[Development] Trying Add Custom Monsters Or NPC

Joined
Mar 13, 2008
Messages
758
Reaction score
1,005
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.


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.


Loading NPC Titus


Results.




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
 
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
 
Last edited:
Joined
Mar 13, 2008
Messages
758
Reaction score
1,005

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
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