WhatsApp Discord
RoxGaming Main 5.2 - 60 FPS 2025 Gratis - Source Mu - Mu Server Files
 

Noticias:

SMF - Just Installed!

Menú principal

RoxGaming Main 5.2 - 60 FPS 2025 Gratis

Publicado por Dakosmu, Oct 02, 2025, 05:40 PM

Tema anterior - Siguiente tema

0 Miembros y 1 Visitante están viendo este tema.

Dakosmu

RoxGaming Main 5.2 - 60 FPS 2025 Gratis

Regístrate para ver el enlace Regístrate para ver el enlace Regístrate para ver el enlace Regístrate para ver el enlace Regístrate para ver el enlace Regístrate para ver el enlace Regístrate para ver el enlace Regístrate para ver el enlace

¡Descarga la Source Code (SRC) optimizada para la popular base de MuServer RoxGaming 5.2! Estamos emocionados de compartir esta versión gratuita y mejorada, que incorpora la estabilidad de la Pyke Base con una característica crucial para la jugabilidad moderna: ¡60 FPS estables o ilimitados! Esta optimización ha sido adaptada directamente del Proyecto Sven OpenMU, asegurando una fluidez inigualable que transformará la experiencia de cualquier desarrollador o jugador. Ideal para quienes buscan estabilidad, alto rendimiento y el código fuente más reciente. Olvídate de los problemas de latencia y disfruta de un juego ultra suave. ¡Consigue la SRC 60 FPS hoy mismo!

Compartiendo la SRC 60 FPS / Ilimitado – Base Pyke RoxGaming

¡Saludos, comunidad de ZoneDev!

Estamos liberando para la comunidad la SRC con 60 FPS (o ilimitado) de Pyke, basada en RoxGaming.
Esta es la actualización optimizada a 60 FPS del Proyecto Sven OpenMU, totalmente adaptada a la fuente principal 5.2 de RoxGaming / MuServer.

Lo que encontrarás:

  • FPS fijado en 60 o ilimitado (más fluidez y estabilidad)
  • Base Pyke de RoxGaming como referencia sólida
  • Vinculado a nuestros enlaces oficiales (sin riesgo de caída)
  • Soporte garantizado por la comunidad ZoneDev
  • Video de ayuda con KnoX

Código de referencia:
// SRC 60 FPS Pyke Base RoxGaming
// Proyecto Sven OpenMU TOMÓ el FPS
// Adaptado a RoxGaming 5.2

Demostración en video (Pyke):
Regístrate para ver el enlace

Descarga de la SRC:
Regístrate para ver el enlace

Cualquier duda o sugerencia, publíquela aquí en el foro y estaremos brindando soporte a todos los jugadores y desarrolladores.

ZoneDev – ¡Compartiendo conocimiento, fortaleciendo la comunidad!



Créditos: by KnoX
Bon Dia

Dakosmu

#1
Donde  Colocar el ChatTime en Main 5.2


Regístrate para ver el enlace

Regístrate para ver el enlace
Regístrate para ver el enlace


