Öneri Affect kodlarının güncellenmesi

  • Konuyu açan Konuyu açan TheAdmin33
  • Açılış Tarihi Açılış Tarihi
  • Yanıt Yanıt 3
  • Gösterim Gösterim 155
Konu sahibi önerilerinizi bekliyor. Konuya yorum yazabilirsiniz.

TheAdmin33

Ah, bu şarkıların gözü kör olsun
Geliştirici
Yardımsever Üye
Usta Üye
Editör
Mesaj
1.409
Çözümler
76
Beğeni
5.638
Puan
2.859
Ticaret Puanı
0
oyunun efekt kodlarında bazı değişiklikler yaptım ve sizinlede paylaşmak istedim. öyle über süper bir güncelleme yapmadım ama emin olmak için sizede sorayım dedim.En büyük değişikliği RemoveAffect fonksiyonlarında yaptım bir yanlış hata ve öneriniz varsa yazarsanız güzel olur. (@okan4141)

char_affect.cpp:
Genişlet Daralt Kopyala
CAffect* CHARACTER::FindAffect(DWORD dwType, BYTE bApply /*= APPLY_NONE*/) const
{
    if (m_list_pkAffect.empty())
        return nullptr;
    for (CAffect* pkAffect : m_list_pkAffect)
    {
        if (!pkAffect)
            continue;
        if (pkAffect->dwType == dwType &&
            (bApply == APPLY_NONE || bApply == pkAffect->bApplyOn))
        {
            return pkAffect;
        }
    }
    return nullptr;
}

char_affect.cpp:
Genişlet Daralt Kopyala
void CHARACTER::RefreshAffect()
{
    for (CAffect* pkAff : m_list_pkAffect)
    {
        if (pkAff)
        {
            ComputeAffect(pkAff, true);
        }
    }
}

char_affect.cpp:
Genişlet Daralt Kopyala
void CHARACTER::ClearAffect(bool bSave)
{
    if (m_list_pkAffect.empty())
        return;
    const TAffectFlag afOld = m_afAffectFlag;
    const WORD wMovSpd = GetPoint(POINT_MOV_SPEED);
    const WORD wAttSpd = GetPoint(POINT_ATT_SPEED);
    for (auto it = m_list_pkAffect.begin(); it != m_list_pkAffect.end(); )
    {
        CAffect* pkAff = *it;
        if (!pkAff)
        {
            it = m_list_pkAffect.erase(it);
            continue;
        }
        if (bSave)
        {
            if ( IS_NO_CLEAR_ON_DEATH_AFFECT(pkAff->dwType) || IS_NO_SAVE_AFFECT(pkAff->dwType) )
            {
                ++it;
                continue;
            }
            if (IsPC())
            {
                SendAffectRemovePacket(GetDesc(), GetPlayerID(), pkAff->dwType, pkAff->bApplyOn);
            }
        }
        ComputeAffect(pkAff, false);
        it = m_list_pkAffect.erase(it);
        CAffect::Release(pkAff);
    }
    if (afOld != m_afAffectFlag ||
            wMovSpd != GetPoint(POINT_MOV_SPEED) ||
            wAttSpd != GetPoint(POINT_ATT_SPEED))
        UpdatePacket();
    CheckMaximumPoints();
    if (m_list_pkAffect.empty())
        event_cancel(&m_pkAffectEvent);
}

