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] Trying Add Custom Monsters Or NPC

Joined
Mar 13, 2008
Messages
758
Reaction score
1,002
Well i am trying add a custom monster or NPC.

Main 1.02r

Offsets:

00533800 CMP EAX,172 -> Here compare max monster support. if is eax>172 than mob transform in a Bull.

i recommend make a jmp before of cmp eax,172 for compare a new npc or mob.

00533800 E9 EA3C1B00 JMP Main_102.006E74EF

006E74EF 8D47 FF LEA EAX,DWORD PTR DS:[EDI-1]
006E74F2 3D DE010000 CMP EAX,1DE //ID OF MOB TITUS
006E74F7 75 07 JNZ SHORT Main_102.006E7500
006E74FE EB 3A JMP SHORT Main_102.006E753A // JMP TO LOAD MY NPC
006E7500 3D 72010000 CMP EAX,172
006E7505 ^0F87 FAEDE4FF JA Main_102.00536305
006E750B 33C9 XOR ECX,ECX
006E750D 8A88 2C665300 MOV CL,BYTE PTR DS:[EAX+53662C]
006E7513 FF248D 20645300 JMP DWORD PTR DS:[ECX*4+536420]


LOAD MY NPC

WARNING NOT ALL NPC OR MOBS IS LOADED HOW THIS.

