IkarusV2 Pazarı olduğu yere açması için küçük değişiklik

  • Konuyu açan Konuyu açan ULITRI
  • Açılış Tarihi Açılış Tarihi
  • Yanıt Yanıt 15
  • Gösterim Gösterim 412

ULITRI

MT Üye
MT Üye
Mesaj
164
Çözümler
9
Beğeni
62
Puan
489
Ticaret Puanı
0
Birkaç seferdir hem burada hem farklı yerlerde görüyordum bu soruyu. Çok daha basit ve iyi kodlarla bu çözülebilir belki bilmiyorum. Ben bu düzenlemeyi yaparak güncellemiş oldum. Umarım birilerinin işine yarar.

Linkleri görebilmek için giriş yap veya kayıt ol.


Farklı core ve haritalarla ilgili problem giderildi. Direkt olarak dosyayı bırakıyorum. Değişiklikleri öğrenmek isteyen karşılaştırma yaparak bakabilir. Kodlarla uğraşmamanız için bu şekilde veriyorum.

Pazar mesafe düzenlemesi forumda paylaşıldığı için dosya üzerine ekleme yapmadım. İsteyen bunları uygulasın.
 

Dosya Eklentileri

Son düzenleme:
Aynı konumda üst üste spawn edilmesini engelleme

Kod:
Genişlet Daralt Kopyala
bool CShopManager::RecvShopRestoreDurationDBPacket(DWORD dwOwnerPID)
{
    CShop* pShop = GetShopByOwnerID(dwOwnerPID);
    if (!pShop)
    {
        sys_err("RecvShopRestoreDurationDBPacket: No shop found for owner PID %u", dwOwnerPID);
        return false;
    }

#ifdef EXTEND_IKASHOP_ULTIMATE
    DWORD dwOldDuration = pShop->GetDuration();
    pShop->ChangeDuration(OFFLINESHOP_DURATION_MAX_MINUTES);
#else
    pShop->SetDuration(OFFLINESHOP_DURATION_MAX_MINUTES);
    pShop->RefreshToOwner();
#endif

#ifdef EXTEND_IKASHOP_ULTIMATE
    if (dwOldDuration != 0)
        return true;
#endif

    DestroyShopEntity(pShop);

    LPCHARACTER pOwnerChar = CHARACTER_MANAGER::instance().FindByPID(pShop->GetOwnerPID());
    if (!pOwnerChar)
    {
        sys_err("RecvShopRestoreDurationDBPacket: Owner character not found for PID %u", pShop->GetOwnerPID());
        return false;
    }

    if (!pOwnerChar->GetIkarusShop())
    {
        sys_log(1, "RecvShopRestoreDurationDBPacket: Owner PID %u does not have active Ikarus shop", pShop->GetOwnerPID());
        return false;
    }

    long mapIndex = pOwnerChar->GetMapIndex();
    long posX = pOwnerChar->GetX();
    long posY = pOwnerChar->GetY();

    if (IsShopAlreadySpawnedAt(mapIndex, posX, posY, pShop->GetOwnerPID()))
    {
        sys_err("RecvShopRestoreDurationDBPacket: Shop for PID %u cannot be spawned — location occupied", dwOwnerPID);
        return false;
    }

    TShopSpawn spawnData;
    spawnData.map = mapIndex;
    spawnData.x = posX;
    spawnData.y = posY;
    pShop->SetSpawn(spawnData);

    CreateShopEntity(pShop);

    sys_log(1, "RecvShopRestoreDurationDBPacket: Shop for owner PID %u restored and spawned at map %d (%d, %d)",
        pShop->GetOwnerPID(), spawnData.map, spawnData.x, spawnData.y);

    return true;
}
 
Aynı konumda üst üste spawn edilmesini engelleme