char_affect.cpp:
Genişlet Daralt Kopyala
bool CHARACTER::RemoveAffect(CAffect * pkAff)
{
    if (!pkAff)
        return false;
    // AFFECT_BUF_FIX
    m_list_pkAffect.remove(pkAff);
    // END_OF_AFFECT_BUF_FIX
    ComputeAffect(pkAff, false);
    if (AFFECT_REVIVE_INVISIBLE != pkAff->dwType)
        ComputePoints();
    else  // @fixme110
        UpdatePacket();
    CheckMaximumPoints();
    if (test_server)
        sys_log(0, "AFFECT_REMOVE: %s (flag %u apply: %u)", GetName(), pkAff->dwFlag, pkAff->bApplyOn);
    if (IsPC())
    {
        SendAffectRemovePacket(GetDesc(), GetPlayerID(), pkAff->dwType, pkAff->bApplyOn);
    }
    CAffect::Release(pkAff);
    return true;
}
bool CHARACTER::RemoveAffect(DWORD dwType)
{
    // CHAT_BLOCK
    if (dwType == AFFECT_BLOCK_CHAT)
    {
        ChatPacket(CHAT_TYPE_INFO, LC_TEXT("äÆÃ ±İÁö°¡ Ç®·È½À´Ï´Ù."));
    }
    // END_OF_CHAT_BLOCK
    if (m_list_pkAffect.empty())
        return false;
    bool flag = false;
    bool flag_affect_revive_invisible = false;
    for (auto it = m_list_pkAffect.begin(); it != m_list_pkAffect.end(); )
    {
        CAffect* pkAff = *it;
        if (!pkAff)
        {
            it = m_list_pkAffect.erase(it);
            continue;
        }
        if (pkAff->dwType == dwType)
        {
            it = m_list_pkAffect.erase(it);
            ComputeAffect(pkAff, false);
            if (AFFECT_REVIVE_INVISIBLE != pkAff->dwType)
                flag_affect_revive_invisible = true;
            if (test_server)
                sys_log(0, "AFFECT_REMOVE: %s (flag %u apply: %u)", GetName(), pkAff->dwFlag, pkAff->bApplyOn);
            if (IsPC())
            {
                SendAffectRemovePacket(GetDesc(), GetPlayerID(), pkAff->dwType, pkAff->bApplyOn);
            }
            CAffect::Release(pkAff);
            flag = true;
        }
        else
        {
            ++it;
        }
    }
    if (flag)
    {
        if (flag_affect_revive_invisible)
            ComputePoints();
        else
            UpdatePacket();
        CheckMaximumPoints();
    }
    return flag;
}
 
dosyadaki kodların tamamını chatcpt ile birlikte komple elden geçirdim isteyen inceleyebilir

char_affect.cpp:
Genişlet Daralt Kopyala
void SendAffectRemovePacket(LPDESC d, DWORD pid, DWORD type, BYTE point)
{
    if (!d)
        return;

    // --- Client paket ---
    TPacketGCAffectRemove ptoc{};
    ptoc.bHeader    = HEADER_GC_AFFECT_REMOVE;
    ptoc.dwType        = type;
    ptoc.bApplyOn    = point;
    d->Packet(&ptoc, sizeof(ptoc));

    // --- DB paket ---
    TPacketGDRemoveAffect ptod{};
    ptod.dwPID        = pid;
    ptod.dwType        = type;
    ptod.bApplyOn    = point;
    db_clientdesc->DBPacket(HEADER_GD_REMOVE_AFFECT, 0, &ptod, sizeof(ptod));
}

void SendAffectAddPacket(LPDESC d, CAffect* pkAff)
{
    if (!d || !pkAff)
        return;

    TPacketGCAffectAdd ptoc{};
    ptoc.bHeader            = HEADER_GC_AFFECT_ADD;
    ptoc.elem.dwType        = pkAff->dwType;
    ptoc.elem.bApplyOn        = pkAff->bApplyOn;
    ptoc.elem.lApplyValue    = pkAff->lApplyValue;
    ptoc.elem.dwFlag        = pkAff->dwFlag;
    ptoc.elem.lDuration        = pkAff->lDuration;
    ptoc.elem.lSPCost        = pkAff->lSPCost;

    d->Packet(&ptoc, sizeof(ptoc));
}
////////////////////////////////////////////////////////////////////
// Affect
CAffect* CHARACTER::FindAffect(DWORD dwType, BYTE bApply /*= APPLY_NONE*/) const
{
    if (m_list_pkAffect.empty())
        return nullptr;

    for (CAffect* pkAffect : m_list_pkAffect)
    {
        if (!pkAffect)
            continue;

        if (pkAffect->dwType == dwType &&
            (bApply == APPLY_NONE || bApply == pkAffect->bApplyOn))
        {
            return pkAffect;
        }
    }

    return nullptr;
}