006E753A 68 00030000 PUSH 300
006E753F E8 4C04F6FF CALL Main_102.00647990
006E7544 8B4D 0C MOV ECX,DWORD PTR SS:[EBP+C]
006E7547 6A 00 PUSH 0
006E7549 53 PUSH EBX
006E754A 51 PUSH ECX
006E754B 68 00030000 PUSH 300
006E7550 56 PUSH ESI
006E7551 E8 3AA7E4FF CALL Main_102.00531C90
006E7556 8BD8 MOV EBX,EAX
006E7558 BF 78A16F00 MOV EDI,Main_102.006FA178
006E755D 83C9 FF OR ECX,FFFFFFFF
006E7560 33C0 XOR EAX,EAX
006E7562 83C4 18 ADD ESP,18
006E7565 8D93 0D020000 LEA EDX,DWORD PTR DS:[EBX+20D]
006E756B F2:AE REPNE SCAS BYTE PTR ES:[EDI]
006E756D F7D1 NOT ECX
006E756F 2BF9 SUB EDI,ECX
006E7571 8BC1 MOV EAX,ECX
006E7573 8BF7 MOV ESI,EDI
006E7575 8BFA MOV EDI,EDX
006E7577 C1E9 02 SHR ECX,2
006E757A F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:>
006E757C 8BC8 MOV ECX,EAX
006E757E 83E1 03 AND ECX,3
006E7581 F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[E>
006E7583 ^E9 7AEEE4FF JMP Main_102.00536402

006479C9 CMP EAX,43 Here i dont know what compare but later of this do a jmp to offset for charge X (Npc or monster). Here we need do change JA xxxx to a new offset where we will to compare the value of monster or npc.

in my case i use npc 479 Titus

i change offset JA xxxx to JA 006E7588 and there i put it.

006E7588 3D 07010000 CMP EAX,107 //Value of my mob or NPC
006E758D 74 09 JE SHORT Main_102.006E7598 // If is true jmp to 6e7598
006E758F 90 NOP
006E7590 90 NOP
006E7591 90 NOP
006E7592 90 NOP
006E7593 ^E9 A70DF6FF JMP Main_102.0064833F
006E7598 33D2 XOR EDX,EDX //we need do it for charge movements of mob
006E759A ^E9 17FFFFFF JMP Main_102.006E74B6 //here jmp to Load my custom npc

Loading NPC Titus

WARNING NOT ALL NPC OR MOBS IS LOADED HOW THIS.

006E74B6 6A FF PUSH -1
006E74B8 68 E7746E00 PUSH Main_102.006E74E7 ; ASCII "titus"
006E74BD 68 34856F00 PUSH Main_102.006F8534 ; ASCII "Data\Npc\"
006E74C2 68 00030000 PUSH 300 //This need be changed on new npc
006E74C7 E8 34B7F5FF CALL Main_102.00642C00
006E74CC 6A 01 PUSH 1
006E74CE 68 00260000 PUSH 2600
006E74D3 68 01290000 PUSH 2901
006E74D8 68 2C856F00 PUSH Main_102.006F852C ; ASCII "Npc\"
006E74DD 68 00030000 PUSH 300 //This need be changed on new npc
006E74E2 ^E9 500EF6FF JMP Main_102.00648337

Results.

Pinkof - [Development] Trying Add Custom Monsters Or NPC - RaGEZONE Forums



now i have a problem i cant talk with the npc maybe someone can help to fix it.

More later i will upload my main with titus NPC.
 
Junior Spellweaver
Joined
Aug 5, 2008
Messages
149
Reaction score
38
Nice work pink ^^ i made this time ago but i never get the usefull of this cuz i not code into gameserver for get new function or something XDD maybe just for add monsters and make a custom for new events :D
 
Hybrid
Loyal Member
Joined
Mar 15, 2006
Messages
451
Reaction score
285
there is a code that compares monster IDs and makes them act like NPCs.
you can either set bp on talk request packet(use regular NPCs) and analyze functions in call stack, or try to search code by regular NPCs IDs.

in old mains for adding NEW mobs(npcs) you will have to allocate more memory for models than main does, or you may have conflict problems, except for mobs(npcs) with player model, since it's already loaded =)
 
Experienced Elementalist
Joined
Oct 11, 2008
Messages
225
Reaction score
423
Everything is much simpler:
1. Object attr (like NPC / Mob / None) stored in one struct in main, like OBJECTSTRUCT from server
2. Everything that is necessary - load model for monster id, other changes can make in struct

About you problem with talk:
- You need change attr for you new Object in struct, set param +722 (BYTE) == 4 (1 = Player, 2 = Monster, 4 = NPC)

Example with Elf Soldier:
Code:
// -> 515596 -> 1 Call
int gMakePreviewSoldierElf(int StructAddr) 
{
	Preview * gPreview = &*(Preview*)StructAddr;
	// ----
	gPreview->WingsSlot			= ITEM2(12, 3);
	// ----
	gPreview->HelmSlot			= ITEM2(7, 24);
	gPreview->HelmLevel			= 13;
	// ----
	gPreview->ArmorSlot			= ITEM2(8, 24);
	gPreview->ArmorLevel		= 13;
	// ----
	gPreview->PantsSlot			= ITEM2(9, 24);
	gPreview->PantsLevel		= 13;
	// ----
	gPreview->GlovesSlot		= ITEM2(10, 24);
	gPreview->GlovesLevel		= 13;
	// ----
	gPreview->BootsSlot			= ITEM2(11, 24);
	gPreview->BootsLevel		= 13;
	// ----
	gPreview->Action			= 11;
	gPreview->ModelScale		= 0x3F800000;
	gPreview->SelectZone		+= 70.0;
	// ----
	return gPreview->Unknown700;
}

In this function main set special attr for this NPC, like items, model scale, action, pk status and etc.

530802 ( int gObjSetAttr(Preview * gPreview, int ObjectID) )
- this function set Object attr from ID, you can use it, example:

Code:
if( ObjectID == 368 || ObjectID == 369 || ObjectID == 370 )
{
	*(BYTE *)(gPreview + 722) = 4; //-> Set NPC status to Object
}
if( ObjectID == 367
	|| ObjectID == 371
	|| ObjectID == 375
	|| ObjectID == 376
	|| ObjectID == 377
	|| ObjectID == 379
	|| ObjectID == 380
	|| ObjectID == 381
	|| ObjectID == 382
	|| ObjectID == 383
	|| ObjectID == 384
	|| ObjectID == 385
	|| ObjectID == 406
	|| ObjectID == 407
	|| ObjectID == 408
	|| ObjectID == 414
	|| ObjectID == 415
	|| ObjectID == 416
	|| ObjectID == 417
	|| ObjectID == 450
	|| ObjectID == 452
	|| ObjectID == 453
	|| ObjectID == 464
	|| ObjectID == 465
	|| ObjectID == 467
	|| ObjectID == 468
	|| ObjectID == 469
	|| ObjectID == 470
	|| ObjectID == 471
	|| ObjectID == 472
	|| ObjectID == 473
	|| ObjectID == 474
	|| ObjectID == 475
	|| ObjectID == 478
	|| ObjectID == 479
	|| ObjectID == 492
	|| ObjectID == 540
	|| ObjectID == 541
	|| ObjectID == 542
	|| ObjectID == 522
	|| ObjectID == 543
	|| ObjectID == 544
	|| ObjectID == 545
	|| ObjectID == 546
	|| ObjectID == 547 )
{
	*(BYTE *)(gPreview + 722) = 4; //-> Set NPC status to Object
}

Full function:

Code:
//530802	->
int gObjSetAttr(Preview * gPreview, int ObjectID) 
{
	int Result = *(DWORD*)oMapNumber - 9;	//-> int 92114C
	int MapNumber = Result;
	// ----
	if( MapNumber - 9 > 0 && MapNumber <= 8 && ObjectID >= 84 && ObjectID <= 143 )
	{
		gPreview->Unknown98 = 0;	//-> WORD +98
		Result = (int)gPreview;		//-> Return struct addr
		// ----
		gPreview->ModelScale += (double)(MapNumber / 3) * 0.050000001; //-> float +796
	}
	// ----
	if( gPreview )
	{
		for( i = 0; i < 1024; i++ ) //-> Max monster space
		{
			if( ObjectID == word_7B522E8[27 * i] )	//-> Filled monster table, maybe store names
			{
				gSetDisplayMonsterTarget(gPreview + 56);	//-> 8AAC00
				break;
			}
		}
		// ----
		gPreview->Unknown100 = ObjectID;	//-> WORD +100
		Result = (int)gPreview; //-> Return struct addr
		// ----
		gPreview->Unknown720	= 0;	//-> BYTE +720
		gPreview->Unknown96		= dword_81A01CC;	//-> WORD +96
		// ----
		if( ObjectID == 200 )	//Soccerball
		{
			Result = gPreview->Unknown700;	//-> Some result value for many functions
			gPreview->ObjectType = 2;	//-> BYTE +722, set monster type for Soccerball 
		}
		else
		{
			if( ObjectID < 260 )
			{
				if( ObjectID <= 200 )
				{
					if( ObjectID < 150 )
					{
						if( ObjectID <= 110 )
						{
							if( ObjectID < 100 )
							{
								Result = gPreview->Unknown700;
								gPreview->ObjectType = 2; //-> Set Monster object type
							}
							else
							{
								gPreview->ObjectType = 8;	//-> Set NONE object type
							}
						}
						else
						{
							gPreview->ObjectType = 2; //-> Set Monster object type
						}
					}
					else
					{
						Result = gPreview->Unknown700;
						gPreview->ObjectType = 2; //-> Set Monster object type
					}
				}
				else
				{
					gPreview->ObjectType = 4; //-> Set NPC object type
				}
			}
			else
			{
				gPreview->ObjectType = 2; //-> Set Monster object type
			}
		}
		// ----
		if( ObjectID == 368 || ObjectID == 369 || ObjectID == 370 )
		{
			gPreview->ObjectType = 4; //-> Set NPC object type
		}
		if( ObjectID == 367
			|| ObjectID == 371
			|| ObjectID == 375
			|| ObjectID == 376
			|| ObjectID == 377
			|| ObjectID == 379
			|| ObjectID == 380
			|| ObjectID == 381
			|| ObjectID == 382
			|| ObjectID == 383
			|| ObjectID == 384
			|| ObjectID == 385
			|| ObjectID == 406
			|| ObjectID == 407
			|| ObjectID == 408
			|| ObjectID == 414
			|| ObjectID == 415
			|| ObjectID == 416
			|| ObjectID == 417
			|| ObjectID == 450
			|| ObjectID == 452
			|| ObjectID == 453
			|| ObjectID == 464
			|| ObjectID == 465
			|| ObjectID == 467
			|| ObjectID == 468
			|| ObjectID == 469
			|| ObjectID == 470
			|| ObjectID == 471
			|| ObjectID == 472
			|| ObjectID == 473
			|| ObjectID == 474
			|| ObjectID == 475
			|| ObjectID == 478
			|| ObjectID == 479
			|| ObjectID == 492
			|| ObjectID == 540
			|| ObjectID == 541
			|| ObjectID == 542
			|| ObjectID == 522
			|| ObjectID == 543
			|| ObjectID == 544
			|| ObjectID == 545
			|| ObjectID == 546
			|| ObjectID == 547 )
		{
			gPreview->ObjectType = 4; //-> Set NPC object type
		}
		// ----
		if( ObjectID >= 480 && ObjectID <= 491 )
		{
			Result = gPreview->Unknown700;
			gPreview->ObjectType = 2; //-> Set Monster object type
		}
		// ----
		if( ObjectID == 451 )
		{
			gPreview->ObjectType = 0x80u;	//-> Cherry Blossom Tree, set NONE Object type
		}
	}
	// ----
	return Result;
}

My offsets from 1.03.28 GMO, good luck)

