I will post my personal approaches:
First of all, in the ideal case, the "essence of all evil" will show up in the debug file:
Either as -
Code: Select all
(ptCelContext->dwCel < ptGfxBlock->bNumCelsPerDir)
Couldn't get cel handle in for:(null) TYPE:1 CLASS:293 MODE:2 FILE:C:\projects\D2\head\Diablo2\Source\D2CMP\Src\SpriteCache.cpp LINE:1833
Type: 1 (Monster)
Class: 293 (hcIdx 293 in MonStats.txt)
Mode: 2 (NU)
1=DT
2=NU
3=WL
4=GH
5=A1
6=A2
7=BL
8=SC
9=S1
10=S2
11=S3
12=S4
13=DD
14=KB [same as GH mode anim]
15=SQ [global mode for sequences]
16=RN
Note that this usually appears ABOVE the Assertion message, it is not part of the dump.
Actually, the animations it dumps out are only very rarely the reason for the crash, it simply dumps out the last animation passed on to the function, the crash however appears to occur when it reaches the frame where the layer-data becomes messed up, and this is seldom frame 1. This is the prime reason why 90% of the time the crashdump includes the animation your char was in at the moment of the crash...
Now, there are several common reasons why this occurs:
You should at all cost replace a1-7cmncof.d2 files with dummies. All 7 dummies only require this content.
Code: Select all
FF FF FF FF 00 00 00 00 2E 00 00 00 78 78 78 78 78 78 78 00 FF FF FF FF 01 01 08 14 01 F0 FD 7F
6F FF FF FF 6B 00 00 00 D0 FF FF FF 40 00 00 00 00 01 00 00 01 01 01 00 00 68 74 68 00 00 01 01
01 01 01 01 01 01 FF FF FF FF 00 00 00 00 B5 00 00 00 78 78 78 78 78 78 78 00 FF FF FF FF 01 10
08 14 00 00 13 00 3C FF FF FF 7D 00 00 00 46 FF FF FF 3E 00 00 00 00 01 00 00 01 01 01 00 00 68
74 68 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
I don't know for sure, but I think the game uses this to check the COF files and in case it is different from the cached one in the *.d2 file the later will be used, thus resulting in a crash.
The next approach is to check whenever the monster causing the problem has all the modes required for the skill, also it is important to check whenever all these modes have COF and animdata entries! Some monsters have unused modes (A2 on wraiths for example), many of them however lack appropriate entries in animdata.d2.
If the crash still wasen't solved, there are still a bunch of things that can cause this:
First of, bad animation data: Such as one direction being shorter then the others (16x8 monster with one direction only lasting 15 frames...)
Also, having wrong layering data in the COF files very often causes this, this is why you enter generate the COF files or write them from scratch, using existing ones from monsters can lead to problems (for example if you use an animation from a multilayer monster the game will crash while it tries to arrange the graphic on screen AFAIK).
The best way to check how many layers a cof file has is to look at the first byte, if this byte is 01 then the cof file has only TR.
Code: Select all
01 10 08 14 00 FF 00 00 00 FE FF FF 00 02 00 00 00 FE FF FF 00 02 00 00 00 01 00 00 01 01 01 00 00 68 74 68 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
Code: Select all
01 10 08 14 00 FF 00 00 00 FE FF FF 00 02 00 00 00 FE FF FF 00 02 00 00 00 01 00 00 01 01 01 00 00 68 74 68 00 [color=red]00[/color] 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01
Finally, a skill-sequence can also result in a crash, if so, change the entry to use a static animation like S1 or S2, or add a new sequence to monseq.txt.
I hope this post has been helpful to those out there who struggle with this forsaken little crash.