EVENTFUNC(affect_event)
{
    auto* info = dynamic_cast<char_event_info*>(event->info);
    if (!info)
    {
        sys_err("affect_event > Null event info pointer");
        return 0;
    }

    LPCHARACTER ch = info->ch;
    if (!ch)
    {
        sys_err("affect_event > Null character pointer");
        return 0;
    }

    if (!ch->UpdateAffect())
        return 0;

    return passes_per_sec;
}

bool CHARACTER::UpdateAffect()
{
    // --- HP Recovery ---
    int hpRecovery = GetPoint(POINT_HP_RECOVERY);
    if (hpRecovery > 0)
    {
        if (GetHP() >= GetMaxHP())
        {
            PointChange(POINT_HP_RECOVERY, -hpRecovery);
        }
        else
        {
            int iVal = MIN(hpRecovery, GetMaxHP() * 7 / 100);
            PointChange(POINT_HP, iVal);
            PointChange(POINT_HP_RECOVERY, -iVal);
        }
    }

    // --- SP Recovery ---
    int spRecovery = GetPoint(POINT_SP_RECOVERY);
    if (spRecovery > 0)
    {
        if (GetSP() >= GetMaxSP())
        {
            PointChange(POINT_SP_RECOVERY, -spRecovery);
        }
        else
        {
            int iVal = MIN(spRecovery, GetMaxSP() * 7 / 100);
            PointChange(POINT_SP, iVal);
            PointChange(POINT_SP_RECOVERY, -iVal);
        }
    }

    if (GetPoint(POINT_HP_RECOVER_CONTINUE) > 0)
    {
        PointChange(POINT_HP, GetPoint(POINT_HP_RECOVER_CONTINUE));
    }

    if (GetPoint(POINT_SP_RECOVER_CONTINUE) > 0)
    {
        PointChange(POINT_SP, GetPoint(POINT_SP_RECOVER_CONTINUE));
    }

    AutoRecoveryItemProcess( AFFECT_AUTO_HP_RECOVERY );
    AutoRecoveryItemProcess( AFFECT_AUTO_SP_RECOVERY );

    // --- Stamina Recovery ---
    if (GetStamina() < GetMaxStamina())
    {
        int iSec = (get_dword_time() - GetStopTime()) / 3000;
        if (iSec > 0)
            PointChange(POINT_STAMINA, GetMaxStamina());
    }

    // --- Process Affect ---
    if (ProcessAffect())
    {
        if (GetPoint(POINT_HP_RECOVERY) == 0 &&
            GetPoint(POINT_SP_RECOVERY) == 0 &&
            GetStamina() == GetMaxStamina())
        {
            m_pkAffectEvent = nullptr;
            return false;
        }
    }

    return true;
}

void CHARACTER::StartAffectEvent()
{
    if (m_pkAffectEvent)
        return;

    auto* info = AllocEventInfo<char_event_info>();
    if (!info)
    {
        sys_err("StartAffectEvent > Failed to allocate event info for %s", GetName());
        return;
    }

    info->ch = this;

    m_pkAffectEvent = event_create(affect_event, info, passes_per_sec);
    sys_log(1, "StartAffectEvent %s %p %p", GetName(), this, get_pointer(m_pkAffectEvent));
}