Kod:
Genişlet Daralt Kopyala
bool CShopManager::RecvShopRestoreDurationDBPacket(DWORD dwOwnerPID)
{
    CShop* pShop = GetShopByOwnerID(dwOwnerPID);
    if (!pShop)
    {
        sys_err("RecvShopRestoreDurationDBPacket: No shop found for owner PID %u", dwOwnerPID);
        return false;
    }

#ifdef EXTEND_IKASHOP_ULTIMATE
    DWORD dwOldDuration = pShop->GetDuration();
    pShop->ChangeDuration(OFFLINESHOP_DURATION_MAX_MINUTES);
#else
    pShop->SetDuration(OFFLINESHOP_DURATION_MAX_MINUTES);
    pShop->RefreshToOwner();
#endif

#ifdef EXTEND_IKASHOP_ULTIMATE
    if (dwOldDuration != 0)
        return true;
#endif

    DestroyShopEntity(pShop);

    LPCHARACTER pOwnerChar = CHARACTER_MANAGER::instance().FindByPID(pShop->GetOwnerPID());
    if (!pOwnerChar)
    {
        sys_err("RecvShopRestoreDurationDBPacket: Owner character not found for PID %u", pShop->GetOwnerPID());
        return false;
    }

    if (!pOwnerChar->GetIkarusShop())
    {
        sys_log(1, "RecvShopRestoreDurationDBPacket: Owner PID %u does not have active Ikarus shop", pShop->GetOwnerPID());
        return false;
    }

    long mapIndex = pOwnerChar->GetMapIndex();
    long posX = pOwnerChar->GetX();
    long posY = pOwnerChar->GetY();

    if (IsShopAlreadySpawnedAt(mapIndex, posX, posY, pShop->GetOwnerPID()))
    {
        sys_err("RecvShopRestoreDurationDBPacket: Shop for PID %u cannot be spawned — location occupied", dwOwnerPID);
        return false;
    }

    TShopSpawn spawnData;
    spawnData.map = mapIndex;
    spawnData.x = posX;
    spawnData.y = posY;
    pShop->SetSpawn(spawnData);

    CreateShopEntity(pShop);

    sys_log(1, "RecvShopRestoreDurationDBPacket: Shop for owner PID %u restored and spawned at map %d (%d, %d)",
        pShop->GetOwnerPID(), spawnData.map, spawnData.x, spawnData.y);

    return true;
}
Ekleme için teşekkürler
 
IsShopAlreadySpawnedAt

hata veriyor
 

Dosya Eklentileri

  • Ekran görüntüsü 2025-05-16 210522.webp
    Ekran görüntüsü 2025-05-16 210522.webp
    18,2 KB · Gösterim: 17
IsShopAlreadySpawnedAt

hata veriyor
IsShopAlreadySpawnedAt eksik olduğu için hata vermiş. Bu şekilde düzenleme yapıp dener misiniz ?

ikarus_shop_manager.cpp İçerisinde Bul:
Genişlet Daralt Kopyala
bool CShopManager::CheckSearchCooldown(DWORD pid)

Bulduğun bloğun altına ekle:
Genişlet Daralt Kopyala
    bool CShopManager::IsShopAlreadySpawnedAt(long mapIndex, long posX, long posY, DWORD excludeOwnerPID)
    {
        for (const auto& [pid, shop] : m_mapShops)
        {
            if (pid == excludeOwnerPID)
                continue;

            const auto& spawn = shop->GetSpawn();
            if (spawn.map == mapIndex && spawn.x == posX && spawn.y == posY)
                return true;
        }
        return false;
    }

ikarus_shop_manager.h İçerisinde Bul:
Genişlet Daralt Kopyala
#ifdef EXTEND_IKASHOP_ULTIMATE
        long long GetAveragePrice(DWORD vnum, DWORD count);
        long long GetNormalizedPrice(DWORD vnum, DWORD count, long long price);

Makronun Dışına Ekle:
Genişlet Daralt Kopyala
        bool IsShopAlreadySpawnedAt(long mapIndex, long posX, long posY, DWORD excludeOwnerPID);
 
