Merhabalar,
Aranızda ROK Projesini bilenler vardır. Yaratık & npc hızlarını ve yapay zekasını bu proje için geliştirmiştik. ICE ve lighting işlemeleri, sorunsuz takip sistemi vs.. sizlerle paylaşıyorum. %100 ÇÖZÜMDÜR.!
[HIDE-REPLY]
Öncelikle AI Server içerisinde, Npc.h eklemeniz gerekenler;
Unit.h eklemeniz gereken;
Unit.cpp Initialize() içerisinde varsayılan olarak 100 değeri vermeyi unutmayın.
AI > Npc.cpp içerisindeki IsNoPathFind fonksiyonunu bununla değişin;
Eksik fonksiyonumuz bunu da altına ekleyin;
Hareket hızlarımız yazılımsal olarak düzelmiştir. Şimdide takip olayındaki hataları fixleyelim.
Yine Npc.cpp içindeki NpcTracing fonksiyonunda aşağıdaki return değerlerini güncelleyin.
Fonksiyonun en son ki return değeri ;
Yine aynı şekilde NpcAttacking fonksiyonun return değerleri aşağıdaki gibi olmalı;
Sıradaki fonksiyon : NpcMoving aynı işlemi uygulayın;
Sıradaki fonksiyon, NpcStanding aynı işlemi uygulayın;
Fonksiyonun en sonki return değeri;
Sıradaki fonksiyon, Attack() aynı işlemi uygulayın; direk tüm fonksiyonu veriyorum. sizdekiyle return değerlerini güncelleyin yeter.
Bunlarıda uyguladıktan sonra tıpki 1299 daki gibi hareket olayları çalışacaktır. Slot bozulamaları, donmaları vs durumlar ortadan kalkıyor.
Veritabanı kısmında yapacağınız işlem ise hız ve range olaylarını ayarlamak.
AttackRange : 2 - 5 arası olmalı. yaratığa göre ayarlamalısınız.
TrackingRange: 45 civarı
m_speed : 1300-1600 civarı ayarlarsanız sorun çıkmayacaktır. Bu değerleri sizlere vermiyorum. Kendiniz ayarlayın.
Yapmanız gereken son bir şey ise m_bSpeedAmount değeri Ai server de tutulmamakta. Bu yüzden aisocket aracılığı ile gameserver den m_bSpeedAmount bilgisini ai servere göndermeniz gerekiyor. Yoksa ice & lighting işlemi gerçekleşmez. Bu fonksiyonuda size bırakıyorum. 95% kısmını paylaşmış oldum. Gerisini getirirsiniz.
[/HIDE-REPLY]
İyi çalışmalar...
Aranızda ROK Projesini bilenler vardır. Yaratık & npc hızlarını ve yapay zekasını bu proje için geliştirmiştik. ICE ve lighting işlemeleri, sorunsuz takip sistemi vs.. sizlerle paylaşıyorum. %100 ÇÖZÜMDÜR.!
[HIDE-REPLY]
Öncelikle AI Server içerisinde, Npc.h eklemeniz gerekenler;
Kod:
void NpcCalling(float fDis,float fDistance, __Vector3 oPos, __Vector3 cPost);
Unit.h eklemeniz gereken;
Kod:
uint8 m_bSpeedAmount;
Unit.cpp Initialize() içerisinde varsayılan olarak 100 değeri vermeyi unutmayın.
Kod:
m_bSpeedAmount = 100;
AI > Npc.cpp içerisindeki IsNoPathFind fonksiyonunu bununla değişin;
Kod:
void CNpc::IsNoPathFind(float fDistance){
ClearPathFindData();
m_bPathFlag = true;
int nX = 0, nZ = 0;
__Vector3 vStart, vEnd, vDis, vOldDis;
float fDis = 0.0f;
vStart.Set(m_fStartPoint_X, 0, m_fStartPoint_Y);
vEnd.Set(m_fEndPoint_X, 0, m_fEndPoint_Y);
vDis.Set(m_fStartPoint_X, 0, m_fStartPoint_Y);
int count = 0;
int nError = 0;
fDis = GetDistance(vStart, vEnd);
if (fDis > NPC_MAX_MOVE_RANGE) {
ClearPathFindData();
TRACE("#### Npc-IsNoPathFind Fail : NPC_MAX_MOVE_RANGE overflow .. [nid = %d, name=%s], cur_x=%.2f, z=%.2f, dest_x=%.2f, dest_z=%.2f, fDis=%.2f#####\n",
GetID(), GetName().c_str(), m_fStartPoint_X, m_fStartPoint_Y, m_fEndPoint_X, m_fEndPoint_Y, fDis);
return;
}
if (GetMap() == nullptr)
{
ClearPathFindData();
TRACE("#### Npc-IsNoPathFind No map : [nid=%d, name=%s], zone=%d #####\n", GetID(), GetName().c_str(), GetZoneID());
return;
}
MAP* pMap = GetMap();
vOldDis.Set(vDis.x, 0, vDis.z);
fDis = GetDistance(vOldDis, vEnd);
if (count < 0 || count >= MAX_PATH_LINE) {
count = 0;
}
GetVectorPosition(vDis, vEnd, fDistance, &vDis);
NpcCalling(fDis,fDistance, vOldDis, vDis);
if (count <= 0 || count >= MAX_PATH_LINE) {
ClearPathFindData();
TRACE("#### IsNoPtahfind Fail : nid=%d,%s, count=%d ####\n", GetID(), GetName().c_str(), count);
return;
}
m_iAniFrameIndex = count;
}
Eksik fonksiyonumuz bunu da altına ekleyin;
Kod:
void CNpc::NpcCalling(float fDis,float fDistance, __Vector3 oPos, __Vector3 cPost){
float bChamber = TILE_SIZE + 3;
if (m_bSpeedAmount > 0 && m_bSpeedAmount < 100) {
float pTile = (float)(10 - (m_bSpeedAmount / 10) - TILE_SIZE);
bChamber -= (pTile >= 1 ? pTile + 2 : 0);
}
else if (m_bSpeedAmount > 100) {
float pTile = (float)(10 - (m_bSpeedAmount / 10) - TILE_SIZE);
bChamber += (pTile >= 1 ? pTile + 2 : 0);
}
bChamber = fDis / bChamber;
if (bChamber > 15)bChamber = 15;
m_curx = (cPost.x / bChamber) + oPos.x;
m_curz = (cPost.z / bChamber) + oPos.z;
float tempSpeed = m_fSecForRealMoveMetor;
if (tempSpeed == 0)
tempSpeed = m_fSpeed_1;
float nMoveSpeed = (float)(tempSpeed / ((float)m_sSpeed / 1000));
if (nMoveSpeed != 0) {
SendMoveResult(m_curx, m_fPrevY, m_curz, (float)(nMoveSpeed));
}
}
Hareket hızlarımız yazılımsal olarak düzelmiştir. Şimdide takip olayındaki hataları fixleyelim.
Yine Npc.cpp içindeki NpcTracing fonksiyonunda aşağıdaki return değerlerini güncelleyin.
Kod:
if (isNonAttackingObject()) {
InitTarget();
m_NpcState = NPC_STANDING;
return 0;
}
Kod:
if (m_byMoveType == 4) {
m_NpcState = NPC_FIGHTING;
return 0;
}
Kod:
if (result == CloseTargetInGeneralRange) {
NpcMoveEnd();
m_NpcState = NPC_FIGHTING;
return 0;
}
else if (result == CloseTargetInvalid)
{
InitTarget();
NpcMoveEnd();
m_NpcState = NPC_STANDING;
return 0;
}
else if (result == CloseTargetInAttackRange && GetProto()->m_byDirectAttack == 2)
{
NpcMoveEnd();
m_NpcState = NPC_FIGHTING;
return 0;
}
Kod:
if (m_bStopFollowingTarget) {
if (!ResetPath())// && !m_tNpcTraceType)
{
InitTarget();
NpcMoveEnd();
m_NpcState = NPC_STANDING;
return 0;
}
}
Kod:
if ( (!m_bPathFlag && !StepMove()) || (m_bPathFlag && !StepNoPathMove()))
{
m_NpcState = NPC_STANDING;
return 0;
}
Fonksiyonun en son ki return değeri ;
Kod:
return m_sSpeed;
Yine aynı şekilde NpcAttacking fonksiyonun return değerleri aşağıdaki gibi olmalı;
Kod:
if (isNonAttackingObject()) {
m_NpcState = NPC_STANDING;
return 0;
}
Kod:
if (result == CloseTargetInGeneralRange) {
m_NpcState = NPC_FIGHTING;
return m_sAttackDelay;
}
Kod:
int nValue = GetTargetPath(); if (nValue == -1)
{
if (!RandomMove())
{
InitTarget();
m_NpcState = NPC_STANDING;
return m_sStandTime;
}
InitTarget();
m_NpcState = NPC_MOVING;
return 0;
}
else if (nValue == 0)
{
m_fSecForMetor = m_fSpeed_2;
IsNoPathFind(m_fSecForMetor);
}
m_NpcState = NPC_TRACING;
return m_sStandTime;
Sıradaki fonksiyon : NpcMoving aynı işlemi uygulayın;
Kod:
NpcMoveEnd(); m_NpcState = NPC_ATTACKING;
return 0;
Kod:
if (IsMovingEnd()) {
m_curx = m_fPrevX;
m_curz = m_fPrevZ;
if (GetX() < 0 || GetZ() < 0)
TRACE("Npc-NpcMoving-2 : nid=(%d, %s), x=%.2f, z=%.2f\n", GetID(), GetName().c_str(), GetX(), GetZ());
m_NpcState = NPC_STANDING;
return m_sStandTime;
}
Kod:
if ( (!m_bPathFlag && !StepMove()) || (m_bPathFlag && !StepNoPathMove()))
{
m_NpcState = NPC_STANDING;
return 0;
}
SendMoveResult(m_fPrevX, m_fPrevY, m_fPrevZ, (float)((m_fSecForRealMoveMetor) / ((double)m_sSpeed / 1000)));
return m_fSpeed_1;
Sıradaki fonksiyon, NpcStanding aynı işlemi uygulayın;
Kod:
if (pRoom != nullptr && pRoom->m_byStatus == 1)
{
m_NpcState = NPC_STANDING;
return m_sStandTime;
}
Kod:
if (RandomMove()) {
m_iAniFrameCount = 0;
m_NpcState = NPC_MOVING;
return m_sStandTime;
}
Fonksiyonun en sonki return değeri;
Kod:
return m_sStandTime;
Sıradaki fonksiyon, Attack() aynı işlemi uygulayın; direk tüm fonksiyonu veriyorum. sizdekiyle return değerlerini güncelleyin yeter.
Kod:
try { if (isDead())
return -1;
int nRandom = 0, nPercent = 1000;
bool bTeleport = false;
if (isNonAttackingObject())
{
m_NpcState = NPC_STANDING;
InitTarget();
return 0;
}
if (GetProto()->m_byDirectAttack == 1)
return LongAndMagicAttack();
int nStandingTime = m_sStandTime;
auto result = IsCloseTarget(m_byAttackRange, AttackTypeMagic);
if (result == CloseTargetNotInRange)
{
m_sStepCount = 0;
m_byActionFlag = ATTACK_TO_TRACE;
m_NpcState = NPC_TRACING;
return m_sAttackDelay;
}
else if (result == CloseTargetInAttackRange)
{
if (GetProto()->m_byDirectAttack == 2)
return LongAndMagicAttack();
m_sStepCount = 0;
m_byActionFlag = ATTACK_TO_TRACE;
m_NpcState = NPC_TRACING;
return m_sAttackDelay;
}
else if (result == CloseTargetInvalid)
{
m_NpcState = NPC_STANDING;
InitTarget();
return 0;
}
int nDamage = 0;
uint16 nID = m_Target.id; // Target ì„ êµ¬í•œë‹¤.
// Targeting player
if (nID < NPC_BAND)
{
CUser * pUser = g_pMain->GetUserPtr(nID);
if (pUser == nullptr
|| pUser->isDead()
|| pUser->m_bInvisibilityType)
{
InitTarget();
m_NpcState = NPC_STANDING;
return 0;
}
// Don't attack GMs.
if (pUser->isGM())
{
InitTarget();
m_NpcState = NPC_MOVING;
return 0;
}
if (GetProto()->m_byMagicAttack == 4 || GetProto()->m_byMagicAttack == 5)
{
nRandom = myrand(1, 10000);
if (nRandom < nPercent)
{
CNpcMagicProcess::MagicPacket(MAGIC_EFFECTING, m_proto->m_iMagic1, GetID(), -1, int16(pUser->GetX()), int16(pUser->GetY()), int16(pUser->GetZ()));
//printf("AreaMagicAttack --- sid=%d, magicid=%d, name=%s\n", GetID(), m_proto->m_iMagic1, m_proto->m_strName.c_str());
return m_sAttackDelay + 1000;
}
}
else if (GetProto()->m_byMagicAttack == 2)
{
nRandom = myrand(1, 10000);
if (nRandom < nPercent)
{
CNpcMagicProcess::MagicPacket(MAGIC_EFFECTING, m_proto->m_iMagic1, GetID(), pUser->GetID());
// printf("LongAndMagicAttack --- sid=%d, tid=%d, magicid=%d, name=%s\n", GetID(), pUser->GetID(), m_proto->m_iMagic1, m_proto->m_strName.c_str());
return m_sAttackDelay;
}
}
SendAttackRequest(pUser->GetID());
}
else // Targeting NPC
{
CNpc * pNpc = g_pMain->GetNpcPtr(nID);
if (pNpc == nullptr
|| pNpc->isDead())
{
InitTarget();
m_NpcState = NPC_STANDING;
return 0;
}
if (isHealer()
&& !isHostileTo(pNpc))
{
m_NpcState = NPC_HEALING;
return 0;
}
SendAttackRequest(pNpc->GetID());
}
return m_sAttackDelay;
}
catch (...) {
GlobalError(__FILE__, __LINE__);
return 0;
}
}
Bunlarıda uyguladıktan sonra tıpki 1299 daki gibi hareket olayları çalışacaktır. Slot bozulamaları, donmaları vs durumlar ortadan kalkıyor.
Veritabanı kısmında yapacağınız işlem ise hız ve range olaylarını ayarlamak.
AttackRange : 2 - 5 arası olmalı. yaratığa göre ayarlamalısınız.
TrackingRange: 45 civarı
m_speed : 1300-1600 civarı ayarlarsanız sorun çıkmayacaktır. Bu değerleri sizlere vermiyorum. Kendiniz ayarlayın.
Yapmanız gereken son bir şey ise m_bSpeedAmount değeri Ai server de tutulmamakta. Bu yüzden aisocket aracılığı ile gameserver den m_bSpeedAmount bilgisini ai servere göndermeniz gerekiyor. Yoksa ice & lighting işlemi gerçekleşmez. Bu fonksiyonuda size bırakıyorum. 95% kısmını paylaşmış oldum. Gerisini getirirsiniz.
[/HIDE-REPLY]
İyi çalışmalar...