P.S.: Screen =D
Pinkof - [Development] Trying Add Custom Monsters Or NPC - RaGEZONE Forums
 
Last edited:
Joined
Mar 13, 2008
Messages
758
Reaction score
1,002
Everything is much simpler:
1. Object attr (like NPC / Mob / None) stored in one struct in main, like OBJECTSTRUCT from server
2. Everything that is necessary - load model for monster id, other changes can make in struct

About you problem with talk:
- You need change attr for you new Object in struct, set param +722 (BYTE) == 4 (1 = Player, 2 = Monster, 4 = NPC)

Example with Elf Soldier:
Code:
// -> 515596 -> 1 Call
int gMakePreviewSoldierElf(int StructAddr) 
{
    Preview * gPreview = &*(Preview*)StructAddr;
    // ----
    gPreview->WingsSlot            = ITEM2(12, 3);
    // ----
    gPreview->HelmSlot            = ITEM2(7, 24);
    gPreview->HelmLevel            = 13;
    // ----
    gPreview->ArmorSlot            = ITEM2(8, 24);
    gPreview->ArmorLevel        = 13;
    // ----
    gPreview->PantsSlot            = ITEM2(9, 24);
    gPreview->PantsLevel        = 13;
    // ----
    gPreview->GlovesSlot        = ITEM2(10, 24);
    gPreview->GlovesLevel        = 13;
    // ----
    gPreview->BootsSlot            = ITEM2(11, 24);
    gPreview->BootsLevel        = 13;
    // ----
    gPreview->Action            = 11;
    gPreview->ModelScale        = 0x3F800000;
    gPreview->SelectZone        += 70.0;
    // ----
    return gPreview->Unknown700;
}

