void CStatusEffectContainer::RemoveStatusEffect(uint32 id)
{
    CStatusEffect* PStatusEffect = m_StatusEffectList.at(id);

    luautils::OnEffectLose(m_POwner, PStatusEffect);

    m_POwner->delModifiers(&PStatusEffect->modList);
    m_POwner->UpdateHealth();

    m_StatusEffectList.erase(m_StatusEffectList.begin() + id);

    if (m_POwner->objtype == TYPE_PC)
    {
        CCharEntity* PChar = (CCharEntity*)m_POwner;

        if (PStatusEffect->GetIcon() != 0)
        {
            UpdateStatusIcons();
            PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, PStatusEffect->GetIcon(), 0, 206));
        }
        if (PChar->status == STATUS_NORMAL) PChar->status = STATUS_UPDATE;

        PChar->pushPacket(new CCharHealthPacket(PChar));
        PChar->pushPacket(new CCharSyncPacket(PChar));
    }
    delete PStatusEffect;
}
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);
    }
}
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;
}
Esempio n. 4
0
bool CAttack::CheckAnticipated()
{
    CStatusEffect* effect = m_victim->StatusEffectContainer->GetStatusEffect(EFFECT_THIRD_EYE, 0);
    if (effect == nullptr)
    {
        return false;
    }

    //power stores how many times this effect has anticipated
    auto pastAnticipations = effect->GetPower();

    if (pastAnticipations > 7)
    {
        //max 7 anticipates!
        m_victim->StatusEffectContainer->DelStatusEffect(EFFECT_THIRD_EYE);
        return false;
    }

    bool hasSeigan = m_victim->StatusEffectContainer->HasStatusEffect(EFFECT_SEIGAN, 0);

    if (!hasSeigan && pastAnticipations == 0)
    {
        m_victim->StatusEffectContainer->DelStatusEffect(EFFECT_THIRD_EYE);
        m_anticipated = true;
        return true;
    }
    else if (!hasSeigan)
    {
        m_victim->StatusEffectContainer->DelStatusEffect(EFFECT_THIRD_EYE);
        return false;
    }
    else
    { //do have seigan, decay anticipations correctly (guesstimated)
        //5-6 anticipates is a 'lucky' streak, going to assume 15% decay per proc, with a 100% base w/ Seigan
        if (dsprand::GetRandomNumber(100) < (100 - (pastAnticipations * 15) + m_victim->getMod(Mod::THIRD_EYE_ANTICIPATE_RATE)))
        {
            //increment power and don't remove
            effect->SetPower(effect->GetPower() + 1);
            //chance to counter - 25% base
            if (dsprand::GetRandomNumber(100) < 25 + m_victim->getMod(Mod::THIRD_EYE_COUNTER_RATE))
            {

                if (m_victim->PAI->IsEngaged())
                {
                    m_isCountered = true;
                    m_isCritical = (dsprand::GetRandomNumber(100) < battleutils::GetCritHitRate(m_victim, m_attacker, false));
                }
            }
            m_anticipated = true;
            return true;
        }
        m_victim->StatusEffectContainer->DelStatusEffect(EFFECT_THIRD_EYE);
        return false;
    }

    return false;
}
Esempio n. 5
0
void CParty::DisbandParty(bool playerInitiated)
{
    if (m_PAlliance)
    {
        m_PAlliance->removeParty(this);
    }
    m_PSyncTarget = nullptr;
    SetQuarterMaster(nullptr);

    m_PLeader = nullptr;
    m_PAlliance = nullptr;

    if (m_PartyType == PARTY_PCS)
    {
        PushPacket(0, 0, new CPartyDefinePacket(nullptr));

        for (uint8 i = 0; i < members.size(); ++i)
        {
            CCharEntity* PChar = (CCharEntity*)members.at(i);

            PChar->PParty = nullptr;
            PChar->PLatentEffectContainer->CheckLatentsPartyJobs();
            PChar->PLatentEffectContainer->CheckLatentsPartyMembers(members.size());
            PChar->PLatentEffectContainer->CheckLatentsPartyAvatar();
            PChar->pushPacket(new CPartyMemberUpdatePacket(PChar, 0, 0, PChar->getZone()));

            // TODO: TreasurePool должен оставаться у последнего персонажа, но сейчас это не критично

            if (PChar->PTreasurePool != nullptr &&
                PChar->PTreasurePool->GetPoolType() != TREASUREPOOL_ZONE)
            {
                PChar->PTreasurePool->DelMember(PChar);
                PChar->PTreasurePool = new CTreasurePool(TREASUREPOOL_SOLO);
                PChar->PTreasurePool->AddMember(PChar);
                PChar->PTreasurePool->UpdatePool(PChar);
            }
            CStatusEffect* sync = PChar->StatusEffectContainer->GetStatusEffect(EFFECT_LEVEL_SYNC);
            if (sync && sync->GetDuration() == 0)
            {
                PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 30, 553));
                sync->SetStartTime(server_clock::now());
                sync->SetDuration(30000);
            }
            Sql_Query(SqlHandle, "DELETE FROM accounts_parties WHERE charid = %u;", PChar->id);
        }

        // make sure chat server isn't notified of a disband if this came from the chat server already
        if (playerInitiated)
        {
            uint8 data[8] {};
            ref<uint32>(data, 0) = m_PartyID;
            ref<uint32>(data, 4) = m_PartyID;
            message::send(MSG_PT_DISBAND, data, sizeof data, nullptr);
        }
    }
    delete this;
}
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
}
void CStatusEffectContainer::CheckEffects(uint32 tick)
{
	DSP_DEBUG_BREAK_IF(m_POwner == nullptr);

	if (!m_POwner->isDead())
	{
		if ((tick - m_EffectCheckTime) < 1000 )
		{
			return;
		}

		m_EffectCheckTime = tick;

		for (uint16 i = 0; i < m_StatusEffectList.size(); ++i)
		{
			CStatusEffect* PStatusEffect = m_StatusEffectList.at(i);

			if (PStatusEffect->GetTickTime() != 0 &&
				PStatusEffect->GetLastTick() + PStatusEffect->GetTickTime() <= tick)
			{
				PStatusEffect->SetLastTick(tick);
				luautils::OnEffectTick(m_POwner,PStatusEffect);
			}

			if (PStatusEffect->GetDuration() != 0 &&
				PStatusEffect->GetDuration() + PStatusEffect->GetStartTime() <= tick && i <m_StatusEffectList.size())
			{
				RemoveStatusEffect(i--);
			}
		}
    }
}
void CStatusEffectContainer::CheckEffects(time_point tick)
{
    DSP_DEBUG_BREAK_IF(m_POwner == nullptr);

    if (!m_POwner->isDead())
    {
        if ((tick - m_EffectCheckTime) < 1s && (tick - m_EffectCheckTime > 0s))
        {
            return;
        }

        m_POwner->PAI->EventHandler.triggerListener("EFFECT_TICK", m_POwner);
        m_EffectCheckTime = tick;

        for (uint16 i = 0; i < m_StatusEffectList.size(); ++i)
        {
            CStatusEffect* PStatusEffect = m_StatusEffectList.at(i);

            if (PStatusEffect->GetTickTime() != 0 &&
                PStatusEffect->GetLastTick() + std::chrono::milliseconds(PStatusEffect->GetTickTime()) <= tick)
            {
                PStatusEffect->SetLastTick(tick);
                luautils::OnEffectTick(m_POwner, PStatusEffect);
            }

            if (PStatusEffect->GetDuration() != 0 &&
                std::chrono::milliseconds(PStatusEffect->GetDuration()) + PStatusEffect->GetStartTime() <= tick && i < m_StatusEffectList.size())
            {
                RemoveStatusEffect(i--);
            }
        }
    }
}
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;
}
Esempio n. 10
0
void CParty::DisbandParty()
{
	DisableSync();
	SetQuaterMaster(NULL);

	m_PLeader = NULL;
	m_PAlliance	= NULL;

    if (m_PartyType == PARTY_PCS)
    {
        PushPacket(NULL, 0, new CPartyDefinePacket(NULL));

	    for (uint8 i = 0; i < members.size(); ++i)
	    {
		    CCharEntity* PChar = (CCharEntity*)members.at(i);

		    PChar->PParty = NULL;
			PChar->PLatentEffectContainer->CheckLatentsPartyJobs();
			PChar->PLatentEffectContainer->CheckLatentsPartyMembers(members.size());
			PChar->PLatentEffectContainer->CheckLatentsPartyAvatar();
		    PChar->pushPacket(new CPartyMemberUpdatePacket(PChar, 0, PChar->getZone()));

		    // TODO: TreasurePool должен оставаться у последнего персонажа, но сейчас это не критично

            if (PChar->PTreasurePool != NULL &&
                PChar->PTreasurePool->GetPoolType() != TREASUREPOOL_ZONE)
		    {
			    PChar->PTreasurePool->DelMember(PChar);
			    PChar->PTreasurePool = new CTreasurePool(TREASUREPOOL_SOLO);
			    PChar->PTreasurePool->AddMember(PChar);
                PChar->PTreasurePool->UpdatePool(PChar);
		    }
            CStatusEffect* sync = PChar->StatusEffectContainer->GetStatusEffect(EFFECT_LEVEL_SYNC);
            if (sync && sync->GetDuration() == 0)
            {
    			PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 30, 553));
                sync->SetStartTime(gettick());
                sync->SetDuration(30000);
            }
	    }
        Sql_Query(SqlHandle,"UPDATE accounts_sessions SET partyid = %u WHERE partyid = %u", 0, m_PartyID);
    }
	delete this;
}
Esempio n. 11
0
void CStatusEffectContainer::RemoveStatusEffect(uint32 id, bool silent)
{
    CStatusEffect* PStatusEffect = m_StatusEffectList.at(id);

    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
		CLatentEffectContainer* PLatentEffectContainer;
		PChar->PLatentEffectContainer->CheckLatentsFoodEffect();
		PChar->PLatentEffectContainer->CheckLatentsStatusEffect();
		PChar->UpdateHealth();

        if (PChar->status == STATUS_NORMAL) PChar->status = STATUS_UPDATE;

        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;
}
/************************************************************************
*																		*
*  Deletes all status effects without sending messages              	*
*																		*
************************************************************************/
void CStatusEffectContainer::KillAllStatusEffect()
{
	for (uint16 i = 0; i < m_StatusEffectList.size(); ++i)
	{
		CStatusEffect* PStatusEffect = m_StatusEffectList.at(i);

        if (PStatusEffect->GetDuration() != 0)
        {

            luautils::OnEffectLose(m_POwner, PStatusEffect);

            m_POwner->delModifiers(&PStatusEffect->modList);

            m_StatusEffectList.erase(m_StatusEffectList.begin() + i);

            delete PStatusEffect;
        }
	}
    m_POwner->UpdateHealth();
}
/************************************************************************
* *
* ????????? ??????? ????????? *
* *
************************************************************************/
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);
    }
}
Esempio n. 15
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;
}
Esempio n. 16
0
void CParty::RemoveMember(CBattleEntity* PEntity)
{
    DSP_DEBUG_BREAK_IF(PEntity == nullptr);
    DSP_DEBUG_BREAK_IF(PEntity->PParty != this);

    if (m_PLeader == PEntity)
    {
        RemovePartyLeader(PEntity);
    }
    else
    {
        for (uint32 i = 0; i < members.size(); ++i)
        {
            if (PEntity == members.at(i))
            {
                members.erase(members.begin() + i);

                if (m_PartyType == PARTY_PCS)
                {
                    CCharEntity* PChar = (CCharEntity*)PEntity;

                    if (m_PQuaterMaster == PChar)
                    {
                        SetQuarterMaster(nullptr);
                    }
                    if (m_PSyncTarget == PChar)
                    {
                        SetSyncTarget(nullptr, 553);
                        CStatusEffect* sync = PChar->StatusEffectContainer->GetStatusEffect(EFFECT_LEVEL_SYNC);
                        if (sync && sync->GetDuration() == 0)
                        {
                            PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 30, 553));
                            sync->SetStartTime(server_clock::now());
                            sync->SetDuration(30000);
                        }
                        DisableSync();
                    }
                    if (m_PSyncTarget != nullptr && m_PSyncTarget != PChar)
                    {
                        if (PChar->status != STATUS_DISAPPEAR)
                        {
                            CStatusEffect* sync = PChar->StatusEffectContainer->GetStatusEffect(EFFECT_LEVEL_SYNC);
                            if (sync && sync->GetDuration() == 0)
                            {
                                PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 30, 553));
                                sync->SetStartTime(server_clock::now());
                                sync->SetDuration(30000);
                            }
                        }
                    }
                    PChar->PLatentEffectContainer->CheckLatentsPartyMembers(members.size());

                    PChar->pushPacket(new CPartyDefinePacket(nullptr));
                    PChar->pushPacket(new CPartyMemberUpdatePacket(PChar, 0, 0, PChar->getZone()));
                    PChar->pushPacket(new CCharUpdatePacket(PChar));
                    PChar->PParty = nullptr;

                    Sql_Query(SqlHandle, "DELETE FROM accounts_parties WHERE charid = %u;", PChar->id);

                    uint8 data[4] {};
                    ref<uint32>(data, 0) = m_PartyID;
                    message::send(MSG_PT_RELOAD, data, sizeof data, nullptr);

                    if (PChar->PTreasurePool != nullptr &&
                        PChar->PTreasurePool->GetPoolType() != TREASUREPOOL_ZONE)
                    {
                        PChar->PTreasurePool->DelMember(PChar);
                        PChar->PTreasurePool = new CTreasurePool(TREASUREPOOL_SOLO);
                        PChar->PTreasurePool->AddMember(PChar);
                        PChar->PTreasurePool->UpdatePool(PChar);
                    }
                }
                break;
            }
        }
    }
}
bool CAutomatonController::TryTPMove()
{
    if (PAutomaton->health.tp >= 1000)
    {
        const auto& FamilySkills = battleutils::GetMobSkillList(PAutomaton->m_Family);

        std::vector<CMobSkill*> validSkills;

        //load the skills that the automaton has access to with it's skill
        SKILLTYPE skilltype = SKILL_AME;

        if (PAutomaton->getFrame() == FRAME_SHARPSHOT)
            skilltype = SKILL_ARA;

        for (auto skillid : FamilySkills)
        {
            auto PSkill = battleutils::GetMobSkill(skillid);
            if (PSkill && PAutomaton->GetSkill(skilltype) > PSkill->getParam() && PSkill->getParam() != -1 &&
                distance(PAutomaton->loc.p, PTarget->loc.p) < PSkill->getRadius())
            {
                validSkills.push_back(PSkill);
            }
        }

        int16 currentSkill = -1;
        CMobSkill* PWSkill = nullptr;
        int8 currentManeuvers = -1;

        bool attemptChain = (PAutomaton->getMod(Mod::AUTO_TP_EFFICIENCY) != 0);

        if (attemptChain)
        {
            CStatusEffect* PSCEffect = PTarget->StatusEffectContainer->GetStatusEffect(EFFECT_SKILLCHAIN, 0);
            if (PSCEffect)
            {
                std::list<SKILLCHAIN_ELEMENT> resonanceProperties;
                if (PSCEffect->GetTier() == 0)
                {
                    if (PSCEffect->GetStartTime() + 3s < m_Tick)
                    {
                        if (PSCEffect->GetPower())
                        {
                            CWeaponSkill* PWeaponSkill = battleutils::GetWeaponSkill(PSCEffect->GetPower());
                            resonanceProperties.push_back((SKILLCHAIN_ELEMENT)PWeaponSkill->getPrimarySkillchain());
                            resonanceProperties.push_back((SKILLCHAIN_ELEMENT)PWeaponSkill->getSecondarySkillchain());
                            resonanceProperties.push_back((SKILLCHAIN_ELEMENT)PWeaponSkill->getTertiarySkillchain());
                        }
                        else
                        {
                            CBlueSpell* oldSpell = (CBlueSpell*)spell::GetSpell(static_cast<SpellID>(PSCEffect->GetSubPower()));
                            resonanceProperties.push_back((SKILLCHAIN_ELEMENT)oldSpell->getPrimarySkillchain());
                            resonanceProperties.push_back((SKILLCHAIN_ELEMENT)oldSpell->getSecondarySkillchain());
                        }
                    }
                }
                else
                {
                    resonanceProperties.push_back((SKILLCHAIN_ELEMENT)PSCEffect->GetPower());
                }

                for (auto PSkill : validSkills)
                {
                    if (PSkill->getParam() > currentSkill)
                    {
                        std::list<SKILLCHAIN_ELEMENT> skillProperties;
                        skillProperties.push_back((SKILLCHAIN_ELEMENT)PSkill->getPrimarySkillchain());
                        skillProperties.push_back((SKILLCHAIN_ELEMENT)PSkill->getSecondarySkillchain());
                        skillProperties.push_back((SKILLCHAIN_ELEMENT)PSkill->getTertiarySkillchain());
                        if (battleutils::FormSkillchain(resonanceProperties, skillProperties) != SC_NONE)
                        {
                            currentManeuvers = 1;
                            currentSkill = PSkill->getParam();
                            PWSkill = PSkill;
                        }
                    }
                }
            }
        }

        if (!attemptChain || (currentManeuvers == -1 && PAutomaton->PMaster && PAutomaton->PMaster->health.tp < PAutomaton->getMod(Mod::AUTO_TP_EFFICIENCY)))
        {
            for (auto PSkill : validSkills)
            {
                int8 maneuvers = luautils::OnMobAutomatonSkillCheck(PTarget, PAutomaton, PSkill);
                if (maneuvers > -1 && (maneuvers > currentManeuvers || (maneuvers == currentManeuvers && PSkill->getParam() > currentSkill)))
                {
                    currentManeuvers = maneuvers;
                    currentSkill = PSkill->getParam();
                    PWSkill = PSkill;
                }
            }
        }

        // No WS was chosen (waiting on master's TP to skillchain probably)
        if (currentManeuvers == -1)
            return false;

        if (PWSkill)
            return MobSkill(PTarget->targid, PWSkill->getID());
    }
    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;
}
Esempio n. 19
0
void CParty::SetSyncTarget(CBattleEntity* PEntity, uint16 message)
{
    if (map_config.level_sync_enable)
    {
        if (PEntity && PEntity->objtype == TYPE_PC)
        {
            CCharEntity* PChar = (CCharEntity*)PEntity;
            //enable level sync
            if (PChar->GetMLevel() < 10 )
            {
                ((CCharEntity*)GetLeader())->pushPacket(new CMessageBasicPacket((CCharEntity*)GetLeader(), (CCharEntity*)GetLeader(), 0, 10, 541));
                return;
            }
            else if (PChar->getZone() != GetLeader()->getZone())
            {
                ((CCharEntity*)GetLeader())->pushPacket(new CMessageBasicPacket((CCharEntity*)GetLeader(), (CCharEntity*)GetLeader(), 0, 0, 542));
                return;
            }
            else
            {
                for (uint32 i = 0; i < members.size(); ++i)
                {
                    if(members.at(i)->StatusEffectContainer->HasStatusEffect(EFFECT_LEVEL_RESTRICTION))
                    {
                        ((CCharEntity*)GetLeader())->pushPacket(new CMessageBasicPacket((CCharEntity*)GetLeader(), (CCharEntity*)GetLeader(), 0, 0, 543));
                        return;
                    }
                }
                m_PSyncTarget = PChar;
	            for (uint32 i = 0; i < members.size(); ++i)
	            {
		            if(members.at(i)->objtype != TYPE_PC) continue;

		            CCharEntity* member = (CCharEntity*)members.at(i);

                    if (member->status != STATUS_DISAPPEAR &&
                         member->getZone() == PChar->getZone() )
		            {
			            member->pushPacket(new CMessageStandardPacket(PChar->GetMLevel(), 0, 0, 0, message));
                        member->StatusEffectContainer->AddStatusEffect(new CStatusEffect(
                            EFFECT_LEVEL_SYNC,
                            EFFECT_LEVEL_SYNC,
                            PChar->GetMLevel(),
                            0,
                            0), true);
                        member->StatusEffectContainer->DelStatusEffectsByFlag(EFFECTFLAG_DISPELABLE);
                        member->loc.zone->PushPacket(member, CHAR_INRANGE, new CCharSyncPacket(member));
		            }
	            }
            }
        }
        else
        {
            if (m_PSyncTarget != NULL)
            {
                //disable level sync
                for (uint32 i = 0; i < members.size(); ++i)
	            {
		            if(members.at(i)->objtype != TYPE_PC) continue;

		            CCharEntity* member = (CCharEntity*)members.at(i);

                    if (member->status != STATUS_DISAPPEAR &&
                         member->getZone() == m_PSyncTarget->getZone() )
		            {
                        CStatusEffect* sync = member->StatusEffectContainer->GetStatusEffect(EFFECT_LEVEL_SYNC);
                        if (sync && sync->GetDuration() == 0)
                        {
			                member->pushPacket(new CMessageBasicPacket(member, member, 10, 30, message));
                            sync->SetStartTime(gettick());
                            sync->SetDuration(30000);
                        }
		            }
	            }
            }
        }
    }
}
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;
}
Esempio n. 21
0
void CParty::SetSyncTarget(int8* MemberName, uint16 message)
{
    CBattleEntity* PEntity = nullptr;
    if (MemberName)
    {
        PEntity = GetMemberByName(MemberName);
    }

    if (map_config.level_sync_enable)
    {
        if (PEntity && PEntity->objtype == TYPE_PC)
        {
            CCharEntity* PChar = (CCharEntity*)PEntity;
            //enable level sync
            if (PChar->GetMLevel() < 10)
            {
                ((CCharEntity*)GetLeader())->pushPacket(new CMessageBasicPacket((CCharEntity*)GetLeader(), (CCharEntity*)GetLeader(), 0, 10, 541));
                return;
            }
            else if (PChar->getZone() != GetLeader()->getZone())
            {
                ((CCharEntity*)GetLeader())->pushPacket(new CMessageBasicPacket((CCharEntity*)GetLeader(), (CCharEntity*)GetLeader(), 0, 0, 542));
                return;
            }
            else
            {
                for (uint8 i = 0; i < members.size(); ++i)
                {
                    if (members.at(i)->StatusEffectContainer->HasStatusEffect({EFFECT_LEVEL_RESTRICTION, EFFECT_LEVEL_SYNC}))
                    {
                        ((CCharEntity*)GetLeader())->pushPacket(new CMessageBasicPacket((CCharEntity*)GetLeader(), (CCharEntity*)GetLeader(), 0, 0, 543));
                        return;
                    }
                }
                m_PSyncTarget = PChar;
                for (uint8 i = 0; i < members.size(); ++i)
                {
                    if (members.at(i)->objtype != TYPE_PC) continue;

                    CCharEntity* member = (CCharEntity*)members.at(i);

                    if (member->status != STATUS_DISAPPEAR &&
                        member->getZone() == PChar->getZone())
                    {
                        member->pushPacket(new CMessageStandardPacket(PChar->GetMLevel(), 0, 0, 0, message));
                        member->StatusEffectContainer->AddStatusEffect(new CStatusEffect(
                            EFFECT_LEVEL_SYNC,
                            EFFECT_LEVEL_SYNC,
                            PChar->GetMLevel(),
                            0,
                            0), true);
                        member->StatusEffectContainer->DelStatusEffectsByFlag(EFFECTFLAG_DISPELABLE | EFFECTFLAG_ON_ZONE);
                        member->loc.zone->PushPacket(member, CHAR_INRANGE, new CCharSyncPacket(member));
                    }
                }
                Sql_Query(SqlHandle, "UPDATE accounts_parties SET partyflag = partyflag & ~%d WHERE partyid = %u AND partyflag & %d", PARTY_SYNC, m_PartyID, PARTY_SYNC);
                Sql_Query(SqlHandle, "UPDATE accounts_parties SET partyflag = partyflag | %d WHERE partyid = %u AND charid = '%u';", PARTY_SYNC, m_PartyID, PChar->id);
            }
        }
        else
        {
            if (m_PSyncTarget != nullptr)
            {
                //disable level sync
                for (uint8 i = 0; i < members.size(); ++i)
                {
                    if (members.at(i)->objtype != TYPE_PC) continue;

                    CCharEntity* member = (CCharEntity*)members.at(i);

                    if (member->status != STATUS_DISAPPEAR)
                    {
                        CStatusEffect* sync = member->StatusEffectContainer->GetStatusEffect(EFFECT_LEVEL_SYNC);
                        if (sync && sync->GetDuration() == 0)
                        {
                            member->pushPacket(new CMessageBasicPacket(member, member, 10, 30, message));
                            sync->SetStartTime(server_clock::now());
                            sync->SetDuration(30000);
                        }
                    }
                }
            }
            m_PSyncTarget = nullptr;
            Sql_Query(SqlHandle, "UPDATE accounts_parties SET partyflag = partyflag & ~%d WHERE partyid = %u AND partyflag & %d", PARTY_SYNC, m_PartyID, PARTY_SYNC);
        }
    }
}
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;

        uint32 realduration = (PStatusEffect->GetDuration() + PStatusEffect->GetStartTime() - gettick()) / 1000;

        if (realduration > 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));
            }

            uint32 tick = PStatusEffect->GetTickTime() == 0 ? 0 : PStatusEffect->GetTickTime() / 100;
            uint32 duration = PStatusEffect->GetDuration() == 0 ? 0 : realduration;

            Sql_Query(SqlHandle, Query,
                m_POwner->id,
                PStatusEffect->GetStatusID(),
                PStatusEffect->GetIcon(),
                PStatusEffect->GetPower(),
                tick,
                duration,
                PStatusEffect->GetSubID(),
                PStatusEffect->GetSubPower(),
                PStatusEffect->GetTier());
        }
    }
}
Esempio n. 23
0
void CParty::DelMember(CBattleEntity* PEntity)
{
	DSP_DEBUG_BREAK_IF(PEntity == NULL);
	DSP_DEBUG_BREAK_IF(PEntity->PParty != this);

	if (m_PLeader == PEntity)
	{
		RemovePartyLeader(PEntity);
	}
	else
	{
		for (uint32 i = 0; i < members.size(); ++i)
		{
			if (PEntity == members.at(i))
			{
				members.erase(members.begin() + i);

				if (m_PartyType == PARTY_PCS)
				{
					CCharEntity* PChar = (CCharEntity*)PEntity;

					if (m_PQuaterMaster == PChar)
					{
						SetQuarterMaster(NULL);
					}
					if (m_PSyncTarget == PChar)
					{
						SetSyncTarget(NULL, 553);
						CStatusEffect* sync = PChar->StatusEffectContainer->GetStatusEffect(EFFECT_LEVEL_SYNC);
						if (sync && sync->GetDuration() == 0)
						{
							PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 30, 553));
							sync->SetStartTime(gettick());
							sync->SetDuration(30000);
						}
						DisableSync();
					}
					if (m_PSyncTarget != NULL && m_PSyncTarget != PChar)
					{
						if (PChar->status != STATUS_DISAPPEAR &&
							PChar->getZone() == m_PSyncTarget->getZone())
						{
							CStatusEffect* sync = PChar->StatusEffectContainer->GetStatusEffect(EFFECT_LEVEL_SYNC);
							if (sync && sync->GetDuration() == 0)
							{
								PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 30, 553));
								sync->SetStartTime(gettick());
								sync->SetDuration(30000);
							}
						}
					}
					PChar->PLatentEffectContainer->CheckLatentsPartyMembers(members.size());

					PChar->pushPacket(new CPartyDefinePacket(NULL));
					PChar->pushPacket(new CPartyMemberUpdatePacket(PChar, 0, PChar->getZone()));
					PChar->pushPacket(new CCharUpdatePacket(PChar));
					PChar->PParty = NULL;

					if (PChar->PTreasurePool != NULL &&
						PChar->PTreasurePool->GetPoolType() != TREASUREPOOL_ZONE)
					{
						PChar->PTreasurePool->DelMember(PChar);
						PChar->PTreasurePool = new CTreasurePool(TREASUREPOOL_SOLO);
						PChar->PTreasurePool->AddMember(PChar);
						PChar->PTreasurePool->UpdatePool(PChar);
					}
				}
				break;
			}
		}
	}
}