Ayyıldız2 | 2008 TR Yapısı • 1-99 Orta Emek Destan • Oto Avsız • 10 Temmuz 21:00 HEMEN TIKLA!
Merhaba,
Sistem aslında doğru kullanılırsa mükemmel bir fikir içeriyor.
Mantık çok basit, eğer belirlediğiniz NPC'ye doğru yaklaşırsanız, oto potlarınız otomatik olarak dolmaya başlıyor.
Aşağıdaki videodaki gibi. Silah satıcısına karakter yaklaştığında oto potun doluşuna bakın. Bunu wslik olur, arena alanlarında olur benzinlik NPC si gibi bir NPC ile potları otomatik doldurma imkanı sağlayarak oyuncularınıza çok güzel pazarlayabilirsiniz.
DİKKATLE OKU!
Eğer GET NPC LOCATION BY VNUM sistemi sizde ekli değilse, önce onu eklemeniz gerek!!!!
Burada paylaştım : https://forum.turkmmo.com/konu/3902...by-vnum-npcnin-haritadaki-koordinatini-bulun/
Service.h / CommonDefines.h
game/sectree_manager.h
game/sectree_manager.cpp
game/unique_item.h
game/char.h
game/char.cpp
game/item.h
game/item.cpp
game/input_login.cpp
İşlem bu kadar.
Sistem aslında doğru kullanılırsa mükemmel bir fikir içeriyor.
Mantık çok basit, eğer belirlediğiniz NPC'ye doğru yaklaşırsanız, oto potlarınız otomatik olarak dolmaya başlıyor.
Aşağıdaki videodaki gibi. Silah satıcısına karakter yaklaştığında oto potun doluşuna bakın. Bunu wslik olur, arena alanlarında olur benzinlik NPC si gibi bir NPC ile potları otomatik doldurma imkanı sağlayarak oyuncularınıza çok güzel pazarlayabilirsiniz.
DİKKATLE OKU!
Eğer GET NPC LOCATION BY VNUM sistemi sizde ekli değilse, önce onu eklemeniz gerek!!!!
Burada paylaştım : https://forum.turkmmo.com/konu/3902...by-vnum-npcnin-haritadaki-koordinatini-bulun/
Service.h / CommonDefines.h
Kod:
//ekle:
#define ENABLE_POTION_REFILL
game/sectree_manager.h
Kod:
//Bul:
bool SaveAttributeToImage(int lMapIndex, const char * c_pszFileName, LPSECTREE_MAP pMapSrc = NULL);
//Ekle:
#ifdef ENABLE_POTION_REFILL
bool GetNpcLocationByVnum(long lMapIndex, DWORD npcVnum, std::vector<std::pair<long, long>>& positions);
#endif
game/sectree_manager.cpp
Kod:
//Fonkisyonu bul:
bool SECTREE_MANAGER::SaveAttributeToImage(int lMapIndex, const char * c_pszFileName, LPSECTREE_MAP pMapSrc)
//Fonkisyonun bitişini takip et ve ekle:
#ifdef ENABLE_POTION_REFILL
bool SECTREE_MANAGER::GetNpcLocationByVnum(long lMapIndex, DWORD npcVnum, std::vector<std::pair<long, long>>& positions)
{
LPSECTREE_MAP sectree = SECTREE_MANAGER::instance().GetMap(lMapIndex);
if (sectree != nullptr)
{
struct FFindNPCByVnum
{
DWORD specifiedVnum;
std::vector<std::pair<long, long>>& npcPositions;
FFindNPCByVnum(DWORD vnum, std::vector<std::pair<long, long>>& positions)
: specifiedVnum(vnum), npcPositions(positions) {}
void operator()(LPENTITY ent)
{
if (ent->IsType(ENTITY_CHARACTER))
{
LPCHARACTER pChar = static_cast<LPCHARACTER>(ent);
if (pChar->IsNPC() && pChar->GetMobTable().dwVnum == specifiedVnum)
{
npcPositions.emplace_back(pChar->GetX(), pChar->GetY());
}
}
}
};
std::vector<std::pair<long, long>> npcPositions;
FFindNPCByVnum finder(npcVnum, npcPositions);
sectree->for_each(finder);
positions.insert(positions.end(), npcPositions.begin(), npcPositions.end());
return !positions.empty();
}
return false;
}
#endif
game/unique_item.h
Kod:
/!!!ÖNEMLİ!!!
//Enum'u ihtiyaçlarınıza göre ayarlayın, ör. Farklı otomatik iksir vnum'ları kullanıyorsanız.
//AUTO_POTION_MAX_NUM, kullandığınız otomatik iksirlerin sayısına eşit olmalıdır.
//!!!ÖNEMLİ!!!
//Dosyanın sonuna ekle:
#ifdef ENABLE_POTION_REFILL
enum EAutoPotion
{
ITEM_AUTO_HP_POTION_1 = ITEM_AUTO_HP_RECOVERY_S,
ITEM_AUTO_HP_POTION_2 = ITEM_AUTO_HP_RECOVERY_M,
ITEM_AUTO_HP_POTION_3 = ITEM_AUTO_HP_RECOVERY_L,
ITEM_AUTO_HP_POTION_4 = ITEM_AUTO_HP_RECOVERY_X,
ITEM_AUTO_SP_POTION_1 = ITEM_AUTO_SP_RECOVERY_S,
ITEM_AUTO_SP_POTION_2 = ITEM_AUTO_SP_RECOVERY_M,
ITEM_AUTO_SP_POTION_3 = ITEM_AUTO_SP_RECOVERY_L,
ITEM_AUTO_SP_POTION_4 = ITEM_AUTO_SP_RECOVERY_X,
AUTO_POTION_MAX_NUM = 8,
};
#endif
game/char.h
Kod:
//bul:
BYTE m_bChatCounter;
//ekle:
#ifdef ENABLE_POTION_REFILL
bool m_bIsNearRefillNPC;
LPEVENT m_refillPotionEvent;
void PotionRefillMgt();
#endif
//bul:
DWORD GetLastAttackTime() const { return m_dwLastAttackTime; }
//ekle:
#ifdef ENABLE_POTION_REFILL
void PotionRefillMgt();
void SetNearRefillNPC(bool bIsNear);
bool GetNearRefillNPC() const { return m_bIsNearRefillNPC; }
#endif
game/char.cpp
Kod:
//bool CHARACTER::Move(long x, long y): fonksiyonu içinde bul
OnMove();
return Sync(x, y);
//bulduğun fonksiyonun üstüne ekle:
#ifdef ENABLE_POTION_REFILL
PotionRefillMgt();
#endif
//fonksiyonun içinde void CHARACTER::Disconnect(const char * c_pszReason): aşağıdaki kodu bul
marriage::CManager::instance().Logout(this);
//üstüne ekle
#ifdef ENABLE_POTION_REFILL
if (GetNearRefillNPC())
{
SetNearRefillNPC(false);
}
#endif
//fonksiyonu bul:
void CHARACTER::SendMovePacket(BYTE bFunc, BYTE bArg, DWORD x, DWORD y, DWORD dwDuration, DWORD dwTime, int iRot)
//fonksiyon bittikten sonra altına yeni fonksiyon olarak ekleyin:
#ifdef ENABLE_POTION_REFILL
void CHARACTER::PotionRefillMgt()
{
if (IsPC())
{
DWORD dwVnum = 9001; //Change NPC vnum here
float fArea = 1500.0f; //Change area around NPC here
std::vector<std::pair<long, long>> positions;
if (SECTREE_MANAGER::Instance().GetNpcLocationByVnum(GetMapIndex(), dwVnum, positions))
{
if (!positions.empty())
{
if (!GetNearRefillNPC())
{
for (const auto& position : positions)
{
if (DISTANCE_APPROX(position.first - GetX(), position.second - GetY()) <= fArea)
{
ChatPacket(CHAT_TYPE_INFO, "Potions are refilling...");
SetNearRefillNPC(true);
break;
}
}
}
else
{
for (const auto& position : positions)
{
if (DISTANCE_APPROX(position.first - GetX(), position.second - GetY()) > fArea)
{
ChatPacket(CHAT_TYPE_INFO, "Refilling of potions stopped");
SetNearRefillNPC(false);
break;
}
}
}
}
}
}
}
void CHARACTER::PotionRefillMgt()
{
if (IsPC())
{
DWORD dwVnum = 9001; //Change NPC vnum here
float fArea = 1500.0f; //Change area around NPC here
std::vector<std::pair<long, long>> positions;
if (SECTREE_MANAGER::Instance().GetNpcLocationByVnum(GetMapIndex(), dwVnum, positions))
{
if (!positions.empty())
{
if (!GetNearRefillNPC())
{
for (const auto& position : positions)
{
if (DISTANCE_APPROX(position.first - GetX(), position.second - GetY()) <= fArea)
{
ChatPacket(CHAT_TYPE_INFO, "Potions are refilling...");
SetNearRefillNPC(true);
break;
}
}
}
else
{
for (const auto& position : positions)
{
if (DISTANCE_APPROX(position.first - GetX(), position.second - GetY()) > fArea)
{
ChatPacket(CHAT_TYPE_INFO, "Refilling of potions stopped");
SetNearRefillNPC(false);
break;
}
}
}
}
}
}
}
void CHARACTER::SetNearRefillNPC(bool bIsNear)
{
m_bIsNearRefillNPC = bIsNear;
std::vector<LPITEM> ownedPotions;
LPITEM item = nullptr;
for (int i = 0; i < AUTO_POTION_MAX_NUM; i++)
{
switch (i)
{
case 0:
item = FindSpecifyItem(ITEM_AUTO_HP_POTION_1);
break;
case 1:
item = FindSpecifyItem(ITEM_AUTO_HP_POTION_2);
break;
case 2:
item = FindSpecifyItem(ITEM_AUTO_HP_POTION_3);
break;
case 3:
item = FindSpecifyItem(ITEM_AUTO_HP_POTION_4);
break;
case 4:
item = FindSpecifyItem(ITEM_AUTO_SP_POTION_1);
break;
case 5:
item = FindSpecifyItem(ITEM_AUTO_SP_POTION_2);
break;
case 6:
item = FindSpecifyItem(ITEM_AUTO_SP_POTION_3);
break;
case 7:
item = FindSpecifyItem(ITEM_AUTO_SP_POTION_4);
break;
default:
break;
}
if (item)
ownedPotions.push_back(item);
}
for (auto &potion : ownedPotions)
{
if (bIsNear)
potion->StartPotionRecoveryEvent();
else
potion->StopPotionRecoveryEvent();
}
}
#endif
// void CHARACTER::Disconnect(const char * c_pszReason): fonksiyonu içinde bul
marriage::CManager::instance().Logout(this);
//Add üstüne ekle:
#ifdef ENABLE_POTION_REFILL
if (GetNearRefillNPC())
{
SetNearRefillNPC(false);
}
#endif
game/item.h
Kod:
//bul:
void StartDestroyEvent(int iSec=300);
//ekle:
#ifdef ENABLE_POTION_REFILL
void SetPotionRecoveryEvent(LPEVENT pkEvent);
void StartPotionRecoveryEvent();
void StopPotionRecoveryEvent();
#endif
//bul:
LPEVENT m_pkOwnershipEvent;
//ekle:
#ifdef ENABLE_POTION_REFILL
LPEVENT m_pkPotionRecoveryEvent;
#endif
game/item.cpp
Kod:
//bul:
m_pkRealTimeExpireEvent = NULL;
//ekle:
#ifdef ENABLE_POTION_REFILL
m_pkPotionRecoveryEvent = NULL;
#endif
// void CItem::Destroy()): fonksiyonu içinde bul
CEntity::Destroy();
//altına ekle:
#ifdef ENABLE_POTION_REFILL
event_cancel(&m_pkPotionRecoveryEvent);
#endif
//şu fonksiyonu bul:
void CItem::StartDestroyEvent(int iSec)
//fonksiyon bitince altına ekle
#ifdef ENABLE_POTION_REFILL
EVENTFUNC(potion_recovery_event)
{
item_event_info* info = dynamic_cast<item_event_info*>(event->info);
if (info == NULL)
{
sys_err("potion_recovery_event> <Factor> Null pointer");
return 0;
}
LPITEM pkItem = info->item;
//Check if potion is fully restored
//return and cancel event if so
const TItemTable* itemTable = pkItem->GetProto();
if (pkItem->GetSocket(1) == 0)
{
pkItem->SetPotionRecoveryEvent(NULL);
return 0;
}
else
{
int potionValueToRestore = itemTable->alValues[0] / 100 * 10;
int missingPotionValue = pkItem->GetSocket(1);
int newPotionValue = 0;
if (missingPotionValue < potionValueToRestore)
{
pkItem->SetSocket(1, 0, false);
pkItem->SetPotionRecoveryEvent(NULL);
return 0;
}
else
{
newPotionValue = pkItem->GetSocket(1) - potionValueToRestore;
pkItem->SetSocket(1, newPotionValue, false);
return PASSES_PER_SEC(3);
}
}
}
void CItem::SetPotionRecoveryEvent(LPEVENT pkEvent)
{
m_pkPotionRecoveryEvent = pkEvent;
}
void CItem::StartPotionRecoveryEvent()
{
if (m_pkPotionRecoveryEvent)
return;
item_event_info* info = AllocEventInfo<item_event_info>();
info->item = this;
SetPotionRecoveryEvent(event_create(potion_recovery_event, info, PASSES_PER_SEC(3)));
}
void CItem::StopPotionRecoveryEvent()
{
if (m_pkPotionRecoveryEvent)
{
event_cancel(&m_pkPotionRecoveryEvent);
}
}
#endif
game/input_login.cpp
Kod:
//Fonksiyonu bul:
void CInputLogin::Entergame(LPDESC d, const char * data)
//Altına ekle
#ifdef ENABLE_POTION_REFILL
ch->PotionRefillMgt();
#endif
//void CInputLogin::Entergame(LPDESC d, const char * data) fonksiyonunun altına ekleyin:
#ifdef ENABLE_POTION_REFILL
ch->PotionRefillMgt();
#endif
İşlem bu kadar.
Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)
Benzer konular
- Cevaplar
- 9
- Görüntüleme
- 352
- Cevaplar
- 2
- Görüntüleme
- 198
- Cevaplar
- 15
- Görüntüleme
- 774
- Cevaplar
- 20
- Görüntüleme
- 860