void MainScene(HDC hDC)
{

    //fix chat Dakosmu
    if (ChatTime > 0) ChatTime--;
    if (MacroTime > 0) MacroTime--;
    //
    if (LOG_IN_SCENE == SceneFlag || CHARACTER_SCENE == SceneFlag)
    {
        double dDeltaTick = g_pTimer->GetTimeElapsed();
        dDeltaTick = MIN(dDeltaTick, 200.0 * FPS_ANIMATION_FACTOR);
        //g_pTimer->ResetTimer();

        CInput::Instance().Update();
        CUIMng::Instance().Update(dDeltaTick);
    }
Bon Dia

Dakosmu

AutoPotion 5.2 (2x Shift)


NewUIMainFrameWindow.cpp

Regístrate para ver el enlace

bool SEASON3B::CNewUIItemHotKey::UpdateKeyEvent()
{
    static bool bAutoKeyMode = false;
    static int iLastShiftPressTime = 0;
    static int iShiftPressCount = 0;
    const int DOUBLE_PRESS_DELAY = 300;
    const int AUTO_KEY_DELAY = 1;

    int iIndex = -1;
    int currentTime = GetTickCount();

    if (SEASON3B::IsPress(VK_SHIFT))
    {
        if (currentTime - iLastShiftPressTime <= DOUBLE_PRESS_DELAY)
        {
            iShiftPressCount++;
            if (iShiftPressCount >= 2)
            {
                bAutoKeyMode = !bAutoKeyMode;
                g_pChatListBox->AddText("", bAutoKeyMode ? "[2X Shift] AutoPotion [ON]" : "[2X Shift] AutoPotion [OFF]", SEASON3B::TYPE_SYSTEM_MESSAGE);
                iShiftPressCount = 0;
            }
        }
        else
        {
            iShiftPressCount = 1;
        }
        iLastShiftPressTime = currentTime;
    }

    if (bAutoKeyMode)
    {
        static int iLastAutoKeyTime = 0;
        static int iCurrentKeyIndex = 0;
        const char keys[] = { 'Q', 'W', 'E', 'R' };

        if (currentTime - iLastAutoKeyTime >= AUTO_KEY_DELAY)
        {
            if (iCurrentKeyIndex < 4)
            {
                switch (keys[iCurrentKeyIndex])
                {
                case 'Q': iIndex = GetHotKeyItemIndex(HOTKEY_Q); break;
                case 'W': iIndex = GetHotKeyItemIndex(HOTKEY_W); break;
                case 'E': iIndex = GetHotKeyItemIndex(HOTKEY_E); break;
                case 'R': iIndex = GetHotKeyItemIndex(HOTKEY_R); break;
                }
                iCurrentKeyIndex++;
                if (iCurrentKeyIndex >= 4)
                    iCurrentKeyIndex = 0;
                iLastAutoKeyTime = currentTime;
            }
        }
    }
    else
    {
        if (SEASON3B::IsPress('Q'))
        {
            iIndex = GetHotKeyItemIndex(HOTKEY_Q);
        }
        else if (SEASON3B::IsPress('W'))
        {
            iIndex = GetHotKeyItemIndex(HOTKEY_W);
        }
        else if (SEASON3B::IsPress('E'))
        {
            iIndex = GetHotKeyItemIndex(HOTKEY_E);
        }
        else if (SEASON3B::IsPress('R'))
        {
            //Dakosmu Fix Pet
            iIndex = GetHotKeyItemIndex(HOTKEY_R);
        }
    }

    if (iIndex != -1)
    {
        ITEM* pItem = NULL;
        pItem = g_pMyInventory->FindItem(iIndex);
        if ((pItem->Type >= ITEM_POTION + 78 && pItem->Type <= ITEM_POTION + 82))
        {
            std::list<eBuffState> secretPotionbufflist;
            secretPotionbufflist.push_back(eBuff_SecretPotion1);
            secretPotionbufflist.push_back(eBuff_SecretPotion2);
            secretPotionbufflist.push_back(eBuff_SecretPotion3);
            secretPotionbufflist.push_back(eBuff_SecretPotion4);
            secretPotionbufflist.push_back(eBuff_SecretPotion5);

            if (g_isCharacterBufflist((&Hero->Object), secretPotionbufflist) != eBuffNone)
            {
                SEASON3B::CreateOkMessageBox(GlobalText[2530], RGBA(255, 30, 0, 255));
            }
            else
            {
                SendRequestUse(iIndex, 0);
            }
        }
        else
        {
            SendRequestUse(iIndex, 0);
        }
        return false;
    }

    return true;
}

NewUIMainFrameWindow.h

Regístrate para ver el enlace

    enum
    {
        HOTKEY_Q = 0,
        HOTKEY_W,
        HOTKEY_E,
        //Dakosmu Fix Pet
         HOTKEY_R,
         //
        HOTKEY_COUNT,
    };
Bon Dia

Dakosmu

Show Window Stats

Regístrate para ver el enlace

Guía Paso a Paso (Archivo: NewUIHeroPositionInfo.cpp)

---

Paso 1: Agregar la Función ShowInfoTitleWindow()

Vamos a buscar la función Render() para insertar la nueva función encima de ella.

  • En tu archivo NewUIHeroPositionInfo.cpp, usa la búsqueda (Ctrl+F) y busca la línea que dice:

bool CNewUIHeroPositionInfo::Render()

  • Desplázate hacia arriba hasta encontrar la función inmediatamente anterior a Render(), que en tu código es bool CNewUIHeroPositionInfo::Update().
  • Inserta el código de la nueva función después del final de Update() y antes del inicio de Render().

Busca estas líneas en tu archivo:

// ... (código dentro de Update)
    return true;
} // <-- Aquí termina la función Update()
 
 
bool CNewUIHeroPositionInfo::Render() // <-- Aquí comienza la función Render()
{
// ...

Inserta el código de la función ShowInfoTitleWindow() justo en el medio, así:

// ... (código dentro de Update)
    return true;
} // <-- Aquí termina la función Update()
 
 
// =======================================================================
// COMIENZO DEL CÓDIGO A AÑADIR (Función ShowInfoTitleWindow)
// =======================================================================
void ShowInfoTitleWindow()
{
    bool condition = true;
    std::string windowName = gProtect->m_MainInfo.WindowName;
    if (Hero)
    {
        windowName += " [Char: " + std::string(CharacterAttribute->Name) + "]";
        windowName += " (Lv " + std::to_string(CharacterAttribute->Level);
        windowName += " || Rs " + std::to_string(CharacterAttribute->PrintPlayer.ViewReset);
        windowName += " || RL " + std::to_string(CharacterAttribute->PrintPlayer.ViewMasterReset) + ")";
        windowName += " || (FPS: " + std::to_string((int)FPS_AVG) + ")";
    }
    SetWindowText(g_hWnd, windowName.c_str());
}
// =======================================================================
// FIN DEL CÓDIGO A AÑADIR
// =======================================================================
 
 
bool CNewUIHeroPositionInfo::Render() // <-- Aquí comienza la función Render()
{
// ...

⚠️ NOTA IMPORTANTE sobre FPS: Si tu proyecto no usa FPS_AVG (lo cual es común) y te da un error en la compilación, deberás reemplazar esta línea dentro de ShowInfoTitleWindow():

    windowName += " || (FPS: " + std::to_string((int)FPS_AVG) + ")";

por esta otra:

    windowName += " || (FPS: " + std::to_string((int)FPS) + ")";

---

Paso 2: Llamar a la Función ShowInfoTitleWindow()

Ahora vamos a hacer que la función Render() llame a la función que acabas de crear para que el título se actualice constantemente.

  • En el mismo archivo NewUIHeroPositionInfo.cpp, baja un poco y localiza el inicio de la función Render():

bool CNewUIHeroPositionInfo::Render()
{
    float x = 0.0;
// ...

  • Inserta la llamada a la función después de la llave de apertura y la inicialización de x, pero antes del resto del código de renderizado (los GWidescreen.CreateNButton).

Busca estas líneas en tu archivo:

bool CNewUIHeroPositionInfo::Render()
{
    float x = 0.0;
    GWidescreen.CreateNButton(IMAGE_HERO_POSITION_INFO_BASE_WINDOW, x, 00.0f, 24, 24, INTERFACE_OPTION); //-- Menu
// ...

Inserta el código ShowInfoTitleWindow(); justo así:

bool CNewUIHeroPositionInfo::Render()
{
    ShowInfoTitleWindow(); // <-- ¡Esta es la línea que debes agregar!
    float x = 0.0;
    GWidescreen.CreateNButton(IMAGE_HERO_POSITION_INFO_BASE_WINDOW, x, 00.0f, 24, 24, INTERFACE_OPTION); //-- Menu
// ...

---

Paso 3: Guardar y Continuar con el otro archivo

  • Guarda el archivo NewUIHeroPositionInfo.cpp.
  • ¡No olvides la Parte 1! Tienes que hacer las modificaciones en el archivo _struct.h (si aún no lo hiciste) para que todo compile correctamente.

¿Necesitas que repita los pasos para el archivo _struct.h o estás listo para compilar?
Bon Dia

Dakosmu

La tienda del Mago No bre - Solucion


Regístrate para ver el enlace


Ver Youtube Regístrate para ver el enlace creditos GabrielC

Regístrate para ver el enlace



Entrar a
\MuServer\Data\Scripts\Configs
Archivo

NpcRescueItens.lua

Asi deberia quedar
NpcRescueItem_Config = {
Enabled = false,


Regístrate para ver el enlace





Bon Dia

Dakosmu

CustomNPC MOVE

Pasos para Agregar el CustomNpcMove


Regístrate para ver el enlace

Regístrate para ver el enlace



Aquí tienes la guía paso a paso para implementar el CustomNpcMove.

1. Crear los Nuevos Archivos
Debes crear dos nuevos archivos en tu carpeta de source (probablemente dentro de la carpeta GameServer o similar):

A. CustomNpcMove.h
Crea este archivo e inserta el siguiente código:
#pragma once 
#include "User.h" 
 
struct NPC_MOVE_INFO 

    int Index; 
    int MonsterClass; 
    int Map; 
    int X; 
    int Y; 
    int MoveMap; 
    int MoveX; 
    int MoveY; 
    int MinLevel; 
    int MaxLevel; 
    int MinReset; 
    int MaxReset; 
    int MinMReset; 
    int MaxMReset; 
    int AccountLevel; 
    int PkMove; 
    int ItemIndex; 
    int ItemLevel; 
    int ItemQtd; 
    int DeleteItem; 
}; 
 
class CCustomNpcMove 

public: 
    CCustomNpcMove(); 
    virtual ~CCustomNpcMove(); 
    void Load(char* path); 
    bool GetNpcMove(LPOBJ lpObj, int MonsterClass, int Map, int X, int Y); 
private: 
    std::map<int, NPC_MOVE_INFO> m_CustomNpcMove; 
}; 
 
extern CCustomNpcMove gCustomNpcMove;

B. CustomNpcMove.cpp
Crea este archivo e inserta el siguiente código:
#include "stdafx.h" 
#include "CustomNpcMove.h" 
#include "CastleSiegeSync.h" 
#include "Map.h" 
#include "MapManager.h" 
#include "MemScript.h" 
#include "Message.h" 
#include "Notice.h" 
#include "NpcTalk.h" 
#include "Path.h" 
#include "Util.h" 
#include "EffectManager.h" 
 
// Asegúrate de incluir ItemManager.h si la función gItemManager.InventoryDelItem 
// da error o si no está incluida en "stdafx.h". 
// #include "ItemManager.h" 
 
CCustomNpcMove gCustomNpcMove; 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CCustomNpcMove::CCustomNpcMove() // OK 

    this->m_CustomNpcMove.clear(); 

 
CCustomNpcMove::~CCustomNpcMove() // OK 


 
void CCustomNpcMove::Load(char* path) // OK 

    CMemScript* lpMemScript = new CMemScript; 
 
    if (lpMemScript == 0) 
    { 
        ErrorMessageBox(MEM_SCRIPT_ALLOC_ERROR, path); 
        return; 
    } 
 
    if (lpMemScript->SetBuffer(path) == 0) 
    { 
        ErrorMessageBox(lpMemScript->GetLastError()); 
        delete lpMemScript; 
        return; 
    } 
 
    this->m_CustomNpcMove.clear(); 
 
    try 
    { 
        while (true) 
        { 
            if (lpMemScript->GetToken() == TOKEN_END) 
            { 
                break; 
            } 
 
            if (strcmp("end", lpMemScript->GetString()) == 0) 
            { 
                break; 
            } 
 
            NPC_MOVE_INFO info; 
 
            info.Index = lpMemScript->GetNumber(); 
            info.MonsterClass = lpMemScript->GetAsNumber(); 
            info.Map = lpMemScript->GetAsNumber(); 
            info.X = lpMemScript->GetAsNumber(); 
            info.Y = lpMemScript->GetAsNumber(); 
            info.MoveMap = lpMemScript->GetAsNumber(); 
            info.MoveX = lpMemScript->GetAsNumber(); 
            info.MoveY = lpMemScript->GetAsNumber(); 
            info.MinLevel = lpMemScript->GetAsNumber(); 
            info.MaxLevel = lpMemScript->GetAsNumber(); 
            info.MinReset = lpMemScript->GetAsNumber(); 
            info.MaxReset = lpMemScript->GetAsNumber(); 
            info.MinMReset = lpMemScript->GetAsNumber(); 
            info.MaxMReset = lpMemScript->GetAsNumber(); 
            info.AccountLevel = lpMemScript->GetAsNumber(); 
            info.PkMove = lpMemScript->GetAsNumber(); 
            info.ItemIndex = lpMemScript->GetAsNumber(); 
            info.ItemLevel = lpMemScript->GetAsNumber(); 
            info.ItemQtd = lpMemScript->GetAsNumber(); 
            info.DeleteItem = lpMemScript->GetAsNumber(); 
 
            this->m_CustomNpcMove.insert(std::pair<int, NPC_MOVE_INFO>(info.Index, info)); 
        } 
    } 
    catch (...) 
    { 
        ErrorMessageBox(lpMemScript->GetLastError()); 
    } 
 
    delete lpMemScript; 

 
bool CCustomNpcMove::GetNpcMove(LPOBJ lpObj, int MonsterClass, int Map, int X, int Y) 

    for (std::map<int, NPC_MOVE_INFO>::iterator it = this->m_CustomNpcMove.begin(); it != this->m_CustomNpcMove.end(); it++) 
    { 
        if (it->second.MonsterClass == MonsterClass && it->second.Map == Map && it->second.X == X && it->second.Y == Y) 
        { 
            // Chequeos de nivel, reset, etc. 
            if (it->second.MinLevel > 0 && lpObj->Level < it->second.MinLevel) { gNotice.GCNoticeSend(lpObj->Index, 1, 0, 0, 0, 0, 0, gMessage.GetMessage(999)); return 1; } 
            if (it->second.MaxLevel > 0 && lpObj->Level > it->second.MaxLevel) { gNotice.GCNoticeSend(lpObj->Index, 1, 0, 0, 0, 0, 0, gMessage.GetMessage(999)); return 1; } 
            // Se asume que aquí irían los demás chequeos (MinReset, MaxReset, etc.) 
 
            if (it->second.ItemIndex != -1 && it->second.ItemQtd > 0) 
            { 
                LogAdd(LOG_BLACK, "[CustomNpcMove] Verificando item: ItemIndex=%d, ItemQtd=%d, DeleteItem=%d", 
                    it->second.ItemIndex, it->second.ItemQtd, it->second.DeleteItem); 
 
                int itemCount = 0; 
                // El inventario de MU suele ser de 12 (equipamiento) a 120 (inventario) 
                for (int i = 12; i < 120; i++) 
                { 
                    if (lpObj->Inventory[i].IsItem() && 
                        lpObj->Inventory[i].m_Index == it->second.ItemIndex && 
                        lpObj->Inventory[i].m_Level >= it->second.ItemLevel) 
                    { 
                        itemCount += lpObj->Inventory[i].m_Durability; 
                    } 
                } 
 
                LogAdd(LOG_BLACK, "[CustomNpcMove] Total de itens encontrados: %d", itemCount); 
 
                if (itemCount < it->second.ItemQtd) 
                { 
                    // Mensaje 999: "Você não possui os itens necessários!" 
                    gNotice.GCNoticeSend(lpObj->Index, 1, 0, 0, 0, 0, 0, gMessage.GetMessage(999)); 
                    return 1; 
                } 
 
                if (it->second.DeleteItem == 1) 
                { 
                    int required = it->second.ItemQtd; 
                    for (int i = 12; i < 120; i++) 
                    { 
                        if (lpObj->Inventory[i].IsItem() && 
                            lpObj->Inventory[i].m_Index == it->second.ItemIndex && 
                            lpObj->Inventory[i].m_Level >= it->second.ItemLevel && 
                            required > 0) 
                        { 
                            LogAdd(LOG_BLACK, "[CustomNpcMove] Deletando item em slot %d: Durability=%d", 
                                i, lpObj->Inventory[i].m_Durability); 
 
                            int toRemove = min(required, (int)lpObj->Inventory[i].m_Durability); 
                            required -= toRemove; 
 
                            // Aquí se requiere gItemManager.InventoryDelItem y gItemManager.GCItemDeleteSend 
                            gItemManager.InventoryDelItem(lpObj->Index, i); 
                            gItemManager.GCItemDeleteSend(lpObj->Index, i, 1); 
 
                            LogAdd(LOG_BLACK, "[CustomNpcMove] Item deletado do slot %d, restante a remover: %d", 
                                i, required); 
                        } 
                    } 
 
                    if (required > 0) 
                    { 
                        LogAdd(LOG_RED, "[CustomNpcMove] Erro: Não foi possível deletar todos os itens requeridos (%d restantes)", required); 
                        gNotice.GCNoticeSend(lpObj->Index, 1, 0, 0, 0, 0, 0, gMessage.GetMessage(999)); 
                        return 1; 
                    } 
                    // Mensaje 998: "Item consumido com sucesso!" 
                    gNotice.GCNoticeSend(lpObj->Index, 1, 0, 0, 0, 0, 0, gMessage.GetMessage(998)); 
                } 
            } 
 
            // Mensaje 997: "Movido com sucesso!" 
            gObjTeleport(lpObj->Index, it->second.MoveMap, it->second.MoveX, it->second.MoveY); 
            gNotice.GCNoticeSend(lpObj->Index, 1, 0, 0, 0, 0, 0, gMessage.GetMessage(997)); 
            return 1; 
        } 
    } 
    return 0; 
}

---

2. Modificar Archivos Existentes
Ahora, modifica los archivos existentes en tu source:

A. Modificar NpcTalk.cpp
  • Abre el archivo NpcTalk.cpp.
  • Agrega el include al inicio del archivo, junto a otros #include:
#include "CustomNpcMove.h"

  • Busca la función bool CNpcTalk::NpcTalk(LPOBJ lpNpc,LPOBJ lpObj) y añade la llamada a la función justo al principio de la misma (después de las comprobaciones iniciales):
bool CNpcTalk::NpcTalk(LPOBJ lpNpc, LPOBJ lpObj) // OK 

    // ... (Tu código existente aquí, por ejemplo: chequeo de GS_STANDBY) 
 
    // **AÑADE ESTO:** if (gCustomNpcMove.GetNpcMove(lpObj, lpNpc->Class, lpNpc->Map, lpNpc->X, lpNpc->Y) != 0) 
    { 
        return 1; 
    } 
    // **FIN DEL CÓDIGO AÑADIDO** // ... (Tu código existente aquí con el switch de los NPCs, etc.) 
}

B. Modificar ServerInfo.cpp
  • Abre el archivo ServerInfo.cpp.
  • Agrega el include al inicio del archivo, junto a otros #include:
#include "CustomNpcMove.h"

  • Busca la función void CServerInfo::ReadCustomInfo() (o una similar de carga de configuraciones) y añade la línea de carga del archivo de configuración:
void CServerInfo::ReadCustomInfo() // OK 

    // ... (Tu código de carga existente aquí) 
 
    // **AÑADE ESTO:** gCustomNpcMove.Load(gPath.GetFullPath("NPC\\NPCMove.txt")); 
    // **FIN DEL CÓDIGO AÑADIDO** // ... (Tu código de carga restante) 
}

