Rose Online File Formats

Updated: 2018-07-07

Credit: osROSE Community

Implementations

AIP

DWORD trigger_count
DWORD idle_check
DWORD damage_check
LSTR title

:FOREACH( trigger_count )
    FSTR[0x20] trigger_name
    DWORD block_count
    :FOREACH( block_count )
        FSTR[0x20] block_name
        DWORD condition_count
        :FOREACH( condition_count )
            DWORD part_size
            DWORD part_cmd

            :PACK[4]
            :IF( partcmd == E[conditions].RECVDAMAGE )
                DWORD damage
                BYTE recvorgive
            :ELSEIF( partcmd == E[conditions].FINDOBJECT1 )
                DWORD distance
                BYTE isallied
                WORD levelmin
                WORD levelmax
                WORD charnum
            :ELSEIF( partcmd == E[conditions].SPAWNDISTANCE )
                DWORD distance
            :ELSEIF( partcmd == E[conditions].TARGETDISTANCE )
                DWORD distance
                BYTE moreorless
            :ELSEIF( partcmd == E[conditions].TARGETABILITY )
                BYTE abilitytype
                DWORD difference
                BYTE moreorless
            :ELSEIF( partcmd == E[conditions].HPPERCENT )
                DWORD hp
                BYTE moreorless
            :ELSEIF( partcmd == E[conditions].RANDOMCHANCE )
                BYTE percent
            :ELSEIF( partcmd == E[conditions].FINDOBJECT2 )
                DWORD distance
                WORD levelmin
                WORD levelmax
                BYTE isallied
            :ELSEIF( partcmd == E[conditions].TARGETDESTCHECK )
            :ELSEIF( partcmd == E[conditions].TARGETDESTABILITY )
                BYTE abilitytype
                BYTE moreorless
            :ELSEIF( partcmd == E[conditions].DESTABILITY )
                BYTE abilitytype
                DWORD value
                BYTE moreorless
            :ELSEIF( partcmd == E[conditions].DAYNIGHT )
                BYTE when
            :ELSEIF( partcmd == E[conditions].TARGETMAGICSTATUS )
                BYTE checktarget
                BYTE statustype
                BYTE hasstatus
            :ELSEIF( partcmd == E[conditions].OBJECTVAR )
                BYTE varindex
                DWORD value
                BYTE operator
            :ELSEIF( partcmd == E[conditions].WORLDVAR )
                BYTE varindex
                DWORD value
                BYTE operator
            :ELSEIF( partcmd == E[conditions].ECONOMYVAR )
                BYTE varindex
                DWORD value
                BYTE operator
            :ELSEIF( partcmd == E[conditions].SELECTNPC )
                DWORD npcid
            :ELSEIF( partcmd == E[conditions].OWNERDISTANCE )
                DWORD distance
                BYTE operator
            :ELSEIF( partcmd == E[conditions].ZONETIME )
                DWORD starttime
                DWORD endtime
            :ELSEIF( partcmd == E[conditions].ABILITY )
                BYTE abilitytype
                DWORD value
                BYTE operator
            :ELSEIF( partcmd == E[conditions].OWNEREXISTS )
            :ELSEIF( partcmd == E[conditions].OWNERHASTARGET )
            :ELSEIF( partcmd == E[conditions].WORLDTIME )
                DWORD starttime
                DWORD endtime
            :ELSEIF( partcmd == E[conditions].LOCALTIMEDATE )
                BYTE date
                BYTE hour1
                BYTE min1
                BYTE hour2
                BYTE min2
            :ELSEIF( partcmd == E[conditions].LOCALTIMEDAY )
                BYTE weekday
                BYTE hour1
                BYTE min1
                BYTE hour2
                BYTE min2
            :ELSEIF( partcmd == E[conditions].CHECKCHANNEL )
                WORD min
                WORD max
            :ELSEIF( partcmd == E[conditions].FINDOBJECT3 )
                DWORD distance
                BYTE isallied
                WORD levelmin
                WORD levelmax
                WORD charnum
                BYTE operator
            :ELSEIF( partcmd == E[conditions].AIVARIABLE )
                WORD varindex
                BYTE operator
                DWORD value
            :ENDIF
        :ENDFOR
        :PACK[1]

        DWORD action_count
        :FOREACH( action_count )
            DWORD part_size
            DWORD part_cmd

            -- NOT DONE

        :ENDFOR
    :ENDFOR
:ENDFOR

CHR

WORD meshcount
:FOREACH( meshcount )
  ZSTR path
:ENDFOR
WORD motioncount
:FOREACH( motioncount )
  ZSTR path
:ENDFOR
WORD effectcount
:FOREACH( effectcount )
  ZSTR path
:ENDFOR
WORD charactercount
:FOREACH( charactercount )
  BYTE isactive
  :IF( isactive )
    WORD boneid
    ZSTR name
    WORD meshcount
    :FOREACH( meshcount )
      WORD meshid  // Links to an "object" from the ZSC file
    :ENDFOR
    WORD motioncount
    :FOREACH( motioncount )
      WORD id
      WORD motionid
    :ENDFOR
    WORD effectcount
    :FOREACH( effectcount )
      WORD id
      WORD effectid
    :ENDFOR
  :ENDIF
:ENDFOR

CON

DWORD event_mask

:FOREACH( 16 )
    FSTR[0x20] load_function
:ENDFOR

DWORD block_offset
DWORD lua_offset

DWORD init_count
DWORD init_offset
DWORD dialog_count
DWORD dialog_offset

:SEEK[SET] 0x20c + init_offset

:FOREACH( init_count )
    DWORD init_dataoffset
:ENDFOR
:FOREACH( init_count )
    DWORD entry_id
    DWORD command
    DWORD data
    FSTR[0x20] condition_function
    FSTR[0x20] reward_function
    DWORD str_id
:ENDFOR