Farklı core dahki bir haritada mağaza düzenleme bozuluyor bu kodla. Mağazanız kapalı gibi gözüküyor.
 
Farklı core dahki bir haritada mağaza düzenleme bozuluyor bu kodla. Mağazanız kapalı gibi gözüküyor.
Bloğu bu şekilde güncelleyebilirsin. Harita kontrolü pazar düzenlemesinde de kalmış. Sadece yeni pazar kurma durumuna çekildi.

C++:
Genişlet Daralt Kopyala
bool CShopManager::RecvShopRestoreDurationDBPacket(DWORD owner)
{
    if(auto shop = GetShopByOwnerID(owner))
    {
        LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(shop->GetOwnerPID());
        if (ch && ch->GetIkarusShop())
        {
            if (shop->GetDuration() == 0)
            {
                if (!ALLOWED_SPAWN_MAPS.contains(ch->GetMapIndex()))
                {
                    ch->ChatPacket(CHAT_TYPE_INFO, "[IkarusShop] Bu haritada pazar kuramazsiniz.");
                    return false;
                }

                if (IsShopAlreadySpawnedAt(ch->GetMapIndex(), ch->GetX(), ch->GetY(), shop->GetOwnerPID()))
                {
                    ch->ChatPacket(CHAT_TYPE_INFO, "[IkarusShop] Bu konumda zaten bir pazar var.");
                    return false;
                }
            }

#ifdef EXTEND_IKASHOP_ULTIMATE
            auto oldDuration = shop->GetDuration();
            shop->ChangeDuration(OFFLINESHOP_DURATION_MAX_MINUTES);
#else
            shop->SetDuration(OFFLINESHOP_DURATION_MAX_MINUTES);
            shop->RefreshToOwner();
#endif

#ifdef EXTEND_IKASHOP_ULTIMATE
            if(oldDuration == 0)
#endif
            {
                DestroyShopEntity(shop);
                TShopSpawn spawn;
                spawn.map = ch->GetMapIndex();
                spawn.x = ch->GetX();
                spawn.y = ch->GetY();

                shop->SetSpawn(spawn);
                CreateShopEntity(shop);
            }
        }
    }

    return true;
}
 
Bloğu bu şekilde güncelleyebilirsin. Harita kontrolü pazar düzenlemesinde de kalmış. Sadece yeni pazar kurma durumuna çekildi.

C++:
Genişlet Daralt Kopyala
bool CShopManager::RecvShopRestoreDurationDBPacket(DWORD owner)
{
    if(auto shop = GetShopByOwnerID(owner))
    {
        LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(shop->GetOwnerPID());
        if (ch && ch->GetIkarusShop())
        {
            if (shop->GetDuration() == 0)
            {
                if (!ALLOWED_SPAWN_MAPS.contains(ch->GetMapIndex()))
                {
                    ch->ChatPacket(CHAT_TYPE_INFO, "[IkarusShop] Bu haritada pazar kuramazsiniz.");
                    return false;
                }

                if (IsShopAlreadySpawnedAt(ch->GetMapIndex(), ch->GetX(), ch->GetY(), shop->GetOwnerPID()))
                {
                    ch->ChatPacket(CHAT_TYPE_INFO, "[IkarusShop] Bu konumda zaten bir pazar var.");
                    return false;
                }
            }

#ifdef EXTEND_IKASHOP_ULTIMATE
            auto oldDuration = shop->GetDuration();
            shop->ChangeDuration(OFFLINESHOP_DURATION_MAX_MINUTES);
#else
            shop->SetDuration(OFFLINESHOP_DURATION_MAX_MINUTES);
            shop->RefreshToOwner();
#endif

#ifdef EXTEND_IKASHOP_ULTIMATE
            if(oldDuration == 0)
#endif
            {
                DestroyShopEntity(shop);
                TShopSpawn spawn;
                spawn.map = ch->GetMapIndex();
                spawn.x = ch->GetX();
                spawn.y = ch->GetY();

                shop->SetSpawn(spawn);
                CreateShopEntity(shop);
            }
        }
    }

    return true;
}
Maalesef sorun hala aynı. Çözülmedi.
 