void CHARACTER::ClearAffect(bool bSave)
{
    if (m_list_pkAffect.empty())
        return;

    const TAffectFlag afOld = m_afAffectFlag;
    const WORD wMovSpd = GetPoint(POINT_MOV_SPEED);
    const WORD wAttSpd = GetPoint(POINT_ATT_SPEED);

    for (auto it = m_list_pkAffect.begin(); it != m_list_pkAffect.end(); )
    {
        CAffect* pkAff = *it;
        if (!pkAff)
        {
            it = m_list_pkAffect.erase(it);
            continue;
        }

        if (bSave)
        {
            if ( IS_NO_CLEAR_ON_DEATH_AFFECT(pkAff->dwType) || IS_NO_SAVE_AFFECT(pkAff->dwType) )
            {
                ++it;
                continue;
            }

            if (IsPC())
            {
                SendAffectRemovePacket(GetDesc(), GetPlayerID(), pkAff->dwType, pkAff->bApplyOn);
            }
        }

        ComputeAffect(pkAff, false);

        it = m_list_pkAffect.erase(it);
        CAffect::Release(pkAff);
    }

    if (afOld != m_afAffectFlag ||
            wMovSpd != GetPoint(POINT_MOV_SPEED) ||
            wAttSpd != GetPoint(POINT_ATT_SPEED))
        UpdatePacket();

    CheckMaximumPoints();

    if (m_list_pkAffect.empty())
        event_cancel(&m_pkAffectEvent);
}

int CHARACTER::ProcessAffect()
{
    bool bDiff = false;
    CAffect* pkAff = nullptr;

    // --- Premium affect kontrolü ---
    for (int i = 0; i <= PREMIUM_MAX_NUM; ++i)
    {
        int aff_idx = i + AFFECT_PREMIUM_START;
        pkAff = FindAffect(aff_idx);
        if (!pkAff)
            continue;

        int remain = GetPremiumRemainSeconds(i);
        if (remain < 0)
        {
            RemoveAffect(aff_idx);
            bDiff = true;
        }
        else
        {
            pkAff->lDuration = remain + 1;
        }
    }

    ////////// HAIR_AFFECT
    pkAff = FindAffect(AFFECT_HAIR);
    if (pkAff)
    {
        // IF HAIR_LIMIT_TIME() < CURRENT_TIME()
        if ( this->GetQuestFlag("hair.limit_time") < get_global_time())
        {
            // SET HAIR NORMAL
            this->SetPart(PART_HAIR, 0);
            // REMOVE HAIR AFFECT
            RemoveAffect(AFFECT_HAIR);
        }
        else
        {
            // INCREASE AFFECT DURATION
            ++(pkAff->lDuration);
        }
    }

    // --- Horse name validation ---
    CHorseNameManager::instance().Validate(this);

    // --- Affect flag & speed snapshots ---
    TAffectFlag afOld = m_afAffectFlag;
    long lMovSpd = GetPoint(POINT_MOV_SPEED);
    long lAttSpd = GetPoint(POINT_ATT_SPEED);

    // --- Affect list processing ---
    for (auto it = m_list_pkAffect.begin(); it != m_list_pkAffect.end();)
    {
        pkAff = *it;
        bool bEnd = false;

        // --- Guild skill check ---
        if (pkAff->dwType >= GUILD_SKILL_START && pkAff->dwType <= GUILD_SKILL_END)
        {
            if (!GetGuild() || !GetGuild()->UnderAnyWar())
                bEnd = true;
        }

        // --- SP cost check ---
        if (pkAff->lSPCost > 0)
        {
            if (GetSP() < pkAff->lSPCost)
                bEnd = true;
            else
                PointChange(POINT_SP, -pkAff->lSPCost);
        }

        // --- Duration check ---
        if (--pkAff->lDuration <= 0)
            bEnd = true;

        // --- Remove affect if ended ---
        if (bEnd)
        {
            it = m_list_pkAffect.erase(it);
            ComputeAffect(pkAff, false);
            bDiff = true;

            if (IsPC())
                SendAffectRemovePacket(GetDesc(), GetPlayerID(), pkAff->dwType, pkAff->bApplyOn);

            CAffect::Release(pkAff);
            continue;
        }

        ++it;
    }

    // --- Packet update if affect changed ---
    if (bDiff)
    {
        if (afOld != m_afAffectFlag ||
            lMovSpd != GetPoint(POINT_MOV_SPEED) ||
            lAttSpd != GetPoint(POINT_ATT_SPEED))
        {
            UpdatePacket();
        }

        CheckMaximumPoints();
    }

    if (m_list_pkAffect.empty())
        return true;

    return false;
}