In this function main set special attr for this NPC, like items, model scale, action, pk status and etc.

530802 ( int gObjSetAttr(Preview * gPreview, int ObjectID) )
- this function set Object attr from ID, you can use it, example:

Code:
if( ObjectID == 368 || ObjectID == 369 || ObjectID == 370 )
{
    *(BYTE *)(gPreview + 722) = 4; //-> Set NPC status to Object
}
if( ObjectID == 367
    || ObjectID == 371
    || ObjectID == 375
    || ObjectID == 376
    || ObjectID == 377
    || ObjectID == 379
    || ObjectID == 380
    || ObjectID == 381
    || ObjectID == 382
    || ObjectID == 383
    || ObjectID == 384
    || ObjectID == 385
    || ObjectID == 406
    || ObjectID == 407
    || ObjectID == 408
    || ObjectID == 414
    || ObjectID == 415
    || ObjectID == 416
    || ObjectID == 417
    || ObjectID == 450
    || ObjectID == 452
    || ObjectID == 453
    || ObjectID == 464
    || ObjectID == 465
    || ObjectID == 467
    || ObjectID == 468
    || ObjectID == 469
    || ObjectID == 470
    || ObjectID == 471
    || ObjectID == 472
    || ObjectID == 473
    || ObjectID == 474
    || ObjectID == 475
    || ObjectID == 478
    || ObjectID == 479
    || ObjectID == 492
    || ObjectID == 540
    || ObjectID == 541
    || ObjectID == 542
    || ObjectID == 522
    || ObjectID == 543
    || ObjectID == 544
    || ObjectID == 545
    || ObjectID == 546
    || ObjectID == 547 )
{
    *(BYTE *)(gPreview + 722) = 4; //-> Set NPC status to Object
}

