Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

[Development] Source Mu Main 1.03.35 [Season 5.1 - Season 5.2]

Joined
Jul 31, 2012
Messages
490
Reaction score
92
leorond Great this (PLAYER_STOP_RAGEFIGHTER = 283) Works Fine

Please I need help with Skills Structure

typedef struct // SIZE: 0x58
{
char Name[32]; // 0x00
BYTE Level; // 0x20
WORD Damage; // 0x22
WORD Mana; // 0x24
WORD AbilityGuage; // 0x26
BYTE Distance; // 0x28
int Delay; // 0x2C
int Energy; // 0x30
WORD Charisma; // 0x34
BYTE MasteryType; // 0x36
BYTE SkillUseType; // 0x37
BYTE SkillBrand; // 0x38
BYTE KillCount; // 0x3C
BYTE RequireDutyClass[MAX_DUTY_CLASS]; // 0x3D
BYTE RequireClass[MAX_CLASS]; // 0x40
WORD Magic_Icon; // 0x48
BYTE TypeSkill; // 0x4A
int Strength; // 0x4C
int Dexterity; // 0x50
BYTE SkillRank; // 0x54
BYTE IsDamage; // 0x55
WORD unk56; // 0x56
int unk58; // 0x58
} SKILL_ATTRIBUTE;

I am Getting Errors with skills

What are the errors?
What season are you using?
 
Newbie Spellweaver
Joined
Apr 24, 2015
Messages
31
Reaction score
7
I am using Season 6.3 GMO

download - [Development] Source Mu Main 1.03.35 [Season 5.1 - Season 5.2] - RaGEZONE Forums
dsw_pool - [Development] Source Mu Main 1.03.35 [Season 5.1 - Season 5.2] - RaGEZONE Forums
 

Attachments

You must be registered for see attachments list
Joined
Jul 31, 2012
Messages
490
Reaction score
92
I am using Season 6.3 GMO

View attachment 172685
dsw_pool - [Development] Source Mu Main 1.03.35 [Season 5.1 - Season 5.2] - RaGEZONE Forums

I use a slightly different structure

PHP:
typedef struct
{
	char Name[50];
	BYTE Level;
	WORD Damage;
	WORD Mana;
	WORD AbilityGuage;
	BYTE Distance;
	int  Delay;
	int Energy;
	WORD Charisma;
	BYTE MasteryType;
	BYTE SkillUseType; 
	BYTE SkillBrand; 
	BYTE KillCount;
	BYTE RequireDutyClass[MAX_DUTY_CLASS];
	BYTE RequireClass[MAX_CLASS];
	WORD Magic_Icon;
	BYTE TypeSkill;
	int Strength;
	int Dexterity;
	// => 27 arguments
} SKILL_ATTRIBUTE;

But I am loading the spells from a text file

Try changing the size of the skills name

PHP:
	char Name[50];

what about stack in visual studio?
 
Last edited:
Newbie Spellweaver
Joined
Apr 24, 2015
Messages
31
Reaction score
7
I use a slightly different structure

PHP:
typedef struct
{
    char Name[50];
    BYTE Level;
    WORD Damage;
    WORD Mana;
    WORD AbilityGuage;
    BYTE Distance;
    int  Delay;
    int Energy;
    WORD Charisma;
    BYTE MasteryType;
    BYTE SkillUseType; 
    BYTE SkillBrand; 
    BYTE KillCount;
    BYTE RequireDutyClass[MAX_DUTY_CLASS];
    BYTE RequireClass[MAX_CLASS];
    WORD Magic_Icon;
    BYTE TypeSkill;
    int Strength;
    int Dexterity;
    // => 27 arguments
} SKILL_ATTRIBUTE;

But I am loading the spells from a text file

Try changing the size of the skills name

PHP:
    char Name[50];

what about stack in visual studio?

As you see I put the variables size according to Main 6.2 and all Right the problem at the end of the structure

I Had a problem with debugging but gonna try fix and debug
 
