WhatsApp Discord
Fixing Shadows for Characters, Armors, Wings and Pets in Main 5.2 Client - Source Mu - Mu Server Files
 

Fixing Shadows for Characters, Armors, Wings and Pets in Main 5.2 Client

Publicado por Dakosmu, Dic 09, 2025, 07:14 PM

Tema anterior - Siguiente tema

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

Dakosmu

✅ Guía Paso a Paso: Corrigiendo Sombras en Main 5.2 (Personajes, Armaduras, Alas y Pets) ✅

¡Volvamos a activar la comunidad MU!
Gracias a todos los que han compartido desinteresadamente sus correcciones en el pasado. Espero que más personas se unan y contribuyan con sus soluciones.


  • 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

---

🛠� ARCHIVO 1: GOBoid.cpp 🛠�

Paso 1: Abre el archivo GOBoid.cpp.

Paso 2: Busca la siguiente línea de código:
bool RenderBug(OBJECT* o, bool bForceRender)
Paso 3: Añade el siguiente bloque de código debajo de la línea que encontraste en el Paso 2:
RenderObject(o, false, 0, State);

// 1) 查找这个只属于该对象对应的主人 CHARACTER(通过 Owner 指针)
CHARACTER* ownerChar = nullptr;
for (int i = 0; i < MAX_CHARACTERS_CLIENT; ++i)
{
CHARACTER* c = &CharactersClient[i];
if (&c->Object == o->Owner)
{
ownerChar = c;
break;
}
}

// 2) 确定"不带影子"类型

// 自定义类型宠物(你原来用的检测)
bool isCustomPet = (gCustomPet2.CheckCustomPetByItem(o->Type - 1171) == 1);

// 默认 Helper2 / Helper3(根据主人 Helper.Type 来区分,而不是 Hero)
bool isDefaultHelper2 = false;
bool isDefaultHelper3 = false;

if (ownerChar)
{
isDefaultHelper2 = (ownerChar->Helper.Type == MODEL_HELPER + 2);
isDefaultHelper3 = (ownerChar->Helper.Type == MODEL_HELPER + 3);
}

// 3) 安全区判断:
// - 自定义宠物:安全区内外都可以有影子
// - MODEL_HELPER+2 / +3:安全区内不显示影子
bool blockShadowInSafeZone = false;
if (ownerChar && ownerChar->SafeZone)
{
if (isDefaultHelper2 || isDefaultHelper3)
blockShadowInSafeZone = true;
}

// 4) 最终判定是否需要显示影子
bool needShadow = false;

if (isCustomPet)
needShadow = true; // 自定义宠物默认需要影子(忽略地图限制)

if ((isDefaultHelper2 || isDefaultHelper3) && !blockShadowInSafeZone)
needShadow = true; // 默认 Helper2/3,非安全区才需要影子

if (needShadow)
{
// 地图限制:和人物影子规则保持一致
if (gMapManager.WorldActive != WD_10HEAVEN
&& gMapManager.InHellas() == false
&& !g_Direction.m_CKanturu.IsMayaScene())
{
BMD* b = &Models[o->Type];

vec3_t ShadowPos;
VectorCopy(o->Position, ShadowPos);

// 影子定位在地面上
ShadowPos[2] = RequestTerrainHeight(ShadowPos[0], ShadowPos[1]);

// 把模型的 BodyOrigin 赋值到地面位置,方便 RenderBodyShadow 调用
VectorCopy(ShadowPos, b->BodyOrigin);

// 开启 alpha 测试,用于绘制特殊透明度
EnableAlphaTest();
glColor4f(0.f, 0.f, 0.f, 0.3f * o->Alpha);    // 透明度可自行调整

// 使用模型自带的绘制渲染影子
b->RenderBodyShadow();

// 还原为白色,避免影响之后的渲染
glColor4f(1.f, 1.f, 1.f, 1.f);
}
}

// ================== ⭐⭐ 影子追踪结束 ⭐⭐ ==================

---

🛠� ARCHIVO 2: ZzzCharacter.cpp - RenderLinkObject 🛠�

Paso 1: Abre el archivo ZzzCharacter.cpp.

Paso 2: Busca la función:
void RenderLinkObject(float x, float y, float z, CHARACTER* c, PART_t* f, int Type, int Level, int Option1, bool Link, bool Translate, int RenderType, bool bRightHandItem)
Paso 3: Dentro de esa función, busca las líneas que están después del bloque `switch` y antes del cierre del bloque `if (p->Type != -1)` (o cerca de la línea que contiene `CreateSprite(BITMAP_LIGHT_MARKS...` dentro del `if (p->Type != -1)`).