void CHARACTER::SaveAffect()
{
    TPacketGDAddAffect packet;

    for (auto* pkAff : m_list_pkAffect)
    {
        if (!pkAff)
            continue;

        if (IS_NO_SAVE_AFFECT(pkAff->dwType))
            continue;

        sys_log(1, "AFFECT_SAVE: %u %u %d %d",
            pkAff->dwType, pkAff->bApplyOn, pkAff->lApplyValue, pkAff->lDuration);

        packet.dwPID              = GetPlayerID();
        packet.elem.dwType        = pkAff->dwType;
        packet.elem.bApplyOn      = pkAff->bApplyOn;
        packet.elem.lApplyValue   = pkAff->lApplyValue;
        packet.elem.dwFlag        = pkAff->dwFlag;
        packet.elem.lDuration     = pkAff->lDuration;
        packet.elem.lSPCost       = pkAff->lSPCost;

        db_clientdesc->DBPacket(HEADER_GD_ADD_AFFECT, 0, &packet, sizeof(packet));
    }
}

EVENTINFO(load_affect_login_event_info)
{
    DWORD pid;
    DWORD count;
    char* data;

    load_affect_login_event_info()
        : pid(0)
        , count(0)
        , data(nullptr)
    {
    }
};

EVENTFUNC(load_affect_login_event)
{
    auto* info = dynamic_cast<load_affect_login_event_info*>( event->info );

    if (!info)
    {
        sys_err( "load_affect_login_event_info> <Factor> Null pointer" );
        return 0;
    }

    DWORD dwPID = info->pid;
    LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(dwPID);

    if (!ch)
    {
        M2_DELETE_ARRAY(info->data);
        return 0;
    }

    LPDESC d = ch->GetDesc();

    if (!d)
    {
        M2_DELETE_ARRAY(info->data);
        return 0;
    }

    // --- Client phase kontrolü ---
    if (d->IsPhase(PHASE_HANDSHAKE) ||
        d->IsPhase(PHASE_LOGIN) ||
        d->IsPhase(PHASE_SELECT) ||
        d->IsPhase(PHASE_DEAD) ||
        d->IsPhase(PHASE_LOADING))
    {
        return PASSES_PER_SEC(1);
    }

    if (d->IsPhase(PHASE_CLOSE))
    {
        M2_DELETE_ARRAY(info->data);
        return 0;
    }

    if (d->IsPhase(PHASE_GAME))
    {
        sys_log(1, "Affect Load by Event");
        ch->LoadAffect(info->count, reinterpret_cast<TPacketAffectElement*>(info->data));
        M2_DELETE_ARRAY(info->data);
        return 0;
    }

    // --- Geçersiz phase uyarısı ---
    sys_err("input_db.cpp:quest_login_event INVALID PHASE pid %d", ch->GetPlayerID());
    M2_DELETE_ARRAY(info->data);
    return 0;
}