Joined
Jul 31, 2012
Messages
490
Reaction score
92
As you see I put the variables size according to Main 6.2 and all Right the problem at the end of the structure

I Had a problem with debugging but gonna try fix and debug

Find this definition and write me how many skills you have set to the maximum number

PHP:
#define MAX_SKILLS

It will be an ill-defined data type.
For example, WORD instead of INT
 
Last edited:
Joined
Jul 31, 2012
Messages
490
Reaction score
92
Count whether there are the same number of columns in the BMD file and the structure

Maybe the last 2 arguments of the structure should be in BYTE



#define MAX_SKILLS 650

Please private message me your Skill_eng.bmd file and this function.

PHP:
void OpenSkillScript(char *FileName)

I will try to find out where the error is
 
Newbie Spellweaver
Joined
Apr 24, 2015
Messages
31
Reaction score
7
@leorond Thx bro For Helping, The problem was in SKILL_STRUCT just Found now

Correct One for 6.3

typedef struct // SIZE: 0x58
{
char Name[32]; // 0x00
WORD Level; // 0x20
WORD Damage; // 0x22
WORD Mana; // 0x24
WORD AbilityGuage; // 0x26
BYTE Distance; // 0x28
int Delay; // 0x2C
int Energy; // 0x30
WORD Charisma; // 0x34
BYTE MasteryType; // 0x36
BYTE SkillUseType; // 0x37
BYTE SkillBrand; // 0x38
BYTE KillCount; // 0x3C
BYTE RequireDutyClass[MAX_DUTY_CLASS]; // 0x3D
BYTE RequireClass[MAX_CLASS]; // 0x40
WORD Magic_Icon; // 0x48
BYTE TypeSkill; // 0x4A
WORD Strength; // 0x4C
WORD Dexterity; // 0x50
WORD unk52; // 0x52
BYTE SkillRank;// 0x54
BYTE IsDamage; // 0x55
WORD unk56; // 0x56
int unk58; // 0x58
} SKILL_ATTRIBUTE;

About Unk Variables didnt look at them yet but they are for MasterSkillTree
 
Newbie Spellweaver
Joined
Nov 17, 2016
Messages
14
Reaction score
19
@leorond Thx bro For Helping, The problem was in SKILL_STRUCT just Found now

Correct One for 6.3

typedef struct // SIZE: 0x58
{
char Name[32]; // 0x00
WORD Level; // 0x20
WORD Damage; // 0x22
WORD Mana; // 0x24
WORD AbilityGuage; // 0x26
BYTE Distance; // 0x28
int Delay; // 0x2C
int Energy; // 0x30
WORD Charisma; // 0x34
BYTE MasteryType; // 0x36
BYTE SkillUseType; // 0x37
BYTE SkillBrand; // 0x38
BYTE KillCount; // 0x3C
BYTE RequireDutyClass[MAX_DUTY_CLASS]; // 0x3D
BYTE RequireClass[MAX_CLASS]; // 0x40
WORD Magic_Icon; // 0x48
BYTE TypeSkill; // 0x4A
WORD Strength; // 0x4C
WORD Dexterity; // 0x50
WORD unk52; // 0x52
BYTE SkillRank;// 0x54
BYTE IsDamage; // 0x55
WORD unk56; // 0x56
int unk58; // 0x58
} SKILL_ATTRIBUTE;

About Unk Variables didnt look at them yet but they are for MasterSkillTree

I remember when i did this for my S6 bmd editor