---

3. Crear el Archivo de Configuración
Crea la carpeta NPC (si no existe) dentro de tu carpeta de datos (generalmente Data o similar). Dentro de ella, crea el archivo NPCMove.txt e inserta el siguiente contenido.

NPCMove.txt
//Index Npc NpcMap NpcX NpcY MoveMap MoveX MoveY MinLevel MaxLevel MinReset MaxReset MinMReset MaxMReset AccountLevel PKMove ItemReqIndex ItemReqLevel ItemReqQtd DeletarItem Comment 
0      247 0      146    120    2      222    62      50          * * * * * 0              1      6344          1              5          1      //Move To Devias Teste 
1      247 0      143    120    2      25      25      50          * * * * * 0              1      -1            0              20        0      //Move To Devias Teste 
end

---

4. Actualizar los Mensajes (Message.txt)
Para que las notificaciones funcionen correctamente, verifica o agrega estas IDs y textos en tu archivo de mensajes (Message.txt o equivalente):

997    "Movido com sucesso!" 
998    "Item consumido com sucesso!" 
999    "Você não possui os itens necessários!"

---

5. Compilar
Una vez que hayas añadido los nuevos archivos (CustomNpcMove.h, CustomNpcMove.cpp) al proyecto de tu source y hayas realizado las modificaciones en NpcTalk.cpp y ServerInfo.cpp, debes compilar tu proyecto de GameServer para que los cambios surtan efecto.
Bon Dia