@random Konuyu güncelledim. Direkt olarak dosyayı alıp kullanabilirsin hocam. Pazar mesafe şeyi uygulanmamış halidir bilgin olsun.
 
@random Konuyu güncelledim. Direkt olarak dosyayı alıp kullanabilirsin hocam. Pazar mesafe şeyi uygulanmamış halidir bilgin olsun.
C++:
Genişlet Daralt Kopyala
ikarus_shop_manager.cpp:1875:55: error: too many arguments to function call, expected single argument 'owner', have 2 arguments
                        SendShopRestoreDurationDBPacket(ch->GetPlayerID(), spawn);
                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                    ^~~~~
./ikarus_shop_manager.h:250:13: note: 'SendShopRestoreDurationDBPacket' declared here
/*db*/  void SendShopRestoreDurationDBPacket(DWORD owner);
             ^
ikarus_shop_manager.cpp:3664:21: error: out-of-line definition of 'SendShopRestoreDurationDBPacket' does not match any declaration in 'ikashop::CShopManager'
        void CShopManager::SendShopRestoreDurationDBPacket(DWORD owner, const TShopSpawn& spawn)
                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 errors generated.

:)
 
Son düzenleme:
C++:
Genişlet Daralt Kopyala
ikarus_shop_manager.cpp:1875:55: error: too many arguments to function call, expected single argument 'owner', have 2 arguments
                        SendShopRestoreDurationDBPacket(ch->GetPlayerID(), spawn);
                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                    ^~~~~
./ikarus_shop_manager.h:250:13: note: 'SendShopRestoreDurationDBPacket' declared here
/*db*/  void SendShopRestoreDurationDBPacket(DWORD owner);
             ^
ikarus_shop_manager.cpp:3664:21: error: out-of-line definition of 'SendShopRestoreDurationDBPacket' does not match any declaration in 'ikashop::CShopManager'
        void CShopManager::SendShopRestoreDurationDBPacket(DWORD owner, const TShopSpawn& spawn)
                           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 errors generated.

:)
Yanlış klasör içerisindeki dosyaları rarlamışım hocam düzelttim atmadan önce de test ettim build alıyor.
 
sys_err("RecvShopRestoreDurationDBPacket: No shop found for owner PID %u", dwOwnerPID);

IsShopAlreadySpawnedAt eksik olduğu için hata vermiş. Bu şekilde düzenleme yapıp dener misiniz ?

ikarus_shop_manager.cpp İçerisinde Bul:
Genişlet Daralt Kopyala
bool CShopManager::CheckSearchCooldown(DWORD pid)

Bulduğun bloğun altına ekle:
Genişlet Daralt Kopyala
    bool CShopManager::IsShopAlreadySpawnedAt(long mapIndex, long posX, long posY, DWORD excludeOwnerPID)
    {
        for (const auto& [pid, shop] : m_mapShops)
        {
            if (pid == excludeOwnerPID)
                continue;

            const auto& spawn = shop->GetSpawn();
            if (spawn.map == mapIndex && spawn.x == posX && spawn.y == posY)
                return true;
        }
        return false;
    }

ikarus_shop_manager.h İçerisinde Bul:
Genişlet Daralt Kopyala
#ifdef EXTEND_IKASHOP_ULTIMATE
        long long GetAveragePrice(DWORD vnum, DWORD count);
        long long GetNormalizedPrice(DWORD vnum, DWORD count, long long price);

Makronun Dışına Ekle:
Genişlet Daralt Kopyala
        bool IsShopAlreadySpawnedAt(long mapIndex, long posX, long posY, DWORD excludeOwnerPID);