:SEEK[SET] 0x20c + dialog_offset
:FOREACH( block_count )
    DWORD block_dataoffset
:ENDFOR
:FOREACH( block_count )
    DWORD block_size
    DWORD entry_count
    :XOR( ( (BYTE)entry_count & 1 ) ? (BYTE)entry_count : (BYTE)block_size)
        DWORD[entry_count] entry_lookuptable
        :FOREACH( entry_count )
            DWORD entry_id
            E[dialog_command] command
            DWORD data
            FSTR[0x20] condition_function
            FSTR[0x20] reward_function
            DWORD str_id
        :ENDFOR
    :ENDXOR
:ENDFOR

DWORD code_len
:XOR( ( (BYTE)code_len & 1 ) ? (BYTE)code_len : (BYTE){FILE_SIZE} )
    BYTE[code_len] lua_data
:ENDXOR

--

:ENUM dialog_command
    CLOSE = 0
    NEXTMSG = 1
    NPCSAY = 2
    PLAYERSELECT = 3
    JUMPSELECT = 4
:ENUM

EFT

LSTR name
DWORD use_sound_file
LSTR sound_file_name
DWORD sound_loop_count

DWORD system_count
:FOREACH( system_count )
    LSTR name
    LSTR unique_name
    DWORD stb_index
    LSTR ptl_file
    DWORD use_animation
    LSTR zmo_file
    DWORD animation_loop_count
    DWORD animation_stb_index
    VECTOR3 position
    QUARTERNION rotation
    DWORD delay
    DWORD is_linked
:ENDFOR

DWORD animation_count
:FOREACH( animation_count )
    LSTR name
    LSTR unique_name
    DWORD stb_index
    LSTR zms_file
    LSTR zmo_file
    LSTR dds_file
    DWORD alpha_enabled
    DWORD two_sided
    DWORD alpha_test_enabled
    DWORD ztest_enabled
    DWORD zwrite_enabled
    E[blend_mode] source_blend
    E[blend_mode] destination_blend
    E[blendop_type] blend_op
    DWORD use_animation
    LSTR animation_name
    DWORD animation_loop_count
    DWORD animation_stb_index
    VECTOR3 position
    QUARTERNION rotation
    DWORD delay
    DWORD repeat_count
    DWORD is_linked
:ENDFOR( animation count )

--

:ENUM[DWORD] blend_mode
    ZERO = 1
    ONE = 2
    SRCCOLOR = 3
    INVSRCCOLOR = 4
    SRCALPHA = 5
    INVSRCALPHA = 6
    DESTALPHA = 7
    INVDESTALPHA = 8
    DESTCOLO = 9
    INVDESTCOLOR = 10
    SRCALPHASAT = 11
    BOTHSRCALPHA = 12
    BOTHINVSRCALPHA = 13
    BLENDFACTOR = 14
    INVBLENDFACTOR = 15
    SRCCOLOR2 = 16
    INVSRCCOLOR2 = 17
:ENDENUM

:ENUM[DWORD] blendop_type
    ADD = 1
    SUBTRACT = 2
    REVSUBTRACT = 3
    MIN = 4
    MAX = 5
:ENDENUM

HIM

DWORD width
DWORD height
DWORD grid_count
FLOAT grid_size
:FOREACH( width )
    :FOREACH( height )
        FLOAT height
    :ENDFOR
:ENDFOR
E[collision_type] collision_type
DWORD quadentry_count
:FOREACH( quadentry_count )
    FLOAT minZ
    FLOAT maxZ
:ENDFOR
:DEFINE quadtree_count = 1 + 4 + 16 + 32
DWORD quadtree_count
:CALL writequadnode( 256 )
:CALL writequadnode( 128 )
:CALL writequadnode( 64 )
:CALL writequadnode( 32 )
--
:FUNCTION writequadnode( divisonsize )
    // I can't really write the pseudo-format for this, but basically, it writes
    //     the min and max heights for each quadratic division of the map quadtree
:ENDFUNCTION
:ENUM[BSTR] collision_type
    QUAD = "QUAD"
:ENDENUM

HLP

BSTR version

DWORD root_count // Must be 1
BSTR root_node_name

DWORD node_count
:FOREACH( node_count )
    :CALL read_node
:ENDFOR

DWORD page_count
:FOREACH( page_count )
    BSTR page_title
    BSTR page_content
:ENDFOR

--

:FUNCTION read_node
    BSTR node_name

    DWORD subnode_count
    :FOREACH( subnode_count )
        :CALL read_node
    :ENDFOR
:ENDFUNCTION

IDX

DWORD base_version
DWORD current_version
DWORD vfs_count
:FOREACH( vfs_count )
    SSTR vfs_path
    DWORD data_offset
:ENDFOR

:FOREACH( vfs_count )
    :SEEK[SET] data_offset
    DWORD file_count
    DWORD delete_count
    DWORD start_offset
    :FOREACH file_count
        SSTR file_path
        DWORD offset
        DWORD file_length
        DWORD block_size
        BYTE deleted
        BYTE compressed_type
        BYTE encryption_type
        DWORD version
        DWORD checksum
    :ENDFOR
:ENDFOR

IFO

DWORD block_count
:FOREACH( block_count )
    E[block_type] block_type
    DWORD block_offset
:ENDFOR

