Items and economy
Combinations
Old combine and CombineEx at NPCs
Overview
Combinations exchange a set of items at an NPC for a new item. The game has two independent systems.
| Old combine | CombineEx (“Hero combine”) | |
|---|---|---|
| Recipes on the server | ItemCombine.dat, 103 rows | CombineTable.dat + CombineTable2.dat |
| In the client | Item.edf, group 45 | ItemCombine.edf |
| Result | one item straight into the inventory | a list of up to 24 items, waits for confirmation (7/35) |
| On Sirin | native code | replaced by Lua ReloadableScripts\CombineEx |
How it works
- Old combine:
m_nCombineIdxis the NPC button key; the client scans only the first 103 rows, the result is inm_strCode. - CombineEx: the recipe number is the running position in the two server files, so inserting a row shifts the numbers and the client is built together with the server. The client picks the recipe, the first match in
ItemCombine.edforder: row order is priority, a later recipe with the same material set is unreachable. - The lists
LinkedStuff.dat(LL) andLinkedResult.dat(LR) are code sets linked by position: a material from an LL list yields the result at the same position in LR. The server does not see repeated codes in LR — it takes the first. - The roll: result weights out of 10 000; a sum below 10 000 leaves the remainder as failure, above it the last results are unreachable.
FailOutItemis how many materials are kept on failure (0 — all are lost); the client's “failure” list is display only. - The material upgrade mask
m_dwUptis an exact value or −1 “any”.
What matters when editing
- Empty material slots start with
-, quantity ≤ 0, mask −1; filled slots are consecutive and the client'sMaterialCountequals their number. - A material quantity must fit into one window cell: the client requires an exact match.
Files of the category
7 in the registry| File | Side | Format | Level | Corpora | Record | Digest | Note |
|---|---|---|---|---|---|---|---|
script\CombineTable.dat | server | dat | ready for full | AoP ✓, GU ✓, Sirin ✓ | AoP 968, GU 968, Sirin 968 | combinations.md | CombineEx, default mode; combinations.md §3.1 |
script\CombineTable2.dat | server | dat | ready for full | AoP ✓, GU ✓, Sirin ✓ | AoP 968, GU 968, Sirin 968 | combinations.md | CombineEx, default mode; combinations.md §3.1 |
script\ItemCombine.dat | server | dat | ready for full | AoP ✓, GU ✓, Sirin ✓ | AoP 208, GU 208, Sirin 208 | combinations.md | old combination, combinations.md §2 |
script\LinkedResult.dat | server | dat | ready for full | AoP ✓, GU ✓, Sirin ✓ | AoP 6468, GU 6468, Sirin 6468 | combinations.md | combinations.md §3.2 |
script\LinkedStuff.dat | server | dat | ready for full | AoP ✓, GU ✓, Sirin ✓ | AoP 6468, GU 6468, Sirin 6468 | combinations.md | combinations.md §3.2 |
sirin-lua\threads\main\ReloadableScripts\CombineEx\*.lua | server | lua | ready for full | AoP –, GU –, Sirin 3 | combinations.md | Sirin mode of the combination editor; combine_example.lua, skins.lua, socket_extender.lua | |
DataTable\ItemCombine.edf | client | edf | derived | AoP ✓, GU ✓, Sirin ✓ | AoP 2 sections: 124/1208, GU 2 sections: 124… | combinations.md | Derived from: CombineTable*.dat + LinkedStuff.dat (without results). combinations.md §3.4; in STRS the first section is split into two children (60 375 + the rest) |
“ready for full” — the format is understood and the fields are described; “derived” — the file is assembled from another; “opaque” — the format is not fully known; “postponed” and “out of scope” — the studio does not edit the file.
Sections of the category
The files of the category are split into groups; every group and subgroup has its own page with the fields of its files only.
CombineEx
DataTable\ItemCombine.edf; script\CombineTable.dat, script\CombineTable2.dat; script\LinkedResult.dat; script\LinkedStuff.dat
Total 45 Known 23 Derived 18 Unused 4Sirin mode (Lua)
sirin-lua\threads\main\ReloadableScripts\CombineEx\*.lua
Total 4 Known 4 Derived 0 Unused 0Unused parameters
Fields that neither the server nor the client reads. For each: why it was decided so and where that was established. The editor keeps their bytes as they are.
DataTable\ItemCombine.edf client file
Record: CombineTable I, CombineTable II (CombineTable)
| Offset | Field | Why unused | Data |
|---|---|---|---|
+0x011 | (unnamed) | padding: materials are structures aligned to 4 combinations.md §3.4; unused: padding bytes (after a byte field up to the field at the next multiple of 4; unnamed bytes have no reads in MSVC code except whole-record copies; 2004 source citemdatamgr.h); 0 everywhere in AoP | 183 values; most often `` (99%) |
+0x015 | (unnamed) ×5 | padding after the material group byte combinations.md §3.4; unused: padding bytes (after a byte field up to the field at the next multiple of 4; unnamed bytes have no reads in MSVC code except whole-record copies; 2004 source citemdatamgr.h); 0 everywhere in AoP | 232 values; most often / / / … (99%) |
Record: LinkedStuff
| Offset | Field | Why unused | Data |
|---|---|---|---|
+0x00C | ?-- ×100 | 0 in all filled AoP elements; the AoP client does not read it combinations.md §3.4: the LinkedStuff table (ItemCombine::Board+0x4714) is taken only by the constructor 00509B30, destructor 00509C90, loader 00509D30 and material matching 0050AC50; the latter reads +0x04 (count) of the record and only the group (+0x08) and code (+0x10) of an element; there are no other accesses to +0x4714…+0x4720 (clines) | — |
script\CombineTable.dat, script\CombineTable2.dat server file
| Offset | Field | Why unused | Data |
|---|---|---|---|
+0x08C | m_strCombineType | description (Korean, cp949), the server does not read it combinations.md §3.1: digest — “+0x8C | m_strCombineType | description (Korean, cp949), the server does not read it”; does not go to the client file (ItemCombine.edf is mapped, combinations.md §3.4) | 15267 values; most often 1-3¹«Áö¾÷±×·¹ÀÌ´õ C±Þ¹«± (0%) |