Full function:

Code:
//530802    ->
int gObjSetAttr(Preview * gPreview, int ObjectID) 
{
    int Result = *(DWORD*)oMapNumber - 9;    //-> int 92114C
    int MapNumber = Result;
    // ----
    if( MapNumber - 9 > 0 && MapNumber <= 8 && ObjectID >= 84 && ObjectID <= 143 )
    {
        gPreview->Unknown98 = 0;    //-> WORD +98
        Result = (int)gPreview;        //-> Return struct addr
        // ----
        gPreview->ModelScale += (double)(MapNumber / 3) * 0.050000001; //-> float +796
    }
    // ----
    if( gPreview )
    {
        for( i = 0; i < 1024; i++ ) //-> Max monster space
        {
            if( ObjectID == word_7B522E8[27 * i] )    //-> Filled monster table, maybe store names
            {
                gSetDisplayMonsterTarget(gPreview + 56);    //-> 8AAC00
                break;
            }
        }
        // ----
        gPreview->Unknown100 = ObjectID;    //-> WORD +100
        Result = (int)gPreview; //-> Return struct addr
        // ----
        gPreview->Unknown720    = 0;    //-> BYTE +720
        gPreview->Unknown96        = dword_81A01CC;    //-> WORD +96
        // ----
        if( ObjectID == 200 )    //Soccerball
        {
            Result = gPreview->Unknown700;    //-> Some result value for many functions
            gPreview->ObjectType = 2;    //-> BYTE +722, set monster type for Soccerball 
        }
        else
        {
            if( ObjectID < 260 )
            {
                if( ObjectID <= 200 )
                {
                    if( ObjectID < 150 )
                    {
                        if( ObjectID <= 110 )
                        {
                            if( ObjectID < 100 )
                            {
                                Result = gPreview->Unknown700;
                                gPreview->ObjectType = 2; //-> Set Monster object type
                            }
                            else
                            {
                                gPreview->ObjectType = 8;    //-> Set NONE object type
                            }
                        }
                        else
                        {
                            gPreview->ObjectType = 2; //-> Set Monster object type
                        }
                    }
                    else
                    {
                        Result = gPreview->Unknown700;
                        gPreview->ObjectType = 2; //-> Set Monster object type
                    }
                }
                else
                {
                    gPreview->ObjectType = 4; //-> Set NPC object type
                }
            }
            else
            {
                gPreview->ObjectType = 2; //-> Set Monster object type
            }
        }
        // ----
        if( ObjectID == 368 || ObjectID == 369 || ObjectID == 370 )
        {
            gPreview->ObjectType = 4; //-> Set NPC object type
        }
        if( ObjectID == 367
            || ObjectID == 371
            || ObjectID == 375
            || ObjectID == 376
            || ObjectID == 377
            || ObjectID == 379
            || ObjectID == 380
            || ObjectID == 381
            || ObjectID == 382
            || ObjectID == 383
            || ObjectID == 384
            || ObjectID == 385
            || ObjectID == 406
            || ObjectID == 407
            || ObjectID == 408
            || ObjectID == 414
            || ObjectID == 415
            || ObjectID == 416
            || ObjectID == 417
            || ObjectID == 450
            || ObjectID == 452
            || ObjectID == 453
            || ObjectID == 464
            || ObjectID == 465
            || ObjectID == 467
            || ObjectID == 468
            || ObjectID == 469
            || ObjectID == 470
            || ObjectID == 471
            || ObjectID == 472
            || ObjectID == 473
            || ObjectID == 474
            || ObjectID == 475
            || ObjectID == 478
            || ObjectID == 479
            || ObjectID == 492
            || ObjectID == 540
            || ObjectID == 541
            || ObjectID == 542
            || ObjectID == 522
            || ObjectID == 543
            || ObjectID == 544
            || ObjectID == 545
            || ObjectID == 546
            || ObjectID == 547 )
        {
            gPreview->ObjectType = 4; //-> Set NPC object type
        }
        // ----
        if( ObjectID >= 480 && ObjectID <= 491 )
        {
            Result = gPreview->Unknown700;
            gPreview->ObjectType = 2; //-> Set Monster object type
        }
        // ----
        if( ObjectID == 451 )
        {
            gPreview->ObjectType = 0x80u;    //-> Cherry Blossom Tree, set NONE Object type
        }
    }
    // ----
    return Result;
}