:FOREACH( block_count )
    :SEEK( block_offset )

    :IF( block_type == E[block_type].ECONOMYDATA )
        DWORD width
        DWORD height
        DWORD map_cell_x
        DWORD map_cell_y
        MATRIX4X4 unused
        BSTR block_name
    :ENDIF

    :IF( block_type == E[block_type].DECORATIONS )
        :CALL readbasictype
    :ENDIF

    :IF( block_type == E[block_type].NPCLOCATIONS )
        :CALL readbasictype
        DWORD ai_pattern_index
        BSTR con_file
    :ENDIF
    :IF( block_type == E[block_type].BUILDINGS )
        :CALL readbasictype
    :ENDIF
    :IF( block_type == E[block_type].SOUNDEFFECTS )
        :CALL readbasictype
        BSTR path
        DWORD range
        DWORD interval
    :ENDIF
    :IF( block_type == E[block_type].EFFECTS )
        :CALL readbasictype
        BSTR path
    :ENDIF
    :IF( block_type == E[block_type].ANIMATABLES )
        :CALL readbasictype
    :ENDIF
    :IF( block_type == E[block_type].WATERBIG )
        DWORD x_count
        DWORD y_count
        :FOREACH( x_count )
            :FOREACH( y_count )
                BYTE use
                FLOAT height
                DWORD water_type
                DWORD water_index
                DWORD reserved
            :ENDFOR
        :ENDFOR
        :GOTO NEXT BLOCK!
    :ENDIF
    :IF( block_type == E[block_type].MONSTERSPAWNS )
        :CALL readbasictype
        DWORD spawn_count
        :FOREACH( spawn_count )
            BSTR spawn_name
            DWORD basicmob_count
            :FOREACH( basicmob_count )
                BSTR mob_name
                DWORD monster_id
                DWORD amount
            :ENDFOR
            DWORD tacticmob_count
            :FOREACH( tacticmob_count )
                BSTR mob_name
                DWORD monster_id
                DWORD amount
            :ENDFOR
            DWORD interval
            DWORD limit_count
            DWORD range
            DWORD tactic_points
        :ENDFOR
    :ENDIF
    :IF( block_type == E[block_type].WATERPLANES )
        DWORD entry_count
        :FOREACH( entry_count )
            VECTOR3 start
            VECTOR3 end
        :ENDFOR
    :ENDIF
    :IF( block_type == E[block_type].WARPGATES )
        :CALL readbasictype
    :ENDIF
    :IF( block_type == E[block_type].COLLISIONBLOCK )
        :CALL readbasictype
    :ENDIF
    :IF( block_type == E[block_type].TRIGGERS )
        :CALL readbasictype
        BSTR qsd_trigger
        BSTR lua_trigger
    :ENDIF
:ENDFOR

--

:FUNCTION readbasictype
    DWORD entry_count
    :FOREACH( entry_count )
        BSTR str_data
        WORD warp_id
        WORD event_id
        DWORD obj_type
        DWORD obj_id
        DWORD map_pos_x
        DWORD map_pos_y
        QUARTERNION rotation
        VECTOR3 position
        VECTOR3 scale
    :ENDFOR
:ENDFUNCTION
:ENUM block_type
    ECONOMYDATA = 0
    DECORATIONS = 1
    NPCSPAWNS = 2
    BUILDINGS = 3
    SOUNDEFFECTS = 4
    EFFECTS = 5
    ANIMATABLES = 6
    WATERBIG = 7
    MONSTERSPAWNS = 8
    WATERPLANES = 9
    WARPGATES = 10
    COLLISIONBLOCK = 11
    TRIGGERS = 12
:ENDENUM

LIT

DWORD obj_count
:FOREACH obj_count
    DWORD part_count
    DWORD objid
    :FOREACH part_count
        BSTR originalname
        DWORD part_id
        BSTR ddsname
        DWORD dds_id
        DWORD dds_division_size
        DWORD dds_division_count
        DWORD dds_part_id
    :ENDFOR
:ENDFOR
DWORD dds_count
:FOREACH dds_count
    BSTR ddsname
:ENDFOR

LOD

ZSTR name
:FOREACH( 0x1F )
    :FOREACH( 0x1F )
        DWORD detaillevel
    :ENDFOR
:ENDFOR

LTB

DWORD column_count
DWORD row_count
:FOREACH( row_count )
    :FOREACH( column_count )
        DWORD offset
        WORD length
    :ENDFOR
:ENDFOR
:FOREACH( row_count )
     :FOREACH( column_count )
        :SEEK[SET] offset
        USTR[length] data
    :ENDFOR
:ENDFOR

MOV

DWORD width
DWORD height
:FOREACH( width )
    :FOREACH( height )
        BYTE iswalkable
    :ENDFOR
:ENDFOR

PTL

DWORD emmiter_count
:FOREACH( emmiter_count )
    LSTR name
    FLOAT2 life_time
    FLOAT2 emit_rate
    DWORD loop_count
    FLOAT3 minimum_spawn_direction
    FLOAT3 maximum_spawn_direction
    FLOAT3 minimum_emit_radius
    FLOAT3 maximum_emit_radius
    FLOAT3 minimum_gravity
    FLOAT3 maximum_gravity
    LSTR texture
    DWORD particle_number
    DWORD align_type
    DWORD update_coordinate
    DWORD texture_width
    DWORD texture_height
    DWORD sprite_type
    E[blend_mode] destination_blend_mode
    E[blend_mode] source_blend_mode
    E[blendop_type] blend_op
    DWORD infocount
    :FOREACH( infocount )
        DWORD type
        FLOAT time_range
        BYTE fade
        :IF( type == E[anim_type].SIZE )
            VECTOR2 size
        :ELSEIF( type == E[anim_type].EVENTTIMER )
            FLOAT val
        :ELSEIF( type == E[anim_type].RED )
            FLOAT val
        :ELSEIF( type == E[anim_type].GREEN )
            FLOAT val
        :ELSEIF( type == E[anim_type].BLUE )
            FLOAT val
        :ELSEIF( type == E[anim_type].ALPHA )
            FLOAT val
        :ELSEIF( type == E[anim_type].COLOR )
            RGBA color_minimum
            RGBA color_maximum
        :ELSEIF( type == E[anim_type].VELOCITYX )
            FLOAT val
        :ELSEIF( type == E[anim_type].VELOCITYY )
            FLOAT val
        :ELSEIF( type == E[anim_type].VELOCITYZ )
            FLOAT val
        :ELSEIF( type == E[anim_type].VELOCITY )
            POINT velocty
        :ELSEIF( type == E[anim_type].UV)
            VECTOR2 val
        :ENDIF
    :ENDFOR
