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::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--);
            }
        }
    }
}
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::DelStatusEffectsByFlag(uint32 flag, bool silent)
{
    for (uint16 i = 0; i < m_StatusEffectList.size(); ++i)
	{
        if (m_StatusEffectList.at(i)->GetFlag() & flag)
		{
			RemoveStatusEffect(i--, silent);
		}
	}
}
void CStatusEffectContainer::DelStatusEffectsByIcon(uint16 IconID)
{
	for (uint16 i = 0; i < m_StatusEffectList.size(); ++i)
	{
        if (m_StatusEffectList.at(i)->GetIcon() == IconID)
		{
			RemoveStatusEffect(i--);
		}
	}
}
void CStatusEffectContainer::RemoveAllManeuvers()
{
    for (uint16 i = 0; i < m_StatusEffectList.size(); ++i)
    {
        if (m_StatusEffectList.at(i)->GetStatusID() >= EFFECT_FIRE_MANEUVER && 
            m_StatusEffectList.at(i)->GetStatusID() <= EFFECT_DARK_MANEUVER)
        {
            RemoveStatusEffect(i--, true);
        }
    }
}
void CStatusEffectContainer::DelStatusEffectsByType(uint16 Type)
{
if(Type <= 0) return;
for (uint16 i = 0; i < m_StatusEffectList.size(); ++i)
{
if (m_StatusEffectList.at(i)->GetType() == Type)
{
RemoveStatusEffect(i--, true);
}
}
}
bool CStatusEffectContainer::DispelStatusEffect(bool RemoveAll)
{
	for (uint32 i = 0; i < m_StatusEffectList.size(); ++i)
	{
		if (m_StatusEffectList.at(i)->GetFlag() == EFFECTFLAG_DISPELABLE)
		{
			RemoveStatusEffect(i--);
			if (!RemoveAll) return true;
		}
	}
	return false;
}
bool CStatusEffectContainer::DelStatusEffectSilent(EFFECT StatusID)
{
	for (uint16 i = 0; i < m_StatusEffectList.size(); ++i)
	{
		if (m_StatusEffectList.at(i)->GetStatusID() == StatusID)
		{
			RemoveStatusEffect(i, true);
			return true;
		}
	}
	return false;
}
bool CStatusEffectContainer::DelStatusEffect(EFFECT StatusID, uint16 SubID) 
{
	for (uint32 i = 0; i < m_StatusEffectList.size(); ++i) 
	{
		if (m_StatusEffectList.at(i)->GetStatusID() == StatusID &&
		   (m_StatusEffectList.at(i)->GetSubID() == SubID))
		{
			RemoveStatusEffect(i);
			return true;
		}
	}
	return false;
}
bool CStatusEffectContainer::DelStatusEffectByTier(EFFECT StatusID, uint16 tier)
{
	for (uint16 i = 0; i < m_StatusEffectList.size(); ++i)
	{
		if (m_StatusEffectList.at(i)->GetStatusID() == StatusID &&
		   (m_StatusEffectList.at(i)->GetTier() == tier))
		{
			RemoveStatusEffect(i, true);
			return true;
		}
	}
	return false;
}
/*
Erases all negative status effects
returns number of erased effects
*/
uint8 CStatusEffectContainer::EraseAllStatusEffect()
{
    uint8 count = 0;
    for (uint16 i = 0; i < m_StatusEffectList.size(); ++i)
    {
        if (m_StatusEffectList.at(i)->GetFlag() & EFFECTFLAG_ERASABLE &&
            m_StatusEffectList.at(i)->GetDuration() > 0)
        {
            RemoveStatusEffect(i);
            count++;
        }
    }
    return count;
}
/*
Dispels all positive status effects
returns number of dispelled effects
*/
uint8 CStatusEffectContainer::DispelAllStatusEffect(EFFECTFLAG flag)
{
    uint8 count = 0;
    for (int i = 0; i < m_StatusEffectList.size(); ++i)
    {
        if (m_StatusEffectList.at(i)->GetFlag() & flag &&
            m_StatusEffectList.at(i)->GetDuration() > 0)
        {
            RemoveStatusEffect(i, true);
            i--;
            count++;
        }
    }
    return count;
}
EFFECT CStatusEffectContainer::DispelStatusEffect(EFFECTFLAG flag)
{
	std::vector<uint16>	dispelableList;
	for (uint16 i = 0; i < m_StatusEffectList.size(); ++i)
	{
		if (m_StatusEffectList.at(i)->GetFlag() & flag &&
			m_StatusEffectList.at(i)->GetDuration() > 0)
		{
			dispelableList.push_back(i);
		}
	}
	if (!dispelableList.empty())
	{
        uint16 rndIdx = WELL512::GetRandomNumber(dispelableList.size());
		EFFECT result = m_StatusEffectList.at(dispelableList.at(rndIdx))->GetStatusID();
		RemoveStatusEffect(dispelableList.at(rndIdx), true);
		return result;
	}
	return EFFECT_NONE;
}
EFFECT CStatusEffectContainer::EraseStatusEffect()
{
    std::vector<uint16> erasableList;
    for (uint16 i = 0; i < m_StatusEffectList.size(); ++i)
    {
        if (m_StatusEffectList.at(i)->GetFlag() & EFFECTFLAG_ERASABLE &&
            m_StatusEffectList.at(i)->GetDuration() > 0)
        {
            erasableList.push_back(i);
        }
    }
    if (!erasableList.empty())
    {
        uint16 rndIdx = WELL512::GetRandomNumber(erasableList.size());
        EFFECT result = m_StatusEffectList.at(erasableList.at(rndIdx))->GetStatusID();
        RemoveStatusEffect(erasableList.at(rndIdx));
        return result;
    }
    return EFFECT_NONE;
}
EFFECT CStatusEffectContainer::HealingWaltz()
{
   std::vector<uint16> waltzableList;
   for( uint16 i = 0; i < m_StatusEffectList.size(); ++i )
   {
      if( ( m_StatusEffectList.at(i)->GetFlag() & EFFECTFLAG_WALTZABLE || 
          m_StatusEffectList.at(i)->GetFlag() & EFFECTFLAG_ERASABLE ) &&
          m_StatusEffectList.at(i)->GetDuration() > 0 )
      {
         waltzableList.push_back(i);
      }
   }
   if( !waltzableList.empty() )
   {
       uint16 rndIdx = WELL512::GetRandomNumber(waltzableList.size());
      EFFECT result = m_StatusEffectList.at(waltzableList.at(rndIdx))->GetStatusID();
      RemoveStatusEffect(waltzableList.at(rndIdx));
      return result;
   }
    return EFFECT_NONE;
}
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);
    }
}