Crafting

Information and updates for all other projects by Black Omen Productions (besides Shadow Empires): Namely Codename: MetalStorm, Anti-Balance, Ultimate Fixer and all versions of XyRAX

Moderators: Nefarius, Joel, Doombreed-x, Vendanna

Post Reply
sokol815
Posts: 92
Joined: Tue Aug 24, 2010 4:04 am
Location: Texas
United States of America

Crafting

Post by sokol815 » Sat Apr 21, 2012 2:29 pm

Hey, Nefarius! I'd just like to say, I have been a lurker in this forum for about 3 years now. All that I have read makes it sound like you guys are doing some great work here, rewriting the entire codebase for Diablo II. I'm writing a roguelike in C# and I have somewhere around 25000 lines of code.... can't imagine how managing 330,000 lines is. Must be incredibly daunting. I am glad someone is taking the time to go about doing things the right way. Just curious, did you have to go through in Assembly and reconstruct the C++ code?

I am also curious as to how much the crafting system will play a part in your modifications. It never really did much in vanilla, to what extent will crafting be possible? For instance: some mods use some sort of tempering system, where an item can be crafted onto x times, or you have Zy-El, where items can be as powerful as you have gold. I have read posts of yours talking about changing how modifications are added to items to make them more likely to spawn with useful stats, so I am very interested to know your thoughts on crafting.

Also, as a side note: Will your changes still be compatible with plugY? I imagine rewriting things moves entry points around and whatnot...

Anyways, Keep up the good work! Learning about what changes you had to make and just how many bugs there really were in Vanilla D2 is very interesting to me. Thanks for your time!

User avatar
Nefarius
Retired Admin
Cherub
Posts: 11607
Joined: Sat Jun 15, 2002 8:13 pm
Location: Where the blood forever rains
Contact:

Hand-picked

Re: Crafting

Post by Nefarius » Mon Apr 23, 2012 2:46 am