:ENDFOR
--
:ENUM[DWORD] blend_mode
    ZERO = 1
    ONE = 2
    SRCCOLOR = 3
    INVSRCCOLOR = 4
    SRCALPHA = 5
    INVSRCALPHA = 6
    DESTALPHA = 7
    INVDESTALPHA = 8
    DESTCOLO = 9
    INVDESTCOLOR = 10
    SRCALPHASAT = 11
    BOTHSRCALPHA = 12
    BOTHINVSRCALPHA = 13
    BLENDFACTOR = 14
    INVBLENDFACTOR = 15
    SRCCOLOR2 = 16
    INVSRCCOLOR2 = 17
:ENDENUM
:ENUM[DWORD] blendop_type
    ADD = 1
    SUBTRACT = 2
    REVSUBTRACT = 3
    MIN = 4
    MAX = 5
:ENDENUM
:ENUM[DWORD] anim_type
    SIZE = 1
    TIMER = 2
    RED = 3
    GREEN = 4
    BLUE = 5
    ALPHA = 6
    COLOR = 7
    VELOCITYX = 8
    VELOCITYY = 9
    VELOCITYZ = 10
    VELOCITY = 11
    TEXTUREINDEX = 12
:ENDENUM

QSD

DWORD file_version
DWORD block_count
SSTR qsd_name
:FOREACH( block_count )
    DWORD record_count
    SSTR block_name
    :FOREACH( record_count )
        BYTE check_next
        DWORD condition_count
        DWORD action_count
        SSTR record_name
        :FOREACH( condition_count )
            DWORD length
            DWORD command
            BYTE[length - 8] data
        :ENDFOR
        :FOREACH( action_count )
            DWORD length
            DWORD command
            BYTE[length - 8] data
        :ENDFOR
    :ENDFOR
:ENDFOR

STB

FSTR[4] format_code
DWORD data_offset
DWORD rowcount
DWORD columncount
:SEEK[SET] data_offset
DWORD rowheight
:FOREACH( columncount + 1 )
    WORD columnwidth
:ENDFOR
:FOREACH( columncount )
    SSTR columntitle
:ENDFOR
SSTR idcolumnname
:FOREACH( rowcount - 1 )
    SSTR rowdata
:ENDFOR
:FOREACH( rowcount - 1 )
    :FOREACH( columncount - 1 )
        SSTR celldata
    :ENDFOR
:ENDFOR

STL

BSTR stl_type
DWORD entry_count
:FOREACH( entry_count )
    BSTR string_id
    DWORD id
:ENDFOR

DWORD language_count
:FOREACH( language_count )
    DWORD language_offset
:ENDFOR

:FOREACH( language_count )
    :SEEK[SET] language_offset
    :FOREACH( entry_count )
        DWORD entry_offset
    :ENDFOR
:ENDFOR

:FOREACH( language_count )
    :FOREACH( entry_count )
        :SEEK[SET] entry_offset
        BSTR text
        :IF( stl_type == "QEST01" OR stl_type == "ITST01" )
            BSTR comment
            :IF( stl_type == "QEST01" )
                BSTR quest1
                BSTR quest2
            :ENDIF
        :ENDIF
    :ENDFOR
:ENDFOR

TBL

WORD max_range
:FOREACH( max_range )
    WORD start_index
    WORD index_count
:ENDFOR
WORD point_count
:FOREACH( point_count )
    POINT val
:ENDFOR

TIL

DWORD width
DWORD height
:FOREACH( width )
    :FOREACH( height )
        BYTE brush_id
        BYTE tile_index
        BYTE tile_set_number
        DWORD tile_id
    :ENDFOR
:ENDFOR

TSI

WORD dds_count
:FOREACH( dds_count )
    SSTR path
    DWORD colour_key
:ENDFOR

WORD totalelement_count
:FOREACH( dds_count )
    WORD ddselement_count
    :FOREACH( ddselement_count )
        WORD ownerid
        DWORD x1
        DWORD y1
        DWORD x2
        DWORD y2
        DWORD colour
        FSTR[0x20] name
    :ENDFOR
:ENDFOR

ZCA

FSTR[7] format_code
E[camera_type] camera_type
MATRIX4X4 model_view_matrix
MATRIX4X4 projection_matrix
FLOAT field_of_view
FLOAT aspect_ratio
FLOAT near_plane
FLOAT far_plane
FLOAT eye_x
FLOAT eye_y
FLOAT eye_z
FLOAT center_x
FLOAT center_y
FLOAT center_z
FLOAT up_x
FLOAT up_y
FLOAT up_z
--
:ENUM[DWORD] camera_type
    PERSPECTIVE = 0
    ORTHOGANAL = 1
:ENDENUM

ZMD

FSTR[7] format_code
    DWORD bone_count
:FOREACH( bone_count )
    DWORD parentid
    ZSTR name
    FLOAT posx
    FLOAT posy
    FLOAT posz
    FLOAT rotw
    FLOAT rotx
    FLOAT roty
    FLOAT rotz
:ENDFOR
DWORD dummy_count
:FOREACH( dummy_count )
    ZSTR name
    DWORD parentid
    FLOAT posx
    FLOAT posy
    FLOAT posz
    FLOAT rotw
    FLOAT rotx
    FLOAT roty
    FLOAT rotz
:ENDFOR

ZMO

FSTR[8] format_code
DWORD fps
DWORD frame_count
DWORD channel_count
:FOREACH( channel_count )
    E[track_type] tracktype
    DWORD trackid