My offsets from 1.03.28 GMO, good luck)

P.S.: Screen =D
Pinkof - [Development] Trying Add Custom Monsters Or NPC - RaGEZONE Forums

thanks i will try do it =).
 
Junior Spellweaver
Joined
Dec 14, 2007
Messages
150
Reaction score
146
-=DarkSim=-,pinkof : i want change Helm, Armor, Pant.v.v. of NPC Guard or SoldierElf for main1.04D ss6ep3 you can guide ?


Example with Elf Soldier: but i make don't work
Code:
// -> 515596 -> 1 Call
int gMakePreviewSoldierElf(int StructAddr) 
{    Preview * gPreview = &*(Preview*)StructAddr; 
   // ---- 
   gPreview->WingsSlot            = ITEM2(12, 3); 
   // ---- 
   gPreview->HelmSlot            = ITEM2(7, 24);    gPreview->HelmLevel            = 13; 
   // ---- 
   gPreview->ArmorSlot            = ITEM2(8, 24);    gPreview->ArmorLevel        = 13;
    // ---- 
   gPreview->PantsSlot            = ITEM2(9, 24);    gPreview->PantsLevel        = 13; 
   // ---- 
   gPreview->GlovesSlot        = ITEM2(10, 24);    gPreview->GlovesLevel        = 13; 
   // ----
    gPreview->BootsSlot            = ITEM2(11, 24);    gPreview->BootsLevel        = 13; 
   // ---- 
   gPreview->Action            = 11;    gPreview->ModelScale        = 0x3F800000;    gPreview->SelectZone        += 70.0; 
   // ---- 
   return gPreview->Unknown700;}

sorry english
 
Last edited:
Experienced Elementalist
Joined
Oct 11, 2008
Messages
225
Reaction score
423
caothuphutho



Main 1.03.25 (1.03Y+ JPN)

P.S.:
#define ITEM2(x, y) ((x * 512) + y + 834)

834 - Value only for 1.03.25, you need research it, you can calculate it value from model loader in any main
 
Junior Spellweaver
Joined
Dec 14, 2007
Messages
150
Reaction score
146
work 100% thank -=DarkSim=- very much :))

 
Junior Spellweaver
Joined
Dec 14, 2007
Messages
150
Reaction score
146
DarkSim you have offset sets 1.03.11 Chaos Card NPC?

this is offset style chaos card master, main 1.03k jpn

#define NPC_ChaosCardMaster_Wing (0x0050302A+7)
#define NPC_ChaosCardMaster_Helm (0x00502FEE+7)
#define NPC_ChaosCardMaster_Armor (0x00502FFA+7)
#define NPC_ChaosCardMaster_Pants (0x00503006+7)
#define NPC_ChaosCardMaster_Gloves (0x00503012+7)
#define NPC_ChaosCardMaster_Boots (0x0050301E+7)
#define NPC_ChaosCardMaster_LevelItem (0x00503033+3)
 