Dakosmu

Activar la letra M


Regístrate para ver el enlace


Buscar SEASON3B::IsPress('M'
Regístrate para ver el enlace

Quitar lo comentado asi como indica la imagen

Regístrate para ver el enlace


Bon Dia

Dakosmu

letras Habilitadas:

Regístrate para ver el enlace

V, F, C, T, P, G, A, U, D, M, B, Z, O, X


bool SEASON3B::CNewUIHotKey::UpdateKeyEvent()
{
if(SEASON3B::IsPress(VK_ESCAPE) == true)
{
if(g_MessageBox->IsEmpty())
{
SEASON3B::CreateMessageBox(MSGBOX_LAYOUT_CLASS(SEASON3B::CSystemMenuMsgBoxLayout));
PlayBuffer(SOUND_CLICK01);
return false;
}
}

if( m_bStateGameOver == true )
{
return false;
}

if(SEASON3B::IsPress(VK_TAB) == false && g_pNewUISystem->IsVisible(SEASON3B::INTERFACE_MINI_MAP) == true)
{
return false;
}

if(g_isCharacterBuff((&Hero->Object), eBuff_DuelWatch))
{
//if (SEASON3B::IsPress('M') == true)
//{
// g_pNewUISystem->Toggle(SEASON3B::INTERFACE_MOVEMAP);
// PlayBuffer(SOUND_CLICK01);
//}
return false;
}

if(AutoGetItem() == true)
{
return false;
}

if(CanUpdateKeyEventRelatedMyInventory() == true)
{
if(SEASON3B::IsPress('V'))
{
if (g_pNPCShop->IsSellingItem() == false)
{
g_pNewUISystem->Toggle(SEASON3B::INTERFACE_INVENTORY);
PlayBuffer(SOUND_CLICK01);
return false;
}
}

return true;
}
else if(CanUpdateKeyEvent() == false)
{
return true;
}

if(SEASON3B::IsPress('F'))
{
if(gMapManager.InChaosCastle() == true)
{
return true;
}

int iLevel = CharacterAttribute->Level;

if(iLevel < 6)
{
if(g_pChatListBox->CheckChatRedundancy(GlobalText[1067]) == FALSE)
{
g_pChatListBox->AddText("",GlobalText[1067],SEASON3B::TYPE_SYSTEM_MESSAGE);
}
}
else
{
g_pNewUISystem->Toggle(SEASON3B::INTERFACE_FRIEND);
}

PlayBuffer(SOUND_CLICK01);
return false;
}

else if(SEASON3B::IsPress('V'))
{
if (g_pNPCShop->IsSellingItem() == false)
{
g_pNewUISystem->Toggle(SEASON3B::INTERFACE_INVENTORY);
PlayBuffer(SOUND_CLICK01);
return false;
}
}
else if(SEASON3B::IsPress('C'))
{
g_pNewUISystem->Toggle(SEASON3B::INTERFACE_CHARACTER);
PlayBuffer(SOUND_CLICK01);
return false;
}

else if(SEASON3B::IsPress('T'))
{
g_pNewUISystem->Toggle(SEASON3B::INTERFACE_MYQUEST);
PlayBuffer(SOUND_CLICK01);
return false;
}

else if(SEASON3B::IsPress('P'))
{
g_pNewUISystem->Toggle(SEASON3B::INTERFACE_PARTY);
PlayBuffer(SOUND_CLICK01);
return false;
}
else if(SEASON3B::IsPress('G'))
{
g_pNewUISystem->Toggle(SEASON3B::INTERFACE_GUILDINFO);
PlayBuffer(SOUND_CLICK01);
return false;
}

else if(SEASON3B::IsPress('A'))
{
if(gCharacterManager.IsMasterLevel( Hero->Class ) == true
#ifdef PBG_ADD_NEWCHAR_MONK
&& GetCharacterClass(Hero->Class) != CLASS_TEMPLENIGHT
#endif //PBG_ADD_NEWCHAR_MONK
)
g_pNewUISystem->Toggle(SEASON3B::INTERFACE_MASTER_LEVEL);
PlayBuffer(SOUND_CLICK01);

return false;
}
else if(SEASON3B::IsPress('U'))
{
g_pNewUISystem->Toggle(SEASON3B::INTERFACE_WINDOW_MENU);
PlayBuffer(SOUND_CLICK01);
return false;
}
else if(gMapManager.InChaosCastle() == false && SEASON3B::IsPress('D'))
{
if (::IsStrifeMap(gMapManager.WorldActive))
{
if (g_pChatListBox->CheckChatRedundancy(GlobalText[2989]) == FALSE)
g_pChatListBox->AddText("", GlobalText[2989], SEASON3B::TYPE_SYSTEM_MESSAGE);
}
else
{
g_pNewUISystem->Toggle(SEASON3B::INTERFACE_COMMAND);
PlayBuffer(SOUND_CLICK01);
}

return false;
}

else if(SEASON3B::IsPress(VK_F1) == true)
{
g_pNewUISystem->Toggle(SEASON3B::INTERFACE_HELP);
PlayBuffer(SOUND_CLICK01);
return false;
}
//Dakosmu Activar letra M
else if(SEASON3B::IsPress('M') == true)
{
g_pNewUISystem->Toggle(SEASON3B::INTERFACE_MOVEMAP);
PlayBuffer(SOUND_CLICK01);

return false;
}
else if(SEASON3B::IsPress(VK_TAB) == true && gMapManager.InBattleCastle() == true )
{
g_pNewUISystem->Toggle( SEASON3B::INTERFACE_SIEGEWARFARE );
PlayBuffer(SOUND_CLICK01);
return false;
}
else if(SEASON3B::IsPress(VK_TAB) == true)
{
if(g_pNewUIMiniMap->m_bSuccess == false)
{
g_pNewUISystem->Hide(SEASON3B::INTERFACE_MINI_MAP);
}
else
g_pNewUISystem->Toggle( SEASON3B::INTERFACE_MINI_MAP );
PlayBuffer(SOUND_CLICK01);
return false;
}
else if (SEASON3B::IsPress('B'))
{
SendRequestWareHouseOpen();
PlayBuffer(SOUND_CLICK01);
//PlayBuffer(SOUND_INTERFACE01);
return false;
}
#ifdef NEW_MUHELPER_ON
else if (SEASON3B::IsPress('Z'))
{
g_pNewUISystem->Toggle(SEASON3B::INTERFACE_MACRO_MAIN);
PlayBuffer(SOUND_CLICK01);
return false;
}
else if (SEASON3B::IsPress('O'))
{
if (pAIController->IsRunning() != true)
{
if (pAIController->CanUseAIController())
{
SendRequestStartHelper(0);
}
return false;
}
else
{
SendRequestStartHelper(TRUE);
return false;
}
PlayBuffer(SOUND_CLICK01);
return false;
}
#endif

else if(SEASON3B::IsPress('X') == true)
{
g_ConsoleDebug->Write(MCD_NORMAL,"InGameShopStatue.Txt CallStack - CNewUIHotKey.UpdateKeyEvent()");
if(g_pInGameShop->IsInGameShopOpen() == false)
return false;


if( g_InGameShopSystem->IsScriptDownload() == true )
{
if( g_InGameShopSystem->ScriptDownload() == false )
return false;
}
if( g_InGameShopSystem->IsBannerDownload() == true )
{
if( g_InGameShopSystem->BannerDownload() == true )
{
g_pInGameShop->InitBanner(g_InGameShopSystem->GetBannerFileName(), g_InGameShopSystem->GetBannerURL());
}
}


if( g_pNewUISystem->IsVisible(SEASON3B::INTERFACE_INGAMESHOP) == false)
{
if( g_InGameShopSystem->GetIsRequestShopOpenning() == false )
{
SendRequestIGS_CashShopOpen(0);
g_InGameShopSystem->SetIsRequestShopOpenning(true);

g_pMainFrame->SetBtnState(MAINFRAME_BTN_PARTCHARGE, true);

}
}
else
{
SendRequestIGS_CashShopOpen(1);
g_pNewUISystem->Hide(SEASON3B::INTERFACE_INGAMESHOP);
}

return false;
}
else if(SEASON3B::IsPress('B'))
{
if(!g_pNewUIGensRanking->SetGensInfo())
return false;

g_pNewUISystem->Toggle(SEASON3B::INTERFACE_GENSRANKING);
PlayBuffer(SOUND_CLICK01);
return false;
}

return true;
}
Bon Dia

Dakosmu


[FIX] Monstruos: Solución a la Animación de Muerte

Regístrate para ver el enlace

Buscar
w_CharacterInfo.h
remplazar a este BYTE        Dead;

por este float        Dead;
Bon Dia

Dakosmu

FIX: No Daño con Evil Spirit (Multi Skill)

Descripción del Problema:
Al usar la habilidad Evil Spirit con múltiples objetivos (multi skill), el cliente no enviaba el paquete de ataque al servidor, lo que causaba que los personajes o monstruos afectados recibieran el efecto visual (como el stun) pero no el daño.

---
Pasos para Aplicar la Solución

1. Identificar el Archivo a Modificar

El código a modificar se encuentra en el source de tu cliente (Main), en el archivo:
  • ZzzEffect.cpp

2. Realizar el Reemplazo
  • Abre el archivo ZzzEffect.cpp en el source de tu Main.
  • Busca la función: bool AttackCharacterRange(int Index, vec3_t Position, float Range, BYTE Serial, short PKKey, WORD SkillSerialNum).
  • Reemplaza la función existente por el código completo proporcionado en el siguiente paso. (Generalmente, la función original solo contiene return false;).

---
Código Reemplazado y Comentado

Este es el bloque de código C++ completo que debes insertar. Únicamente este bloque va dentro de las etiquetas :

[code]
bool AttackCharacterRange(int Index, vec3_t Position, float Range, BYTE Serial, short PKKey, WORD SkillSerialNum) {
      // Obtenemos la ID de la habilidad que se está usando
      int Skill = CharacterAttribute->Skill[Index];
     
      int      Count = 0;             // Contador de objetivos afectados
      int      DamageKey[5];          // Array para almacenar las "Keys" (índices) de los objetivos (máximo 5)
      bool     DamageChr = false;     // Bandera que permite el daño a otros personajes
     
      // 1. CHEQUEO DE ZONAS SEGURAS EN CASTLE SIEGE
      // Si estamos en Castle Siege y el evento ha comenzado
      if (gMapManager.InBattleCastle() && battleCastle::IsBattleCastleStart())
      {
         // Obtiene el atributo del terreno en la posición de ataque
         DWORD att = TERRAIN_ATTRIBUTE(Position[0], Position[1]);
         // Si la zona es una ZONA DE NO ATAQUE (TW_NOATTACKZONE), cancela el ataque.
         if ((att & TW_NOATTACKZONE) == TW_NOATTACKZONE)
         {
            return false;
         }
         // Si no es zona de no ataque, permitimos el daño a personajes (necesario en CS).
         DamageChr = true;
      }
     
      // 2. BÚSQUEDA DE OBJETIVOS DENTRO DEL RANGO
      for (int i = 0; i < MAX_CHARACTERS_CLIENT; i++)
      {
         CHARACTER* c = &CharactersClient[i];
         OBJECT* o = &c->Object;
         
         // Saltar si el objetivo no está vivo, no es visible, es el propio Hero o está muerto.
         if (o->Live == false
            || o->Visible == false
            || c == Hero
            || (bool)c->Dead == true)
         {
            continue;
         }
         
         // Calcula la distancia euclidiana (Pythagoras) entre el punto de ataque y el objetivo.
         float dx = Position[0] - o->Position[0];
         float dy = Position[1] - o->Position[1];
         float Distance = sqrtf(dx * dx + dy * dy);
         
         // Si el objetivo está dentro del rango...
         if (Distance <= Range
            // Y es un MONSTRUO O (es un JUGADOR y tiene la PKKey correcta O estamos en una zona que permite daño)
            && (o->Kind == KIND_MONSTER || (o->Kind == KIND_PLAYER && (c->Key == PKKey || DamageChr))))
         {
            // 3. LÓGICA ESPECÍFICA PARA HABILIDADES DE STUN/FREEZE (EVIL SPIRIT / STORM)
            // Si la habilidad es AT_SKILL_STORM o AT_SKILL_EVIL o una de sus variantes.
            if (Skill == AT_SKILL_STORM || Skill == AT_SKILL_EVIL || (AT_SKILL_EVIL_SPIRIT_UP <= Skill && AT_SKILL_EVIL_SPIRIT_UP + 4 >= Skill) || (AT_SKILL_EVIL_SPIRIT_UP_M <= Skill && AT_SKILL_EVIL_SPIRIT_UP_M + 4 >= Skill)
               )
            {
               // Si el personaje NO está en forma fija (e.g., transformado o inmune a control de masas)
               if (c->m_bFixForm == false)
               {
                  c->StormTime = 10; // Aplica un "tiempo de Storm" (posiblemente un stun visual).
               }
               
               // Exclusiones: Si es un monstruo específico (jefes o monstruos inmunes), no aplica el StormTime.
               if (c->MonsterIndex >= 459 && c->MonsterIndex <= 462)
               {
                  c->StormTime = 0;
               }
               else if (524 <= c->MonsterIndex && c->MonsterIndex <= 528)
               {
                  c->StormTime = 0;
               }
            }
           
            // 4. AÑADIR OBJETIVO A LA LISTA
            DamageKey[Count++] = c->Key; // Almacena la Key del objetivo y aumenta el contador.
            if (Count >= 5) // Si hemos alcanzado el límite de 5 objetivos, salimos del bucle.
            {
               break;
            }
         }
      }
     
      // 5. ENVIAR PAQUETE DE ATAQUE AL SERVIDOR
      if (Count > 0) // Si se encontró al menos un objetivo...
      {
         // Lógica específica para habilidades como Dark Scream o Fire Scream (necesitan un paquete especial).
         if (Skill == AT_SKILL_DARK_SCREAM || (AT_SKILL_FIRE_SCREAM_UP <= Skill && AT_SKILL_FIRE_SCREAM_UP + 4 >= Skill))
         {
            BYTE _SerialTemp = (BYTE)SkillSerialNum;
            // Envía la solicitud de ataque mágico/de rango al servidor.
            SendRequestMagicAttack(Skill, (int)(Position[0] / TERRAIN_SCALE), (int)(Position[1] / TERRAIN_SCALE), _SerialTemp, Count, DamageKey, SkillSerialNum);
         }
         else
         {
            // Lógica para el resto de habilidades de rango/AoE.
            if (Skill != AT_SKILL_MULTI_SHOT)
            {
               // Envía la solicitud de ataque al servidor.
               SendRequestMagicAttack(Skill, (int)(Position[0] / TERRAIN_SCALE), (int)(Position[1] / TERRAIN_SCALE), Serial, Count, DamageKey, SkillSerialNum);
            }
            // Multi-Shot no envía paquete aquí (se maneja de otra forma, típicamente por proyectiles individuales).
         }
         return true; // Éxito: Se envió el paquete de ataque.
      }
      return false; // Fracaso: No se encontraron objetivos.
}

---
Pasos Finales
  • Compila tu proyecto de Main.
  • Asegúrate de que todas las variables y funciones utilizadas estén correctamente definidas en tus #include.
Bon Dia

Dakosmu

Corrección de Animación del Fenrir (Cliente)

Descripción del Problema:
Esta corrección soluciona el problema de que el Fenrir (Red, Blue, Black o Gold) se quede congelado o no muestre la animación correcta (caminar/correr) en el cliente, a pesar de que el personaje se está moviendo. La solución asegura que la animación se actualice antes de aplicar la lógica específica del Fenrir.

---
Pasos de Implementación

Esta corrección debe realizarse en el source de tu cliente (Main).

1. Ubicar el Archivo y la Función
  • Abre el archivo GOBoid.cpp.
  • Busca la función:

bool MoveBug ( OBJECT* o, bool bForceRender )

2. Realizar la Inserción del Código

Dentro de la función MoveBug, debes insertar una línea de código justo antes de que comience el bloque switch que maneja los modelos de Fenrir.

Busca las líneas inmediatamente anteriores a:
switch (o->Type)
{
case MODEL_FENRIR_BLACK:
// ...

Inserta el nuevo código en ese punto, de modo que el bloque se vea así:

bool MoveBug ( OBJECT* o, bool bForceRender )
{
    // ... (código anterior)
   
    // <<-- INSERTA ESTA LÍNEA AQUÍ (Fix FENRIR_WALK/FENRIR_RUN)
    b->PlayAnimation(&o->AnimationFrame, &o->PriorAnimationFrame, &o->PriorAction, o->Velocity, o->Position, o->Angle);
   
    switch (o->Type)
    {
    case MODEL_FENRIR_BLACK:
    case MODEL_FENRIR_BLUE:
    case MODEL_FENRIR_RED:
    case MODEL_FENRIR_GOLD:
    // ... (resto del switch)

3. Explicación del Código Añado
  • b->PlayAnimation(...): Esta línea fuerza la actualización inmediata de la animación del objeto (boid b) usando la velocidad, posición y ángulo actuales del objeto (o).
  • Propósito: Al ejecutar PlayAnimation antes de la lógica específica del Fenrir, se asegura que los datos de animación (o->AnimationFrame, etc.) estén sincronizados correctamente. Esto corrige el bug visual donde el Fenrir se congelaba o usaba una animación de reposo mientras el personaje se movía.

4. Compilar
  • Una vez insertada la línea en GOBoid.cpp, compila el proyecto de tu Main (cliente).
Bon Dia

bigrealtk92


finalfts24

When im starting Gameserver, the log show Could not connect to Databse?
I dont know why, i had edit Database name and change all dtb name to this name :(
Im running Connect Server, Data Server, Join Server is oke, but GameServer is not

Dakosmu

Regístrate para ver el enlaceWhen im starting Gameserver, the log show Could not connect to Databse?
I dont know why, i had edit Database name and change all dtb name to this name :(
Im running Connect Server, Data Server, Join Server is oke, but GameServer is not

Regístrate para ver el enlace

usar guia apra instalar server
Bon Dia

Dakosmu

Bon Dia

🡱 🡳
Real Time Web Analytics