@@ -18,13 +18,14 @@ public class M2Converter : WowFile
1818 private int particleCount ;
1919 private uint particleOffset , texturesSize ;
2020 private string modelName ;
21- private int animOffset , animCount , animLookupOffset , animLookupCount , textureCount , textureOffset , dataSize ;
21+ private int animOffset , animCount , animLookupOffset , animLookupCount , textureOffset , dataSize ;
2222
2323 private HashSet < uint > shiftedOfs = new HashSet < uint > ( ) ;
2424 private Dictionary < int , byte [ ] > multitextInfo = new Dictionary < int , byte [ ] > ( ) ;
2525 private List < SkinConverter > skins = new List < SkinConverter > ( ) ;
2626
2727 private Dictionary < Texture , int > Textures = new Dictionary < Texture , int > ( ) ;
28+ private List < string > SkinFiles = new List < string > ( ) ;
2829
2930 public M2Converter ( string m2 , bool fix_helm ) : base ( m2 )
3031 {
@@ -61,14 +62,17 @@ public M2Converter(string m2, bool fix_helm) : base(m2)
6162
6263 // Skip to M2Array<Texture>.
6364 reader . ReadBytes ( 0x50 ) ;
64- textureCount = reader . ReadInt32 ( ) ;
65- textureOffset = reader . ReadInt32 ( ) ;
65+ reader . ReadInt32 ( ) ;
66+ textureOffset = reader . ReadInt32 ( ) ;
6667
6768 reader . BaseStream . Position = offset + size ;
6869 break ;
6970 case "TXID" :
7071 ReadTXID ( reader , size ) ;
7172 break ;
73+ case "SFID" :
74+ ReadSFID ( reader , size ) ;
75+ break ;
7276 default :
7377 reader . BaseStream . Position += size ;
7478 Console . WriteLine ( $ "Skipping chunk: { chunk } ") ;
@@ -126,6 +130,19 @@ private void ReadTXID(BinaryReader reader, uint size)
126130 }
127131 }
128132
133+ private void ReadSFID ( BinaryReader reader , uint size )
134+ {
135+ for ( var i = 0u ; i < size / 4u ; ++ i )
136+ {
137+ var skinFileId = reader . ReadUInt32 ( ) ;
138+ var filename = Listfile . LookupFilename ( skinFileId , ".m2" ) . Replace ( '/' , '\\ ' ) ;
139+
140+ filename = System . IO . Path . GetFileName ( filename ) ;
141+
142+ SkinFiles . Add ( filename ) ;
143+ }
144+ }
145+
129146 public bool Fix ( )
130147 {
131148 // file too small
@@ -142,76 +159,79 @@ public bool Fix()
142159 FixSkins ( ) ;
143160
144161 // Nothing to do
145- if ( particleCount > 0 )
146- {
147- int particleEnd = ( int ) particleOffset + ( 476 + 16 ) * particleCount ;
148-
149- if ( NeedParticleFix ( ) )
150- {
151- AddEmptyBytes ( particleEnd , 16 * particleCount ) ;
152- for ( int i = particleCount ; i > 0 ; i -- )
153- {
154- int pos = ( i * 476 ) + ( i - 1 ) * 16 + ( int ) particleOffset ;
155- multitextInfo [ i - 1 ] = new byte [ 16 ] ;
156- BlockCopy ( pos , multitextInfo [ i - 1 ] , 0 , 16 ) ;
157- RemoveBytes ( pos , 16 ) ;
158- }
159- }
160-
161- particleEnd = ( int ) particleOffset + 476 * particleCount ;
162-
163- for ( int i = 0 ; i < particleCount ; i ++ )
164- {
165- int pos = i * 476 + ( int ) particleOffset + 0x28 ;
166- char c = ReadChar ( pos ) ;
167-
168- int flagsOfs = ( int ) ( i * 476 + particleOffset + 4 ) ;
169- uint flags = ReadUInt ( flagsOfs ) ;
170- if ( c > 4 )
171- {
172- Data [ pos ] = 4 ;
173- //FixEmitterSpeed(i);
174- }
175-
176- if ( ( flags & 0x800000 ) != 0 )
177- {
178- FixGravity ( i ) ;
179- }
180-
181-
182- pos = i * 476 + ( int ) particleOffset + 22 ;
183- if ( ( flags & 0x10000000 ) != 0 )
184- {
185- short val = ReadShort ( pos ) ;
186- short text0 = ( short ) ( val & 0x1F ) ;
187- short text1 = ( short ) ( ( val & 0x3E0 ) >> 5 ) ;
188- short text2 = ( short ) ( ( val & 0x7C00 ) >> 10 ) ;
189-
190- WriteShort ( pos , text0 ) ;
191- }
192-
193- // 0x4000000 do not throttle emission rate based on distance => cause for high value emission rate ?
194- if ( ( flags & 0x4000000 ) != 0 )
195- {
196- //FixEmitterSpeed(i);
197- }
198- }
199-
200- for ( int i = particleCount - 1 ; i >= 0 ; i -- )
201- {
202- if ( BitConverter . ToUInt16 ( multitextInfo [ i ] , 2 ) == 0xFF )
203- {
204- particleCount -- ;
205- }
206- else // particles added are at the end
207- {
208- break ;
209- }
210- }
211-
212- WriteInt ( 0x128 , particleCount ) ;
213-
214- }
162+ WriteInt ( 0x128 , 0 ) ; // Particle Size
163+ WriteInt ( 0x12C , 0 ) ; // Particle Offset
164+ #region Particle Shit
165+ // if (particleCount > 0)
166+ // {
167+ // int particleEnd = (int)particleOffset + (476 + 16) * particleCount;
168+ //
169+ // if (NeedParticleFix())
170+ // {
171+ // AddEmptyBytes(particleEnd, 16 * particleCount);
172+ // for (int i = particleCount; i > 0; i--)
173+ // {
174+ // int pos = (i * 476) + (i - 1) * 16 + (int)particleOffset;
175+ // multitextInfo[i - 1] = new byte[16];
176+ // BlockCopy(pos, multitextInfo[i - 1], 0, 16);
177+ // RemoveBytes(pos, 16);
178+ // }
179+ // }
180+ //
181+ // particleEnd = (int)particleOffset + 476 * particleCount;
182+ //
183+ // for (int i = 0; i < particleCount; i++)
184+ // {
185+ // int pos = i * 476 + (int)particleOffset + 0x28;
186+ // char c = ReadChar(pos);
187+ //
188+ // int flagsOfs = (int)(i * 476 + particleOffset + 4);
189+ // uint flags = ReadUInt(flagsOfs);
190+ // if (c > 4)
191+ // {
192+ // Data[pos] = 4;
193+ // //FixEmitterSpeed(i);
194+ // }
195+ //
196+ // if ((flags & 0x800000) != 0)
197+ // {
198+ // FixGravity(i);
199+ // }
200+ //
201+ //
202+ // pos = i * 476 + (int)particleOffset + 22;
203+ // if ((flags & 0x10000000) != 0)
204+ // {
205+ // short val = ReadShort(pos);
206+ // short text0 = (short)(val & 0x1F);
207+ // short text1 = (short)((val & 0x3E0) >> 5);
208+ // short text2 = (short)((val & 0x7C00) >> 10);
209+ //
210+ // WriteShort(pos, text0);
211+ // }
212+ //
213+ // // 0x4000000 do not throttle emission rate based on distance => cause for high value emission rate ?
214+ // if ((flags & 0x4000000) != 0)
215+ // {
216+ // //FixEmitterSpeed(i);
217+ // }
218+ // }
219+ //
220+ // for (int i = particleCount - 1; i >= 0; i--)
221+ // {
222+ // if (BitConverter.ToUInt16(multitextInfo[i], 2) == 0xFF)
223+ // {
224+ // particleCount--;
225+ // }
226+ // else // particles added are at the end
227+ // {
228+ // break;
229+ // }
230+ // }
231+ //
232+ // WriteInt(0x128, particleCount);
233+ // }
234+ #endregion
215235
216236 // update version
217237 WriteUInt ( 0x4 , 264 ) ;
@@ -509,75 +529,48 @@ private void FixCamera()
509529 }
510530 }
511531
512- /// <summary>
513- /// Get the id
514- /// </summary>
515- /// <returns></returns>
516- private Dictionary < ushort , ushort > GetTransparencyLookupTargetType ( )
517- {
518- Dictionary < ushort , ushort > dico = new Dictionary < ushort , ushort > ( ) ;
519-
520- int ofsTrans = ReadInt ( 0x5C ) ;
521- int ofsTransLookup = ReadInt ( 0x94 ) ;
522- int nTransLookup = ReadInt ( 0x90 ) ;
523-
524- for ( ushort i = 0 ; i < nTransLookup ; i ++ )
525- {
526- short id = ReadShort ( ofsTransLookup + 2 * i ) ;
527- dico [ i ] = ReadUShort ( ofsTrans + id * 0x14 ) ;
528- }
529-
530- return dico ;
531- }
532-
533532 private void FixSkins ( )
534533 {
535- int n = ReadInt ( 0x70 ) ;
536- int ofs = ReadInt ( 0x74 ) ;
534+ var transparencyLookupCount = ReadInt ( 0x90 ) ;
537535
538- int n_transparency_lookup = ReadInt ( 0x90 ) ;
536+ var textureUnitLookup = new List < short > ( ) ;
537+ var blendOverride = new List < ushort > ( ) ;
539538
540- string f = Path . Replace ( ".m2" , "0" ) ;
541- List < short > texture_unit_lookup = new List < short > ( ) ;
542- List < ushort > blend_override = new List < ushort > ( ) ;
543- for ( int i = 0 ; i < ReadInt ( 0x44 ) ; i ++ )
539+ foreach ( var skinFile in SkinFiles )
544540 {
545- string s = f + i + ".skin" ;
546- if ( ! File . Exists ( s ) )
541+ if ( ! File . Exists ( skinFile ) )
547542 continue ;
548543
549- var sf = new SkinConverter ( s ) ;
550- sf . Fix ( ref texture_unit_lookup , ref blend_override , n_transparency_lookup ) ;
544+ var sf = new SkinConverter ( skinFile ) ;
545+ sf . Fix ( ref textureUnitLookup , ref blendOverride , transparencyLookupCount ) ;
551546 skins . Add ( sf ) ;
552547 }
553548
554- if ( blend_override . Count > 0 )
549+ if ( blendOverride . Count > 0 )
555550 {
556- uint globalflags = ReadUInt ( 0x10 ) ;
557- globalflags |= 0x8 ;
558- WriteUInt ( 0x10 , globalflags ) ;
551+ var globalFlags = ReadUInt ( 0x10 ) ;
552+ globalFlags |= 0x8 ;
553+ WriteUInt ( 0x10 , globalFlags ) ;
559554
560- int blend_override_pos = Data . Length ;
561- int n_blend_override = blend_override . Count ;
562- AddEmptyBytes ( blend_override_pos , 2 * n_blend_override ) ;
555+ var blendOverridePosition = Data . Length ;
556+ var blendOverrideCount = blendOverride . Count ;
557+ AddEmptyBytes ( blendOverridePosition , 2 * blendOverrideCount ) ;
563558
564- for ( int i = 0 ; i < n_blend_override ; ++ i )
565- {
566- WriteUShort ( blend_override_pos + 0x2 * i , blend_override [ i ] ) ;
567- }
559+ for ( var i = 0 ; i < blendOverrideCount ; ++ i )
560+ WriteUShort ( blendOverridePosition + 0x2 * i , blendOverride [ i ] ) ;
568561
569- WriteInt ( 0x130 , blend_override . Count ) ;
570- WriteInt ( 0x134 , blend_override_pos ) ;
562+ WriteInt ( 0x130 , blendOverride . Count ) ;
563+ WriteInt ( 0x134 , blendOverridePosition ) ;
571564 }
572565
573- int start = Data . Length ;
574- WriteInt ( 0x88 , texture_unit_lookup . Count ) ;
566+ var start = Data . Length ;
567+ WriteInt ( 0x88 , textureUnitLookup . Count ) ;
575568 WriteInt ( 0x8C , start ) ;
576569
577- AddEmptyBytes ( start , texture_unit_lookup . Count * sizeof ( ushort ) ) ;
578- for ( int i = 0 ; i < texture_unit_lookup . Count ; ++ i )
570+ AddEmptyBytes ( start , textureUnitLookup . Count * sizeof ( ushort ) ) ;
571+ for ( var i = 0 ; i < textureUnitLookup . Count ; ++ i )
579572 {
580- WriteShort ( start + i * 2 , texture_unit_lookup [ i ] ) ;
573+ WriteShort ( start + i * 2 , textureUnitLookup [ i ] ) ;
581574 }
582575
583576 // correct the renderflags given
@@ -686,39 +679,6 @@ private bool NeedParticleFix()
686679 return false ;
687680 }
688681
689- private HashSet < ushort > StaticAnim ( )
690- {
691- HashSet < ushort > anims = new HashSet < ushort > ( ) ;
692- uint nUVAnim = ReadUInt ( 0x98 ) ;
693- uint ofs = ReadUInt ( 0x9C ) ;
694-
695- for ( ushort t = 0 ; t < nUVAnim ; t ++ )
696- if ( ReadShort ( ( int ) ( ofs + t * 0x2 ) ) == - 1 )
697- anims . Add ( t ) ;
698-
699- return anims ;
700- }
701-
702- private HashSet < ushort > GetOpaqueRenderFlags ( )
703- {
704- HashSet < ushort > rf = new HashSet < ushort > ( ) ;
705-
706- uint n = ReadUInt ( 0x70 ) ;
707- uint ofs = ReadUInt ( 0x74 ) ;
708-
709- for ( ushort i = 0 ; i < n ; i ++ )
710- {
711- ushort flag = ReadUShort ( ( int ) ( ofs + i * 0x4 ) ) ;
712- ushort blend = ReadUShort ( ( int ) ( ofs + i * 0x4 + 0x2 ) ) ;
713- if ( flag == 0 || blend == 0 )
714- {
715- rf . Add ( i ) ;
716- }
717- }
718-
719- return rf ;
720- }
721-
722682 #region Shift Offset
723683
724684 /// <summary>
0 commit comments