OnurBoyla 1
OnurBoyla
noisiv 1
noisiv
Manwe Work 1
Manwe Work
farkmt2official 1
farkmt2official
mavzermete 1
mavzermete
dreamstone 1
dreamstone
Fethi Polat 1
Fethi Polat
Bvural41 1
Bvural41
Hikaye Ekle

[C++] CHARACTER::Sync Renewal (Cannot Find Tree FIX)

  • Konuyu başlatan Konuyu başlatan MT2Dev
  • Başlangıç tarihi Başlangıç tarihi
  • Cevaplar Cevaplar 7
  • Görüntüleme Görüntüleme 2K
  • Etiketler Etiketler
    c++ fix mt2dev
5.00 yıldız(lar) 2 Değerlendirme Değerlendirenler

HERAKLES Otomatik Avlı kalıcı sunucu. 19 Haziran'da açılıyor. Atius & Wizard güvencesiyle hemen kayıt ol, ön kayıt ödülleri aktif. HEMEN TIKLA!

GİRİŞ & PROBLEM

Merhaba, server src içerisindeki "CHARACTER::Sync" fonksiyonundaki meşhur "Cannot Find Tree" probleminin ve aynı fonksiyon içerisinde bulunan PC olmayan her şey için kullanılan "Dead();" bölümünün sebep olabileceği hataları çözeceğiz.

NEDEN ?

Mevcut olarak paylaşılan fix adı altındaki düzenlemelerin aslında hepsi eksik, bu sorunu kökünden çözmek için yeni bir düzenleme yaptım, bu sayede sorunu tamamen fixlemiş olacağız.


GÜNCELLEME - 18/10/2024

Mitachi'nin büyük katkısıyla "RewardlessDead" fonksiyonunu daha işlevsel ve güvenli bir şekilde yeniden yazdım.

SON GÜNCELLEME - 23/10/2024

Fonksiyonun (!new_tree) kısmının her şartta false dönmesine sebep olan bir yazım hatasını düzenledim, ayrıca gerekli yerlere tüm nullptr kontrollerini ve ekstra sys_err mesajlarını ekledim, mevcut sys_err mesajlarının içeriğini genişlettim, bu değişiklikler performans olarak hiçbir dezavantaj yaratmayacak ayrıca artık herhangi bir şekilde kötü kullanılma ihtimali de yok, lütfen son halini tekrar ekleyin.

ÇÖZÜM

Mevcut dead fonksiyonunun ödül mekanizmasını düzenlemek gibi detaylara girmeden basitçe yeni bir ölüm fonksiyonu yaratıp Sync içerisinde onu kullanacağız, sadece mob ve metinler için kullanılabilecek olan bu fonksiyonun temel amacı ölüm işleminden sonra drop vermemesi, başlayalım.


[CODE lang="cpp" title="char_battle.cpp"]// BULUNUR

struct FuncSetLastAttacked

// ÜSTÜNE eklenir

void CHARACTER::RewardlessDead() // DevFix 29
{
if (IsPC()) // This function only for mobs or stones, so if IsPC() has triggered this, redirect it regular Dead() function. - [MT2Dev Note] - 18/10/2024
{
sys_log (0, "<CHARACTER::RewardlessDead> Wrong Usage! It was a PC, redirect it to regular Dead()");
Dead(); // Just to prevent, not needed if you use it properly. - [Mitachi] - 18/10/2024
return;
}

if (IsDead())
{
return;
}

if (IsMonster() || IsStone()) // Dead is only possible when victim is mob or stone. - [MT2Dev Note] - 10/10/2024
{
m_dwKillerPID = 0; // Remove the killer to avoid quest triggers may in dead. - [Mitachi] - 18/10/2024
SET_BIT (m_pointsInstant.instant_flag, INSTANT_FLAG_NO_REWARD); // Set no reward. - [Mitachi] - 18/10/2024
SetPosition (POS_DEAD);
ClearAffect (true);
ClearSync();

if (m_pkStunEvent)
{
event_cancel (&m_pkStunEvent);
}

TPacketGCDead pack;
pack.header = HEADER_GC_DEAD;
pack.vid = m_vid;
PacketAround (&pack, sizeof (pack));
REMOVE_BIT (m_pointsInstant.instant_flag, INSTANT_FLAG_STUN);
sys_log (0, "Rewardless_DEAD: %s %p", GetName(), this);

// Create Dead event.. In the Dead event, for monsters, make them destroy after a few seconds. - [Ymir Dev Note]
if (m_pkDeadEvent)
{
event_cancel (&m_pkDeadEvent);
}

if (IsStone())
{
ClearStone();
}

if (GetDungeon())
{
GetDungeon()->DeadCharacter (this);
}

SCharDeadEventInfo* pEventInfo = AllocEventInfo<SCharDeadEventInfo>();
pEventInfo->isPC = false;
pEventInfo->dwID = this->GetVID();
m_pkDeadEvent = event_create (dead_event, pEventInfo, PASSES_PER_SEC (0));
sys_log (0, "Rewardless_DEAD_EVENT_CREATE: %s %p %p", GetName(), this, get_pointer (m_pkDeadEvent));
}
}[/CODE]