:ENDFOR
:FOREACH( frame_count )
    :FOREACH( channel_count )
        :IF( tracktype == E[track_type].POSITION )
            VECTOR3 position
        :ELSEIF( tracktype == E[track_type].ROTATION )
            QUARTERNION rotation
        :IF( tracktype == E[track_type].NORMAL )
            VECTOR3 normal
        :IF( tracktype == E[track_type].ALPHA )
            FLOAT alpha
        :IF( tracktype == E[track_type].UV1 )
            VECTOR2 uv1
        :IF( tracktype == E[track_type].UV2 )
            VECTOR2 uv2
        :IF( tracktype == E[track_type].UV3 )
            VECTOR2 uv3
        :IF( tracktype == E[track_type].UV4 )
            VECTOR2 uv4
        :IF( tracktype == E[track_type].TEXTUREANIM )
            FLOAT texture_animation
        :IF( tracktype == E[track_type].SCALE )
            FLOAT scale
        :ENDIF
    :ENDFOR
:ENDFOR
--
:ENUM track_type
    POSITION = 0x2
    ROTATION = 0x4
    NORMAL = 0x8
    ALPHA = 0x10
    UV1 = 0x20
    UV2 = 0x40
    UV3 = 0x80
    UV4 = 0x100
    TEXTUREANIM = 0x200
    SCALE = 0x400
:ENDENUM

ZMS

FSTR[8] format_code
E[vertex_format] vertformat
VECTOR3 minbounds
VECTOR3 maxbounds
// Bone Lookup Table
WORD bone_count
:FOREACH( bone_count )
    WORD boneid
:ENDFOR
WORD vert_count
:IF( vertformat & E[vertex_format].POSITION )
    :FOREACH( vert_count )
        VECTOR3 position
    :ENDFOR
:ENDIF
:IF( vertformat & E[vertex_format].NORMAL )
    :FOREACH( vert_count )
        VECTOR3 normal
    :ENDFOR
:ENDIF
:IF( vertformat & E[vertex_format].COLOR )
    :FOREACH( vert_count )
        RGBA color
    :ENDFOR
:ENDIF
:IF( vertformat & E[vertex_format].BONEINDICES && vertformat & E[vertex_format].BONEWEIGHTS )
    :FOREACH( vert_count )
        FLOAT weight1
        FLOAT weight2
        FLOAT weight3
        FLOAT weight4
        WORD boneid1
        WORD boneid2
        WORD boneid3
        WORD boneid4
    :ENDFOR
:ENDIF
:IF( vertformat & E[vertex_format].TANGENT )
    :FOREACH( vert_count )
        VECTOR3 tangent
    :ENDFOR
:ENDIF
:IF( vertformat & E[vertex_format].UVMAP1 )
    :FOREACH( vert_count )
        VECTOR2 UVCoords1
    :ENDFOR
:ENDIF
:IF( vertformat & E[vertex_format].UVMAP2 )
    :FOREACH( vert_count )
        VECTOR2 UVCoords2
    :ENDFOR
:ENDIF
:IF( vertformat & E[vertex_format].UVMAP3 )
    :FOREACH( vert_count )
        VECTOR2 UVCoords3
    :ENDFOR
:ENDIF
:IF( vertformat & E[vertex_format].UVMAP4 )
    :FOREACH( vert_count )
        VECTOR2 UVCoords4
    :ENDFOR
:ENDIF
// Triangle Face Data
WORD face_count
:FOREACH( face_count )
    WORD vertid1
    WORD vertid2
    WORD vertid3
:ENDFOR
// Strip Face Data
WORD strip_count
:FOREACH( strip_count )
    WORD vertid
:ENDFOR
WORD mattype
--
:ENUM vertex_format
    POSITION = 2
    NORMAL = 4
    COLOR = 8
    BONEINDICES = 16
    BONEWEIGHTS = 32
    TANGENT = 64
    UVMAP1 = 128
    UVMAP2 = 256
    UVMAP3 = 512
    UVMAP4 = 1024
:ENDENUM

ZON

DWORD blockcount
:FOREACH( blockcount )
    DWORD blockid
    DWORD blockoffset
:ENDFOR
:FOREACH( blockcount )
    :SEEK[SET] blockoffset
    :IF( blockid == E[block_type].BASICINFO )
        DWORD zone_type
        DWORD zone_width
        DWORD zone_height
        DWORD grid_count
        FLOAT grid_size
        DWORD xcount
        DWORD ycount
        :FOREACH( zone_width )
            :FOREACH( zone_height )
                BYTE use_map
                FLOAT x
                FLOAT y
            :ENDFOR
        :ENDFOR
    :ELSEIF( blockid == E[block_type].EVENTPOINTS )
        DWORD entrycount
        :FOREACH( entrycount )
            FLOAT x
            FLOAT z
            FLOAT y
            BSTR name
        :ENDFOR
    :ELSEIF( blockid == E[block_type].TEXTURELIST )
        DWORD entrycount
        :FOREACH( entrycount )
            BSTR path
        :ENDFOR
    :ELSEIF( blockid == E[block_type].TILELIST )
        DWORD entrycount
        :FOREACH( entrycount )
            DWORD base1
            DWORD base2
            DWORD offset1
            DWORD offset2
            DWORD is_blending
            DWORD orientation
            DWORD tile_type
        :ENDFOR
    :ELSEIF( blockid == E[block_type].WTFINFO )
        BSTR area_name
        DWORD is_underground
        BSTR button_bgm
        BSTR button_back
        DWORD check_count
        DWORD standard_population
        DWORD standard_growth_rate
        DWORD metal_consumption
        DWORD stone_consumption
        DWORD wood_consumption
        DWORD leather_consumption
        DWORD cloth_consumption
        DWORD alchemy_consumption
        DWORD chemical_consumption
        DWORD industrial_consumption
        DWORD medicine_consumption
        DWORD food_consumption
    :ENDIF