void CHARACTER::LoadAffect(DWORD dwCount, TPacketAffectElement* pElements)
{
    m_bIsLoadedAffect = false;

    LPDESC d = GetDesc();
    if (!d)
        return;

    // --- Eğer client henüz PHASE_GAME'de değilse, event oluştur ---
    if (!d->IsPhase(PHASE_GAME))
    {
        if (test_server)
            sys_log(0, "LOAD_AFFECT: Creating Event %s count %d", GetName(), dwCount);

        auto* info = AllocEventInfo<load_affect_login_event_info>();
        info->pid    = GetPlayerID();
        info->count    = dwCount;

//        info->data    = M2_NEW char[sizeof(TPacketAffectElement) * dwCount];
//        thecore_memcpy(info->data, pElements, sizeof(TPacketAffectElement) * dwCount);

        // Smart pointer ile array yönetimi › memory leak riski sıfır
        std::unique_ptr<char[]> data(new char[sizeof(TPacketAffectElement) * dwCount]);
        thecore_memcpy(data.get(), pElements, sizeof(TPacketAffectElement) * dwCount);
        info->data = data.release(); // release › info sorumluluğu

        event_create(load_affect_login_event, info, PASSES_PER_SEC(1));
        return;
    }

    // --- PHASE_GAME --- Clear eski affectler ---
    ClearAffect(true);

    if (test_server)
        sys_log(0, "LOAD_AFFECT: %s count %d", GetName(), dwCount);

    // --- Affect flag ve hız snapshot ---
    TAffectFlag afOld = m_afAffectFlag;
    long lMovSpd = GetPoint(POINT_MOV_SPEED);
    long lAttSpd = GetPoint(POINT_ATT_SPEED);

    for (DWORD i = 0; i < dwCount; ++i, ++pElements)
    {
        if (pElements->dwType == SKILL_MUYEONG)
            continue;

        // --- Auto recovery item lock ---
        if (pElements->dwType == AFFECT_AUTO_HP_RECOVERY || pElements->dwType == AFFECT_AUTO_SP_RECOVERY)
        {
            LPITEM item = FindItemByID(pElements->dwFlag);
            if (!item)
                continue;

            item->Lock(true);
        }

        // --- ApplyOn kontrolü ---
        if (pElements->bApplyOn >= POINT_MAX_NUM)
        {
            sys_err("invalid affect data %s ApplyOn %u ApplyValue %d",
                    GetName(), pElements->bApplyOn, pElements->lApplyValue);
            continue;
        }

        if (test_server)
            sys_log(0, "Load Affect : Affect %s %d %d", GetName(), pElements->dwType, pElements->bApplyOn);

        // --- Affect oluştur ve listeye ekle ---
        CAffect* pkAff = CAffect::Acquire();
        m_list_pkAffect.emplace_back(pkAff);

        pkAff->dwType        = pElements->dwType;
        pkAff->bApplyOn        = pElements->bApplyOn;
        pkAff->lApplyValue    = pElements->lApplyValue;
        pkAff->dwFlag        = pElements->dwFlag;
        pkAff->lDuration    = pElements->lDuration;
        pkAff->lSPCost        = pElements->lSPCost;

        SendAffectAddPacket(d, pkAff);
        ComputeAffect(pkAff, true);
    }

    // --- Arena map check ---
    if (CArenaManager::instance().IsArenaMap(GetMapIndex()))
        RemoveGoodAffect();

    // --- Packet update ---
    if (afOld != m_afAffectFlag ||
        lMovSpd != GetPoint(POINT_MOV_SPEED) ||
        lAttSpd != GetPoint(POINT_ATT_SPEED))
    {
        UpdatePacket();
    }

    StartAffectEvent();
    m_bIsLoadedAffect = true;

    ComputePoints(); // @fixme156
    DragonSoul_Initialize();

    // --- HP/SP restore for alive characters ---
    if (!IsDead()) // @fixme118
    {
        PointChange(POINT_HP, GetMaxHP() - GetHP());
        PointChange(POINT_SP, GetMaxSP() - GetSP());
    }
}