typedef struct // SIZE: 88
{
/* +00 */ char Name[32];
/* +32 */ BYTE RequireLevel;
/* +33 */ // BYTE FILL (PRAGMA PACK 4)
/* +34 */ WORD Damage;
/* +36 */ WORD ManaUse;
/* +38 */ WORD BPUse;
/* +40 */ BYTE Range;
/* +41 */ // BYTE FILL (PRAGMA PACK 4)
/* +42 */ // BYTE FILL (PRAGMA PACK 4)
/* +43 */ // BYTE FILL (PRAGMA PACK 4)
/* +44 */ DWORD Delay;
/* +48 */ DWORD RequireEnergy;
/* +52 */ WORD RequireCommand;
/* +54 */ BYTE Attribute;
/* +55 */ BYTE UseType;
/* +56 */ DWORD Brand;
/* +60 */ BYTE RequireKillCount;
/* +61 */ BYTE RequireGuildMaster;
/* +62 */ BYTE RequireAssistant;
/* +63 */ BYTE RequireBattleMaster;
/* +64 */ BYTE RequireDW;
/* +65 */ BYTE RequireDK;
/* +66 */ BYTE RequireELF;
/* +67 */ BYTE RequireMG;
/* +68 */ BYTE RequireDL;
/* +69 */ BYTE RequireSUM;
/* +70 */ BYTE RequireRF;
/* +71 */ BYTE SkillRank;
/* +72 */ WORD IconNumber;
/* +74 */ BYTE SkillType;
/* +75 */ // BYTE FILL (PRAGMA PACK 4)
/* +76 */ DWORD RequireStrength;
/* +80 */ DWORD RequireAgility;
/* +84 */ BYTE ItemSkill;
/* +85 */ BYTE IsDamage;
/* +86 */ WORD Effect;
} SKILL_ATTRIBUTE;

Those that says "byte fill" are for the default packing settings that addapts the whole structure to the largets single definition. In this structure, the largest is type "DWORD" so it will pack the data in spaces of 4 bytes.
For example:
if i have -> BYTE BYTE DWORD, the whole structure will size 8 bytes because the first 2 bytes are allocated in a pack of 4 bytes and lets 2 bytes empty and the dword is allocated in another pack of 4 bytes.

source in spanish:
 
Newbie Spellweaver
Joined
Apr 24, 2015
Messages
31
Reaction score
7
Thx Alot @leorond.. Now RF Stands Right.

Do you have idea about this issue (When I Open more than 1 MU Windows and try to take Screenshot in any one of them.. Both Took Screen Shots
How to seperate Each ScreenShot for current window only)

there is new 8 bytes in SKILL_ATTRIBUTE in the end of the struct .. Found them ?

Fix For Seperate Windows All Actions >> if (g_hWnd != GetActiveWindow()) { return; } in Begining of MainScene Function
 
Newbie Spellweaver
Joined
Jul 13, 2019
Messages
84
Reaction score
35
I'm looking at the master skill sheet, it's not working, has anyone done it, can you tell me how to fix it
 
Joined
Jul 31, 2012
Messages
490
Reaction score
92
Fix For Seperate Windows All Actions >> if (g_hWnd != GetActiveWindow()) { return; } in Begining of MainScene Function

Yes, that is the right way.



I'm looking at the master skill sheet, it's not working, has anyone done it, can you tell me how to fix it

Can you be more specific about your problem?



I remember when i did this for my S6 bmd editor

typedef struct // SIZE: 88
{
/* +00 */ char Name[32];
/* +32 */ BYTE RequireLevel;
/* +33 */ // BYTE FILL (PRAGMA PACK 4)
/* +34 */ WORD Damage;
/* +36 */ WORD ManaUse;
/* +38 */ WORD BPUse;
/* +40 */ BYTE Range;
/* +41 */ // BYTE FILL (PRAGMA PACK 4)
/* +42 */ // BYTE FILL (PRAGMA PACK 4)
/* +43 */ // BYTE FILL (PRAGMA PACK 4)
/* +44 */ DWORD Delay;
/* +48 */ DWORD RequireEnergy;
/* +52 */ WORD RequireCommand;
/* +54 */ BYTE Attribute;
/* +55 */ BYTE UseType;
/* +56 */ DWORD Brand;
/* +60 */ BYTE RequireKillCount;
/* +61 */ BYTE RequireGuildMaster;
/* +62 */ BYTE RequireAssistant;
/* +63 */ BYTE RequireBattleMaster;
/* +64 */ BYTE RequireDW;
/* +65 */ BYTE RequireDK;
/* +66 */ BYTE RequireELF;
/* +67 */ BYTE RequireMG;
/* +68 */ BYTE RequireDL;
/* +69 */ BYTE RequireSUM;
/* +70 */ BYTE RequireRF;
/* +71 */ BYTE SkillRank;
/* +72 */ WORD IconNumber;
/* +74 */ BYTE SkillType;
/* +75 */ // BYTE FILL (PRAGMA PACK 4)
/* +76 */ DWORD RequireStrength;
/* +80 */ DWORD RequireAgility;
/* +84 */ BYTE ItemSkill;
/* +85 */ BYTE IsDamage;
/* +86 */ WORD Effect;
} SKILL_ATTRIBUTE;