:ENDFOR
--
:ENUM block_type
    BASICINFO = 0
    EVENTPOINTS = 1
    TEXTURELIST = 2
    TILELIST = 3
    WTFINFO = 4
:ENDENUM

ZSC

WORD mesh_count
:FOREACH( mesh_count )
    ZSTR path
:ENDFOR
WORD material_count
:FOREACH( material_count )
    ZSTR path
    WORD is_skin
    WORD alpha_enabled
    WORD two_sided
    WORD alpha_test_enabled
    WORD alpha_ref_enabled
    WORD z_write_enabled
    WORD z_test_enabled
    WORD blending_mode
    WORD specular_enabled
    FLOAT alpha
    WORD glow_type
    FLOAT red
    FLOAT green
    FLOAT blue
:ENDFOR
WORD effect_count
:FOREACH( effect_count )
    ZSTR path
:ENDFOR
WORD object_count
:FOREACH( object_count )
    DWORD boundingsphere_radius
    DWORD boundingsphere_x
    DWORD boundingsphere_y
    DWORD mesh_count
    :IF( mesh_count > 0 )
        :FOREACH( mesh_count )
            DWORD mesh_id
            DWORD material_id
            :WHILE( true )
                BYTE flag_id
                :IF( flag_id == 0 )
                    :BREAK
                :ENDIF
                BYTE flag_size
                IF( flag_id == E[flag_type].POSITION )
                    VECTOR3 pos
                :ELSEIF( flag_id == E[flag_type].ROTATION )
                    QUARTERNION rot
                :ELSEIF( flag_id == E[flag_type].SCALE )
                    VECTOR3 scale
                :ELSEIF( flag_id == E[flag_type].AXISROTATION )
                    QUARTERNION axisrot
                :ELSEIF( flag_id == E[flag_type].BONEINDEX )
                    WORD bone_index
                :ELSEIF( flag_id == E[flag_type].DUMMYINDEX )
                    WORD dummy_index
                :ELSEIF( flag_id == E[flag_type].PARENT )
                    WORD parent
                :ELSEIF( flag_id == E[flag_type].COLLISION )
                    E[collision_info] collision
                :ELSEIF( flag_id == E[flag_type].ZMOPATH )
                    BYTE[flag_size] motion_path
                :ELSEIF( flag_id == E[flag_type].RANGEMODE )
                    WORD range_set
                :ELSEIF( flag_id == E[flag_type].LIGHTMAPMODE )
                    WORD use_lightmap
    :ENDIF
            :WEND
        :ENDFOR
            WORD effect_count
        :FOREACH( effect_count )
            DWORD effect_id
            E[effect_type] effect_type
            :WHILE( true )
                BYTE flag_id
                :IF( flag_id == 0 )
                    :BREAK
                :ENDIF
                BYTE flag_size
                :IF( flag_id == 0x01)
                    VECTOR3 pos
                :ELSEIF( flag_id == 0x02)
                    QUARTERNION rot
                :ELSEIF( flag_id == 0x03)
                    VECTOR3 scale
                :ELSEIF( flag_id == 0x07)
                    WORD parent
                :ELSE
                    BYTE[flag_size] data
    :ENDIF
            :ENDWHILE
        :ENDFOR
            //These are for Bounding Box
        VECTOR3 minbounds
        VECTOR3 maxbounds
    :ENDIF
:ENDFOR
--
:ENUM[WORD] blend_mode
    NONE = 0
    CUSTOM = 1
    NORMAL = 2
    LIGHTEN = 3
:ENDENUM
:ENUM[WORD] glow_type
    NONE = 0
    NOTSET = 1
    SIMPLE = 2
    LIGHT = 3
    TEXTURE = 4
    TEXTURELIGHT = 5
    ALPHA = 6
:ENDENUM
:ENUM[BYTE] flag_type
    POSITION = 0x1
    ROTATION = 0x2
    SCALE = 0x3
    AXISROTATION = 0x4
    BONEINDEX = 0x5
    DUMMYINDEX = 0x6
    PARENT = 0x7
    COLLISION = 0x1D
    ZMOPATH = 0x1E
    RANGEMODE = 0x1F
    LIGHTMAPMODE = 0x20
:ENDENUM
:ENUM[WORD] collision_type
    NONE = 0
    SPHERE = 1
    AXISALIGNEDBOUNDINGBOX = 2
    ORIENTEDBOUNDINGBOX = 3
    POLYGON = 4
:ENDENUM
:ENUM[WORD] collisionpick_type
    NONE = 0
    NOTMOVABLE = 8
    NOTPICKABLE = 16
    HEIGHTONLY = 32
    NOCAMERACOLLISION = 64
:ENDENUM
:TYPEDEF[WORD] collision_info
    collision_type | collisionpick_type
:ENDTYPEDEF
:ENUM[DWORD] effect_type
    NORMAL = 0
    DAYNIGHT = 1
    LIGHTCONTAINER = 2
:ENDENUM

Misc

FSTR[S] - Fixed length string where S is the length of the strength
BSTR - Byte-prefixed string where the length is stored as the first byte
SSTR - Short-prefix string where the length is stored as teh first 2 bytes
LSTR - Long-prefixed string where the legnth is stored as the first 4 bytes
ZSTR - Null-terminated string

Packets