[CODE lang="cpp" title="char.cpp"]// BULUNUR;

bool CHARACTER::Sync (long x, long y)

// FONKSİYON KOMPLE DEĞİŞTİRİLİR;

// DevFix 29 - Necessary arrangement for scenarios where sync is not possible. - [MT2Dev Note] - 01/04/2024
// Moves to the specified x, y position regardless. - [Ymir Dev Note]
bool CHARACTER::Sync (long x, long y)
{
LPSECTREE current_tree = GetSectree(); // For a better performance, call it only once.. - [MT2Dev Note]
if (!current_tree)
{
sys_err ("<CHARACTER::Sync> Sectree is NULL!");
return false;
}

if (IsPC() && IsDead()) // DevFix 27 - Dead players not needed sync.. - [MT2Dev Note] - 01/04/2024
{
return false;
}

LPSECTREE new_tree = SECTREE_MANAGER::instance().Get (GetMapIndex(), x, y);
if (!new_tree)
{
if (GetDesc())
{
sys_err ("No Tree: (x: %ld) (y: %ld) (Name: %s) (Map: %d)", x, y, GetName(), GetMapIndex()); // Added map index. - [MT2Dev Note] - 23/10/2024
x = GetX();
y = GetY();
new_tree = current_tree; // If there is no new tree, just use the old one. - [MT2Dev Note]
if (!new_tree)
{
sys_err ("[CRITICAL!!] - No Tree: (x: %ld) (y: %ld) (Name: %s) (Map: %d)", x, y, GetName(), GetMapIndex()); // Added map index. - [MT2Dev Note] - 23/10/2024
GetDesc()->SetPhase (PHASE_CLOSE);
return false; // Set the new_tree, call that a "fix" and forget one f**in line that cause return it false, hi there it's MT2Dev -_-
}
}
else
{
if (IsMonster() || IsStone()) // Dead is only possible when victim is mob or stone. - [MT2Dev Note] - 10/10/2024
{
sys_err ("[MOB or STONE]No Tree: (x: %ld) (y: %ld) (Map: %d)", x, y, GetMapIndex());
RewardlessDead(); // In this case, we don't want any reward so this is new function for it. - [MT2Dev Note] - 10/10/2024
return false;
}
else
{
sys_err ("[POTENTIAL HACK!]No Tree: (x: %ld) (y: %ld) (Map: %d)", x, y, GetMapIndex());
return false;
}
}
}

SetRotationToXY (x, y);
SetXYZ (x, y, 0);

// Under that, you will see some kind a unnecesary nullptr controls, this ones for ensure everything is correct.
// This ones will not chance anything about performance in new compilers, so that ones don't hurt anyone i guess. - [MT2Dev Note] - 23/10/2024
if (GetDungeon())
{
if (new_tree)
{
// Dungeon event attribute change. - [Ymir Dev Note]
int iLastEventAttr = m_iEventAttr;
m_iEventAttr = new_tree->GetEventAttribute (x, y);
if (m_iEventAttr != iLastEventAttr)
{
if (GetParty())
{
quest::CQuestManager::instance().AttrOut (GetParty()->GetLeaderPID(), this, iLastEventAttr);
quest::CQuestManager::instance().AttrIn (GetParty()->GetLeaderPID(), this, m_iEventAttr);
}
else
{
quest::CQuestManager::instance().AttrOut (GetPlayerID(), this, iLastEventAttr);
quest::CQuestManager::instance().AttrIn (GetPlayerID(), this, m_iEventAttr);
}
}
}
else
{
sys_err ("[POTENTIAL HACK!] Dungeon - There is no new tree!");
return false;
}
}

if (current_tree != new_tree)
{
if (!IsNPC())
{
if (current_tree && new_tree)
{
SECTREEID id = new_tree->GetID();
SECTREEID old_id = current_tree->GetID();
const float fDist = DISTANCE_SQRT (id.coord.x - old_id.coord.x, id.coord.y - old_id.coord.y);
sys_log (0, "SECTREE DIFFER: %s %dx%d was %dx%d dist %.1fm", GetName(), id.coord.x, id.coord.y, old_id.coord.x, old_id.coord.y, fDist); // DevFix 30
}
else
{
sys_err ("[POTENTIAL HACK!] There is no current tree or new tree!");
return false;
}
}

if (new_tree)
{
new_tree->InsertEntity (this);
}
else
{
sys_err ("[POTENTIAL HACK!] InsertEntity NOT possible because there is no new tree!");
return false;
}
}

return true;
}[/CODE]

[CODE lang="cpp" title="char.h"]// BULUNUR;

void Dead (LPCHARACTER pkKiller = NULL, bool bImmediateDead = false);

// Altına eklenir;

void RewardlessDead(); // DevFix 29[/CODE]

Sevgiler, MT2Dev.
 
Son düzenleme:

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)

Geri
Üst