I am glad someone is taking the time to go about doing things the right way. Just curious, did you have to go through in Assembly and reconstruct the C++ code?
There are usually three phases involved in this, check the original assembly, implement it in C, repair any problems the original code might have had and remove any restrictions it might impose. The code base as a whole is composed ca. 98% out of C code, the remaining 2% are c++ and ASM (more of the former then the later, ASM is only used for injects into functions I didn't entirely replace yet), c++ is used for isolated parts of the code such as the PRNG and to automate some tasks with templates.
I am also curious as to how much the crafting system will play a part in your modifications. It never really did much in vanilla, to what extent will crafting be possible? For instance: some mods use some sort of tempering system, where an item can be crafted onto x times, or you have Zy-El, where items can be as powerful as you have gold. I have read posts of yours talking about changing how modifications are added to items to make them more likely to spawn with useful stats, so I am very interested to know your thoughts on crafting.
Most minor modifications to items are done throughout the use of oils that work like their hellfire counterparts (you obtain an oil, and use it like an identify scroll), you can apply oils of a specific type a limited amount of times, this applies across the whole set of oils, so while you can apply all types of eligible enhancements to one item, you can't stack infinite amounts of enhancements form each subtype (for example you can add 8 durability increases to the same item, but you can't add 9 of them; allthewhile adding 8 durability increases and 1 speed increase works fine). You can apply oils to all item qualities beside Set, Unique and Legendary. Dyes work in pretty much the same way oils do, they allow you to override an items color with a custom one (the number of colors is also larger compared to vanilla D2). Some item modifications are also applied by NPCs (some of vanilla's quest rewards have been turned into services generally offered in exchange for gold or other items), some of these have been changed, for example personalized items are now regarded as unique quality.

Should give some more insight into the oils
> https://d2mods.info/index.php?ind=galle ... ow&ida=345

One more thing that would probably fall under crafting, some skills allow you to create magical items, these work like a buff, they aren't saved and can only be used by the caster, these usually come with higher defense and damage then regular items of the same type would, they are designed to make higher defense and blocking accessable to builds that would normally be unable to use such items effectively.

For actual crafting in the sense of vanilla (a note in this regard is that there have been a myriad of crafting recipes in the LoD beta that remained in the files for a while, they never enabled most of them and ended up removing most of them in v1.09), the crafted item quality is still there and works the same way it has until now, but there are several twists to it, in one of the older posts about the affix systems I have mentioned that rare items have a prevalence to spawn with enhanced damage/defense (depending on their type), the odds for this are slightly higher for crafted items, this paired with the improved affix system and cleaned up affix pools tends to ensure the 4 random properties they receive (it is always 4 now) aren't worse then what the recipe adds, unless you're extremely unlucky, the remainder of the properties is driven from the recipe.
Also, as a side note: Will your changes still be compatible with plugY? I imagine rewriting things moves entry points around and whatnot...
It goes beyond that, we're not using original exe so PlugY won't be able to launch the mod, beside that I don't think there is any code left in the original DLLs that PlugY operates on that is still in use, the edits would be applied to dormant functions that aren't called anymore (I suspect it would also collide with some of the integrity checks I've added, and just raise an error as a result).
Anyways, Keep up the good work! Learning about what changes you had to make and just how many bugs there really were in Vanilla D2 is very interesting to me. Thanks for your time!
The bugs I post about here tend to be the more spectacular (or enraging) ones, there are many I don't bother to mention (they have rather uninteresting or no side effects for gameplay), it is mind boggling after a while that the game even manages to run.
''(...) The game can basically be considered unhackable. '' - Blizzard Entertainment (30th May 2000)
Black Omen Productions | MetalStorm: Progress Report | Screenshots

User avatar
cla$$ics
Moderator
Arch-Angel
Posts: 1320
Joined: Wed Aug 15, 2007 3:48 pm
United States of America

Hand-picked

Re: Crafting

Post by cla$$ics » Mon Apr 23, 2012 11:34 pm

Ah, so you're using C instead of C++? This is most intriguing news. I consider myself to be leagues better at plain C then at C++.
Although done for our needs, mod-makers should like these changes, too.
11/1/08 - COTL; 5/10/09 - Angel; 11/11/09 - Archangel

User avatar
Nefarius
Retired Admin
Cherub
Posts: 11607
Joined: Sat Jun 15, 2002 8:13 pm
Location: Where the blood forever rains
Contact:

Hand-picked

Re: Crafting

Post by Nefarius » Tue Apr 24, 2012 9:06 am

Yes it is almost entirely c code, although in places I've used c++ templates to generate c routines, here is a quick example of that:

Code: Select all

template <int eType> __declspec(noinline) int __fastcall MONAI_SEEK_GetUnitByClass( D2UnitStrc* pTarget, GetUnitByClass* hSeek )
{
	// checks whenever the target matches the search criteria
	// contained in the param structure, it will stop the query
	// if a target is within an arms length from the source...
	// REVISED 2011.NOV.14 (by Nefarius)
		
	if ( pTarget == NULL || pTarget == hSeek->pSource )
	{
		// never allow this to find the same unit that initiated
		// the query, this usually won't end well depending on
		// what the caller is trying to do with it...
		
		return 0;
	}
		
	if ( pTarget->eType != eType )
	{
		// the unit isn't of the correct type, so we
		// cannot select it in this query, exit...
	
		return 0;
	}
	
	int eUnitClass = pTarget->nIndex;
	int eSeekClass = hSeek->eClass;
	
	if ( eSeekClass >= 0 && eUnitClass != eSeekClass )
	{
		// if we're looking for an explicit class, check
		// whenever this unit has the correct class, if
		// it doesn't, continue onwards to the next unit
	
		return 0;
	}
	
	int eBaseClass = hSeek->eBase;
	
	if ( eBaseClass >= 0 )
	{
		// we're looking for units by their base class, this
		// is only supported for monsters, objects and items
	
		if ( eType == UNIT_MONSTER )
		{
			if ( MONSTERS_GetBaseID( eUnitClass ) != eBaseClass )
			{
				return 0;
			}
		}
			else if ( eType == UNIT_OBJECT )
		{
			if ( !OBJECTS_CheckObjectType( pTarget, eBaseClass ) )
			{
				return 0;
			}
		}
			else if ( eType == UNIT_ITEM )
		{
			if ( !D2CheckItemType( pTarget, eBaseClass ) )
			{
				return 0;
			}
		}
	}
	
	if ( eType == UNIT_PLAYER )
	{
		if ( UnitIsDeadPlayer( pTarget, 0 ) )
		{
			// this player has died, we cannot select it
			// for this query, as this only returns living
			// units that can be targeted...
		
			return 0;
		}
	}
		else if ( eType == UNIT_MONSTER )
	{
		// if this monster has died, or is under the
		// effect of skills such as Confuse, don't return
		// it and rather continue with the next unit...
	
		if ( UnitIsDeadMonster( pTarget, 0 ) )
		{
			return 0;
		}
		
		if ( SafeGetUnitAI( pTarget ) == NULL )
		{
			return 0;
		}
	}
		else if ( eType == UNIT_OBJECT )
	{
		// objects are only returned if they're still
		// closed, opened chests and such are ignored
	
		if ( pTarget->eObjMode != OBJMODE_NEUTRAL )
		{
			return 0;
		}
	}
		else if ( eType == UNIT_ITEM )
	{
		// items are only returned if they're laying
		// on the floor, anything else is ignored...
	
		if ( pTarget->eItmMode != ITEMMODE_FLOOR )
		{
			return 0;
		}
	}
	
	// if the seeker cannot see this unit, don't bother
	// to continue, as we won't be returning this...

	D2CoordStrc tCoords;
	
	AIGetUnitCoords( pTarget, tCoords );
	
	if ( D2CheckLineOfSightEx( hSeek->pRoom, &hSeek->tSource, &tCoords, COLLISION_LOS_WALL ) )
	{
		return 0;
	}

	int nDist	= 0;
	int nRadius	= hSeek->nRadius;
	
	if ( nRadius > 0 )
	{
		// if we're too far away from the target, or the target
		// isn't closer then the previous one, continue with the
		// next one in line...
	
		nDist = GetDistanceBetweenPoints( hSeek->tSource.x, hSeek->tSource.y, tCoords.x, tCoords.y );
		
		if ( nDist > nRadius || nDist >= hSeek->nDistance )
		{
			return 0;
		}
		
		hSeek->nDistance = nDist;
	}
	
	hSeek->pFound = pTarget;
	
	return ( ( nDist <= 1 ) ? 1 : 0 );
}
This being a template of course eliminates all realtime comparisons with eType (beside the one check that confirms the target is of the proper type), which keeps the source cleaner and smaller (I don't need to have x different routines all doing mostly the same task, but at the same time I hate redundant realtime checks).
''(...) The game can basically be considered unhackable. '' - Blizzard Entertainment (30th May 2000)
Black Omen Productions | MetalStorm: Progress Report | Screenshots

User avatar
Necrolis
Senior Admin
Throne
Posts: 9125
Joined: Sat Mar 25, 2006 1:22 pm
Location: The Land of the Dead
Contact:
South Africa

Hand-picked

Re: Crafting

Post by Necrolis » Tue Apr 24, 2012 11:32 am

technically you are using procedural C++, not C in the classic sense, but it doesn't really matter until you hit differences like implicit casts from void*, const, requirement of the struct and enum keywords for variable types, references, and most importantly function overloading.
Image
Netiquette, Do you USE it?!?! | Nefarius' Fixed TXT Files | Terms Of Service
Blackened | Day of Death | D2GFEx
"What was yours is mine. Your land, your people, and now your life." - Lim-Dul, the Necromancer
Judgement is Final, Death is Eternal

User avatar
Nefarius
Retired Admin
Cherub
Posts: 11607
Joined: Sat Jun 15, 2002 8:13 pm
Location: Where the blood forever rains
Contact:

Hand-picked

Re: Crafting

Post by Nefarius » Tue Apr 24, 2012 4:11 pm

Of course it isn't C in the classic (or for that matter real sense), that would be real C syntax compiled throughout a C-compiler :P, but it is close enough to it, you can't really distinguish the two at the assembler level if you avoid the lardier aspects of the language (or rather, the VC implementation of them).

---

Also I recalled that there was a similar topic from a couple of years ago where I gave some more insight into the process.
''(...) The game can basically be considered unhackable. '' - Blizzard Entertainment (30th May 2000)
Black Omen Productions | MetalStorm: Progress Report | Screenshots

User avatar
cla$$ics
Moderator
Arch-Angel
Posts: 1320
Joined: Wed Aug 15, 2007 3:48 pm
United States of America

Hand-picked

Re: Crafting

Post by cla$$ics » Tue Apr 24, 2012 10:06 pm

Interesting process there Nef. While I'm obviously not the type of person to teach myself everything about C/C++/ASM like you have, I do think that your process makes quite a lot of sense.
Of course, I haven't lurked on these forums in quite a bit, so I'm just speaking from a perspective of changing experiences. Not like I won't poke around MS when it comes out. :twisted:
Although done for our needs, mod-makers should like these changes, too.
11/1/08 - COTL; 5/10/09 - Angel; 11/11/09 - Archangel

User avatar
kidpaddle94
Forum Legend
Principality
Posts: 2057
Joined: Thu Aug 13, 2009 2:54 pm
Location: localhost
Canada

Re: Crafting

Post by kidpaddle94 » Thu May 03, 2012 11:11 pm

I teached myself (almost) everything I know of C/C++/ASM, I never took a single programming class in my life.
Really!? Honestly, seeing what you are doing on MetalStorm, I thought you were working as a programmer in real life.
Well, your work is even more impressive then XD Keep it up!

I even wondered, at some point, if you were part of Blizzard. Lol.

Rheikon
Posts: 24
Joined: Sun Sep 08, 2002 2:10 am
Location: NM

Re: Crafting

Post by Rheikon » Tue May 08, 2012 9:37 am

kidpaddle94" wrote:
I teached myself (almost) everything I know of C/C++/ASM, I never took a single programming class in my life.
Really!? Honestly, seeing what you are doing on MetalStorm, I thought you were working as a programmer in real life.
Well, your work is even more impressive then XD Keep it up!

I even wondered, at some point, if you were part of Blizzard. Lol.
It seems the most impressive projects that I have seen in the field are by those who also did the majority of learning on their own. Those that went to school to learn it all usually don't go near as far in my experience.

Post Reply

Return to “Mods by Nefarius”