CLI = Packets send from the client to any server
LSV = Packets send from the login server to the login server
WSV = Packets send from the login server to the char server
GSV = Packets send from the login server to the world server
(0x700) CLI_ALIVE
(0x700) SVR_ERROR
(0x701) SVR_ANNOUNCE_TEXT
(0x702) GSV_ANNOUNCE_CHAT
(0x703) CLI_ACCEPT_REQ
(0x704) CLI_CHANNEL_LIST_REQ
(0x704) SRV_CHANNEL_LIST_REPLY
(0x705) CLI_CHECK_AUTH
(0x705) SRV_CHECK_AUTH
(0x707) SRV_LOGOUT_REQ
(0x707) GSV_LOGOUT_REPLY
(0x708) SRV_LOGIN_REQ
(0x708) SRV_LOGIN_REPLY
(0x709) GSV_LOGIN_REPLY
(0x70a) SRV_SELECT_SERVER
(0x70a) LSV_SELECT_SERVER
(0x70b) CLI_JOIN_SERVER_REQ
(0x70c) SRV_JOIN_SERVER_REPLY
(0x70d) GSV_GM_COMMAND
(0x70e) GSV_SET_GLOBAL_VAR
(0x70f) GSV_SET_GLOBAL_FLAG
(0x711) WSV_MOVE_SERVER
(0x712) CLI_CHAR_LIST
(0x712) WSV_CHAR_LIST
(0x713) CLI_CREATE_CHAR
(0x713) WSV_CREATE_CHAR
(0x714) CLI_DELETE_CHAR
(0x714) WSV_DELETE_CHAR
(0x715) CLI_SELECT_CHAR
(0x715) GSV_SELECT_CHAR
(0x716) GSV_INVENTORY_DATA
(0x717) GSV_SET_MONEYnINV
(0x718) GSV_SET_INV_ONLY
(0x719) GSV_SERVER_DATA
(0x71a) GSV_RELAY_REQ
(0x71a) CLI_RELAY_REPLY
(0x71b) GSV_QUEST_DATA
(0x71c) CLI_CHAR_CHANGE
(0x71c) WSV_CHAR_CHANGE
(0x71d) GSV_SET_MONEY_ONLY
(0x71e) GSV_REWARD_MONEY
(0x71f) GSV_REWARD_ITEM
(0x720) GSV_REWARD_ADD_ABILITY
(0x721) GSV_REWARD_SET_ABILITY
(0x722) CLI_LOGOUT_CANCLE
(0x723) GSV_QUEST_ONLY
(0x724) GSV_WISH_LIST
(0x730) CLI_QUEST_REQ
(0x730) GSV_QUEST_REPLY
(0x731) GSV_CHECK_NPC_EVENT
(0x751) GSV_CHEAT_CODE
(0x753) CLI_JOIN_ZONE
(0x753) GSV_JOIN_ZONE
(0x754) GSV_INIT_DATA
(0x755) CLI_REVIVE_REQ
(0x755) GSV_REVIVE_REPLY
(0x756) SET_REVIVE_POS
(0x757) CLI_SET_VAR_REQ
(0x757) GSV_SET_VAR_REPLY
(0x761) CLI_CHAR_INFO_REQ
(0x761) GSV_CHAR_INFO_REPLY
(0x762) CLI_SET_WEIGHT_RATE
(0x762) GSV_SET_WEIGHT_RATE
(0x770) GSV_ADJUST_POS
(0x771) CLI_CANTMOVE
(0x771) GSV_CANTMOVE
(0x772) CLI_ATTACK_START
(0x772) GSV_ATTACK_START
(0x773) GSV_ATTACK_STOP
(0x774) GSV_CHANGE_NPC
(0x775) CLI_SUMMON_CMD
(0x775) GSV_SUMMON_CMD
(0x781) CLI_SET_MOTION
(0x781) GSV_SET_MOTION
(0x782) CLI_TOGGLE
(0x782) GSV_TOGGLE
(0x783) CLI_CHAT
(0x783) GSV_CHAT
(0x784) CLI_WHISPER
(0x784) GSV_WHISPER
(0x785) CLI_SHOUT
(0x785) GSV_SHOUT
(0x786) CLI_PARTY_CHAT
(0x786) GSV_PARTY_CHAT
(0x787) CLI_CLAN_CHAT
(0x787) WSV_CLAN_CHAT
(0x788) CLI_ALLIED_CHAT
(0x788) GSV_ALLIED_CHAT
(0x789) CLI_ALLIED_SHOUT
(0x789) GSV_ALLIED_SHOUT
(0x790) GSV_SET_EVENT_STATUS
(0x791) GSV_NPC_CHAR
(0x792) GSV_MOB_CHAR
(0x793) GSV_AVT_CHAR
(0x794) GSV_SUB_OBJECT
(0x795) CLI_SETPOS
(0x796) CLI_STOP
(0x796) GSV_STOP
(0x797) GSV_MOVE
(0x798) CLI_ATTACK
(0x798) GSV_ATTACK
(0x799) CLI_DAMAGE
(0x799) GSV_DAMAGE
(0x79a) CLI_MOUSECMD
(0x79a) GSV_MOUSECMD
(0x79b) GSV_SETEXP
(0x79e) GSV_LEVELUP
(0x79f) CLI_HP_REQ
(0x79f) GSV_HP_REPLY
(0x7a0) GSV_SET_HPnMP
(0x7a1) CLI_STORE_TRADE_REQ
(0x7a1) GSV_STORE_TRADE_REPLY
(0x7a2) CLI_CREATE_ITEM_EXP_REQ
(0x7a3) CLI_USE_ITEM
(0x7a3) GSV_USE_ITEM
(0x7a4) CLI_DROP_ITEM
(0x7a5) CLI_EQUIP_ITEM
(0x7a5) GSV_EQUIP_ITEM
(0x7a6) GSV_ADD_FIELDITEM
(0x7a6) GSV_SUB_FIELDITEM
(0x7a7) CLI_GET_FIELDITEM_REQ
(0x7a7) GSV_GET_FIELDITEM_REPLY
(0x7a8) CLI_TELEPORT_REQ
(0x7a8) GSV_TELEPORT_REPLY
(0x7a9) CLI_USE_BPOINT_REQ
(0x7a9) GSV_USE_BPOINT_REPLY
(0x7aa) CLI_SET_HOTICON
(0x7aa) GSV_SET_HOTICON
(0x7ab) CLI_SET_BULLET
(0x7ab) GSV_SET_BULLET
(0x7ac) CLI_CHANGE_SKIN
(0x7ac) GSV_CHANGE_SKIN
(0x7ad) CLI_BANK_LIST_REQ
(0x7ad) CLI_BANK_LIST_REPLY
(0x7ae) CLI_MOVE_ITEM
(0x7ae) GSV_MOVE_ITEM
(0x7af) CLI_CREATE_ITEM_REQ
(0x7af) GSV_CREATE_ITEM_REPLY
(0x7b0) GSV_SKILL_LEARN_REPLY
(0x7b1) CLI_SKILL_LEVELUP_REQ
(0x7b1) GSV_SKILL_LEVELUP_REPLY
(0x7b2) CLI_SELF_SKILL
(0x7b2) GSV_SELF_SKILL
(0x7b3) CLI_TARGET_SKILL
(0x7b3) GSV_TARGET_SKILL
(0x7b4) CLI_POSITION_SKILL
(0x7b4) GSV_POSITION_SKILL
(0x7b5) GSV_EFFECT_OF_SKILL
(0x7b6) GSV_DAMAGE_OF_SKILL
(0x7b7) GSV_CLEAR_STATUS
(0x7b8) GSV_SPEED_CHANGED
(0x7b9) GSV_RESULT_OF_SKILL
(0x7ba) CLI_APPRAISAL_REQ
(0x7ba) GSV_APPRAISAL_REPLY
(0x7bb) GSV_SKILL_START
(0x7bc) CLI_CRAFT_ITEM_REQ
(0x7bc) GSV_CRAFT_ITEM_REPLY
(0x7bd) GSV_SKILL_CANCEL
(0x7bf) VLI_SET_WISHITEM
(0x7c0) CLI_TRADE_P2P
(0x7c0) GSV_TRADE_P2P
(0x7c1) CLI_TRADE_P2P_ITEM
(0x7c1) GSV_TRADE_P2P_ITEM
(0x7c2) CLI_P_STORE_OPEN
(0x7c2) GSV_P_STORE_OPENED
(0x7c3) CLI_P_STORE_CLOSE
(0x7c3) GSV_P_STORE_CLOSED
(0x7c4) CLI_P_STORE_LIST_REQ
(0x7c4) GSV_P_STORE_LIST_REPLY
(0x7c5) CLI_P_STORE_BUY_REQ
(0x7c6) CLI_P_STORE_SELL_REQ
(0x7c6) GSV_P_STORE_RESULT
(0x7c7) GSV_P_STORE_MONEYnINV
(0x7ca) CLI_ASSEMBLE_RIDE_ITEM
(0x7ca) GSV_ASSEMBLE_RIDE_ITEM
(0x7cb) CLI_USE_ITEM_TO_REPAIR
(0x7cb) GSV_USED_ITEM_TO_REPAIR
(0x7cd) CLI_REPAIR_FROM_NPC
(0x7cd) GSV_REPAIRED_FROM_NPC
(0x7ce) GSV_SET_ITEM_LIFE
(0x7d0) CLI_PARTY_REQ
(0x7d0) GSV_PARTY_REQ
(0x7d1) CLI_PARTY_REPLY
(0x7d1) GSV_PARTY_REPLY
(0x7d2) GSV_PARTY_MEMBER
(0x7d3) GSV_PARTY_INFO
(0x7d3) GSV_PARTY_ITEM
(0x7d4) GSV_PARTY_LEVnEXP
(0x7d5) GSV_CHANGE_OBJIDX
(0x7d6) GSV_ADD_EVENTOBJ
(0x7d6) GSV_SUB_EVENTOBJ
(0x7d7) CLI_PARTY_RULE
(0x7d7) GSV_PARTY_RULE
(0x7d8) CLI_ITEM_RESULT_REPORT
(0x7d8) GSV_ITEM_RESULT_REPORT
(0x7d9) CLI_MALL_ITEM_REQ
(0x7d9) GSV_MALL_ITEM_REPLY
(0x7da) CLI_MOVE_ZULY
(0x7da) GSV_MOVE_ZULY
(0x7db) GSV_SET_NPC_SHOW
(0x7dc) GSV_GODDNESS_MODE
(0x7dd) CLI_CART_RIDE
(0x7dd) GSV_CART_RIDE
(0x7de) GSV_BILLING_MESSAGE_EXT
(0x7df) GSV_BULLING_MESSAGE
(0x7e0) CLI_CLAN_COMMAND
(0x7e0) WSV_CLAN_COMMAND
(0x7e1) CLI_MESSENGER
(0x7e1) WSV_MESSENGER
(0x7e2) CLI_MESSENGER_CHAT
(0x7e2) WSV_MESSENGER_CHAT
(0x7e3) CLI_CHATROOM
(0x7e3) SVR_CHATROOM
(0x7e4) CLI_CHATROOM_MSG
(0x7e4) WSV_CHATROOM_MSG
(0x7e5) CLI_MEMO
(0x7e5) WSV_MEMO
(0x7e6) CLI_CLANMARK_SET
(0x7e7) CLI_CLANMARK_REQ
(0x7e7) WSV_CLANMARK_REPLY
(0x7e8) CLI_CLANMARK_REG_TIME
(0x7e8) WSV_CLANMARK_REG_TIME
(0x7e9) GSV_PATSTATE_CHANGE
(0x7ea) GSV_CHARSTATE_CHANGE
(0x7eb) CLI_SCREEN_SHOT_TIME
(0x7eb) GSV_SCREEN_SHOT_TIME
(0x808) CLI_FAKE_GAMEGUARD_REQ
(0x808) GSV_FAKE_GAMEGUARD_REPLY