<commit_before>import r from 'restructure';
import Chunk from '../chunked/chunk';
import Chunked from '../chunked';
import PaddedStrings from '../chunked/padded-strings';
import SkipChunk from '../chunked/skip-chunk';
import { Vec3Float } from '../types';

const MOHD = Chunk({
  textureCount: r.uint32le,
  groupCount: r.uint32le,
  portalCount: r.uint32le,
  lightCount: r.uint32le,
  modelCount: r.uint32le,
  doodadCount: r.uint32le,
  doodadSetCount: r.uint32le,
  color: r.uint32le,
  wmoID: r.uint32le,
  minBoundingBox: Vec3Float,
  maxBoundingBox: Vec3Float,
  flags: r.uint32le
});

const MOTX = Chunk({
  filenames: new PaddedStrings('size', 'bytes')
});

const MOMT = Chunk({
  materials: new r.Array(new r.Struct({
    flags: r.uint32le,
    shader: r.uint32le,
    blendMode: r.uint32le,

    textures: new r.Array(new r.Struct({
      offset: r.uint32le,
      color: r.uint32le,
      flags: r.uint32le
    }), 3),

    unknowns: new r.Reserved(r.uint32le, 4)
  }), 'size', 'bytes')
});

const MOGN = Chunk({
  names: new r.Array(new r.String(null), 'size', 'bytes')
});

const MOGI = Chunk({
  groups: new r.Array(new r.Struct({
    flags: r.uint32le,
    minBoundingBox: Vec3Float,
    maxBoundingBox: Vec3Float,
    nameOffset: r.int32le
  }), 'size', 'bytes')
});

const MOSB = Chunk({
  skybox: new r.String('size')
});

const MODS = Chunk({
  sets: new r.Array(new r.Struct({
    name: new r.String(20),
    startIndex: r.uint32le,
    doodadCount: r.uint32le,
    unused: new r.Reserved(r.uint32le)
  }), 'size', 'bytes')
});

const MFOG = Chunk({
  fogs: new r.Array(new r.Struct({
    flags: r.uint32le,
    position: Vec3Float,
    smallerRadius: r.floatle,
    largerRadius: r.floatle,
    fogEnd: r.floatle,
    fogStartMultiplier: r.floatle,
    color: r.uint32le,
    unknowns: new r.Reserved(r.floatle, 2),
    color2: r.uint32le
  }), 'size', 'bytes')
});

export default Chunked({
  MOHD: MOHD,
  MOTX: MOTX,
  MOMT: MOMT,
  MOGN: MOGN,
  MOGI: MOGI,
  MOSB: MOSB,
  MOPV: SkipChunk,
  MOPT: SkipChunk,
  MOPR: SkipChunk,
  MOVV: SkipChunk,
  MOVB: SkipChunk,
  MOLT: SkipChunk,
  MODS: MODS,
  MODN: SkipChunk,
  MODD: SkipChunk,
  MFOG: MFOG,
  // TODO: Optional MCVP chunk

  flags: function() {
    return this.MOHD.flags;
  }
});
<commit_msg>Decode WMO doodads<commit_after>import r from 'restructure';
import Chunk from '../chunked/chunk';
import Chunked from '../chunked';
import PaddedStrings from '../chunked/padded-strings';
import { Quat, Vec3Float } from '../types';
import SkipChunk from '../chunked/skip-chunk';

const MOHD = Chunk({
  textureCount: r.uint32le,
  groupCount: r.uint32le,
  portalCount: r.uint32le,
  lightCount: r.uint32le,
  modelCount: r.uint32le,
  doodadCount: r.uint32le,
  doodadSetCount: r.uint32le,
  color: r.uint32le,
  wmoID: r.uint32le,
  minBoundingBox: Vec3Float,
  maxBoundingBox: Vec3Float,
  flags: r.uint32le
});

const MOTX = Chunk({
  filenames: new PaddedStrings('size', 'bytes')
});

const MOMT = Chunk({
  materials: new r.Array(new r.Struct({
    flags: r.uint32le,
    shader: r.uint32le,
    blendMode: r.uint32le,

    textures: new r.Array(new r.Struct({
      offset: r.uint32le,
      color: r.uint32le,
      flags: r.uint32le
    }), 3),

    unknowns: new r.Reserved(r.uint32le, 4)
  }), 'size', 'bytes')
});

const MOGN = Chunk({
  names: new r.Array(new r.String(null), 'size', 'bytes')
});

const MOGI = Chunk({
  groups: new r.Array(new r.Struct({
    flags: r.uint32le,
    minBoundingBox: Vec3Float,
    maxBoundingBox: Vec3Float,
    nameOffset: r.int32le
  }), 'size', 'bytes')
});

const MOSB = Chunk({
  skybox: new r.String('size')
});

const MODS = Chunk({
  sets: new r.Array(new r.Struct({
    name: new r.String(20),
    startIndex: r.uint32le,
    doodadCount: r.uint32le,
    unused: new r.Reserved(r.uint32le)
  }), 'size', 'bytes')
});

const MODN = Chunk({
  filenames: new PaddedStrings('size', 'bytes')
});

const MODD = Chunk({
  doodads: new r.Array(new r.Struct({
    filenameOffset: r.uint24le,
    filename: function() {
      return this.parent.parent.MODN.names[this.filenameOffset];
    },
    flags: r.uint8,
    position: Vec3Float,
    rotation: Quat,
    scale: r.floatle,
    color: r.uint32le
  }), 'size', 'bytes')
});

const MFOG = Chunk({
  fogs: new r.Array(new r.Struct({
    flags: r.uint32le,
    position: Vec3Float,
    smallerRadius: r.floatle,
    largerRadius: r.floatle,
    fogEnd: r.floatle,
    fogStartMultiplier: r.floatle,
    color: r.uint32le,
    unknowns: new r.Reserved(r.floatle, 2),
    color2: r.uint32le
  }), 'size', 'bytes')
});

export default Chunked({
  MOHD: MOHD,
  MOTX: MOTX,
  MOMT: MOMT,
  MOGN: MOGN,
  MOGI: MOGI,
  MOSB: MOSB,
  MOPV: SkipChunk,
  MOPT: SkipChunk,
  MOPR: SkipChunk,
  MOVV: SkipChunk,
  MOVB: SkipChunk,
  MOLT: SkipChunk,
  MODS: MODS,
  MODN: MODN,
  MODD: MODD,
  MFOG: MFOG,
  // TODO: Optional MCVP chunk

  flags: function() {
    return this.MOHD.flags;
  }
});

{'fraction_non_alphanumeric': 0.15296251511487305, 'fraction_numerical': 0.026199113260781944, 'mean_word_length': 3.36115992970123, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1030672', 'n_tokens_mistral': 2052, 'n_tokens_neox': 2005, 'n_words': 457}