bool CHARACTER::AddAffect(DWORD dwType, BYTE bApplyOn, long lApplyValue, DWORD dwFlag, long lDuration, long lSPCost, bool bOverride, bool IsCube )
{
    // CHAT_BLOCK
    if (dwType == AFFECT_BLOCK_CHAT && lDuration > 1)
    {
        ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¿î¿µÀÚ Á¦Á¦·Î äÆÃÀÌ ±İÁö µÇ¾ú½À´Ï´Ù."));
    }
    // END_OF_CHAT_BLOCK

    // --- Geçersiz duration kontrolü ---
    if (lDuration == 0)
    {
        sys_err("Character::AddAffect lDuration == 0 type %d", dwType);
        lDuration = 1;
    }

    CAffect* pkAff = nullptr;

    // --- Affect var mı kontrolü ---
    if (IsCube)
        pkAff = FindAffect(dwType, bApplyOn);
    else
        pkAff = FindAffect(dwType);

    // --- Stun flag işlemleri ---
    if (dwFlag == AFF_STUN)
    {
        if (m_posDest.x != GetX() || m_posDest.y != GetY())
        {
            m_posDest.x = m_posStart.x = GetX();
            m_posDest.y = m_posStart.y = GetY();
            battle_end(this);
            SyncPacket();
        }
    }

    // --- Mevcut affect override ---
    if (pkAff && bOverride)
    {
        ComputeAffect(pkAff, false);

        if (GetDesc())
            SendAffectRemovePacket(GetDesc(), GetPlayerID(), pkAff->dwType, pkAff->bApplyOn);
    }
    else
    {
        // --- Yeni affect oluştur ---
        pkAff = CAffect::Acquire();
        m_list_pkAffect.emplace_back(pkAff);
    }

    sys_log(1, "AddAffect %s type %d apply %d %d flag %u duration %d", GetName(), dwType, bApplyOn, lApplyValue, dwFlag, lDuration);
    sys_log(0, "AddAffect %s type %d apply %d %d flag %u duration %d", GetName(), dwType, bApplyOn, lApplyValue, dwFlag, lDuration);

    // --- Affect bilgilerini ayarla ---
    pkAff->dwType        = dwType;
    pkAff->bApplyOn        = bApplyOn;
    pkAff->lApplyValue    = lApplyValue;
    pkAff->dwFlag        = dwFlag;
    pkAff->lDuration    = lDuration;
    pkAff->lSPCost        = lSPCost;

    // --- Snapshot: hareket ve saldırı hızı ---
    WORD wMovSpd = GetPoint(POINT_MOV_SPEED);
    WORD wAttSpd = GetPoint(POINT_ATT_SPEED);

    ComputeAffect(pkAff, true);

    // --- Eğer affect flag değiştiyse packet update et ---
    if (pkAff->dwFlag || wMovSpd != GetPoint(POINT_MOV_SPEED) || wAttSpd != GetPoint(POINT_ATT_SPEED))
        UpdatePacket();

    StartAffectEvent();

    // --- PC ise client ve DB packet gönder ---
    if (IsPC())
    {
        SendAffectAddPacket(GetDesc(), pkAff);

        if (!IS_NO_SAVE_AFFECT(pkAff->dwType))
        {
            TPacketGDAddAffect p{};
            p.dwPID                = GetPlayerID();
            p.elem.dwType        = pkAff->dwType;
            p.elem.bApplyOn        = pkAff->bApplyOn;
            p.elem.lApplyValue    = pkAff->lApplyValue;
            p.elem.dwFlag        = pkAff->dwFlag;
            p.elem.lDuration    = pkAff->lDuration;
            p.elem.lSPCost        = pkAff->lSPCost;

            db_clientdesc->DBPacket(HEADER_GD_ADD_AFFECT, 0, &p, sizeof(p));
        }
    }

    return true;
}

void CHARACTER::RefreshAffect()
{
    for (CAffect* pkAff : m_list_pkAffect)
    {
        if (pkAff)
        {
            ComputeAffect(pkAff, true);
        }
    }
}