böyle daha iyi sanki


C++:
Genişlet Daralt Kopyala
    bool CShopManager::IsShopAlreadySpawnedAt(long mapIndex, long posX, long posY, DWORD excludeOwnerPID)
    {
        constexpr int MIN_DISTANCE_SQUARED = 1500;

        for (const auto& [pid, shop] : m_mapShops)
        {
            if (pid == excludeOwnerPID)
                continue;

            const auto& spawn = shop->GetSpawn();

            if (spawn.map != mapIndex)
                continue;

            long dx = spawn.x - posX;
            long dy = spawn.y - posY;
            long distanceSquared = dx * dx + dy * dy;

            if (distanceSquared <= MIN_DISTANCE_SQUARED)
                return true;
        }
        return false;
    }

bu da pazar yeri değiştirirken kontrol ettirmek için


C++:
Genişlet Daralt Kopyala
    bool CShopManager::RecvMoveShopEntityClientPacket(LPCHARACTER ch)
    {
        // validating character pointer
        if (!ch)
            return false;

        if (!ch->GetIkarusShop() || ch->GetIkarusShop()->GetDuration() == 0)
        {
            SendPopupMessage(ch, "IKASHOP_SERVER_POPUP_MESSAGE_CANNOT_MOVE_CLOSED_SHOP");
            return false;
        }

        if (!ch->IkarusShopFloodCheck(SHOP_ACTION_WEIGHT_MOVE_SHOP))
            return false;

        if (!ALLOWED_SPAWN_MAPS.contains(ch->GetMapIndex()))
        {
            SendPopupMessage(ch, "IKASHOP_SERVER_POPUP_MESSAGE_CANNOT_CREATE_SHOP_ON_WRONG_PLACE");
            return false;
        }

        if (ch->GetGold() < 100000)
            return false;

        ch->PointChange(POINT_GOLD, -100000);

        TShopSpawn spawn{};
        spawn.map = ch->GetMapIndex();
        spawn.x = ch->GetX();
        spawn.y = ch->GetY();

        // check pos
        if (IsShopAlreadySpawnedAt(spawn.map, spawn.x, spawn.y, ch->GetPlayerID()))
        {
            SendPopupMessage(ch, "IKASHOP_SERVER_POPUP_MESSAGE_TOO_CLOSE_TO_ANOTHER_SHOP");
            return false;
        }

        // encoding packets to db
        TPacketGDNewIkarusShop pack{};
        pack.bSubHeader = ikashop::SUBHEADER_GD_MOVE_SHOP_ENTITY;

        TSubPacketGDMoveShopEntity subpack{};
        subpack.owner = ch->GetPlayerID();
        subpack.spawn = spawn;
       
        TEMP_BUFFER buffer;
        buffer.write(pack);
        buffer.write(subpack);

        db_clientdesc->DBPacket(HEADER_GD_NEW_OFFLINESHOP, 0, buffer.read_peek(), buffer.size());
        return true;
    }
 
Son düzenleme:
böyle daha iyi sanki


C++:
Genişlet Daralt Kopyala
    bool CShopManager::IsShopAlreadySpawnedAt(long mapIndex, long posX, long posY, DWORD excludeOwnerPID)
    {
        constexpr int MIN_DISTANCE_SQUARED = 500;

        for (const auto& [pid, shop] : m_mapShops)
        {
            if (pid == excludeOwnerPID)
                continue;

            const auto& spawn = shop->GetSpawn();

            if (spawn.map != mapIndex)
                continue;

            long dx = spawn.x - posX;
            long dy = spawn.y - posY;
            long distanceSquared = dx * dx + dy * dy;

            if (distanceSquared <= MIN_DISTANCE_SQUARED)
                return true;
        }
        return false;
    }
O Düzenlemede problem vardı hocam son güncel halini ana konuya direkt olarak rar içerisinde dosya olarak verdim
 
Geri
Üst