Those that says "byte fill" are for the default packing settings that addapts the whole structure to the largets single definition. In this structure, the largest is type "DWORD" so it will pack the data in spaces of 4 bytes.
For example:
if i have -> BYTE BYTE DWORD, the whole structure will size 8 bytes because the first 2 bytes are allocated in a pack of 4 bytes and lets 2 bytes empty and the dword is allocated in another pack of 4 bytes.

source in spanish:

Why use BYTE BYTE DWORD?
int64 is the long datatype (8 bytes or 64-bits)
Int64 is an immutable value type that represents signed integers with values that range from negative 9,223,372,036,854,775,808 (which is represented by the Int64.MinValue constant) through positive 9,223,372,036,854,775,807 (which is represented by the Int64.MaxValue constant. The .NET Framework also includes an unsigned 64-bit integer value type, UInt64, which represents values that range from 0 to 18,446,744,073,709,551,615.

Sorry, I misunderstood your post.

Yes, you are right, the structure needs to be aligned.
It can be done better, but it is the right procedure.
 
Last edited:
Newbie Spellweaver
Joined
Jul 13, 2019
Messages
84
Reaction score
35
Yes, that is the right way.





Can you be more specific about your problem?


When I try to add points to the master skill table, it doesn't work, there is no any feedback log of the action so I can track and find the error location,
 
Joined
Jul 31, 2012
Messages
490
Reaction score
92
When dividing points into the master table, the game server verifies whether you are a master character.

As a rule, it is a similar function

PHP:
int CMasterLevelSystem::CheckIsMasterLevelCharacter(LPOBJ lpObj)
{
	if(lpObj == NULL)
	{
		return 0;
	}

	if(lpObj->MLInfoLoad == 0)
	{
		return 0;
	}

	if(lpObj->Level >= 400 && lpObj->ChangeUP3rd == 1)
	{
		return 1;
	}

	return 0;
}
- Then there is the function to verify and add points to the spell
PHP:
void CMasterSkillSystem::CGMasterSkillSend(PMSG_ML_SKILL_RECV_INFO * lpMsg, int aIndex)
{
	if(gObjIsConnected(aIndex) == FALSE)
	{
		CloseClient(aIndex);
		return;
	}

	LPOBJ lpObj = &gObj[aIndex];

	PMSG_ML_SKILL_SEND pMsg;
	
	PHeadSubSetB((LPBYTE)&pMsg, 0xF3, 0x52, sizeof(pMsg));

	pMsg.Result = 0;
	pMsg.MLPoint = lpObj->MLPoint;
	pMsg.MLSkill = -1;
	pMsg.MLSkillLevel = 0;

	int loc7 = MagicDamageC.GetSkillReqLevel(lpMsg->MLSkill);
	int loc8 = this->CheckMagicAdd(lpObj, lpMsg->MLSkill, loc7);

	if(loc8 == 1)
	{
		if(this->MagicAdd(lpObj, lpMsg->MLSkill, loc7) < 0)
		{
			loc8 = 5;
			LogAddTD("[MasterSkill] [%s][%s] Fail - Add Magic List, Skill:%d Level:%d", lpObj->AccountID, lpObj->Name, lpMsg->MLSkill, loc7);
		}
		else
		{
			lpObj->MLPoint -= MagicDamageC.GetSkillReqMLPoint(lpMsg->MLSkill);
			pMsg.Result = loc8;
			pMsg.MLPoint = lpObj->MLPoint;
			pMsg.MLSkill = lpMsg->MLSkill;
			pMsg.MLSkillLevel = loc7;

			this->AddPassiveSkill(lpObj, lpMsg->MLSkill, loc7);

			LogAddTD("[MasterSkill] [%s][%s] Success - Add Magic List, Skill:%d Level:%d MLPoint:%d", lpObj->AccountID, lpObj->Name, lpMsg->MLSkill, loc7, lpObj->MLPoint);
		}
	}
	else
	{
		pMsg.Result = loc8;
	}

	DataSend(lpObj->m_Index, (LPBYTE)&pMsg, pMsg.h.size);
}
- And finally, the last function of the verification itself
PHP:
int CMasterSkillSystem::CheckMagicAdd(LPOBJ lpObj, int skill, int level)
{
	if(gObjIsConnected(lpObj) == FALSE)
	{
		GCResultSend(lpObj->m_Index, 0x51, 3);
		return 2;
	}

	if ( skill < 0 || skill > MAX_SKILL-1 )
	{
		LogAdd(lMsg.Get(MSGGET(1, 201)), __FILE__, __LINE__);
		return 3;
	}

	if(g_MasterLevelSystem.CheckIsMasterLevelCharacter(lpObj) == 0)
	{
		return 2;
	}

	if(g_MasterSkillSystem.CheckRequireStatus(skill) == 0) //should be "this->" lol
	{
		return 4;
	}

	int loc2 = MagicDamageC.GetSkillReqMLPoint(skill); //Check Requirement

	if(lpObj->MLPoint < loc2)
	{
		return 4;
	}

	if(this->FindPrimarySkill(lpObj, skill) == 0) //Former Skill
	{
		return 4;
	}

	int loc3 = MagicDamageC.GetSkillGroup(skill); //Check Skill
	int loc4 = 0;

	if(level > 1)
	{
		for(int i = 0; i < MAX_MAGIC; i++)
		{
			if(lpObj->Magic[i].IsMagic() == TRUE)
			{
				loc4 = MagicDamageC.GetSkillGroup(lpObj->Magic[i].m_Skill); //ebp10

				if(loc4 > 0)
				{
					if(loc4 == loc3 && lpObj->Magic[i].m_Skill == skill - 1 && lpObj->Magic[i].m_Level == level - 1)
					{
						return 1;
					}
				}
			}
		}
		return 4;
	}
	return 1;
}
- Put a message in each condition, for example
PHP:
LogAdd("[MasterSkill] Fail %s %d",__FILE__,__LINE__);

If the point is not added and it goes through the protocol from the game client to the game server, you will immediately see which line and in which file there is a problem.
 
Newbie Spellweaver
Joined
Jul 13, 2019
Messages
84
Reaction score
35
When dividing points into the master table, the game server verifies whether you are a master character.

As a rule, it is a similar function

PHP:
int CMasterLevelSystem::CheckIsMasterLevelCharacter(LPOBJ lpObj)
{
    if(lpObj == NULL)
    {
        return 0;
    }

    if(lpObj->MLInfoLoad == 0)
    {
        return 0;
    }

    if(lpObj->Level >= 400 && lpObj->ChangeUP3rd == 1)
    {
        return 1;
    }

    return 0;
}
- Then there is the function to verify and add points to the spell
PHP:
void CMasterSkillSystem::CGMasterSkillSend(PMSG_ML_SKILL_RECV_INFO * lpMsg, int aIndex)
{
    if(gObjIsConnected(aIndex) == FALSE)
    {
        CloseClient(aIndex);
        return;
    }

    LPOBJ lpObj = &gObj[aIndex];

    PMSG_ML_SKILL_SEND pMsg;
    
    PHeadSubSetB((LPBYTE)&pMsg, 0xF3, 0x52, sizeof(pMsg));

    pMsg.Result = 0;
    pMsg.MLPoint = lpObj->MLPoint;
    pMsg.MLSkill = -1;
    pMsg.MLSkillLevel = 0;

    int loc7 = MagicDamageC.GetSkillReqLevel(lpMsg->MLSkill);
    int loc8 = this->CheckMagicAdd(lpObj, lpMsg->MLSkill, loc7);

    if(loc8 == 1)
    {
        if(this->MagicAdd(lpObj, lpMsg->MLSkill, loc7) < 0)
        {
            loc8 = 5;
            LogAddTD("[MasterSkill] [%s][%s] Fail - Add Magic List, Skill:%d Level:%d", lpObj->AccountID, lpObj->Name, lpMsg->MLSkill, loc7);
        }
        else
        {
            lpObj->MLPoint -= MagicDamageC.GetSkillReqMLPoint(lpMsg->MLSkill);
            pMsg.Result = loc8;
            pMsg.MLPoint = lpObj->MLPoint;
            pMsg.MLSkill = lpMsg->MLSkill;
            pMsg.MLSkillLevel = loc7;

            this->AddPassiveSkill(lpObj, lpMsg->MLSkill, loc7);

            LogAddTD("[MasterSkill] [%s][%s] Success - Add Magic List, Skill:%d Level:%d MLPoint:%d", lpObj->AccountID, lpObj->Name, lpMsg->MLSkill, loc7, lpObj->MLPoint);
        }
    }
    else
    {
        pMsg.Result = loc8;
    }

    DataSend(lpObj->m_Index, (LPBYTE)&pMsg, pMsg.h.size);
}
- And finally, the last function of the verification itself
PHP:
int CMasterSkillSystem::CheckMagicAdd(LPOBJ lpObj, int skill, int level)
{
    if(gObjIsConnected(lpObj) == FALSE)
    {
        GCResultSend(lpObj->m_Index, 0x51, 3);
        return 2;
    }

    if ( skill < 0 || skill > MAX_SKILL-1 )
    {
        LogAdd(lMsg.Get(MSGGET(1, 201)), __FILE__, __LINE__);
        return 3;
    }

    if(g_MasterLevelSystem.CheckIsMasterLevelCharacter(lpObj) == 0)
    {
        return 2;
    }

    if(g_MasterSkillSystem.CheckRequireStatus(skill) == 0) //should be "this->" lol
    {
        return 4;
    }

    int loc2 = MagicDamageC.GetSkillReqMLPoint(skill); //Check Requirement

    if(lpObj->MLPoint < loc2)
    {
        return 4;
    }

    if(this->FindPrimarySkill(lpObj, skill) == 0) //Former Skill
    {
        return 4;
    }

    int loc3 = MagicDamageC.GetSkillGroup(skill); //Check Skill
    int loc4 = 0;

    if(level > 1)
    {
        for(int i = 0; i < MAX_MAGIC; i++)
        {
            if(lpObj->Magic[i].IsMagic() == TRUE)
            {
                loc4 = MagicDamageC.GetSkillGroup(lpObj->Magic[i].m_Skill); //ebp10

                if(loc4 > 0)
                {
                    if(loc4 == loc3 && lpObj->Magic[i].m_Skill == skill - 1 && lpObj->Magic[i].m_Level == level - 1)
                    {
                        return 1;
                    }
                }
            }
        }
        return 4;
    }
    return 1;
}
- Put a message in each condition, for example
PHP:
LogAdd("[MasterSkill] Fail %s %d",__FILE__,__LINE__);

If the point is not added and it goes through the protocol from the game client to the game server, you will immediately see which line and in which file there is a problem.


thank you very much, i will try to check according to what you suggested
 
Joined
Jul 31, 2012
Messages
490
Reaction score
92
thank you very much, i will try to check according to what you suggested

Don't forget that the function doesn't have to have the same name.
You have to search.
According to these functions, the protocol call in the game client can also be traced.



Has anyone managed an interesting fix or improvement that they would like to share with us?

3D Camera, Separate system messages from chat,...
 
Newbie Spellweaver
Joined
Jul 13, 2019
Messages
84
Reaction score
35
I try downgrade to season 3




 
Back
Top