Newbie Spellweaver
Joined
Oct 3, 2006
Messages
28
Reaction score
2
i search to add elf soldier to 0.99.28 main chs, anyone have source code or guide to do it?

thanks :)
 
Newbie Spellweaver
Joined
Oct 3, 2006
Messages
28
Reaction score
2
Everything is much simpler:
1. Object attr (like NPC / Mob / None) stored in one struct in main, like OBJECTSTRUCT from server
2. Everything that is necessary - load model for monster id, other changes can make in struct

About you problem with talk:
- You need change attr for you new Object in struct, set param +722 (BYTE) == 4 (1 = Player, 2 = Monster, 4 = NPC)

Example with Elf Soldier:
Code:
// -> 515596 -> 1 Call
int gMakePreviewSoldierElf(int StructAddr) 
{
Preview * gPreview = &*(Preview*)StructAddr;
// ----
gPreview->WingsSlot= ITEM2(12, 3);
// ----
gPreview->HelmSlot= ITEM2(7, 24);
gPreview->HelmLevel= 13;
// ----
gPreview->ArmorSlot= ITEM2(8, 24);
gPreview->ArmorLevel= 13;
// ----
gPreview->PantsSlot= ITEM2(9, 24);
gPreview->PantsLevel= 13;
// ----
gPreview->GlovesSlot= ITEM2(10, 24);
gPreview->GlovesLevel= 13;
// ----
gPreview->BootsSlot= ITEM2(11, 24);
gPreview->BootsLevel= 13;
// ----
gPreview->Action= 11;
gPreview->ModelScale= 0x3F800000;
gPreview->SelectZone+= 70.0;
// ----
return gPreview->Unknown700;
}

In this function main set special attr for this NPC, like items, model scale, action, pk status and etc.

530802 ( int gObjSetAttr(Preview * gPreview, int ObjectID) )
- this function set Object attr from ID, you can use it, example:

Code:
if( ObjectID == 368 || ObjectID == 369 || ObjectID == 370 )
{
*(BYTE *)(gPreview + 722) = 4; //-> Set NPC status to Object
}
if( ObjectID == 367
|| ObjectID == 371
|| ObjectID == 375
|| ObjectID == 376
|| ObjectID == 377
|| ObjectID == 379
|| ObjectID == 380
|| ObjectID == 381
|| ObjectID == 382
|| ObjectID == 383
|| ObjectID == 384
|| ObjectID == 385
|| ObjectID == 406
|| ObjectID == 407
|| ObjectID == 408
|| ObjectID == 414
|| ObjectID == 415
|| ObjectID == 416
|| ObjectID == 417
|| ObjectID == 450
|| ObjectID == 452
|| ObjectID == 453
|| ObjectID == 464
|| ObjectID == 465
|| ObjectID == 467
|| ObjectID == 468
|| ObjectID == 469
|| ObjectID == 470
|| ObjectID == 471
|| ObjectID == 472
|| ObjectID == 473
|| ObjectID == 474
|| ObjectID == 475
|| ObjectID == 478
|| ObjectID == 479
|| ObjectID == 492
|| ObjectID == 540
|| ObjectID == 541
|| ObjectID == 542
|| ObjectID == 522
|| ObjectID == 543
|| ObjectID == 544
|| ObjectID == 545
|| ObjectID == 546
|| ObjectID == 547 )
{
*(BYTE *)(gPreview + 722) = 4; //-> Set NPC status to Object
}

Full function:

Code:
//530802->
int gObjSetAttr(Preview * gPreview, int ObjectID) 
{
int Result = *(DWORD*)oMapNumber - 9;//-> int 92114C
int MapNumber = Result;
// ----
if( MapNumber - 9 > 0 && MapNumber <= 8 && ObjectID >= 84 && ObjectID <= 143 )
{
gPreview->Unknown98 = 0;//-> WORD +98
Result = (int)gPreview;//-> Return struct addr
// ----
gPreview->ModelScale += (double)(MapNumber / 3) * 0.050000001; //-> float +796
}
// ----
if( gPreview )
{
for( i = 0; i < 1024; i++ ) //-> Max monster space
{
if( ObjectID == word_7B522E8[27 * i] )//-> Filled monster table, maybe store names
{
gSetDisplayMonsterTarget(gPreview + 56);//-> 8AAC00
break;
}
}
// ----
gPreview->Unknown100 = ObjectID;//-> WORD +100
Result = (int)gPreview; //-> Return struct addr
// ----
gPreview->Unknown720= 0;//-> BYTE +720
gPreview->Unknown96= dword_81A01CC;//-> WORD +96
// ----
if( ObjectID == 200 )//Soccerball
{
Result = gPreview->Unknown700;//-> Some result value for many functions
gPreview->ObjectType = 2;//-> BYTE +722, set monster type for Soccerball 
}
else
{
if( ObjectID < 260 )
{
if( ObjectID <= 200 )
{
if( ObjectID < 150 )
{
if( ObjectID <= 110 )
{
if( ObjectID < 100 )
{
Result = gPreview->Unknown700;
gPreview->ObjectType = 2; //-> Set Monster object type
}
else
{
gPreview->ObjectType = 8;//-> Set NONE object type
}
}
else
{
gPreview->ObjectType = 2; //-> Set Monster object type
}
}
else
{
Result = gPreview->Unknown700;
gPreview->ObjectType = 2; //-> Set Monster object type
}
}
else
{
gPreview->ObjectType = 4; //-> Set NPC object type
}
}
else
{
gPreview->ObjectType = 2; //-> Set Monster object type
}
}
// ----
if( ObjectID == 368 || ObjectID == 369 || ObjectID == 370 )
{
gPreview->ObjectType = 4; //-> Set NPC object type
}
if( ObjectID == 367
|| ObjectID == 371
|| ObjectID == 375
|| ObjectID == 376
|| ObjectID == 377
|| ObjectID == 379
|| ObjectID == 380
|| ObjectID == 381
|| ObjectID == 382
|| ObjectID == 383
|| ObjectID == 384
|| ObjectID == 385
|| ObjectID == 406
|| ObjectID == 407
|| ObjectID == 408
|| ObjectID == 414
|| ObjectID == 415
|| ObjectID == 416
|| ObjectID == 417
|| ObjectID == 450
|| ObjectID == 452
|| ObjectID == 453
|| ObjectID == 464
|| ObjectID == 465
|| ObjectID == 467
|| ObjectID == 468
|| ObjectID == 469
|| ObjectID == 470
|| ObjectID == 471
|| ObjectID == 472
|| ObjectID == 473
|| ObjectID == 474
|| ObjectID == 475
|| ObjectID == 478
|| ObjectID == 479
|| ObjectID == 492
|| ObjectID == 540
|| ObjectID == 541
|| ObjectID == 542
|| ObjectID == 522
|| ObjectID == 543
|| ObjectID == 544
|| ObjectID == 545
|| ObjectID == 546
|| ObjectID == 547 )
{
gPreview->ObjectType = 4; //-> Set NPC object type
}
// ----
if( ObjectID >= 480 && ObjectID <= 491 )
{
Result = gPreview->Unknown700;
gPreview->ObjectType = 2; //-> Set Monster object type
}
// ----
if( ObjectID == 451 )
{
gPreview->ObjectType = 0x80u;//-> Cherry Blossom Tree, set NONE Object type
}
}
// ----
return Result;
}

My offsets from 1.03.28 GMO, good luck)

P.S.: Screen =D
Pinkof - [Development] Trying Add Custom Monsters Or NPC - RaGEZONE Forums
Hi -=DarkSim=- you now the way to add elf soldier npc to 99b main? 0.99.28 chs

You can teach me or give me some guide to do it?

Thanks

 
Back
Top