Paso 4: Añade el siguiente bloque de código debajo de:
CreateSprite(BITMAP_LIGHT_MARKS, Position, fSize + 0.3f, vLight, Object, rand() % 360);
}
break;
}
Debe quedar de la siguiente manera:
CreateSprite(BITMAP_LIGHT_MARKS, Position, fSize + 0.3f, vLight, Object, rand() % 360);
}
break;
}
if (gMapManager.WorldActive != WD_10HEAVEN &&!gMapManager.InHellas() &&!g_Direction.m_CKanturu.IsMayaScene())
{
bool handled = false;     // 标记:是否已经在此 switch 里特定处理过

switch (Type)
{
//================= 旧版翅膀:不带光环 =================
case MODEL_WINGS_OF_ELF:        // Wings of Elf
case MODEL_WINGS_OF_HEAVEN:     // Wings of Heaven
case MODEL_WINGS_OF_SATAN:      // Wings of Satan
case MODEL_WING_OF_CURSE:       // Wing of Curse

case MODEL_WINGS_OF_SPIRITS:    // Wings of Spirits
case MODEL_WINGS_OF_SOUL:       // Wings of Soul
case MODEL_WINGS_OF_DRAGON:     // Wings of Dragon
case MODEL_WINGS_OF_DARKNESS:   // Wings of Darkness
case MODEL_WINGS_OF_DESPAIR:    // Wings of Despair

case MODEL_WING_OF_STORM:       // Wing of Storm
case MODEL_WING_OF_ETERNAL:     // Wing of Eternal
case MODEL_WING_OF_ILLUSION:    // Wing of Illusion
case MODEL_WING_OF_RUIN:        // Wing of Ruin
case MODEL_WING_OF_DIMENSION:   // Wing of Dimension

case MODEL_WING + 131:          // Small Wing of Curse
case MODEL_WING + 132:          // Small Wings of Elf
case MODEL_WING + 133:          // Small Wings of Heaven
case MODEL_WING + 134:          // Small Wings of Satan
b->RenderBodyShadow();      // 普通影子
handled = true;
break;

//================= 披风:需要处理光环的影子 =================
case MODEL_CAPE_OF_LORD:        // Cape of Lord
case MODEL_CAPE_OF_FIGHTER:     // Cape of Fighter
case MODEL_CAPE_OF_EMPEROR:     // Cape of Emperor
case MODEL_CAPE_OF_OVERRULE:    // Cape of Overrule
case MODEL_WING + 130:          // Small Cape of Lord
case MODEL_WING + 135:          // Little Warrior's Cloak
b->RenderBodyShadow(-1, -1, -1, -1, o->m_pCloth, o->m_byNumCloth);
handled = true;
break;
}

//================= 默认处理(武器 / 首饰 / 其他) =================
if (!handled)
{
// 如果这个模型有光环,就参考披风那样,不然就普通影子
if (o->m_pCloth && o->m_byNumCloth > 0)
{
b->RenderBodyShadow(-1, -1, -1, -1, o->m_pCloth, o->m_byNumCloth);
}
else
{
b->RenderBodyShadow();
}
}
}

---

🛠� ARCHIVO 2: ZzzCharacter.cpp - RenderCharacter 🛠�

Paso 1: En el mismo archivo ZzzCharacter.cpp, busca la función:
void RenderCharacter(CHARACTER* c, OBJECT* o, int Select)
Paso 2: Dentro de esa función, localiza el siguiente bloque de código:
if (o->Alpha >= 0.5f && c->HideShadow == false)
Paso 3: Reemplaza todo el bloque encontrado en el Paso 2 por la siguiente lógica de sombra corregida:
if (o->Alpha >= 0.5f && c->HideShadow == false)
{
if (gMapManager.WorldActive != WD_10HEAVEN&& (o->Type == MODEL_PLAYER)&& gMapManager.InHellas() == false)
{
if (gMapManager.InBloodCastle() && o->m_bActionStart && c->Dead > 0)
{
float height = RequestTerrainHeight(o->Position[0], o->Position[1]);
if (height < o->Position[2])
{
o->Position[2] = height;
}
}
o->EnableShadow = true;
for (int i = MAX_BODYPART - 1; i >= 0; i--)
{
PART_t* p = &c->BodyPart[i];
if (p->Type != -1)
{
int Type = p->Type;

RenderPartObject(&c->Object, Type, p, c->Light, o->Alpha, 0, 0, 0, false, false, Translate);
}
else
{
RenderPartObject(&c->Object, MODEL_SHADOW_BODY, NULL, c->Light, o->Alpha, 0, 0, 0, false, false, Translate);
}
}

o->EnableShadow = false;
}
}

---

ℹ️ NOTA ADICIONAL ℹ️

Opcional: Puedes añadir una opción para activar/desactivar las sombras en el menú de Configuración (el que se abre con la tecla O).

---
¡Listo! Con estos cambios, las sombras deberían renderizarse correctamente para personajes, armaduras, alas y pets en el cliente Main 5.2.
Bon Dia

🡱 🡳
Real Time Web Analytics