void CHARACTER::ComputeAffect(CAffect* pkAff, bool bAdd)
{
    if (!pkAff)
        return;

    // --- Guild skill affect kontrolü ---
    if (bAdd && pkAff->dwType >= GUILD_SKILL_START && pkAff->dwType <= GUILD_SKILL_END)
    {
        if (!GetGuild() || !GetGuild()->UnderAnyWar())
            return;
    }

    // --- Affect flag işlemleri ---
    if (pkAff->dwFlag)
    {
        if (bAdd)
            m_afAffectFlag.Set(pkAff->dwFlag);
        else
            m_afAffectFlag.Reset(pkAff->dwFlag);
    }

    // --- Stat değişimi ---
    PointChange(pkAff->bApplyOn, bAdd ? pkAff->lApplyValue : -pkAff->lApplyValue);

    // --- Muyeong özel durumu ---
    if (pkAff->dwType == SKILL_MUYEONG)
    {
        if (bAdd)
            StartMuyeongEvent();
        else
            StopMuyeongEvent();
    }
}

bool CHARACTER::RemoveAffect(CAffect * pkAff)
{
    if (!pkAff)
        return false;

    // AFFECT_BUF_FIX
    m_list_pkAffect.remove(pkAff);
    // END_OF_AFFECT_BUF_FIX

    ComputeAffect(pkAff, false);

    if (AFFECT_REVIVE_INVISIBLE != pkAff->dwType)
        ComputePoints();
    else  // @fixme110
        UpdatePacket();

    CheckMaximumPoints();

    if (test_server)
    {
        sys_log(0, "AFFECT_REMOVE: %s (flag %u apply: %u)",
            GetName(), pkAff->dwFlag, pkAff->bApplyOn);
    }

    // --- Client’a kaldırma bildir ---
    if (IsPC())
    {
        SendAffectRemovePacket(GetDesc(), GetPlayerID(), pkAff->dwType, pkAff->bApplyOn);
    }

    // --- Affect nesnesini serbest bırak ---
    CAffect::Release(pkAff);
    return true;
}

bool CHARACTER::RemoveAffect(DWORD dwType)
{
    // CHAT_BLOCK
    if (dwType == AFFECT_BLOCK_CHAT)
    {
        ChatPacket(CHAT_TYPE_INFO, LC_TEXT("äÆÃ ±İÁö°¡ Ç®·È½À´Ï´Ù."));
    }
    // END_OF_CHAT_BLOCK

    if (m_list_pkAffect.empty())
        return false;

    bool flag = false;
    bool flag_affect_revive_invisible = false;

    for (auto it = m_list_pkAffect.begin(); it != m_list_pkAffect.end(); )
    {
        CAffect* pkAff = *it;
        if (!pkAff)
        {
            it = m_list_pkAffect.erase(it);
            continue;
        }

        if (pkAff->dwType == dwType)
        {
            it = m_list_pkAffect.erase(it);

            ComputeAffect(pkAff, false);

            if (AFFECT_REVIVE_INVISIBLE != pkAff->dwType)
                flag_affect_revive_invisible = true;

            if (test_server)
            {
                sys_log(0, "AFFECT_REMOVE: %s (flag %u apply: %u)",
                    GetName(), pkAff->dwFlag, pkAff->bApplyOn);
            }

            if (IsPC())
            {
                SendAffectRemovePacket(GetDesc(), GetPlayerID(), pkAff->dwType, pkAff->bApplyOn);
            }

            CAffect::Release(pkAff);
            flag = true;
        }
        else
        {
            ++it;
        }
    }

    if (flag)
    {
        if (flag_affect_revive_invisible)
            ComputePoints();
        else
            UpdatePacket();

        CheckMaximumPoints();
    }

    return flag;
}
 
Son düzenleme:
Bilgi sahibi arkadaşlardan LoadAffect ve RemoveAffect fonksiyonlarıyla ilgili yorum bekliyorum.
 
Tam olarak hangi ihtiyaçtan dolayı bu şekilde bi düzenleme yapma gereksinimi duydunuz, ihtiyacınızı söylerseniz eğer ona göre ilerleme sağlayabiliriz.
 
Geri
Üst