diff --git a/.gitignore b/.gitignore index e56462b4..be7c8f23 100644 --- a/.gitignore +++ b/.gitignore @@ -24,12 +24,7 @@ __pycache__/ *.pyc .env.live-smoke.local -# playable network tests: local scenario/fixture configs, credential files and -# run outputs never enter git. Only scenario.example.json and the static gate -# fixtures in test/playable are committed. Run outputs live under /build/playable. -/test/playable/*.local.json -/test/playable/*.local.txt -/test/playable/runs/ +# credential files never enter git. *.credentials *.credentials.json .env.*.local @@ -44,17 +39,8 @@ __pycache__/ /oracle/*.dylib # vendored-lib test artifacts -/test/oracle_dumps/ -/test/*.actual.png /build-tools/ -# libgr2 tool outputs -/fuzz-report.json -/test/m2-numeric.json.tmp - -# compare.py render output -/test/compare-shots/ -/test/compare-report.json # Written by 40250 uitaskbar.py at runtime. /mouse.cfg diff --git a/CMakeLists.txt b/CMakeLists.txt index 6c109856..ab285e3d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,6 @@ option(MT_BUILD_PORT "Build the 40250 port and its tests" ON) option(MT_BUILD_NATIVE_RENDER "Build the SDL3 and Vulkan client" OFF) add_subdirectory(libgr2) -add_subdirectory(formats) add_subdirectory(extension/third_party) add_subdirectory(extension/src/codepage) if(MT_BUILD_PORT OR MT_BUILD_NATIVE_RENDER) diff --git a/GEMINI.md b/GEMINI.md deleted file mode 100644 index 0b1399a5..00000000 --- a/GEMINI.md +++ /dev/null @@ -1,3 +0,0 @@ -# Project instructions - -For any task involving Metin2 40250 comparison, 1:1 parity, missing original-client behavior, or parity regression, first read `.agents/skills/metin2-40250-parity-audit/SKILL.md` completely and follow it. Use `audit/manifest.json` as the persistent audit state and do not repeat still-valid verified work. diff --git a/bgm/Only_my_battle.mp3 b/bgm/Only_my_battle.mp3 deleted file mode 100644 index f0a353f6..00000000 Binary files a/bgm/Only_my_battle.mp3 and /dev/null differ diff --git a/bgm/a_rhapsody_of_war.mp3 b/bgm/a_rhapsody_of_war.mp3 deleted file mode 100644 index 308f6770..00000000 Binary files a/bgm/a_rhapsody_of_war.mp3 and /dev/null differ diff --git a/bgm/another_way.mp3 b/bgm/another_way.mp3 deleted file mode 100644 index 2ce3599a..00000000 Binary files a/bgm/another_way.mp3 and /dev/null differ diff --git a/bgm/back_to_back.mp3 b/bgm/back_to_back.mp3 deleted file mode 100644 index a2a0fc7e..00000000 Binary files a/bgm/back_to_back.mp3 and /dev/null differ diff --git a/bgm/blacksea.mp3 b/bgm/blacksea.mp3 deleted file mode 100644 index 171fbdcc..00000000 Binary files a/bgm/blacksea.mp3 and /dev/null differ diff --git a/bgm/catacomb_of_devil.mp3 b/bgm/catacomb_of_devil.mp3 deleted file mode 100644 index 3b29f0a6..00000000 Binary files a/bgm/catacomb_of_devil.mp3 and /dev/null differ diff --git a/bgm/characterselect.mp3 b/bgm/characterselect.mp3 deleted file mode 100644 index ed7d4178..00000000 Binary files a/bgm/characterselect.mp3 and /dev/null differ diff --git a/bgm/death_of_landmark.mp3 b/bgm/death_of_landmark.mp3 deleted file mode 100644 index 0b9104d9..00000000 Binary files a/bgm/death_of_landmark.mp3 and /dev/null differ diff --git a/bgm/desert.mp3 b/bgm/desert.mp3 deleted file mode 100644 index 1d320c8c..00000000 Binary files a/bgm/desert.mp3 and /dev/null differ diff --git a/bgm/dungeon_fire.mp3 b/bgm/dungeon_fire.mp3 deleted file mode 100644 index c89d96e5..00000000 Binary files a/bgm/dungeon_fire.mp3 and /dev/null differ diff --git a/bgm/enter_the_east.mp3 b/bgm/enter_the_east.mp3 deleted file mode 100644 index c1b22105..00000000 Binary files a/bgm/enter_the_east.mp3 and /dev/null differ diff --git a/bgm/follow_war_god.mp3 b/bgm/follow_war_god.mp3 deleted file mode 100644 index 9b96655f..00000000 Binary files a/bgm/follow_war_god.mp3 and /dev/null differ diff --git a/bgm/last-war2.mp3 b/bgm/last-war2.mp3 deleted file mode 100644 index f35d88b4..00000000 Binary files a/bgm/last-war2.mp3 and /dev/null differ diff --git a/bgm/login_window.mp3 b/bgm/login_window.mp3 deleted file mode 100644 index 976dfab8..00000000 Binary files a/bgm/login_window.mp3 and /dev/null differ diff --git a/bgm/lost_my_name.mp3 b/bgm/lost_my_name.mp3 deleted file mode 100644 index b3d3c91b..00000000 Binary files a/bgm/lost_my_name.mp3 and /dev/null differ diff --git a/bgm/m2bg.mp3 b/bgm/m2bg.mp3 deleted file mode 100644 index 43d4f8e5..00000000 Binary files a/bgm/m2bg.mp3 and /dev/null differ diff --git a/bgm/misty_forest.mp3 b/bgm/misty_forest.mp3 deleted file mode 100644 index b8a62d63..00000000 Binary files a/bgm/misty_forest.mp3 and /dev/null differ diff --git a/bgm/monkey_temple.mp3 b/bgm/monkey_temple.mp3 deleted file mode 100644 index 8a585fd7..00000000 Binary files a/bgm/monkey_temple.mp3 and /dev/null differ diff --git a/bgm/mountain_of_death.mp3 b/bgm/mountain_of_death.mp3 deleted file mode 100644 index 1346eb26..00000000 Binary files a/bgm/mountain_of_death.mp3 and /dev/null differ diff --git a/bgm/mt.mp3 b/bgm/mt.mp3 deleted file mode 100644 index da6cc5c4..00000000 Binary files a/bgm/mt.mp3 and /dev/null differ diff --git a/bgm/open_the_gate.mp3 b/bgm/open_the_gate.mp3 deleted file mode 100644 index 67730254..00000000 Binary files a/bgm/open_the_gate.mp3 and /dev/null differ diff --git a/bgm/save_me.mp3 b/bgm/save_me.mp3 deleted file mode 100644 index f70f81c0..00000000 Binary files a/bgm/save_me.mp3 and /dev/null differ diff --git a/bgm/wedding.mp3 b/bgm/wedding.mp3 deleted file mode 100644 index faba2d0d..00000000 Binary files a/bgm/wedding.mp3 and /dev/null differ diff --git a/bgm/wonderland.mp3 b/bgm/wonderland.mp3 deleted file mode 100644 index b2a5c7c6..00000000 Binary files a/bgm/wonderland.mp3 and /dev/null differ diff --git a/bgm/xmas.mp3 b/bgm/xmas.mp3 deleted file mode 100644 index 567f4474..00000000 Binary files a/bgm/xmas.mp3 and /dev/null differ diff --git a/extension/src/platform/CMakeLists.txt b/extension/src/platform/CMakeLists.txt index 53c1d636..72241ba9 100644 --- a/extension/src/platform/CMakeLists.txt +++ b/extension/src/platform/CMakeLists.txt @@ -10,8 +10,7 @@ if(NOT TARGET mtpython) list(FILTER MT_PLATFORM_SOURCES EXCLUDE REGEX "/ScriptLib/") endif() add_library(port_platform STATIC ${MT_PLATFORM_SOURCES}) -target_link_libraries(port_platform PUBLIC port_logic PRIVATE mt3p::freetype xrender::libgr2 xrender::formats) -target_include_directories(port_platform PRIVATE ${CMAKE_SOURCE_DIR}/formats) +target_link_libraries(port_platform PUBLIC port_logic PRIVATE mt3p::freetype xrender::libgr2) foreach(src IN LISTS MT_PLATFORM_SOURCES) mt_port_apply_defines(${src}) endforeach() diff --git a/extension/src/platform/SpeedTreeLib/SpeedTreeRT.cpp b/extension/src/platform/SpeedTreeLib/SpeedTreeRT.cpp index 87291509..26326b8e 100644 --- a/extension/src/platform/SpeedTreeLib/SpeedTreeRT.cpp +++ b/extension/src/platform/SpeedTreeLib/SpeedTreeRT.cpp @@ -21,7 +21,7 @@ #include "SpeedTreeLib/StdAfx.h" #include -#include +#include "spt.h" #include "../EterLib/RenderCommands3D.h" diff --git a/formats/spt.cpp b/extension/src/platform/SpeedTreeLib/spt.cpp similarity index 93% rename from formats/spt.cpp rename to extension/src/platform/SpeedTreeLib/spt.cpp index dee3a574..926b7be3 100644 --- a/formats/spt.cpp +++ b/extension/src/platform/SpeedTreeLib/spt.cpp @@ -1,7 +1,5 @@ #include "spt.h" -#include "m2_tokvec.h" // read_file - #include #include #include @@ -91,10 +89,5 @@ bool sniff_spt(const std::string& b, SptInfo& out) { return out.ok; } -bool sniff_spt_file(const std::string& path, SptInfo& out) { - std::string b; - if (!read_file(path, b)) return false; - return sniff_spt(b, out); -} } // namespace fmt diff --git a/formats/spt.h b/extension/src/platform/SpeedTreeLib/spt.h similarity index 96% rename from formats/spt.h rename to extension/src/platform/SpeedTreeLib/spt.h index 2d1536d3..07e623cb 100644 --- a/formats/spt.h +++ b/extension/src/platform/SpeedTreeLib/spt.h @@ -11,6 +11,7 @@ // 这里只做「嗅探」:读文件头 magic + version,抽取内嵌贴图和 composite atlas token。 // 不解析枝干/叶片几何。无 godot 依赖。 #pragma once +#include #include #include @@ -29,6 +30,5 @@ struct SptInfo { }; bool sniff_spt(const std::string& bytes, SptInfo& out); -bool sniff_spt_file(const std::string& path, SptInfo& out); } // namespace fmt diff --git a/extension/src/proto/proto.cpp b/extension/src/proto/proto.cpp deleted file mode 100644 index e7574c41..00000000 --- a/extension/src/proto/proto.cpp +++ /dev/null @@ -1,253 +0,0 @@ -#include "proto.h" - -#include "EterBase/StdAfx.h" -#include "EterBase/lzo.h" -#include "GameLib/StdAfx.h" -#include "GameLib/ItemData.h" -#include "../platform/UserInterface/UserInterface.h" - -#include -#include - -namespace mtproto { - -namespace { - -// CPythonNonPlayer::SMobTable (UserInterface/PythonNonPlayer.h), the 40250 ILP32 layout. The mirror of that header -// needs UserInterface/StdAfx.h, which includes the Python headers (after batch 2P); until then the table is here. -#pragma pack(push, 1) -struct SMobSkillLevel { - DWORD dwVnum; - BYTE bLevel; -}; - -struct SMobTable { - DWORD dwVnum; - char szName[24 + 1]; // CHARACTER_NAME_MAX_LEN (UserInterface/StdAfx.h) - char szLocaleName[24 + 1]; - - BYTE bType; - BYTE bRank; - BYTE bBattleType; - BYTE bLevel; - BYTE bSize; - - DWORD dwGoldMin; - DWORD dwGoldMax; - DWORD dwExp; - DWORD dwMaxHP; - BYTE bRegenCycle; - BYTE bRegenPercent; - WORD wDef; - - DWORD dwAIFlag; - DWORD dwRaceFlag; - DWORD dwImmuneFlag; - - BYTE bStr, bDex, bCon, bInt; - DWORD dwDamageRange[2]; - - short sAttackSpeed; - short sMovingSpeed; - BYTE bAggresiveHPPct; - WORD wAggressiveSight; - WORD wAttackRange; - - char cEnchants[6]; // MOB_ENCHANTS_MAX_NUM - char cResists[11]; // MOB_RESISTS_MAX_NUM - - DWORD dwResurrectionVnum; - DWORD dwDropItemVnum; - - BYTE bMountCapacity; - BYTE bOnClickType; - - BYTE bEmpire; - char szFolder[64 + 1]; - float fDamMultiply; - DWORD dwSummonVnum; - DWORD dwDrainSP; - DWORD dwMonsterColor; - DWORD dwPolymorphItemVnum; - - SMobSkillLevel Skills[5]; // MOB_SKILL_MAX_NUM - - BYTE bBerserkPoint; - BYTE bStoneSkinPoint; - BYTE bGodSpeedPoint; - BYTE bDeathBlowPoint; - BYTE bRevivePoint; -}; -#pragma pack(pop) -static_assert(sizeof(SMobTable) == 255, "mob_proto record"); - -using TItemTable = CItemData::TItemTable; - -uint32_t rd_u32(const uint8_t *p) { - uint32_t v; - std::memcpy(&v, p, 4); - return v; -} - -std::string cstr(const char *p, size_t maxn) { - size_t n = 0; - while (n < maxn && p[n]) { - ++n; - } - return std::string(p, n); -} - -} // namespace - -bool load_proto(const std::string &path, const std::array &key, Proto &out, - std::string *err) { - std::ifstream f(path, std::ios::binary); - if (!f) { - if (err) *err = "cannot open " + path; - return false; - } - std::vector file((std::istreambuf_iterator(f)), std::istreambuf_iterator()); - return load_proto_bytes(file, key, out, err); -} - -// The header checks of CItemManager::LoadItemTable / CPythonNonPlayer::LoadNonPlayerData, then CLZO::Decompress. -bool load_proto_bytes(const std::vector &file, const std::array &key, - Proto &out, std::string *err) { - out = Proto{}; - if (file.size() < 12) { - if (err) *err = "file too small"; - return false; - } - - size_t pos = 0; - auto read_u32 = [&](uint32_t &v) { - if (pos + 4 > file.size()) { - return false; - } - v = rd_u32(file.data() + pos); - pos += 4; - return true; - }; - - read_u32(out.fourcc); - if (out.fourcc == MAKEFOURCC('M', 'I', 'P', 'X')) { - if (!read_u32(out.version) || !read_u32(out.stride)) { - if (err) *err = "truncated MIPX header"; - return false; - } - if (out.version != 1) { - if (err) *err = "invalid item_proto VERSION " + std::to_string(out.version); - return false; - } - if (out.stride != sizeof(TItemTable)) { - if (err) *err = "invalid item_proto STRIDE " + std::to_string(out.stride) + " != sizeof(SItemTable)"; - return false; - } - } else if (out.fourcc == MAKEFOURCC('M', 'I', 'P', 'T')) { - out.stride = sizeof(TItemTable); - } else if (out.fourcc == MAKEFOURCC('M', 'M', 'P', 'T')) { - out.stride = sizeof(SMobTable); - } else { - if (err) *err = "invalid proto type"; - return false; - } - - uint32_t data_size = 0; - if (!read_u32(out.elements) || !read_u32(data_size)) { - if (err) *err = "truncated proto header"; - return false; - } - // 40250 reads dwDataSize bytes without checking; CLZO then reads its own header lengths. - if (pos + data_size > file.size() || data_size < sizeof(CLZObject::THeader)) { - if (err) *err = "declared data_size past end of file"; - return false; - } - - PackSingletons(); // CLZO, as 40250 Main() creates it - DWORD dwKey[4] = {key[0], key[1], key[2], key[3]}; - CLZObject zObj; - if (!CLZO::Instance().Decompress(zObj, file.data() + pos, dwKey)) { - if (err) *err = "CLZO::Decompress failed (wrong key or corrupt data)"; - return false; - } - - if (out.fourcc == MAKEFOURCC('M', 'M', 'P', 'T') && (zObj.GetSize() % sizeof(SMobTable)) != 0) { - if (err) *err = "invalid mob_proto size " + std::to_string(zObj.GetSize()) + ", check data format"; - return false; - } - // 40250 walks dwElements records from the buffer without comparing against its size. - if (static_cast(out.stride) * out.elements > zObj.GetSize()) { - if (err) *err = "elements * stride past decompressed size"; - return false; - } - const BYTE *buf = zObj.GetBuffer(); - out.blob.assign(buf, buf + static_cast(out.stride) * out.elements); - return true; -} - -ItemRecord parse_item(const uint8_t *r, uint32_t stride) { - ItemRecord it; - if (!r || stride != sizeof(TItemTable)) { - return it; - } - TItemTable t; - std::memcpy(&t, r, sizeof(t)); - it.vnum = t.dwVnum; - it.vnum_range = t.dwVnumRange; - it.name = cstr(t.szName, sizeof(t.szName)); - it.locale_name = cstr(t.szLocaleName, sizeof(t.szLocaleName)); - it.type = t.bType; - it.sub_type = t.bSubType; - it.weight = t.bWeight; - it.size = t.bSize; - it.anti_flags = t.dwAntiFlags; - it.flags = t.dwFlags; - it.wear_flags = t.dwWearFlags; - it.immune_flag = t.dwImmuneFlag; - it.buy_price = t.dwIBuyItemPrice; - it.sell_price = t.dwISellItemPrice; - for (int i = 0; i < CItemData::ITEM_LIMIT_MAX_NUM; ++i) { - it.limits[i] = {t.aLimits[i].bType, t.aLimits[i].lValue}; - } - for (int i = 0; i < CItemData::ITEM_APPLY_MAX_NUM; ++i) { - it.applies[i] = {t.aApplies[i].bType, t.aApplies[i].lValue}; - } - for (int i = 0; i < CItemData::ITEM_VALUES_MAX_NUM; ++i) { - it.values[i] = t.alValues[i]; - } - for (int i = 0; i < CItemData::ITEM_SOCKET_MAX_NUM; ++i) { - it.sockets[i] = t.alSockets[i]; - } - it.refined_vnum = t.dwRefinedVnum; - it.refine_set = t.wRefineSet; - it.alter_to_magic_pct = t.bAlterToMagicItemPct; - it.specular = t.bSpecular; - it.gain_socket_pct = t.bGainSocketPct; - return it; -} - -MobRecord parse_mob(const uint8_t *r, uint32_t stride) { - MobRecord m; - if (!r || stride != sizeof(SMobTable)) { - return m; - } - SMobTable t; - std::memcpy(&t, r, sizeof(t)); - m.vnum = t.dwVnum; - m.name = cstr(t.szName, sizeof(t.szName)); - m.locale_name = cstr(t.szLocaleName, sizeof(t.szLocaleName)); - m.type = t.bType; - m.rank = t.bRank; - m.battle_type = t.bBattleType; - m.level = t.bLevel; - m.size = t.bSize; - m.attack_speed = t.sAttackSpeed; - m.moving_speed = t.sMovingSpeed; - m.on_click_type = t.bOnClickType; - m.empire = t.bEmpire; - m.folder = cstr(t.szFolder, sizeof(t.szFolder)); - m.monster_color = t.dwMonsterColor; - return m; -} - -} // namespace mtproto diff --git a/extension/src/proto/proto.h b/extension/src/proto/proto.h deleted file mode 100644 index 90b5e306..00000000 --- a/extension/src/proto/proto.h +++ /dev/null @@ -1,104 +0,0 @@ -#pragma once -// item_proto / mob_proto reader, the 40250 format (GameLib/ItemManager.cpp CItemManager::LoadItemTable, -// UserInterface/PythonNonPlayer.cpp CPythonNonPlayer::LoadNonPlayerData). -// -// Outer: item = [u32 'MIPX'][u32 ver=1][u32 stride=156][u32 elements][u32 datasize][CLZObject] -// (or the older [u32 'MIPT'][u32 elements][u32 datasize][CLZObject]) -// mob = [u32 'MMPT'][u32 elements][u32 datasize][CLZObject] -// CLZObject = [u32 'MCOZ'][u32 encryptSize][u32 compressedSize][u32 realSize] + TEA/LZO payload, decoded by the -// ported CLZO::Decompress with the table's key. Records are #pragma pack(1) ILP32 structs: -// CItemData::TItemTable (156 bytes, port/GameLib/ItemData.h) and CPythonNonPlayer::TMobTable (255 bytes). - -#include -#include -#include -#include - -namespace mtproto { - -// The 4-DWORD keys 40250 hardcodes: s_adwItemProtoKey (GameLib/ItemManager.cpp), s_adwMobProtoKey -// (UserInterface/PythonNonPlayer.cpp). -inline constexpr std::array ITEM_PROTO_KEY = {173217u, 72619434u, 408587239u, 27973291u}; -inline constexpr std::array MOB_PROTO_KEY = {4813894u, 18955u, 552631u, 6822045u}; - -struct Proto { - uint32_t fourcc = 0; - uint32_t version = 0; - uint32_t stride = 0; // record size: sizeof(TItemTable) or sizeof(TMobTable) - uint32_t elements = 0; // record count - std::vector blob; // elements * stride bytes - - const uint8_t *record(uint32_t i) const { - return (i < elements) ? blob.data() + static_cast(i) * stride : nullptr; - } -}; - -// Load + decompress. `key` is ITEM_PROTO_KEY or MOB_PROTO_KEY; the format follows the fourcc. -// Parse from an already-read buffer (the extension reads through asset_io, e.g. pack://locale/en/item_proto). -bool load_proto_bytes(const std::vector &bytes, const std::array &key, - Proto &out, std::string *err); -bool load_proto(const std::string &path, const std::array &key, Proto &out, - std::string *err = nullptr); - -// --- typed views over the records --- - -struct ItemLimit { - uint8_t type = 0; - int32_t value = 0; -}; - -struct ItemApply { - uint8_t type = 0; - int32_t value = 0; -}; - -// CItemData::TItemTable, field for field. -struct ItemRecord { - uint32_t vnum = 0; - uint32_t vnum_range = 0; - std::string name; // szName[25] - std::string locale_name; // szLocaleName[25] - uint8_t type = 0; - uint8_t sub_type = 0; - uint8_t weight = 0; - uint8_t size = 0; - uint32_t anti_flags = 0; // ITEM_ANTIFLAG_* - uint32_t flags = 0; // ITEM_FLAG_* - uint32_t wear_flags = 0; - uint32_t immune_flag = 0; - uint32_t buy_price = 0; // dwIBuyItemPrice - uint32_t sell_price = 0; // dwISellItemPrice - std::array limits{}; - std::array applies{}; - int32_t values[6] = {0}; // alValues (armor: values[3] = body shape index) - int32_t sockets[3] = {0}; - uint32_t refined_vnum = 0; - uint16_t refine_set = 0; - uint8_t alter_to_magic_pct = 0; - uint8_t specular = 0; // PARITY §2.7 fSpecular = specular/100 - uint8_t gain_socket_pct = 0; -}; -// Empty record when `stride` is not sizeof(TItemTable). -ItemRecord parse_item(const uint8_t *rec, uint32_t stride); - -// The leading CPythonNonPlayer::TMobTable fields plus the ones the client reads for display. -struct MobRecord { - uint32_t vnum = 0; - std::string name; // szName[25] - std::string locale_name; // szLocaleName[25] - uint8_t type = 0; - uint8_t rank = 0; - uint8_t battle_type = 0; - uint8_t level = 0; - uint8_t size = 0; - int16_t attack_speed = 0; - int16_t moving_speed = 0; - uint8_t on_click_type = 0; - uint8_t empire = 0; - std::string folder; // szFolder[65] - uint32_t monster_color = 0; -}; -// Empty record when `stride` is not sizeof(TMobTable). -MobRecord parse_mob(const uint8_t *rec, uint32_t stride); - -} // namespace mtproto diff --git a/formats/CMakeLists.txt b/formats/CMakeLists.txt deleted file mode 100644 index 61e113e9..00000000 --- a/formats/CMakeLists.txt +++ /dev/null @@ -1,65 +0,0 @@ -# msm / msa —— Metin2 文本包装格式(M2)。照 EterGrnLib/RaceManager 复刻。 -# m2map/* —— A1 世界渲染的地图格式(SHINSOO-WORLD-RENDERING.md W0)。无 godot 依赖。 -add_library(xr_formats STATIC - textscript.cpp # M2 T1: Metin2 文本脚本 token 树解析(.msa / .msm 共用) - msm.cpp # 模型:base gr2 + 发型(RaceDataScript 子集) - msa.cpp # 动作:anim gr2 + duration + accumulation + 事件 - combo_table.cpp # §3.5: playersettingmodule.py 的 ComboAttackNew -> PC 连击段表 - attribute_data.cpp # .mdatr: 静态碰撞与高度三角网格 - - m2_tokvec.cpp # W0: LoadMultipleTextData 等价(Start/End 块 → token 向量表) - m2_coord.cpp # W0: Metin2↔Godot 坐标 / 单位 / 区块编号(BACKLOG I5) - map_setting.cpp # W0: setting.txt - texture_set.cpp # W0: TextureSet .txt - area_data.cpp # W0: areadata / areaambiencedata / areaproperty - terrain_files.cpp # W0: height.raw / tile.raw / attr.atr / water.wtr - environment.cpp # W0: .msenv(Group/List 文本树) - property.cpp # W0: .prb/.prt/.pre/.prd/.pra + CRC 注册表(BACKLOG E13) - asset_resolver.cpp # W0: 虚拟路径 -> 散文件(BACKLOG G7) - terrain_mesh.cpp # W1: heightmap -> 顶点/法线/索引 + GetHeight 三角插值 - splat.cpp # W2: tile.raw -> 每图层 258x258 alpha(RAW_GenerateSplat 端口) - spt.cpp # W4: .spt 嗅探(几何不可读,见文件头注释) -) -add_library(xrender::formats ALIAS xr_formats) -target_include_directories(xr_formats PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) -target_link_libraries(xr_formats PUBLIC xrender::libgr2) -target_compile_features(xr_formats PUBLIC cxx_std_20) - -if(BUILD_TESTING) - add_executable(formats_msa_test tests/msa_test.cpp) - target_link_libraries(formats_msa_test PRIVATE xrender::formats) - add_test(NAME formats.msa_loop_data COMMAND formats_msa_test) - if(DEFINED ENV{M2_ASSETS}) - set_tests_properties(formats.msa_loop_data PROPERTIES - ENVIRONMENT "M2_ASSETS=$ENV{M2_ASSETS}") - endif() - - add_executable(formats_msm_test tests/msm_test.cpp) - target_link_libraries(formats_msm_test PRIVATE xrender::formats) - add_test(NAME formats.msm_hair COMMAND formats_msm_test) - - add_executable(formats_combo_table_test tests/combo_table_test.cpp) - target_link_libraries(formats_combo_table_test PRIVATE xrender::formats) - add_test(NAME formats.combo_table COMMAND formats_combo_table_test) - if(DEFINED ENV{M2_ASSETS}) - set_tests_properties(formats.combo_table PROPERTIES - ENVIRONMENT "M2_ASSETS=$ENV{M2_ASSETS}") - endif() - - add_executable(formats_attribute_data_test tests/attribute_data_test.cpp) - target_link_libraries(formats_attribute_data_test PRIVATE xrender::formats) - add_test(NAME formats.attribute_data COMMAND formats_attribute_data_test) - if(DEFINED ENV{M2_ASSETS}) - set_tests_properties(formats.attribute_data PROPERTIES - ENVIRONMENT "M2_ASSETS=$ENV{M2_ASSETS}") - endif() - - add_executable(formats_map_test tests/map_formats_test.cpp) - target_link_libraries(formats_map_test PRIVATE xrender::formats) - add_test(NAME formats.map_formats COMMAND formats_map_test) - # 真实 A1 资源路径(可选):设了就跑 live 断言。 - if(DEFINED ENV{M2_ASSETS}) - set_tests_properties(formats.map_formats PROPERTIES - ENVIRONMENT "M2_ASSETS=$ENV{M2_ASSETS}") - endif() -endif() diff --git a/formats/area_data.cpp b/formats/area_data.cpp deleted file mode 100644 index 0417ab07..00000000 --- a/formats/area_data.cpp +++ /dev/null @@ -1,132 +0,0 @@ -#include "area_data.h" - -#include "m2_tokvec.h" - -#include -#include - -namespace fmt { - -namespace { - -// "yaw#pitch#roll" 或单个数(= roll)。原客户端 Area.cpp 用 atoi,这里用 atof 更宽容。 -void parse_ypr(const std::string& s, float& yaw, float& pitch, float& roll) { - yaw = pitch = roll = 0; - auto h1 = s.find('#'); - if (h1 == std::string::npos) { - roll = (float)std::atof(s.c_str()); - return; - } - auto h2 = s.find('#', h1 + 1); - yaw = (float)std::atof(s.substr(0, h1).c_str()); - if (h2 == std::string::npos) { - pitch = (float)std::atof(s.substr(h1 + 1).c_str()); - } else { - pitch = (float)std::atof(s.substr(h1 + 1, h2 - h1 - 1).c_str()); - roll = (float)std::atof(s.substr(h2 + 1).c_str()); - } -} - -} // namespace - -bool parse_area_data(const std::string& text, AreaData& out, std::string* err) { - TokVecMap tv; - std::string perr; - parse_tokvec(text, tv, &perr); - out = AreaData{}; - - if (!tv.has("areadatafile")) { - if (err) *err = "areadata 缺首行 `AreaDataFile`"; - return false; - } - if (!tv.has("objectcount")) { - if (err) *err = "areadata 缺 ObjectCount"; - return false; - } - out.declared_count = (int)tv.inum("objectcount"); - - for (int i = 0; i < out.declared_count; ++i) { - char key[32]; - std::snprintf(key, sizeof(key), "object%03d", i); - const auto* v = tv.find(key); - if (!v) continue; // 原客户端也是 `continue` - if (v->size() < 4) { - if (err) *err = std::string("areadata 块 ") + key + " token 不足 4 个"; - return false; - } - AreaObject o; - o.x = std::atof((*v)[0].c_str()); - o.y = std::atof((*v)[1].c_str()); - o.z = std::atof((*v)[2].c_str()); - o.crc = (uint32_t)std::strtoul((*v)[3].c_str(), nullptr, 10); - if (v->size() > 4) parse_ypr((*v)[4], o.yaw, o.pitch, o.roll); - if (v->size() > 5) o.height_bias = (float)std::atof((*v)[5].c_str()); - for (size_t k = 6; k < v->size(); ++k) - o.portal_ids.push_back(std::atoi((*v)[k].c_str())); - out.objects.push_back(std::move(o)); - } - return true; -} - -bool parse_area_ambience(const std::string& text, AreaAmbienceData& out, std::string* err) { - TokVecMap tv; - std::string perr; - parse_tokvec(text, tv, &perr); - out = AreaAmbienceData{}; - - if (!tv.has("areaambiencedatafile")) { - if (err) *err = "areaambiencedata 缺首行"; - return false; - } - if (!tv.has("objectcount")) { - if (err) *err = "areaambiencedata 缺 ObjectCount"; - return false; - } - out.declared_count = (int)tv.inum("objectcount"); - - for (int i = 0; i < out.declared_count; ++i) { - char key[32]; - std::snprintf(key, sizeof(key), "object%03d", i); - const auto* v = tv.find(key); - if (!v || v->size() < 5) continue; - AreaAmbienceObject o; - o.x = std::atof((*v)[0].c_str()); - o.y = std::atof((*v)[1].c_str()); - o.z = std::atof((*v)[2].c_str()); - o.crc = (uint32_t)std::strtoul((*v)[3].c_str(), nullptr, 10); - o.range = (float)std::atof((*v)[4].c_str()); - out.objects.push_back(std::move(o)); - } - return true; -} - -bool parse_area_property(const std::string& text, AreaProperty& out, std::string* err) { - TokVecMap tv; - std::string perr; - parse_tokvec(text, tv, &perr); - out = AreaProperty{}; - out.area_name = tv.str("areaname"); - out.num_water = (int)tv.inum("numwater", 0); - (void)err; - return true; -} - -// --- file wrappers --- -static bool load(const std::string& path, std::string& text, std::string* err) { - if (!read_file(path, text)) { - if (err) *err = "打不开 " + path; - return false; - } - return true; -} -bool parse_area_data_file(const std::string& p, AreaData& o, std::string* e) { - std::string t; return load(p, t, e) && parse_area_data(t, o, e); -} -bool parse_area_ambience_file(const std::string& p, AreaAmbienceData& o, std::string* e) { - std::string t; return load(p, t, e) && parse_area_ambience(t, o, e); -} -bool parse_area_property_file(const std::string& p, AreaProperty& o, std::string* e) { - std::string t; return load(p, t, e) && parse_area_property(t, o, e); -} - -} // namespace fmt diff --git a/formats/area_data.h b/formats/area_data.h deleted file mode 100644 index 452a90d5..00000000 --- a/formats/area_data.h +++ /dev/null @@ -1,54 +0,0 @@ -// areadata.txt / areaambiencedata.txt / areaproperty.txt —— 每个区块的对象记录。 -// 对标 GameLib/Area.cpp __Load_LoadObject / __Load_LoadAmbience 和 -// MapOutdoorLoad.cpp 的 AreaProperty 解析。SHINSOO §5.3 / §5.6。 -// -// 坐标系(W0 判明 → W3 修正,2026-08-29):areadata 的 position 是**地图全局厘米**(不是 -// 区块本地!只有 000000 因为在原点附近才看着像本地)。x 正 = 东,y 负 = 南(幅度 = 距地图 -// 北边缘),随 tile_y 增大而更负。`Area::SetCoordinate` 不偏移,正因为 position 已是全局。 -// 各区块 x∈[tile_x·25600, +25600]、|y|∈[tile_y·25600, +25600](实测 A1 全 20 区块)。 -// z 是竖直(高度)轴 cm。heightBias 加在 z 上。转换:直接 position_to_godot(x, y, z)。 -#pragma once -#include -#include -#include - -namespace fmt { - -struct AreaObject { - double x = 0, y = 0, z = 0; // 区块本地 cm - uint32_t crc = 0; // property CRC - float yaw = 0, pitch = 0, roll = 0; - float height_bias = 0; - std::vector portal_ids; -}; - -struct AreaData { - int declared_count = 0; // ObjectCount - std::vector objects; // 实际解析到的(缺块会跳过,故可能 < declared) -}; - -struct AreaAmbienceObject { - double x = 0, y = 0, z = 0; - uint32_t crc = 0; - float range = 0; -}; -struct AreaAmbienceData { - int declared_count = 0; - std::vector objects; -}; - -struct AreaProperty { - std::string area_name; // AreaName(去引号) - int num_water = 0; -}; - -bool parse_area_data(const std::string& text, AreaData& out, std::string* err); -bool parse_area_data_file(const std::string& path, AreaData& out, std::string* err); - -bool parse_area_ambience(const std::string& text, AreaAmbienceData& out, std::string* err); -bool parse_area_ambience_file(const std::string& path, AreaAmbienceData& out, std::string* err); - -bool parse_area_property(const std::string& text, AreaProperty& out, std::string* err); -bool parse_area_property_file(const std::string& path, AreaProperty& out, std::string* err); - -} // namespace fmt diff --git a/formats/asset_resolver.cpp b/formats/asset_resolver.cpp deleted file mode 100644 index f53c7a3a..00000000 --- a/formats/asset_resolver.cpp +++ /dev/null @@ -1,261 +0,0 @@ -#include "asset_resolver.h" -#include "m2_tokvec.h" // fmt::read_file(host 可注入 FileAccess) - -#include -#include -#include -#include - -namespace fmt { - -namespace fs = std::filesystem; - -namespace { - -std::string lower(std::string s) { - std::transform(s.begin(), s.end(), s.begin(), - [](unsigned char c) { return (char)std::tolower(c); }); - return s; -} - -// "a/b/./c/../d" -> "a/b/d"(不越过根;越根的 ".." 直接丢) -std::string collapse(const std::string& in) { - std::vector parts; - std::string cur; - auto flush = [&] { - if (cur.empty()) return; - if (cur == ".") { - } else if (cur == "..") { - if (!parts.empty()) parts.pop_back(); - } else { - parts.push_back(cur); - } - cur.clear(); - }; - for (char c : in) { - if (c == '/') flush(); - else cur += c; - } - flush(); - std::string out; - for (size_t i = 0; i < parts.size(); ++i) { - if (i) out += '/'; - out += parts[i]; - } - return out; -} - -const char* kYmir = "ymir work/"; - -// 若 path 含 "ymir work/",返回从那里起的后缀,否则 ""。 -std::string ymir_suffix(const std::string& norm) { - auto p = norm.find(kYmir); - if (p == std::string::npos) return ""; - return norm.substr(p); -} - -// 一级目录归类:0=基础(在 priority 里),1=普通,2=patch/补丁 -int pack_rank(const std::string& top, const std::vector& prio) { - std::string t = lower(top); - for (size_t i = 0; i < prio.size(); ++i) - if (lower(prio[i]) == t) return (int)i; // 0..N-1 - if (t.rfind("metin2_patch_", 0) == 0 || t.rfind("patch", 0) == 0) return 100000; - return 50000; -} - -} // namespace - -std::vector AssetResolver::default_priority() { - return {"Zone", "Terrain", "ETC", "PC", "Tree", "Property", "Effect", - "Monster", "NPC", "season2", "season3_eu"}; -} - -std::string AssetResolver::normalize(const std::string& vp) { - std::string s = vp; - for (char& c : s) - if (c == '\\') c = '/'; - s = lower(s); - // 去盘符 "d:/..." / "d:..." - if (s.size() >= 2 && std::isalpha((unsigned char)s[0]) && s[1] == ':') - s = s.substr(2); - while (!s.empty() && s[0] == '/') s.erase(s.begin()); - return collapse(s); -} - -bool AssetResolver::build(const std::string& root, const std::vector& prio, - std::string* err) { - assets_root = root; - std::error_code ec; - if (!fs::exists(root, ec)) { - if (err) *err = "assets 根不存在: " + root; - return false; - } - - // 收集 (rank, real_path, rel_norm) 后按 rank 稳定排序 —— 保证先注册者 = 高优先级 - struct Rec { - int rank; - std::string real, rel; - }; - std::vector recs; - fs::path base(root); - for (auto it = fs::recursive_directory_iterator( - root, fs::directory_options::skip_permission_denied, ec); - it != fs::recursive_directory_iterator(); it.increment(ec)) { - if (ec) { ec.clear(); continue; } - if (!it->is_regular_file(ec)) continue; - std::string rel_real = fs::relative(it->path(), base, ec).generic_string(); - std::string rel = lower(rel_real); - if (rel.empty()) continue; - std::string top = rel.substr(0, rel.find('/')); - // real_path 存**相对** assets_root(保留原始大小写);resolve() 拼回。 - recs.push_back({pack_rank(top, prio), rel_real, rel}); - } - std::stable_sort(recs.begin(), recs.end(), - [](const Rec& a, const Rec& b) { return a.rank < b.rank; }); - - std::vector seen_conflicts; - for (auto& r : recs) { - ++files_indexed; - // by_rel - { - auto& e = by_rel[r.rel]; - if (e.real_path.empty()) e.real_path = r.real; - e.all_candidates.push_back(r.real); - } - // by_ymir - std::string suf = ymir_suffix(r.rel); - if (!suf.empty()) { - auto& e = by_ymir[suf]; - if (e.real_path.empty()) { - e.real_path = r.real; - } else { - ++ymir_conflicts; - if (seen_conflicts.size() < 50 && - std::find(seen_conflicts.begin(), seen_conflicts.end(), suf) == - seen_conflicts.end()) { - seen_conflicts.push_back(suf); - conflict_keys.push_back(suf); - } - } - e.all_candidates.push_back(r.real); - } - } - return true; -} - -std::string AssetResolver::resolve(const std::string& vp, std::string* reason) const { - // The 40250 pack manager already resolves its own virtual paths and patch priority. - // Keep the drive prefix: CEterPackManager indexes "d:/ymir work/..." as such. - if (assets_root == "pack://") { - std::string name = lower(vp); - std::replace(name.begin(), name.end(), '\\', '/'); - if (name.rfind("pack://", 0) == 0) name.erase(0, 7); - if (name.empty()) { - if (reason) *reason = "empty pack path"; - return ""; - } - return assets_root + name; - } - auto join = [this](const std::string& rel) { - if (rel.empty()) return std::string(); - if (assets_root.empty()) return rel; - std::string r = assets_root; - if (r.back() != '/') r += '/'; - return r + rel; - }; - std::string norm = normalize(vp); - std::string suf = ymir_suffix(norm); - if (!suf.empty()) { - auto it = by_ymir.find(suf); - if (it != by_ymir.end()) return join(it->second.real_path); - if (reason) *reason = "未在 ymir 索引找到: " + suf; - return ""; - } - auto it = by_rel.find(norm); - if (it != by_rel.end()) return join(it->second.real_path); - if (reason) *reason = "未在相对路径索引找到: " + norm; - return ""; -} - -// --- 索引烘焙 / 装载 --------------------------------------------------- - -std::string AssetResolver::save_index() const { - // 行式:MTIDX1 头 + 每行 "Y|R\t\t"。只存被采用的 real_path。 - std::ostringstream ss; - ss << "MTIDX1\n"; - for (const auto& kv : by_ymir) { - ss << "Y\t" << kv.first << '\t' << kv.second.real_path << '\n'; - } - for (const auto& kv : by_rel) { - ss << "R\t" << kv.first << '\t' << kv.second.real_path << '\n'; - } - return ss.str(); -} - -bool AssetResolver::load_index(const std::string& root, const std::string& text, - std::string* err) { - by_ymir.clear(); - by_rel.clear(); - files_indexed = 0; - ymir_conflicts = 0; - conflict_keys.clear(); - assets_root = root; - - std::istringstream in(text); - std::string line; - if (!std::getline(in, line) || line.rfind("MTIDX1", 0) != 0) { - if (err) *err = "asset_index:坏头(期望 MTIDX1)"; - return false; - } - while (std::getline(in, line)) { - if (line.empty() || line[0] == '#') continue; - // tag \t key \t rel - size_t t1 = line.find('\t'); - size_t t2 = (t1 == std::string::npos) ? std::string::npos : line.find('\t', t1 + 1); - if (t2 == std::string::npos) continue; - std::string tag = line.substr(0, t1); - std::string key = line.substr(t1 + 1, t2 - t1 - 1); - std::string rel = line.substr(t2 + 1); - if (!rel.empty() && rel.back() == '\r') rel.pop_back(); - if (key.empty() || rel.empty()) continue; - Entry e; - e.real_path = rel; - if (tag == "Y") { - by_ymir.emplace(std::move(key), std::move(e)); - } else if (tag == "R") { - by_rel.emplace(std::move(key), std::move(e)); - } - ++files_indexed; - } - if (by_ymir.empty() && by_rel.empty()) { - if (err) *err = "asset_index:空索引"; - return false; - } - return true; -} - -bool AssetResolver::build_or_load(const std::string& root, - const std::vector& prio, std::string* err) { - if (root == "pack://") { - assets_root = root; - return true; - } - std::string text; - if (read_file(root + "/asset_index.txt", text) && text.rfind("MTIDX1", 0) == 0) { - return load_index(root, text, err); - } - return build(root, prio, err); -} - -bool AssetResolver::exists(const std::string& vp) const { - return !resolve(vp, nullptr).empty(); -} - -std::vector AssetResolver::all_rel() const { - std::vector out; - out.reserve(by_rel.size()); - for (const auto& kv : by_rel) out.push_back(kv.second.real_path); - return out; -} - -} // namespace fmt diff --git a/formats/asset_resolver.h b/formats/asset_resolver.h deleted file mode 100644 index 143a7e2e..00000000 --- a/formats/asset_resolver.h +++ /dev/null @@ -1,64 +0,0 @@ -// AssetResolver —— 虚拟路径(`d:\ymir work\...`)-> 真实散文件路径。 -// SHINSOO §4.2 / §9-W0 / BACKLOG G7。无 godot 依赖(放 formats/ 以便 CTest; -// SHINSOO §7.1 原列在 extension/src,此处按「解析层不依赖 godot」的原则前移)。 -// -// 散文件按原 eterpack 名散在多个一级目录(Zone/ Terrain/ ETC/ PC/ Tree/ Property/ -// metin2_patch_*/ ...),每个下面有 `ymir work/`。所以按「ymir work/ 之后的后缀」建索引, -// 而不是假设 `assets/ymir work/...`。 -#pragma once -#include -#include -#include - -namespace fmt { - -struct AssetResolver { - struct Entry { - std::string real_path; // 采用的真实路径,**相对 assets_root**(resolve 时拼回) - std::vector all_candidates; // 全部命中(开发模式查 patch 覆盖;load_index 后为空) - }; - - // key = 规范化后的索引键(小写 / '/')。两套: - // by_ymir : "ymir work/..." 之后的后缀 (虚拟路径主用) - // by_rel : assets 根起的相对路径 (地图数据等直接相对寻址) - std::map by_ymir; - std::map by_rel; - - int files_indexed = 0; - int ymir_conflicts = 0; // 同 key 多个真实文件 - std::vector conflict_keys; // 去重后的冲突 key(前若干个) - std::string assets_root; - - // pack 优先级:越靠前越优先(先注册者胜)。默认基础包在前、patch 包在后。 - // 未列出的一级目录按字母序排在「基础」与「patch」之间。 - bool build(const std::string& assets_root, - const std::vector& pack_priority = default_priority(), - std::string* err = nullptr); - - // 烘焙 / 装载索引(PCK 里没法 std::filesystem 扫目录)。 - // save_index() -> 一段文本(行式,路径相对 assets_root) - // load_index() <- 该文本 + 运行时 assets_root(resolve 拼回真实路径) - std::string save_index() const; - bool load_index(const std::string& assets_root, const std::string& text, - std::string* err = nullptr); - - // assets_root 下有 asset_index.txt 就 load,否则 build() 扫盘。 - // 读文件走 fmt::read_file(host 可注入 FileAccess -> res:// 可用)。 - bool build_or_load(const std::string& assets_root, - const std::vector& pack_priority = default_priority(), - std::string* err = nullptr); - - // 规范化:'\'->'/',去盘符,去开头 '/',小写,折叠 '//',处理 '.'/'..'。 - static std::string normalize(const std::string& virtual_path); - - // 解析。成功返回真实路径;失败返回 "" 且(可选)写 reason。 - std::string resolve(const std::string& virtual_path, std::string* reason = nullptr) const; - bool exists(const std::string& virtual_path) const; - - // 所有已索引文件的相对路径(by_rel 的 real_path 去重)。PropertyRegistry::scan_list 用。 - std::vector all_rel() const; - - static std::vector default_priority(); -}; - -} // namespace fmt diff --git a/formats/attribute_data.cpp b/formats/attribute_data.cpp deleted file mode 100644 index 332ca82c..00000000 --- a/formats/attribute_data.cpp +++ /dev/null @@ -1,165 +0,0 @@ -#include "attribute_data.h" - -#include -#include -#include - -namespace fmt { - -namespace { - -constexpr char kHeader[] = "AttributeData"; -constexpr std::size_t kHeaderSize = sizeof(kHeader); // include trailing NUL -constexpr std::uint32_t kMaxRecords = 1u << 20; -constexpr std::uint32_t kMaxHeightVertices = 1u << 24; - -struct Reader { - const std::uint8_t *data = nullptr; - std::size_t size = 0; - std::size_t offset = 0; - std::string *error = nullptr; - - bool fail(const std::string &message) { - if (error) - *error = message + " at offset " + std::to_string(offset); - return false; - } - - bool require(std::size_t count) { - if (count > size || offset > size - count) - return fail("AttributeData truncated"); - return true; - } - - template - bool read(T &value) { - if (!require(sizeof(T))) - return false; - std::memcpy(&value, data + offset, sizeof(T)); - offset += sizeof(T); - return true; - } - - bool read_bytes(void *dst, std::size_t count) { - if (!require(count)) - return false; - std::memcpy(dst, data + offset, count); - offset += count; - return true; - } -}; - -std::size_t dimension_count(std::uint32_t type) { - switch (static_cast(type)) { - case AttributeCollisionType::Plane: - case AttributeCollisionType::Cylinder: - return 2; - case AttributeCollisionType::Box: - case AttributeCollisionType::Sphere: - case AttributeCollisionType::Aabb: - case AttributeCollisionType::Obb: - return type == static_cast(AttributeCollisionType::Sphere) ? 1 : 3; - default: - return 0; - } -} - -std::string fixed_name(const char (&raw)[32]) { - const void *nul = std::memchr(raw, '\0', 32); - const auto count = nul ? static_cast(nul) - raw : 32; - return std::string(raw, static_cast(count)); -} - -} // namespace - -bool parse_attribute_data(const std::uint8_t *data, std::size_t size, - AttributeData &out, std::string *err) { - out = AttributeData{}; - if (data == nullptr) - return err ? ((*err = "AttributeData buffer is null"), false) : false; - - Reader r{data, size, 0, err}; - char header[kHeaderSize] = {}; - if (!r.read_bytes(header, kHeaderSize)) - return false; - if (std::memcmp(header, kHeader, kHeaderSize) != 0) - return r.fail("AttributeData bad header"); - - std::uint32_t collision_count = 0; - std::uint32_t height_count = 0; - if (!r.read(collision_count) || !r.read(height_count)) - return false; - if (collision_count > kMaxRecords || height_count > kMaxRecords) - return r.fail("AttributeData record count is unreasonable"); - - out.collisions.reserve(collision_count); - for (std::uint32_t i = 0; i < collision_count; ++i) { - AttributeCollision collision; - if (!r.read(collision.type)) - return false; - const std::size_t dims = dimension_count(collision.type); - if (dims == 0) - return r.fail("AttributeData unknown collision type"); - - char raw_name[32] = {}; - if (!r.read_bytes(raw_name, sizeof(raw_name)) || - !r.read_bytes(collision.position.data(), sizeof(float) * 3) || - !r.read_bytes(collision.dimensions.data(), sizeof(float) * dims) || - !r.read_bytes(collision.quaternion.data(), sizeof(float) * 4)) - return false; - collision.name = fixed_name(raw_name); - out.collisions.push_back(std::move(collision)); - } - - out.heights.reserve(height_count); - for (std::uint32_t i = 0; i < height_count; ++i) { - AttributeHeight height; - char raw_name[32] = {}; - std::uint32_t vertex_count = 0; - if (!r.read_bytes(raw_name, sizeof(raw_name)) || !r.read(vertex_count)) - return false; - if (vertex_count > kMaxHeightVertices) - return r.fail("AttributeData height vertex count is unreasonable"); - if (vertex_count > 0 && vertex_count > (std::numeric_limits::max() / 12)) - return r.fail("AttributeData height size overflows"); - if (!r.require(static_cast(vertex_count) * 12)) - return false; - height.name = fixed_name(raw_name); - height.vertices.resize(vertex_count); - for (auto &vertex : height.vertices) { - if (!r.read_bytes(vertex.data(), sizeof(float) * 3)) - return false; - } - out.heights.push_back(std::move(height)); - } - - if (r.offset != size) - return r.fail("AttributeData trailing bytes"); - return true; -} - -bool parse_attribute_data_file(const std::string &path, AttributeData &out, - std::string *err) { - std::ifstream file(path, std::ios::binary | std::ios::ate); - if (!file) { - if (err) - *err = "cannot open AttributeData: " + path; - return false; - } - const std::streamoff end = file.tellg(); - if (end < 0) { - if (err) - *err = "cannot stat AttributeData: " + path; - return false; - } - std::vector bytes(static_cast(end)); - file.seekg(0, std::ios::beg); - if (!bytes.empty() && !file.read(reinterpret_cast(bytes.data()), static_cast(bytes.size()))) { - if (err) - *err = "cannot read AttributeData: " + path; - return false; - } - return parse_attribute_data(bytes.data(), bytes.size(), out, err); -} - -} // namespace fmt diff --git a/formats/attribute_data.h b/formats/attribute_data.h deleted file mode 100644 index 09a79c7c..00000000 --- a/formats/attribute_data.h +++ /dev/null @@ -1,56 +0,0 @@ -// .mdatr —— Metin2 AttributeData 静态碰撞 / 高度网格资源。 -// -// The legacy client reads this file as a packed little-endian stream. Keep the -// format layer independent from Godot so it can be used by the world loader and -// by host-side validation tests alike. -#pragma once - -#include -#include -#include -#include - -namespace fmt { - -enum class AttributeCollisionType : std::uint32_t { - Plane = 0, - Box = 1, - Sphere = 2, - Cylinder = 3, - Aabb = 4, - Obb = 5, -}; - -struct AttributeCollision { - std::uint32_t type = 0; - std::string name; - std::array position = {0.0f, 0.0f, 0.0f}; - // Plane/Cylinder use dimensions[0..1], the other supported primitives use - // dimensions[0..2]. Values retain the source units (centimetres). - std::array dimensions = {0.0f, 0.0f, 0.0f}; - // x, y, z, w in the same order as the D3DXQUATERNION on disk. - std::array quaternion = {0.0f, 0.0f, 0.0f, 1.0f}; -}; - -struct AttributeHeight { - std::string name; - // The legacy file calls these vertices "primitives". They are a flat - // triangle list: every consecutive three vertices form one triangle. - std::vector> vertices; -}; - -struct AttributeData { - std::vector collisions; - std::vector heights; -}; - -// Parse the complete byte buffer. The parser rejects truncated data, unknown -// primitive types and unreasonable counts rather than accepting a partial -// collision resource. -bool parse_attribute_data(const std::uint8_t *data, std::size_t size, - AttributeData &out, std::string *err = nullptr); - -bool parse_attribute_data_file(const std::string &path, AttributeData &out, - std::string *err = nullptr); - -} // namespace fmt diff --git a/formats/combo_table.cpp b/formats/combo_table.cpp deleted file mode 100644 index 35a0938a..00000000 --- a/formats/combo_table.cpp +++ /dev/null @@ -1,186 +0,0 @@ -// M2 §3.5 —— playersettingmodule.py 的 ComboAttackNew 调用 -> PC 连击段表。 -#include "combo_table.h" -#include "m2_tokvec.h" // fmt::read_file - -#include -#include - -namespace fmt { - -const std::vector* ComboTable::get(uint16_t motion_mode, uint16_t combo_type) const { - auto it = combos.find(make_combo_key(motion_mode, combo_type)); - return it == combos.end() ? nullptr : &it->second; -} - -const ComboTable& PlayerComboTables::klass(int combo_class) const { - static const ComboTable kEmpty; - if (combo_class < 0 || combo_class >= COMBO_CLASS_COUNT) return kEmpty; - return per_class[combo_class]; -} - -namespace { - -std::string trim(const std::string& s) { - size_t a = 0, b = s.size(); - while (a < b && std::isspace(static_cast(s[a]))) ++a; - while (b > a && std::isspace(static_cast(s[b - 1]))) --b; - return s.substr(a, b - a); -} - -bool starts_with(const std::string& s, const char* p) { - return s.rfind(p, 0) == 0; -} - -// chr.MOTION_MODE_XXX -> CRaceMotionData::EMode 值。 -bool resolve_motion_mode(const std::string& suffix, long& out) { - static const std::map kMap = { - {"RESERVED", 0}, {"GENERAL", 1}, {"ONEHAND_SWORD", 2}, {"TWOHAND_SWORD", 3}, - {"DUALHAND_SWORD", 4}, {"BOW", 5}, {"FAN", 6}, {"BELL", 7}, {"FISHING", 8}, - {"HORSE", 9}, {"HORSE_ONEHAND_SWORD", 10}, {"HORSE_TWOHAND_SWORD", 11}, - {"HORSE_DUALHAND_SWORD", 12}, {"HORSE_BOW", 13}, {"HORSE_FAN", 14}, - {"HORSE_BELL", 15}, {"WEDDING_DRESS", 16}, - }; - auto it = kMap.find(suffix); - if (it == kMap.end()) return false; - out = it->second; - return true; -} - -// COMBO_TYPE_N / COMBO_INDEX_N -> N-1(两者都是从 1 起的人读编号,值从 0 起)。 -bool resolve_one_based(const std::string& tail, long& out) { - if (tail.empty()) return false; - char* end = nullptr; - long n = std::strtol(tail.c_str(), &end, 10); - if (end == tail.c_str() || *end != '\0' || n < 1) return false; - out = n - 1; - return true; -} - -// 一个实参 token -> 整数。认符号常量,也认裸整数。 -bool resolve_token(const std::string& tok_in, long& out) { - const std::string tok = trim(tok_in); - if (tok.empty()) return false; - - if (starts_with(tok, "chr.MOTION_MODE_")) { - return resolve_motion_mode(tok.substr(sizeof("chr.MOTION_MODE_") - 1), out); - } - if (starts_with(tok, "chr.MOTION_COMBO_ATTACK_")) { - if (!resolve_one_based(tok.substr(sizeof("chr.MOTION_COMBO_ATTACK_") - 1), out)) return false; - out = COMBO_NAME_COMBO_ATTACK_1 + out; // 0-based n -> 段号 14 + n - return true; - } - if (tok == "chr.MOTION_NORMAL_ATTACK") { out = COMBO_NAME_NORMAL_ATTACK; return true; } - if (starts_with(tok, "COMBO_TYPE_")) { return resolve_one_based(tok.substr(sizeof("COMBO_TYPE_") - 1), out); } - if (starts_with(tok, "COMBO_INDEX_")) { return resolve_one_based(tok.substr(sizeof("COMBO_INDEX_") - 1), out); } - - // 裸整数 - char* end = nullptr; - long n = std::strtol(tok.c_str(), &end, 10); - if (end == tok.c_str() || *end != '\0') return false; - out = n; - return true; -} - -// "a, b, c)"(call 名后的部分)-> 解析出的整数实参。分号里没有嵌套括号。 -bool parse_call_args(const std::string& after_paren, std::vector& out) { - size_t close = after_paren.find(')'); - if (close == std::string::npos) return false; - const std::string inner = after_paren.substr(0, close); - out.clear(); - size_t start = 0; - while (start <= inner.size()) { - size_t comma = inner.find(',', start); - std::string tok = inner.substr(start, comma == std::string::npos ? std::string::npos : comma - start); - tok = trim(tok); - if (!tok.empty()) { - long v = 0; - if (!resolve_token(tok, v)) return false; - out.push_back(v); - } - if (comma == std::string::npos) break; - start = comma + 1; - } - return true; -} - -int class_from_def_line(const std::string& line) { - if (line.find("def __LoadGameWarriorEx") != std::string::npos) return COMBO_CLASS_WARRIOR; - if (line.find("def __LoadGameAssassinEx") != std::string::npos) return COMBO_CLASS_ASSASSIN; - if (line.find("def __LoadGameSuraEx") != std::string::npos) return COMBO_CLASS_SURA; - if (line.find("def __LoadGameShamanEx") != std::string::npos) return COMBO_CLASS_SHAMAN; - return -1; -} - -} // namespace - -bool parse_player_combo_tables(const std::string& py_text, PlayerComboTables& out, std::string* err) { - out = PlayerComboTables{}; - - int cur_class = -1; - size_t pos = 0; - const size_t n = py_text.size(); - while (pos < n) { - size_t eol = py_text.find('\n', pos); - std::string line = py_text.substr(pos, eol == std::string::npos ? std::string::npos : eol - pos); - pos = (eol == std::string::npos) ? n : eol + 1; - - const std::string t = trim(line); - if (t.empty() || t[0] == '#') continue; - - // 顶层 def 换块:只有四个 __LoadGameEx 有连击段调用,其它 def 复位。 - if (starts_with(line, "def ")) { - cur_class = class_from_def_line(line); - continue; - } - if (cur_class < 0) continue; - - const char* kReserve = "chrmgr.ReserveComboAttackNew("; - const char* kRegister = "chrmgr.RegisterComboAttackNew("; - - size_t r = t.find(kReserve); - if (r != std::string::npos) { - std::vector args; - if (!parse_call_args(t.substr(r + std::string(kReserve).size()), args) || args.size() != 3) { - if (err) *err = "combo_table: 无法解析 ReserveComboAttackNew: " + t; - return false; - } - const uint32_t key = make_combo_key(static_cast(args[0]), static_cast(args[1])); - const long count = args[2] < 0 ? 0 : args[2]; - // CRaceData::ReserveComboAttack 用 map::insert —— 已存在的 key 不覆盖。 - out.per_class[cur_class].combos.emplace( - key, std::vector(static_cast(count), 0)); - continue; - } - - size_t g = t.find(kRegister); - if (g != std::string::npos) { - std::vector args; - if (!parse_call_args(t.substr(g + std::string(kRegister).size()), args) || args.size() != 4) { - if (err) *err = "combo_table: 无法解析 RegisterComboAttackNew: " + t; - return false; - } - const uint32_t key = make_combo_key(static_cast(args[0]), static_cast(args[1])); - const long idx = args[2]; - const uint16_t motion = static_cast(args[3]); - auto it = out.per_class[cur_class].combos.find(key); - if (it == out.per_class[cur_class].combos.end()) continue; // 未 Reserve:跳过 - if (idx < 0 || static_cast(idx) >= it->second.size()) continue; // 越界:跳过 - it->second[static_cast(idx)] = motion; - continue; - } - } - - if (err) err->clear(); - return true; -} - -bool parse_player_combo_tables_file(const std::string& path, PlayerComboTables& out, std::string* err) { - std::string s; - if (!read_file(path, s)) { - if (err) *err = "combo_table: 打不开 " + path; - return false; - } - return parse_player_combo_tables(s, out, err); -} - -} // namespace fmt diff --git a/formats/combo_table.h b/formats/combo_table.h deleted file mode 100644 index 1d73b7bf..00000000 --- a/formats/combo_table.h +++ /dev/null @@ -1,92 +0,0 @@ -// combo_table —— PC 连击段表(CRaceData::TComboAttackDataMap 的等价)。M2 §3.5。 -// -// 参考端的 PC 连击段表**不在** .msm 里(.msm 只有 BaseModelFileName + HairData)。 -// 它由 playersettingmodule.py 的 chrmgr.ReserveComboAttackNew / RegisterComboAttackNew -// 调用在 CRaceData 上建起来(UserInterface/PythonCharacterManagerModule.cpp → -// CRaceData::ReserveComboAttack / RegisterComboAttack,GameLib/RaceData.cpp)。 -// 本解析器就把那批调用读成同一张表。 -// -// NPC/怪物的连击段走另一条路(RaceManager.cpp __LoadRaceMotionList 读 motlist.txt, -// 只在 MODE_GENERAL 下登记 NAME_COMBO_ATTACK_1/2/3,没有段号向量),不在这里。 -#pragma once -#include -#include -#include -#include - -namespace fmt { - -// CRaceMotionData::EMode(chr.MOTION_MODE_*)。combo key 的高 16 位。 -enum ComboMotionMode : uint16_t { - COMBO_MODE_RESERVED = 0, - COMBO_MODE_GENERAL = 1, - COMBO_MODE_ONEHAND_SWORD = 2, - COMBO_MODE_TWOHAND_SWORD = 3, - COMBO_MODE_DUALHAND_SWORD = 4, - COMBO_MODE_BOW = 5, - COMBO_MODE_FAN = 6, - COMBO_MODE_BELL = 7, - COMBO_MODE_FISHING = 8, - COMBO_MODE_HORSE = 9, - COMBO_MODE_HORSE_ONEHAND_SWORD = 10, - COMBO_MODE_HORSE_TWOHAND_SWORD = 11, - COMBO_MODE_HORSE_DUALHAND_SWORD = 12, - COMBO_MODE_HORSE_BOW = 13, - COMBO_MODE_HORSE_FAN = 14, - COMBO_MODE_HORSE_BELL = 15, - COMBO_MODE_WEDDING_DRESS = 16, -}; - -// CRaceMotionData::EName 的攻击段(chr.MOTION_NORMAL_ATTACK / chr.MOTION_COMBO_ATTACK_*)。 -// ComboIndexVector 里存的就是这些段号。 -enum : uint16_t { - COMBO_NAME_NORMAL_ATTACK = 13, - COMBO_NAME_COMBO_ATTACK_1 = 14, - COMBO_NAME_COMBO_ATTACK_8 = 21, -}; - -// RaceData.h: MAKE_COMBO_KEY(motion_mode, combo_type) -inline uint32_t make_combo_key(uint16_t motion_mode, uint16_t combo_type) { - return (static_cast(motion_mode) << 16) | static_cast(combo_type); -} -inline uint16_t combo_key_mode(uint32_t key) { return static_cast((key >> 16) & 0xFFFF); } -inline uint16_t combo_key_type(uint32_t key) { return static_cast(key & 0xFFFF); } - -// playersettingmodule.py 按 __LoadGameEx(race, path) 分四块,男女同一函数体 -// (连击段表与性别无关),所以这里按职业收,不按 race。 -enum ComboClass : int { - COMBO_CLASS_WARRIOR = 0, - COMBO_CLASS_ASSASSIN = 1, - COMBO_CLASS_SURA = 2, - COMBO_CLASS_SHAMAN = 3, - COMBO_CLASS_COUNT = 4, -}; - -// CRaceData::TComboAttackDataMap 的等价:MAKE_COMBO_KEY -> ComboIndexVector。 -struct ComboTable { - // key = make_combo_key(mode, type);value = 有序的 COMBO_NAME_COMBO_ATTACK_* 段号, - // 下标即 dwComboArrayIndex(m_dwcurComboIndex - 1)。 - std::map> combos; - - // GetComboDataPointer:命中返回段号向量指针,否则 nullptr。 - const std::vector* get(uint16_t motion_mode, uint16_t combo_type) const; - bool empty() const { return combos.empty(); } - size_t key_count() const { return combos.size(); } -}; - -struct PlayerComboTables { - ComboTable per_class[COMBO_CLASS_COUNT]; - // 越界返回一张空表(不抛)。 - const ComboTable& klass(int combo_class) const; -}; - -// 解析 playersettingmodule.py 里的 chrmgr.ReserveComboAttackNew / RegisterComboAttackNew -// 调用,按 def __LoadGameEx 分块填 per_class。照 CRaceData 语义: -// Reserve -> combos[key] = vector(count, 0)(重复 key 不覆盖,同 std::map::insert) -// Register -> combos[key][index] = motion(key 未 Reserve 或 index 越界则跳过) -// 认得的符号:chr.MOTION_MODE_*、chr.MOTION_COMBO_ATTACK_N(=13+N)、 -// chr.MOTION_NORMAL_ATTACK(=13)、COMBO_TYPE_N(=N-1)、COMBO_INDEX_N(=N-1)、裸整数。 -bool parse_player_combo_tables(const std::string& py_text, PlayerComboTables& out, std::string* err); -bool parse_player_combo_tables_file(const std::string& path, PlayerComboTables& out, std::string* err); - -} // namespace fmt diff --git a/formats/environment.cpp b/formats/environment.cpp deleted file mode 100644 index b97cd6dd..00000000 --- a/formats/environment.cpp +++ /dev/null @@ -1,218 +0,0 @@ -#include "environment.h" - -#include "m2_tokvec.h" // read_file - -#include -#include -#include -#include - -namespace fmt { - -namespace { - -bool ieq(const std::string& a, const char* b) { - if (a.size() != std::strlen(b)) return false; - for (size_t i = 0; i < a.size(); ++i) - if (std::tolower((unsigned char)a[i]) != std::tolower((unsigned char)b[i])) return false; - return true; -} - -std::vector tok_line(const std::string& line) { - std::vector out; - size_t i = 0, n = line.size(); - while (i < n) { - char c = line[i]; - if (c == '#' || (c == '/' && i + 1 < n && line[i + 1] == '/')) break; - if (std::isspace((unsigned char)c)) { ++i; continue; } - if (c == '{' || c == '}') { out.emplace_back(1, c); ++i; continue; } - if (c == '"') { - ++i; - std::string s; - while (i < n && line[i] != '"') s += line[i++]; - if (i < n) ++i; - out.push_back(s); - continue; - } - std::string s; - while (i < n && !std::isspace((unsigned char)line[i]) && line[i] != '{' && line[i] != '}') - s += line[i++]; - out.push_back(s); - } - return out; -} - -struct Block { - std::string name; - bool is_list = false; - std::vector> lines; // kv lines (lines[k][0] = key) - std::vector> rows; // List rows - std::vector children; - - const std::vector* kv(const char* key) const { - for (auto& l : lines) - if (!l.empty() && ieq(l[0], key)) return &l; - return nullptr; - } - const Block* child(const char* nm) const { - for (auto& c : children) - if (ieq(c.name, nm)) return &c; - return nullptr; - } - float f(const char* key, int idx, float def = 0) const { - auto* l = kv(key); - return (l && (int)l->size() > idx) ? (float)std::atof((*l)[idx].c_str()) : def; - } - int i(const char* key, int def = 0) const { - auto* l = kv(key); - return (l && l->size() > 1) ? std::atoi((*l)[1].c_str()) : def; - } - std::string s(const char* key, const std::string& def = "") const { - auto* l = kv(key); - return (l && l->size() > 1) ? (*l)[1] : def; - } -}; - -bool parse_tree(const std::string& text, Block& root, std::string* err) { - std::istringstream in(text); - std::string line; - std::vector stack{&root}; - std::string pending; // name of a Group/List awaiting '{' - bool pending_list = false; - - while (std::getline(in, line)) { - if (!line.empty() && line.back() == '\r') line.pop_back(); - auto t = tok_line(line); - for (size_t k = 0; k < t.size(); ++k) { - const std::string& x = t[k]; - if (x == "{") { - Block b; - b.name = pending; - b.is_list = pending_list; - stack.back()->children.push_back(std::move(b)); - stack.push_back(&stack.back()->children.back()); - pending.clear(); - pending_list = false; - } else if (x == "}") { - if (stack.size() <= 1) { if (err) *err = "msenv: 多余的 }"; return false; } - stack.pop_back(); - } else if (ieq(x, "Group") || ieq(x, "List")) { - pending_list = ieq(x, "List"); - pending = (k + 1 < t.size()) ? t[k + 1] : ""; - ++k; - } else { - // 一行剩余 token 作为一条记录 - std::vector rec(t.begin() + k, t.end()); - if (stack.back()->is_list) { - std::vector row; - for (auto& v : rec) row.push_back((float)std::atof(v.c_str())); - stack.back()->rows.push_back(std::move(row)); - } else { - stack.back()->lines.push_back(std::move(rec)); - } - break; // 行内其余 token 已并入本记录 - } - } - } - if (stack.size() != 1) { if (err) *err = "msenv: 块未闭合"; return false; } - return true; -} - -Rgba rgba(const std::vector* l, int off = 1) { - Rgba c{{0, 0, 0, 1}}; - if (l) - for (int k = 0; k < 4 && off + k < (int)l->size(); ++k) - c[k] = (float)std::atof((*l)[off + k].c_str()); - return c; -} -Rgba row_rgba(const std::vector& r) { - Rgba c{{0, 0, 0, 0}}; - for (int k = 0; k < 4 && k < (int)r.size(); ++k) c[k] = r[k]; - return c; -} - -} // namespace - -bool parse_environment(const std::string& text, Environment& out, std::string* err) { - Block root; - if (!parse_tree(text, root, err)) return false; - out = Environment{}; - - if (auto* l = root.kv("ScriptType")) out.script_type = l->size() > 1 ? (*l)[1] : ""; - out.script_version = root.f("ScriptVersion", 1); - out.reserved = root.i("Reserved") != 0; - - if (const Block* dl = root.child("DirectionalLight")) { - if (auto* d = dl->kv("Direction")) - for (int k = 0; k < 3 && k + 1 < (int)d->size(); ++k) - out.dir_light.direction[k] = (float)std::atof((*d)[k + 1].c_str()); - if (const Block* bg = dl->child("Background")) { - out.dir_light.bg_enable = bg->i("Enable") != 0; - out.dir_light.bg_diffuse = rgba(bg->kv("Diffuse")); - out.dir_light.bg_ambient = rgba(bg->kv("Ambient")); - } - if (const Block* ch = dl->child("Character")) { - out.dir_light.ch_enable = ch->i("Enable") != 0; - out.dir_light.ch_diffuse = rgba(ch->kv("Diffuse")); - out.dir_light.ch_ambient = rgba(ch->kv("Ambient")); - } - } - if (const Block* m = root.child("Material")) { - out.material.diffuse = rgba(m->kv("Diffuse")); - out.material.ambient = rgba(m->kv("Ambient")); - out.material.emissive = rgba(m->kv("Emissive")); - } - if (const Block* fg = root.child("Fog")) { - out.fog.fog_level = fg->i("foglevel", 0); - out.fog.density_fog = fg->i("IsDensity") != 0; - out.fog.near_distance = fg->f("NearDistance", 1); - out.fog.far_distance = fg->f("FarDistance", 1); - out.fog.color = rgba(fg->kv("Color")); - out.fog.enable = (fg->kv("Enable") && fg->i("Enable") != 0) || out.fog.fog_level > 0; - } - if (const Block* flt = root.child("Filter")) { - out.filter.enable = flt->i("Enable") != 0; - out.filter.color = rgba(flt->kv("Color")); - out.filter.alpha_src = flt->i("AlphaSrc", out.filter.alpha_src); - out.filter.alpha_dest = flt->i("AlphaDest", out.filter.alpha_dest); - } - if (const Block* sb = root.child("SkyBox")) { - out.sky.texture_render_mode = sb->i("BTextureRenderMode") != 0; - for (int k = 0; k < 3; ++k) out.sky.scale[k] = sb->f("Scale", k + 1); - out.sky.gradient_level_upper = sb->i("GradientLevelUpper"); - out.sky.gradient_level_lower = sb->i("GradientLevelLower"); - static constexpr const char* kFaceKeys[6] = { - "FrontFaceFileName", "BackFaceFileName", "LeftFaceFileName", - "RightFaceFileName", "TopFaceFileName", "BottomFaceFileName"}; - for (int k = 0; k < 6; ++k) - out.sky.face_textures[k] = sb->s(kFaceKeys[k]); - for (int k = 0; k < 2; ++k) { - out.sky.cloud_scale[k] = sb->f("CloudScale", k + 1); - out.sky.cloud_texture_scale[k] = sb->f("CloudTextureScale", k + 1); - out.sky.cloud_speed[k] = sb->f("CloudSpeed", k + 1); - } - out.sky.cloud_height = sb->f("CloudHeight", 1); - out.sky.cloud_texture = sb->s("CloudTextureFileName"); - if (const Block* cc = sb->child("CloudColor")) - for (auto& r : cc->rows) out.sky.cloud_color.push_back(row_rgba(r)); - if (const Block* gr = sb->child("Gradient")) - for (auto& r : gr->rows) out.sky.gradient.push_back(row_rgba(r)); - } - if (const Block* lf = root.child("LensFlare")) { - out.lens_flare.enable = lf->i("Enable") != 0; - out.lens_flare.brightness_color = rgba(lf->kv("BrightnessColor")); - out.lens_flare.max_brightness = lf->f("MaxBrightness", 1); - out.lens_flare.main_flare_enable = lf->i("MainFlareEnable") != 0; - out.lens_flare.main_flare_texture = lf->s("MainFlareTextureFileName"); - out.lens_flare.main_flare_size = lf->f("MainFlareSize", 1); - } - return true; -} - -bool parse_environment_file(const std::string& path, Environment& out, std::string* err) { - std::string text; - if (!read_file(path, text)) { if (err) *err = "打不开 " + path; return false; } - return parse_environment(text, out, err); -} - -} // namespace fmt diff --git a/formats/environment.h b/formats/environment.h deleted file mode 100644 index ea4b01e3..00000000 --- a/formats/environment.h +++ /dev/null @@ -1,72 +0,0 @@ -// .msenv(首行 `ScriptType EnvrionmentData` —— 原格式拼写错误,照收)。 -// 文本,`Group NAME { ... }` + `List NAME { ... }`(匿名 rgba 行)。SHINSOO §5.5。 -// 真值:ETC/ymir work/environment/*.msenv 实测 + EterLib 环境类。W5 用。 -#pragma once -#include -#include -#include - -namespace fmt { - -using Rgba = std::array; -using Vec3f = std::array; -using Vec2f = std::array; - -struct EnvDirLight { - Vec3f direction{{0.5f, 0.5f, -0.5f}}; - bool bg_enable = false, ch_enable = false; - Rgba bg_diffuse{{1, 1, 1, 1}}, bg_ambient{{0.5f, 0.5f, 0.5f, 1}}; - Rgba ch_diffuse{{1, 1, 1, 1}}, ch_ambient{{0.5f, 0.5f, 0.5f, 1}}; -}; -struct EnvMaterial { - Rgba diffuse{{0.8f, 0.8f, 0.8f, 1}}, ambient{{0.8f, 0.8f, 0.8f, 1}}, - emissive{{0.8f, 0.8f, 0.8f, 1}}; -}; -struct EnvFog { - // 两种写法:老版 `Enable`/`NearDistance`/`FarDistance`;A1 实盘用 `foglevel`(0=关,>0=开)。 - bool enable = false; // Enable != 0 || fog_level > 0 - bool density_fog = false; // IsDensity(参考端保留,当前 Godot 用深度雾) - int fog_level = 0; // foglevel - float near_distance = 25600.0f * 0.5f, far_distance = 25600.0f * 0.7f; - Rgba color{{0.5f, 0.5f, 0.5f, 1}}; -}; -struct EnvFilter { - bool enable = false; - Rgba color{{0.3f, 0.1f, 0.1f, 0}}; - int alpha_src = 1; // D3DBLEND_ONE - int alpha_dest = 1; // D3DBLEND_ONE -}; -struct EnvSkyBox { - Vec3f scale{{3500, 3500, 3500}}; - bool texture_render_mode = false; - int gradient_level_upper = 0, gradient_level_lower = 0; - std::array face_textures{}; // front/back/left/right/top/bottom - Vec2f cloud_scale{{200000, 200000}}, cloud_texture_scale{{4, 4}}, cloud_speed{{0.001f, 0.001f}}; - float cloud_height = 30000; - std::string cloud_texture; - std::vector cloud_color; // List CloudColor - std::vector gradient; // List Gradient(成对 = 一段渐变的上下色) -}; -struct EnvLensFlare { - bool enable = false, main_flare_enable = false; - Rgba brightness_color{{1, 1, 1, 1}}; - float max_brightness = 1, main_flare_size = 0.2f; - std::string main_flare_texture; -}; - -struct Environment { - std::string script_type; // "EnvrionmentData" - float script_version = 0; - EnvDirLight dir_light; - EnvMaterial material; - EnvFog fog; - EnvFilter filter; - EnvSkyBox sky; - EnvLensFlare lens_flare; - bool reserved = false; -}; - -bool parse_environment(const std::string& text, Environment& out, std::string* err); -bool parse_environment_file(const std::string& path, Environment& out, std::string* err); - -} // namespace fmt diff --git a/formats/m2_coord.cpp b/formats/m2_coord.cpp deleted file mode 100644 index 3fa0862f..00000000 --- a/formats/m2_coord.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "m2_coord.h" - -#include -#include - -namespace fmt::m2coord { - -std::string tile_dir(int tile_x, int tile_y) { - char buf[16]; - std::snprintf(buf, sizeof(buf), "%06u", tile_id(tile_x, tile_y)); - return buf; -} - -namespace { -Mat3 mul(const Mat3& a, const Mat3& b) { - Mat3 r{}; - for (int i = 0; i < 3; ++i) - for (int j = 0; j < 3; ++j) - for (int k = 0; k < 3; ++k) - r.m[i * 3 + j] += a.m[i * 3 + k] * b.m[k * 3 + j]; - return r; -} -Mat3 rot_x(double a) { - double c = std::cos(a), s = std::sin(a); - return {{1, 0, 0, 0, c, -s, 0, s, c}}; -} -Mat3 rot_y(double a) { - double c = std::cos(a), s = std::sin(a); - return {{c, 0, s, 0, 1, 0, -s, 0, c}}; -} -Mat3 rot_z(double a) { - double c = std::cos(a), s = std::sin(a); - return {{c, -s, 0, s, c, 0, 0, 0, 1}}; -} -} // namespace - -Mat3 ypr_basis(double yaw_deg, double pitch_deg, double roll_deg) { - const double d2r = 3.14159265358979323846 / 180.0; - return mul(mul(rot_y(yaw_deg * d2r), rot_x(pitch_deg * d2r)), rot_z(roll_deg * d2r)); -} - -Mat3 object_basis_godot(double yaw_deg, double pitch_deg, double roll_deg) { - // Conjugate the Metin2-space rotation through the Z-up -> Y-up axis swap - // C = rotate(-90deg, X): (x,y,z) -> (x,z,-y). R_godot = C * R_m2 * C^-1 - const Mat3 C{{1, 0, 0, 0, 0, 1, 0, -1, 0}}; - const Mat3 Ci{{1, 0, 0, 0, 0, -1, 0, 1, 0}}; - return mul(mul(C, ypr_basis(yaw_deg, pitch_deg, roll_deg)), Ci); -} - -bool parse_tile_dir(const std::string& name, int& tile_x, int& tile_y) { - if (name.size() != 6) return false; - for (char c : name) - if (c < '0' || c > '9') return false; - long id = std::strtol(name.c_str(), nullptr, 10); - tile_x = int(id / 1000); - tile_y = int(id % 1000); - return true; -} - -} // namespace fmt::m2coord diff --git a/formats/m2_coord.h b/formats/m2_coord.h deleted file mode 100644 index 29daffed..00000000 --- a/formats/m2_coord.h +++ /dev/null @@ -1,66 +0,0 @@ -// Metin2 -> Godot 坐标 / 单位统一转换(纯数学,无 godot 依赖)。 -// BACKLOG I5 · SHINSOO §6。extension 侧的 mtgodot::coord 薄封装应直接调用这里, -// 不得另写公式。 -// -// Metin2:厘米,Z-up(左手) Godot:米,Y-up(右手) -// Godot.x = Metin2.x * 0.01 -// Godot.y = Metin2.z * 0.01 -// Godot.z = -Metin2.y * 0.01 -// 等价于 make_conv 的 rotate(-90°,X) + scale(0.01)。 -#pragma once -#include -#include - -namespace fmt::m2coord { - -struct Vec3 { double x = 0, y = 0, z = 0; }; - -constexpr double CM_TO_M = 0.01; -constexpr int CELLSCALE = 200; // PRTerrainLib TerrainType.h -constexpr int TERRAIN_SIZE = 128; -constexpr int CHUNK_CM = CELLSCALE * TERRAIN_SIZE; // 25600 —— 一个区块的边长(cm) - -// 位置:厘米 Z-up -> 米 Y-up。 -inline Vec3 position_to_godot(double x_cm, double y_cm, double z_cm) { - return { x_cm * CM_TO_M, z_cm * CM_TO_M, -y_cm * CM_TO_M }; -} -inline Vec3 position_to_godot(const Vec3& v) { return position_to_godot(v.x, v.y, v.z); } - -// 方向:只做轴转换,不缩放、不平移。 -inline Vec3 direction_to_godot(double x, double y, double z) { - return { x, z, -y }; -} - -// 区块目录编号:tile_id = tile_x*1000 + tile_y,目录名 = 6 位十进制。 -inline uint32_t tile_id(int tile_x, int tile_y) { - return uint32_t(tile_x) * 1000u + uint32_t(tile_y); -} -std::string tile_dir(int tile_x, int tile_y); // "000000" / "001003" -bool parse_tile_dir(const std::string& name, int& tile_x, int& tile_y); - -// 区块原点(该区块 (0,0) 格在地图内的厘米坐标,未做轴转换)。 -inline Vec3 chunk_origin_cm(int tile_x, int tile_y) { - return { double(tile_x) * CHUNK_CM, double(tile_y) * CHUNK_CM, 0.0 }; -} - -// height.raw 采样值 -> 厘米高度:raw * HeightScale。 -inline double height_raw_to_cm(uint16_t raw, double height_scale) { - return double(raw) * height_scale; -} - -struct Mat3 { double m[9]; }; // row-major: m[r*3+c] - -// AreaData 的 yaw#pitch#roll(度)-> **Metin2 Z-up 空间**的旋转(行主序 3×3)。 -// 忠实移植原客户端 `CGraphicObjectInstance::SetRotation` 的 -// `D3DXMatrixRotationYawPitchRoll(yaw, pitch, roll)`(列向量约定下 = Ry(yaw)·Rx(pitch)·Rz(roll))。 -// 注意 Metin2 世界是 Z-up:yaw 绕 Y、pitch 绕 X、**roll 绕 Z = 竖直轴 = 朝向**。 -// areadata 单值旋转 → roll(`Area.cpp:820`)。这一版**未**做 Z-up→Y-up 轴转换, -// 直接塞进 Godot Basis 会把「朝向」错当成绕 Godot Z 的翻滚 —— 放置物体请用 object_basis_godot()。 -Mat3 ypr_basis(double yaw_deg, double pitch_deg, double roll_deg); - -// 同上,但已把旋转共轭到 **Godot Y-up 空间**(R_godot = C · R_m2 · C⁻¹,C = rotate(-90°,X))。 -// 可直接作为 Godot Basis 使用:物体的 Godot 变换 = Transform3D(object_basis_godot(...), g) * make_conv()。 -// roll(朝向)→ 绕 Godot +Y 的 heading,不再翻滚。行主序 3×3。 -Mat3 object_basis_godot(double yaw_deg, double pitch_deg, double roll_deg); - -} // namespace fmt::m2coord diff --git a/formats/m2_tokvec.cpp b/formats/m2_tokvec.cpp deleted file mode 100644 index e195b86b..00000000 --- a/formats/m2_tokvec.cpp +++ /dev/null @@ -1,155 +0,0 @@ -#include "m2_tokvec.h" - -#include -#include -#include -#include -#include - -namespace fmt { - -namespace { - -std::string lower(std::string s) { - std::transform(s.begin(), s.end(), s.begin(), - [](unsigned char c) { return (char)std::tolower(c); }); - return s; -} - -bool ieq(const std::string& a, const char* b) { - return lower(a) == b; -} - -// 一行 -> token 列表。`"..."` 单 token;`#` / `//` 到行尾注释。 -std::vector tokenize_line(const std::string& line) { - std::vector out; - size_t i = 0, n = line.size(); - while (i < n) { - char c = line[i]; - if (c == '#' || (c == '/' && i + 1 < n && line[i + 1] == '/')) break; - if (std::isspace((unsigned char)c)) { ++i; continue; } - if (c == '"') { - ++i; - std::string s; - while (i < n && line[i] != '"') s += line[i++]; - if (i < n) ++i; // 收尾引号 - out.push_back(s); - continue; - } - std::string s; - while (i < n && !std::isspace((unsigned char)line[i])) - s += line[i++]; - out.push_back(s); - } - return out; -} - -} // namespace - -bool TokVecMap::has(const std::string& key) const { return m.count(key) != 0; } - -const std::vector* TokVecMap::find(const std::string& key) const { - auto it = m.find(lower(key)); - return it == m.end() ? nullptr : &it->second; -} - -std::string TokVecMap::str(const std::string& key, const std::string& def) const { - auto* v = find(key); - return (v && !v->empty()) ? (*v)[0] : def; -} - -long TokVecMap::inum(const std::string& key, long def) const { - auto* v = find(key); - return (v && !v->empty()) ? std::strtol((*v)[0].c_str(), nullptr, 10) : def; -} - -double TokVecMap::num(const std::string& key, double def) const { - auto* v = find(key); - return (v && !v->empty()) ? std::strtod((*v)[0].c_str(), nullptr) : def; -} - -bool parse_tokvec(const std::string& text, TokVecMap& out, std::string* err) { - out = TokVecMap{}; - std::istringstream in(text); - std::string line; - - std::string block_key; // 非空 = 正在收块 - std::vector block_tokens; - std::vector seen_dups; - - auto commit = [&](const std::string& key, std::vector toks) { - std::string k = lower(key); - if (out.m.count(k)) { - out.dup_count++; - if (std::find(seen_dups.begin(), seen_dups.end(), k) == seen_dups.end()) { - seen_dups.push_back(k); - out.dup_keys.push_back(k); - } - return; // 保留第一个 - } - out.m.emplace(std::move(k), std::move(toks)); - }; - - while (std::getline(in, line)) { - if (!line.empty() && line.back() == '\r') line.pop_back(); - auto toks = tokenize_line(line); - if (toks.empty()) continue; - - if (!block_key.empty()) { - if (ieq(toks[0], "end")) { - commit(block_key, std::move(block_tokens)); - block_key.clear(); - block_tokens.clear(); - } else { - for (auto& t : toks) block_tokens.push_back(std::move(t)); - } - continue; - } - - if (ieq(toks[0], "start")) { - if (toks.size() < 2) { - if (err) *err = "Start 缺块名"; - return false; - } - block_key = toks[1]; - block_tokens.clear(); - continue; - } - - // 顶层 `key v1 v2 ...` - std::string key = toks[0]; - std::vector vals(toks.begin() + 1, toks.end()); - commit(key, std::move(vals)); - } - - if (!block_key.empty()) { - // 文件在块中截断 —— 宽容收尾但记 err - commit(block_key, std::move(block_tokens)); - if (err) *err = "文件在 Start '" + block_key + "' 块中截断(缺 End)"; - } - return true; -} - -static FileReader g_file_reader = nullptr; -void set_file_reader(FileReader r) { g_file_reader = r; } - -bool read_file(const std::string& path, std::string& out) { - if (g_file_reader) return g_file_reader(path, out); - std::ifstream f(path, std::ios::binary); - if (!f) return false; - std::ostringstream ss; - ss << f.rdbuf(); - out = ss.str(); - return true; -} - -bool parse_tokvec_file(const std::string& path, TokVecMap& out, std::string* err) { - std::string text; - if (!read_file(path, text)) { - if (err) *err = "打不开文件: " + path; - return false; - } - return parse_tokvec(text, out, err); -} - -} // namespace fmt diff --git a/formats/m2_tokvec.h b/formats/m2_tokvec.h deleted file mode 100644 index 25e8fa0a..00000000 --- a/formats/m2_tokvec.h +++ /dev/null @@ -1,43 +0,0 @@ -// Metin2 地图文本格式的通用解析 —— 对标原客户端 EterBase `LoadMultipleTextData` + -// `CTokenVectorMap`(`GameLib/Area.cpp`、`PRTerrainLib/TextureSet.cpp` 都用它)。 -// -// 语义: -// - 以空白分隔 token;`"..."` 为单 token;`#` 或 `//` 到行尾是注释。 -// - 顶层行 `key v1 v2 ...` -> map[lower(key)] = [v1, v2, ...] -// - `Start ` ... `End []` -> map[lower(Name)] = [块内所有 token 展平] -// - 重复 key:保留第一个,`dup_count` 记录冲突数(W0 报告用)。 -// -// 无 godot 依赖,纯 C++20,走 CTest。SHINSOO §9-W0 / §5。 -#pragma once -#include -#include -#include - -namespace fmt { - -struct TokVecMap { - std::map> m; - int dup_count = 0; // 重复 key 次数 - std::vector dup_keys; // 重复的 key 名(去重后) - - bool has(const std::string& key) const; // key 已小写 - const std::vector* find(const std::string& key) const; - // 便捷取值(key 传入时大小写不敏感) - std::string str(const std::string& key, const std::string& def = "") const; - long inum(const std::string& key, long def = 0) const; - double num(const std::string& key, double def = 0) const; -}; - -// 解析整段文本。语法层面不会失败(宽容解析);err 仅在明显结构错误时写。 -bool parse_tokvec(const std::string& text, TokVecMap& out, std::string* err); -bool parse_tokvec_file(const std::string& path, TokVecMap& out, std::string* err); - -// 小工具:整文件读入字符串。失败返回 false。 -// Whole-file read used by every fmt loader. By default std::ifstream; the host -// app can install a reader that pulls from res:// (Godot PCK on iOS/Android) via -// set_file_reader(). The standalone CTests leave it unset -> plain ifstream. -using FileReader = bool (*)(const std::string& path, std::string& out); -void set_file_reader(FileReader r); // nullptr resets to the ifstream default -bool read_file(const std::string& path, std::string& out); - -} // namespace fmt diff --git a/formats/map_setting.cpp b/formats/map_setting.cpp deleted file mode 100644 index bf9627c0..00000000 --- a/formats/map_setting.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "map_setting.h" - -#include "m2_tokvec.h" - -#include - -namespace fmt { - -bool parse_map_setting(const std::string& text, MapSetting& out, std::string* err) { - TokVecMap tv; - std::string perr; - parse_tokvec(text, tv, &perr); - - out = MapSetting{}; - - if (!tv.has("mapsize")) { - if (err) *err = "setting.txt 缺 MapSize"; - return false; - } - if (const auto* v = tv.find("mapsize"); v && v->size() >= 2) { - out.map_size_x = (int)std::strtol((*v)[0].c_str(), nullptr, 10); - out.map_size_y = (int)std::strtol((*v)[1].c_str(), nullptr, 10); - } else { - if (err) *err = "setting.txt MapSize 需要两个整数"; - return false; - } - if (out.map_size_x <= 0 || out.map_size_y <= 0) { - if (err) *err = "setting.txt MapSize 非法"; - return false; - } - - if (tv.has("cellscale")) out.cell_scale = (int)tv.inum("cellscale"); - if (tv.has("heightscale")) out.height_scale = tv.num("heightscale"); - out.view_radius = (int)tv.inum("viewradius", 0); - - if (const auto* v = tv.find("baseposition"); v && v->size() >= 2) { - out.base_position_x = std::strtol((*v)[0].c_str(), nullptr, 10); - out.base_position_y = std::strtol((*v)[1].c_str(), nullptr, 10); - } - - out.texture_set = tv.str("textureset"); - out.environment = tv.str("environment"); - - if (out.cell_scale <= 0) { - if (err) *err = "setting.txt CellScale 非法"; - return false; - } - return true; -} - -bool parse_map_setting_file(const std::string& path, MapSetting& out, std::string* err) { - std::string text; - if (!read_file(path, text)) { - if (err) *err = "打不开 " + path; - return false; - } - return parse_map_setting(text, out, err); -} - -} // namespace fmt diff --git a/formats/map_setting.h b/formats/map_setting.h deleted file mode 100644 index 3aff204c..00000000 --- a/formats/map_setting.h +++ /dev/null @@ -1,26 +0,0 @@ -// setting.txt(ScriptType MapSetting)—— 地图全局设置。 -// 对标 GameLib/MapOutdoorLoad.cpp 的 setting 解析。SHINSOO §5.1。 -#pragma once -#include - -namespace fmt { - -struct MapSetting { - int cell_scale = 200; // CellScale(cm/格),默认取 PRTerrainLib 常量 - double height_scale = 0.5; // HeightScale(raw 高度乘数) - int view_radius = 0; // ViewRadius - int map_size_x = 0; // MapSize 第 1 个数(区块列数) - int map_size_y = 0; // MapSize 第 2 个数(区块行数) - long base_position_x = 0; // BasePosition(全局世界基准,cm) - long base_position_y = 0; - std::string texture_set; // TextureSet 相对路径(原样,含反斜杠) - std::string environment; // Environment(.msenv 名) - - int chunk_count() const { return map_size_x * map_size_y; } -}; - -// text = setting.txt 全文。缺关键字段 -> false + err。 -bool parse_map_setting(const std::string& text, MapSetting& out, std::string* err); -bool parse_map_setting_file(const std::string& path, MapSetting& out, std::string* err); - -} // namespace fmt diff --git a/formats/msa.cpp b/formats/msa.cpp deleted file mode 100644 index 7e03544a..00000000 --- a/formats/msa.cpp +++ /dev/null @@ -1,174 +0,0 @@ -// M2 T1 —— .msa 解析(照 EterGrnLib/Util.cpp CGrannyMotion::LoadMotionData 的字段)。 -#include "msa.h" -#include "textscript.h" -#include - -namespace fmt { - -static void vec3(const std::vector* l, float* out) { - if (!l) return; - for (int k = 0; k < 3 && k + 1 < (int)l->size(); ++k) out[k] = float(std::atof((*l)[k + 1].c_str())); -} - -static void loop_data(const Node& root, Msa& out) { - if (const Node* loop = root.group("LoopData")) { - out.has_loop_data = true; - out.motion_loop_count = loop->inum("MotionLoopCount", -1); - out.loop_cancel_enable = loop->inum("LoopCancelEnable", 0) != 0; - out.loop_start_time = loop->num("LoopStartTime"); - out.loop_end_time = loop->num("LoopEndTime"); - } -} - -// `List HitPosition { t lastXYZ XYZ t lastXYZ XYZ ... }` —— 7 个一组切成采样点。 -static void hit_positions(const Node& win, std::vector& out) { - const Node* lst = win.group("HitPosition"); - if (!lst || lst->lines.empty()) return; - const std::vector& t = lst->lines[0]; - for (size_t i = 0; i + 7 <= t.size(); i += 7) { - Msa::HitSample s; - s.time = float(std::atof(t[i].c_str())); - for (int k = 0; k < 3; ++k) s.last_pos[k] = float(std::atof(t[i + 1 + k].c_str())); - for (int k = 0; k < 3; ++k) s.pos[k] = float(std::atof(t[i + 4 + k].c_str())); - out.push_back(s); - } -} - -// 一个命中窗(NRaceData::THitData)。老式写法里 win == AttackingData 组本身。 -static Msa::HitWindow hit_window(const Node& win) { - Msa::HitWindow w; - w.start_time = win.num("AttackingStartTime"); - w.end_time = win.num("AttackingEndTime"); - w.bone_name = win.str("AttackingBone"); - w.weapon_length = win.num("WeaponLength"); - hit_positions(win, w.samples); - return w; -} - -// Group ComboInputData / Group AttackingData —— 照 EterGrnLib CGrannyMotion::LoadMotionData -// 与 GameLib NRaceData::LoadMotionAttackData 的字段名读取;缺组时保持默认值。 -static void combat_data(const Node& root, Msa& out) { - if (const Node* c = root.group("ComboInputData")) { - out.has_combo_input = true; - out.combo_pre_input_time = c->num("PreInputTime"); - out.combo_direct_input_time = c->num("DirectInputTime"); - out.combo_input_limit_time = c->num("InputLimitTime"); - out.combo_link_time = c->num("LinkTime"); - } - if (const Node* a = root.group("AttackingData")) { - out.has_attacking_data = true; - out.attacking_type = a->inum("AttackType", a->inum("AttackingType", 0)); - out.motion_type = a->inum("MotionType", out.attacking_type); - out.hitting_type = a->inum("HittingType", 0); - out.stiffen_time = a->num("StiffenTime"); - out.invisible_time = a->num("InvisibleTime"); - out.external_force = a->num("ExternalForce"); - out.hit_limit_count = a->inum("HitLimitCount", 0); - - // 新式:HitDataCount N + Group HitData00..0N;老式:无 HitDataCount,组本身即窗。 - bool has_children = false; - for (const Node& g : a->groups) { - const std::string& n = g.name; - if (n.size() >= 7 && (n.compare(0, 7, "HitData") == 0 || n.compare(0, 7, "hitdata") == 0)) { - out.hit_windows.push_back(hit_window(g)); - has_children = true; - } - } - if (!has_children) - out.hit_windows.push_back(hit_window(*a)); - - if (!out.hit_windows.empty()) { - out.attack_start_time = out.hit_windows.front().start_time; - out.attack_end_time = out.hit_windows.front().end_time; - } - } -} - -static void motion_event(const Node& ev, MotionEvent& e) { - e.type = ev.inum("MotionEventType"); - e.start_time = ev.num("StartingTime"); - e.duration_time = ev.num("DuringTime"); - e.effect_file = ev.str("EffectFileName"); - e.sound_file = ev.str("SoundFileName"); - e.attaching_bone = ev.str("AttachingBoneName"); - e.attaching = ev.inum("AttachingEnable") != 0; - e.following = ev.inum("FollowingEnable") != 0; - e.independent = ev.inum("IndependentFlag") != 0; - e.fishing_effect = ev.inum("FishingEffectFlag") != 0; - vec3(ev.find("EffectPosition"), e.position); - - // 40250 TMotionEventDataFly has its own resource and offset fields. - e.fly_file = ev.str("FlyFileName"); - e.fly_attaching_bone = ev.str("AttachingBoneName"); - e.fly_attaching = ev.inum("AttachingEnable") != 0; - vec3(ev.find("FlyPosition"), e.fly_position); - - // 40250 TScreenWavingEventData defaults AffectingRange to zero and reads - // DuringTime/Power from the event itself. - e.power = ev.inum("Power"); - e.affecting_range = ev.inum("AffectingRange"); - - // 40250 TMotionAttackingEventData defaults EnableHitProcess to TRUE. - e.enable_hit_process = ev.inum("EnableHitProcess", 1) != 0; - e.attack_type = ev.inum("AttackType", ev.inum("AttackingType")); - e.hitting_type = ev.inum("HittingType"); - e.stiffen_time = ev.num("StiffenTime"); - e.invisible_time = ev.num("InvisibleTime"); - e.external_force = ev.num("ExternalForce"); - e.hit_limit_count = ev.inum("HitLimitCount"); - e.collision_type = ev.inum("CollisionType"); - for (const Node& g : ev.groups) { - if (g.name.size() < 10 || g.name.compare(0, 10, "SphereData") != 0) - continue; - MotionEvent::CollisionSphere sphere; - sphere.radius = g.num("Radius"); - vec3(g.find("Position"), sphere.position); - e.collision_spheres.push_back(sphere); - } -} - -static void motion_events(const Node& root, Msa& out) { - const Node* med = root.group("MotionEventData"); - if (!med) return; - int count = med->inum("MotionEventDataCount", int(med->groups.size())); - (void)count; - for (const Node& ev : med->groups) { - MotionEvent e; - motion_event(ev, e); - out.events.push_back(std::move(e)); - } -} - -bool parse_msa(const std::string& text, Msa& out, std::string* err) { - Node root; - if (!parse_textscript(text, root, err)) return false; - out = Msa{}; - - out.motion_gr2 = root.str("MotionFileName"); - out.duration = root.num("MotionDuration"); - vec3(root.find("Accumulation"), out.accumulation); - loop_data(root, out); - combat_data(root, out); - - motion_events(root, out); - - if (out.motion_gr2.empty()) { if (err) *err = "msa: 缺 MotionFileName"; return false; } - return true; -} - -bool parse_msa_file(const std::string& path, Msa& out, std::string* err) { - Node root; - if (!parse_textscript_file(path, root, err)) return false; - // 复用上面逻辑:重解析文本更简单,这里直接从 root 走一遍 - out = Msa{}; - out.motion_gr2 = root.str("MotionFileName"); - out.duration = root.num("MotionDuration"); - vec3(root.find("Accumulation"), out.accumulation); - loop_data(root, out); - combat_data(root, out); - motion_events(root, out); - if (out.motion_gr2.empty()) { if (err) *err = "msa: 缺 MotionFileName (" + path + ")"; return false; } - return true; -} - -} // namespace fmt diff --git a/formats/msa.h b/formats/msa.h deleted file mode 100644 index de5ec29e..00000000 --- a/formats/msa.h +++ /dev/null @@ -1,108 +0,0 @@ -// .msa —— Metin2 动作描述(文本,ScriptType MotionData)。M2 T1。 -#pragma once -#include -#include - -namespace fmt { - -struct MotionEvent { - int type = 0; // MotionEventType(1=effect, 4=special attack, 6=fly, ...) - float start_time = 0; // StartingTime - float duration_time = 0; // DuringTime(SCREEN_WAVING / SPECIAL_ATTACKING) - std::string effect_file; // EffectFileName(type 1/10) - std::string sound_file; // SoundFileName - std::string attaching_bone; - bool attaching = false; - bool following = false; - bool independent = false; - bool fishing_effect = false; - float position[3] = {0, 0, 0}; - - // FLY 的字段不能复用 EFFECT 的 EffectFileName/EffectPosition:40250 - // 在 MotionEventDataEvent.h 中使用另一套 FlyFileName/FlyPosition。 - std::string fly_file; - std::string fly_attaching_bone; - bool fly_attaching = false; - float fly_position[3] = {0, 0, 0}; - - // SCREEN_WAVING 参数(GameEventManager::ProcessEventScreenWaving)。 - int power = 0; - int affecting_range = 0; - - // SPECIAL_ATTACKING 参数(TMotionAttackingEventData)。 - bool enable_hit_process = true; // 40250 缺省值为 TRUE - int attack_type = 0; - int hitting_type = 0; - float stiffen_time = 0; - float invisible_time = 0; - float external_force = 0; - int hit_limit_count = 0; - int collision_type = 0; - struct CollisionSphere { - float radius = 0; - float position[3] = {0, 0, 0}; - }; - std::vector collision_spheres; -}; - -struct Msa { - std::string motion_gr2; // MotionFileName(原样,含 d:\... 前缀) - float duration = 0; // MotionDuration - float accumulation[3] = {0,0,0};// Accumulation(root motion 位移) - std::vector events; - bool has_loop_data = false; // LoopData 是片段循环,不等同于整段播放模式 - int motion_loop_count = 0; // -1 无限;原客户端仅在 >1 或 -1 时回绕片段 - bool loop_cancel_enable = false; - float loop_start_time = 0; - float loop_end_time = 0; - - // Group ComboInputData —— 连击输入时间窗(EterGrnLib CGrannyMotion::LoadMotionData → - // CRaceMotionData::TComboInputData)。攻击节奏来自这里,不是硬编码间隔。 - // PreInputTime → fInputStartTime 连击输入窗开始(可提前缓存下一击) - // DirectInputTime→ fNextComboTime 直接输入阈值 / 下一段连击起点(= 普攻节奏) - // InputLimitTime → fInputEndTime 连击输入窗关闭(超时归零) - // LinkTime → fComboLinkTime 段间衔接时间 - bool has_combo_input = false; - float combo_pre_input_time = 0; - float combo_direct_input_time = 0; - float combo_input_limit_time = 0; - float combo_link_time = 0; - - // Group AttackingData —— 命中判定窗(GameLib GameType.cpp NRaceData::TMotionAttackData)。 - // 两种写法:老式(组内直接 AttackingStartTime/…/List HitPosition,无 HitDataCount)= - // 单个命中窗;新式(AttackType + MotionType + HitDataCount N + Group HitData00..0N)= - // N 个命中窗(多段挥击 / 旋风斩)。命中帧 / 硬直 / 无敌帧由动作数据驱动。 - bool has_attacking_data = false; - int attacking_type = 0; // AttackType / AttackingType(SAttackData::iAttackType) - int motion_type = 0; // MotionType(缺省回退到 attacking_type) - int hitting_type = 0; // HittingType - float stiffen_time = 0; // StiffenTime(受击硬直,喂给 §3.7 / 受击方) - float invisible_time = 0; // InvisibleTime(攻击者无敌帧) - float external_force = 0; // ExternalForce(击退力度) - int hit_limit_count = 0; // HitLimitCount(0 = 不限) - - // HitPosition 单个采样:time + 上一帧位置(xyz) + 当前帧位置(xyz),用于挥击扫掠球判定。 - struct HitSample { - float time = 0; - float last_pos[3] = {0, 0, 0}; - float pos[3] = {0, 0, 0}; - }; - // 一个命中窗(NRaceData::THitData)。 - struct HitWindow { - float start_time = 0; // AttackingStartTime - float end_time = 0; // AttackingEndTime - std::string bone_name; // AttackingBone - float weapon_length = 0; // WeaponLength - std::vector samples; // List HitPosition - }; - std::vector hit_windows; // = THitDataContainer;老式写法长度为 1 - - // 兼容旧调用方:第一个命中窗的起止时间(无命中窗时为 0)。 - float attack_start_time = 0; - float attack_end_time = 0; -}; - -bool parse_msa(const std::string& text, Msa& out, std::string* err); -bool parse_msa_file(const std::string& path, Msa& out, std::string* err); - -} // namespace fmt diff --git a/formats/msm.cpp b/formats/msm.cpp deleted file mode 100644 index 4699e803..00000000 --- a/formats/msm.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// M2 T1 —— .msm 解析(照 RaceManager.cpp CRaceData::LoadRaceData 的字段子集)。 -#include "msm.h" -#include "textscript.h" - -namespace fmt { - -static bool fill(const Node& root, Msm& out, std::string* err) { - out = Msm{}; - out.base_model_gr2 = root.str("BaseModelFileName"); - out.motion_list_file = root.str("MotionListFileName"); - if (const Node* hd = root.group("HairData")) { - out.hair_path = hd->str("PathName"); - for (const Node& h : hd->groups) { - HairEntry e; - e.index = h.inum("HairIndex"); - e.model = h.str("Model"); - e.source_skin = h.str("SourceSkin"); - e.target_skin = h.str("TargetSkin"); - out.hairs.push_back(std::move(e)); - } - } - if (out.base_model_gr2.empty()) { if (err) *err = "msm: 缺 BaseModelFileName"; return false; } - return true; -} - -bool parse_msm(const std::string& text, Msm& out, std::string* err) { - Node root; - if (!parse_textscript(text, root, err)) return false; - return fill(root, out, err); -} -bool parse_msm_file(const std::string& path, Msm& out, std::string* err) { - Node root; - if (!parse_textscript_file(path, root, err)) return false; - return fill(root, out, err); -} - -} // namespace fmt diff --git a/formats/msm.h b/formats/msm.h deleted file mode 100644 index d178e1e2..00000000 --- a/formats/msm.h +++ /dev/null @@ -1,27 +0,0 @@ -// .msm —— Metin2 种族/模型描述(文本,ScriptType RaceDataScript)。M2 T1。 -// 照 RaceManager.cpp CRaceData::LoadRaceData。 -#pragma once -#include -#include - -namespace fmt { - -struct HairEntry { - int index = 0; - std::string model; // gr2(相对 PathName) - std::string source_skin; - std::string target_skin; -}; - -struct Msm { - std::string base_model_gr2; // BaseModelFileName - std::string motion_list_file; // MotionListFileName - std::string hair_path; // HairData.PathName - std::vector hairs; - // 武器 / 时装挂点 / 材质类型按需补(PoC 先到发型 + base) -}; - -bool parse_msm(const std::string& text, Msm& out, std::string* err); -bool parse_msm_file(const std::string& path, Msm& out, std::string* err); - -} // namespace fmt diff --git a/formats/property.cpp b/formats/property.cpp deleted file mode 100644 index c4114208..00000000 --- a/formats/property.cpp +++ /dev/null @@ -1,168 +0,0 @@ -#include "property.h" - -#include "m2_tokvec.h" // read_file - -#include -#include -#include -#include -#include - -namespace fmt { - -namespace fs = std::filesystem; - -std::string Property::get(const std::string& key, const std::string& def) const { - auto it = kv.find(key); - return it == kv.end() ? def : it->second; -} - -PropertyType property_type_from_string(const std::string& s) { - std::string l = s; - std::transform(l.begin(), l.end(), l.begin(), [](unsigned char c) { return (char)std::tolower(c); }); - if (l == "tree") return PropertyType::Tree; - if (l == "building") return PropertyType::Building; - if (l == "effect") return PropertyType::Effect; - if (l == "ambience") return PropertyType::Ambience; - if (l == "dungeonblock") return PropertyType::DungeonBlock; - return PropertyType::Unknown; -} - -bool parse_property(const std::string& text, Property& out, std::string* err) { - out = Property{}; - std::istringstream in(text); - std::string line; - - // 行1: YPRT - if (!std::getline(in, line)) { if (err) *err = "空文件"; return false; } - while (!line.empty() && (line.back() == '\r' || line.back() == ' ' || line.back() == '\t')) - line.pop_back(); - { - std::string t; - for (char c : line) if (!std::isspace((unsigned char)c)) t += c; - if (t != "YPRT") { if (err) *err = "首行不是 YPRT: '" + t + "'"; return false; } - } - // 行2: crc - if (!std::getline(in, line)) { if (err) *err = "缺 CRC 行"; return false; } - out.crc = (uint32_t)std::strtoul(line.c_str(), nullptr, 10); - if (out.crc == 0) { if (err) *err = "CRC 行解析为 0: '" + line + "'"; return false; } - - // 行3+: key\t"value" - while (std::getline(in, line)) { - if (!line.empty() && line.back() == '\r') line.pop_back(); - // key = 第一段非空白 - size_t i = 0, n = line.size(); - while (i < n && std::isspace((unsigned char)line[i])) ++i; - if (i >= n) continue; - size_t ks = i; - while (i < n && !std::isspace((unsigned char)line[i])) ++i; - std::string key = line.substr(ks, i - ks); - std::transform(key.begin(), key.end(), key.begin(), - [](unsigned char c) { return (char)std::tolower(c); }); - // value = 引号内,或剩余去空白 - while (i < n && std::isspace((unsigned char)line[i])) ++i; - std::string val; - if (i < n && line[i] == '"') { - ++i; - while (i < n && line[i] != '"') val += line[i++]; - } else { - val = line.substr(i); - while (!val.empty() && (val.back() == '\r' || std::isspace((unsigned char)val.back()))) - val.pop_back(); - } - out.kv[key] = val; - } - - out.name = out.get("propertyname"); - out.type_str = out.get("propertytype"); - out.type = property_type_from_string(out.type_str); - return true; -} - -bool parse_property_file(const std::string& path, Property& out, std::string* err) { - std::string text; - if (!read_file(path, text)) { if (err) *err = "打不开 " + path; return false; } - if (!parse_property(text, out, err)) return false; - out.source_path = path; - return true; -} - -const Property* PropertyRegistry::find(uint32_t crc) const { - auto it = by_crc.find(crc); - return it == by_crc.end() ? nullptr : &it->second; -} - -bool PropertyRegistry::scan(const std::string& root, std::string* err) { - std::error_code ec; - if (!fs::exists(root, ec)) { if (err) *err = "目录不存在: " + root; return false; } - - static const char* kExts[] = {".prb", ".prt", ".pre", ".prd", ".pra"}; - for (auto it = fs::recursive_directory_iterator( - root, fs::directory_options::skip_permission_denied, ec); - it != fs::recursive_directory_iterator(); it.increment(ec)) { - if (ec) { ec.clear(); continue; } - if (!it->is_regular_file(ec)) continue; - std::string ext = it->path().extension().string(); - std::transform(ext.begin(), ext.end(), ext.begin(), - [](unsigned char c) { return (char)std::tolower(c); }); - if (std::find(std::begin(kExts), std::end(kExts), ext) == std::end(kExts)) continue; - - ++files_scanned; - Property p; - std::string e2; - if (!parse_property_file(it->path().string(), p, &e2)) { - ++parse_failed; - failed_paths.push_back(it->path().string() + " : " + e2); - continue; - } - type_counts[p.type_str.empty() ? "" : p.type_str]++; - auto [ins, ok] = by_crc.emplace(p.crc, p); - if (!ok) ++crc_collisions; - } - return true; -} - -bool PropertyRegistry::scan_list(const std::string& root, - const std::vector& rel_paths, std::string* err) { - static const char* kExts[] = {".prb", ".prt", ".pre", ".prd", ".pra"}; - std::string r = root; - if (!r.empty() && r.back() == '/') r.pop_back(); - for (const std::string& rel : rel_paths) { - // 只认顶层 Property/ 下的(对齐 scan(root + "/Property"),不吃 patch 覆盖) - if (rel.size() < 9) continue; - { - std::string top = rel.substr(0, 8); - std::transform(top.begin(), top.end(), top.begin(), - [](unsigned char c) { return (char)std::tolower(c); }); - if (top != "property" || (rel[8] != '/' && rel[8] != '\\')) continue; - } - std::string ext; - size_t dot = rel.find_last_of('.'); - if (dot != std::string::npos) { - ext = rel.substr(dot); - std::transform(ext.begin(), ext.end(), ext.begin(), - [](unsigned char c) { return (char)std::tolower(c); }); - } - if (std::find(std::begin(kExts), std::end(kExts), ext) == std::end(kExts)) continue; - - ++files_scanned; - Property p; - std::string e2; - std::string full = r + "/" + rel; - if (!parse_property_file(full, p, &e2)) { // read_file -> host FileAccess -> res:// ok - ++parse_failed; - failed_paths.push_back(full + " : " + e2); - continue; - } - type_counts[p.type_str.empty() ? "" : p.type_str]++; - auto [ins, ok] = by_crc.emplace(p.crc, p); - if (!ok) ++crc_collisions; - } - if (files_scanned == 0) { - if (err) *err = "清单里没有属性文件(.pr*)"; - return false; - } - return true; -} - -} // namespace fmt diff --git a/formats/property.h b/formats/property.h deleted file mode 100644 index a4092df6..00000000 --- a/formats/property.h +++ /dev/null @@ -1,55 +0,0 @@ -// Property 文件(`.prb` Building / `.prt` Tree / `.pre` Effect / `.prd` DungeonBlock / -// `.pra` Ambience)+ CRC 注册表。SHINSOO §5.6 / §9-W0 / BACKLOG E13。 -// -// 文件格式(文本): -// 行1: YPRT -// 行2: 十进制 uint32 -// 行3+: \t"" (key 小写,value 去引号) -// -// AreaData 的 property_crc 指向这里的 crc。W0 只建 crc -> Property 索引,不做实例化。 -#pragma once -#include -#include -#include -#include - -namespace fmt { - -enum class PropertyType { Unknown, Tree, Building, Effect, Ambience, DungeonBlock }; - -struct Property { - uint32_t crc = 0; - PropertyType type = PropertyType::Unknown; - std::string name; // propertyname - std::string type_str; // propertytype 原字符串 - std::map kv; // 全部键值(含 buildingfile / treefile / ...) - std::string source_path; // 来源文件(诊断用) - - std::string get(const std::string& key, const std::string& def = "") const; -}; - -PropertyType property_type_from_string(const std::string& s); - -bool parse_property(const std::string& text, Property& out, std::string* err); -bool parse_property_file(const std::string& path, Property& out, std::string* err); - -// 扫一个目录树,收集所有 property 文件,按 crc 索引。 -struct PropertyRegistry { - std::map by_crc; - int files_scanned = 0; - int parse_failed = 0; - int crc_collisions = 0; // 同 crc 出现多次(保留第一个) - std::vector failed_paths; - std::map type_counts; // "Tree" -> N ... - - const Property* find(uint32_t crc) const; - // root 通常是 `/Property`。递归找 *.prb/*.prt/*.pre/*.prd/*.pra(std::filesystem)。 - bool scan(const std::string& root, std::string* err); - - // 同上,但文件清单外部给(PCK 里没法 recursive_directory_iterator)。 - // rel_paths 里挑属性扩展名的,逐个 read_file(root + "/" + rel) 解析。 - bool scan_list(const std::string& root, const std::vector& rel_paths, - std::string* err); -}; - -} // namespace fmt diff --git a/formats/splat.cpp b/formats/splat.cpp deleted file mode 100644 index 796777f1..00000000 --- a/formats/splat.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include "splat.h" - -namespace fmt { - -void build_splat(const TileMap& tile, int runtime_layer_count, SplatSet& out) { - out = SplatSet{}; - const int S = SPLAT_RAW_XY; // 258 - const auto& t = tile.raw; // 258*258 - if ((int)t.size() != S * S) return; - - // 直方图 + 出现过的图层 - int maxidx = 0; - for (uint8_t v : t) maxidx = std::max(maxidx, (int)v); - out.tile_histogram.assign(maxidx + 1, 0); - for (uint8_t v : t) out.tile_histogram[v]++; - - const int limit = std::max(runtime_layer_count - 1, maxidx); - for (int i = 1; i <= limit; ++i) { - if (i >= (int)out.tile_histogram.size() || out.tile_histogram[i] == 0) continue; - - SplatLayer L; - L.layer = i; - L.alpha.resize(size_t(S) * S); - int cov = 0; - for (int y = 0; y < S; ++y) { - const uint8_t* row = &t[size_t(y) * S]; - const uint8_t* up = y > 0 ? row - S : nullptr; - const uint8_t* dn = y < S - 1 ? row + S : nullptr; - uint8_t* a = &L.alpha[size_t(y) * S]; - for (int x = 0; x < S; ++x) { - uint8_t tn = row[x]; - if (tn == i) { - a[x] = 0xFF; - ++cov; - } else if (tn > i) { - bool found = false; - if (x > 0 && row[x - 1] == i) found = true; - else if (x < S - 1 && row[x + 1] == i) found = true; - else if (up) { - if (up[x] == i) found = true; - else if (x > 0 && up[x - 1] == i) found = true; - else if (x < S - 1 && up[x + 1] == i) found = true; - } - if (!found && dn) { - if (dn[x] == i) found = true; - else if (x > 0 && dn[x - 1] == i) found = true; - else if (x < S - 1 && dn[x + 1] == i) found = true; - } - a[x] = found ? 0xFF : 0x00; - if (found) ++cov; - } else { - a[x] = 0x00; - } - } - } - L.coverage = cov; - out.layers.push_back(std::move(L)); - } -} - -} // namespace fmt diff --git a/formats/splat.h b/formats/splat.h deleted file mode 100644 index 7e07d6ac..00000000 --- a/formats/splat.h +++ /dev/null @@ -1,30 +0,0 @@ -// W2 —— tile.raw -> 每图层 258×258 alpha(splat 权重)。 -// 逐字节照 GameLib/AreaTerrain.cpp CTerrain::RAW_GenerateSplat: -// texel 值 = TextureSet 运行时图层索引; -// layer i 的 alpha = 0xFF 当 tile==i;当 tile>i 且 3×3 邻域有 ==i 时也 0xFF(1px 羽化);否则 0。 -// SHINSOO §9-W2。无 godot 依赖。 -#pragma once -#include -#include - -#include "terrain_files.h" - -namespace fmt { - -constexpr int SPLAT_RAW_XY = TILEMAP_RAW_XY; // 258 - -struct SplatLayer { - int layer = 0; // TextureSet 运行时索引(1..N) - std::vector alpha; // 258*258,行主序 - int coverage = 0; // alpha==0xFF 的 texel 数(调试 / 决定是否提交) -}; - -struct SplatSet { - std::vector layers; // 只含在本区块出现过的图层,按索引升序 - std::vector tile_histogram; // [runtime_layer_index] -> texel 数(长度 = max+1) -}; - -// tile 来自 load_tile_map。runtime_layer_count = TextureSet.runtime_count()(含 index 0 空层)。 -void build_splat(const TileMap& tile, int runtime_layer_count, SplatSet& out); - -} // namespace fmt diff --git a/formats/terrain_files.cpp b/formats/terrain_files.cpp deleted file mode 100644 index 13c74c87..00000000 --- a/formats/terrain_files.cpp +++ /dev/null @@ -1,106 +0,0 @@ -#include "terrain_files.h" - -#include "m2_tokvec.h" // read_file - -#include - -namespace fmt { - -namespace { -uint16_t rd_u16(const uint8_t* p) { return uint16_t(p[0]) | (uint16_t(p[1]) << 8); } -} // namespace - -bool load_height_map(const std::string& path, HeightMap& out, std::string* err) { - std::string buf; - if (!read_file(path, buf)) { if (err) *err = "打不开 " + path; return false; } - const size_t need = size_t(HEIGHTMAP_RAW_XY) * HEIGHTMAP_RAW_XY * 2; - if (buf.size() != need) { - if (err) *err = "height.raw 大小 " + std::to_string(buf.size()) + - " != " + std::to_string(need) + "(131*131*2)"; - return false; - } - out.raw.resize(size_t(HEIGHTMAP_RAW_XY) * HEIGHTMAP_RAW_XY); - const auto* p = reinterpret_cast(buf.data()); - for (size_t i = 0; i < out.raw.size(); ++i) out.raw[i] = rd_u16(p + i * 2); - return true; -} - -bool load_tile_map(const std::string& path, TileMap& out, std::string* err) { - std::string buf; - if (!read_file(path, buf)) { if (err) *err = "打不开 " + path; return false; } - const size_t need = size_t(TILEMAP_RAW_XY) * TILEMAP_RAW_XY; - if (buf.size() != need) { - if (err) *err = "tile.raw 大小 " + std::to_string(buf.size()) + - " != " + std::to_string(need) + "(258*258)"; - return false; - } - out.raw.assign(buf.begin(), buf.end()); - return true; -} - -bool load_attr_map(const std::string& path, AttrMap& out, std::string* err) { - std::string buf; - if (!read_file(path, buf)) { if (err) *err = "打不开 " + path; return false; } - const size_t payload = size_t(ATTRMAP_XY) * ATTRMAP_XY; - if (buf.size() != 6 + payload) { - if (err) *err = "attr.atr 大小 " + std::to_string(buf.size()) + - " != " + std::to_string(6 + payload) + "(6B 头 + 256*256)"; - return false; - } - const auto* p = reinterpret_cast(buf.data()); - uint16_t magic = rd_u16(p), w = rd_u16(p + 2), h = rd_u16(p + 4); - if (magic != ATTR_MAGIC) { - if (err) *err = "attr.atr magic " + std::to_string(magic) + " != 2634"; - return false; - } - if (w != ATTRMAP_XY || h != ATTRMAP_XY) { - if (err) *err = "attr.atr 尺寸头 " + std::to_string(w) + "x" + std::to_string(h) + - " != 256x256"; - return false; - } - out.data.assign(buf.begin() + 6, buf.end()); - return true; -} - -bool load_water_map(const std::string& path, WaterMap& out, std::string* err) { - std::string buf; - if (!read_file(path, buf)) { if (err) *err = "打不开 " + path; return false; } - if (buf.size() < 7) { if (err) *err = "water.wtr 太小"; return false; } - const auto* p = reinterpret_cast(buf.data()); - uint16_t magic = rd_u16(p), w = rd_u16(p + 2), h = rd_u16(p + 4); - uint8_t layers = p[6]; - if (magic != WATER_MAGIC) { - if (err) *err = "water.wtr magic " + std::to_string(magic) + " != 5426"; - return false; - } - if (w != WATERMAP_XY || h != WATERMAP_XY) { - if (err) *err = "water.wtr 尺寸头 != 128x128"; - return false; - } - const size_t ids = size_t(WATERMAP_XY) * WATERMAP_XY; - const size_t rest = buf.size() - 7; - // Terrain.cpp 接受两种:u16 层高 或 long(u32) 层高。 - size_t hsize = 0; - if (rest == ids + size_t(layers) * 2) hsize = 2; - else if (rest == ids + size_t(layers) * 4) hsize = 4; - else if (rest == ids && layers == 0) hsize = 0; - else { - if (err) *err = "water.wtr 数据段大小 " + std::to_string(rest) + - " 与 layers=" + std::to_string(layers) + " 不符"; - return false; - } - out.layer_count = layers; - out.ids.assign(buf.begin() + 7, buf.begin() + 7 + ids); - out.heights.clear(); - const auto* hp = p + 7 + ids; - for (int i = 0; i < layers; ++i) { - if (hsize == 2) out.heights.push_back((int16_t)rd_u16(hp + i * 2)); - else if (hsize == 4) - out.heights.push_back((int32_t)(uint32_t(hp[i * 4]) | (uint32_t(hp[i * 4 + 1]) << 8) | - (uint32_t(hp[i * 4 + 2]) << 16) | - (uint32_t(hp[i * 4 + 3]) << 24))); - } - return true; -} - -} // namespace fmt diff --git a/formats/terrain_files.h b/formats/terrain_files.h deleted file mode 100644 index 907fd2e1..00000000 --- a/formats/terrain_files.h +++ /dev/null @@ -1,44 +0,0 @@ -// 区块二进制:height.raw / tile.raw / attr.atr / water.wtr。 -// 真值来源:PRTerrainLib/Terrain.cpp(LoadHeightMap / RAW_LoadTileMap / LoadAttrMap / -// LoadWaterMapFile)+ Terrain.h / TerrainType.h 常量。SHINSOO §5.3。 -// -// XSIZE = 128 -// height.raw : 无头,u16 LE [131*131] (HEIGHTMAP_RAW = XSIZE+3) -// tile.raw : 无头,u8 [258*258] (TILEMAP_RAW = XSIZE*2+2) -// attr.atr : 6B 头 {u16 magic=2634, u16 w=256, u16 h=256} + u8 [256*256] -// water.wtr : 7B 头 {u16 magic=5426, u16 w=128, u16 h=128, u8 layers} -// + u8 [128*128] + layers×(u16 或 u32) 层高 -#pragma once -#include -#include -#include - -namespace fmt { - -constexpr int HEIGHTMAP_RAW_XY = 131; // 128+3 -constexpr int TILEMAP_RAW_XY = 258; // 128*2+2 -constexpr int ATTRMAP_XY = 256; // 128*2 -constexpr int WATERMAP_XY = 128; -constexpr uint16_t ATTR_MAGIC = 2634; -constexpr uint16_t WATER_MAGIC = 5426; - -struct HeightMap { - std::vector raw; // 131*131, 行主序(含 1 圈边界样本) - uint16_t at(int sx, int sy) const { // 与 Terrain.h GetHeight 一致:+1 偏移 - return raw[(sy + 1) * HEIGHTMAP_RAW_XY + (sx + 1)]; - } -}; -struct TileMap { std::vector raw; }; // 258*258 -struct AttrMap { std::vector data; }; // 256*256(去头) -struct WaterMap { - uint8_t layer_count = 0; - std::vector ids; // 128*128;0xFF = 无水 - std::vector heights; // layer_count 个 -}; - -bool load_height_map(const std::string& path, HeightMap& out, std::string* err); -bool load_tile_map(const std::string& path, TileMap& out, std::string* err); -bool load_attr_map(const std::string& path, AttrMap& out, std::string* err); -bool load_water_map(const std::string& path, WaterMap& out, std::string* err); - -} // namespace fmt diff --git a/formats/terrain_mesh.cpp b/formats/terrain_mesh.cpp deleted file mode 100644 index cb1ae78b..00000000 --- a/formats/terrain_mesh.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include "terrain_mesh.h" - -#include "m2_coord.h" - -#include -#include - -namespace fmt { - -namespace { -constexpr int CS = m2coord::CELLSCALE; // 200 cm -constexpr double CS_M = double(CS) * m2coord::CM_TO_M; // 2.0 m -} // namespace - -double terrain_height_at(const HeightMap& hm, double lx_cm, double ly_cm, double hs) { - // 照 CTerrain::GetHeight(本地坐标版,调用方已把全局->本地 + y 取绝对值) - if (lx_cm < 0 || ly_cm < 0 || lx_cm > double(m2coord::TERRAIN_SIZE) * CS || - ly_cm > double(m2coord::TERRAIN_SIZE) * CS) - return 0.0; - - long xi = (long)lx_cm, yi = (long)ly_cm; - long xdist = xi % CS, ydist = yi % CS; - long x = xi / CS, y = yi / CS; - const double oo = 1.0 / double(CS); - - double h1 = hm.at((int)x, (int)y) * hs; // TL - double h2 = hm.at((int)x + 1, (int)y + 1) * hs; // BR - if (xdist <= ydist) { // 左三角:TL, BR, BL - double h3 = hm.at((int)x, (int)y + 1) * hs; - double xslope = (h2 - h3) * oo; - double yslope = (h3 - h1) * oo; - return h1 + (xdist * xslope + ydist * yslope); - } - // 右三角:TL, BR, TR - double h3 = hm.at((int)x + 1, (int)y) * hs; - double xslope = (h3 - h1) * oo; - double yslope = (h2 - h3) * oo; - return h1 + (xdist * xslope + ydist * yslope); -} - -void build_terrain_mesh(const HeightMap& hm, int tile_x, int tile_y, double hs, - TerrainMesh& out, bool ccw_from_above) { - out = TerrainMesh{}; - const int N = TerrainMesh::VERTS_XY; // 129 - out.positions.resize(size_t(N) * N * 3); - out.normals.resize(size_t(N) * N * 3); - out.uvs.resize(size_t(N) * N * 2); - out.indices.reserve(size_t(TerrainMesh::QUADS_XY) * TerrainMesh::QUADS_XY * 6); - - // Godot 空间原点:见 area_data.h 说明 —— 区块 y 取负,position_to_godot 再翻正。 - const double X0 = double(tile_x) * m2coord::CHUNK_CM * m2coord::CM_TO_M; - const double Z0 = double(tile_y) * m2coord::CHUNK_CM * m2coord::CM_TO_M; - - auto height_m = [&](int i, int j) -> double { - return hm.at(i, j) * hs * m2coord::CM_TO_M; - }; - - double miny = 1e30, maxy = -1e30; - for (int j = 0; j < N; ++j) { - for (int i = 0; i < N; ++i) { - const double gy = height_m(i, j); - const size_t o = (size_t(j) * N + i) * 3; - out.positions[o + 0] = float(X0 + i * CS_M); - out.positions[o + 1] = float(gy); - out.positions[o + 2] = float(Z0 + j * CS_M); - const size_t uo = (size_t(j) * N + i) * 2; - out.uvs[uo + 0] = float(i) / float(TerrainMesh::QUADS_XY); - out.uvs[uo + 1] = float(j) / float(TerrainMesh::QUADS_XY); - miny = std::min(miny, gy); - maxy = std::max(maxy, gy); - - // 中心差分(用边界样本,跨区块无缝);y=f(x,z) 的法线 = (-df/dx, 1, -df/dz) - const double dh_di = (height_m(i + 1, j) - height_m(i - 1, j)) / (2.0 * CS_M); - const double dh_dj = (height_m(i, j + 1) - height_m(i, j - 1)) / (2.0 * CS_M); - double nx = -dh_di, ny = 1.0, nz = -dh_dj; - const double len = std::sqrt(nx * nx + ny * ny + nz * nz); - out.normals[o + 0] = float(nx / len); - out.normals[o + 1] = float(ny / len); - out.normals[o + 2] = float(nz / len); - } - } - out.min_y = float(miny); - out.max_y = float(maxy); - - auto vid = [N](int i, int j) { return int32_t(j * N + i); }; - for (int j = 0; j < TerrainMesh::QUADS_XY; ++j) { - for (int i = 0; i < TerrainMesh::QUADS_XY; ++i) { - int32_t TL = vid(i, j), TR = vid(i + 1, j); - int32_t BL = vid(i, j + 1), BR = vid(i + 1, j + 1); - // 对角线 TL-BR(= GetHeight 的 h1/h2) - if (ccw_from_above) { - out.indices.insert(out.indices.end(), {TL, BR, BL}); - out.indices.insert(out.indices.end(), {TL, TR, BR}); - } else { - out.indices.insert(out.indices.end(), {TL, BL, BR}); - out.indices.insert(out.indices.end(), {TL, BR, TR}); - } - } - } -} - -} // namespace fmt diff --git a/formats/terrain_mesh.h b/formats/terrain_mesh.h deleted file mode 100644 index 3a8567d2..00000000 --- a/formats/terrain_mesh.h +++ /dev/null @@ -1,38 +0,0 @@ -// W1 —— 一个区块的地形几何(heightmap -> 顶点 / 法线 / 索引),纯数学、无 godot 依赖。 -// 三角划分与法线照 GameLib/AreaTerrain.cpp CTerrain::GetHeight / CalculateNormal。 -// SHINSOO §9-W1。 -// -// 129×129 可见顶点,128×128 quad。每个 quad 对角线 = TL->BR(GetHeight 的 h1/h2)。 -// 顶点已做 Metin2(cm,Z-up) -> Godot(m,Y-up) 转换(m2_coord),并加了区块原点。 -#pragma once -#include -#include - -#include "terrain_files.h" - -namespace fmt { - -struct TerrainMesh { - static constexpr int VERTS_XY = 129; // XSIZE+1 - static constexpr int QUADS_XY = 128; // XSIZE - - std::vector positions; // 3/vert,Godot 空间(米,Y-up),含区块原点 - std::vector normals; // 3/vert,Godot 空间,单位向量 - std::vector uvs; // 2/vert,区块内 [0,1](用于 splat / 地表贴图) - std::vector indices; // 3/tri,6/quad - float min_y = 0, max_y = 0; // Godot Y(高度)范围,做 custom_aabb / 相机用 - - int vertex_count() const { return VERTS_XY * VERTS_XY; } - int index_count() const { return QUADS_XY * QUADS_XY * 6; } -}; - -// height_scale 从 MapSetting 取(A1 = 0.5)。tile_x/tile_y 决定区块原点。 -// ccw_from_above=true:三角绕序在 Godot 里从上方看为逆时针(默认,若发现背面朝上则传 false)。 -void build_terrain_mesh(const HeightMap& hm, int tile_x, int tile_y, double height_scale, - TerrainMesh& out, bool ccw_from_above = true); - -// 与 CTerrain::GetHeight 一致的三角插值。lx/ly = 区块本地厘米([0, 128*200])。 -// 返回厘米高度(未转 Godot 单位)。 -double terrain_height_at(const HeightMap& hm, double lx_cm, double ly_cm, double height_scale); - -} // namespace fmt diff --git a/formats/tests/attribute_data_test.cpp b/formats/tests/attribute_data_test.cpp deleted file mode 100644 index efe392d3..00000000 --- a/formats/tests/attribute_data_test.cpp +++ /dev/null @@ -1,132 +0,0 @@ -#include "attribute_data.h" - -#include -#include -#include -#include -#include -#include -#include - -namespace { - -int failures = 0; - -#define CHECK(condition, message) \ - do { \ - if (!(condition)) { \ - std::fprintf(stderr, "FAIL: %s (%s:%d)\n", (message), __FILE__, \ - __LINE__); \ - ++failures; \ - } \ - } while (0) - -template -void append(std::vector &bytes, const T &value) { - const auto *p = reinterpret_cast(&value); - bytes.insert(bytes.end(), p, p + sizeof(T)); -} - -void append_name(std::vector &bytes, const char *name) { - char fixed[32] = {}; - std::strncpy(fixed, name, sizeof(fixed)); - bytes.insert(bytes.end(), reinterpret_cast(fixed), - reinterpret_cast(fixed) + sizeof(fixed)); -} - -void append_collision(std::vector &bytes, std::uint32_t type, - const char *name, const float *position, - const float *dimensions, const float *quaternion, - std::size_t dimension_count) { - append(bytes, type); - append_name(bytes, name); - for (std::size_t i = 0; i < 3; ++i) - append(bytes, position[i]); - for (std::size_t i = 0; i < dimension_count; ++i) - append(bytes, dimensions[i]); - for (std::size_t i = 0; i < 4; ++i) - append(bytes, quaternion[i]); -} - -void test_synthetic() { - std::vector bytes; - const char header[] = "AttributeData"; - bytes.insert(bytes.end(), header, header + sizeof(header)); - const std::uint32_t collisions = 3; - const std::uint32_t heights = 1; - append(bytes, collisions); - append(bytes, heights); - - const float p0[] = {10, 20, 30}, d0[] = {40, 50}, q0[] = {0, 0, 0, 1}; - append_collision(bytes, 0, "plane", p0, d0, q0, 2); - const float p1[] = {-1, 2, -3}, d1[] = {7}, q1[] = {1, 2, 3, 4}; - append_collision(bytes, 2, "sphere", p1, d1, q1, 1); - const float p2[] = {4, 5, 6}, d2[] = {8, 9, 10}, q2[] = {0, 0.5f, 0, 0.5f}; - append_collision(bytes, 5, "obb", p2, d2, q2, 3); - - append_name(bytes, "height0"); - const std::uint32_t vertex_count = 3; - append(bytes, vertex_count); - const float vertices[] = {0, 0, 0, 100, 0, 0, 0, 100, 0}; - for (float value : vertices) - append(bytes, value); - - fmt::AttributeData parsed; - std::string error; - CHECK(fmt::parse_attribute_data(bytes.data(), bytes.size(), parsed, &error), - "synthetic .mdatr parses"); - CHECK(parsed.collisions.size() == 3 && parsed.heights.size() == 1, - "synthetic counts"); - CHECK(parsed.collisions[0].name == "plane" && - parsed.collisions[0].dimensions[1] == 50.0f, - "plane fields"); - CHECK(parsed.collisions[1].type == 2 && - parsed.collisions[1].dimensions[0] == 7.0f && - parsed.collisions[1].quaternion[0] == 1.0f, - "sphere fields"); - CHECK(parsed.collisions[2].name == "obb" && - parsed.collisions[2].dimensions[2] == 10.0f, - "obb fields"); - CHECK(parsed.heights[0].name == "height0" && - parsed.heights[0].vertices.size() == 3 && - parsed.heights[0].vertices[1][0] == 100.0f, - "height triangle fields"); - - auto truncated = bytes; - truncated.pop_back(); - CHECK(!fmt::parse_attribute_data(truncated.data(), truncated.size(), parsed, &error), - "truncated .mdatr rejected"); - auto trailing = bytes; - trailing.push_back(0); - CHECK(!fmt::parse_attribute_data(trailing.data(), trailing.size(), parsed, &error), - "trailing .mdatr rejected"); -} - -void test_real_asset() { - const char *root = std::getenv("M2_ASSETS"); - if (!root || !*root) - return; - const std::string path = std::string(root) + - "/metin2_patch_eu3/ymir work/zone/devilcave/devil_entrance1f.mdatr"; - fmt::AttributeData parsed; - std::string error; - CHECK(fmt::parse_attribute_data_file(path, parsed, &error), - "real devil_entrance1f.mdatr parses"); - CHECK(parsed.collisions.size() == 9 && parsed.heights.empty(), - "real .mdatr collision/height count"); - CHECK(parsed.collisions[0].type == 0 && parsed.collisions[0].name == "collision04", - "real .mdatr first collision"); -} - -} // namespace - -int main() { - test_synthetic(); - test_real_asset(); - if (failures == 0) { - std::puts("PASS: formats_attribute_data_test"); - return 0; - } - std::fprintf(stderr, "%d check(s) failed\n", failures); - return 1; -} diff --git a/formats/tests/combo_table_test.cpp b/formats/tests/combo_table_test.cpp deleted file mode 100644 index a2aeecc7..00000000 --- a/formats/tests/combo_table_test.cpp +++ /dev/null @@ -1,142 +0,0 @@ -// M2 §3.5 —— playersettingmodule.py 的 ComboAttackNew 调用 -> PC 连击段表。 -// 照 GameLib/RaceData.cpp CRaceData::ReserveComboAttack / RegisterComboAttack 语义。 -#include - -#include -#include -#include - -using namespace fmt; - -static int g_fail = 0; -#define CHECK(c, msg) \ - do { \ - if (!(c)) { \ - std::fprintf(stderr, "FAIL: %s\n", (msg)); \ - ++g_fail; \ - } \ - } while (0) - -// warrior_m/_w 共用的 __LoadGameWarriorEx 片段 + assassin 的 DUALHAND(男限), -// 外加一个非 Ex 的 def 用来验证块复位。缩进 / tab 混用照原文。 -static const char *kPy = R"PY( -COMBO_TYPE_1 = 0 -COMBO_TYPE_2 = 1 -COMBO_TYPE_3 = 2 -COMBO_INDEX_1 = 0 -COMBO_INDEX_6 = 5 - -def __LoadGameWarriorEx(race, path): - chrmgr.SelectRace(race) - - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_GENERAL, COMBO_TYPE_1, 1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_GENERAL, COMBO_TYPE_1, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - - ## Combo Type 1 - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_1, 4) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_4, chr.MOTION_COMBO_ATTACK_4) - ## Combo Type 2 —— 段号跳到 5 / 7(非连续,验证按下标写而非追加) - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, 5) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_4, chr.MOTION_COMBO_ATTACK_5) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_5, chr.MOTION_COMBO_ATTACK_7) - # 越界的 Register(下标 5 >= size 5):照参考端 AssertLog + return,忽略 - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, 5, chr.MOTION_COMBO_ATTACK_8) - # 对已存在 key 的重复 Reserve:map::insert 不覆盖,原向量保留 - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, 99) - -def __LoadGameAssassinEx(race, path): - chrmgr.SelectRace(race) - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_DUALHAND_SWORD, COMBO_TYPE_3, 6) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_DUALHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_6, chr.MOTION_COMBO_ATTACK_8) - -def __LoadGameNPC(): - # 块外的调用不该落到任何职业里 - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_GENERAL, COMBO_TYPE_1, 3) -)PY"; - -static void check_vec(const std::vector *v, std::initializer_list want, const char *msg) { - if (!v) { std::fprintf(stderr, "FAIL: %s (nullptr)\n", msg); ++g_fail; return; } - if (v->size() != want.size()) { std::fprintf(stderr, "FAIL: %s (size %zu != %zu)\n", msg, v->size(), want.size()); ++g_fail; return; } - size_t i = 0; - for (uint16_t w : want) { - if ((*v)[i] != w) { std::fprintf(stderr, "FAIL: %s ([%zu]=%u != %u)\n", msg, i, (*v)[i], w); ++g_fail; return; } - ++i; - } -} - -int main() { - // ---- key 编码:RaceData.h MAKE_COMBO_KEY ------------------------------- - CHECK(make_combo_key(COMBO_MODE_ONEHAND_SWORD, 1) == ((2u << 16) | 1u), "make_combo_key"); - CHECK(combo_key_mode(make_combo_key(5, 2)) == 5 && combo_key_type(make_combo_key(5, 2)) == 2, "combo_key split"); - - // ---- 解析 ------------------------------------------------------------ - PlayerComboTables tbl; - std::string err; - if (!parse_player_combo_tables(kPy, tbl, &err)) { - std::fprintf(stderr, "parse failed: %s\n", err.c_str()); - return 1; - } - - const ComboTable &w = tbl.klass(COMBO_CLASS_WARRIOR); - const ComboTable &a = tbl.klass(COMBO_CLASS_ASSASSIN); - const ComboTable &s = tbl.klass(COMBO_CLASS_SURA); - - // GENERAL / type1 —— 单段普攻连击(NAME_COMBO_ATTACK_1 = 14) - check_vec(w.get(COMBO_MODE_GENERAL, 0), {14}, "warrior GENERAL type1 = [14]"); - - // ONEHAND_SWORD / type1 —— 连续 4 段 14..17 - check_vec(w.get(COMBO_MODE_ONEHAND_SWORD, 0), {14, 15, 16, 17}, "warrior 1H type1 = [14,15,16,17]"); - - // ONEHAND_SWORD / type2 —— 5 段,末两段跳到 18 / 20(COMBO_ATTACK_5 / _7) - check_vec(w.get(COMBO_MODE_ONEHAND_SWORD, 1), {14, 15, 16, 18, 20}, "warrior 1H type2 = [14,15,16,18,20]"); - - // 越界 Register 被忽略;重复 Reserve 不覆盖(size 仍是 5,不是 99) - CHECK(w.get(COMBO_MODE_ONEHAND_SWORD, 1)->size() == 5, "dup Reserve ignored / OOB Register ignored"); - - // type3 从没 Reserve 过 -> GetComboDataPointer 应为 nullptr - CHECK(w.get(COMBO_MODE_ONEHAND_SWORD, 2) == nullptr, "warrior 1H type3 absent -> nullptr"); - - // 职业隔离:DUALHAND 只在 assassin 块里;warrior/sura 没有 - check_vec(a.get(COMBO_MODE_DUALHAND_SWORD, 2), {0, 0, 0, 0, 0, 21}, "assassin DUAL type3 idx5 = COMBO_ATTACK_8(21)"); - CHECK(w.get(COMBO_MODE_DUALHAND_SWORD, 2) == nullptr, "warrior has no DUALHAND table"); - CHECK(s.empty(), "sura block absent in snippet -> empty table"); - - // 块外(__LoadGameNPC)的 Reserve 不该落进任何职业 - size_t total = 0; - for (int c = 0; c < COMBO_CLASS_COUNT; ++c) total += tbl.klass(c).key_count(); - CHECK(total == 4, "only the 4 in-Ex-block combo keys registered (2 warrior 1H + 1 warrior GENERAL + 1 assassin DUAL)"); - - // 越界职业索引 -> 空表,不崩 - CHECK(tbl.klass(-1).empty() && tbl.klass(99).empty(), "out-of-range class -> empty"); - - // ---- 可选:真实 playersettingmodule.py(设了 M2_ASSETS 才跑)---------- - if (const char *root = std::getenv("M2_ASSETS")) { - const std::string path = std::string(root) + "/root/playersettingmodule.py"; - PlayerComboTables live; - std::string lerr; - if (parse_player_combo_tables_file(path, live, &lerr)) { - check_vec(live.klass(COMBO_CLASS_WARRIOR).get(COMBO_MODE_ONEHAND_SWORD, 0), - {14, 15, 16, 17}, "live warrior 1H type1"); - // sura ONEHAND type3 末段回到 COMBO_ATTACK_4 (17) - const auto *sv = live.klass(COMBO_CLASS_SURA).get(COMBO_MODE_ONEHAND_SWORD, 2); - CHECK(sv && sv->size() == 6 && sv->back() == 17, "live sura 1H type3 tail = COMBO_ATTACK_4"); - // shaman FAN type1 = 4 连续段 - check_vec(live.klass(COMBO_CLASS_SHAMAN).get(COMBO_MODE_FAN, 0), - {14, 15, 16, 17}, "live shaman FAN type1"); - std::printf("live playersettingmodule.py: OK\n"); - } else { - std::fprintf(stderr, "live parse skipped: %s\n", lerr.c_str()); - } - } - - if (g_fail == 0) { - std::printf("PASS: formats_combo_table_test (§3.5 PC 连击段表)\n"); - } - return g_fail == 0 ? 0 : 1; -} diff --git a/formats/tests/map_formats_test.cpp b/formats/tests/map_formats_test.cpp deleted file mode 100644 index 7697b3d5..00000000 --- a/formats/tests/map_formats_test.cpp +++ /dev/null @@ -1,544 +0,0 @@ -// W0 —— A1 地图格式解析单测。SHINSOO §9-W0 / §11.1。 -// -// 无参数:跑内联字符串单测(不需要资源)。 -// 环境变量 M2_ASSETS 指向 Metin2 资产目录(默认 /assets):额外跑真实 A1 的 W0 验收断言。 -#include "area_data.h" -#include "asset_resolver.h" -#include "environment.h" -#include "m2_coord.h" -#include "m2_tokvec.h" -#include "map_setting.h" -#include "property.h" -#include "splat.h" -#include "spt.h" -#include "terrain_files.h" -#include "terrain_mesh.h" -#include "texture_set.h" - -#include -#include -#include -#include - -static int g_fail = 0; -#define CHECK(cond, msg) \ - do { \ - if (!(cond)) { \ - std::fprintf(stderr, "FAIL: %s (%s:%d)\n", (msg), __FILE__, __LINE__); \ - ++g_fail; \ - } \ - } while (0) - -static void test_tokvec() { - const std::string t = R"( -ScriptType MapSetting -MapSize 4 5 -Start Object000 - 1.5 -2.0 3.0 - 569394331 -End Object -# comment -Start Object000 - 9 9 9 -End Object -)"; - fmt::TokVecMap tv; - std::string err; - CHECK(fmt::parse_tokvec(t, tv, &err), "tokvec parse"); - CHECK(tv.str("scripttype") == "MapSetting", "tokvec top-level str"); - const auto* ms = tv.find("MapSize"); // 大小写不敏感 - CHECK(ms && ms->size() == 2 && (*ms)[1] == "5", "tokvec MapSize tokens"); - const auto* o0 = tv.find("object000"); - CHECK(o0 && o0->size() == 4, "tokvec block flattens all lines"); - CHECK(o0 && (*o0)[3] == "569394331", "tokvec block token order"); - CHECK(tv.dup_count == 1, "tokvec dup detected"); -} - -static void test_coord() { - using namespace fmt::m2coord; - Vec3 g = position_to_godot(100.0, 200.0, 300.0); - CHECK(std::fabs(g.x - 1.0) < 1e-9, "coord x"); - CHECK(std::fabs(g.y - 3.0) < 1e-9, "coord y = z*0.01"); - CHECK(std::fabs(g.z + 2.0) < 1e-9, "coord z = -y*0.01"); - CHECK(tile_id(1, 3) == 1003u, "tile_id"); - CHECK(tile_dir(0, 0) == "000000", "tile_dir 0"); - CHECK(tile_dir(1, 3) == "001003", "tile_dir 1,3"); - int tx = -1, ty = -1; - CHECK(parse_tile_dir("003004", tx, ty) && tx == 3 && ty == 4, "parse_tile_dir"); - CHECK(!parse_tile_dir("00300", tx, ty), "parse_tile_dir rejects len!=6"); - CHECK(CHUNK_CM == 25600, "chunk cm"); - - // ypr_basis = 原始 D3DXMatrixRotationYawPitchRoll 端口,在 **Metin2 Z-up 空间**。 - Mat3 y90 = ypr_basis(90.0, 0, 0); // yaw 绕 Metin2 Y(未转轴) - // m 是 row-major,基向量 = 列:new_x = (m[0],m[3],m[6]) - CHECK(std::fabs(y90.m[0]) < 1e-6 && std::fabs(y90.m[6] + 1.0) < 1e-6, - "ypr yaw=90: local +X -> -Z (Metin2 space)"); - Mat3 id = ypr_basis(0, 0, 0); - CHECK(std::fabs(id.m[0] - 1) < 1e-9 && std::fabs(id.m[4] - 1) < 1e-9 && - std::fabs(id.m[8] - 1) < 1e-9, - "ypr zero = identity"); - - // object_basis_godot = ypr_basis 共轭到 Godot Y-up。放置物体必须用这个。 - Mat3 og0 = object_basis_godot(0, 0, 0); - CHECK(std::fabs(og0.m[0] - 1) < 1e-9 && std::fabs(og0.m[4] - 1) < 1e-9 && - std::fabs(og0.m[8] - 1) < 1e-9, - "object_basis_godot zero = identity"); - // areadata 单值旋转 = roll = 朝向。共轭后必须是绕 Godot +Y 的 heading, - // 不是绕 Godot Z 的翻滚(修复前的 bug)。 - Mat3 rl90 = object_basis_godot(0, 0, 90.0); - CHECK(std::fabs(rl90.m[1]) < 1e-6 && std::fabs(rl90.m[4] - 1.0) < 1e-6 && - std::fabs(rl90.m[7]) < 1e-6, - "object_basis_godot roll=90: Godot +Y axis fixed (heading, no roll)"); - CHECK(std::fabs(rl90.m[0]) < 1e-6 && std::fabs(rl90.m[6] + 1.0) < 1e-6, - "object_basis_godot roll=90: local +X -> Godot -Z"); - // 正交且右手(det=+1):取一个混合角 - Mat3 m = object_basis_godot(20.0, -35.0, 110.0); - double det = m.m[0] * (m.m[4] * m.m[8] - m.m[5] * m.m[7]) - - m.m[1] * (m.m[3] * m.m[8] - m.m[5] * m.m[6]) + - m.m[2] * (m.m[3] * m.m[7] - m.m[4] * m.m[6]); - CHECK(std::fabs(det - 1.0) < 1e-6, "object_basis_godot det = +1"); - double col0 = m.m[0] * m.m[0] + m.m[3] * m.m[3] + m.m[6] * m.m[6]; - CHECK(std::fabs(col0 - 1.0) < 1e-6, "object_basis_godot col0 unit"); -} - -static void test_map_setting() { - const std::string t = R"( -ScriptType MapSetting -CellScale 200 -HeightScale 0.500000 -ViewRadius 128 -MapSize 4 5 -BasePosition 409600 896000 -TextureSet textureset\metin2_A1.txt -Environment A1.msenv -)"; - fmt::MapSetting s; - std::string err; - CHECK(fmt::parse_map_setting(t, s, &err), "map_setting parse"); - CHECK(s.cell_scale == 200, "cell_scale"); - CHECK(std::fabs(s.height_scale - 0.5) < 1e-9, "height_scale"); - CHECK(s.map_size_x == 4 && s.map_size_y == 5, "map_size"); - CHECK(s.chunk_count() == 20, "chunk_count"); - CHECK(s.base_position_x == 409600 && s.base_position_y == 896000, "base_position"); - CHECK(s.environment == "A1.msenv", "environment"); -} - -static void test_texture_set() { - const std::string t = R"( -TextureSet -TextureCount 2 -Start Texture001 - "d:\ymir work\terrainmaps\b\field\field 01.dds" - 5.0 5.0 0.0 0.0 0 0 0 -End Texture001 -Start Texture002 - "d:\ymir work\terrainmaps\b\field\field 02.dds" - 6.0 6.0 0.0 0.0 1 10 20 -End Texture002 -)"; - fmt::TextureSet ts; - std::string err; - CHECK(fmt::parse_texture_set(t, ts, &err), "texture_set parse"); - CHECK(ts.declared_count == 2, "declared_count"); - CHECK(ts.layers.size() == 2, "layers"); - CHECK(ts.runtime_count() == 3, "runtime_count = layers + 1 (index0 empty)"); - CHECK(ts.layers[1].splat_enabled && ts.layers[1].height_end == 20, "layer fields"); - CHECK(ts.layers[0].texture.find("field 01.dds") != std::string::npos, "quoted path w/ space"); -} - -static void test_area_data() { - const std::string t = R"( -AreaDataFile - -Start Object000 - 20801.746094 -13522.107422 17875.500000 - 569394331 - 0.000000#0.000000#180.000000 - -40.000000 -End Object -Start Object001 - 17069.0 -11315.7 17926.9 - 865570388 - 0.000000#15.000000#225.000000 -End Object - -ObjectCount 2 -)"; - fmt::AreaData a; - std::string err; - CHECK(fmt::parse_area_data(t, a, &err), "area_data parse"); - CHECK(a.declared_count == 2, "declared"); - CHECK(a.objects.size() == 2, "objects"); - CHECK(a.objects[0].crc == 569394331u, "crc"); - CHECK(std::fabs(a.objects[0].roll - 180.0f) < 1e-3f, "ypr roll"); - CHECK(std::fabs(a.objects[0].height_bias + 40.0f) < 1e-3f, "height_bias"); - CHECK(a.objects[0].x > 0 && a.objects[0].y < 0, "global cm: x>0 (east), y<0 (south)"); - CHECK(std::fabs(a.objects[1].pitch - 15.0f) < 1e-3f && a.objects[1].height_bias == 0.0f, - "ypr without height_bias"); -} - -static void test_environment() { - const std::string t = R"( -ScriptType EnvrionmentData -ScriptVersion 1.0000 -Group DirectionalLight -{ - Direction 0.35 0.56 -0.75 - Group Background - { - Enable 1 - Diffuse 1.0 0.97 0.97 1.0 - Ambient 0.0 0.0 0.0 1.0 - } - Group Character - { - Enable 1 - Ambient 0.15 0.15 0.15 1.0 - } -} -Group Fog -{ - foglevel 6 - IsDensity 1 - Color 0.69 0.74 0.83 1.0 -} -Group Filter -{ - Enable 1 - Color 0.1 0.2 0.3 0.4 - AlphaSrc 5 - AlphaDest 6 -} -Group SkyBox -{ - BTextureRenderMode 1 - Scale 3500.0 3500.0 3500.0 - CloudTextureFileName "d:/ymir work/environment/clouds_zone01.tga" - FrontFaceFileName "d:/ymir work/environment/skybox/front.dds" - List Gradient - { - 0.09 0.28 0.65 0.0 - 0.23 0.40 0.72 0.0 - 0.37 0.49 0.72 0.0 - } -} -)"; - fmt::Environment e; - std::string err; - CHECK(fmt::parse_environment(t, e, &err), ("env parse: " + err).c_str()); - CHECK(e.script_type == "EnvrionmentData", "env script_type (misspelled, accepted)"); - CHECK(std::fabs(e.dir_light.direction[2] + 0.75f) < 1e-3f, "env dir light Direction z"); - CHECK(e.dir_light.bg_enable && e.dir_light.ch_enable, "env bg/ch enable"); - CHECK(std::fabs(e.dir_light.bg_diffuse[1] - 0.97f) < 1e-3f, "env bg diffuse"); - CHECK(e.fog.enable && e.fog.fog_level == 6, "env fog (foglevel form)"); - CHECK(e.fog.density_fog, "env density fog flag"); - CHECK(e.filter.enable && e.filter.alpha_src == 5 && e.filter.alpha_dest == 6, - "env screen filter fields"); - CHECK(std::fabs(e.filter.color[2] - 0.3f) < 1e-3f, "env screen filter color"); - CHECK(e.sky.texture_render_mode && e.sky.face_textures[0].find("front.dds") != std::string::npos, - "env skybox texture mode + front face"); - CHECK(std::fabs(e.sky.scale[0] - 3500.0f) < 1e-1f, "env skybox scale"); - CHECK(e.sky.cloud_texture.find("clouds_zone01.tga") != std::string::npos, "env cloud tex path"); - CHECK(e.sky.gradient.size() == 3, "env List Gradient rows"); - CHECK(std::fabs(e.sky.gradient[2][0] - 0.37f) < 1e-3f, "env List row values"); -} - -static void test_property() { - const std::string prb = "YPRT\n274490822\nbuildingfile\t\"d:/ymir work/zone/x.gr2\"\n" - "propertyname\t\"rock_pillar_02\"\npropertytype\t\"Building\"\n" - "shadowflag\t\"1\"\n"; - fmt::Property p; - std::string err; - CHECK(fmt::parse_property(prb, p, &err), ("property parse: " + err).c_str()); - CHECK(p.crc == 274490822u, "property crc"); - CHECK(p.type == fmt::PropertyType::Building, "property type Building"); - CHECK(p.name == "rock_pillar_02", "property name"); - CHECK(p.get("buildingfile").find("x.gr2") != std::string::npos, "property buildingfile"); - CHECK(p.get("shadowflag") == "1", "property shadowflag"); - - fmt::Property bad; - CHECK(!fmt::parse_property("NOPE\n123\n", bad, &err), "property rejects non-YPRT"); -} - -static void test_terrain_mesh() { - // 合成一张 131x131 heightmap:平坦 + 一个已知斜坡 - fmt::HeightMap hm; - hm.raw.assign(size_t(fmt::HEIGHTMAP_RAW_XY) * fmt::HEIGHTMAP_RAW_XY, 1000); - // 在 (sx,sy)=(10,10) 抬高 - auto set = [&](int sx, int sy, uint16_t v) { - hm.raw[(sy + 1) * fmt::HEIGHTMAP_RAW_XY + (sx + 1)] = v; - }; - set(10, 10, 2000); - - fmt::TerrainMesh tm; - fmt::build_terrain_mesh(hm, 0, 0, 0.5, tm); - CHECK(tm.vertex_count() == 129 * 129, "terrain vert count"); - CHECK((int)tm.positions.size() == 129 * 129 * 3, "terrain positions size"); - CHECK((int)tm.indices.size() == 128 * 128 * 6, "terrain index count"); - // 平坦区顶点高度 = 1000 * 0.5 * 0.01 = 5.0 m - size_t o = (size_t(0) * 129 + 0) * 3; - CHECK(std::fabs(tm.positions[o + 1] - 5.0f) < 1e-4f, "terrain flat height 5m"); - // 平坦区法线朝上 - CHECK(std::fabs(tm.normals[o + 1] - 1.0f) < 1e-4f, "terrain flat normal up"); - // 抬高点:1000 高度差 * 0.5 * 0.01 = 5m 峰 - size_t p = (size_t(10) * 129 + 10) * 3; - CHECK(std::fabs(tm.positions[p + 1] - 10.0f) < 1e-4f, "terrain bump height 10m"); - // 峰邻域法线不再朝正上 - size_t q = (size_t(10) * 129 + 9) * 3; - CHECK(tm.normals[q + 1] < 0.999f, "terrain slope normal tilted"); - // 区块原点:tile(1,2) 的 (0,0) 顶点应在 (128*2, _, 256*2) m - fmt::TerrainMesh tm2; - fmt::build_terrain_mesh(hm, 1, 2, 0.5, tm2); - CHECK(std::fabs(tm2.positions[0] - 256.0f) < 1e-3f, "terrain chunk origin X = tile_x*256"); - CHECK(std::fabs(tm2.positions[2] - 512.0f) < 1e-3f, "terrain chunk origin Z = tile_y*256"); - - // GetHeight 三角插值:格心 - double h = fmt::terrain_height_at(hm, 100.0, 100.0, 0.5); // cell (0,0), xdist=ydist=100 - CHECK(std::fabs(h - 500.0) < 1.0, "terrain_height_at flat = 500cm"); -} - -static void test_splat() { - // 3 层棋盘:texel 值 1 / 2 / 3 - fmt::TileMap tile; - const int S = fmt::SPLAT_RAW_XY; - tile.raw.assign(size_t(S) * S, 1); - for (int y = 0; y < S; ++y) - for (int x = 0; x < S; ++x) { - if (x > S / 2) tile.raw[y * S + x] = 2; - if (x > S / 2 && y > S / 2) tile.raw[y * S + x] = 3; - } - fmt::SplatSet ss; - fmt::build_splat(tile, 4, ss); - CHECK(ss.layers.size() == 3, "splat: 3 used layers"); - CHECK(ss.layers[0].layer == 1 && ss.layers[2].layer == 3, "splat: layers sorted by index"); - // 图层 1 在左半区应满覆盖 - CHECK(ss.layers[0].alpha[10 * S + 10] == 0xFF, "splat L1 covers its region"); - CHECK(ss.layers[0].alpha[10 * S + (S - 10)] == 0x00, "splat L1 zero outside (no bleed there)"); - // 图层 2 在右半区覆盖;边界 1px 会羽化进 L3 区 - CHECK(ss.layers[1].alpha[10 * S + (S - 10)] == 0xFF, "splat L2 covers its region"); - CHECK(ss.layers[2].coverage > 0, "splat L3 has coverage"); - // 未出现的图层不生成 - fmt::TileMap flat; - flat.raw.assign(size_t(S) * S, 1); - fmt::SplatSet ss2; - fmt::build_splat(flat, 8, ss2); - CHECK(ss2.layers.size() == 1, "splat: only used layers emitted"); -} - -static void test_asset_resolver_norm() { - using fmt::AssetResolver; - CHECK(AssetResolver::normalize("d:\\ymir work\\Tree\\A.spt") == "ymir work/tree/a.spt", - "resolver normalize backslash+drive+case"); - CHECK(AssetResolver::normalize("D:/ymir work/env/./x/../y.tga") == "ymir work/env/y.tga", - "resolver normalize . and .."); - CHECK(AssetResolver::normalize("/foo//bar") == "foo/bar", "resolver normalize // and lead /"); - AssetResolver pack; - std::string error; - CHECK(pack.build_or_load("pack://", {}, &error), "40250 virtual pack root needs no directory scan"); - CHECK(pack.resolve("D:\\Ymir Work\\Environment\\A.msenv") == - "pack://d:/ymir work/environment/a.msenv", "pack lookup preserves drive prefix"); -} - -static void test_spt_tokens() { - std::string b; - const uint32_t h = 0; - const uint32_t n = 13; - b.append(reinterpret_cast(&h), sizeof(h)); - b.append(reinterpret_cast(&n), sizeof(n)); - b.append("__IdvSpt_02_", n); - b.push_back('\0'); - b += "\\\\PagodaTreeBark.tga"; - b.push_back('\0'); - b += "CompositeShadowMapB1.tgaQF"; - b.push_back('\0'); - b += "CompositeMapB1#N"; - - fmt::SptInfo si; - CHECK(fmt::sniff_spt(b, si) && si.ok, "spt inline magic"); - CHECK(si.composite_texture == "CompositeMapB1.dds", "spt composite atlas token"); - CHECK(si.self_shadow_texture == "CompositeShadowMapB1.dds", "spt shadow atlas token"); -} - -// ---- live A1 断言(M2_ASSETS 设了才跑)---- -static void test_live(const std::string& assets) { - const std::string map = assets + "/OutdoorA1/metin2_map_a1"; - std::string err; - - fmt::MapSetting s; - CHECK(fmt::parse_map_setting_file(map + "/setting.txt", s, &err), - ("live setting.txt: " + err).c_str()); - CHECK(s.map_size_x == 4 && s.map_size_y == 5, "live MapSize 4x5"); - CHECK(s.chunk_count() == 20, "live 20 chunks"); - - // 20 个区块目录都在 - int found = 0; - for (int tx = 0; tx < s.map_size_x; ++tx) - for (int ty = 0; ty < s.map_size_y; ++ty) { - fmt::HeightMap hm; - std::string e2; - if (fmt::load_height_map(map + "/" + fmt::m2coord::tile_dir(tx, ty) + "/height.raw", - hm, &e2)) - ++found; - else - std::fprintf(stderr, " tile %s: %s\n", - fmt::m2coord::tile_dir(tx, ty).c_str(), e2.c_str()); - } - CHECK(found == 20, "live: all 20 height.raw load as 131x131"); - - fmt::TileMap tm; - CHECK(fmt::load_tile_map(map + "/000000/tile.raw", tm, &err), - ("live tile.raw 258x258: " + err).c_str()); - fmt::AttrMap am; - CHECK(fmt::load_attr_map(map + "/000000/attr.atr", am, &err), - ("live attr.atr magic 2634: " + err).c_str()); - fmt::WaterMap wm; - CHECK(fmt::load_water_map(map + "/000000/water.wtr", wm, &err), - ("live water.wtr magic 5426: " + err).c_str()); - - // TextureSet:解析路径 textureset\metin2_A1.txt(大小写不敏感 -> 实盘小写) - fmt::TextureSet ts; - bool got_ts = fmt::parse_texture_set_file( - assets + "/textureset/textureset/metin2_a1.txt", ts, &err); - CHECK(got_ts, ("live textureset: " + err).c_str()); - if (got_ts) CHECK(ts.layers.size() == 17, "live TextureSet 17 layers"); - - fmt::AreaData ad; - CHECK(fmt::parse_area_data_file(map + "/000000/areadata.txt", ad, &err), - ("live areadata: " + err).c_str()); - CHECK(ad.declared_count == 23, "live areadata ObjectCount 23"); - CHECK(ad.objects.size() == 23, "live areadata parsed 23"); - if (!ad.objects.empty()) - CHECK(ad.objects[0].crc == 569394331u, "live areadata Object000 CRC 569394331"); - // 坐标系:000000 在原点附近,x,y 幅度 < 一个区块(全局 == 本地在此区块巧合) - bool o000_ok = true; - for (auto& o : ad.objects) - if (o.x < 0 || o.x >= fmt::m2coord::CHUNK_CM || o.y > 0 || o.y <= -fmt::m2coord::CHUNK_CM) - o000_ok = false; - CHECK(o000_ok, "live 000000 areadata within chunk 0 (global cm, x>=0 y<=0)"); - // 别的区块要落在该区块的全局范围 —— 001003 的 x 应 > 25600 - fmt::AreaData ad13; - if (fmt::parse_area_data_file(map + "/001003/areadata.txt", ad13, &err) && !ad13.objects.empty()) { - bool shifted = false; - for (auto& o : ad13.objects) - if (o.x >= fmt::m2coord::CHUNK_CM) shifted = true; - CHECK(shifted, "live: 001003 objects are GLOBAL cm (x > 25600), not chunk-local"); - } - - // PARITY §3.7 —— 相邻区块共享边高度 / 顶点位置一致(无接缝) - { - fmt::HeightMap h00, h10; - std::string e3; - bool ok00 = fmt::load_height_map(map + "/000000/height.raw", h00, &e3); - bool ok10 = fmt::load_height_map(map + "/001000/height.raw", h10, &e3); - CHECK(ok00 && ok10, "seam: load 000000 + 001000 height.raw"); - if (ok00 && ok10) { - int bad = 0; - for (int j = 0; j < fmt::TerrainMesh::VERTS_XY; ++j) - if (h00.at(128, j) != h10.at(0, j)) // 000000 右缘 vs 001000 左缘 - ++bad; - CHECK(bad == 0, "seam: 000000 col-128 heights == 001000 col-0 (border samples)"); - - fmt::TerrainMesh m00, m10; - fmt::build_terrain_mesh(h00, 0, 0, s.height_scale, m00); - fmt::build_terrain_mesh(h10, 1, 0, s.height_scale, m10); - const int N = fmt::TerrainMesh::VERTS_XY; - int pbad = 0; - for (int j = 0; j < N; ++j) { - size_t a = (size_t(j) * N + (N - 1)) * 3; // m00 右缘 - size_t b = (size_t(j) * N + 0) * 3; // m10 左缘 - for (int k = 0; k < 3; ++k) - if (std::fabs(m00.positions[a + k] - m10.positions[b + k]) > 1e-3f) - ++pbad; - } - CHECK(pbad == 0, "seam: 000000/001000 shared-edge vertex positions match"); - } - } - - // .spt 嗅探(几何不可读,仅确认 magic + 抽贴图名 —— W4 结论 c 的程序化确认) - { - fmt::SptInfo si; - bool got = fmt::sniff_spt_file( - assets + "/Tree/ymir work/tree/b1_pagodatree_rt.spt", si); - CHECK(got && si.ok, "live .spt magic __IdvSpt"); - CHECK(si.magic.rfind("__IdvSpt", 0) == 0, "live .spt magic string"); - CHECK(!si.texture_refs.empty(), "live .spt has embedded texture refs"); - CHECK(si.composite_texture == "CompositeMapB1.dds", "live .spt composite atlas"); - CHECK(si.self_shadow_texture == "CompositeShadowMapB1.dds", "live .spt shadow atlas"); - } - - // Environment:A1.msenv 由虚拟路径解析 - fmt::Environment env; - CHECK(fmt::parse_environment_file(assets + "/ETC/ymir work/environment/a1.msenv", env, &err), - ("live a1.msenv: " + err).c_str()); - CHECK(env.script_type == "EnvrionmentData", "live msenv script_type"); - CHECK(env.fog.enable && env.sky.gradient.size() >= 8, "live msenv fog + gradient list"); - - fmt::Environment trent; - CHECK(fmt::parse_environment_file( - assets + "/season2/season2/metin2_map_trent02_a/trent02.msenv", trent, &err), - ("live trent02.msenv: " + err).c_str()); - CHECK(trent.dir_light.ch_enable && trent.dir_light.ch_ambient[0] > 0.39f, - "live trent character light"); - CHECK(!trent.filter.enable && trent.filter.alpha_src == 2 && trent.filter.alpha_dest == 2, - "live trent filter fields"); - CHECK(trent.sky.cloud_color.size() == 2 && trent.lens_flare.enable, - "live trent cloud gradient + lens flare"); - - // Property CRC 注册表 - fmt::PropertyRegistry reg; - CHECK(reg.scan(assets + "/Property", &err), ("live Property scan: " + err).c_str()); - CHECK(reg.by_crc.size() > 1000, "live Property registry > 1000 entries"); - const fmt::Property* p0 = reg.find(569394331u); - CHECK(p0 != nullptr, "live Property CRC 569394331 resolves"); - if (p0) CHECK(p0->type == fmt::PropertyType::Tree, "live CRC 569394331 = Tree (Pagoda1)"); - // areadata 的每个 CRC 都能在注册表命中 - int miss = 0; - for (auto& o : ad.objects) - if (!reg.find(o.crc)) ++miss; - CHECK(miss == 0, "live: every 000000 areadata CRC found in Property registry"); - - // AssetResolver - fmt::AssetResolver res; - CHECK(res.build(assets, fmt::AssetResolver::default_priority(), &err), - ("live AssetResolver build: " + err).c_str()); - CHECK(res.files_indexed > 10000, "live resolver indexed > 10000 files"); - std::string r; - CHECK(!res.resolve("d:/ymir work/environment/clouds_zone01.tga", &r).empty(), - ("live resolve cloud tga: " + r).c_str()); - CHECK(!res.resolve("d:\\ymir work\\tree\\b1_pagodatree_rt.spt", &r).empty(), - ("live resolve pagoda spt: " + r).c_str()); - CHECK(res.resolve("d:/ymir work/does/not/exist.xxx", &r).empty(), - "live resolve missing -> empty"); - // TextureSet 里的图层贴图路径应可解析 - int tex_miss = 0; - for (auto& L : ts.layers) - if (res.resolve(L.texture, nullptr).empty()) ++tex_miss; - CHECK(tex_miss == 0, "live: all TextureSet layer textures resolve"); -} - -int main() { - test_tokvec(); - test_coord(); - test_map_setting(); - test_texture_set(); - test_area_data(); - test_environment(); - test_property(); - test_terrain_mesh(); - test_asset_resolver_norm(); - test_spt_tokens(); - - if (const char* a = std::getenv("M2_ASSETS"); a && *a) { - std::fprintf(stderr, "-- live A1 asserts (M2_ASSETS=%s) --\n", a); - test_live(a); - } else { - std::fprintf(stderr, "-- M2_ASSETS unset: skipping live A1 asserts --\n"); - } - - if (g_fail) { - std::fprintf(stderr, "%d check(s) failed\n", g_fail); - return 1; - } - std::fprintf(stderr, "all checks passed\n"); - return 0; -} diff --git a/formats/tests/msa_test.cpp b/formats/tests/msa_test.cpp deleted file mode 100644 index 7c45ae95..00000000 --- a/formats/tests/msa_test.cpp +++ /dev/null @@ -1,347 +0,0 @@ -#include - -#include -#include -#include - -int main() { - { - fmt::Msa effects; - std::string error; - if (!fmt::parse_msa(R"(MotionFileName "test.gr2" -Group MotionEventData -{ - Group Event00 - { - MotionEventType 1 - StartingTime 0.25 - EffectFileName "d:/ymir work/pc/test.mse" - AttachingBoneName "equip_right_hand" - AttachingEnable 1 - FollowingEnable 1 - IndependentFlag 1 - EffectPosition 10 20 30 - } -} -)", effects, &error) || effects.events.size() != 1 || - !effects.events[0].attaching || !effects.events[0].following || - !effects.events[0].independent || effects.events[0].attaching_bone != "equip_right_hand" || - effects.events[0].position[2] != 30) { - std::fprintf(stderr, "effect attachment metadata lost\n"); - return 1; - } - } - { - // 40250 RaceMotionDataEvent has dedicated payloads for FLY, - // SCREEN_WAVING and SPECIAL_ATTACKING. Keep the no-payload event - // types in the same snapshot so they cannot be silently dropped. - const std::string events = R"(MotionFileName "events.gr2" -Group MotionEventData -{ - Group Event00 - { - MotionEventType 2 - StartingTime 0.10 - DuringTime 0.20 - Power 300 - AffectingRange 200 - } - Group Event01 - { - MotionEventType 4 - StartingTime 0.30 - DuringTime 0.40 - EnableHitProcess 0 - AttackType 1 - HittingType 2 - StiffenTime 0.05 - InvisibleTime 0.10 - ExternalForce 20 - HitLimitCount 3 - CollisionType 4 - SphereDataCount 2 - Group SphereData00 - { - Radius 100 - Position 1 2 3 - } - Group SphereData01 - { - Radius 200 - Position 4 5 6 - } - } - Group Event02 - { - MotionEventType 6 - StartingTime 0.50 - AttachingEnable 1 - AttachingBoneName "Bip01 R Hand" - FlyFileName "d:/ymir work/pc/warrior/effect/geompung.msf" - FlyPosition 7 8 9 - } - Group Event03 - { - MotionEventType 7 - StartingTime 0.60 - } - Group Event04 - { - MotionEventType 8 - StartingTime 0.70 - } - Group Event05 - { - MotionEventType 9 - StartingTime 0.80 - } -} -)"; - fmt::Msa parsed; - std::string error; - if (!fmt::parse_msa(events, parsed, &error) || parsed.events.size() != 6) { - std::fprintf(stderr, "motion event payload parse failed: %s\n", error.c_str()); - return 1; - } - const fmt::MotionEvent *wave = &parsed.events[0]; - const fmt::MotionEvent *attack = &parsed.events[1]; - const fmt::MotionEvent *fly = &parsed.events[2]; - if (wave->type != 2 || std::fabs(wave->duration_time - 0.2f) > 1e-6f || - wave->power != 300 || wave->affecting_range != 200 || - attack->type != 4 || attack->enable_hit_process || attack->attack_type != 1 || - attack->hitting_type != 2 || attack->collision_type != 4 || - attack->collision_spheres.size() != 2 || - std::fabs(attack->collision_spheres[1].radius - 200.0f) > 1e-6f || - attack->collision_spheres[1].position[2] != 6.0f || - fly->type != 6 || fly->fly_file.find("geompung.msf") == std::string::npos || - !fly->fly_attaching || fly->fly_attaching_bone != "Bip01 R Hand" || - fly->fly_position[0] != 7.0f || parsed.events[3].type != 7 || - parsed.events[4].type != 8 || parsed.events[5].type != 9) { - std::fprintf(stderr, "40250 motion event payload fields were lost\n"); - return 1; - } - } - const std::string text = R"( -ScriptType MotionData -MotionFileName "d:/ymir work/pc/test.gr2" -MotionDuration 2.0 -Group LoopData -{ - MotionLoopCount 2 - LoopCancelEnable 1 - LoopStartTime 0.25 - LoopEndTime 1.75 -} -)"; - fmt::Msa msa; - std::string err; - if (!fmt::parse_msa(text, msa, &err)) { - std::fprintf(stderr, "parse failed: %s\n", err.c_str()); - return 1; - } - const bool ok = msa.has_loop_data && msa.motion_loop_count == 2 && - msa.loop_cancel_enable && std::fabs(msa.loop_start_time - 0.25f) < 1e-6f && - std::fabs(msa.loop_end_time - 1.75f) < 1e-6f; - if (!ok) { - std::fprintf(stderr, "LoopData fields were not preserved\n"); - return 1; - } - - // A motion with no ComboInputData / AttackingData leaves the flags clear. - if (msa.has_combo_input || msa.has_attacking_data) { - std::fprintf(stderr, "combat groups reported present when absent\n"); - return 1; - } - - // CLIENT-GAP §3.3 / §3.5 —— real onehand_sword/combo_01.msa field values. - const std::string combo = R"( -ScriptType MotionData -MotionFileName "d:/ymir work/pc/warrior/onehand_sword/combo_01.gr2" -MotionDuration 1.000000 -Accumulation 0.00 -131.76 0.00 -Group ComboInputData -{ - PreInputTime 0.167094 - DirectInputTime 0.533333 - InputLimitTime 0.602564 - LinkTime 0.058889 -} -Group AttackingData -{ - AttackingType 2 - HittingType 2 - StiffenTime 0.0 - InvisibleTime 0.100000 - ExternalForce 8.000000 - AttackingStartTime 0.192308 - AttackingEndTime 0.315385 -} -)"; - fmt::Msa cm; - if (!fmt::parse_msa(combo, cm, &err)) { - std::fprintf(stderr, "combo parse failed: %s\n", err.c_str()); - return 1; - } - const bool combo_ok = cm.has_combo_input && - std::fabs(cm.combo_pre_input_time - 0.167094f) < 1e-5f && - std::fabs(cm.combo_direct_input_time - 0.533333f) < 1e-5f && - std::fabs(cm.combo_input_limit_time - 0.602564f) < 1e-5f && - std::fabs(cm.combo_link_time - 0.058889f) < 1e-5f; - const bool atk_ok = cm.has_attacking_data && cm.attacking_type == 2 && cm.hitting_type == 2 && - std::fabs(cm.attack_start_time - 0.192308f) < 1e-5f && - std::fabs(cm.attack_end_time - 0.315385f) < 1e-5f && - std::fabs(cm.invisible_time - 0.1f) < 1e-5f && - std::fabs(cm.external_force - 8.0f) < 1e-5f; - if (!combo_ok || !atk_ok) { - std::fprintf(stderr, "ComboInputData / AttackingData fields were not preserved\n"); - return 1; - } - - // §3.5 修改 1 —— 老式内联写法(无 HitDataCount):单个命中窗,含 List HitPosition 采样。 - const std::string inl = R"( -ScriptType MotionData -MotionFileName "d:/ymir work/pc/warrior/general/attack.gr2" -MotionDuration 1.0 -Group AttackingData -{ - AttackingType 1 - HittingType 2 - StiffenTime 0.0 - InvisibleTime 0.5 - ExternalForce 0.0 - AttackingStartTime 0.456410 - AttackingEndTime 0.597436 - AttackingBone "equip_right_hand" - WeaponLength 0.0 - List HitPosition - { - 0.456410 1.0 2.0 3.0 4.0 5.0 6.0 - 0.464744 7.0 8.0 9.0 10.0 11.0 12.0 - } -} -)"; - fmt::Msa im; - if (!fmt::parse_msa(inl, im, &err)) { - std::fprintf(stderr, "inline attacking parse failed: %s\n", err.c_str()); - return 1; - } - if (im.hit_windows.size() != 1 || im.hit_windows[0].samples.size() != 2 || - im.hit_windows[0].bone_name != "equip_right_hand" || - std::fabs(im.hit_windows[0].start_time - 0.456410f) > 1e-5f || - std::fabs(im.hit_windows[0].end_time - 0.597436f) > 1e-5f || - std::fabs(im.attack_start_time - 0.456410f) > 1e-5f || - std::fabs(im.hit_windows[0].samples[1].time - 0.464744f) > 1e-5f || - std::fabs(im.hit_windows[0].samples[1].last_pos[0] - 7.0f) > 1e-5f || - std::fabs(im.hit_windows[0].samples[1].pos[2] - 12.0f) > 1e-5f) { - std::fprintf(stderr, "inline HitData window / HitPosition samples not preserved\n"); - return 1; - } - - // §3.5 修改 1 —— 新式写法:AttackType + MotionType + HitDataCount N + Group HitData0N。 - const std::string multi = R"( -ScriptType MotionData -MotionFileName "d:/ymir work/pc/warrior/twohand_sword/combo_05.gr2" -MotionDuration 1.6 -Group AttackingData -{ - AttackType 0 - HittingType 2 - StiffenTime 0.0 - InvisibleTime 0.2 - ExternalForce 5.0 - HitLimitCount 3 - MotionType 2 - HitDataCount 2 - Group HitData00 - { - AttackingStartTime 0.455475 - AttackingEndTime 0.759124 - AttackingBone "equip_right_hand" - WeaponLength 150.0 - List HitPosition - { - 0.455475 54.5 -30.5 71.1 89.9 105.7 19.4 - } - } - Group HitData01 - { - AttackingStartTime 0.9 - AttackingEndTime 1.1 - AttackingBone "equip_left_hand" - WeaponLength 120.0 - } -} -)"; - fmt::Msa mm; - if (!fmt::parse_msa(multi, mm, &err)) { - std::fprintf(stderr, "multi HitData parse failed: %s\n", err.c_str()); - return 1; - } - if (mm.attacking_type != 0 || mm.motion_type != 2 || mm.hit_limit_count != 3 || - mm.hit_windows.size() != 2 || - std::fabs(mm.hit_windows[0].start_time - 0.455475f) > 1e-5f || - mm.hit_windows[0].samples.size() != 1 || - mm.hit_windows[1].bone_name != "equip_left_hand" || - std::fabs(mm.hit_windows[1].end_time - 1.1f) > 1e-5f || - mm.hit_windows[1].samples.size() != 0 || - std::fabs(mm.attack_start_time - 0.455475f) > 1e-5f) { - std::fprintf(stderr, "multi HitData windows not preserved\n"); - return 1; - } - - // ---- 可选:真实 PC .msa(设了 M2_ASSETS 才跑)---------------------------- - if (const char* root = std::getenv("M2_ASSETS")) { - const std::string base = std::string(root) + "/PC/ymir work/pc/warrior/"; - fmt::Msa a1; - if (fmt::parse_msa_file(base + "general/attack.msa", a1, &err)) { - if (a1.hit_windows.size() != 1 || a1.hit_windows[0].bone_name != "equip_right_hand" || - std::fabs(a1.hit_windows[0].start_time - 0.456410f) > 1e-4f || - std::fabs(a1.hit_windows[0].end_time - 0.597436f) > 1e-4f || - a1.hit_windows[0].samples.size() != 17) { - std::fprintf(stderr, "live general/attack.msa window/samples wrong " - "(windows=%zu samples=%zu)\n", a1.hit_windows.size(), - a1.hit_windows.empty() ? 0 : a1.hit_windows[0].samples.size()); - return 1; - } - } - fmt::Msa c5; - if (fmt::parse_msa_file(base + "twohand_sword/combo_05.msa", c5, &err)) { - if (c5.hit_windows.size() != 1 || c5.motion_type != 2 || - std::fabs(c5.hit_windows[0].weapon_length - 150.0f) > 1e-3f || - std::fabs(c5.hit_windows[0].start_time - 0.455475f) > 1e-4f || - c5.hit_windows[0].samples.size() != 37) { - std::fprintf(stderr, "live twohand_sword/combo_05.msa wrong " - "(windows=%zu samples=%zu)\n", c5.hit_windows.size(), - c5.hit_windows.empty() ? 0 : c5.hit_windows[0].samples.size()); - return 1; - } - } - // 真正的双持双命中窗(右手窗 + 左手窗)。 - const std::string adh = std::string(root) + "/PC/ymir work/pc/assassin/dualhand_sword/combo_01.msa"; - fmt::Msa dh; - if (fmt::parse_msa_file(adh, dh, &err)) { - if (dh.hit_windows.size() != 2 || - dh.hit_windows[0].bone_name != "Bip01 R Hand" || - dh.hit_windows[1].bone_name != "Bip01 L Hand" || - dh.hit_windows[0].samples.size() != 13 || - dh.hit_windows[1].samples.size() != 13 || - std::fabs(dh.hit_windows[1].start_time - 0.605128f) > 1e-4f) { - std::fprintf(stderr, "live assassin dualhand combo_01.msa two-window wrong " - "(windows=%zu)\n", dh.hit_windows.size()); - return 1; - } - } - fmt::Msa pb; - if (fmt::parse_msa_file(base + "skill/palbang.msa", pb, &err)) { - // AttackingData 后还有 Group MotionEventData —— List 修复后二者都要解析到。 - if (pb.hit_windows.size() != 1 || pb.hit_limit_count != 18 || - std::fabs(pb.hit_windows[0].weapon_length - 130.0f) > 1e-3f || - pb.events.size() != 3) { - std::fprintf(stderr, "live skill/palbang.msa wrong " - "(windows=%zu events=%zu)\n", pb.hit_windows.size(), pb.events.size()); - return 1; - } - } - } - return 0; -} diff --git a/formats/tests/msm_test.cpp b/formats/tests/msm_test.cpp deleted file mode 100644 index 2a703d8d..00000000 --- a/formats/tests/msm_test.cpp +++ /dev/null @@ -1,84 +0,0 @@ -// .msm HairData: SourceSkin -> TargetSkin recolour catalogue (PARITY §2.4). -#include - -#include -#include - -int main() { - // Shape of assets/root/msm/warrior_m.msm HairData. - const std::string text = R"( -ScriptType RaceDataScript - -BaseModelFileName "d:/ymir work/pc2/warrior/warrior_novice.GR2" -MotionListFileName "motlist_range.txt" - -Group HairData -{ - PathName "d:/ymir Work/pc2/warrior/" - - HairDataCount 3 - Group HairData00 - { - HairIndex 0 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "warrior_hair_01.dds" - } - Group HairData01 - { - HairIndex 3 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "warrior_hair_01_red.dds" - } - Group HairData02 - { - HairIndex 1001 - Model "hair/hair_2_1.gr2" - SourceSkin "hair/hair_2_1.dds" - TargetSkin "warrior_hair_02_gold.dds" - } -} -)"; - fmt::Msm m; - std::string err; - if (!fmt::parse_msm(text, m, &err)) { - std::fprintf(stderr, "parse failed: %s\n", err.c_str()); - return 1; - } - int fails = 0; - auto check = [&](bool c, const char *msg) { - if (!c) { - std::fprintf(stderr, "FAIL: %s\n", msg); - ++fails; - } - }; - - check(m.base_model_gr2 == "d:/ymir work/pc2/warrior/warrior_novice.GR2" || - m.base_model_gr2 == "d:/ymir work/pc2/warrior/warrior_novice.gr2", - "base model gr2"); - check(m.motion_list_file == "motlist_range.txt", "motion list file"); - check(m.hair_path == "d:/ymir Work/pc2/warrior/" || m.hair_path == "d:/ymir work/pc2/warrior/", - "hair PathName"); - check(m.hairs.size() == 3, "3 hair entries"); - if (m.hairs.size() == 3) { - check(m.hairs[0].index == 0, "entry0 HairIndex"); - check(m.hairs[0].model == "hair/hair_1_1.gr2", "entry0 Model"); - check(m.hairs[0].source_skin == "hair/hair_1_1.dds", "entry0 SourceSkin"); - check(m.hairs[0].target_skin == "warrior_hair_01.dds", "entry0 TargetSkin"); - // same gr2 + SourceSkin, different TargetSkin -> the recolour case - check(m.hairs[1].model == m.hairs[0].model, "entry1 shares gr2"); - check(m.hairs[1].source_skin == m.hairs[0].source_skin, "entry1 shares SourceSkin"); - check(m.hairs[1].target_skin == "warrior_hair_01_red.dds", "entry1 TargetSkin differs"); - check(m.hairs[1].index == 3, "entry1 HairIndex"); - check(m.hairs[2].model == "hair/hair_2_1.gr2", "entry2 Model"); - check(m.hairs[2].target_skin == "warrior_hair_02_gold.dds", "entry2 TargetSkin"); - } - - if (fails) { - std::fprintf(stderr, "%d check(s) failed\n", fails); - return 1; - } - std::printf("all checks passed\n"); - return 0; -} diff --git a/formats/textscript.cpp b/formats/textscript.cpp deleted file mode 100644 index 55319ad0..00000000 --- a/formats/textscript.cpp +++ /dev/null @@ -1,129 +0,0 @@ -// M2 T1 —— Metin2 文本脚本 token 树解析。 -#include "textscript.h" -#include "m2_tokvec.h" // fmt::read_file (host-injectable; res:// on mobile) -#include -#include -#include -#include - -namespace fmt { -namespace { - -bool ieq(const std::string& a, const char* b) { - if (a.size() != std::strlen(b)) return false; - for (size_t i = 0; i < a.size(); ++i) - if (std::tolower((unsigned char)a[i]) != std::tolower((unsigned char)b[i])) return false; - return true; -} - -// tokenize 一行为止:支持 "quoted"(含空白)、# 注释 -std::vector tokenize_all(const std::string& text) { - std::vector toks; - size_t i = 0, n = text.size(); - while (i < n) { - char c = text[i]; - if (c == '#' || (c == '/' && i + 1 < n && text[i + 1] == '/')) { // 行注释 - while (i < n && text[i] != '\n') ++i; - continue; - } - if (std::isspace((unsigned char)c)) { ++i; continue; } - if (c == '{' || c == '}') { toks.emplace_back(1, c); ++i; continue; } - if (c == '"') { - ++i; std::string s; - while (i < n && text[i] != '"') s += text[i++]; - if (i < n) ++i; // 跳过右引号 - toks.push_back(s); - continue; - } - std::string s; - while (i < n && !std::isspace((unsigned char)text[i]) && text[i] != '{' && text[i] != '}') - s += text[i++]; - toks.push_back(s); - } - return toks; -} - -// 递归解析一个 Group 体(已消费到 '{' 之后;到匹配的 '}' 或流尾停) -bool parse_body(const std::vector& t, size_t& i, Node& node, std::string* err) { - while (i < t.size()) { - const std::string& tok = t[i]; - if (tok == "}") { ++i; return true; } - // `Group Name { ... }` 和 `List Name { ... }`(CTextFileLoader 的 GetTokenVector) - // 都当子节点:Group 体是 key/子组,List 体是一串裸值(收进子节点的单行)。 - if (ieq(tok, "Group") || ieq(tok, "List")) { - const char* kind = ieq(tok, "Group") ? "Group" : "List"; - if (i + 2 >= t.size()) { if (err) *err = std::string(kind) + " 缺名字 / {"; return false; } - Node sub; - sub.name = t[i + 1]; - if (t[i + 2] != "{") { if (err) *err = std::string(kind) + " '" + sub.name + "' 后缺 {"; return false; } - i += 3; - if (!parse_body(t, i, sub, err)) return false; - node.groups.push_back(std::move(sub)); - continue; - } - // 普通行:从 tok 起,直到下一个会开启新语义的 token(Group / } / 或另一行的 key) - // .msa/.msm 是「一行一 key」,我们靠换行还原不了(已丢),改用: - // key + 其后所有非 Group/非} token 直到遇到一个「像 key 的」…太脆。 - // 实际这些文件每行 = key + 定长值,值都是数字 / 带引号串 / 简单标识。 - // 简化:把连续的 token 收进当前行,遇到 Group/} 或「首字母大写且后面还跟 Group 结构」时断。 - // 经验规则:值不会是 "Group";key 之后收 1..N 个值,遇到下一个满足「不是纯数字、不是带过引号」 - // 的裸标识就当新行开始。对 dance_1.msa / warrior_w.msm 足够。 - std::vector line; - line.push_back(t[i++]); - while (i < t.size()) { - const std::string& x = t[i]; - if (x == "}" || ieq(x, "Group")) break; - // 判断 x 是否是「新行的 key」:不含数字开头、不含 '.'、'/'、'\\'、'"' 迹象, - // 且当前行已至少有 1 个值 - bool looks_key = line.size() >= 2 && - (std::isalpha((unsigned char)x[0]) || x[0] == '_') && - x.find_first_of("/\\.:") == std::string::npos; - // 数字 / 负号 / 小数一律当值 - bool is_num = !x.empty() && (x[0] == '-' || x[0] == '+' || x[0] == '.' || - std::isdigit((unsigned char)x[0])); - if (looks_key && !is_num) break; - line.push_back(x); - ++i; - } - node.lines.push_back(std::move(line)); - } - return true; // 流尾(根节点) -} - -} // namespace - -const std::vector* Node::find(const char* key) const { - for (const auto& l : lines) if (!l.empty() && ieq(l[0], key)) return &l; - return nullptr; -} -std::string Node::str(const char* key, const std::string& def) const { - auto* l = find(key); - return (l && l->size() >= 2) ? (*l)[1] : def; -} -float Node::num(const char* key, float def) const { - auto* l = find(key); - return (l && l->size() >= 2) ? float(std::atof((*l)[1].c_str())) : def; -} -int Node::inum(const char* key, int def) const { - auto* l = find(key); - return (l && l->size() >= 2) ? std::atoi((*l)[1].c_str()) : def; -} -const Node* Node::group(const char* name) const { - for (const auto& g : groups) if (ieq(g.name, name)) return &g; - return nullptr; -} - -bool parse_textscript(const std::string& text, Node& root, std::string* err) { - root = Node{}; - auto toks = tokenize_all(text); - size_t i = 0; - return parse_body(toks, i, root, err); -} - -bool parse_textscript_file(const std::string& path, Node& root, std::string* err) { - std::string s; - if (!read_file(path, s)) { if (err) *err = "cannot open " + path; return false; } - return parse_textscript(s, root, err); -} - -} // namespace fmt diff --git a/formats/textscript.h b/formats/textscript.h deleted file mode 100644 index 0248ea63..00000000 --- a/formats/textscript.h +++ /dev/null @@ -1,27 +0,0 @@ -// Metin2 文本脚本(.msa / .msm / 各种 .txt)—— token 树解析。 -// 语法:空白分隔 token;`key value...` 行;`Group Name { ... }` 块;`"quoted"` 串;`#` 到行尾注释。 -// 照 EterBase/CTextFileLoader + EterLib CTokenVector 的效果。M2 T1。 -#pragma once -#include -#include - -namespace fmt { - -struct Node { - std::string name; // Group 名(根节点为空) - std::vector> lines; // 非 Group 行:token 列表([0]=key) - std::vector groups; // 子 Group - - // 便捷取值(在本节点的 lines 里找 key,大小写不敏感) - const std::vector* find(const char* key) const; - std::string str(const char* key, const std::string& def = "") const; // 取第 1 个值(去引号) - float num(const char* key, float def = 0) const; - int inum(const char* key, int def = 0) const; - const Node* group(const char* name) const; -}; - -// 解析整段文本。失败返回 false 并写 err。 -bool parse_textscript(const std::string& text, Node& root, std::string* err); -bool parse_textscript_file(const std::string& path, Node& root, std::string* err); - -} // namespace fmt diff --git a/formats/texture_set.cpp b/formats/texture_set.cpp deleted file mode 100644 index 1b550ca7..00000000 --- a/formats/texture_set.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include "texture_set.h" - -#include "m2_tokvec.h" - -#include -#include - -namespace fmt { - -bool parse_texture_set(const std::string& text, TextureSet& out, std::string* err) { - TokVecMap tv; - std::string perr; - parse_tokvec(text, tv, &perr); - - out = TextureSet{}; - - if (!tv.has("textureset")) { - if (err) *err = "textureset 缺首行 `TextureSet`"; - return false; - } - if (!tv.has("texturecount")) { - if (err) *err = "textureset 缺 TextureCount"; - return false; - } - out.declared_count = (int)tv.inum("texturecount"); - if (out.declared_count < 0) { - if (err) *err = "textureset TextureCount 非法"; - return false; - } - - for (int i = 1; i <= out.declared_count; ++i) { - char key[32]; - std::snprintf(key, sizeof(key), "texture%03d", i); - const auto* v = tv.find(key); - if (!v) { - if (err) *err = std::string("textureset 缺块 ") + key; - return false; - } - if (v->size() < 8) { - if (err) *err = std::string("textureset 块 ") + key + " token 不足 8 个"; - return false; - } - TextureLayer L; - L.texture = (*v)[0]; - L.u_scale = (float)std::atof((*v)[1].c_str()); - L.v_scale = (float)std::atof((*v)[2].c_str()); - L.u_offset = (float)std::atof((*v)[3].c_str()); - L.v_offset = (float)std::atof((*v)[4].c_str()); - L.splat_enabled = std::atoi((*v)[5].c_str()) != 0; - L.height_begin = (unsigned short)std::atoi((*v)[6].c_str()); - L.height_end = (unsigned short)std::atoi((*v)[7].c_str()); - out.layers.push_back(std::move(L)); - } - return true; -} - -bool parse_texture_set_file(const std::string& path, TextureSet& out, std::string* err) { - std::string text; - if (!read_file(path, text)) { - if (err) *err = "打不开 " + path; - return false; - } - return parse_texture_set(text, out, err); -} - -} // namespace fmt diff --git a/formats/texture_set.h b/formats/texture_set.h deleted file mode 100644 index f051c21c..00000000 --- a/formats/texture_set.h +++ /dev/null @@ -1,31 +0,0 @@ -// TextureSet .txt(首行 `TextureSet`)—— 地表图层表。 -// 对标 PRTerrainLib/TextureSet.cpp CTextureSet::Load。SHINSOO §5.4。 -// -// 关键:运行时 index 0 是原客户端内部的空图层(AddEmptyTexture),文件里的 -// `Texture001` 对应运行时索引 1。`layers` 按文件顺序(即运行时索引 1..N)。 -#pragma once -#include -#include - -namespace fmt { - -struct TextureLayer { - std::string texture; // 相对路径(原样,含 d:\ymir work\ 前缀) - float u_scale = 1, v_scale = 1; - float u_offset = 0, v_offset = 0; - bool splat_enabled = false; - unsigned short height_begin = 0; - unsigned short height_end = 0; -}; - -struct TextureSet { - int declared_count = 0; // TextureCount - std::vector layers; // 实际解析到的图层(运行时索引 = 下标 + 1) - - int runtime_count() const { return (int)layers.size() + 1; } // +1 空图层 -}; - -bool parse_texture_set(const std::string& text, TextureSet& out, std::string* err); -bool parse_texture_set_file(const std::string& path, TextureSet& out, std::string* err); - -} // namespace fmt diff --git a/libgr2/README.md b/libgr2/README.md index aef186d4..00606c05 100644 --- a/libgr2/README.md +++ b/libgr2/README.md @@ -17,7 +17,7 @@ ## 验证 - 全量 9166 个 Metin2 `.gr2`:**0 崩溃、0 非退化谓词失败**(`tools/gr2fuzz`) -- **对拍真 Granny 2.9.12**:骨骼世界矩阵 ≤ 4.6e-5、蒙皮顶点 ≤ 6.5e-5(`tools/oracle_diff`,`test/m2-numeric.json`,23 用例含 v7 / 双 root / 刚体 / 多动画帧) +- **对拍真 Granny 2.9.12**:骨骼世界矩阵 ≤ 4.6e-5、蒙皮顶点 ≤ 6.5e-5(`tools/oracle_diff`,`oracle/m2-numeric.json`,23 用例含 v7 / 双 root / 刚体 / 多动画帧) - 坏输入(空 / 错 magic / 截断 / 越界索引)一律干净报错,不崩 ## 明确不做(Metin2 语料里 0 出现;要「任意 gr2」才需要) diff --git a/test/m2-numeric.json b/oracle/m2-numeric.json similarity index 100% rename from test/m2-numeric.json rename to oracle/m2-numeric.json diff --git a/oracle/run-diff-suite.sh b/oracle/run-diff-suite.sh index 0aa16f5b..3066211c 100755 --- a/oracle/run-diff-suite.sh +++ b/oracle/run-diff-suite.sh @@ -1,12 +1,12 @@ #!/usr/bin/env bash -# M2 门禁·主:对测试资产集跑 oracle dump + oracle_diff,汇总 test/m2-numeric.json。 +# M2 门禁·主:对测试资产集跑 oracle dump + oracle_diff,汇总 oracle/m2-numeric.json。 # 前置:oracle/build-wine.sh 已产出 oracle.exe;WINEPREFIX 已 init(见 RUNBOOK.md); # oracle_diff 已构建(cmake -B build-tools -DMT_BUILD_TOOLS=ON)。 set -uo pipefail cd "$(dirname "$0")/.." REPO="$(pwd)" ASSETS="$(cd "${MT_ASSETS:-$REPO/assets}" && pwd)" -DUMPS="$REPO/test/oracle_dumps" +DUMPS="$REPO/build/oracle_dumps" DIFF="" for c in "$REPO/build-tools/tools/oracle_diff" "$REPO/build/tools/oracle_diff"; do [ -x "$c" ] && DIFF="$c" && break @@ -72,7 +72,7 @@ wait # ── 2. diff + 汇总 ───────────────────────────────────────────────────── echo "== oracle_diff ==" -JSON="$REPO/test/m2-numeric.json" +JSON="$REPO/oracle/m2-numeric.json" { echo '{' echo ' "granny": "2.9.12.0",' diff --git a/test/README.md b/test/README.md deleted file mode 100644 index f0dc3306..00000000 --- a/test/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# Test data - -`golden/` and `bgfx-reference/` contain historical reference screenshots. `assets.list` and `assets-good.txt` list asset samples; `m2-numeric.json` records Granny oracle comparisons. - -Build the asset tools without a UI engine: - -```sh -cmake -S . -B build-tools -DMT_BUILD_TOOLS=ON -cmake --build build-tools -j8 -``` - -The active 40250 port tests run through `script/port_gate.sh macos`. The native SDL/Vulkan client has its own acceptance runner, `script/native_mac_acceptance.mjs`. diff --git a/test/assets-good.txt b/test/assets-good.txt deleted file mode 100644 index 0408b3e9..00000000 --- a/test/assets-good.txt +++ /dev/null @@ -1,9166 +0,0 @@ -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_cheongrin_lod_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_cheongrin_lod_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/fishing/fishing_wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/fishing/fishing_fail.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/fishing/fishing_cancel.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/fishing/throw.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/fishing/run.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/fishing/fishing_catch.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/fishing/walk.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/fishing/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_cheongrin_lod_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_marry_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/intro/selected.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/intro/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/intro/not_selected.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/skill/jipjung.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/skill/jeonsingonggyeok.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/skill/jeongwi.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/skill/noegeom.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/skill/gyeoksan.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/skill/daejin.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/skill/geompung.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/skill/jeonsinbangeo.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/skill/gihyeol.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/skill/samyeon.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/skill/gigongcham.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/skill/musa.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/skill/kwaegeom.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/skill/geomgyeong.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/skill/cheongeun.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/skill/palbang.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/skill/gigongsul.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/skill/gitu.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/general/damage_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/general/damage_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/general/damage_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/general/back_damage_flying.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/general/falling_stand.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/general/dig.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/general/back_falling_stand.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/general/dead.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/general/attack.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/general/run.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/general/damage.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/general/pick_up.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/general/wait_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/general/walk.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/general/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/general/damage_flying.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/general/attack_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_4-1_lod_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_nahan_lod_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_nahan_lod_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_4-1_lod_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_nahan_lod_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/twohand_sword/damage_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/twohand_sword/combo_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/twohand_sword/combo_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/twohand_sword/damage_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/twohand_sword/combo_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/twohand_sword/damage_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/twohand_sword/combo_04.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/twohand_sword/combo_05.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/twohand_sword/combo_07.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/twohand_sword/combo_06.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/twohand_sword/run.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/twohand_sword/rampage_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/twohand_sword/damage.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/twohand_sword/rampage_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/twohand_sword/rampage_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/twohand_sword/rampage.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/twohand_sword/pick_up.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/twohand_sword/wait_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/twohand_sword/walk.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/twohand_sword/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/twohand_sword/change_weapon.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/wedding/walk.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/wedding/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_4-1_lod_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_saja_lod_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_lord_lod_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_saja_lod_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/horse_twohand_sword/combo_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/horse_twohand_sword/combo_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/horse_twohand_sword/combo_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/horse_twohand_sword/skill_wildattack.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/horse_twohand_sword/skill_splash.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_lord_lod_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_novice.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_lord_lod_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_saja_lod_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_novice_lod_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/joy.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/dance_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/french_kiss_with_shaman.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/sad.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/dance_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/dance_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/kiss_with_sura.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/kiss_with_assassin.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/dance_4.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/slap_hurt.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/dance_5.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/banter.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/congratulation.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/shy.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/attractive.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/cheers_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/forgive.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/cheers_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/french_kiss_with_warrior.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/french_kiss_with_assassin.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/angry.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/cheerup.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/french_kiss_with_sura.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/clap.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/slap_hit.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/kiss_with_warrior.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/action/kiss_with_shaman.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_novice_lod_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_novice_lod_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_yongsin.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_saja.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_4-1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_cheongrin.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_nahan.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/onehand_sword/damage_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/onehand_sword/combo_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/onehand_sword/combo_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/onehand_sword/damage_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/onehand_sword/combo_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/onehand_sword/damage_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/onehand_sword/combo_04.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/onehand_sword/combo_05.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/onehand_sword/combo_07.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/onehand_sword/combo_06.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/onehand_sword/attack.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/onehand_sword/run.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/onehand_sword/rampage_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/onehand_sword/damage.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/onehand_sword/rampage_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/onehand_sword/rampage_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/onehand_sword/rampage.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/onehand_sword/pick_up.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/onehand_sword/wait_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/onehand_sword/walk.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/onehand_sword/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/onehand_sword/change_weapon.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/onehand_sword/attack_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/onehand_sword/attack_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/horse/stop.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/horse/skill_charge.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/horse/dead.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/horse/run.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/horse/wait_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/horse/damage.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/horse/wait_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/horse/walk.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/horse/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/horse_onehand_sword/combo_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/horse_onehand_sword/combo_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/horse_onehand_sword/combo_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/horse_onehand_sword/skill_wildattack.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/horse_onehand_sword/skill_splash.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/hair/hair_3_4.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/hair/hair_1_4.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/hair/hair_3_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/hair/hair_3_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/hair/hair_1_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/hair/hair_1_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/hair/hair_3_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/hair/hair_1_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/hair/hair_4_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/hair/hair_2_4.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/hair/hair_4_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/hair/hair_4_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/hair/hair_2_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/hair/hair_2_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/hair/hair_4_4.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/hair/hair_2_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/warrior/warrior_lord.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/fishing/fishing_wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/fishing/fishing_fail.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/fishing/fishing_cancel.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/fishing/throw.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/fishing/run.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/fishing/fishing_catch.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/fishing/walk.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/fishing/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/sura_novice.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/sura_4-1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/intro/selected.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/intro/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/intro/not_selected.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/skill/muyeong.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/skill/hyeolhwan.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/skill/jumagap.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/skill/yonggwon.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/skill/geongon.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/skill/gwigeom.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/skill/swaeryeong.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/skill/jumageom.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/skill/hyeolma.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/skill/geompung.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/skill/geomhwan.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/skill/johon.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/skill/pabeop.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/skill/ihyeol.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/skill/heukma.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/skill/hwayeom.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/skill/maryeong.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/sura_saryeong.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/general/damage_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/general/damage_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/general/damage_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/general/back_damage_flying.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/general/falling_stand.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/general/dig.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/general/back_falling_stand.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/general/dead.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/general/attack.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/general/run.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/general/damage.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/general/pick_up.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/general/walk.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/general/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/general/change_weapon.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/general/run10.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/general/damage_flying.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/general/attack_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/sura_maryeong.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/sura_unra_lod_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/sura_unra_lod_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/wedding/walk.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/wedding/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/sura_marry_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/sura_unra.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/sura_saryeong_lod_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/sura_saryeong_lod_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/sura_lord.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/joy.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/dance_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/french_kiss_with_shaman.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/sad.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/dance_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/dance_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/kiss_with_sura.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/kiss_with_assassin.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/dance_4.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/slap_hurt.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/dance_5.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/banter.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/congratulation.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/shy.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/attractive.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/cheers_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/forgive.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/cheers_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/french_kiss_with_warrior.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/french_kiss_with_assassin.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/angry.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/cheerup.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/french_kiss_with_sura.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/clap.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/slap_hit.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/kiss_with_warrior.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/action/kiss_with_shaman.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/sura_saryeong_lod_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/sura_novice_lod_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/sura_novice_lod_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/sura_jinhon.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/sura_novice_lod_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/onehand_sword/damage_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/onehand_sword/combo_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/onehand_sword/combo_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/onehand_sword/damage_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/onehand_sword/combo_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/onehand_sword/damage_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/onehand_sword/combo_04.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/onehand_sword/combo_05.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/onehand_sword/combo_07.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/onehand_sword/combo_06.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/onehand_sword/run.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/onehand_sword/rampage_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/onehand_sword/damage.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/onehand_sword/rampage_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/onehand_sword/rampage_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/onehand_sword/rampage.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/onehand_sword/pick_up.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/onehand_sword/walk.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/onehand_sword/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/horse/stop.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/horse/skill_charge.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/horse/dead.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/horse/run.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/horse/wait_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/horse/damage.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/horse/wait_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/horse/walk.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/horse/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/horse/skill_splash.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/sura_4-1_lod_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/horse_onehand_sword/combo_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/horse_onehand_sword/combo_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/horse_onehand_sword/combo_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/horse_onehand_sword/skill_wildattack.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/sura_jinhon_lod_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/sura_jinhon_lod_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/sura_lord_lod_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/sura_4-1_lod_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/hair/hair_3_4.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/hair/hair_1_4.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/hair/hair_3_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/hair/hair_3_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/hair/hair_1_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/hair/hair_1_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/hair/hair_3_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/hair/hair_1_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/hair/hair_4_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/hair/hair_2_4.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/hair/hair_4_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/hair/hair_4_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/hair/hair_2_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/hair/hair_2_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/hair/hair_4_4.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/hair/hair_2_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/sura_lord_lod_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/sura_jinhon_lod_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/sura_lord_lod_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/sura/sura_4-1_lod_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_tanma_lod_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_tanma_lod_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/dualhand_sword/damage_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/dualhand_sword/combo_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/dualhand_sword/combo_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/dualhand_sword/damage_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/dualhand_sword/combo_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/dualhand_sword/damage_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/dualhand_sword/combo_04.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/dualhand_sword/combo_05.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/dualhand_sword/combo_07.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/dualhand_sword/combo_06.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/dualhand_sword/run.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/dualhand_sword/rampage_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/dualhand_sword/damage.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/dualhand_sword/rampage_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/dualhand_sword/rampage_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/dualhand_sword/rampage.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/dualhand_sword/pick_up.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/dualhand_sword/wait_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/dualhand_sword/walk.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/dualhand_sword/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/dualhand_sword/combo_08.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/dualhand_sword/change_weapon.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/fishing/fishing_wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/fishing/fishing_fail.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/fishing/fishing_cancel.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/fishing/throw.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/fishing/run.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/fishing/fishing_catch.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/fishing/walk.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/fishing/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_tanma_lod_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_biyeong_lod_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_lord_lod_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_biyeong_lod_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/intro/selected.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/intro/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/intro/not_selected.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/skill/seomgwang.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/skill/seomjeon.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/skill/amseup.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/skill/eunhyeong.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/skill/charyun.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/skill/kwaegeom.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/skill/gyeonggong.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/skill/make_trap.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/skill/cheonryong.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/skill/shoot.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/skill/poison_cloud.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/skill/gungsin.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/skill/gwangyeok.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_biyeong_lod_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_lord_lod_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/bow/damage_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/bow/damage_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/bow/damage_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/bow/attack.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/bow/run.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/bow/damage.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/bow/pick_up.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/bow/wait_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/bow/walk.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/bow/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/bow/change_weapon.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/bow/attack_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/bow/attack_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_lord_lod_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/general/damage_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/general/damage_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/general/damage_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/general/back_damage_flying.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/general/falling_stand.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/general/dig.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/general/back_falling_stand.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/general/dead.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/general/attack.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/general/run.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/general/damage.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/general/pick_up.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/general/wait_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/general/walk.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/general/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/general/damage_flying.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/general/attack_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_lord.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_bihyeon.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_yonga.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/wedding/walk.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/wedding/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_novice.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_yonga_lod_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_yonga_lod_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_yonga_lod_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_4-1_lod_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_4-1_lod_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/joy.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/dance_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/french_kiss_with_shaman.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/sad.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/dance_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/dance_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/kiss_with_sura.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/kiss_with_assassin.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/dance_4.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/slap_hurt.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/dance_5.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/banter.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/congratulation.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/shy.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/attractive.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/cheers_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/forgive.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/cheers_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/french_kiss_with_warrior.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/french_kiss_with_assassin.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/angry.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/cheerup.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/french_kiss_with_sura.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/clap.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/slap_hit.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/kiss_with_warrior.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/action/kiss_with_shaman.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_4-1_lod_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_4-1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse_bow/dead.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse_bow/attack.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse_bow/run.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse_bow/wait_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse_bow/damage.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse_bow/wait_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse_bow/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse_bow/skill_splash.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_marry_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_biyeong.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse_dualhand_sword/combo_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse_dualhand_sword/combo_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse_dualhand_sword/combo_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse_dualhand_sword/skill_wildattack.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse_dualhand_sword/skill_splash.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/onehand_sword/damage_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/onehand_sword/combo_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/onehand_sword/combo_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/onehand_sword/damage_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/onehand_sword/combo_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/onehand_sword/damage_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/onehand_sword/combo_04.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/onehand_sword/combo_05.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/onehand_sword/combo_07.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/onehand_sword/combo_06.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/onehand_sword/run.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/onehand_sword/rampage_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/onehand_sword/damage.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/onehand_sword/rampage_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/onehand_sword/rampage_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/onehand_sword/rampage.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/onehand_sword/pick_up.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/onehand_sword/wait_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/onehand_sword/walk.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/onehand_sword/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/onehand_sword/change_weapon.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse/stop.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse/skill_charge.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse/dead.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse/run.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse/wait_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse/damage.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse/wait_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse/walk.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse_onehand_sword/combo_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse_onehand_sword/combo_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse_onehand_sword/combo_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse_onehand_sword/skill_wildattack.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/horse_onehand_sword/skill_splash.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_tanma.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_novice_lod_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/hair/hair_3_4.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/hair/hair_1_4.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/hair/hair_3_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/hair/hair_3_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/hair/hair_1_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/hair/hair_1_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/hair/hair_3_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/hair/hair_1_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/hair/hair_4_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/hair/hair_2_4.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/hair/hair_4_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/hair/hair_4_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/hair/hair_2_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/hair/hair_2_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/hair/hair_4_4.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/hair/hair_2_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_novice_lod_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/assassin/assassin_novice_lod_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_novice_lod_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_novice.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_novice_lod_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fishing/fishing_wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fishing/fishing_fail.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fishing/fishing_cancel.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fishing/throw.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fishing/run.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fishing/fishing_catch.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fishing/walk.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fishing/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_novice_lod_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_lord.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/intro/selected.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/intro/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/intro/not_selected.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/skill/me.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/skill/yongsin.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/skill/buhwal.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/skill/target.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/skill/byeorak.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/skill/noejeon.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/skill/shoot.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_lord_backup.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/general/damage_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/general/damage_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/general/damage_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/general/back_damage_flying.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/general/falling_stand.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/general/dig.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/general/back_falling_stand.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/general/dead.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/general/attack.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/general/run.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/general/damage.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/general/pick_up.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/general/wait_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/general/walk.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/general/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/general/damage_flying.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/general/attack_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/horse_fan/combo_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/horse_fan/combo_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/horse_fan/combo_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/horse_fan/skill_wildattack.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_miyeom_lod_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_miyeom_lod_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/wedding/walk.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/wedding/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_miyeom_lod_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_lord_lod_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_cheongnang.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_lord_lod_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_lord_lod_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_marry_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_4-1_lod_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_miyeom.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/joy.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/dance_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/french_kiss_with_shaman.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/sad.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/dance_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/dance_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/kiss_with_sura.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/kiss_with_assassin.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/dance_4.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/slap_hurt.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/dance_5.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/banter.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/congratulation.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/shy.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/attractive.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/cheers_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/forgive.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/cheers_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/french_kiss_with_warrior.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/french_kiss_with_assassin.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/angry.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/cheerup.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/french_kiss_with_sura.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/clap.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/slap_hit.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/kiss_with_warrior.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/action/kiss_with_shaman.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_4-1_lod_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_4-1_lod_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/horse_bell/combo_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/horse_bell/combo_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/horse_bell/combo_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/horse_bell/skill_wildattack.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_4-1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/bell/damage_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/bell/combo_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/bell/combo_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/bell/damage_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/bell/combo_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/bell/damage_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/bell/combo_04.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/bell/combo_05.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/bell/combo_07.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/bell/combo_06.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/bell/run.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/bell/rampage_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/bell/damage.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/bell/rampage_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/bell/rampage_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/bell/rampage.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/bell/pick_up.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/bell/walk.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/bell/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/bell/change_weapon.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_cheonryun_lod_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fan/damage_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fan/combo_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fan/combo_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fan/damage_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fan/combo_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fan/damage_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fan/combo_04.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fan/combo_05.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fan/combo_07.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fan/combo_06.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fan/run.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fan/rampage_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fan/damage.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fan/rampage_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fan/rampage_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fan/rampage.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fan/pick_up.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fan/walk.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fan/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/fan/change_weapon.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_cheongnang_lod_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_cheongnang_lod_03.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_cheonryun_lod_02.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_bongsin.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_cheongnang_lod_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_cheonryun_lod_01.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/shaman_cheonryun.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/horse/stop.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/horse/skill_charge.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/horse/dead.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/horse/run.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/horse/wait_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/horse/damage.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/horse/wait_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/horse/walk.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/horse/wait.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/horse/skill_splash.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/hair/hair_3_4.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/hair/hair_1_4.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/hair/hair_3_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/hair/hair_3_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/hair/hair_1_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/hair/hair_1_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/hair/hair_3_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/hair/hair_1_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/hair/hair_4_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/hair/hair_2_4.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/hair/hair_4_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/hair/hair_4_3.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/hair/hair_2_1.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/hair/hair_2_2.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/hair/hair_4_4.gr2 -../m2dev-client-main/assets/PC/ymir work/pc/shaman/hair/hair_2_3.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc2/rabbit_pet/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc2/rabbit_pet/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc2/rabbit_pet/rabbit_pet.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc2/rabbit_pet/run.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc2/rabbit_pet/walk.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc2/rabbit_pet/wait.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc2/leopard_young1/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc2/leopard_young1/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc2/leopard_young1/run.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc2/leopard_young1/leopard_young1_yellow.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc2/leopard_young1/walk.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc2/leopard_young1/wait.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc2/egg_pet/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc2/egg_pet/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc2/egg_pet/run.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc2/egg_pet/walk.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc2/egg_pet/wait.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc2/egg_pet/egg_pet.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc/turkey/turkey_2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc/turkey/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc/turkey/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc/turkey/turkey_3.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc/turkey/dead.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc/turkey/combo_attack.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc/turkey/turkey_2.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc/turkey/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc/turkey/turkey_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc/turkey/run.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc/turkey/turkey_3_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc/turkey/walk.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc/turkey/skill2.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc/turkey/wait.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc/turkey/turkey_1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc/leopard/leopard_yellow.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc/leopard/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc/leopard/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc/leopard/dead.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc/leopard/combo_attack.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc/leopard/leopard_yellow_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc/leopard/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc/leopard/run.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc/leopard/walk.gr2 -../m2dev-client-main/assets/metin2_patch_pet2/ymir work/npc/leopard/wait.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/pc/warrior/hair/hair_10_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/pc/sura/hair/hair_10_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/pc/assassin/hair/hair_10_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/pc/shaman/hair/hair_10_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/pc2/warrior/hair/hair_10_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/pc2/sura/hair/hair_10_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/pc2/assassin/hair/hair_10_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/pc2/shaman/hair/hair_10_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/npc2/halloween1/walk1.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/npc2/halloween1/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/npc2/halloween1/halloween1.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/npc2/halloween1/wait.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/npc2/pwahuang1/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/npc2/pwahuang1/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/npc2/pwahuang1/wait3.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/npc2/pwahuang1/pwahuang1.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/npc2/pwahuang1/run.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/npc2/pwahuang1/walk.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/npc2/pwahuang1/wait.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/npc/leechung/leechung.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/npc/leechung/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/npc/leechung/run.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/npc/leechung/walk.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/npc/leechung/wait.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/npc/spy1/wait.gr2 -../m2dev-client-main/assets/metin2_patch_eu4/ymir work/npc/spy1/spy1.gr2 -../m2dev-client-main/assets/metin2_patch_w20_etc/ymir work/monster2/redthief_boss2/special_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_w20_etc/ymir work/monster2/redthief_boss2/special_attack.gr2 -../m2dev-client-main/assets/metin2_patch_w20_etc/ymir work/item/weapon/07370.gr2 -../m2dev-client-main/assets/metin2_patch_w20_etc/ymir work/item/weapon/02370.gr2 -../m2dev-client-main/assets/metin2_patch_w20_etc/ymir work/item/weapon/05340.gr2 -../m2dev-client-main/assets/metin2_patch_w20_etc/ymir work/item/weapon/00470.gr2 -../m2dev-client-main/assets/metin2_patch_w20_etc/ymir work/item/weapon/01340.gr2 -../m2dev-client-main/assets/metin2_patch_w20_etc/ymir work/item/weapon/00460.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/zone/devilcave/devil_entrance2f_3f.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/zone/devilcave/devil_entrance1f.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/zone/devilcave/devil_entrance_pilla.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/zone/devilcave/devilcave_door_rock.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/zone/devilcave/ob_stone_fence_a.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/zone/devilcave/ob_stone_fence_b.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/zone/devilcave/devil_entrance.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/zone/devilcave/devilcave_boss1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_sword/34_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_sword/30_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_sword/00.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_sword/31_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_sword/03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_sword/33.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_sword/32.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_sword/30.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_sword/31.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_sword/zombie_diseased_sword.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_sword/20_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_sword/35.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_sword/20.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_sword/34.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_sword/zombie_diseased_sword_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_sword/36.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_sword/37.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_scythe/34_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_scythe/30_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_scythe/zombie_soldier_scythe.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_scythe/00.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_scythe/03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_scythe/33.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_scythe/32.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_scythe/00_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_scythe/30.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_scythe/31.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_scythe/20_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_scythe/35.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_scythe/20.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_scythe/34.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_scythe/36.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_scythe/37.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_scythe/zombie_soldier_scythe_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_spear/34_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_spear/30_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_spear/00.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_spear/03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_spear/zombie_soldier_spear_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_spear/33.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_spear/32.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_spear/00_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_spear/30.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_spear/31.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_spear/20_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_spear/35.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_spear/20.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_spear/34.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_spear/36.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_spear/37.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_spear/zombie_soldier_spear.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_dog/37_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_dog/zombie_diseased_dog_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_dog/00.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_dog/33_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_dog/03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_dog/02.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_dog/00_2.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_dog/33.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_dog/32.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_dog/02_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_dog/00_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_dog/30.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_dog/31.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_dog/20_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_dog/35.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_dog/20.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_dog/34.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_dog/37.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_dog/03_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_dog/zombie_diseased_dog.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_bow/34_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_bow/30_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_bow/00.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_bow/03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_bow/33.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_bow/32.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_bow/zombie_diseased_bow_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_bow/00_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_bow/30.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_bow/31.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_bow/35.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_bow/20.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_bow/34.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_bow/37.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_bow/zombie_diseased_bow.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_boss/34_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_boss/zombie_diseased_boss.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_boss/30_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_boss/00.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_boss/03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_boss/33.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_boss/32.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_boss/30.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_boss/31.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_boss/20_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_boss/35.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_boss/20.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_boss/34.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_boss/36.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_boss/37.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_boss/zombie_diseased_boss_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_bow/34_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_bow/30_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_bow/zombie_soldier_bow_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_bow/00.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_bow/03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_bow/zombie_soldier_bow.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_bow/33.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_bow/32.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_bow/30.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_bow/31.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_bow/35.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_bow/20.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_bow/34.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_bow/36.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_soldier_bow/37.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_infector/34_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_infector/30_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_infector/00.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_infector/zombie_diseased_infector.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_infector/03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_infector/02.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_infector/zombie_diseased_infector_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_infector/33.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_infector/32.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_infector/00_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_infector/30.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_infector/31.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_infector/20_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_infector/35.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_infector/20.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_infector/34.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_infector/37.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_kid/zombie_diseased_kid.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_kid/37_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_kid/00.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_kid/31_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_kid/zombie_diseased_kid_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_kid/03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_kid/33.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_kid/32.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_kid/00_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_kid/30.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_kid/31.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_kid/35.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_kid/20.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_kid/34.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_kid/36.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_kid/37.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_spear/34_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_spear/30_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_spear/00.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_spear/03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_spear/33.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_spear/32.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_spear/00_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_spear/30.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_spear/31.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_spear/20_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_spear/35.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_spear/20.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_spear/34.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_spear/36.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_spear/37.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_spear/zombie_diseased_spear_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_diseased_spear/zombie_diseased_spear.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_general/34_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_general/zombie_general_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_general/30_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_general/00.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_general/03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_general/33.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_general/32.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_general/30.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_general/31.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_general/20_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_general/35.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_general/20.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_general/34.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_general/36.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_general/37.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_general/zombie_general.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss/34_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss/zombie_bigboss_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss/zombie_bigboss.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss/30_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss/00.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss/31_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss/03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss/33.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss/32.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss/00_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss/30.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss/31.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss/20_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss/35.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss/20.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss/34.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss/36.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss/37.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss2/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss2/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss2/back_dead.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss2/normal_attack01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss2/zombie_bigboss2.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss2/normal_attack00.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss2/wait01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss2/back_damage01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss2/wait00.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss2/back_damage00.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss2/wait02.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss2/run.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss2/front_damage01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss2/front_damage00.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss2/walk.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss2/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss2/special_attack01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_bigboss2/special_attack00.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_god/34_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_god/30_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_god/00.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_god/03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_god/33.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_god/32.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_god/00_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_god/30.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_god/24.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_god/25.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_god/31.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_god/zombie_god_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_god/20_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_god/35.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_god/20.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_god/34.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_god/36.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_god/37.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_god/zombie_god.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_magician/zombie_magician_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_magician/34_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_magician/30_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_magician/00.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_magician/zombie_magician.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_magician/03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_magician/33.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_magician/32.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_magician/30.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_magician/31.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_magician/20_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_magician/35.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_magician/20.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_magician/34.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_magician/20_2.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_magician/37.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_king/34_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_king/zombie_king_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_king/32_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_king/00.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_king/33_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_king/03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_king/33.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_king/32.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_king/00_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_king/31.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_king/20_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_king/35.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_king/20.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_king/34.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_king/36.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_king/37.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_king/zombie_king.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_ghost/34_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_ghost/30_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_ghost/00.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_ghost/03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_ghost/zombie_ghost_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_ghost/33.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_ghost/32.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_ghost/00_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_ghost/30.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_ghost/31.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_ghost/20_1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_ghost/35.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_ghost/20.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_ghost/34.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_ghost/36.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_ghost/zombie_ghost.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster2/zombie_ghost/37.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc2/phoenix1/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc2/phoenix1/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc2/phoenix1/phoenix1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc2/phoenix1/run.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc2/phoenix1/walk.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc2/phoenix1/wait.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc2/zombie_ghost_door/close_wait.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc2/zombie_ghost_door/zombie_ghost_door.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc2/zombie_ghost_door/open.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc2/zombie_security_stone/zombie_security_stone.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc2/zombie_god_stone/zombie_god_stone.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc2/zombie_warp_stone/zombie_warp_stone.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc2/zombie_key_stone/zombie_key_stone.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/boar/boar_3.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/boar/boar_0_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/boar/boar_0_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/boar/combo_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/boar/boar_0_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/boar/boar_0.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/boar/boar_3_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/boar/boar_3_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/boar/boar_3_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/boar/skill2.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/dog_god/dog_god_3.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/dog_god/dog_god_0.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/dog_god/combo_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/dog_god/dog_god_3_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/dog_god/dog_god_3_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/dog_god/dog_god_3_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/dog_god/dog_god_0_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/dog_god/dog_god_0_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/dog_god/dog_god_0_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/dog_god/skill2.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_0.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_3.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_white_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_darkred_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_darkred_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_white_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_darkred_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_white_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_darkred.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_gold_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_gold.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_3_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_gold_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_3_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/combo_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_3_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_gold_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_green_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_pied.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_green_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_green_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_blue_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_blue_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_blue_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_0_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_white.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_pied_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_0_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_pied_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_pied_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_0_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/skill2.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_green.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/fire_tiger/fire_tiger_blue.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/lion/lion_3_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/lion/lion_3_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/lion/combo_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/lion/lion_3_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/lion/lion_3.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/lion/lion_0.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/lion/lion_0_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/lion/lion_0_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/lion/lion_0_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/npc/lion/skill2.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster/metinstone_02/metinstone_loop.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster/metinstone_02/metinstone_attack.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster/metinstone_02/metinstone_10.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster/metinstone_02/metinstone_drop.gr2 -../m2dev-client-main/assets/metin2_patch_eu3/ymir work/monster/metinstone_02/metinstone_blow.gr2 -../m2dev-client-main/assets/season2/season2/npc/chenjo_warpgate/chenjo_warpgate.gr2 -../m2dev-client-main/assets/season2/season2/npc/signal_fire/signalfire.gr2 -../m2dev-client-main/assets/season2/season2/npc/signal_fire/signalfire_ani.gr2 -../m2dev-client-main/assets/season2/season2/npc/jinno_warpgate/jinno_warpgate.gr2 -../m2dev-client-main/assets/season2/season2/npc/sinsu_warpgate/sinsu_warpgate.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_footman/skipia_footman_wait1.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_footman/skipia_footman_back_knockdown.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_footman/skipia_footman_front_damage.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_footman/skipia_footman_front_knockdown.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_footman/skipia_footman_lod_01.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_footman/skipia_footman_dead.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_footman/skipia_footman_front_standup.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_footman/skipia_footman_front_stand.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_footman/skipia_footman_back_dead.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_footman/skipia_footman_front_damage1.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_footman/skipia_footman_wait.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_footman/skipia_footman_back_damage1.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_footman/skipia_footman_back_standup.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_footman/skipia_footman.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_footman/skipia_footman_attack.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_footman/skipia_footman_attack1.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_footman/skipia_footman_run.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_footman/skipia_footman_back_damage.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_magician/skipia_magician_wait1.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_magician/skipia_magician.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_magician/skipia_magician_back_knockdown.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_magician/skipia_magician_damage.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_magician/skipia_magician_damage1.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_magician/skipia_magician_back_damage.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_magician/skipia_magician_run.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_magician/skipia_magician_front_knockdown.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_magician/skipia_magician_attack.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_magician/skipia_magician_attack1.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_magician/skipia_magician_wait.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_magician/skipia_magician_back_dead.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_magician/skipia_magician_back_standup.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_magician/skipia_magician_back_damage1.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_magician/skipia_magician_dead.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_magician/skipia_magician_lod_01.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_magician/skipia_magician_front_standup.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_bowman/skipia_bowman_dead.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_bowman/skipia_bowman.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_bowman/skipia_bowman_lod_01.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_bowman/skipia_bowman_run.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_bowman/skipia_bowman_back_damage.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_bowman/skipia_bowman_back_dead.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_bowman/skipia_bowman_wait.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_bowman/skipia_bowman_front_knockdown.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_bowman/skipia_bowman_wait1.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_bowman/skipia_bowman_damage1.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_bowman/skipia_bowman_damage.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_bowman/skipia_bowman_attack1.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_bowman/skipia_bowman_front_standup.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_bowman/skipia_bowman_attack.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_bowman/skipia_bowman_back_damage1.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_bowman/skipia_bowman_back_standup.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_bowman/skipia_bowman_back_knockdown.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_general/skipia_general.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_general/skipia_general_skill1.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_general/skipia_general_back_knockdown.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_general/skipia_general_skill2.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_general/skipia_general_front_knockdown.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_general/skipia_general_back_standup.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_general/skipia_general_back_damage1.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_general/skipia_general_attack.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_general/skipia_general_front_standup.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_general/skipia_general_front_damage1.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_general/skipia_general_run.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_general/skipia_general_back_dead.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_general/skipia_general_dead.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_general/skipia_general_wait1.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_general/skipia_general_back_damage.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_general/skipia_general_front_damage.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_general/skipia_general_attack1.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_general/skipia_general_wait.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_general/skipia_general_lod_01.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_officer/skipia_officer_wait1.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_officer/skipia_officer_lod_01.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_officer/skipia_officer_front_standup.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_officer/skipia_officer_front_damage1.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_officer/skipia_officer_back_standup.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_officer/skipia_officer_back_damage1.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_officer/skipia_officer_attack.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_officer/skipia_officer_front_knockdown.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_officer/skipia_officer_back_damage.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_officer/skipia_officer_back_dead.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_officer/skipia_officer_wait.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_officer/skipia_officer_front_damage.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_officer/skipia_officer_dead.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_officer/skipia_officer_back_knockdown.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_officer/skipia_officer_attack1.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_officer/skipia_officer_run.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_officer/skipia_officer.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_water_dragon/water_dragon_lod_01.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_water_dragon/00.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_water_dragon/02.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_water_dragon/00_1.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_water_dragon/20_4.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_water_dragon/31.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_water_dragon/20_5.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_water_dragon/20_1.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_water_dragon/20.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_water_dragon/20_2.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_water_dragon/20_3.gr2 -../m2dev-client-main/assets/season2/season2/monster/ch_water_dragon/water_dragon.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_watchtower02-01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigstone06_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stone05.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stonepillar_02_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_fence05_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stone18_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_tent01_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/ob-7-02-01_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-general_obj_21_1_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-general_obj_04_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-018-stonelight-1_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bell_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/landmark-01-bellhouse.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stone10.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/ob-bigstatue01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_suspension bridge03_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigtower12_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_ferryboat02_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stone15_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigtower03_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-general_obj_01_4.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/ob-bigstatue03.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stone12.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stone06.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-general_obj_21_1.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-018-stonelight-1.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_watchtower01_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stone07.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stone13.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/ob-bigstone01_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/ob-bigstatue02.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_tent02.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-general_obj_01_1.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stoneimage01_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigtower06_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigstone09.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/landmark_grandstone02.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stone10_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/ob-bigstone04_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigstone08.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_lionstoneimage.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_pillar.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_tent01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigstonegate01_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-general_obj_01_2.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stone14.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow-002-inwall-02.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/landmark_grandstone01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigstone03_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow_building04.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-general_obj_01_2_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stone01_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stone15.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stone01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-general_obj_01_3.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-10m-bridge02_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_lionstoneimage_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-general_obj_01_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-general_obj_06_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow_tower01_04.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigtower09.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_watchtower01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-037-tower.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_suspension bridge01_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigtower10_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-004-house2.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stone06_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow-middledam-04.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow-middledam-05.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stonepillar_02.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_fence06.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/ob-7-01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow-033-guesthouse-02.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_lamp_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigstone04_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigtower08.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-general_obj_04.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-037-tower_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_watchtower03_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/ob-c-0013_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/warpgate03_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_watchtower02.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-general_obj_06.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/landmark_grandstone02_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-022-10m-bridge_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/ob-bigstone03_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_fence04.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-018-stonelight_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow-middledam-07.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow-004-hause2.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/ob-bigstone04.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow-middledam-06.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stonepillar_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigtower01_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow-033-guesthouse-01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_fence05.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-general_obj_07.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_watchtower03.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigstone09_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/ob-bigstatue02_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_watermill_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigstone10_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-035-woodgate.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow_tower01_02.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-general_obj_03.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/ob-7-02-02.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_fence01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow-middledam-02.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/ob-bigstone01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow-middledam-03.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_lamp.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-022-10m-bridge.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-016-house9.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stoneimage03_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigtower04_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-general_obj_02.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stone12_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow_tower01_03.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow_tower01_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/ob-7-02-01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_fence02.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-general_obj_03_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow-middledam-01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/ob-bigstone03.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/ob-bigstone02.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-032-shamanhouse.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow_tower.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_fence02_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow_4fbuilding.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigtower09_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-018-stonelight.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_fence03.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-001-house3.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-general_obj_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigstone01_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigtower07_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stoneimage01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bell.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stonedoor_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow-32-shamanhouse.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/warpgate01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow-bigdam-01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigtower01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_flag.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stoneimage02.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigstone02_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow-009-hotel.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow-032-shamanhouse.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigtower03.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/ob-c-0013.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_watermill_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_fence01_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow-bigdam-03.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/warpgate02.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/warpgate03.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_watchtower03-01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow-bigdam-02.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_pilla_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-general_obj_01_3_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigtower02.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow-006-castle.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stoneimage03.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/obj-0006.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_fence04_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stone19_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigtower06.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigtower12.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow-bigdam-06.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigstone07_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stonebox.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-10m-bridge02.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow-035-woodgate.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_watchtower03-01_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_suspension bridge02_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_ferryboat03_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stone05_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigtower07.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-general_obj_21.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/ob-bigstatue01_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigtower11.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigtower05.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stone14_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigtower02_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow-bigdam-05.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/obj-0006_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/landmark_grandstone01_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow-bigdam-04.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigtower04.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigtower10.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/obj-0010.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigstonegate02.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_carriage_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stone18.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_watermill_01_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigstone06.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow_brazier.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigtower05_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stone13_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/warpgate02_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigstone07.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stone19.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stoneimage02_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigstonegate01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_carriage.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-general_obj_02_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-general_obj_01_1_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigstone05.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow_tower01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/obj-0010_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigstone10.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigstone04.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stonebox_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_fence03_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigstonegate02_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigtower08_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow-004-house2.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/snow_ring_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-general_obj_01_4_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigtower11_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_ferryboat01_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_suspension bridge03.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stone07_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/ob-7-02-02_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_flag_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-general_obj_07_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stonepillar_01_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_fence06_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/ob-7-03-01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_tent02_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigstone01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_suspension bridge02.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_ferryboat01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigstone05_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/ob-bigstone02_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_ferryboat03.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigstone03.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_watchtower02_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_watermill.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_txtstone_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/ob-7-03-02.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/nsm-general_obj_21_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigstone08_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_bigstone02.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/ob-bigstatue03_lod_01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_stonedoor.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_suspension bridge01.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_txtstone.gr2 -../m2dev-client-main/assets/Property/property/n/obj/snow.m/general_obj_ferryboat02.gr2 -../m2dev-client-main/assets/metin2_patch_dance/ymir work/pc/warrior/action/dance_6.gr2 -../m2dev-client-main/assets/metin2_patch_dance/ymir work/pc/sura/sura_4-1.gr2 -../m2dev-client-main/assets/metin2_patch_dance/ymir work/pc/sura/action/dance_6.gr2 -../m2dev-client-main/assets/metin2_patch_dance/ymir work/pc/sura/sura_4-1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_dance/ymir work/pc/sura/sura_4-1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_dance/ymir work/pc/sura/sura_4-1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dance/ymir work/pc/assassin/assassin_4-1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_dance/ymir work/pc/assassin/assassin_4-1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_dance/ymir work/pc/assassin/action/dance_6.gr2 -../m2dev-client-main/assets/metin2_patch_dance/ymir work/pc/assassin/assassin_4-1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dance/ymir work/pc/assassin/assassin_4-1.gr2 -../m2dev-client-main/assets/metin2_patch_dance/ymir work/pc/shaman/action/dance_6.gr2 -../m2dev-client-main/assets/metin2_patch_dance/ymir work/pc2/warrior/warrior_4-1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_dance/ymir work/pc2/warrior/warrior_4-1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_dance/ymir work/pc2/warrior/warrior_4-1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dance/ymir work/pc2/warrior/action/dance_6.gr2 -../m2dev-client-main/assets/metin2_patch_dance/ymir work/pc2/warrior/warrior_4-1.gr2 -../m2dev-client-main/assets/metin2_patch_dance/ymir work/pc2/sura/action/dance_6.gr2 -../m2dev-client-main/assets/metin2_patch_dance/ymir work/pc2/assassin/action/dance_6.gr2 -../m2dev-client-main/assets/metin2_patch_dance/ymir work/pc2/shaman/action/dance_6.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/oxevent/o_flag.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/oxevent/x_flag.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/oxevent/ox_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/old_resources picking zon/kimtest.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/old_resources picking zon/resources_picking_ground.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/old_resources picking zon/resources_picking_wall.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/old_resources picking zon/jhtest.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/old_resources picking zon/mushroom02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/old_resources picking zon/mushroom03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/old_resources picking zon/resources_picking_all.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/old_resources picking zon/mushroom01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/old_resources picking zon/mushroom04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/devil_tower/deviltowergate.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/devil_tower/deviltower_1f.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/monkey03_dungeon02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/monkey_dungeon_cave04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/monkey03_dungeon01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/monkey_dungeon_cave03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/monkey_dungeon_cave02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/monkey_dungeon_cave01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/monkey02_dungeon_cave04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/monkey02_dungeon_cave01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/monkey02_dungeon_cave02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/monkey02_dungeon_cave03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/monkey_dungeon01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/monkey03_dungeon_cave01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/monkey03_dungeon_cave03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/monkey_dungeon02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/monkey03_dungeon_cave02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/monkey03_dungeon_cave04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/monkey02_dungeon02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/monkey02_dungeon01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/20050218/monkey03_dungeon02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/20050218/monkey_dungeon_cave04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/20050218/monkey03_dungeon01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/20050218/monkey_dungeon_cave03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/20050218/monkey_dungeon_cave02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/20050218/monkey_dungeon_cave01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/20050218/monkey02_dungeon_cave04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/20050218/monkey02_dungeon_cave01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/20050218/monkey02_dungeon_cave02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/20050218/monkey02_dungeon_cave03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/20050218/monkey_dungeon01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/20050218/monkey03_dungeon_cave01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/20050218/monkey03_dungeon_cave03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/20050218/monkey_dungeon02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/20050218/monkey03_dungeon_cave02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/20050218/monkey03_dungeon_cave04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/20050218/monkey02_dungeon02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/monkey_dungeon/20050218/monkey02_dungeon01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/thief_dungeon/thief_dungeon_gate.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/devil_tower3/deviltower3.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/devil_tower2/deviltower2.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/resources_picking_zon/kimtest.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/resources_picking_zon/resources_picking_ground.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/resources_picking_zon/resources_picking_wall.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/resources_picking_zon/jhtest.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/resources_picking_zon/mushroom02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/resources_picking_zon/mushroom03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/resources_picking_zon/resources_picking_all.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/resources_picking_zon/mushroom01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/resources_picking_zon/mushroom04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/haven_dungeon/skipia_passi.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/haven_dungeon/skipia_passc(1).gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/haven_dungeon/skipia_passl.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/haven_dungeon/skipia_passic.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/haven_dungeon/skipia_boss.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/haven_dungeon/skipia_passc.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/haven_dungeon/skipia_passt.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/haven_dungeon/skipia_passp.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/haven_dungeon/skipia_passis1.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/haven_dungeon/skipia_passis2.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/snow_dungeon/dungeon_c3.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/snow_dungeon/dungeon_c2.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/snow_dungeon/dungeon_c1.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/snow_dungeon/dungeon_b1.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/snow_dungeon/dungeon_b2.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/snow_dungeon/snow_bossroom.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/snow_dungeon/dungeon_b3.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/snow_dungeon/icicle_up_05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/snow_dungeon/icicle_up_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/snow_dungeon/dungeon_a2.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/snow_dungeon/ice_pillar_s01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/snow_dungeon/ice_pillar_s00.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/snow_dungeon/dungeon_a3.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/snow_dungeon/dungeon_a1.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/snow_dungeon/ice_pillar_s05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/deviltower2f/deviltower2f.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/spider_dungeon/spider_dungeon07.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/spider_dungeon/spider_dungeon06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/spider_dungeon/spider_dungeon04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/spider_dungeon/spider_dungeon01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/spider_dungeon/spider_dungeon02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/spider_dungeon/spider_dungeon03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/spider_dungeon/spider_dungeon_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/spider_dungeon/spider_dungeon_02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/spider_dungeon/spider_dungeon_boss02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/spider_dungeon/spider_dungeon_gate.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/spider_dungeon/spider_dungeon_boss.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/dungeon/spider_dungeon/spider_dungeongate_up.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_flame_01/ob-bigstatue01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_flame_01/ob-bigstatue03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_flame_01/ob-bigstatue02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_flame_01/general_obj_lionstoneimage.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_flame_01/general_obj_bigtower09.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_flame_01/general_obj_bigtoewr01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_flame_01/general_obj_bigtower08.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_flame_01/general_obj_stoneimage01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_flame_01/warpgate01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_flame_01/general_obj_stoneimage02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_flame_01/general_obj_bigtower03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_flame_01/warpgate02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_flame_01/general_obj_bigtower02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_flame_01/general_obj_stoneimage03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_flame_01/general_obj_bigtower06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_flame_01/general_obj_bigtower12.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_flame_01/general_obj_bigtower07.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_flame_01/general_obj_bigtower11.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_flame_01/general_obj_bigtower05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_flame_01/general_obj_bigtower04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_flame_01/general_obj_bigtower10.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_flame_01/warpgate02_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_flame_01/general_obj_stonedoor.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_watchtower02-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigstone06_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stone05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stonepillar_02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_fence05_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stone18_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_tent01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/ob-7-02-01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-general_obj_21_1_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-general_obj_04_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-018-stonelight-1_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bell_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/landmark-01-bellhouse.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stone10.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-033-guesthouse-01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/ob-bigstatue01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_suspension bridge03_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigtower12_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_ferryboat02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stone15_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigtower03_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-general_obj_01_4.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/ob-bigstatue03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stone12.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stone06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-general_obj_21_1.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-middledam-07_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-018-stonelight-1.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_watchtower01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/warpgate02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stone07.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stone13.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/ob-bigstone01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/ob-bigstatue02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-middledam-02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_tent02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-general_obj_01_1.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stoneimage01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigtower06_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigstone09.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/landmark_grandstone02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stone10_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-004-house2_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/ob-bigstone04_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigstone08.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_lionstoneimage.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_pillar.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_tent01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigstonegate01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-general_obj_01_2.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stone14.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-002-inwall-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/landmark_grandstone01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow_tower01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigstone03_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow_building04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-general_obj_01_2_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stone01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stone15.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stone01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-general_obj_01_3.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-10m-bridge02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_lionstoneimage_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-general_obj_01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-general_obj_06_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow_tower01_04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigtower09.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_watchtower01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-037-tower.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_suspension bridge01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigtower10_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-004-house2.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stone06_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-middledam-04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-middledam-05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stonepillar_02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_fence06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/ob-7-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-033-guesthouse-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_lamp_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigstone04_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigtower08.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-general_obj_04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-002-inwall-02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-037-tower_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_watchtower03_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/ob-c-0013_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/warpgate03_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_watchtower02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-general_obj_06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/landmark_grandstone02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-022-10m-bridge_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/ob-bigstone03_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_fence04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-018-stonelight_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-middledam-07.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-004-hause2.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/ob-bigstone04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-middledam-06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stonepillar_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigtower01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-033-guesthouse-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_fence05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-general_obj_07.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-035-woodgate_lod-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_watchtower03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-middledam-05_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/warpgate03_01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigstone09_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/ob-bigstatue02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_watermill_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigstone10_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-035-woodgate.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow_tower01_02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-general_obj_03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/ob-7-02-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_fence01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-middledam-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/ob-bigstone01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-middledam-03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_lamp.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-022-10m-bridge.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-016-house9.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stoneimage03_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigtower04_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-general_obj_02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stone12_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow_tower01_03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow_brazier-lod-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow_tower01_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/ob-7-02-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_fence02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-general_obj_03_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-middledam-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/ob-bigstone03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/ob-bigstone02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-032-shamanhouse.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow_tower.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_fence02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow_4fbuilding.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigtower09_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-018-stonelight.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_fence03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-001-house3.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-general_obj_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigstone01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigtower07_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-006-castle_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stoneimage01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bell.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stonedoor_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-middledam-03_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/warpgate01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-bigdam-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigtower01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_flag.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stoneimage02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigstone02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-009-hotel.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-032-shamanhouse.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigtower03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/ob-c-0013.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_watermill_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_fence01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-bigdam-03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/warpgate02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/warpgate03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_watchtower03-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-bigdam-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_pilla_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-general_obj_01_3_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigtower02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-006-castle.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stoneimage03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/obj-0006.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_fence04_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stone19_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigtower06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigtower12.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-bigdam-06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigstone07_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stonebox.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-10m-bridge02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/ice_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-035-woodgate.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_watchtower03-01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_suspension bridge02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_ferryboat03_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stone05_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigtower07.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-middledam-06_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/warpgate02_01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-general_obj_21.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/ob-bigstatue01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigtower11.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigtower05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stone14_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigtower02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-bigdam-05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/obj-0006_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/landmark_grandstone01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-bigdam-04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigtower04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigtower10.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/warpgate03_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/obj-0010.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigstonegate02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_carriage_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stone18.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_watermill_01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigstone06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow_brazier.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigtower05_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stone13_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/warpgate02_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow_building04_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigstone07.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow_brazier_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stone19.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-middledam-01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stoneimage02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigstonegate01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_carriage.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-general_obj_02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-general_obj_01_1_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigstone05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow_tower01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-009-hotel_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/obj-0010_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigstone10.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigstone04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stonebox_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_fence03_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigstonegate02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigtower08_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-004-house2.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-033-guesthouse-02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow_ring_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-general_obj_01_4_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigtower11_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_ferryboat01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_suspension bridge03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stone07_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/ob-7-02-02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_flag_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-general_obj_07_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stonepillar_01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_fence06_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/ob-7-03-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_tent02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigstone01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_suspension bridge02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_ferryboat01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-035-woodgate_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigstone05_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/ob-bigstone02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_ferryboat03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigstone03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_watchtower02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_watermill.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_txtstone_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/warpgate01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/snow-middledam-04_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/ob-7-03-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/nsm-general_obj_21_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigstone08_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_bigstone02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/ob-bigstatue03_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_stonedoor.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_suspension bridge01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_txtstone.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/snow.m/general_obj_ferryboat02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/tombstone.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_charcoal.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_16.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_17.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/ob-bigstatue01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/ob-bigstatue03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_29.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_15.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_28.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/ob-bigstatue02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_tent02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_bigstone09.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_10.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_bigstone08.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_lionstoneimage.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/ob-b1-005-woodbarrel.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_tent01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_07.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_drum.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_bigtoewr01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_woodchair.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_brazier.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_fence06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_fence04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_bigtoewr02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/ob-bigstone04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_bigtoewr03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_fence05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_fence01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_bigtoewr07.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/ob-bigstone01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_bigtoewr06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_bigtoewr12.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_fence02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_bigtoewr04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_bigtoewr10.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/ob-bigstone03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/ob-bigstone02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_bigtoewr11.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_bigtoewr05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_fence03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/ob-b1-006-woodbarrel.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_stoneimage01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_bigtoewr08.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/warpgate01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_bigtoewr09.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_flag.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_stoneimage02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_25_1.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/ob-b1-001-box02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_woodbed.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/warpgate02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/ob-b1-001-box03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_stoneimage03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_01_1.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_05_1.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_21_1.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_jar_red01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_bigstone06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_23.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/warpgate02_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_22.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_bigstone07.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_jar_red02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_carriage.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_bigstone05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_21.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_25-2.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_09.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_bigstone10.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_bigstone04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_25.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_18.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_jar_blue02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_24.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_bigstone01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_bigstone03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_26.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/b_general_obj_27.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_jar_blue01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_bigstone02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/map_n_desert_01/general_obj_stonedoor.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/obj/tombstone1.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/milgyo/milgyo_tower01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/milgyo/milgyo_building02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/milgyo/milgyo_building03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/milgyo/milgyo_tower02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/milgyo/milgyo_brazier.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/milgyo/milgyo_building04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/milgyo/milgyo_4fbuilding.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/milgyo/milgyo_pavilion.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/flame/bigdam_001.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/flame/middlestone_bridge.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/flame/bigstone_bridge.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/icemount/n_snow_m_empiregate_03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/icemount/n_snow_m_empiregate_02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/icemount/n_snow_m_resoucegate.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/icemount/n_snow_m_empiregate_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-035-woodgate.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_tower_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-middledam-05_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_woodfence03_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-bigdam-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-bigdam-03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-009-hotel.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_4fbuilding.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_cart02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_board01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-bigdam-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-bigdam-06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_carriage01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-bigdam-05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_tent01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_carriage01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-bigdam-04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-castle02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-033-guesthouse-02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-bigstone01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-006-castle_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-middledam-07_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_lamp01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-032-shamanhouse.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-bigstone02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_building04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-bigstone03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-bigstone02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_lionstone_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-middledam-02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-bigstone04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_-bridge01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_cart01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_woodfence02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_woodfence03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-033-guesthouse-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-bigstone01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_tower01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_tower03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_cart02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-castle02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_woodfence01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-033-guesthouse-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_tower02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_brazier.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-middledam-01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_lionstone.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-033-guesthouse-01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_woodfence02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-middledam-04_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_-bridge01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-002-inwall-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-004-house2.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_lamp01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_tent01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-bigstone04_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_tower04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-035-woodgate_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_wooddoor01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-middledam-03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-bigstone03_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/cactus_02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-009-hotel_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/cactus_03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-middledam-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-middledam-03_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/cactus_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-middledam-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-middledam-06_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-middledam-05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/cactus_04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/cactus_05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_tower.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-middledam-04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-004-house2_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-006-castle.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-middledam-06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_brazier_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert_cart01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/desert-middledam-07.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/n/desert/b1-011-workhouse_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-004-house2_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-024-10m-bridge.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-004-house2.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-038-wall-door.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-rms-001.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-016-house9.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1s-002-inwall-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-022-10m-bridge.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-032-shamanhouse.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-001-house3.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-007-itemshop.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1s-002-inwall-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-009-hotel.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-011-workhouse_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-038-wall-corner.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1_018-stonelight.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-013-6tower.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-034-stonedoor.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-033-guesthouse-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-016-house9_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-038-wall-lin2.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-035-woodgate.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-033-guesthouse-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-033-guesthouse-01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1s-017.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-007-itemshop_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-middledam-04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-landmark-01-bellhouse.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-009-hotel_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-middledam-05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-middledam-07.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1_018-stonelight-1.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-037-tower.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-008-house5.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-008-house5_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-middledam-06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-033-guesthouse-02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-013-6tower_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-middledam-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-011-workhouse.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-010-bank_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-middledam-03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-010-bank.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-middledam-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-001-house3_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-031-tower.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/a/building/a1-038-wall-lin.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/b_general_obj_28_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/ob-b1-001-bix01_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/ob-b1-001-015_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/ob-b1-001-box03_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_bigtower12_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_fence04_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_lamp_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_bigtower10_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/ob-b1-001-box01_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_bigtower02_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_fence06_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/b_general_obj_02_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/b_general_obj_10_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/sign_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_carriage_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_fence02_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_bigtower06_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_brazier_01_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/b_general_obj_10_1_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/a1_018-stonelight_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/b_general_obj_22_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/b_general_obj_06_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_flag_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/b_general_obj_10_11_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/obj-0003_03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/obj-0003_02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/b_general_obj_16_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/obj-0003_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_bigtower08_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_bigtower04_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_fence05_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/b_general_obj_21_1_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_woodbox_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/ob-b1-001-box02_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/a1_018-stonelight-1_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_bigtower01_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/obj-0006_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_fence02_01_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/b_general_obj_27_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/ob-b1-001-bix02_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_woodbed_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/ob-b1-006-woodbarrel_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_bigtower11_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_bigtower03_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/b_general_obj_07_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/ob-b1-001-box01_01_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_woodchair_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/b_general_obj_10_12_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_bigtower07_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/ob-b1-005-woodbarrel_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_fence03_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_bigtower09_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/obj-0002_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_bigtower05_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/obj-0010_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_fence01_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/b_general_obj_17_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/b_general_obj_21_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/obj/general_obj_pillar_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/b1-001-house3_01_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/c1-032-shamanhouse_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/c1-004-house2_02_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/c1-010-bank_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/c1-016-house9_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/c1_0004_house2_03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/c1-008-house5-2_02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/c1-034-stonedoor-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/c1-038-wqll-lin_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/c1-038-wall-door_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/c1-033-guesthouse-01_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/ob-10-01_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/c1-038-wall-lin2_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/c1-035-woodgate_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/c1-007-itemshop_01_02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/c1-038-wall_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/c1-007-itemshop_02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/c1-033-guesthouse-02_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/c1-038-wall-corner_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/c1-038-wall-lin_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/c1-009-hotel01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/ghost/c1-011-workhouse-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/nusluck/tent_01_lamp02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/nusluck/tent_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/nusluck/tent_02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/nusluck/bone_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/nusluck/grass_of.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/nusluck/corpse.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/nusluck/tent_01_lamp1.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/nusluck/corpse_023.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/nusluck/corpse_022.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/nusluck/torch_2.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/nusluck/top.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/nusluck/tent_small.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/nusluck/nusluck_flag01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/nusluck/grass_ok.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/duel/a1-038-wall-door_duel.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/duel/a1-038-wall-lin2_duel.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/duel/a1-038-wall-corner.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/duel/a1-038-wall-lin_duel.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/duel/a1-038-wall-corner_duel.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/duel/ring.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-011-workhouse_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-010-bank_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-024-10m-bridge.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-033-guesthouse-02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-033-guesthouse-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-016-house9_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-035-woodgate.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-033-guesthouse-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-022-10m-bridge.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-009-hotel.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-004-house2_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-landmark-01-bellhouse.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1_018-stonelight.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-008-house5.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-010-bank.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-007-itemshop.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-011-workhouse.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-017.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-032-shamanhouse.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-034-stonedoor.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-013-6tower.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-009-hotel_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-007-itemshop_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-002-inwall-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-002-inwall-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-038-wall-lin2.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1_018-stonelight-1.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-004-house2.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-middledam-04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-038-wall-door.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-rms-001.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-031-tower.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-033-guesthouse-01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-middledam-05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-008-house5_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-middledam-07.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-middledam-06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-037-tower.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-middledam-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-038-wall-corner.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-013-6tower_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-middledam-03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-016-house9.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-middledam-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-001-house3.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-001-house3_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/c/building/c1-038-wall-lin.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-5-03-1thiefden.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_watchtower02-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_charcoal.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stone05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stone11.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_16.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-12-09.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_woodbox.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_17.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stone10.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stone04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-03-bonetunnel05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-bigstatue01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-033-guesthouse-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-05-bonetomb_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-10-05-house03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-1-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-05-bonetomb_03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-bigstatue03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stone12.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stone06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b-general_wbridge01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_29.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_15.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-004-hause2.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-7-11-building01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_14.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_28.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-tower01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stone07.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stone13.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-bigstatue02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-033-guesthouse-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-05-bonetomb_02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_tent02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stone03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-03-bonetunnel02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bigstone09.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_10.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/landmark_grandstone02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_38.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-03-bonetunnel02_08.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_itembox01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-03-bonetunnel02_09.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/grass01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_39.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/landmark_grandstone03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_11.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bigstone08.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stone02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_lionstoneimage.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/landmark_observatory.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_pillar.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_jar_blue01-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-b1-005-woodbarrel.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_tent01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stone14.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-03-bonetunnel01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_07.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/landmark_grandstone01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_drum.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_13.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_itembox03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-12-03stair.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_cliffgate01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_itembox02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_12.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob_4fbuilding.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stone15.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stone01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-05-bonetomb_04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_pieceofstone01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-01-skeletontower02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-01-skeletonwall01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_watchtower01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bigtoewr01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_boat01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_woodchair.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-10-02-wall-lin.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_brazier.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-7-12-building02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stonepillar_02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_fence06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-7-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob_brazier_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-01-skeletontower03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_pieceofstone02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-01-skeletontower01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-7-13-building04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/warpgate03_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_10_1.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-01-skeletonwall02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_watchtower02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_fence04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_boat02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bigtoewr02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-004-hause2_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-bigstone04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stonepillar_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bigtoewr03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_fence05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-10-03-house01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_watchtower03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_brimstone.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/sign.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_pieceofstone03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_watermill_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-01-skeletontower04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_jar_yellow01-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-7-02-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_fence01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bigtoewr07.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-033-guesthouse-01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_target 01-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-5-03thiefden.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-bigstone01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_lamp.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-01-skeletontowerstair01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bigtoewr06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bigtoewr12.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-01-skeletontower05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_jar_red01-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_pieceofstone04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-7-02-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_fence02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bigtoewr04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bigtoewr10.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_target 01-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-bigstone03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-bigstone02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-01-skeletontowerstair02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bigtoewr11.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bigtoewr05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_fence03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-7-04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-b1-006-woodbarrel.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-7-13-building03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-01-skeletontower06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_01_3.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-03-bonetunnel04_05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stoneimage01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_jar_blue02-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bell.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_40.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bigtoewr08.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-b1-001-box01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/warpgate01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stump.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bigtoewr09.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-033-guesthouse-02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_41.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-10-02-wall-lin2.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_jar_yellow01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bridge.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-03-bonetunnel04_04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-bigdam-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_01_2.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_flag.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/obj-0001.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/obj-0003.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-bigdam-03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stoneimage02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-c-0013.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_25_1.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_unglazed.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-b1-001-box02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_woodbed.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/warpgate02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/warpgate03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-tower01_04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-b1-001-box03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_watchtower03-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_42.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_jar_yellow02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stoneimage03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-bigdam-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_01_1.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/obj-0002.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/obj-0012.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/obj-0006.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-03-bonetunnel04_03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-bigdam-06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bottle.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_05_1.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stonebox.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-tower01_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_21_1.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-013-tower01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-03-bonetunnel04_02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-10-02-wall-corner.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/hay_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-035-woodgate_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_01_4.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stonebridge.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/obj-0011.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-032-shamanhouse.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-bigdam-05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-tower01_03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-tower01_02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-10-04-house02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-b1-013-lamp02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-bigdam-04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-03-bonetunnel04_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/hay_02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-035-woodgate.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/obj-0010.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/obj-0004.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/landmark_statuestone.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bigstonegate02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_jar_red01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-02-stonelight02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stone18.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bigstone06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-standganpan-03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_23.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_37.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-03-bonetunnel02_07.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-03-bonetunnel02_13.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-12-14.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-12-03gate04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-05-bonelight_02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-05-bonelight_03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-12-03gate05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-03-bonetunnel02_12.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/warpgate02_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-03-bonetunnel02_06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_36.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_22.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-standganpan-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_target 02-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bigstone07.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stone19.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-02-stonelight03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_jar_yellow02-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_jar_red02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bigstonegate01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-02-stonelight01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_carriage.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bigstone05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_08.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-4-04-04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_34.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_20.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-03-bonetunnel02_10.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-12-03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-03-bonetunnel02_04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-05-bonelight_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b-general_external04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-12-03gate06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-03-bonetunnel02_05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-12-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-03-bonetunnel02_11.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_21.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_25-2.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_35.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-standganpan-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_09.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bigstone10.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bigstone04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_target 02-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_jar_red02-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_farming tool01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob_brazier.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_suspension bridge03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_brazier_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_breakenbox01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_31.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_cliffgate_wall02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_25.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-standganpan-05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_19.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-4-04-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-05-bonelight_04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-12-03gate02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-03-bonetunnel02_15.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-12-06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-03-bonetunnel02_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b-general_external01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-7-03-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-12-07.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-03-bonetunnel02_14.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-12-03gate03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_target 02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_18.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-standganpan-04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_jar_blue02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_24.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_cliffgate_wall03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_30.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bigstone01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_suspension bridge02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_campfire.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_ferryboat01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_ferryboat03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_farming tool02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-10-02-wall-door.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stone09.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bigstone03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_breakenbox02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_watermill.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_26.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_32.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_cliffgate_wall01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-4-04-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-standganpan-06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-12-03gate01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-12-05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-03-bonetunnel02_02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b-general_external02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b-general_external03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-7-03-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-11-03-bonetunnel02_03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-4-04-03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_target 01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_33.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/b_general_obj_27.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_jar_blue01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_bigstone02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_breakenbox03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stone08.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_stonedoor.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_suspension bridge01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_txtstone.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/general_obj_ferryboat02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/obj/ob-10-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/landmark-01-bellhouse.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-035-woodgate.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-024-10m-bridge.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-c-0013.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-middledam-wooddoor-ani-open.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1s-002-inwall-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-038-wall-door.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1_018-stonelight-1.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-022-10m-bridge.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1s-002-inwall-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-009-hotel_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-004-house2_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-008-house5.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-033-guesthouse-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-bigdam-06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-038-wall-lin2.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-016-house9_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1_018-stonelight.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-033-guesthouse-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-007-itemshop.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-bigdam-05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-bigdam-04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-middledam-stonedoor_ani_open.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-010-bank_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-034-stonedoor.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-bigdam-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-006-castle01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-middledam_00.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-009-hotel.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-middledam-wooddoor_ani_open.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-bigdam-03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-bigdam-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-033-guesthouse-02_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-001-house3_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-016-house9.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-006-castle01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-033-guesthouse-01_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-013-6tower_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-010-bank.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-001-house3.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-011-workhouse.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-middledam-wooddoor_model.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-004-house2.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-008-house5_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-middledam-stonedoor_model.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-038-wall-corner.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1s-017.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-middledam-02.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-middledam-wooddoor-ani-close.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-middledam-03.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-007-itemshop_lod_01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-middledam-01.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-032-shamanhouse.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-037-tower.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-middledam-wooddoor_ani_close.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-038-wall-lin.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-middledam-04.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-006-castle.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-middledam-stonedoor_ani_close.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/rms-001.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-middledam-05.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-middledam-07.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-031-tower.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-013-6tower.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-middledam-06.gr2 -../m2dev-client-main/assets/Zone/ymir work/zone/b/building/b1-011-workhouse_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/zone/dungeon/haven_dungeon/skipia_passi.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/zone/dungeon/haven_dungeon/skipia_passl.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/zone/dungeon/haven_dungeon/skipia_passic.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/zone/dungeon/haven_dungeon/skipia_boss.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/zone/dungeon/haven_dungeon/skipia_passc.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/zone/dungeon/haven_dungeon/skipia_passt.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/zone/dungeon/haven_dungeon/skipia_passp.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/zone/dungeon/haven_dungeon/skipia_collision.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/zone/dungeon/haven_dungeon/skipia_passis1.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/zone/dungeon/haven_dungeon/skipia_passis2.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/zone/dungeon/haven_dungeon/skipia_passis3.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_footman/34_1.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_footman/skipia_footman_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_footman/30_1.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_footman/00.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_footman/03.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_footman/33.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_footman/32.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_footman/00_1.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_footman/30.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_footman/31.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_footman/20_1.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_footman/35.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_footman/20.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_footman/34.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_footman/skipia_footman.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_footman/36.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_footman/37.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_magician/34_1.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_magician/skipia_magician.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_magician/30_1.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_magician/00.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_magician/03.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_magician/33.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_magician/32.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_magician/00_1.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_magician/30.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_magician/31.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_magician/20_1.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_magician/35.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_magician/20.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_magician/34.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_magician/36.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_magician/37.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_magician/skipia_magician_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_bowman/34_1.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_bowman/skipia_bowman.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_bowman/skipia_bowman_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_bowman/30_1.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_bowman/00.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_bowman/03.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_bowman/33.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_bowman/32.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_bowman/00_1.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_bowman/30.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_bowman/31.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_bowman/20_1.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_bowman/35.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_bowman/20.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_bowman/34.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_bowman/36.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_bowman/37.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_general/34_1.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_general/skipia_general.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_general/30_1.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_general/00.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_general/03.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_general/33.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_general/32.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_general/00_1.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_general/30.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_general/24.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_general/25.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_general/31.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_general/20_1.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_general/35.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_general/20.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_general/34.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_general/36.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_general/37.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_general/skipia_general_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/outlaw/outlaw_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_officer/34_1.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_officer/skipia_officer_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_officer/30_1.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_officer/00.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_officer/03.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_officer/33.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_officer/32.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_officer/00_1.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_officer/30.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_officer/31.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_officer/20_1.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_officer/35.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_officer/20.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_officer/34.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_officer/36.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_officer/37.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_officer/skipia_officer.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_water_dragon/water_dragon_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_water_dragon/00.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_water_dragon/28.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_water_dragon/03.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_water_dragon/27.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_water_dragon/26.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_water_dragon/00_1.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_water_dragon/24.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_water_dragon/25.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_water_dragon/31.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_water_dragon/20.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/monster2/ch_water_dragon/water_dragon.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/item/weapon/07180.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/item/weapon/07190.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/item/weapon/05330.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/npc2/obj_bag003/obj_bag003.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/npc2/sura_skeleton/sura_skeleton5.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/npc2/sura_skeleton/sura_skeleton4.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/npc2/sura_skeleton/sura_skeleton3.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/npc2/sura_skeleton/sura_skeleton2.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/npc2/sura_skeleton/sura_skeleton1.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/npc2/worship_dragon/worship_dragon.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/npc2/suraghost/suraghost.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/npc2/suraghost/wait.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/npc2/warriorghost/warriorghost.gr2 -../m2dev-client-main/assets/season3_eu/ymir work/npc2/warriorghost/wait.gr2 -../m2dev-client-main/assets/season3_eu/season2/npc/ent_elder/ent_elder_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/season2/npc/ent_elder/00.gr2 -../m2dev-client-main/assets/season3_eu/season2/npc/ent_elder/03.gr2 -../m2dev-client-main/assets/season3_eu/season2/npc/ent_elder/00_2.gr2 -../m2dev-client-main/assets/season3_eu/season2/npc/ent_elder/33.gr2 -../m2dev-client-main/assets/season3_eu/season2/npc/ent_elder/32.gr2 -../m2dev-client-main/assets/season3_eu/season2/npc/ent_elder/00_1.gr2 -../m2dev-client-main/assets/season3_eu/season2/npc/ent_elder/30.gr2 -../m2dev-client-main/assets/season3_eu/season2/npc/ent_elder/24.gr2 -../m2dev-client-main/assets/season3_eu/season2/npc/ent_elder/25.gr2 -../m2dev-client-main/assets/season3_eu/season2/npc/ent_elder/31.gr2 -../m2dev-client-main/assets/season3_eu/season2/npc/ent_elder/20_1.gr2 -../m2dev-client-main/assets/season3_eu/season2/npc/ent_elder/35.gr2 -../m2dev-client-main/assets/season3_eu/season2/npc/ent_elder/20.gr2 -../m2dev-client-main/assets/season3_eu/season2/npc/ent_elder/34.gr2 -../m2dev-client-main/assets/season3_eu/season2/npc/ent_elder/36.gr2 -../m2dev-client-main/assets/season3_eu/season2/npc/ent_elder/37.gr2 -../m2dev-client-main/assets/season3_eu/season2/npc/ent_elder/ent_elder.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_watchtower02-01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigstone06_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stone05.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stonepillar_02_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_fence05_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stone18_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_tent01_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/ob-7-02-01_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-general_obj_21_1_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-general_obj_04_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-018-stonelight-1_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bell_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/landmark-01-bellhouse.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stone10.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/ob-bigstatue01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_suspension bridge03_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigtower12_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_ferryboat02_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stone15_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigtower03_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-general_obj_01_4.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/ob-bigstatue03.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stone12.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stone06.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-general_obj_21_1.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-018-stonelight-1.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_watchtower01_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stone07.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stone13.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/ob-bigstone01_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/ob-bigstatue02.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_tent02.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-general_obj_01_1.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stoneimage01_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigtower06_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigstone09.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/landmark_grandstone02.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stone10_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/ob-bigstone04_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigstone08.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_lionstoneimage.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_pillar.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_tent01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigstonegate01_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-general_obj_01_2.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stone14.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow-002-inwall-02.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/landmark_grandstone01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigstone03_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow_building04.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-general_obj_01_2_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stone01_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stone15.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stone01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-general_obj_01_3.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-10m-bridge02_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_lionstoneimage_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-general_obj_01_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-general_obj_06_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow_tower01_04.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigtower09.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_watchtower01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-037-tower.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_suspension bridge01_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigtower10_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-004-house2.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stone06_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow-middledam-04.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow-middledam-05.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stonepillar_02.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_fence06.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/ob-7-01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow-033-guesthouse-02.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_lamp_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigstone04_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigtower08.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-general_obj_04.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-037-tower_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_watchtower03_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/ob-c-0013_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/warpgate03_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_watchtower02.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-general_obj_06.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/landmark_grandstone02_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-022-10m-bridge_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/ob-bigstone03_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_fence04.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-018-stonelight_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow-middledam-07.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow-004-hause2.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/ob-bigstone04.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow-middledam-06.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stonepillar_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigtower01_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow-033-guesthouse-01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_fence05.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-general_obj_07.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_watchtower03.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigstone09_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/ob-bigstatue02_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_watermill_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigstone10_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-035-woodgate.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow_tower01_02.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-general_obj_03.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/ob-7-02-02.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_fence01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow-middledam-02.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/ob-bigstone01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow-middledam-03.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_lamp.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-022-10m-bridge.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-016-house9.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stoneimage03_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigtower04_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-general_obj_02.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stone12_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow_tower01_03.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow_tower01_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/ob-7-02-01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_fence02.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-general_obj_03_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow-middledam-01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/ob-bigstone03.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/ob-bigstone02.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-032-shamanhouse.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow_tower.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_fence02_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow_4fbuilding.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigtower09_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-018-stonelight.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_fence03.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-001-house3.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-general_obj_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigstone01_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigtower07_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stoneimage01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bell.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stonedoor_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow-32-shamanhouse.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/warpgate01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow-bigdam-01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigtower01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_flag.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stoneimage02.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigstone02_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow-009-hotel.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow-032-shamanhouse.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigtower03.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/ob-c-0013.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_watermill_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_fence01_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow-bigdam-03.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/warpgate02.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/warpgate03.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_watchtower03-01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow-bigdam-02.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_pilla_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-general_obj_01_3_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigtower02.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow-006-castle.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stoneimage03.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/obj-0006.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_fence04_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stone19_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigtower06.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigtower12.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow-bigdam-06.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigstone07_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stonebox.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-10m-bridge02.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow-035-woodgate.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_watchtower03-01_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_suspension bridge02_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_ferryboat03_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stone05_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigtower07.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-general_obj_21.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/ob-bigstatue01_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigtower11.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigtower05.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stone14_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigtower02_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow-bigdam-05.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/obj-0006_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/landmark_grandstone01_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow-bigdam-04.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigtower04.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigtower10.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/obj-0010.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigstonegate02.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_carriage_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stone18.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_watermill_01_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigstone06.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow_brazier.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigtower05_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stone13_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/warpgate02_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigstone07.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stone19.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stoneimage02_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigstonegate01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_carriage.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-general_obj_02_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-general_obj_01_1_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigstone05.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow_tower01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/obj-0010_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigstone10.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigstone04.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stonebox_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_fence03_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigstonegate02_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigtower08_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow-004-house2.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/snow_ring_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-general_obj_01_4_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigtower11_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_ferryboat01_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_suspension bridge03.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stone07_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/ob-7-02-02_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_flag_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-general_obj_07_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stonepillar_01_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_fence06_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/ob-7-03-01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_tent02_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigstone01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_suspension bridge02.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_ferryboat01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigstone05_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/ob-bigstone02_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_ferryboat03.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigstone03.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_watchtower02_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_watermill.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_txtstone_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/ob-7-03-02.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/nsm-general_obj_21_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigstone08_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_bigstone02.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/ob-bigstatue03_lod_01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_stonedoor.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_suspension bridge01.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_txtstone.gr2 -../m2dev-client-main/assets/season3_eu/property/n/obj/snow.m/general_obj_ferryboat02.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/warrior/warrior_pwahuang1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/warrior/warrior_pwahuang1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/warrior/warrior_pwahuang1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/warrior/warrior_pwahuang1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/warrior/warrior_blacksnake1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/warrior/warrior_blacksnake1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/warrior/warrior_blacksnake1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/warrior/warrior_blacksnake1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/warrior/hair/hair_30_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/warrior/hair/hair_29_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/warrior/hair/hair_32_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/warrior/hair/hair_35_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/warrior/hair/hair_33_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/warrior/hair/hair_31_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/warrior/hair/hair_28_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/sura/sura_blacksnake1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/sura/sura_pwahuang1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/sura/sura_pwahuang1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/sura/sura_pwahuang1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/sura/sura_blacksnake1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/sura/sura_blacksnake1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/sura/sura_pwahuang1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/sura/sura_blacksnake1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/sura/hair/hair_30_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/sura/hair/hair_29_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/sura/hair/hair_32_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/sura/hair/hair_35_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/sura/hair/hair_33_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/sura/hair/hair_31_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/sura/hair/hair_28_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/assassin/assassin_pwahuang1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/assassin/assassin_blacksnake1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/assassin/assassin_pwahuang1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/assassin/assassin_blacksnake1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/assassin/assassin_pwahuang1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/assassin/hair/hair_30_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/assassin/hair/hair_29_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/assassin/hair/hair_32_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/assassin/hair/hair_35_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/assassin/hair/hair_33_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/assassin/hair/hair_31_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/assassin/hair/hair_28_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/assassin/assassin_blacksnake1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/assassin/assassin_blacksnake1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/assassin/assassin_pwahuang1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/shaman/shaman_blacksnake1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/shaman/shaman_blacksnake1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/shaman/shaman_blacksnake1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/shaman/shaman_pwahuang1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/shaman/shaman_blacksnake1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/shaman/shaman_pwahuang1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/shaman/shaman_pwahuang1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/shaman/shaman_pwahuang1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/shaman/hair/hair_30_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/shaman/hair/hair_29_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/shaman/hair/hair_32_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/shaman/hair/hair_35_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/shaman/hair/hair_33_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/shaman/hair/hair_31_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc/shaman/hair/hair_28_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/warrior/warrior_pwahuang1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/warrior/warrior_pwahuang1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/warrior/warrior_pwahuang1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/warrior/warrior_pwahuang1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/warrior/warrior_blacksnake1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/warrior/warrior_blacksnake1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/warrior/warrior_blacksnake1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/warrior/warrior_blacksnake1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/warrior/hair/hair_30_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/warrior/hair/hair_29_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/warrior/hair/hair_32_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/warrior/hair/hair_35_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/warrior/hair/hair_33_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/warrior/hair/hair_31_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/warrior/hair/hair_28_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/sura/sura_blacksnake1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/sura/sura_pwahuang1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/sura/sura_pwahuang1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/sura/sura_pwahuang1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/sura/sura_blacksnake1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/sura/sura_blacksnake1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/sura/sura_pwahuang1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/sura/sura_blacksnake1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/sura/hair/hair_30_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/sura/hair/hair_29_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/sura/hair/hair_32_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/sura/hair/hair_35_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/sura/hair/hair_33_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/sura/hair/hair_31_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/sura/hair/hair_28_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/assassin/assassin_pwahuang1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/assassin/assassin_blacksnake1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/assassin/assassin_pwahuang1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/assassin/assassin_blacksnake1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/assassin/assassin_pwahuang1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/assassin/hair/hair_30_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/assassin/hair/hair_29_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/assassin/hair/hair_32_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/assassin/hair/hair_35_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/assassin/hair/hair_33_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/assassin/hair/hair_31_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/assassin/hair/hair_28_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/assassin/assassin_blacksnake1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/assassin/assassin_blacksnake1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/assassin/assassin_pwahuang1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/shaman/shaman_blacksnake1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/shaman/shaman_blacksnake1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/shaman/shaman_blacksnake1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/shaman/shaman_pwahuang1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/shaman/shaman_blacksnake1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/shaman/shaman_pwahuang1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/shaman/shaman_pwahuang1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/shaman/shaman_pwahuang1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/shaman/hair/hair_30_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/shaman/hair/hair_29_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/shaman/hair/hair_32_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/shaman/hair/hair_35_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/shaman/hair/hair_33_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/shaman/hair/hair_31_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc_costume1/ymir work/pc2/shaman/hair/hair_28_1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_magic/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_magic/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_magic/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_magic/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_magic/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_magic/redthief_magic.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_magic/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_magic/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_magic/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_magic/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_magic/redthief_magic_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_magic/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_magic/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_magic/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_magic/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_magic/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_magic/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_magic/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_magic/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_magic/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_magic/manticore_magic.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_magic/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_magic/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_magic/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_magic/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_magic/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_magic/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_magic/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_magic/manticore_magic_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_magic/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss1/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss1/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss1/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss1/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss1/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss1/back_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss1/ent_boss1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss1/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss1/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss1/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss1/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss1/front_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss1/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss1/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss1/special_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss1/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss1/ent_boss1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss1/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_officer/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_officer/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_officer/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_officer/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_officer/triton_officer_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_officer/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_officer/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_officer/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_officer/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_officer/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_officer/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_officer/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_officer/triton_officer.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_officer/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier2/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier2/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier2/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier2/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier2/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier2/manticore_soldier2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier2/maticore_soldier2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier2/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier2/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier2/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier2/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier2/manticore_soldier2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier2/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier2/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier2/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier2/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_general/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_general/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_general/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_general/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_general/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_general/ogre_general.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_general/ogre_general_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_general/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_general/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_general/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_general/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_general/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_general/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_general/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_general/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss/wait3.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss/back_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss/front_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss/special_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss/redthief_boss.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss/redthief_boss_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_magic/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_magic/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_magic/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_magic/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_magic/triton_magic_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_magic/triton_magic.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_magic/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_magic/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_magic/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_magic/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_magic/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_magic/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_magic/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_magic/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_general/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_general/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_general/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_general/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_general/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_general/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_general/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_general/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_general/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_general/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_general/manticore_general_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_general/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_general/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_general/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_general/manticore_general.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss/wait3.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss/back_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss/manticore_boss.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss/front_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss/manticore_boss_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss/special_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier2/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier2/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier2/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier2/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier2/lemures_soldier2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier2/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier2/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier2/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier2/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier2/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier2/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier2/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier2/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier2/lemures_soldier2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief2_magic/redthief2_magic.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief2_magic/redthief2_magic_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss2/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss2/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss2/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss2/special_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss2/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss2/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss2/wait3.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss2/back_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss2/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss2/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss2/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss2/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss2/ogre_boss2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss2/front_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss2/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss2/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss2/special_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss2/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss2/ogre_boss2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss2/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier/gnoll_soldier_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier/gnoll_soldier.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_general/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_general/lemures_general.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_general/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_general/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_general/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_general/lemures_general_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_general/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_general/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_general/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_general/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_general/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_general/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_general/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_general/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_general/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_general/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_general/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_general/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_general/cyclops_general.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_general/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_general/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_general/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_general/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_general/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_general/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_general/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_general/cyclops_general_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_general/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief2_soldier2/redthief2_soldier2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief2_soldier2/redthief2_soldier2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss2/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss2/gnoll_boss2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss2/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss2/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss2/special_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss2/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss2/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss2/back_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss2/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss2/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss2/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss2/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss2/front_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss2/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss2/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss2/special_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss2/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss2/gnoll_boss2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss2/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief2_officer/redthief2_officer.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief2_officer/redthief2_officer_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier2/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier2/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier2/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier2/giant_soldier2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier2/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier2/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier2/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier2/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier2/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier2/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier2/giant_soldier2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier2/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier2/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier2/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier2/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier/crustacean_soldier.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier/crustacean_soldier_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief2_bow/redthief2_bow_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief2_bow/redthief2_bow.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_bow/gnoll_bow.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_bow/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_bow/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_bow/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_bow/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_bow/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_bow/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_bow/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_bow/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_bow/gnoll_bow_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_bow/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_bow/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_bow/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_bow/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier/manticore_soldier.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier/maticore_soldier_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_soldier/manticore_soldier_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier2/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier2/triton_soldier2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier2/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier2/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier2/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier2/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier2/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier2/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier2/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier2/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier2/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier2/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier2/triton_soldier2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier2/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_officer/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_officer/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_officer/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_officer/giant_officer.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_officer/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_officer/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_officer/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_officer/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_officer/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_officer/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_officer/giant_officer_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_officer/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_officer/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_officer/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_officer/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier2/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier2/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier2/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier2/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier2/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier2/cyclops_soldier2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier2/cyclops_soldier2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier2/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier2/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier2/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier2/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier2/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier2/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier2/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier2/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_officer/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_officer/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_officer/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_officer/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_officer/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_officer/redthief_officer_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_officer/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_officer/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_officer/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_officer/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_officer/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_officer/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_officer/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_officer/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_officer/redthief_officer.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_soldier/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_soldier/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_soldier/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_soldier/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_soldier/ogre_soldier_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_soldier/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_soldier/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_soldier/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_soldier/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_soldier/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_soldier/ogre_soldier.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_soldier/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_soldier/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_soldier/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief2_boss/redthief2_boss.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief2_boss/redthief2_boss_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss2/cyclops_boss2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss2/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss2/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss2/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss2/special_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss2/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss2/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss2/wait3.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss2/back_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss2/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss2/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss2/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss2/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss2/front_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss2/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss2/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss2/special_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss2/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss2/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss2/cyclops_boss2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_general/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_general/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_general/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_general/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_general/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_general/crustacean_general_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_general/crustacean_general.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_general/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_general/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_general/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_general/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_general/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_general/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_general/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_general/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss/giant_boss_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss/wait3.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss/back_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss/giant_boss.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss/front_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss/special_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss/back_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss/lemures_boss_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss/front_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss/lemures_boss.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss/special_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss2/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss2/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss2/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss2/special_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss2/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss2/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss2/back_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss2/lemures_boss2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss2/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss2/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss2/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss2/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss2/lemures_boss2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss2/front_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss2/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss2/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss2/special_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss2/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_boss2/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_soldier2/redthief_soldier2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_soldier2/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_soldier2/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_soldier2/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_soldier2/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_soldier2/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_soldier2/redthief_soldier2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_soldier2/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_soldier2/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_soldier2/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_soldier2/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_soldier2/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_soldier2/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_soldier2/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_soldier2/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier/cyclops_soldier.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_soldier/cyclops_soldier_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_magic/giant_magic_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_magic/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_magic/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_magic/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_magic/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_magic/giant_magic.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_magic/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_magic/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_magic/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_magic/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_magic/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_magic/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_magic/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_magic/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier/lemures_soldier_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier/lemures_soldier.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_soldier/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_general/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_general/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_general/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_general/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_general/gnoll_general_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_general/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_general/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_general/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_general/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_general/gnoll_general.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_general/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_general/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_general/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_general/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss2/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss2/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss2/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss2/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss2/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss2/wait3.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss2/back_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss2/ent_boss2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss2/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss2/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss2/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss2/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss2/front_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss2/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss2/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss2/special_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss2/ent_boss2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss2/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss2/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss/back_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss/front_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss/triton_boss_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss/special_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss/triton_boss.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_bow/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_bow/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_bow/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_bow/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_bow/ogre_bow.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_bow/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_bow/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_bow/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_bow/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_bow/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_bow/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_bow/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_bow/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_bow/ogre_bow_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_officer/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_officer/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_officer/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_officer/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_officer/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_officer/crustacean_officer.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_officer/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_officer/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_officer/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_officer/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_officer/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_officer/crustacean_officer_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_officer/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_officer/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_officer/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss/wait3.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss/back_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss/ogre_boss.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss/ogre_boss_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss/front_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss/special_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_boss/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss3/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss3/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss3/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss3/ent_boss3_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss3/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss3/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss3/wait3.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss3/back_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss3/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss3/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss3/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss3/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss3/front_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss3/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss3/ent_boss3.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss3/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss3/special_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss3/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ent_boss3/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_magic/cyclops_magic.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_magic/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_magic/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_magic/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_magic/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_magic/cyclops_magic_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_magic/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_magic/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_magic/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_magic/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_magic/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_magic/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_magic/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_magic/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_bow/crustacean_bow.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_bow/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_bow/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_bow/crustacean_bow_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_bow/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_bow/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_bow/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_bow/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_bow/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_bow/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_bow/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_bow/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_bow/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_bow/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_bow/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier/triton_soldier_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier/triton_soldier.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_soldier/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_general/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_general/redthief_general.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_general/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_general/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_general/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_general/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_general/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_general/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_general/redthief_general_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_general/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_general/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_general/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_general/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_general/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_general/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_general/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_general/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_general/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_general/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_general/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_general/giant_general_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_general/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_general/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_general/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_general/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_general/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_general/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_general/giant_general.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_general/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_general/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_magic/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_magic/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_magic/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_magic/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_magic/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_magic/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_magic/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_magic/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_magic/lemures_magic.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_magic/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_magic/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_magic/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_magic/lemures_magic_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_magic/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss/back_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss/cyclops_boss_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss/front_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss/special_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss/cyclops_boss.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_boss/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss2/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss2/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss2/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss2/special_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss2/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss2/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss2/wait3.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss2/back_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss2/giant_boss2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss2/giant_boss2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss2/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss2/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss2/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss2/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss2/front_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss2/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss2/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss2/special_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss2/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_boss2/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss2/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss2/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss2/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss2/special_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss2/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss2/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss2/wait3.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss2/back_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss2/manticore_boss2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss2/manticore_boss2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss2/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss2/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss2/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss2/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss2/front_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss2/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss2/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss2/special_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss2/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_boss2/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss2/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss2/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss2/specil_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss2/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss2/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss2/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss2/back_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss2/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss2/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss2/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss2/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss2/redthief_boss2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss2/specil_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss2/front_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss2/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss2/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss2/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss2/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_boss2/redthief_boss2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief2_general/redthief2_general_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief2_general/redthief2_general.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss/crustacean_boss_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss/back_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss/crustacean_boss.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss/front_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss/special_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss2/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss2/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss2/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss2/special_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss2/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss2/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss2/back_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss2/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss2/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss2/crustacean_boss2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss2/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss2/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss2/front_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss2/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss2/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss2/special_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss2/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss2/crustacean_boss2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_boss2/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss2/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss2/triton_boss2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss2/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss2/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss2/special_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss2/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss2/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss2/wait3.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss2/back_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss2/triton_boss2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss2/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss2/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss2/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss2/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss2/front_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss2/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss2/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss2/special_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss2/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_boss2/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_magic/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_magic/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_magic/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_magic/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_magic/ogre_magic.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_magic/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_magic/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_magic/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_magic/ogre_magic_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_magic/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_magic/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_magic/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_magic/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_magic/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_officer/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_officer/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_officer/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_officer/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_officer/cyclops_officer_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_officer/cyclops_officer.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_officer/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_officer/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_officer/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_officer/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_officer/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_officer/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_officer/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/cyclops_officer/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief2_boss2/redthief2_boss2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief2_boss2/redthief2_boss2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier2/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier2/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier2/crustacean_soldier2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier2/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier2/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier2/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier2/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier2/crustacean_soldier2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier2/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier2/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier2/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier2/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier2/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/crustacean_soldier2/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_officer/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_officer/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_officer/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_officer/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_officer/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_officer/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_officer/lemures_officer_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_officer/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_officer/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_officer/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_officer/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_officer/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_officer/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/lemures_officer/lemures_officer.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_officer/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_officer/manticore_officer.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_officer/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_officer/manticore_officer_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_officer/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_officer/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_officer/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_officer/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_officer/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_officer/maticore_officer_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_officer/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_officer/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_officer/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_officer/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_officer/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/manticore_officer/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_magic/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_magic/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_magic/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_magic/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_magic/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_magic/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_magic/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_magic/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_magic/gnoll_magic_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_magic/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_magic/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_magic/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_magic/gnoll_magic.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_magic/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier/giant_soldier.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier/giant_soldier_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/giant_soldier/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier2/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier2/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier2/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier2/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier2/gnoll_soldier2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier2/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier2/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier2/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier2/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier2/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier2/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier2/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier2/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_soldier2/gnoll_soldier2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss/back_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss/gnoll_boss.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss/gnoll_boss_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss/front_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss/special_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/gnoll_boss/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_officer/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_officer/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_officer/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_officer/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_officer/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_officer/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_officer/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_officer/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_officer/ogre_officer.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_officer/ogre_officer_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_officer/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_officer/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_officer/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/ogre_officer/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_general/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_general/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_general/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_general/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_general/triton_general.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_general/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_general/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_general/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_general/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_general/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_general/triton_general_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_general/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_general/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/triton_general/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_bow/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_bow/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_bow/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_bow/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_bow/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_bow/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_bow/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_bow/run.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_bow/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_bow/redthief_bow_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_bow/walk.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_bow/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_bow/wait.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_bow/redthief_bow.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief_bow/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc/warrior/warrior_5_1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc/warrior/warrior_5_1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc/warrior/warrior_5_1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc/warrior/warrior_5_1.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc/sura/sura_5_1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc/sura/sura_5_1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc/sura/sura_5_1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc/sura/sura_5_1.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc/assassin/assassin_5_1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc/assassin/assassin_5_1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc/assassin/assassin_5_1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc/assassin/assassin_5_1.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc/shaman/shaman_5_1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc/shaman/shaman_5_1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc/shaman/shaman_5_1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc/shaman/shaman_5_1.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc2/warrior/warrior_5_1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc2/warrior/warrior_5_1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc2/warrior/warrior_5_1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc2/warrior/warrior_5_1.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc2/sura/sura_5_1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc2/sura/sura_5_1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc2/sura/sura_5_1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc2/sura/sura_5_1.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc2/assassin/assassin_5_1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc2/assassin/assassin_5_1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc2/assassin/assassin_5_1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc2/assassin/assassin_5_1.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc2/shaman/shaman_5_1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc2/shaman/shaman_5_1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc2/shaman/shaman_5_1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/pc2/shaman/shaman_5_1.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/npc/eojiryu/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/npc/eojiryu/eojiryu.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/npc/eojiryu/wait.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/npc/gilaso/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/npc/gilaso/gilaso.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/npc/gilaso/wait.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/npc/chagirap/chagirap_lod01.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/npc/chagirap/chagirap.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/npc/chagirap/die.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/npc/chagirap/run.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/npc/chagirap/walk.gr2 -../m2dev-client-main/assets/metin2_patch_5th_armor/ymir work/npc/chagirap/wait.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_soldier/firegolem_soldier.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_soldier/firegolem_soldier_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_soldier/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_soldier/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_soldier/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_soldier/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_soldier/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_soldier/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_soldier/run.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_soldier/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_soldier/walk.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_soldier/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_soldier/wait.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_soldier/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/yamachun_boss/yamachun_boss.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/yamachun_boss/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/yamachun_boss/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/yamachun_boss/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/yamachun_boss/back_standup.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/yamachun_boss/special_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/yamachun_boss/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/yamachun_boss/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/yamachun_boss/back_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/yamachun_boss/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/yamachun_boss/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/yamachun_boss/run.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/yamachun_boss/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/yamachun_boss/front_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/yamachun_boss/walk.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/yamachun_boss/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/yamachun_boss/special_attack.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/yamachun_boss/wait.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/yamachun_boss/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_magician/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_magician/firegolem_magician_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_magician/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_magician/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_magician/back_standup.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_magician/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_magician/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_magician/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_magician/run.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_magician/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_magician/firegolem_magician.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_magician/walk.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_magician/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_magician/wait.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_magician/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/icegolem_soldier/icegolem_soldier.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/icegolem_soldier/icegolem_soldier_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_general/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_general/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_general/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_general/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_general/firegolem_general_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_general/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_general/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_general/run.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_general/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_general/walk.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_general/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_general/wait.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_general/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_general/firegolem_general.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/icegolem_boss/icegolem_boss_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/icegolem_boss/icegolem_boss.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/icegolem_general/icegolem_general.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/icegolem_general/icegolem_general_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/hanma_boss/hanma_boss.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/hanma_boss/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/hanma_boss/special_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/hanma_boss/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/hanma_boss/hanma_boss_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/hanma_boss/special_attack.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/icegolem_magician/icegolem_magician_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/icegolem_magician/icegolem_magician.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_boss/normal_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_boss/firegolem_boss.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_boss/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_boss/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_boss/special_attack1.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_boss/firegolem_boss_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_boss/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_boss/front_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_boss/back_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_boss/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_boss/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_boss/run.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_boss/front_standup.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_boss/front_damage1.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_boss/walk.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_boss/back_knockdown.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_boss/special_attack.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_boss/wait.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/monster2/firegolem_boss/normal_attack.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/npc2/flame_door_npc/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/npc2/flame_door_npc/flame_door_npc.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/npc2/flame_door_npc/wait.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/npc2/flame_bridge_block_chain/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/npc2/flame_bridge_block_chain/bridge_block_chain.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/npc2/flame_bridge_block_chain/wait.gr2 -../m2dev-client-main/assets/metin2_patch_w21_mobs/ymir work/npc2/flame_dungeon_npc/flame_npc.gr2 -../m2dev-client-main/assets/metin2_patch_easter1/ymir work/pc/warrior/warrior_rabbit1.gr2 -../m2dev-client-main/assets/metin2_patch_easter1/ymir work/pc/warrior/warrior_rabbit1_backup.gr2 -../m2dev-client-main/assets/metin2_patch_easter1/ymir work/pc/warrior/hair/hair_11_1.gr2 -../m2dev-client-main/assets/metin2_patch_easter1/ymir work/pc/sura/sura_rabbit1.gr2 -../m2dev-client-main/assets/metin2_patch_easter1/ymir work/pc/sura/hair/hair_11_1.gr2 -../m2dev-client-main/assets/metin2_patch_easter1/ymir work/pc/assassin/assassin_rabbit1.gr2 -../m2dev-client-main/assets/metin2_patch_easter1/ymir work/pc/assassin/hair/hair_11_1.gr2 -../m2dev-client-main/assets/metin2_patch_easter1/ymir work/pc/shaman/shaman_rabbit1.gr2 -../m2dev-client-main/assets/metin2_patch_easter1/ymir work/pc/shaman/hair/hair_11_1.gr2 -../m2dev-client-main/assets/metin2_patch_easter1/ymir work/pc2/warrior/warrior_rabbit1.gr2 -../m2dev-client-main/assets/metin2_patch_easter1/ymir work/pc2/warrior/hair/hair_11_1.gr2 -../m2dev-client-main/assets/metin2_patch_easter1/ymir work/pc2/sura/sura_rabbit1.gr2 -../m2dev-client-main/assets/metin2_patch_easter1/ymir work/pc2/sura/hair/hair_11_1.gr2 -../m2dev-client-main/assets/metin2_patch_easter1/ymir work/pc2/assassin/assassin_rabbit1.gr2 -../m2dev-client-main/assets/metin2_patch_easter1/ymir work/pc2/assassin/hair/hair_11_1.gr2 -../m2dev-client-main/assets/metin2_patch_easter1/ymir work/pc2/shaman/shaman_rabbit1.gr2 -../m2dev-client-main/assets/metin2_patch_easter1/ymir work/pc2/shaman/hair/hair_11_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_bow/34_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_bow/30_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_bow/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_bow/31_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_bow/snakeman_bow_lod_01.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_bow/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_bow/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_bow/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_bow/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_bow/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_bow/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_bow/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_bow/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_bow/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_bow/snakeman_bow.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_nipper/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_nipper/31_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_nipper/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_nipper/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_nipper/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_nipper/spider_nipper_lod_01.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_nipper/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_nipper/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_nipper/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_nipper/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_nipper/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_nipper/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_nipper/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_nipper/spider_nipper.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_tiger_boss/fire_tiger_boss_lod_01.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_tiger_boss/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_tiger_boss/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_tiger_boss/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_tiger_boss/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_tiger_boss/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_tiger_boss/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_tiger_boss/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_tiger_boss/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_tiger_boss/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_tiger_boss/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_tiger_boss/fire_tiger_boss.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/evil_eye/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/evil_eye/31_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/evil_eye/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/evil_eye/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/evil_eye/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/evil_eye/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/evil_eye/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/evil_eye/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/evil_eye/35.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/evil_eye/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/evil_eye/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/evil_eye/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/evil_eye/evil_eye.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/evil_eye/evil_eye_lod_01.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_king/34_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_king/fire_king.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_king/30_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_king/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_king/fire_king_lod_01.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_king/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_king/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_king/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_king/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_king/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_king/24.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_king/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_king/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_king/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_king/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_king/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_2/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_2/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_2/00_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_2/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_2/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_2/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_2/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_2/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_2/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_2/35.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_2/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_2/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_2/mutant_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_2/36.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_2/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_desert_turtle/giant_desert_turtle.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_desert_turtle/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_desert_turtle/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_desert_turtle/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_desert_turtle/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_desert_turtle/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_desert_turtle/24.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_desert_turtle/25.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_desert_turtle/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_desert_turtle/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_desert_turtle/35.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_desert_turtle/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_desert_turtle/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_desert_turtle/giant_desert_turtle_lod_01.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_poison/spider_poison.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_poison/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_poison/31_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_poison/spider_poison_lod_01.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_poison/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_poison/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_poison/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_poison/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_poison/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_poison/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_poison/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_poison/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_poison/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_poison/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_dragon/fire_dragon_lod_01.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_dragon/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_dragon/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_dragon/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_dragon/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_dragon/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_dragon/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_dragon/20_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_dragon/fire_dragon.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_3/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_3/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_3/00_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_3/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_3/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_3/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_3/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_3/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_3/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_3/35.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_3/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_3/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_3/mutant_03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_3/36.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_3/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_3/mutant_3.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_3/nersluck_3.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_3/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_3/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_3/00_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_3/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_3/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_3/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_3/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_3/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_3/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_3/35.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_3/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_3/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_3/36.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_3/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_1/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_1/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_1/00_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_1/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_1/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_1/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_1/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_1/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_1/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_1/35.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_1/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_1/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_1/36.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_1/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_1/golem_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_guru/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_guru/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_guru/00_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_guru/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_guru/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_guru/ent_guru.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_guru/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_guru/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_guru/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_guru/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_guru/35.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_guru/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_guru/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_guru/36.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_guru/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_redpoison/spider_redpoison.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_redpoison/spider_redpoison_lod_01.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_redpoison/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_redpoison/31_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_redpoison/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_redpoison/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_redpoison/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_redpoison/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_redpoison/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_redpoison/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_redpoison/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_redpoison/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_ghost/34_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_ghost/30_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_ghost/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_ghost/31_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_ghost/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_ghost/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_ghost/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_ghost/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_ghost/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_ghost/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_ghost/fire_ghost.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_ghost/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_ghost/35.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_ghost/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_ghost/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_ghost/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_ghost/fire_ghost_lod_01.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_red/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_red/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_red/00_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_red/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_red/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_red/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_red/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_red/24.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_red/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_red/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_red/35.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_red/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_red/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_red/36.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_red/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_red/ent_red.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_2/nersluck_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_2/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_2/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_2/00_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_2/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_2/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_2/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_2/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_2/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_2/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_2/35.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_2/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_2/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_2/36.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_2/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_elder/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_elder/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_elder/00_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_elder/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_elder/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_elder/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_elder/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_elder/24.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_elder/25.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_elder/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_elder/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_elder/35.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_elder/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_elder/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_elder/36.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_elder/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_elder/ent_elder.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/outlaw/34_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/outlaw/outlaw_lod_01.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/outlaw/30_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/outlaw/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/outlaw/31_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/outlaw/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/outlaw/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/outlaw/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/outlaw/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/outlaw/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/outlaw/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/outlaw/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/outlaw/35.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/outlaw/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/outlaw/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/outlaw/36.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/outlaw/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/outlaw/outlaw.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/outlaw/03_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_soldier/34_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_soldier/spider_soldier.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_soldier/30_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_soldier/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_soldier/31_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_soldier/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_soldier/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_soldier/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_soldier/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_soldier/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_soldier/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_soldier/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_soldier/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_soldier/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_soldier/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_soldier/spider_soldier_lod_01.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_black/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_black/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_black/00_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_black/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_black/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_black/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_black/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_black/24.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_black/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_black/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_black/35.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_black/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_black/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_black/36.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_black/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_black/ent_black.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_tiger/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_tiger/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_tiger/fire_tiger_lod_01.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_tiger/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_tiger/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_tiger/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_tiger/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_tiger/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_tiger/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_tiger/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_tiger/fire_tiger.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_tiger/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_sword/34_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_sword/snakeman_sword_lod_01.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_sword/30_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_sword/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_sword/31_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_sword/snakeman_sword.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_sword/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_sword/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_sword/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_sword/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_sword/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_sword/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_sword/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_sword/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_sword/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/snakeman_sword/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_sword/34_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_sword/30_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_sword/scorpionman_sword_lod_01.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_sword/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_sword/31_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_sword/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_sword/31_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_sword/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_sword/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_sword/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_sword/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_sword/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_sword/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_sword/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_sword/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_sword/scorpionman_sword.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_trent/ent_trent.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_trent/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_trent/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_trent/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_trent/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_trent/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_trent/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_1/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_1/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_1/00_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_1/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_1/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_1/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_1/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_1/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_1/mutant_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_1/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_1/35.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_1/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_1/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_1/36.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/mutant_1/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_young/spider_young.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_young/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_young/31_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_young/spider_young_lod_01.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_young/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_young/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_young/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_young/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_young/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_young/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_young/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_young/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_young/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_young/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fennec_fox/fennec_fox_lod_01.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fennec_fox/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fennec_fox/31_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fennec_fox/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fennec_fox/00_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fennec_fox/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fennec_fox/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fennec_fox/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fennec_fox/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fennec_fox/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fennec_fox/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fennec_fox/fennec_fox.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fennec_fox/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fennec_fox/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fennec_fox/20_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fennec_fox/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_man/34_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_man/30_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_man/fire_man_lod_01.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_man/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_man/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_man/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_man/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_man/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_man/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_man/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_man/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_man/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_man/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_man/fire_man.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/monkey/34_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/monkey/30_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/monkey/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/monkey/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/monkey/00_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/monkey/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/monkey/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/monkey/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/monkey/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/monkey/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/monkey/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/monkey/35.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/monkey/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/monkey/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/monkey/36.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/monkey/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/monkey/monkey.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_scorpion/34_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_scorpion/giant_scorpion_lod_01.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_scorpion/30_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_scorpion/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_scorpion/31_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_scorpion/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_scorpion/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_scorpion/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_scorpion/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_scorpion/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_scorpion/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_scorpion/giant_scorpion.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_scorpion/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_scorpion/35.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_scorpion/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_scorpion/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/giant_scorpion/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_bow/34_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_bow/30_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_bow/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_bow/31_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_bow/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_bow/31_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_bow/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_bow/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_bow/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_bow/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_bow/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_bow/scorpionman_bow_lod_01.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_bow/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_bow/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_bow/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/scorpionman_bow/scorpionman_bow.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/japanese_pirate/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/japanese_pirate/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/japanese_pirate/02.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/japanese_pirate/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/japanese_pirate/japanese_pirate.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/japanese_pirate/03_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/japanese_pirate/03_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_2/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_2/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_2/00_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_2/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_2/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_2/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_2/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_2/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_2/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_2/35.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_2/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_2/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_2/36.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_2/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_2/golem_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/god_monkey/34_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/god_monkey/30_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/god_monkey/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/god_monkey/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/god_monkey/00_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/god_monkey/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/god_monkey/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/god_monkey/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/god_monkey/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/god_monkey/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/god_monkey/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/god_monkey/35.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/god_monkey/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/god_monkey/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/god_monkey/36.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/god_monkey/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/god_monkey/god_monkey.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_king/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_king/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_king/spider_king_lod_01.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_king/spider_king.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_king/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_king/24.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_king/25.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_king/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_king/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_king/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_1/nersluck_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_1/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_1/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_1/00_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_1/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_1/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_1/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_1/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_1/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_1/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_1/35.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_1/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_1/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_1/36.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/nersluck_1/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_3/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_3/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_3/00_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_3/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_3/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_3/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_3/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_3/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_3/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_3/35.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_3/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_3/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_3/36.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_3/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/golem_3/golem_3.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/stone_monkey/34_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/stone_monkey/30_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/stone_monkey/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/stone_monkey/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/stone_monkey/00_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/stone_monkey/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/stone_monkey/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/stone_monkey/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/stone_monkey/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/stone_monkey/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/stone_monkey/stone_monkey.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/stone_monkey/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/stone_monkey/35.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/stone_monkey/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/stone_monkey/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/stone_monkey/36.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/stone_monkey/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_hu/ent_hu.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_hu/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_hu/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_hu/00_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_hu/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_hu/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_hu/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_hu/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_hu/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_hu/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_hu/35.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_hu/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_hu/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_hu/36.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_hu/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_huge/ent_huge.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_huge/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_huge/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_huge/00_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_huge/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_huge/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_huge/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_huge/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_huge/24.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_huge/25.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_huge/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_huge/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_huge/35.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_huge/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_huge/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_huge/36.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/ent_huge/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/gold_monkey/34_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/gold_monkey/30_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/gold_monkey/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/gold_monkey/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/gold_monkey/00_2.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/gold_monkey/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/gold_monkey/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/gold_monkey/gold_monkey.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/gold_monkey/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/gold_monkey/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/gold_monkey/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/gold_monkey/20_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/gold_monkey/35.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/gold_monkey/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/gold_monkey/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/gold_monkey/36.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/gold_monkey/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_knight/34_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_knight/30_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_knight/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_knight/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_knight/fire_knight_lod_01.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_knight/33.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_knight/32.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_knight/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_knight/30.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_knight/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_knight/20.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_knight/34.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_knight/37.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/fire_knight/fire_knight.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_queen/spider_queen.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_queen/spider_queen_lod_01.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_queen/00.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_queen/03.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_queen/00_1.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_queen/24.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_queen/31.gr2 -../m2dev-client-main/assets/monster2/ymir work/monster2/spider_queen/20.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_cheongrin_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_cheongrin_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/fishing/fishing_wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/fishing/fishing_fail.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/fishing/fishing_cancel.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/fishing/throw.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/fishing/run.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/fishing/fishing_catch.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/fishing/walk.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/fishing/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_cheongrin_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_marry_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/intro/selected.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/intro/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/intro/not_selected.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/skill/jipjung.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/skill/jeonsingonggyeok.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/skill/jeongwi.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/skill/noegeom.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/skill/gyeoksan.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/skill/daejin.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/skill/geompung.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/skill/jeonsinbangeo.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/skill/gihyeol.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/skill/samyeon.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/skill/gigongcham.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/skill/musa.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/skill/kwaegeom.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/skill/geomgyeong.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/skill/cheongeun.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/skill/palbang.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/skill/gigongsul.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/skill/gitu.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/general/damage_3.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/general/damage_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/general/damage_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/general/back_damage_flying.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/general/falling_stand.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/general/dig.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/general/back_falling_stand.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/general/dead.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/general/attack.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/general/run.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/general/damage.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/general/pick_up.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/general/wait_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/general/walk.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/general/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/general/damage_flying.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/general/attack_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_4-1_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_nahan_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_nahan_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_4-1_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_nahan_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/twohand_sword/damage_3.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/twohand_sword/combo_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/twohand_sword/combo_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/twohand_sword/damage_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/twohand_sword/combo_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/twohand_sword/damage_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/twohand_sword/combo_04.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/twohand_sword/combo_05.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/twohand_sword/combo_07.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/twohand_sword/combo_06.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/twohand_sword/run.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/twohand_sword/rampage_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/twohand_sword/damage.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/twohand_sword/rampage_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/twohand_sword/rampage_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/twohand_sword/rampage.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/twohand_sword/pick_up.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/twohand_sword/wait_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/twohand_sword/walk.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/twohand_sword/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/twohand_sword/change_weapon.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/wedding/walk.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/wedding/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_4-1_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_saja_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_lord_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_saja_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/horse_twohand_sword/combo_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/horse_twohand_sword/combo_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/horse_twohand_sword/combo_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/horse_twohand_sword/skill_wildattack.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/horse_twohand_sword/skill_splash.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_lord_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_novice.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_lord_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_saja_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_novice_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/joy.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/dance_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/french_kiss_with_shaman.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/sad.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/dance_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/dance_3.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/kiss_with_sura.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/kiss_with_assassin.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/dance_4.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/slap_hurt.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/dance_5.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/banter.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/congratulation.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/shy.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/attractive.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/cheers_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/forgive.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/cheers_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/french_kiss_with_warrior.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/french_kiss_with_assassin.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/angry.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/cheerup.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/french_kiss_with_sura.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/clap.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/slap_hit.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/kiss_with_warrior.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/action/kiss_with_shaman.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_novice_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_novice_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_yongsin.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_saja.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_yongsin_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_4-1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_marry_01_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_cheongrin.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_marry_01_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_yongsin_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_yongsin_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_marry_01_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_nahan.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/onehand_sword/damage_3.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/onehand_sword/combo_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/onehand_sword/combo_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/onehand_sword/damage_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/onehand_sword/combo_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/onehand_sword/damage_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/onehand_sword/combo_04.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/onehand_sword/combo_05.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/onehand_sword/combo_07.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/onehand_sword/combo_06.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/onehand_sword/attack.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/onehand_sword/run.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/onehand_sword/rampage_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/onehand_sword/damage.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/onehand_sword/rampage_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/onehand_sword/rampage_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/onehand_sword/rampage.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/onehand_sword/pick_up.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/onehand_sword/wait_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/onehand_sword/walk.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/onehand_sword/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/onehand_sword/change_weapon.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/onehand_sword/attack_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/onehand_sword/attack_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/horse/stop.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/horse/skill_charge.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/horse/dead.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/horse/run.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/horse/wait_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/horse/damage.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/horse/wait_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/horse/walk.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/horse/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/horse_onehand_sword/combo_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/horse_onehand_sword/combo_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/horse_onehand_sword/combo_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/horse_onehand_sword/skill_wildattack.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/horse_onehand_sword/skill_splash.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/hair/hair_1_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/hair/hair_3_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/hair/hair_4_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/hair/hair_2_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/warrior/warrior_lord.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/fishing/fishing_wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/fishing/fishing_fail.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/fishing/fishing_cancel.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/fishing/throw.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/fishing/run.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/fishing/fishing_catch.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/fishing/walk.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/fishing/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_novice.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_4-1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/intro/selected.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/intro/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/intro/not_selected.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/skill/muyeong.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/skill/hyeolhwan.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/skill/jumagap.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/skill/yonggwon.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/skill/geongon.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/skill/gwigeom.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/skill/swaeryeong.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/skill/jumageom.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/skill/hyeolma.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/skill/geompung.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/skill/geomhwan.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/skill/johon.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/skill/pabeop.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/skill/ihyeol.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/skill/heukma.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/skill/hwayeom.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/skill/maryeong.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_saryeong.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/general/damage_3.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/general/damage_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/general/damage_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/general/back_damage_flying.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/general/falling_stand.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/general/dig.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/general/back_falling_stand.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/general/dead.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/general/attack.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/general/run.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/general/damage.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/general/pick_up.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/general/walk.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/general/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/general/change_weapon.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/general/run10.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/general/damage_flying.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/general/attack_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_unra_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_maryeong.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_unra_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_unra_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/wedding/walk.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/wedding/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_marry_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_unra.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_saryeong_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_maryeong_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_maryeong_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_saryeong_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_lord.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/joy.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/dance_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/french_kiss_with_shaman.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/sad.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/dance_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/dance_3.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/kiss_with_sura.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/kiss_with_assassin.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/dance_4.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/slap_hurt.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/dance_5.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/banter.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/congratulation.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/shy.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/attractive.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/cheers_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/forgive.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/cheers_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/french_kiss_with_warrior.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/french_kiss_with_assassin.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/angry.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/cheerup.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/french_kiss_with_sura.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/clap.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/slap_hit.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/kiss_with_warrior.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/action/kiss_with_shaman.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_saryeong_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_maryeong_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_novice_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_marry_01_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_novice_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_jinhon.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_marry_01_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_marry_01_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_novice_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/onehand_sword/damage_3.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/onehand_sword/combo_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/onehand_sword/combo_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/onehand_sword/damage_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/onehand_sword/combo_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/onehand_sword/damage_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/onehand_sword/combo_04.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/onehand_sword/combo_05.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/onehand_sword/combo_07.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/onehand_sword/combo_06.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/onehand_sword/run.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/onehand_sword/rampage_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/onehand_sword/damage.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/onehand_sword/rampage_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/onehand_sword/rampage_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/onehand_sword/rampage.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/onehand_sword/pick_up.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/onehand_sword/walk.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/onehand_sword/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/horse/stop.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/horse/skill_charge.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/horse/dead.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/horse/run.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/horse/wait_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/horse/damage.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/horse/wait_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/horse/walk.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/horse/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/horse/skill_splash.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_4-1_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/horse_onehand_sword/combo_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/horse_onehand_sword/combo_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/horse_onehand_sword/combo_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/horse_onehand_sword/skill_wildattack.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_jinhon_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_jinhon_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_lord_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_4-1_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/hair/hair_1_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/hair/hair_3_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/hair/hair_4_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/hair/hair_2_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_lord_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_jinhon_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_lord_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/sura/sura_4-1_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_tanma_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_tanma_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/dualhand_sword/damage_3.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/dualhand_sword/combo_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/dualhand_sword/combo_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/dualhand_sword/damage_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/dualhand_sword/combo_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/dualhand_sword/damage_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/dualhand_sword/combo_04.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/dualhand_sword/combo_05.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/dualhand_sword/combo_07.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/dualhand_sword/combo_06.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/dualhand_sword/run.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/dualhand_sword/rampage_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/dualhand_sword/damage.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/dualhand_sword/rampage_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/dualhand_sword/rampage_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/dualhand_sword/rampage.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/dualhand_sword/pick_up.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/dualhand_sword/wait_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/dualhand_sword/walk.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/dualhand_sword/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/dualhand_sword/combo_08.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/dualhand_sword/change_weapon.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/fishing/fishing_wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/fishing/fishing_fail.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/fishing/fishing_cancel.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/fishing/throw.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/fishing/run.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/fishing/fishing_catch.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/fishing/walk.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/fishing/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_tanma_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_biyeong_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_lord_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_biyeong_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/intro/selected.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/intro/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/intro/not_selected.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/skill/seomgwang.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/skill/seomjeon.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/skill/amseup.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/skill/eunhyeong.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/skill/charyun.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/skill/kwaegeom.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/skill/gyeonggong.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/skill/make_trap.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/skill/cheonryong.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/skill/shoot.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/skill/poison_cloud.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/skill/gungsin.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/skill/gwangyeok.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_biyeong_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_lord_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/bow/damage_3.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/bow/damage_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/bow/damage_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/bow/attack.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/bow/run.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/bow/damage.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/bow/pick_up.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/bow/wait_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/bow/walk.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/bow/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/bow/change_weapon.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/bow/attack_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/bow/attack_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_lord_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/general/damage_3.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/general/damage_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/general/damage_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/general/back_damage_flying.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/general/falling_stand.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/general/dig.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/general/back_falling_stand.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/general/dead.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/general/attack.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/general/run.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/general/damage.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/general/pick_up.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/general/wait_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/general/walk.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/general/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/general/damage_flying.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/general/attack_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_lord.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_bihyeon.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_yonga.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/wedding/walk.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/wedding/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_novice.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_yonga_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_yonga_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_yonga_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_4-1_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_4-1_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/joy.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/dance_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/french_kiss_with_shaman.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/sad.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/dance_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/dance_3.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/kiss_with_sura.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/kiss_with_assassin.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/dance_4.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/slap_hurt.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/dance_5.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/banter.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/congratulation.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/shy.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/attractive.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/cheers_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/forgive.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/cheers_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/french_kiss_with_warrior.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/french_kiss_with_assassin.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/angry.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/cheerup.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/french_kiss_with_sura.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/clap.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/slap_hit.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/kiss_with_warrior.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/action/kiss_with_shaman.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_4-1_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_marry_01_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_bihyeon_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_4-1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_bihyeon_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_bihyeon_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_marry_01_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse_bow/dead.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse_bow/attack.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse_bow/run.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse_bow/wait_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse_bow/damage.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse_bow/wait_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse_bow/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse_bow/skill_splash.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_marry_01_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_marry_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_biyeong.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse_dualhand_sword/combo_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse_dualhand_sword/combo_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse_dualhand_sword/combo_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse_dualhand_sword/skill_wildattack.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse_dualhand_sword/skill_splash.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/onehand_sword/damage_3.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/onehand_sword/combo_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/onehand_sword/combo_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/onehand_sword/damage_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/onehand_sword/combo_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/onehand_sword/damage_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/onehand_sword/combo_04.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/onehand_sword/combo_05.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/onehand_sword/combo_07.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/onehand_sword/combo_06.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/onehand_sword/run.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/onehand_sword/rampage_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/onehand_sword/damage.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/onehand_sword/rampage_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/onehand_sword/rampage_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/onehand_sword/rampage.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/onehand_sword/pick_up.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/onehand_sword/wait_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/onehand_sword/walk.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/onehand_sword/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/onehand_sword/change_weapon.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse/stop.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse/skill_charge.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse/dead.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse/run.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse/wait_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse/damage.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse/wait_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse/walk.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse_onehand_sword/combo_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse_onehand_sword/combo_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse_onehand_sword/combo_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse_onehand_sword/skill_wildattack.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/horse_onehand_sword/skill_splash.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_tanma.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_novice_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/hair/hair_1_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/hair/hair_3_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/hair/hair_4_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/hair/hair_2_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_novice_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/assassin/assassin_novice_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/joy.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_novice_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_novice.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_novice_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/sad.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fishing/fishing_wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fishing/fishing_fail.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fishing/fishing_cancel.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fishing/throw.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fishing/run.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fishing/fishing_catch.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fishing/walk.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fishing/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_novice_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_lord.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/intro/selected.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/intro/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/intro/not_selected.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/skill/me.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/skill/yongsin.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/skill/buhwal.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/skill/target.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/skill/byeorak.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/skill/noejeon.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/skill/shoot.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/general/damage_3.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/general/damage_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/general/damage_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/general/back_damage_flying.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/general/_run.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/general/falling_stand.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/general/dig.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/general/back_falling_stand.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/general/dead.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/general/attack.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/general/run.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/general/damage.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/general/pick_up.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/general/wait_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/general/walk.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/general/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/general/damage_flying.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/general/attack_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/horse_fan/combo_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/horse_fan/combo_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/horse_fan/combo_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/horse_fan/skill_wildattack.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_miyeom_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/banter.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_miyeom_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/wedding/walk.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/wedding/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_miyeom_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/congratulation.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_lord_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_cheongnang.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shy.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/attractive.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_lord_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_lord_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_marry_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_marry_01_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_marry_01_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/forgive.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_4-1_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_miyeom.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/joy.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/dance_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/french_kiss_with_shaman.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/sad.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/dance_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/dance_3.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/kiss_with_sura.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/kiss_with_assassin.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/dance_4.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/slap_hurt.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/dance_5.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/banter.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/congratulation.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/shy.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/attractive.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/cheers_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/forgive.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/cheers_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/french_kiss_with_warrior.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/french_kiss_with_assassin.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/angry.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/cheerup.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/french_kiss_with_sura.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/clap.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/slap_hit.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/kiss_with_warrior.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/action/kiss_with_shaman.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_4-1_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_marry_01_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_4-1_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/horse_bell/combo_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/horse_bell/combo_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/horse_bell/combo_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/horse_bell/skill_wildattack.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/angry.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/cheerup.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_4-1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/bell/damage_3.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/bell/combo_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/bell/combo_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/bell/damage_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/bell/combo_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/bell/damage_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/bell/combo_04.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/bell/combo_05.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/bell/combo_07.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/bell/combo_06.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/bell/run.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/bell/rampage_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/bell/damage.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/bell/rampage_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/bell/rampage_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/bell/rampage.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/bell/pick_up.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/bell/walk.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/bell/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/bell/change_weapon.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_cheonryun_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fan/damage_3.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fan/combo_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fan/combo_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fan/damage_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fan/combo_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fan/damage_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fan/combo_04.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fan/combo_05.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fan/combo_07.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fan/combo_06.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fan/run.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fan/rampage_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fan/damage.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fan/rampage_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fan/rampage_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fan/rampage.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fan/pick_up.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fan/walk.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fan/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/fan/change_weapon.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_cheongnang_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_cheongnang_lod_03.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_cheonryun_lod_02.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_bongsin.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_cheongnang_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_cheonryun_lod_01.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/shaman_cheonryun.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/horse/stop.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/horse/skill_charge.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/horse/dead.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/horse/run.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/horse/wait_2.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/horse/damage.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/horse/wait_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/horse/walk.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/horse/wait.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/horse/skill_splash.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/hair/hair_1_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/hair/hair_3_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/hair/hair_4_1.gr2 -../m2dev-client-main/assets/pc2/ymir work/pc2/shaman/hair/hair_2_1.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/cliff_wall.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/steel_bridge_body_s.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/horn04.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/flame_bossroom_floor.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/flame_dg_ingate.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/horn01.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/flame_bossroom.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/horn02.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/flame_dg_flage00.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/horn03.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/flame_arch.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/chain.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/cliff_wall_up.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/horn01_1.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/steel_pillar.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/steel_bridge_body.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/stone03.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/rock_pillar_06.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/dungeongate.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/stone02.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/rock_pillar_05.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/flame_fence_01.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/flame_fence_00.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/stone01.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/steel_bridge_body_up.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/rock_pillar_00.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/rock_pillar_01.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/cliff_side.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/steel_bridge_pillar.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/flame_door_pillar.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/rock_pillar_03.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/flame_fence_pillar.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/zone/dungeon/flame_dungeon/rock_pillar_02.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/npc2/flame_door_npc/flame_door_npc.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/npc2/flame_bridge_block_chain/bridge_block_chain.gr2 -../m2dev-client-main/assets/metin2_patch_flame_dungeon/ymir work/npc2/flame_dungeon_npc/flame_npc.gr2 -../m2dev-client-main/assets/metin2_patch_snow_dungeon/ymir work/zone/dungeon/snow_dungeon/dungeon_c3.gr2 -../m2dev-client-main/assets/metin2_patch_snow_dungeon/ymir work/zone/dungeon/snow_dungeon/dungeon_c2.gr2 -../m2dev-client-main/assets/metin2_patch_snow_dungeon/ymir work/zone/dungeon/snow_dungeon/dungeon_c1.gr2 -../m2dev-client-main/assets/metin2_patch_snow_dungeon/ymir work/zone/dungeon/snow_dungeon/dungeon_b1.gr2 -../m2dev-client-main/assets/metin2_patch_snow_dungeon/ymir work/zone/dungeon/snow_dungeon/dungeon_b2.gr2 -../m2dev-client-main/assets/metin2_patch_snow_dungeon/ymir work/zone/dungeon/snow_dungeon/snow_bossroom.gr2 -../m2dev-client-main/assets/metin2_patch_snow_dungeon/ymir work/zone/dungeon/snow_dungeon/dungeon_b3.gr2 -../m2dev-client-main/assets/metin2_patch_snow_dungeon/ymir work/zone/dungeon/snow_dungeon/icicle_up_05.gr2 -../m2dev-client-main/assets/metin2_patch_snow_dungeon/ymir work/zone/dungeon/snow_dungeon/icicle_up_01.gr2 -../m2dev-client-main/assets/metin2_patch_snow_dungeon/ymir work/zone/dungeon/snow_dungeon/dungeon_a2.gr2 -../m2dev-client-main/assets/metin2_patch_snow_dungeon/ymir work/zone/dungeon/snow_dungeon/ice_pillar_s01.gr2 -../m2dev-client-main/assets/metin2_patch_snow_dungeon/ymir work/zone/dungeon/snow_dungeon/ice_pillar_s00.gr2 -../m2dev-client-main/assets/metin2_patch_snow_dungeon/ymir work/zone/dungeon/snow_dungeon/dungeon_a3.gr2 -../m2dev-client-main/assets/metin2_patch_snow_dungeon/ymir work/zone/dungeon/snow_dungeon/dungeon_a1.gr2 -../m2dev-client-main/assets/metin2_patch_snow_dungeon/ymir work/zone/dungeon/snow_dungeon/ice_pillar_s05.gr2 -../m2dev-client-main/assets/metin2_patch_snow_dungeon/ymir work/npc2/ice_lionstone/ice_lionstone.gr2 -../m2dev-client-main/assets/metin2_patch_snow_dungeon/ymir work/npc2/ice_keybox/ice_keybox.gr2 -../m2dev-client-main/assets/metin2_patch_snow_dungeon/ymir work/npc2/ice_stonepillar/front_dead.gr2 -../m2dev-client-main/assets/metin2_patch_snow_dungeon/ymir work/npc2/ice_stonepillar/wait.gr2 -../m2dev-client-main/assets/metin2_patch_snow_dungeon/ymir work/npc2/ice_stonepillar/ice_stonepillar.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/gaint_fence_re_02.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/fortms_build_normal_00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/ships_broken_piece01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_jar_white_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_rock00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_cagobox00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/ships_broken_piece00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/fortms_build_normal_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/fortms_watchtower.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/gaint_fence_re_03.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_barricade_bar00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/fortms_fence_pillar.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/fortms_firesignal.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/gaint_fence_re_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/fortms_build_house00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/weapon_bowcart.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_fire_stand_bowl_00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_target javelin_00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/ships_broken_piece03.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/fortms_build_normal_02.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/obj_tent01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/obj_mtthund_thorn01a.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/fortms_fence_body01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/dawnmist_statue00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/fortms_build_office.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_jar_hole.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/dawnmist_gate_s.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/fortms_fence_body02.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/fortms_pier.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/ships_broken_piece04.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/donkey_bag00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thunder_ruins_pillar00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/cart_shopbox00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_barricade_02.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/fortms_pier_pillarset.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/obj_mtthund_thorn01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/ships_brokenbody00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/cart_shopbox01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thunder_ruins_bridge.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/fotrms_gate.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_barricade_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/obj_mtthund_thorn02.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/obj_mtthund_thorn03.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_barricade_00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_tail02.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_neck00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_tail01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_tail00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_deco02.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_deco01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_turtle_arm00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_turtle_all00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_turtle_all01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_deco00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_lump01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_vertebra00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_lump00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_lump02.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_lump03.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_piece_ver01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_turtle_vertebra00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_piece_ver00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_lump00a.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_piece_ver02.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_piece_ver03.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_piece_ver04.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_piece_rib01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_piece_rib00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_piece_rib02.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_piece_rib03.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_arm01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_turtle_head00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_rib_up01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_rib_up00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_arm00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_turtle_shell00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_head00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/bone/bone_whale_head01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_jar_cap00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/dawnmist_wallpillar00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_jar_cap01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_woodhut_break03.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/gaint_builda_09.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/gaint_builda_08.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_woodhut_break02.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_woodhut_break00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_woodhut_break01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_woodhut_hake00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_woodhut_00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_redthief_build_08.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_woodhut_break04.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_redthief_build_09.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_woodhut_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/gaint_gate_02.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/gaint_fence04.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/gaint_fence05.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_woodhut_02.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/gaint_gate_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/gaint_buildb_04.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/gaint_buildb_05.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/gaint_buildb_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_redthief_gate_00a.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_woodhut_ladder00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/gaint_pillar00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/gaint_buildb_02.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/gaint_buildb_03.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_woodhut_fence01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_redthief_deco_00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_manticore_boss00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_redthief_deco_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_woodhut_fence00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_redthief_gate_00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_manticore_gate02.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_redthief_gate_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_manticore_02.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_manticore_00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_redthief_gate_03.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_manticore_gate00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_manticore_gate01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_redthief_gate_02.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_redthief_build_07.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/gaint_builda_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_redthief_fence_02.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_redthief_build_06.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_redthief_fence_00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/gaint_builda_03.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/gaint_builda_02.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_redthief_build_05.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_redthief_fence_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_redthief_build_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/gaint_builda_06.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_manticore_obj00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/gaint_builda_07.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_redthief_build_00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_redthief_build_02.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/gaint_builda_11.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/gaint_builda_05.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/gaint_builda_04.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/gaint_builda_10.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/camp/camp_redthief_build_03.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_campfire_stone.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/dawnmist_floor00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/stone_steps00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/fortms_box_smithy00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/fortms_ship00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/obj_mtthund_thorn04.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/obj_mtthund_thorn05.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/fortms_box_smithy01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_market tent_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/dawnmist_floor01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/obj_mtthund_thorn05a.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_hake_06.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_barricade_cross00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thunder_ruins_gate00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/triton_tent01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/dawnmist_wall00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/obj_mtthund_thorn05b.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_hake_05.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/dawnmist_stonetotem.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_cagobox_long00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_hake_04.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/obj_mtthund_thorn05c.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/dawnmist_wall01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_hake_00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/triton_tent_re02.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/fortms_ship01_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_hake_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/obj_mtthund_thorn05d.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/things_woodboat_00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_hake_03.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_bag_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/triton_tent_re01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/obj_mtthund_thorn03_a.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/cart_shop.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_bag_00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_hake_02.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/dawnmist_step00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/fortms_pier_pillar02.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/triton_tent_01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/fortms_pier_pillar03.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_hake_roll03.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/dawnmist_step01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/fortms_build_well.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/obj_mtthund_thorn03a.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/dawnmist_gate.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_hake_roll01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/fortms_pier_pillar01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/triton_tent_03.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/fortms_pier_pillar00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/triton_tent_02.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/dawnmist_wallpillar.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/ships_brokenup00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/ships_broken00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/fortms_light.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/fortms_build_smithy.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thunder_ruins_wall01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_cagoboxset00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/dawnmist_statue.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/cart_shopbox.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/dawnmist_light.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thunder_ruins_wall02.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/thing_cagoboxset01.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/zone/devils_dragon_island/fortms_build_totem.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/npc2/npc_fence/npc_fence00.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/npc2/donkey/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/npc2/donkey/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/npc2/donkey/donkey.gr2 -../m2dev-client-main/assets/metin2_patch_dragon_rock/ymir work/npc2/donkey/wait.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/warrior/warrior_halloween2_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/warrior/warrior_halloween2_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/warrior/warrior_halloween2.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/warrior/warrior_halloween2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/warrior/hair/hair_38_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/warrior/hair/hair_36_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/warrior/hair/hair_34_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/warrior/hair/hair_37_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/sura/sura_halloween2.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/sura/sura_halloween2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/sura/sura_halloween2_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/sura/sura_halloween2_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/sura/hair/hair_38_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/sura/hair/hair_36_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/sura/hair/hair_34_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/sura/hair/hair_37_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/assassin/assassin_halloween2.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/assassin/assassin_halloween2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/assassin/assassin_halloween2_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/assassin/assassin_halloween2_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/assassin/hair/hair_38_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/assassin/hair/hair_36_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/assassin/hair/hair_34_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/assassin/hair/hair_37_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/shaman/shaman_halloween2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/shaman/shaman_halloween2_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/shaman/shaman_halloween2_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/shaman/shaman_halloween2.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/shaman/hair/hair_38_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/shaman/hair/hair_36_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/shaman/hair/hair_34_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc/shaman/hair/hair_37_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/warrior/warrior_halloween2_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/warrior/warrior_halloween2_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/warrior/warrior_halloween2.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/warrior/warrior_halloween2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/warrior/hair/hair_38_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/warrior/hair/hair_36_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/warrior/hair/hair_34_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/warrior/hair/hair_37_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/sura/sura_halloween2.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/sura/sura_halloween2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/sura/sura_halloween2_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/sura/sura_halloween2_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/sura/hair/hair_38_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/sura/hair/hair_36_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/sura/hair/hair_34_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/sura/hair/hair_37_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/assassin/assassin_halloween2.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/assassin/assassin_halloween2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/assassin/assassin_halloween2_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/assassin/assassin_halloween2_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/assassin/hair/hair_38_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/assassin/hair/hair_36_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/assassin/hair/hair_34_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/assassin/hair/hair_37_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/shaman/shaman_halloween2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/shaman/shaman_halloween2_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/shaman/shaman_halloween2_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/shaman/shaman_halloween2.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/shaman/hair/hair_38_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/shaman/hair/hair_36_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/shaman/hair/hair_34_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/pc2/shaman/hair/hair_37_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc2/halloween_bonedog1/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc2/halloween_bonedog1/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc2/halloween_bonedog1/run.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc2/halloween_bonedog1/halloween_bonedog1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc2/halloween_bonedog1/walk.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc2/halloween_bonedog1/wait.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc2/redthief2_officer_young1/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc2/redthief2_officer_young1/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc2/redthief2_officer_young1/redthief2_officer_young1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc2/redthief2_officer_young1/run.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc2/redthief2_officer_young1/walk.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc2/redthief2_officer_young1/wait.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc/dinosaur/dinosaur_2_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc/dinosaur/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc/dinosaur/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc/dinosaur/dead.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc/dinosaur/combo_attack.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc/dinosaur/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc/dinosaur/run.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc/dinosaur/dinosaur_3_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc/dinosaur/walk.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc/dinosaur/skill2.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc/dinosaur/dinosaur_1.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc/dinosaur/dinosaur_3.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc/dinosaur/wait.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc/dinosaur/dinosaur_2.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc/dinosaur/dinosaur_1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc/unicorn/unicorn.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc/unicorn/unicorn_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc/unicorn/unicorn_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_pet1/ymir work/npc/unicorn/unicorn_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_costume_soccer/ymir work/pc/warrior/hair/hair_24_1.gr2 -../m2dev-client-main/assets/metin2_patch_costume_soccer/ymir work/pc/sura/hair/hair_24_1.gr2 -../m2dev-client-main/assets/metin2_patch_costume_soccer/ymir work/pc/assassin/hair/hair_24_1.gr2 -../m2dev-client-main/assets/metin2_patch_costume_soccer/ymir work/pc/shaman/hair/hair_24_1.gr2 -../m2dev-client-main/assets/metin2_patch_costume_soccer/ymir work/pc2/warrior/hair/hair_24_1.gr2 -../m2dev-client-main/assets/metin2_patch_costume_soccer/ymir work/pc2/sura/hair/hair_24_1.gr2 -../m2dev-client-main/assets/metin2_patch_costume_soccer/ymir work/pc2/assassin/hair/hair_24_1.gr2 -../m2dev-client-main/assets/metin2_patch_costume_soccer/ymir work/pc2/shaman/hair/hair_24_1.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/05110.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00040.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/01160.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/04030.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/01000.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/05070.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00120.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/02050.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/07100.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/03170.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/03010.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00280.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/02130.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/07060.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00080.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/03210.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/02090.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00240.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/buke.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00250.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/02080.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/04000_1.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/03200.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00090.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/02120.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/07070.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00290.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/03000.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/03160.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/02040.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/07110.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/05060.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00130.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/01010.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/01170.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/04020.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/05100.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00050.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/07200.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00180.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00220.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/02190.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00020.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/01100.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/01060.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/05010.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00140.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/02030.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/07160.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/03110.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/03070.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/02150.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/07000.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/02140.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/07010.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/03060.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/03100.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/02020.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/07170.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/05000.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00150.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/01070.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/01110.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/04040.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00030.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/02180.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00230.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00190.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/03090.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00200.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/07180.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/01080.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/07020.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/02170.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/03050.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/03130.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/07140.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/02010.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00160.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/05030.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/01040.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/01120.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/05150.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00010.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/05140.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/01130.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/01050.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00170.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/05020.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/07150.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/02000.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/03120.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/03040.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/07030.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/02160.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/01090.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/04010_1.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/07190.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00210.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/03080.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/07040.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/02110.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/03030.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/03150.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/07120.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/02070.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00100.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/05050.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/01020.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/04010.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/01140.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00060.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/05130.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/07080.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00260.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/03190.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00300.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/05090.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/01180.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/03220.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/05080.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/03180.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00270.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/07090.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00070.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/05120.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/04000.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/01150.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/01030.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/00110.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/05040.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/07130.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/02060.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/03140.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/03020.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/07050.gr2 -../m2dev-client-main/assets/item/ymir work/item/weapon/02100.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/gold_nugget_3.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/gold_nugget_2.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/youngston_search.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/gold_nugget_1.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/q_box.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/boss_box.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/socks.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/medicine_y.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/god_herb.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/easter_egg1.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/fishing_rod.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/item_box1.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/silver_nugget_1.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/medicine_r.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/money.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/digger_2.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/silver_nugget_2.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/digger_1.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/medicine_g.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/silver_nugget_3.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/medicine_b.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/medicine_w.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/medicine_v.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/item_bag.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/basket2.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/jewellery_box.gr2 -../m2dev-client-main/assets/item/ymir work/item/etc/basket1.gr2 -../m2dev-client-main/assets/season1/season1/pc/warrior/warrior_4-1_lod_03.gr2 -../m2dev-client-main/assets/season1/season1/pc/warrior/warrior_4-1_lod_02.gr2 -../m2dev-client-main/assets/season1/season1/pc/warrior/warrior_4-1_lod_01.gr2 -../m2dev-client-main/assets/season1/season1/pc/warrior/warrior_4-1.gr2 -../m2dev-client-main/assets/season1/season1/pc/warrior/warrior_lord.gr2 -../m2dev-client-main/assets/season1/season1/pc/sura/sura_4-1.gr2 -../m2dev-client-main/assets/season1/season1/pc/sura/sura_lord.gr2 -../m2dev-client-main/assets/season1/season1/pc/sura/sura_4-1_lod_03.gr2 -../m2dev-client-main/assets/season1/season1/pc/sura/sura_4-1_lod_02.gr2 -../m2dev-client-main/assets/season1/season1/pc/sura/sura_4-1_lod_01.gr2 -../m2dev-client-main/assets/season1/season1/pc/assassin/assassin.gr2 -../m2dev-client-main/assets/season1/season1/pc/assassin/assassin_lord.gr2 -../m2dev-client-main/assets/season1/season1/pc/assassin/assassin_4-1_lod_03.gr2 -../m2dev-client-main/assets/season1/season1/pc/assassin/assassin_4-1_lod_02.gr2 -../m2dev-client-main/assets/season1/season1/pc/assassin/assassin_4-1_lod_01.gr2 -../m2dev-client-main/assets/season1/season1/pc/assassin/assassin_4-1.gr2 -../m2dev-client-main/assets/season1/season1/pc/shaman/shaman_lord.gr2 -../m2dev-client-main/assets/season1/season1/pc/shaman/shaman_4-1_lod_01.gr2 -../m2dev-client-main/assets/season1/season1/pc/shaman/shaman_4-1_lod_03.gr2 -../m2dev-client-main/assets/season1/season1/pc/shaman/shaman_4-1_lod_02.gr2 -../m2dev-client-main/assets/season1/season1/pc/shaman/shaman_4-1.gr2 -../m2dev-client-main/assets/season1/season1/npc/visamun/stand01.gr2 -../m2dev-client-main/assets/season1/season1/npc/visamun/visamun_lod_01_backup.gr2 -../m2dev-client-main/assets/season1/season1/npc/visamun/stand00.gr2 -../m2dev-client-main/assets/season1/season1/npc/visamun/visamun.gr2 -../m2dev-client-main/assets/season1/season1/npc/sinsu_guard_spear/sinsu_patrol_spear.gr2 -../m2dev-client-main/assets/season1/season1/npc/sinsu_guard_spear/sinsu_patrol_spear_lod_03.gr2 -../m2dev-client-main/assets/season1/season1/npc/sinsu_guard_spear/sinsu_patrol_spear_lod_02.gr2 -../m2dev-client-main/assets/season1/season1/npc/sinsu_guard_spear/sinsu_patrol_spear_lod_01.gr2 -../m2dev-client-main/assets/season1/season1/npc/cheonjo_guard_spear/cheonjo_patrol_spear_lod_02.gr2 -../m2dev-client-main/assets/season1/season1/npc/cheonjo_guard_spear/cheonjo_patrol_spear_lod_03.gr2 -../m2dev-client-main/assets/season1/season1/npc/cheonjo_guard_spear/cheonjo_patrol_spear_lod_01.gr2 -../m2dev-client-main/assets/season1/season1/npc/cheonjo_guard_spear/cheonjo_patrol_spear.gr2 -../m2dev-client-main/assets/season1/season1/npc/moonstone/moonstone.gr2 -../m2dev-client-main/assets/season1/season1/npc/handaup/handaup.gr2 -../m2dev-client-main/assets/season1/season1/npc/handaup/die.gr2 -../m2dev-client-main/assets/season1/season1/npc/handaup/handaup_lod_01_backup.gr2 -../m2dev-client-main/assets/season1/season1/npc/handaup/run.gr2 -../m2dev-client-main/assets/season1/season1/npc/handaup/walk.gr2 -../m2dev-client-main/assets/season1/season1/npc/handaup/wait.gr2 -../m2dev-client-main/assets/season1/season1/npc/visal/visalstand01.gr2 -../m2dev-client-main/assets/season1/season1/npc/visal/visalstand00.gr2 -../m2dev-client-main/assets/season1/season1/npc/visal/visal.gr2 -../m2dev-client-main/assets/season1/season1/npc/cheonjo_guard_bow/cheonjo_patrol_bow.gr2 -../m2dev-client-main/assets/season1/season1/npc/cheonjo_guard_bow/cheonjo_patrol_bow_lod_01.gr2 -../m2dev-client-main/assets/season1/season1/npc/cheonjo_guard_bow/cheonjo_patrol_bow_lod_03.gr2 -../m2dev-client-main/assets/season1/season1/npc/cheonjo_guard_bow/cheonjo_patrol_bow_lod_02.gr2 -../m2dev-client-main/assets/season1/season1/npc/nnflower/nnflower.gr2 -../m2dev-client-main/assets/season1/season1/npc/waterstone/waterstone.gr2 -../m2dev-client-main/assets/season1/season1/npc/samahi/stand01.gr2 -../m2dev-client-main/assets/season1/season1/npc/samahi/stand00.gr2 -../m2dev-client-main/assets/season1/season1/npc/samahi/samahi.gr2 -../m2dev-client-main/assets/season1/season1/npc/samahi/samahi_lod_01_backup.gr2 -../m2dev-client-main/assets/season1/season1/npc/mailbox/mailbox.gr2 -../m2dev-client-main/assets/season1/season1/npc/keyholestone/keyholestone.gr2 -../m2dev-client-main/assets/season1/season1/npc/sinsu_guard_bow/sinsu_patrol_bow_lod_01.gr2 -../m2dev-client-main/assets/season1/season1/npc/sinsu_guard_bow/sinsu_patrol_bow_lod_03.gr2 -../m2dev-client-main/assets/season1/season1/npc/sinsu_guard_bow/sinsu_patrol_bow_lod_02.gr2 -../m2dev-client-main/assets/season1/season1/npc/sinsu_guard_bow/sinsu_patrol_bow.gr2 -../m2dev-client-main/assets/season1/season1/npc/steelstone/steelstone.gr2 -../m2dev-client-main/assets/season1/season1/npc/jinno_guard_spear/jinno_patrol_spear.gr2 -../m2dev-client-main/assets/season1/season1/npc/jinno_guard_spear/jinno_patrol_spear_lod_01.gr2 -../m2dev-client-main/assets/season1/season1/npc/jinno_guard_spear/jinno_patrol_spear_lod_03.gr2 -../m2dev-client-main/assets/season1/season1/npc/jinno_guard_spear/jinno_patrol_spear_lod_02.gr2 -../m2dev-client-main/assets/season1/season1/npc/signal_fire/signalfire.gr2 -../m2dev-client-main/assets/season1/season1/npc/signal_fire/signalfire_ani.gr2 -../m2dev-client-main/assets/season1/season1/npc/firestone/firestone.gr2 -../m2dev-client-main/assets/season1/season1/npc/ayuka/stand01.gr2 -../m2dev-client-main/assets/season1/season1/npc/ayuka/stand00.gr2 -../m2dev-client-main/assets/season1/season1/npc/ayuka/ayuka_lod_01_backup.gr2 -../m2dev-client-main/assets/season1/season1/npc/ayuka/ayuka.gr2 -../m2dev-client-main/assets/season1/season1/npc/mirinae_brother/mirinae_brother_lod_01_backup.gr2 -../m2dev-client-main/assets/season1/season1/npc/mirinae_brother/mirinae_brother.gr2 -../m2dev-client-main/assets/season1/season1/npc/jinno_guard_bow/jinno_patrol_bow.gr2 -../m2dev-client-main/assets/season1/season1/npc/jinno_guard_bow/jinno_patrol_bow_lod_02.gr2 -../m2dev-client-main/assets/season1/season1/npc/jinno_guard_bow/jinno_patrol_bow_lod_03.gr2 -../m2dev-client-main/assets/season1/season1/npc/jinno_guard_bow/jinno_patrol_bow_lod_01.gr2 -../m2dev-client-main/assets/season1/season1/npc/sinseon/stand00.gr2 -../m2dev-client-main/assets/season1/season1/npc/sinseon/sinsen.gr2 -../m2dev-client-main/assets/season1/season1/npc/sinseon/sinsen_lod_01_backup.gr2 -../m2dev-client-main/assets/season1/season1/npc/sinseon/sinseonstand00.gr2 -../m2dev-client-main/assets/season1/season1/npc/sinseon/sinseon.gr2 -../m2dev-client-main/assets/season1/season1/npc/sinseon/wait.gr2 -../m2dev-client-main/assets/season1/season1/npc/wondaim/wait.gr2 -../m2dev-client-main/assets/season1/season1/npc/wondaim/wondaim.gr2 -../m2dev-client-main/assets/season1/season1/npc/wondaim/wondaim_lod_01_backup.gr2 -../m2dev-client-main/assets/season1/season1/npc/treestone/treestone.gr2 -../m2dev-client-main/assets/season1/season1/npc/naoki/naoki_lod_01.gr2 -../m2dev-client-main/assets/season1/season1/npc/naoki/naoki.gr2 -../m2dev-client-main/assets/season1/season1/npc/naoki/00.gr2 -../m2dev-client-main/assets/season1/season1/npc/naoki/03.gr2 -../m2dev-client-main/assets/season1/season1/npc/naoki/02.gr2 -../m2dev-client-main/assets/season1/season1/npc/naoki/31.gr2 -../m2dev-client-main/assets/season1/season1/npc/naoki/03_2.gr2 -../m2dev-client-main/assets/season1/season1/npc/naoki/03_1.gr2 -../m2dev-client-main/assets/season1/season1/npc/chagirap/chagirap_lod01.gr2 -../m2dev-client-main/assets/season1/season1/npc/chagirap/chagirap.gr2 -../m2dev-client-main/assets/season1/season1/npc/chagirap/die.gr2 -../m2dev-client-main/assets/season1/season1/npc/chagirap/run.gr2 -../m2dev-client-main/assets/season1/season1/npc/chagirap/walk.gr2 -../m2dev-client-main/assets/season1/season1/npc/chagirap/wait.gr2 -../m2dev-client-main/assets/season1/season1/npc/goldenfrog/goldenfrog.gr2 -../m2dev-client-main/assets/season1/season1/npc/backchon/backchon.gr2 -../m2dev-client-main/assets/season1/season1/npc/backchon/backchonstand00.gr2 -../m2dev-client-main/assets/season1/season1/npc/backchon/backchonstand01.gr2 -../m2dev-client-main/assets/season1/season1/npc/backchon/backchon_lod_01_backup.gr2 -../m2dev-client-main/assets/season1/season1/npc/yejin/stand01.gr2 -../m2dev-client-main/assets/season1/season1/npc/yejin/stand00.gr2 -../m2dev-client-main/assets/season1/season1/npc/yejin/yejin_lod_01_backup.gr2 -../m2dev-client-main/assets/season1/season1/npc/yejin/yejin.gr2 -../m2dev-client-main/assets/season1/season1/npc/jinmoo/stand01.gr2 -../m2dev-client-main/assets/season1/season1/npc/jinmoo/stand00.gr2 -../m2dev-client-main/assets/season1/season1/npc/jinmoo/jinmoo_lod_01_backup.gr2 -../m2dev-client-main/assets/season1/season1/npc/jinmoo/jinmoo.gr2 -../m2dev-client-main/assets/season1/season1/monster/fox_ninetail_e/fox_ninetail_e.gr2 -../m2dev-client-main/assets/season1/season1/monster/skeleton_god_e/skeleton_god_e.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_footman/skipia_footman_wait1.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_footman/skipia_footman_back_knockdown.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_footman/skipia_footman_front_damage.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_footman/skipia_footman_front_knockdown.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_footman/skipia_footman_dead.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_footman/skipia_footman_front_standup.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_footman/skipia_footman_front_stand.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_footman/skipia_footman_back_dead.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_footman/skipia_footman_front_damage1.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_footman/skipia_footman_wait.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_footman/skipia_footman_back_damage1.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_footman/skipia_footman_back_standup.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_footman/skipia_footman.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_footman/skipia_footman_attack.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_footman/skipia_footman_attack1.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_footman/skipia_footman_run.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_footman/skipia_footman_back_damage.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_magician/skipia_magician_wait1.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_magician/skipia_magician.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_magician/skipia_magician_back_knockdown.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_magician/skipia_magician_damage.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_magician/skipia_magician_damage1.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_magician/skipia_magician_back_damage.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_magician/skipia_magician_run.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_magician/skipia_magician_front_knockdown.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_magician/skipia_magician_attack.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_magician/skipia_magician_attack1.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_magician/skipia_magician_wait.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_magician/skipia_magician_back_dead.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_magician/skipia_magician_back_standup.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_magician/skipia_magician_back_damage1.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_magician/skipia_magician_dead.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_magician/skipia_magician_front_standup.gr2 -../m2dev-client-main/assets/season1/season1/monster/milgyo_founder_e/milgyo_founder_e.gr2 -../m2dev-client-main/assets/season1/season1/monster/yellow_tigerman_e/yellow_tigerman_e.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_bowman/skipia_bowman_dead.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_bowman/skipia_bowman.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_bowman/skipia_bowman_run.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_bowman/skipia_bowman_back_damage.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_bowman/skipia_bowman_back_dead.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_bowman/skipia_bowman_wait.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_bowman/skipia_bowman_front_knockdown.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_bowman/skipia_bowman_wait1.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_bowman/skipia_bowman_damage1.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_bowman/skipia_bowman_damage.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_bowman/skipia_bowman_attack1.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_bowman/skipia_bowman_front_standup.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_bowman/skipia_bowman_attack.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_bowman/skipia_bowman_back_damage1.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_bowman/skipia_bowman_back_standup.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_bowman/skipia_bowman_back_knockdown.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_general/skipia_general.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_general/skipia_general_skill1.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_general/skipia_general_back_knockdown.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_general/skipia_general_skill2.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_general/skipia_general_front_knockdown.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_general/skipia_general_back_standup.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_general/skipia_general_back_damage1.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_general/skipia_general_attack.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_general/skipia_general_front_standup.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_general/skipia_general_front_damage1.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_general/skipia_general_run.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_general/skipia_general_back_dead.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_general/skipia_general_dead.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_general/skipia_general_wait1.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_general/skipia_general_back_damage.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_general/skipia_general_front_damage.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_general/skipia_general_attack1.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_general/skipia_general_wait.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_officer/skipia_officer_wait1.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_officer/skipia_officer_front_standup.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_officer/skipia_officer_front_damage1.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_officer/skipia_officer_back_standup.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_officer/skipia_officer_back_damage1.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_officer/skipia_officer_attack.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_officer/skipia_officer_front_knockdown.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_officer/skipia_officer_back_damage.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_officer/skipia_officer_back_dead.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_officer/skipia_officer_wait.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_officer/skipia_officer_front_damage.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_officer/skipia_officer_dead.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_officer/skipia_officer_back_knockdown.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_officer/skipia_officer_attack1.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_officer/skipia_officer_run.gr2 -../m2dev-client-main/assets/season1/season1/monster/ch_officer/skipia_officer.gr2 -../m2dev-client-main/assets/season1/season1/monster/spider_queen_e/spider_queen_e.gr2 -../m2dev-client-main/assets/season1/season1/monster/orc_lord_e/orc_lord_e.gr2 -../m2dev-client-main/assets/season1/season1/monster/skeleton_king_e/skeleton_king_e.gr2 -../m2dev-client-main/assets/season1/season1/monster/giant_desert_turtle_e/giant_desert_turtle_e.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc/warrior/warrior_capoeira1.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc/warrior/warrior_capoeira1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc/warrior/warrior_capoeira1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc/warrior/warrior_capoeira1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc/warrior/hair/hair_12_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc/sura/sura_capoeira1.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc/sura/sura_capoeira1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc/sura/sura_capoeira1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc/sura/sura_capoeira1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc/sura/hair/hair_12_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc/assassin/assasin_capoeira1.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc/assassin/assasin_capoeira1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc/assassin/assasin_capoeira1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc/assassin/assasin_capoeira1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc/assassin/hair/hair_12_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc/shaman/shaman_capoeira1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc/shaman/shaman_capoeira1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc/shaman/shaman_capoeira1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc/shaman/hair/hair_12_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc/shaman/shaman_capoeira1.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc2/warrior/warrior_capoeira1.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc2/warrior/warrior_capoeira1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc2/warrior/warrior_capoeira1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc2/warrior/warrior_capoeira1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc2/warrior/hair/hair_12_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc2/sura/sura_capoeira1.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc2/sura/sura_capoeira1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc2/sura/sura_capoeira1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc2/sura/sura_capoeira1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc2/sura/hair/hair_12_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc2/assassin/bow/attack.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc2/assassin/bow/attack_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc2/assassin/assasin_capoeira1.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc2/assassin/assasin_capoeira1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc2/assassin/assasin_capoeira1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc2/assassin/assasin_capoeira1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc2/assassin/hair/hair_12_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc2/shaman/shaman_capoeira1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc2/shaman/shaman_capoeira1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc2/shaman/shaman_capoeira1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc2/shaman/hair/hair_12_1.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/pc2/shaman/shaman_capoeira1.gr2 -../m2dev-client-main/assets/metin2_patch_etc/ymir work/item/weapon/05330.gr2 -../m2dev-client-main/assets/metin2_patch_sd/ymir work/zone/dungeon/spider_dungeon/spider_dungeon03.gr2 -../m2dev-client-main/assets/metin2_patch_sd/ymir work/zone/dungeon/spider_dungeon/spider_dungeon_boss03.gr2 -../m2dev-client-main/assets/metin2_patch_sd/ymir work/monster2/spider_spawn/wait.gr2 -../m2dev-client-main/assets/metin2_patch_sd/ymir work/monster2/spider_spawn/spider_spawn.gr2 -../m2dev-client-main/assets/npc2/ymir work/npc2/privateshop/privateshop_.gr2 -../m2dev-client-main/assets/npc2/ymir work/npc2/privateshop/wait.gr2 -../m2dev-client-main/assets/npc2/ymir work/npc2/privateshop/privateshop.gr2 -../m2dev-client-main/assets/npc2/ymir work/npc2/privateshop2/privateshop_.gr2 -../m2dev-client-main/assets/npc2/ymir work/npc2/privateshop2/privateshop2.gr2 -../m2dev-client-main/assets/npc2/ymir work/npc2/privateshop2/wait.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/warrior/warrior_tailcoat1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/warrior/warrior_salsa1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/warrior/warrior_tailcoat1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/warrior/warrior_salsa1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/warrior/warrior_springwear1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/warrior/warrior_salsa1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/warrior/warrior_tailcoat1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/warrior/warrior_tailcoat1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/warrior/warrior_salsa1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/warrior/warrior_springwear1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/warrior/warrior_springwear1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/warrior/hair/hair_19_1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/warrior/hair/hair_18_1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/warrior/hair/hair_13_1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/warrior/warrior_springwear1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/sura/sura_tailcoat1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/sura/sura_tailcoat1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/sura/sura_salsa1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/sura/sura_salsa1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/sura/sura_tailcoat1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/sura/sura_salsa1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/sura/sura_springwear1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/sura/sura_springwear1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/sura/sura_salsa1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/sura/sura_springwear1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/sura/sura_tailcoat1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/sura/sura_springwear1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/sura/hair/hair_19_1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/sura/hair/hair_18_1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/sura/hair/hair_13_1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/assassin/assassin_springwear1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/assassin/assassin_salsa1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/assassin/assassin_salsa1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/assassin/assassin_salsa1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/assassin/assassin_tailcoat1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/assassin/assassin_tailcoat1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/assassin/assassin_tailcoat1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/assassin/assassin_tailcoat1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/assassin/assassin_springwear1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/assassin/assassin_springwear1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/assassin/assassin_springwear1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/assassin/assassin_salsa1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/assassin/hair/hair_19_1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/assassin/hair/hair_18_1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/assassin/hair/hair_13_1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/shaman/shaman_springwear1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/shaman/shaman_springwear1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/shaman/shaman_springwear1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/shaman/shaman_springwear1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/shaman/shaman_tailcoat1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/shaman/shaman_tailcoat1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/shaman/shaman_tailcoat1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/shaman/shaman_salsa1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/shaman/shaman_tailcoat1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/shaman/shaman_salsa1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/shaman/shaman_salsa1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/shaman/shaman_salsa1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/shaman/hair/hair_19_1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/shaman/hair/hair_18_1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc/shaman/hair/hair_13_1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/warrior/warrior_tailcoat1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/warrior/warrior_salsa1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/warrior/warrior_tailcoat1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/warrior/warrior_salsa1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/warrior/warrior_springwear1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/warrior/warrior_salsa1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/warrior/warrior_tailcoat1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/warrior/warrior_tailcoat1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/warrior/warrior_salsa1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/warrior/warrior_springwear1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/warrior/warrior_springwear1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/warrior/hair/hair_19_1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/warrior/hair/hair_18_1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/warrior/hair/hair_13_1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/warrior/warrior_springwear1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/sura/sura_tailcoat1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/sura/sura_tailcoat1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/sura/sura_salsa1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/sura/sura_salsa1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/sura/sura_tailcoat1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/sura/sura_salsa1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/sura/sura_springwear1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/sura/sura_springwear1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/sura/sura_salsa1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/sura/sura_springwear1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/sura/sura_tailcoat1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/sura/sura_springwear1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/sura/hair/hair_19_1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/sura/hair/hair_18_1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/sura/hair/hair_13_1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/assassin/assassin_springwear1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/assassin/assassin_salsa1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/assassin/assassin_salsa1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/assassin/assassin_salsa1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/assassin/assassin_tailcoat1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/assassin/assassin_tailcoat1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/assassin/assassin_tailcoat1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/assassin/assassin_tailcoat1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/assassin/assassin_springwear1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/assassin/assassin_springwear1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/assassin/assassin_springwear1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/assassin/assassin_salsa1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/assassin/hair/hair_19_1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/assassin/hair/hair_18_1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/assassin/hair/hair_13_1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/shaman/shaman_springwear1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/shaman/shaman_springwear1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/shaman/shaman_springwear1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/shaman/shaman_springwear1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/shaman/shaman_tailcoat1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/shaman/shaman_tailcoat1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/shaman/shaman_tailcoat1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/shaman/shaman_salsa1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/shaman/shaman_tailcoat1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/shaman/shaman_salsa1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/shaman/shaman_salsa1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/shaman/shaman_salsa1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/shaman/hair/hair_19_1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/shaman/hair/hair_18_1.gr2 -../m2dev-client-main/assets/metin2_patch_party/ymir work/pc2/shaman/hair/hair_13_1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/warrior/warrior_santa1_black.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/warrior/warrior_santa1_black_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/warrior/warrior_santa1_black_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/warrior/warrior_santa1_black_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/warrior/warrior_deer1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/warrior/warrior_deer1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/warrior/warrior_deer1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/warrior/warrior_deer1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/warrior/hair/hair_22_1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/warrior/hair/hair_23_1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/sura/sura_santa1_black.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/sura/sura_deer1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/sura/sura_santa1_black_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/sura/sura_deer1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/sura/sura_santa1_black_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/sura/sura_deer1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/sura/sura_deer1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/sura/sura_santa1_black_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/sura/hair/hair_22_1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/sura/hair/hair_23_1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/assassin/assassin_deer1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/assassin/assassin_deer1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/assassin/assassin_deer1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/assassin/assassin_santa1_black.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/assassin/assassin_deer1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/assassin/assassin_santa1_black_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/assassin/assassin_santa1_black_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/assassin/assassin_santa1_black_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/assassin/hair/hair_22_1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/assassin/hair/hair_23_1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/shaman/shaman_santa1_black_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/shaman/shaman_santa1_black_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/shaman/shaman_santa1_black.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/shaman/shaman_santa1_black_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/shaman/shaman_deer1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/shaman/shaman_deer1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/shaman/shaman_deer1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/shaman/shaman_deer1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/shaman/hair/hair_22_1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc/shaman/hair/hair_23_1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/warrior/warrior_santa1_black.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/warrior/warrior_santa1_black_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/warrior/warrior_santa1_black_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/warrior/warrior_santa1_black_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/warrior/warrior_deer1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/warrior/warrior_deer1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/warrior/warrior_deer1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/warrior/warrior_deer1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/warrior/hair/hair_22_1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/warrior/hair/hair_23_1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/sura/sura_santa1_black.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/sura/sura_deer1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/sura/sura_santa1_black_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/sura/sura_deer1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/sura/sura_santa1_black_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/sura/sura_deer1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/sura/sura_deer1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/sura/sura_santa1_black_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/sura/hair/hair_22_1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/sura/hair/hair_23_1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/assassin/assassin_deer1_lod01.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/assassin/assassin_santa1_black.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/assassin/assassin_deer1_lod02.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/assassin/assassin_deer1_lod03.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/assassin/assassin_deer1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/assassin/assassin_santa1_black_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/assassin/assassin_santa1_black_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/assassin/assassin_santa1_black_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/assassin/hair/hair_22_1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/assassin/hair/hair_23_1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/shaman/shaman_santa1_black_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/shaman/shaman_santa1_black_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/shaman/shaman_santa1_black.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/shaman/shaman_santa1_black_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/shaman/shaman_deer1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/shaman/shaman_deer1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/shaman/shaman_deer1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/shaman/shaman_deer1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/shaman/hair/hair_22_1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/pc2/shaman/hair/hair_23_1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/phoenix1/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/phoenix1/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/phoenix1/phoenix1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/phoenix1/run.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/phoenix1/walk.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/phoenix1/wait.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/reindeer_young/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/reindeer_young/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/reindeer_young/run.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/reindeer_young/walk.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/reindeer_young/wait.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/reindeer_young/reindeer_young1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/pig_young1/pig_young1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/pig_young1/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/pig_young1/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/pig_young1/run.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/pig_young1/walk.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/pig_young1/wait.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/panda_young1/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/panda_young1/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/panda_young1/run.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/panda_young1/walk.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/panda_young1/wait.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/panda_young1/panda_young1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/tiger_young1/tiger_young1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/tiger_young1/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/tiger_young1/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/tiger_young1/run.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/tiger_young1/walk.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/tiger_young1/wait.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/phoenix2/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/phoenix2/phoenix2.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/phoenix2/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/phoenix2/run.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/phoenix2/walk.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/phoenix2/wait.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/bear_young1/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/bear_young1/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/bear_young1/bear_young1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/bear_young1/run.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/bear_young1/walk.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/bear_young1/wait.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/dog_young1/dog_young1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/dog_young1/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/dog_young1/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/dog_young1/run.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/dog_young1/walk.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/dog_young1/wait.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/lion_young1/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/lion_young1/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/lion_young1/run.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/lion_young1/walk.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/lion_young1/lion_young1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/lion_young1/wait.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/christmas_tree/christmas_tree.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc2/christmas_tree/wait.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_female/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_female/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_female/dead.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_female/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_female/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_female/attack.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_female/run.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_female/attack1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_female/walk.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_female/skill2.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_female/reindeer_female1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_female/reindeer_female3.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_female/wait.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_female/skill1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_female/reindeer_female2.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/bear/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/bear/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/bear/bear_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/bear/bear_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/bear/bear_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/bear/dead.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/bear/combo_attack.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/bear/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/bear/run.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/bear/walk.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/bear/skill2.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/bear/bear.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/bear/wait.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/panda/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/panda/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/panda/panda.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/panda/dead.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/panda/combo_attack.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/panda/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/panda/run.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/panda/walk.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/panda/skill2.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/panda/wait.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/panda/panda_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/panda/panda_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/panda/panda_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_male/reindeer_male1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_male/wait1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_male/reindeer_male2.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_male/wait2.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_male/reindeer_male3.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_male/dead.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_male/back_damage.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_male/front_damage.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_male/attack.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_male/run.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_male/attack1.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_male/walk.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_male/skill2.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_male/wait.gr2 -../m2dev-client-main/assets/metin2_patch_xmas/ymir work/npc/reindeer_male/skill1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/hunter/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/hunter/hunter.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/hunter/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/hunter/wait_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/hunter/walk.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/hunter/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/peddler/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/peddler/peddler.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/peddler/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/peddler/wait_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/peddler/walk.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/peddler/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/eojiryu/eojiryu.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/eojiryu/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/eojiryu/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/eojiryu/wait_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/eojiryu/walk.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/eojiryu/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/defence/defence.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/defence/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/mr_restaurant/mr_restaurant.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/mr_restaurant/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/mr_restaurant/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/mr_restaurant/wait_2.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/mr_restaurant/wait_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/mr_restaurant/walk.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/mr_restaurant/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sailor/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sailor/sailor.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sailor/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sailor/walk.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sailor/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_bow/34_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_bow/jinno_patrol_bow.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_bow/30_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_bow/00.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_bow/03.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_bow/02.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_bow/33.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_bow/32.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_bow/00_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_bow/30.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_bow/31.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_bow/35.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_bow/20.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_bow/34.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_bow/36.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_bow/37.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/pony/stop.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/pony/04.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/pony/pony.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/pony/00.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/pony/03.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/pony/02.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/pony/00_2.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/pony/33.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/pony/00_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/pony/30.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/pony/25.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/pony/31.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/pony/20_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/pony/20.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_spear/34_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_spear/jinno_patrol_spear.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_spear/30_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_spear/00.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_spear/03.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_spear/02.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_spear/33.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_spear/32.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_spear/00_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_spear/30.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_spear/31.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_spear/20_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_spear/35.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_spear/20.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_spear/34.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_spear/36.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/jinno_patrol_spear/37.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/timid_boy/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/timid_boy/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/timid_boy/wait_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/timid_boy/walk.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/timid_boy/timid_boy.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/timid_boy/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_bow/34_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_bow/30_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_bow/00.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_bow/03.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_bow/02.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_bow/33.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_bow/32.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_bow/00_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_bow/gangyo_patrol_bow.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_bow/30.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_bow/31.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_bow/35.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_bow/20.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_bow/34.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_bow/36.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_bow/37.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/girl_lost_elder_brother/girl_lost_elder_brother.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/girl_lost_elder_brother/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/girl_lost_elder_brother/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/girl_lost_elder_brother/walk.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/girl_lost_elder_brother/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse2/horse2_normal.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse2/stop.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse2/04.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse2/00.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse2/03.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse2/02.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse2/00_2.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse2/33.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse2/00_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse2/30.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse2/25.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse2/31.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse2/20_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse2/20.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse2/horse2_master.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/guard_leader/guard_leader.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/guard_leader/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/guard_leader/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/guard_leader/wait_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/guard_leader/walk.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/guard_leader/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/bank/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/bank/bank.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/beggar/beggar.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/beggar/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/beggar/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/beggar/wait_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/beggar/walk.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/beggar/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/wooden_door/wooden_door.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/wooden_door/close_wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/wooden_door/open.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/doctor/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/doctor/doctor.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/doctor/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/doctor/walk.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/doctor/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/young_merchant/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/young_merchant/young_merchant.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/young_merchant/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/young_merchant/walk.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/young_merchant/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_spear/34_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_spear/30_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_spear/00.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_spear/03.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_spear/02.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_spear/gangyo_patrol_spear.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_spear/33.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_spear/32.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_spear/00_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_spear/30.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_spear/31.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_spear/20_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_spear/35.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_spear/20.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_spear/34.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_spear/36.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gangyo_patrol_spear/37.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/stone_door/close_wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/stone_door/open_wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/stone_door/close.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/stone_door/open.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/stone_door/stone_door.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/plant_researcher/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/plant_researcher/plant_researcher.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/plant_researcher/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/plant_researcher/wait_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/plant_researcher/walk.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/plant_researcher/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/alchemist/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/alchemist/alchemist.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/alchemist/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/alchemist/wait_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/alchemist/walk.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/alchemist/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/hotel_grandfa/hotel_grandfa.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/hotel_grandfa/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/hotel_grandma/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/hotel_grandma/hotel_grandma.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/mineral/fossil_tree.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/mineral/ebony.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/mineral/jade.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/mineral/chunru.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/mineral/white_gold.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/mineral/amber.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/mineral/diamond.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/mineral/pearl.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/mineral/copper.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/mineral/silver.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/mineral/amethyst.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/mineral/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/mineral/gold.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/mineral/quartz.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/widow/widow.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/widow/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/widow/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/widow/walk.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/widow/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/rice_cake_seller/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/rice_cake_seller/rice_cake_seller.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/rice_cake_seller/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/rice_cake_seller/walk.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/rice_cake_seller/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/santa/dead.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/santa/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/santa/damage.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/santa/special.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/santa/wait_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/santa/walk.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/santa/santa.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/santa/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/blacksmith/blacksmith.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/blacksmith/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/blacksmith/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/blacksmith/wait_2.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/blacksmith/wait_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/blacksmith/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/mirinae_brother/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/mirinae_brother/mirinae_brother.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/old_pirate/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/old_pirate/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/old_pirate/wait_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/old_pirate/walk.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/old_pirate/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/old_pirate/old_pirate.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinseon/00.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinseon/00_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinseon/sinseon.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/tombstone1/00.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/tombstone1/tombstone1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/baby_and_mom/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/baby_and_mom/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/baby_and_mom/walk.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/baby_and_mom/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/baby_and_mom/baby_and_mom.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/yu_hwa_rang/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/yu_hwa_rang/yu_hwa_rang.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/yu_hwa_rang/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/yu_hwa_rang/walk.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/yu_hwa_rang/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/warp/warp.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/warp/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gm/00.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gm/03.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gm/gm.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/auntie/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/auntie/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/auntie/walk.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/auntie/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/auntie/auntie.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gilaso/gilaso.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gilaso/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gilaso/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gilaso/walk.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/gilaso/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/goods/goods.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/goods/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/oldster/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/oldster/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/oldster/oldster.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/oldster/wait_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/oldster/walk.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/oldster/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/ceramist/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/ceramist/ceramist.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/ceramist/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/ceramist/wait_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/ceramist/walk.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/ceramist/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/arms/arms.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/arms/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_bow/34_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_bow/30_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_bow/00.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_bow/03.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_bow/02.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_bow/33.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_bow/32.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_bow/00_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_bow/30.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_bow/31.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_bow/35.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_bow/20.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_bow/34.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_bow/36.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_bow/37.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_bow/sinsu_patrol_bow.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse/stop.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse/horse_normal.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse/04.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse/00.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse/03.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse/02.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse/00_2.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse/33.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse/00_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse/30.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse/25.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse/31.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse/20_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse/20.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/horse/horse_master.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_spear/34_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_spear/30_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_spear/00.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_spear/03.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_spear/02.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_spear/33.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_spear/32.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_spear/sinsu_patrol_spear.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_spear/00_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_spear/30.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_spear/31.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_spear/20_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_spear/35.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_spear/20.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_spear/34.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_spear/36.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/sinsu_patrol_spear/37.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/tombstone/00.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/tombstone/tombstone.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/seal_stone/seal_stone.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/seal_stone/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/musician/musician.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/musician/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/musician/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/musician/wait_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/musician/walk.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/musician/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/bookworm/bookworm.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/bookworm/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/bookworm/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/bookworm/walk.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/bookworm/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/woodcutter/woodcutter.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/woodcutter/die.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/woodcutter/run.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/woodcutter/wait_2.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/woodcutter/wait_1.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/woodcutter/wait.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/goldstatue/00.gr2 -../m2dev-client-main/assets/NPC/ymir work/npc/goldstatue/goldstatue.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc/warrior/hair/hair_7_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc/warrior/hair/hair_5_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc/warrior/hair/hair_6_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc/warrior/hair/hair_8_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc/warrior/hair/hair_9_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc/sura/hair/hair_7_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc/sura/hair/hair_5_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc/sura/hair/hair_6_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc/sura/hair/hair_8_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc/sura/hair/hair_9_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc/assassin/hair/hair_7_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc/assassin/hair/hair_5_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc/assassin/hair/hair_6_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc/assassin/hair/hair_8_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc/assassin/hair/hair_9_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc/shaman/hair/hair_7_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc/shaman/hair/hair_5_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc/shaman/hair/hair_6_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc/shaman/hair/hair_8_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc/shaman/hair/hair_9_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/monster2/blue_dragon/34_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/monster2/blue_dragon/30_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/monster2/blue_dragon/00.gr2 -../m2dev-client-main/assets/patch2/ymir work/monster2/blue_dragon/28.gr2 -../m2dev-client-main/assets/patch2/ymir work/monster2/blue_dragon/03.gr2 -../m2dev-client-main/assets/patch2/ymir work/monster2/blue_dragon/27.gr2 -../m2dev-client-main/assets/patch2/ymir work/monster2/blue_dragon/26.gr2 -../m2dev-client-main/assets/patch2/ymir work/monster2/blue_dragon/00_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/monster2/blue_dragon/30.gr2 -../m2dev-client-main/assets/patch2/ymir work/monster2/blue_dragon/24.gr2 -../m2dev-client-main/assets/patch2/ymir work/monster2/blue_dragon/25.gr2 -../m2dev-client-main/assets/patch2/ymir work/monster2/blue_dragon/31.gr2 -../m2dev-client-main/assets/patch2/ymir work/monster2/blue_dragon/20.gr2 -../m2dev-client-main/assets/patch2/ymir work/monster2/blue_dragon/34.gr2 -../m2dev-client-main/assets/patch2/ymir work/monster2/blue_dragon/blue_dragon_lod_01.gr2 -../m2dev-client-main/assets/patch2/ymir work/monster2/blue_dragon/37.gr2 -../m2dev-client-main/assets/patch2/ymir work/monster2/blue_dragon/blue_dragon.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc2/warrior/hair/hair_7_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc2/warrior/hair/hair_5_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc2/warrior/hair/hair_6_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc2/warrior/hair/hair_8_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc2/warrior/hair/hair_9_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc2/sura/hair/hair_7_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc2/sura/hair/hair_5_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc2/sura/hair/hair_6_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc2/sura/hair/hair_8_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc2/sura/hair/hair_9_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc2/assassin/hair/hair_7_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc2/assassin/hair/hair_5_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc2/assassin/hair/hair_6_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc2/assassin/hair/hair_8_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc2/assassin/hair/hair_9_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc2/shaman/hair/hair_7_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc2/shaman/hair/hair_5_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc2/shaman/hair/hair_6_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc2/shaman/hair/hair_8_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/pc2/shaman/hair/hair_9_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/item/etc/football1.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc2/starveling/starveling5.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc2/starveling/starveling4.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc2/starveling/wait1.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc2/starveling/starveling3.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc2/starveling/starveling2.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc2/starveling/wait.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc2/starveling/starveling.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc2/historian/wait1.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc2/historian/run.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc2/historian/walk.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc2/historian/wait.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc2/historian/historian.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc2/rabbit/rabbit.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc2/rabbit/wait01.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc2/rabbit/wait00.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar_2/stand_up.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar_2/wait1.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar_2/wait2.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar_2/skill.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar_2/dead.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar_2/back_damage.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar_2/boar2.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar_2/front_damage.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar_2/run.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar_2/attack3.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar_2/attack2.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar_2/attack1.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar_2/walk.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar_2/boar2_lod_01.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar_2/wait.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar_2/boar2_lod_03.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar_2/boar2_lod_02.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar/boar.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar/stand_up.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar/boar_lod_02.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar/wait1.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar/boar_lod_03.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar/boar_lod_01.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar/wait2.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar/skill.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar/dead.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar/back_damage.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar/front_damage.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar/run.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar/attack3.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar/attack2.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar/attack1.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar/walk.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/boar/wait.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion_white/lion_white.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion_white/lion_white_lod_01.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion_white/lion_white_lod_02.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion_white/lion_white_lod_03.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god/stand_up.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god/wait1.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god/wait2.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god/skill.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god/dog_god.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god/dead.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god/back_damage.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god/front_damage.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god/run.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god/attack3.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god/attack2.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god/attack1.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god/walk.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god/dog_god_lod_01.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god/wait.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god/dog_god_lod_02.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god/dog_god_lod_03.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger/stand_up.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger/wait1.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger/wait2.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger/skill.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger/fire_tiger_lod_01.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger/dead.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger/fire_tiger_lod_02.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger/back_damage.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger/front_damage.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger/fire_tiger_lod_03.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger/run.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger/attack3.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger/attack2.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger/fire_tiger.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger/attack1.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger/walk.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger/wait.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion_2/lion2.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion_2/stand_up.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion_2/wait1.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion_2/wait2.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion_2/skill.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion_2/dead.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion_2/back_damage.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion_2/front_damage.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion_2/run.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion_2/attack3.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion_2/attack2.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion_2/attack1.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion_2/walk.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion_2/wait.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion_2/lion2_lod_03.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion_2/lion2_lod_02.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion_2/lion2_lod_01.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god_2/dog_god_2.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god_2/stand_up.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god_2/wait1.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god_2/wait2.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god_2/skill.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god_2/dead.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god_2/back_damage.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god_2/front_damage.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god_2/run.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god_2/attack3.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god_2/attack2.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god_2/attack1.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god_2/walk.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god_2/dog_god_2_lod_03.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god_2/dog_god_2_lod_02.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god_2/wait.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/dog_god_2/dog_god_2_lod_01.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/horse_event1/00.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/horse_event1/03.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/horse_event1/02.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/horse_event1/00_2.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/horse_event1/33.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/horse_event1/horse_event1.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/horse_event1/00_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/horse_event1/30.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/horse_event1/25.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/horse_event1/31.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/horse_event1/20_1.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/horse_event1/20.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/horse_event1/horse_event1_lod01.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/horse_event1/horse_event1_lod02.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/horse_event1/horse_event1_lod03.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger_2/stand_up.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger_2/wait1.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger_2/wait2.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger_2/skill.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger_2/dead.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger_2/back_damage.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger_2/front_damage.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger_2/run.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger_2/attack3.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger_2/attack2.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger_2/fire_tiger2.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger_2/attack1.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger_2/walk.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger_2/wait.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger_2/fire_tiger2_lod_02.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger_2/fire_tiger2_lod_03.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/fire_tiger_2/fire_tiger2_lod_01.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion/stand_up.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion/lion.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion/wait1.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion/wait2.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion/skill.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion/dead.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion/back_damage.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion/front_damage.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion/run.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion/attack3.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion/attack2.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion/attack1.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion/walk.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion/lion_lod_01.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion/lion_lod_03.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion/wait.gr2 -../m2dev-client-main/assets/patch2/ymir work/npc/lion/lion_lod_02.gr2 -../m2dev-client-main/assets/patch2/ymir work/monster/metinstone_egg/attack.gr2 -../m2dev-client-main/assets/patch2/ymir work/monster/metinstone_egg/blow.gr2 -../m2dev-client-main/assets/patch2/ymir work/monster/metinstone_egg/drop.gr2 -../m2dev-client-main/assets/patch2/ymir work/monster/metinstone_egg/metinstone_egg.gr2 -../m2dev-client-main/assets/patch2/ymir work/monster/metinstone_egg/loop.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/warrior/warrior_assasin1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/warrior/warrior_assasin1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/warrior/warrior_assasin1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/warrior/warrior_assasin1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/warrior/warrior_halloween1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/warrior/warrior_soccer1_germany_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/warrior/warrior_soccer1_germany_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/warrior/warrior_halloween1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/warrior/warrior_halloween1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/warrior/warrior_soccer1_germany_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/warrior/warrior_soccer1_germany.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/warrior/warrior_boxing1_germany_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/warrior/warrior_halloween1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/warrior/warrior_boxing1_germany_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/warrior/warrior_boxing1_germany_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/warrior/warrior_fencing1_germany.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/warrior/warrior_fencing1_germany_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/warrior/warrior_fencing1_germany_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/warrior/warrior_boxing1_germany.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/warrior/hair/hair_20_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/warrior/hair/hair_14_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/warrior/hair/hair_16_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/warrior/hair/hair_17_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/warrior/hair/hair_15_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/warrior/warrior_fencing1_germany_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/sura/sura_soccer1_germany_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/sura/sura_halloween1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/sura/sura_soccer1_germany_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/sura/sura_soccer1_germany_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/sura/sura_fencing1_germany_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/sura/sura_fencing1_germany_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/sura/sura_fencing1_germany_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/sura/sura_assassin1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/sura/sura_halloween1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/sura/sura_halloween1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/sura/sura_halloween1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/sura/sura_soccer1_germany.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/sura/sura_assassin1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/sura/sura_assassin1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/sura/sura_assassin1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/sura/sura_boxing1_germany.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/sura/sura_boxing1_germany_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/sura/sura_fencing1_germany.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/sura/hair/hair_20_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/sura/hair/hair_14_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/sura/hair/hair_16_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/sura/hair/hair_17_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/sura/hair/hair_15_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/sura/sura_boxing1_germany_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/sura/sura_boxing1_germany_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/assassin/assassin_halloween1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/assassin/assassin_halloween1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/assassin/assassin_halloween1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/assassin/assassin_boxing1_germany_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/assassin/assassin_assasin1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/assassin/assassin_assasin1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/assassin/assassin_boxing1_germany_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/assassin/assassin_assasin1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/assassin/assassin_boxing1_germany_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/assassin/assassin_halloween1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/assassin/assassin_fencing1_germany_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/assassin/assassin_fencing1_germany.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/assassin/assassin_fencing1_germany_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/assassin/assassin_fencing1_germany_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/assassin/assassin_boxing1_germany.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/assassin/assassin_soccer1_germany_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/assassin/assassin_soccer1_germany_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/assassin/assassin_soccer1_germany_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/assassin/hair/hair_20_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/assassin/hair/hair_14_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/assassin/hair/hair_16_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/assassin/hair/hair_17_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/assassin/hair/hair_15_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/assassin/assassin_assasin1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/assassin/assassin_soccer1_germany.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/shaman/shaman_fencing1_germany_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/shaman/shaman_fencing1_germany_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/shaman/shaman_fencing1_germany_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/shaman/shaman_boxing1_germany_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/shaman/shaman_boxing1_germany_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/shaman/shaman_boxing1_germany_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/shaman/shaman_fencing1_germany.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/shaman/shaman_assasin1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/shaman/shaman_assasin1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/shaman/shaman_halloween1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/shaman/shaman_assasin1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/shaman/shaman_halloween1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/shaman/shaman_boxing1_germany.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/shaman/shaman_assasin1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/shaman/shaman_halloween1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/shaman/shaman_halloween1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/shaman/shaman_soccer1_germany_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/shaman/shaman_soccer1_germany.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/shaman/shaman_soccer1_germany_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/shaman/shaman_soccer1_germany_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/shaman/hair/hair_20_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/shaman/hair/hair_14_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/shaman/hair/hair_16_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/shaman/hair/hair_17_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc/shaman/hair/hair_15_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/warrior/warrior_soccer1_germany_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/warrior/warrior_soccer1_germany_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/warrior/warrior_soccer1_germany_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/warrior/warrior_assassin1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/warrior/warrior_assassin1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/warrior/warrior_assassin1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/warrior/warrior_soccer1_germany.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/warrior/warrior_boxing1_germany_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/warrior/warrior_boxing1_germany_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/warrior/warrior_assassin1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/warrior/warrior_boxing1_germany_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/warrior/warrior_fencing1_germany.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/warrior/warrior_fencing1_germany_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/warrior/warrior_fencing1_germany_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/warrior/warrior_boxing1_germany.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/warrior/hair/hair_14_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/warrior/hair/hair_16_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/warrior/hair/hair_17_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/warrior/hair/hair_15_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/warrior/warrior_fencing1_germany_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/sura/sura_soccer1_germany_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/sura/sura_soccer1_germany_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/sura/sura_soccer1_germany_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/sura/sura_fencing1_germany_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/sura/sura_fencing1_germany_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/sura/sura_fencing1_germany_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/sura/sura_assassin1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/sura/sura_soccer1_germany.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/sura/sura_assassin1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/sura/sura_assassin1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/sura/sura_assassin1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/sura/sura_boxing1_germany.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/sura/sura_boxing1_germany_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/sura/sura_fencing1_germany.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/sura/hair/hair_14_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/sura/hair/hair_16_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/sura/hair/hair_17_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/sura/hair/hair_15_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/sura/sura_boxing1_germany_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/sura/sura_boxing1_germany_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/assassin/assassin_halloween1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/assassin/assassin_halloween1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/assassin/assasin_soccer1_germany.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/assassin/assassin_halloween1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/assassin/assassin_assasin1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/assassin/assassin_assasin1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/assassin/assassin_assasin1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/assassin/assassin_halloween1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/assassin/assassin_fencing1_germany_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/assassin/assassin_fencing1_germany.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/assassin/assassin_fencing1_germany_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/assassin/assassin_fencing1_germany_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/assassin/assassin_boxing1_germany.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/assassin/assassin_boxing_germany_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/assassin/assasin_soccer1_germany_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/assassin/assassin_boxing_germany_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/assassin/assasin_soccer1_germany_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/assassin/assasin_soccer1_germany_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/assassin/assassin_boxing_germany_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/assassin/hair/hair_20_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/assassin/hair/hair_14_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/assassin/hair/hair_16_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/assassin/hair/hair_17_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/assassin/hair/hair_15_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/assassin/assassin_assasin1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/shaman/shaman_fencing1_germany_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/shaman/shaman_fencing1_germany_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/shaman/shaman_fencing1_germany_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/shaman/shaman_boxing1_germany_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/shaman/shaman_boxing1_germany_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/shaman/shaman_boxing1_germany_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/shaman/shaman_fencing1_germany.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/shaman/shaman_assasin1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/shaman/shaman_assasin1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/shaman/shaman_halloween1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/shaman/shaman_assasin1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/shaman/shaman_halloween1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/shaman/shaman_boxing1_germany.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/shaman/shaman_assasin1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/shaman/shaman_halloween1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/shaman/shaman_halloween1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/shaman/shaman_soccer1_germany_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/shaman/shaman_soccer1_germany.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/shaman/shaman_soccer1_germany_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/shaman/shaman_soccer1_germany_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/shaman/hair/hair_20_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/shaman/hair/hair_14_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/shaman/hair/hair_16_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/shaman/hair/hair_17_1.gr2 -../m2dev-client-main/assets/metin2_patch_mundi/ymir work/pc2/shaman/hair/hair_15_1.gr2 -../m2dev-client-main/assets/metin2_patch_mineral/ymir work/npc/mineral2/mineral2_sapphire.gr2 -../m2dev-client-main/assets/metin2_patch_mineral/ymir work/npc/mineral2/mineral2.gr2 -../m2dev-client-main/assets/metin2_patch_mineral/ymir work/npc/mineral2/mineral2_bery.gr2 -../m2dev-client-main/assets/metin2_patch_mineral/ymir work/npc/mineral2/mineral2_garnet.gr2 -../m2dev-client-main/assets/metin2_patch_mineral/ymir work/npc/mineral2/mineral2_ruby.gr2 -../m2dev-client-main/assets/metin2_patch_mineral/ymir work/npc/mineral2/wait.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkthird/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkthird/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkthird/37_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkthird/bkthird_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkthird/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkthird/31_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkthird/bkthird.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkthird/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkthird/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkthird/00_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkthird/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkthird/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkthird/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkthird/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkthird/24.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkthird/25.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkthird/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkthird/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkthird/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkthird/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkthird/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkthird/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkthird/50.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkthird/51.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkthird/52.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/immotal_ghost/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/immotal_ghost/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/immotal_ghost/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/immotal_ghost/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/immotal_ghost/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/immotal_ghost/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/immotal_ghost/immotal_ghost.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/immotal_ghost/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/immotal_ghost/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/immotal_ghost/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/immotal_ghost/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/immotal_ghost/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/immotal_ghost/immotal_ghost_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/immotal_ghost/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/immotal_ghost/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_boss/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_boss/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_boss/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_boss/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_boss/misterious_diseased_boss_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_boss/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_boss/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_boss/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_boss/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_boss/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_boss/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_boss/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_boss/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_boss/misterious_diseased_boss.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_boss/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_boss/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar/red_wild_boar_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar/red_wild_boar.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar/00_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar/wild_boar.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar/wild_boar_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss3/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss3/thiefboss3.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss3/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss3/thiefboss3_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss3/37_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss3/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss3/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss3/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss3/00_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss3/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss3/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss3/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss3/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss3/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss3/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss3/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss3/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss3/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss3/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss3/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss3/50.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss3/51.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss3/52.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan_general/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan_general/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan_general/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan_general/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan_general/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan_general/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan_general/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan_general/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan_general/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan_general/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan_general/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan_general/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan_general/milgyo_nahan_general.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan_general/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan_general/milgyo_nahan_general_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan_general/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_wizard/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_wizard/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_wizard/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_wizard/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_wizard/skeleton_wizard.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_wizard/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_wizard/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_wizard/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_wizard/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_wizard/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_wizard/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_wizard/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_wizard/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_wizard/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_wizard/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_wizard/skeleton_wizard_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/recycle_monster/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/recycle_monster/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/recycle_monster/recycle_monster_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/recycle_monster/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/recycle_monster/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/recycle_monster/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/recycle_monster/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/recycle_monster/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/recycle_monster/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/recycle_monster/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/recycle_monster/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/recycle_monster/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/recycle_monster/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/recycle_monster/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/recycle_monster/recycle_monster.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/recycle_monster/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/recycle_monster/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/spite_ghost/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/spite_ghost/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/spite_ghost/spite_ghost_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/spite_ghost/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/spite_ghost/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/spite_ghost/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/spite_ghost/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/spite_ghost/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/spite_ghost/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/spite_ghost/spite_ghost.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/spite_ghost/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/spite_ghost/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/spite_ghost/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/spite_ghost/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/spite_ghost/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/spite_ghost/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss2/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss2/thiefboss2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss2/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss2/37_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss2/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss2/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss2/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss2/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss2/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss2/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss2/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss2/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss2/thiefboss2_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss2/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss2/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss2/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss2/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss2/20_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss2/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss2/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss2/50.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss2/51.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss2/52.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_scythe/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_scythe/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_scythe/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_scythe/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_scythe/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_scythe/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_scythe/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_scythe/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_scythe/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_scythe/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_scythe/skeleton_soldier_scythe.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_scythe/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_scythe/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_scythe/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_scythe/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_scythe/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_scythe/skeleton_soldier_scythe_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkarcher/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkarcher/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkarcher/37_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkarcher/37_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkarcher/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkarcher/31_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkarcher/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkarcher/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkarcher/00_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkarcher/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkarcher/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkarcher/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkarcher/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkarcher/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkarcher/bkarcher_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkarcher/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkarcher/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkarcher/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkarcher/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkarcher/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkarcher/bkarcher.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/stray_dog/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/stray_dog/37_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/stray_dog/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/stray_dog/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/stray_dog/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/stray_dog/00_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/stray_dog/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/stray_dog/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/stray_dog/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/stray_dog/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/stray_dog/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/stray_dog/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/stray_dog/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/stray_dog/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/stray_dog/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/stray_dog/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/stray_dog/stray_dog.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/stray_dog/stray_dog_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan1/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan1/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan1/37_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan1/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan1/31_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan1/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan1/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan1/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan1/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan1/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan1/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan1/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan1/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan1/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan1/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan1/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan1/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan1/milgyo_nahan1_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan1/milgyo_nahan1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/mountain_dog_god/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/mountain_dog_god/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/mountain_dog_god/mountain_dog_god.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/mountain_dog_god/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/mountain_dog_god/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/mountain_dog_god/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/mountain_dog_god/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/mountain_dog_god/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/mountain_dog_god/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/mountain_dog_god/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/mountain_dog_god/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/mountain_dog_god/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/mountain_dog_god/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/mountain_dog_god/50.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/mountain_dog_god/51.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/mountain_dog_god/mountain_dog_god_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/mountain_dog_god/52.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_sword/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_sword/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_sword/misterious_diseased_sword_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_sword/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_sword/31_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_sword/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_sword/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_sword/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_sword/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_sword/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_sword/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_sword/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_sword/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_sword/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_sword/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_sword/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_sword/misterious_diseased_sword.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_witch/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_witch/ice_snow_witch.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_witch/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_witch/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_witch/31_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_witch/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_witch/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_witch/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_witch/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_witch/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_witch/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_witch/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_witch/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_witch/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_witch/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_witch/ice_snow_witch_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_infector/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_infector/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_infector/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_infector/misterious_diseased_infector_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_infector/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_infector/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_infector/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_infector/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_infector/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_infector/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_infector/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_infector/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_infector/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_infector/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_infector/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_infector/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_infector/misterious_diseased_infector.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkboss/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkboss/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkboss/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkboss/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkboss/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkboss/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkboss/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkboss/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkboss/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkboss/24.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkboss/25.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkboss/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkboss/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkboss/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkboss/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkboss/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkboss/bkboss_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkboss/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkboss/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkboss/50.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkboss/51.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkboss/25_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkboss/52.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkboss/bkboss.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksoldier/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksoldier/bksoldier_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksoldier/bksoldier.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksoldier/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksoldier/37_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksoldier/37_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksoldier/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksoldier/31_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksoldier/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksoldier/31_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksoldier/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksoldier/00_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksoldier/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksoldier/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksoldier/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksoldier/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksoldier/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksoldier/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksoldier/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksoldier/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksoldier/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksoldier/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksoldier/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/fox_ninetail/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/fox_ninetail/fox_ninetail.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/fox_ninetail/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/fox_ninetail/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/fox_ninetail/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/fox_ninetail/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/fox_ninetail/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/fox_ninetail/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/fox_ninetail/fox_ninetail_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/fox_ninetail/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/fox_ninetail/24.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/fox_ninetail/25.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/fox_ninetail/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/fox_ninetail/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/fox_ninetail/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/fox_ninetail/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/fox_ninetail/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/fox_ninetail/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_soldier/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_soldier/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_soldier/37_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_soldier/barbarian_soldier.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_soldier/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_soldier/31_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_soldier/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_soldier/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_soldier/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_soldier/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_soldier/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_soldier/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_soldier/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_soldier/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_soldier/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_soldier/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_soldier/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_soldier/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_soldier/03_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_soldier/barbarian_soldier_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bear/bear_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bear/bear_brown.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bear/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bear/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bear/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bear/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bear/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bear/bear_gray.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bear/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bear/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bear/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bear/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bear/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bear/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bear/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bear/bear.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bear/bear_black.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_bigblack/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_bigblack/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_bigblack/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_bigblack/orc_bigblack_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_bigblack/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_bigblack/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_bigblack/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_bigblack/orc_bigblack.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_bigblack/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_bigblack/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_bigblack/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_bigblack/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_bigblack/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_bigblack/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_bigblack/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_bigblack/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_bigblack/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_black/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_black/orc_black.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_black/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_black/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_black/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_black/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_black/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_black/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_black/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_black/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_black/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_black/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_black/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_black/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_black/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_black/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_black/orc_black_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_host/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_host/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_host/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_host/misterious_diseased_host_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_host/00_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_host/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_host/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_host/24.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_host/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_host/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_host/misterious_diseased_host.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksecond/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksecond/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksecond/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksecond/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksecond/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksecond/00_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksecond/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksecond/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksecond/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksecond/bksecond.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksecond/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksecond/24.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksecond/25.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksecond/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksecond/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksecond/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksecond/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksecond/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksecond/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksecond/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksecond/50.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksecond/bksecond_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bksecond/52.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/metinstone/metinstone_loop.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/metinstone/metinstone_attack.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/metinstone/metinstone_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/metinstone/metinstone_drop.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/metinstone/metinstone_blow.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_kid/37_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_kid/misterious_diseased_kid.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_kid/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_kid/31_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_kid/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_kid/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_kid/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_kid/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_kid/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_kid/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_kid/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_kid/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_kid/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_kid/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_kid/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_kid/misterious_diseased_kid_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_knight/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_knight/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_knight/orc_knight.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_knight/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_knight/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_knight/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_knight/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_knight/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_knight/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_knight/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_knight/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_knight/orc_knight_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_knight/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_knight/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_knight/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_knight/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_knight/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_bow/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_bow/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_bow/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_bow/31_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_bow/barbarian_bow.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_bow/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_bow/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_bow/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_bow/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_bow/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_bow/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_bow/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_bow/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_bow/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_bow/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_bow/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_bow/barbarian_bow_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_religionist/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_religionist/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_religionist/37_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_religionist/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_religionist/31_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_religionist/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_religionist/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_religionist/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_religionist/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_religionist/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_religionist/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_religionist/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_religionist/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_religionist/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_religionist/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_religionist/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_religionist/milgyo_religionist_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_religionist/milgyo_religionist.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/tiger/tiger_big.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/tiger/tiger_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/tiger/tiger_god.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/tiger/37_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/tiger/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/tiger/tiger.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/tiger/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/tiger/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/tiger/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/tiger/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/tiger/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/tiger/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/tiger/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/tiger/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/tiger/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/tiger/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/tiger/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/tiger/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_giant_man/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_giant_man/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_giant_man/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_giant_man/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_giant_man/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_giant_man/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_giant_man/ice_snow_giant_man.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_giant_man/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_giant_man/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_giant_man/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_giant_man/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_giant_man/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_giant_man/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_giant_man/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_giant_man/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_giant_man/ice_snow_giant_man_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief3/thief3.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief3/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief3/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief3/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief3/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief3/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief3/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief3/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief3/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief3/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkknight/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkknight/bkknight_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkknight/37_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkknight/bkknight.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkknight/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkknight/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkknight/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkknight/00_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkknight/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkknight/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkknight/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkknight/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkknight/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkknight/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkknight/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkknight/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkknight/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkknight/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkknight/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkknight/50.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkknight/52.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/gupae/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/gupae/gupae_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/gupae/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/gupae/37_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/gupae/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/gupae/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/gupae/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/gupae/00_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/gupae/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/gupae/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/gupae/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/gupae/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/gupae/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/gupae/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/gupae/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/gupae/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/gupae/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/gupae/20_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/gupae/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/gupae/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/gupae/gupae.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_magician/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_magician/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_magician/37_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_magician/37_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_magician/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_magician/31_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_magician/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_magician/31_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_magician/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_magician/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_magician/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_magician/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_magician/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_magician/orc_magician_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_magician/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_magician/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_magician/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_magician/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_magician/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_magician/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_magician/orc_magician.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkfourth/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkfourth/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkfourth/37_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkfourth/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkfourth/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkfourth/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkfourth/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkfourth/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkfourth/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkfourth/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkfourth/24.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkfourth/25.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkfourth/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkfourth/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkfourth/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkfourth/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkfourth/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkfourth/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkfourth/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkfourth/50.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkfourth/51.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkfourth/52.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkfourth/bkfourth_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bkfourth/bkfourth.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief2/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief2/thief2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief2/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief2/37_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief2/37_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief2/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief2/31_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief2/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief2/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief2/thief2_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief2/00_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief2/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief2/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief2/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief2/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief2/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief2/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief2/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief2/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief2/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief2/20_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief2/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief2/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/outlaw/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/outlaw/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/outlaw/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/outlaw/31_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/outlaw/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/outlaw/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/outlaw/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/outlaw/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/outlaw/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/outlaw/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/outlaw/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/outlaw/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/outlaw/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/outlaw/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/outlaw/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/outlaw/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/outlaw/outlaw.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/outlaw/03_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_knight/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_knight/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_knight/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_knight/31_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_knight/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_knight/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_knight/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_knight/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_knight/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_knight/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_knight/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_knight/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_knight/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_knight/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_knight/barbarian_knight.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_knight/barbarian_knight_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chuhen/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chuhen/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chuhen/37_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chuhen/chuhen.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chuhen/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chuhen/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chuhen/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chuhen/00_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chuhen/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chuhen/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chuhen/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chuhen/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chuhen/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chuhen/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chuhen/chuhen_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chuhen/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chuhen/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chuhen/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chuhen/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chuhen/50.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chuhen/51.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chuhen/52.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster2/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster2/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster2/37_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster2/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster2/31_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster2/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster2/00_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster2/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster2/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster2/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster2/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster2/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster2/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster2/milgyo_monster2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster2/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster2/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster2/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster2/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster2/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster2/milgyo_monster2_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_whale/ice_snow_whale_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_whale/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_whale/ice_snow_whale.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_whale/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_whale/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_whale/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_whale/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_whale/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_whale/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_whale/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_whale/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_whale/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wolf/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wolf/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wolf/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wolf/00_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wolf/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wolf/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wolf/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wolf/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wolf/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wolf/wolf_gray.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wolf/wolf.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wolf/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wolf/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wolf/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wolf/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wolf/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wolf/wolf_gray_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wolf/wolf_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wolf/wolf_blue.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wolf/wolf_blue_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_boss/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_boss/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_boss/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_boss/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_boss/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_boss/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_boss/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_boss/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_boss/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_boss/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_boss/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_boss/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_boss/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_boss/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_boss/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_boss/barbarian_boss.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_boss/barbarian_boss_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chaos_ghost/chaos_ghost.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chaos_ghost/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chaos_ghost/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chaos_ghost/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chaos_ghost/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chaos_ghost/chaos_ghost_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chaos_ghost/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chaos_ghost/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chaos_ghost/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chaos_ghost/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chaos_ghost/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chaos_ghost/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chaos_ghost/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/chaos_ghost/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_spear/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_spear/misterious_diseased_spear_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_spear/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_spear/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_spear/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_spear/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_spear/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_spear/misterious_diseased_spear.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_spear/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_spear/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_spear/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_spear/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_spear/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_spear/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_spear/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_spear/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_spear/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/metinstonebig/metinstonebig_attack.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/metinstonebig/metinstonebig.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/metinstonebig/metinstonebig_blow.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/metinstonebig/metinstonebig_drop.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/metinstonebig/metinstonebiga.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/metinstonebig/metinstonebig_loop.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss1/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss1/thiefboss1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss1/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss1/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss1/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss1/thiefboss1_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss1/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss1/00_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss1/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss1/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss1/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss1/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss1/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss1/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss1/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss1/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss1/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss1/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss1/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss1/50.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss1/51.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thiefboss1/52.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/yellow_tigerman/yellow_tigerman.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/yellow_tigerman/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/yellow_tigerman/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/yellow_tigerman/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/yellow_tigerman/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/yellow_tigerman/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/yellow_tigerman/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/yellow_tigerman/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/yellow_tigerman/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/yellow_tigerman/24.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/yellow_tigerman/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/yellow_tigerman/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/yellow_tigerman/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/yellow_tigerman/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/yellow_tigerman/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/yellow_tigerman/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/yellow_tigerman/yellow_tigerman_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar_god/wild_boar_god_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar_god/wild_boar_god.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar_god/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar_god/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar_god/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar_god/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar_god/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar_god/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar_god/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar_god/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar_god/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar_god/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar_god/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar_god/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar_god/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar_god/50.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar_god/51.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/wild_boar_god/52.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_bow/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_bow/misterious_diseased_bow_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_bow/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_bow/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_bow/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_bow/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_bow/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_bow/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_bow/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_bow/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_bow/misterious_diseased_bow.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_bow/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_bow/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_bow/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_bow/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_dog/37_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_dog/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_dog/33_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_dog/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_dog/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_dog/00_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_dog/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_dog/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_dog/02_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_dog/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_dog/misterious_diseased_dog.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_dog/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_dog/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_dog/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_dog/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_dog/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_dog/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_dog/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_dog/misterious_diseased_dog_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_dog/03_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_soldier/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_soldier/orc_soldier.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_soldier/orc_soldier_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_soldier/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_soldier/37_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_soldier/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_soldier/31_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_soldier/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_soldier/00_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_soldier/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_soldier/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_soldier/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_soldier/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_soldier/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_soldier/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_soldier/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_soldier/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_soldier/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_soldier/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_soldier/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/goblin_leafhead/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/goblin_leafhead/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/goblin_leafhead/goblin_leafhead.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/goblin_leafhead/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/goblin_leafhead/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/goblin_leafhead/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/goblin_leafhead/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/goblin_leafhead/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/goblin_leafhead/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/goblin_leafhead/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/goblin_leafhead/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/goblin_leafhead/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/goblin_leafhead/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/goblin_leafhead/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/goblin_leafhead/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/goblin_leafhead/goblin_leafhead_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_king/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_king/skeleton_king_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_king/32_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_king/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_king/33_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_king/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_king/skeleton_king.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_king/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_king/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_king/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_king/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_king/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_king/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_king/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_king/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_king/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_king/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_soldier/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_soldier/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_soldier/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_soldier/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_soldier/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_soldier/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_soldier/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_soldier/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_soldier/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_soldier/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_soldier/greenfrog_soldier_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_soldier/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_soldier/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_soldier/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_soldier/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_soldier/greenfrog_soldier.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_insect/ice_snow_insect.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_insect/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_insect/31_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_insect/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_insect/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_insect/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_insect/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_insect/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_insect/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_insect/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_insect/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_insect/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_insect/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_insect/ice_snow_insect_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_god/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_god/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_god/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_god/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_god/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_god/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_god/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_god/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_god/24.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_god/25.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_god/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_god/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_god/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_god/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_god/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_god/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_god/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_god/skeleton_god.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_god/skeleton_god_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bou/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bou/bou.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bou/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bou/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bou/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bou/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bou/00_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bou/bou_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bou/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bou/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bou/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bou/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bou/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bou/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bou/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bou/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bou/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bou/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bou/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bou/50.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bou/51.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/bou/52.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_bow/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_bow/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_bow/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_bow/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_bow/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_bow/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_bow/skeleton_soldier_bow.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_bow/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_bow/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_bow/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_bow/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_bow/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_bow/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_bow/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_bow/skeleton_soldier_bow_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_founder/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_founder/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_founder/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_founder/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_founder/milgyo_founder_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_founder/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_founder/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_founder/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_founder/24.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_founder/25.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_founder/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_founder/milgyo_founder.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_founder/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_founder/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_founder/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_founder/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_egg/misterious_diseased_egg.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_egg/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_egg/00_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan2/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan2/milgyo_nahan2_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan2/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan2/37_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan2/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan2/31_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan2/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan2/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan2/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan2/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan2/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan2/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan2/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan2/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan2/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan2/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan2/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_nahan2/milgyo_nahan2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_general/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_general/orc_general_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_general/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_general/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_general/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_general/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_general/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_general/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_general/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_general/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_general/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_general/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_general/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_general/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_general/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_general/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_general/orc_general.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_scouter/orc_scouter_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_scouter/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_scouter/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_scouter/37_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_scouter/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_scouter/31_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_scouter/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_scouter/31_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_scouter/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_scouter/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_scouter/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_scouter/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_scouter/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_scouter/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_scouter/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_scouter/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_scouter/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_scouter/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_scouter/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_scouter/orc_scouter.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_executor/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_executor/milgyo_executor.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_executor/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_executor/milgyo_executor_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_executor/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_executor/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_executor/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_executor/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_executor/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_executor/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_executor/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_executor/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_executor/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_executor/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_executor/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_spear/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_spear/skeleton_soldier_spear_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_spear/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_spear/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_spear/skeleton_soldier_spear.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_spear/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_spear/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_spear/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_spear/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_spear/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_spear/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_spear/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_spear/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_spear/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_spear/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_spear/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_soldier_spear/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_magician/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_magician/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_magician/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_magician/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_magician/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_magician/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_magician/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_magician/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_magician/skeleton_magician.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_magician/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_magician/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_magician/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_magician/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_magician/ÈĸéÈ¥ºüÁ®³ª°¡±â.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_magician/20_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_magician/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_magician/Á¤¸éÈ¥ºüÁ®³ª°¡±â.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_magician/skeleton_magician_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/maenghwan/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/maenghwan/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/maenghwan/37_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/maenghwan/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/maenghwan/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/maenghwan/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/maenghwan/00_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/maenghwan/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/maenghwan/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/maenghwan/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/maenghwan/maenghwan.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/maenghwan/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/maenghwan/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/maenghwan/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/maenghwan/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/maenghwan/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/maenghwan/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/maenghwan/20_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/maenghwan/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/maenghwan/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/maenghwan/maenghwan_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/maenghwan/50.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/maenghwan/51.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/maenghwan/52.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_dog/ice_snow_dog.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_dog/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_dog/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_dog/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_dog/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_dog/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_dog/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_dog/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_dog/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_dog/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_dog/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_dog/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_dog/ice_snow_dog_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_bosshost/misterious_diseased_bosshost.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_bosshost/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_bosshost/31_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_bosshost/31_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_bosshost/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_bosshost/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_bosshost/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_bosshost/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/misterious_diseased_bosshost/misterious_diseased_bosshost_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_man/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_man/ice_snow_man_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_man/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_man/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_man/31_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_man/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_man/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_man/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_man/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_man/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_man/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_man/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_man/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_man/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_man/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_man/ice_snow_man.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_man/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_man/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_infantry/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_infantry/barbarian_infantry.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_infantry/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_infantry/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_infantry/01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_infantry/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_infantry/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_infantry/00_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_infantry/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_infantry/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_infantry/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_infantry/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_infantry/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_infantry/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_infantry/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_infantry/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_infantry/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_infantry/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/barbarian_infantry/barbarian_infantry_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_monster/ice_snow_monster_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_monster/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_monster/31_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_monster/ice_snow_monster.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_monster/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_monster/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_monster/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_monster/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_monster/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_monster/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_monster/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_monster/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_monster/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_monster/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_monster/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster1/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster1/milgyo_monster1_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster1/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster1/37_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster1/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster1/31_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster1/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster1/00_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster1/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster1/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster1/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster1/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster1/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster1/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster1/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster1/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster1/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster1/milgyo_monster1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster1/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/milgyo_monster1/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_general/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_general/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_general/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_general/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_general/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_general/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_general/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_general/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_general/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_general/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_general/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_general/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_general/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_general/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_general/skeleton_general.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_general/skeleton_general_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_bigboss/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_bigboss/skeleton_bigboss.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_bigboss/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_bigboss/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_bigboss/31_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_bigboss/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_bigboss/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_bigboss/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_bigboss/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_bigboss/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_bigboss/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_bigboss/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_bigboss/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_bigboss/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_bigboss/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_bigboss/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_bigboss/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/skeleton_bigboss/skeleton_bigboss_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_general/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_general/greenfrog_general.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_general/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_general/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_general/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_general/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_general/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_general/greenfrog_general_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_general/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_general/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_general/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_general/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_general/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_general/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_general/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/greenfrog_general/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/sugu_general/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/sugu_general/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/sugu_general/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/sugu_general/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/sugu_general/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/sugu_general/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/sugu_general/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/sugu_general/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/sugu_general/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/sugu_general/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/sugu_general/sugu_general.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/sugu_general/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/sugu_general/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/sugu_general/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/sugu_general/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/sugu_general/sugu_general_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_lord/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_lord/orc_lord_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_lord/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_lord/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_lord/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_lord/orc_lord.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_lord/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_lord/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_lord/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_lord/24.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_lord/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_lord/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_lord/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_lord/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_lord/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_lord/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/orc_lord/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_golem/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_golem/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_golem/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_golem/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_golem/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_golem/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_golem/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_golem/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_golem/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_golem/ice_snow_golem.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_golem/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_golem/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_golem/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_golem/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_golem/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_golem/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/ice_snow_golem/ice_snow_golem_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief1/34_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief1/thief1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief1/30_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief1/37_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief1/37_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief1/00.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief1/31_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief1/03.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief1/02.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief1/00_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief1/33.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief1/32.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief1/00_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief1/thief1_lod_01.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief1/30.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief1/31.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief1/20_1.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief1/35.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief1/20.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief1/34.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief1/20_2.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief1/36.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief1/37.gr2 -../m2dev-client-main/assets/Monster/ymir work/monster/thief1/03_1.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc/warrior/warrior_halloween1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc/warrior/warrior_halloween1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc/warrior/warrior_halloween1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc/warrior/warrior_halloween1.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc/warrior/hair/hair_20_1.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc/sura/sura_halloween1.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc/sura/sura_halloween1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc/sura/sura_halloween1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc/sura/sura_halloween1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc/sura/hair/hair_20_1.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc/assassin/assassin_halloween1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc/assassin/assassin_halloween1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc/assassin/assassin_halloween1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc/assassin/assassin_halloween1.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc/assassin/hair/hair_20_1.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc/shaman/shaman_halloween1.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc/shaman/shaman_halloween1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc/shaman/shaman_halloween1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc/shaman/shaman_halloween1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc/shaman/hair/hair_20_1.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc2/warrior/warrior_halloween1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc2/warrior/warrior_halloween1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc2/warrior/warrior_halloween1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc2/warrior/warrior_halloween1.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc2/warrior/hair/hair_20_1.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc2/sura/sura_halloween1.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc2/sura/sura_halloween1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc2/sura/sura_halloween1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc2/sura/sura_halloween1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc2/sura/hair/hair_20_1.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc2/assassin/assassin_halloween1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc2/assassin/assassin_halloween1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc2/assassin/assassin_halloween1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc2/assassin/assassin_halloween1.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc2/assassin/hair/hair_20_1.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc2/shaman/shaman_halloween1.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc2/shaman/shaman_halloween1_lod_01.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc2/shaman/shaman_halloween1_lod_02.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc2/shaman/shaman_halloween1_lod_03.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/pc2/shaman/hair/hair_20_1.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/npc/horse_halloween1/horse_halloween1_lod01.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/npc/horse_halloween1/horse_halloween1_lod02.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/npc/horse_halloween1/horse_halloween1.gr2 -../m2dev-client-main/assets/metin2_patch_halloween/ymir work/npc/horse_halloween1/horse_halloween1_lod03.gr2 -../m2dev-client-main/assets/guild/ymir work/guild/headquarter/c1-010-bank/c1-010-bank.gr2 -../m2dev-client-main/assets/guild/ymir work/guild/headquarter/b1-010-bank/b1-010-bank.gr2 -../m2dev-client-main/assets/guild/ymir work/guild/headquarter/a1-010-bank/a1-010-bank.gr2 -../m2dev-client-main/assets/guild/ymir work/guild/facility/jedan/jedan.gr2 -../m2dev-client-main/assets/guild/ymir work/guild/facility/suryeonjang/suryeonjang.gr2 -../m2dev-client-main/assets/guild/ymir work/guild/facility/himuijedan/himuijedan_02.gr2 -../m2dev-client-main/assets/guild/ymir work/guild/facility/himuijedan/himuijedan_03.gr2 -../m2dev-client-main/assets/guild/ymir work/guild/facility/himuijedan/himuijedan_01.gr2 -../m2dev-client-main/assets/guild/ymir work/guild/facility/gongjakso/gongjakso.gr2 -../m2dev-client-main/assets/guild/ymir work/guild/facility/yonggwangro/yonggwangro.gr2 -../m2dev-client-main/assets/guild/ymir work/guild/object/guild_symbol/guild_symbol.gr2 -../m2dev-client-main/assets/guild/ymir work/guild/object/guild_symbol/wait.gr2 -../m2dev-client-main/assets/guild/ymir work/guild/fence/fence01_left01.gr2 -../m2dev-client-main/assets/guild/ymir work/guild/fence/fence01_door01.gr2 -../m2dev-client-main/assets/guild/ymir work/guild/fence/fence01_right01.gr2 -../m2dev-client-main/assets/guild/ymir work/guild/fence/fence01_back01.gr2 -../m2dev-client-main/assets/guild/ymir work/guild/inside01/insidepass01.gr2 -../m2dev-client-main/assets/guild/ymir work/guild/inside01/platform01.gr2 -../m2dev-client-main/assets/guild/ymir work/guild/inside01/inside01.gr2 diff --git a/test/assets.list b/test/assets.list deleted file mode 100644 index e06a0551..00000000 --- a/test/assets.list +++ /dev/null @@ -1,35 +0,0 @@ -# 测试资产集 —— 由 M0 T9c 从 fuzz 报告 + 人工挑产出。 -# 路径相对 XRENDER_ASSET_ROOT。每行一个。带 # 的是注释。 -# 覆盖:刚体 / 单材质蒙皮 / 多材质+alpha / 多部件装配+挂点 / 高骨骼数 / 全 4 级 LOD / -# 多 stage 材质(MODULATE2X 或 ADDSIGNED) / 特效挂点 / fuzz 异常个例 -# -# ── bootstrap 引导集(M0 自身验证用,assets.list 产出前)── -PC/ymir work/pc/warrior/warrior_cheongrin.gr2 -PC/ymir work/pc/warrior/warrior_cheongrin_lod_01.gr2 -PC/ymir work/pc/warrior/warrior_cheongrin_lod_02.gr2 -PC/ymir work/pc/warrior/warrior_cheongrin_lod_03.gr2 -PC/ymir work/pc/warrior/action/dance_1.gr2 -Zone/ymir work/zone/oxevent/ox_01.gr2 -# -# ── 正式集:M0 T9c 补(fuzz 全量 9166 零崩溃 / 零谓词失败后精选)── -# -# 蒙皮角色 + 全 4 级 LOD(body/face/附件 5 mesh,PNT332_Skinned,75 骨 Bip01) -# base 已在 bootstrap;补:另一套 warrior 全 LOD 用于跨模型回归 -PC/ymir work/pc/warrior/warrior_lord.gr2 -PC/ymir work/pc/warrior/warrior_lord_lod_01.gr2 -PC/ymir work/pc/warrior/warrior_lord_lod_02.gr2 -PC/ymir work/pc/warrior/warrior_lord_lod_03.gr2 -# 高 mesh 数装配(17 mesh,6 材质 / 3 贴图)—— 顶点类型混合 + 多 stage 材质 -PC/ymir work/pc/assassin/assassin.gr2 -# 多 skeleton(本体 + 2 武器挂点,3 skeleton / 3 model)—— bone-binding 跨 skeleton 解析 -metin2_patch_dragon_rock_mobs/ymir work/monster2/redthief2_soldier2/redthief2_soldier2_lod_01.gr2 -# 刚体 mesh(PNT332,rigid=1)—— 怪物 LOD -monster2/ymir work/monster2/snakeman_bow/snakeman_bow_lod_01.gr2 -# 动画:曲线子类型齐全(pos d0/d2·dim3、rot d0/d2·dim4、scale d0·dim9 + d1·dim9) -PC/ymir work/pc/warrior/action/dance_1.gr2 -monster2/ymir work/monster2/snakeman_bow/00.gr2 -# format v7(Std32LE magic,非 GRNFileMV_Old)—— 11/9166;含 PC 与场景 -PC/ymir work/pc/shaman/shaman_lord.gr2 -Zone/ymir work/zone/dungeon/snow_dungeon/dungeon_a1.gr2 -# 异常个例:bind-pose 自洽 >= 1e-1 的 4 个之一(root 偏移未落在 local/IP 链上) -metin2_patch_easter1/ymir work/pc/warrior/warrior_rabbit1_backup.gr2 diff --git a/test/bgfx-reference/m1-warrior_cheongrin-bindpose-textured.png b/test/bgfx-reference/m1-warrior_cheongrin-bindpose-textured.png deleted file mode 100644 index 20bdc5db..00000000 Binary files a/test/bgfx-reference/m1-warrior_cheongrin-bindpose-textured.png and /dev/null differ diff --git a/test/bgfx-reference/m1-warrior_cheongrin-normals.png b/test/bgfx-reference/m1-warrior_cheongrin-normals.png deleted file mode 100644 index dc03d4b1..00000000 Binary files a/test/bgfx-reference/m1-warrior_cheongrin-normals.png and /dev/null differ diff --git a/test/bgfx-reference/m2-warrior_cheongrin-bindpose.png b/test/bgfx-reference/m2-warrior_cheongrin-bindpose.png deleted file mode 100644 index c0f82e21..00000000 Binary files a/test/bgfx-reference/m2-warrior_cheongrin-bindpose.png and /dev/null differ diff --git a/test/bgfx-reference/m2-warrior_cheongrin-dance_1-t14.2.png b/test/bgfx-reference/m2-warrior_cheongrin-dance_1-t14.2.png deleted file mode 100644 index a8972b31..00000000 Binary files a/test/bgfx-reference/m2-warrior_cheongrin-dance_1-t14.2.png and /dev/null differ diff --git a/test/bgfx-reference/m3-ios-warrior_cheongrin-dance_1-t11.3.png b/test/bgfx-reference/m3-ios-warrior_cheongrin-dance_1-t11.3.png deleted file mode 100644 index dad91ee6..00000000 Binary files a/test/bgfx-reference/m3-ios-warrior_cheongrin-dance_1-t11.3.png and /dev/null differ diff --git a/test/bgfx-reference/render-samples/assassin-bindpose.png b/test/bgfx-reference/render-samples/assassin-bindpose.png deleted file mode 100644 index 7f38e803..00000000 Binary files a/test/bgfx-reference/render-samples/assassin-bindpose.png and /dev/null differ diff --git a/test/bgfx-reference/render-samples/shaman_lord-bindpose.png b/test/bgfx-reference/render-samples/shaman_lord-bindpose.png deleted file mode 100644 index 577f682a..00000000 Binary files a/test/bgfx-reference/render-samples/shaman_lord-bindpose.png and /dev/null differ diff --git a/test/bgfx-reference/render-samples/snakeman-bindpose.png b/test/bgfx-reference/render-samples/snakeman-bindpose.png deleted file mode 100644 index a53a9b0e..00000000 Binary files a/test/bgfx-reference/render-samples/snakeman-bindpose.png and /dev/null differ diff --git a/test/bgfx-reference/render-samples/sura_lord-bindpose.png b/test/bgfx-reference/render-samples/sura_lord-bindpose.png deleted file mode 100644 index 31fdca49..00000000 Binary files a/test/bgfx-reference/render-samples/sura_lord-bindpose.png and /dev/null differ diff --git a/test/bgfx-reference/render-samples/warrior_cheongrin-bindpose.png b/test/bgfx-reference/render-samples/warrior_cheongrin-bindpose.png deleted file mode 100644 index 20bdc5db..00000000 Binary files a/test/bgfx-reference/render-samples/warrior_cheongrin-bindpose.png and /dev/null differ diff --git a/test/bgfx-reference/render-samples/warrior_cheongrin-dance_1-mid.png b/test/bgfx-reference/render-samples/warrior_cheongrin-dance_1-mid.png deleted file mode 100644 index a8972b31..00000000 Binary files a/test/bgfx-reference/render-samples/warrior_cheongrin-dance_1-mid.png and /dev/null differ diff --git a/test/bgfx-reference/rf-sura_hair_8_1.png b/test/bgfx-reference/rf-sura_hair_8_1.png deleted file mode 100644 index 6d6520bc..00000000 Binary files a/test/bgfx-reference/rf-sura_hair_8_1.png and /dev/null differ diff --git a/test/golden/char_lod_strip.png b/test/golden/char_lod_strip.png deleted file mode 100644 index 32d6c4ea..00000000 Binary files a/test/golden/char_lod_strip.png and /dev/null differ diff --git a/test/golden/charselect.png b/test/golden/charselect.png deleted file mode 100644 index cf532d1f..00000000 Binary files a/test/golden/charselect.png and /dev/null differ diff --git a/test/golden/gpu_hair.png b/test/golden/gpu_hair.png deleted file mode 100644 index c6dfc648..00000000 Binary files a/test/golden/gpu_hair.png and /dev/null differ diff --git a/test/golden/m0-scaffold.png b/test/golden/m0-scaffold.png deleted file mode 100644 index f41e0f08..00000000 Binary files a/test/golden/m0-scaffold.png and /dev/null differ diff --git a/test/golden/m1-bindpose.png b/test/golden/m1-bindpose.png deleted file mode 100644 index f37d5e8b..00000000 Binary files a/test/golden/m1-bindpose.png and /dev/null differ diff --git a/test/golden/m1-warrior.png b/test/golden/m1-warrior.png deleted file mode 100644 index 187c5727..00000000 Binary files a/test/golden/m1-warrior.png and /dev/null differ diff --git a/test/golden/m2-dance_1-t7.png b/test/golden/m2-dance_1-t7.png deleted file mode 100644 index 71f90873..00000000 Binary files a/test/golden/m2-dance_1-t7.png and /dev/null differ diff --git a/test/golden/m2-wait.png b/test/golden/m2-wait.png deleted file mode 100644 index ca25cc87..00000000 Binary files a/test/golden/m2-wait.png and /dev/null differ diff --git a/test/golden/m25-assassin.png b/test/golden/m25-assassin.png deleted file mode 100644 index 1642a321..00000000 Binary files a/test/golden/m25-assassin.png and /dev/null differ diff --git a/test/golden/m25-shaman.png b/test/golden/m25-shaman.png deleted file mode 100644 index 11a8c4e9..00000000 Binary files a/test/golden/m25-shaman.png and /dev/null differ diff --git a/test/golden/m25-warrior-fog.png b/test/golden/m25-warrior-fog.png deleted file mode 100644 index c738e957..00000000 Binary files a/test/golden/m25-warrior-fog.png and /dev/null differ diff --git a/test/golden/m25-warrior-shader.png b/test/golden/m25-warrior-shader.png deleted file mode 100644 index ce31fda7..00000000 Binary files a/test/golden/m25-warrior-shader.png and /dev/null differ diff --git a/test/golden/world-a1-persp.png b/test/golden/world-a1-persp.png deleted file mode 100644 index f709f9dd..00000000 Binary files a/test/golden/world-a1-persp.png and /dev/null differ diff --git a/test/golden/world-a1-r1.png b/test/golden/world-a1-r1.png deleted file mode 100644 index a40b21b2..00000000 Binary files a/test/golden/world-a1-r1.png and /dev/null differ diff --git a/test/golden/world-a1-r2.png b/test/golden/world-a1-r2.png deleted file mode 100644 index 25da693f..00000000 Binary files a/test/golden/world-a1-r2.png and /dev/null differ diff --git a/test/golden/world-a1-terrain-top.png b/test/golden/world-a1-terrain-top.png deleted file mode 100644 index c4237c00..00000000 Binary files a/test/golden/world-a1-terrain-top.png and /dev/null differ diff --git a/test/maps/ingame-shinsoo.json b/test/maps/ingame-shinsoo.json deleted file mode 100644 index 76da4ec0..00000000 --- a/test/maps/ingame-shinsoo.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "_doc": "PARITY-GAP.md §0.1 受控参考帧契约。'待采集' = 需从原 D3D 客户端实测,未落盘前只允许修正确性/管线问题,不接受为匹配这张图做的相机/光照/色调/材质调参。参考图应放到 test/reference/ingame-shinsoo.png。", - "reference_image": "test/reference/ingame-shinsoo.png", - - "output": { - "resolution": [1920, 1080], - "godot_version": "4.7.1.stable", - "renderer": "待采集 (Forward+ / Mobile)", - "msaa": "待采集", - "taa": "待采集", - "color_space": "待采集 (sRGB / linear)", - "random_seed": 0 - }, - - "map": { - "map_id": "OutdoorA1/metin2_map_a1", - "confirmed_is_a1": false, - "player_global_cm": ["待采集", "待采集", "待采集"], - "load_radius_tiles": 1, - "visible_tiles": "待采集" - }, - - "camera": { - "yaw_deg": "待采集", - "pitch_deg": "待采集", - "roll_deg": "待采集", - "distance_m": "待采集", - "height_m": "待采集", - "fov_deg": "待采集", - "near": "待采集", - "far": "待采集" - }, - - "player": { - "race": "待采集", - "sex": "待采集", - "body_gr2": "待采集", - "hair_gr2": "待采集", - "weapon": "待采集", - "equipment": "待采集", - "motion": "待采集", - "anim_time_s": "待采集" - }, - - "npc": [], - - "environment": { - "msenv": "A1.msenv", - "time_of_day": "待采集", - "weather": "待采集", - "sun_dir": "待采集", - "fog": "待采集", - "exposure": "待采集", - "post": "待采集" - }, - - "ui": { - "locale": "待采集 (截图角标显示 es?)", - "inventory_open": "待采集", - "minimap_round": "待采集", - "chat_lines": ["待采集"], - "status_bar": "待采集", - "hotbar": "待采集" - }, - - "excluded_from_frame": [ - { "item": "完整 .mse 特效", "reason": "目标帧内不可见", "roi": null }, - { "item": "远离机位的地图内容", "reason": "load_radius 外 / 视锥外", "roi": null } - ] -} diff --git a/test/noise_floor.json b/test/noise_floor.json deleted file mode 100644 index 61305c2d..00000000 --- a/test/noise_floor.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "_comment": "浮点噪声地板。M2/M3 的对拍阈值 ε = 对应值 × 安全余量(约 ×10)。来源见下。", - - "same_dll_determinism": { - "granny": "2.9.12.0", - "mat": 0.0, - "vtx": 0.0, - "method": "同 (model,anim,t) 连续两次 oracle dump,byte-identical。Granny 这条路径单线程无 RNG,完全确定。" - }, - - "cross_impl": { - "_comment": "libgr2 vs 真 Granny —— 两个都正确、浮点运算顺序不同造成的差。这就是实际的地板。", - "granny": "2.9.12.0", - "mat": 4.6e-05, - "vtx": 6.5e-05, - "method": "oracle/run-diff-suite.sh:23 用例(13 模型 bind + 8 动画帧 + v7 + 双 root + 刚体),取 max。", - "report": "m2-numeric.json" - }, - - "cross_version": { - "_comment": "换一版相邻 granny2.dll(2.4.x 或 2.11.x)跑同一 dump 的差 —— 待补,本机只有 2.9.12。", - "mat": null, - "vtx": null, - "status": "pending: 需要另一个 granny2.dll 版本" - }, - - "epsilon": { - "_comment": "M2/M3 数值门禁用。cross_impl × ~15 余量,向上取整到 1e-3。", - "mat": 1e-3, - "vtx": 1e-3 - } -} diff --git a/test/rendering/model_baseline.json b/test/rendering/model_baseline.json deleted file mode 100644 index 2371d61a..00000000 --- a/test/rendering/model_baseline.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "engine": "4.7.1-stable (official)", - "note": "godot --path project --script model_render_test.gd -- --bless", - "races": { - "0": { - "body_gr2": "warrior_novice.gr2", - "body_sha256": "7ac881b0c60ced40c9388d6186bdf02a353a58382d12804345cb65fc3dc1fa74", - "hair_bright_frac": 0.0961239332408458, - "hair_gr2": "hair_1_1.gr2", - "hair_lum_p99": 0.270588235294118, - "hair_mean_lum": 0.0862069988797638, - "hair_mean_lum_ctrl": 0.118492882502141, - "hair_sha256": "2e3c00bda5397d579a2399cfb38a69974667e4f7b92dca6b2a709058a37d0a84", - "head_cover": 0.272221606648199, - "head_px": 45125, - "silhouette_px": 35078 - }, - "1": { - "body_gr2": "assassin_novice.gr2", - "body_sha256": "176d88073cc5a6a4fcd4b4f62d9c401a5a63b27d50a816ad0d5fb463d86f1eab", - "hair_bright_frac": 0.0740650293050516, - "hair_gr2": "hair_1_1.gr2", - "hair_lum_p99": 0.411764705882353, - "hair_mean_lum": 0.122540537286642, - "hair_mean_lum_ctrl": 0.16191718244652, - "hair_sha256": "61424a024587b0bc2dce5febc7d2af5bd1d42177611e2c2772b7fea0d21aad0f", - "head_cover": 0.163433908045977, - "head_px": 27840, - "silhouette_px": 24776 - }, - "2": { - "body_gr2": "sura_novice.gr2", - "body_sha256": "edf32d40ea5cbc080fc3fd9798ce9a2637d2f4a7435e93b48601b05bfe490af1", - "hair_bright_frac": 0.841908258630555, - "hair_gr2": "hair_1_1.gr2", - "hair_lum_p99": 0.67843137254902, - "hair_mean_lum": 0.345470992135172, - "hair_mean_lum_ctrl": 0.36430273043797, - "hair_sha256": "8de6c62889d3c55ef59d6e913f7a25e2a7cdf8748eeae5c68aded52cb1ab4eef", - "head_cover": 0.0245020445851471, - "head_px": 121296, - "silhouette_px": 39682 - }, - "3": { - "body_gr2": "shaman_novice.gr2", - "body_sha256": "1ecfd2e4e2e5e9c2280b18be0f48d749392f6de0006645668126e4ddd8935fca", - "hair_bright_frac": 0.138202264691681, - "hair_gr2": "hair_1_1.gr2", - "hair_lum_p99": 0.325490196078431, - "hair_mean_lum": 0.114180786249986, - "hair_mean_lum_ctrl": 0.148597906212311, - "hair_sha256": "ef76fc009f6df5981637de614a5d68045e5ce778a1a76cc85154293f05c673fe", - "head_cover": 0.696943300601837, - "head_px": 37884, - "silhouette_px": 21923 - }, - "4": { - "body_gr2": "warrior_novice.gr2", - "body_sha256": "fef02eabbd4c4e4ab9b001e98af9cf04a58e04fdcc0955621fc8a2a5539ce8e9", - "hair_bright_frac": 0.232798403525548, - "hair_gr2": "hair_1_1.gr2", - "hair_lum_p99": 0.356862745098039, - "hair_mean_lum": 0.138821295782272, - "hair_mean_lum_ctrl": 0.171530843244045, - "hair_sha256": "9f17eb53e552508d9554df18fe7810e1f237f49040a47edf28aee2e3fc6218db", - "head_cover": 0.222755996904823, - "head_px": 31016, - "silhouette_px": 27285 - }, - "5": { - "body_gr2": "assassin_novice.gr2", - "body_sha256": "4a9b7cd7bcfdb8e94578d760bc40c05c827ec000e67d193522eaef92c3849d78", - "hair_bright_frac": 0.860336341263331, - "hair_gr2": "hair_1_1.gr2", - "hair_lum_p99": 0.427450980392157, - "hair_mean_lum": 0.282471313531006, - "hair_mean_lum_ctrl": 0.307527867586739, - "hair_sha256": "0bf02587413c9b7b5687cc051a1afbfed6fba1ee0ebeb1093fe0b65a1ba74178", - "head_cover": 0.216423497313214, - "head_px": 60109, - "silhouette_px": 36029 - }, - "6": { - "body_gr2": "sura_novice.gr2", - "body_sha256": "03640fdc3502a29ea313d18a206bb826a08e644e771b3b40136c7f250c4b03aa", - "hair_bright_frac": 0.956428325885184, - "hair_gr2": "hair_1_1.gr2", - "hair_lum_p99": 0.698039215686274, - "hair_mean_lum": 0.406448884125668, - "hair_mean_lum_ctrl": 0.423375393471242, - "hair_sha256": "0e2e6eebaad5925540d48645a72073bad7c0556a859c581a091c5e2570227444", - "head_cover": 0.649506781750925, - "head_px": 38928, - "silhouette_px": 24781 - }, - "7": { - "body_gr2": "shaman_novice.gr2", - "body_sha256": "6cb2a74fc0f7b85cd58b1dbe239c5ddcaa68281d5ee37469cea8ec4b209baa40", - "hair_bright_frac": 0.356644645874942, - "hair_gr2": "hair_1_1.gr2", - "hair_lum_p99": 0.415686274509804, - "hair_mean_lum": 0.182649001834564, - "hair_mean_lum_ctrl": 0.204288481408849, - "hair_sha256": "5c6a22c5184737111a1eafcac9b0a8f950145a923da6c59faf09bdf09ec4bb4a", - "head_cover": 0.262338937708471, - "head_px": 59061, - "silhouette_px": 36786 - } - } -} \ No newline at end of file diff --git a/test/shear-bones-survey.md b/test/shear-bones-survey.md deleted file mode 100644 index 62f0dab4..00000000 --- a/test/shear-bones-survey.md +++ /dev/null @@ -1,37 +0,0 @@ -# Shear-bone survey (Godot GPU-skinning viability) - -`tools/anim_probe ` — for every bone, the parent-relative -local that would be fed to `Skeleton3D::set_bone_pose`, its shear, and the error -of a `T·R(quat)·S` round-trip (= what Godot's GPU vertex skinning keeps after it -orthonormalizes the bone matrix before upload). High round-trip error = that bone -**collapses on the GPU (Skeleton3D) path once an animation moves it**. - -Probed with `pc/warrior/action/dance_1.gr2` (retarget by bone name; unmatched -bones sit at bind, so their numbers reflect the model's rest rig). - -| model | shear bones | worst TRS err | worst minDet | GPU-skin viable? | -|---|---|---|---|---| -| `warrior_cheongrin` | **7** (`bone_front_01..04`, `Bone_shoulder_01..04`) | 0.94 | 0.065 (6.5% squash) | ❌ collapses (`dance_1` animates these) | -| `assassin` | 0 | — | — | ✅ | -| `sura_lord` | **16** (`Bone05/06`, `Bone14..27`) | **1.52** | **0.0024** (0.24% squash) | ❌❌ severe | -| `shaman_lord` | 0 | — | — | ✅ | - -## Takeaways - -- The shear/non-uniform-scale is **baked into the rest rig** of these cloth/plate - helper bones (metrics are constant across the animation clock). Static bind pose - survives because `skin_matrix ≈ I` there; any animation that moves a shear bone - breaks it on GPU skinning. -- **`sura` is unusable on Godot's built-in GPU skinning** — 16 bones, one squashed - to 0.24%. It's a core class, so this isn't a corner case. -- `assassin` / `shaman` are clean — GPU skinning would be fine for them. -- **Done (2026-08-29)**: the custom skinning vertex shader is implemented — - `m2_material.cpp` `SRC_SKIN` does LBS with the full per-bone 4×3 matrices from an - RGBAF texture (`Metin2Model::gpu_skin` fills it each frame), no `Skeleton3D`, no - orthonormalization. `MTGODOT_GPUSKIN=1` now routes here (the old broken - `set_bone_pose` path is deleted). warrior `dance_1` GPU render == CPU render - (`test/compare-shots/*.gpu.png`). CPU LBS stays the default; GPU is for crowds - (Phase 2 bench). - -Re-run for a full race sweep (incl. monsters, NPCs, mounts) before Phase 2 to -size the shader work and catch any rig that also needs >4 bone influences. diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 07f0fb8a..33b14a90 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -13,9 +13,6 @@ target_link_libraries(oracle_diff PRIVATE xrender::libgr2) add_executable(anim_probe anim_probe/main.cpp) target_link_libraries(anim_probe PRIVATE xrender::libgr2) -# SHINSOO W0:一张地图的 load report(setting / textureset / 区块二进制 / areadata) -add_executable(map_probe map_probe/main.cpp) -target_link_libraries(map_probe PRIVATE xrender::formats) # gr2dump --gltf 需要 tinygltf(M0 T8 辅助、可延后): # if(TARGET tinygltf) target_link_libraries(gr2dump PRIVATE tinygltf) endif() diff --git a/tools/map_probe/main.cpp b/tools/map_probe/main.cpp deleted file mode 100644 index 82e26553..00000000 --- a/tools/map_probe/main.cpp +++ /dev/null @@ -1,202 +0,0 @@ -// map_probe — SHINSOO-WORLD-RENDERING.md W0 的 load report。 -// -// map_probe [map_rel] map_rel 默认 OutdoorA1/metin2_map_a1 -// -// 扫一张地图:setting.txt / TextureSet / 每个区块的 6 类文件 / areadata, -// 逐项打印「成功 / 失败 + 原因」,末尾给汇总。不加载 .msenv / Property(W0 剩余项)。 -#include "area_data.h" -#include "asset_resolver.h" -#include "environment.h" -#include "m2_coord.h" -#include "map_setting.h" -#include "property.h" -#include "splat.h" -#include "terrain_files.h" -#include "texture_set.h" - -#include -#include -#include -#include -#include - -using namespace fmt; - -static int g_ok = 0, g_bad = 0; -static void line(const char* tag, bool ok, const std::string& detail) { - std::printf(" [%s] %-28s %s\n", ok ? "OK " : "ERR", tag, detail.c_str()); - ok ? ++g_ok : ++g_bad; -} - -int main(int argc, char** argv) { - if (argc < 2) { - std::fprintf(stderr, "usage: map_probe [map_rel]\n"); - return 2; - } - std::string assets = argv[1]; - std::string map_rel = argc > 2 ? argv[2] : "OutdoorA1/metin2_map_a1"; - std::string map = assets + "/" + map_rel; - - std::printf("== map_probe: %s ==\n", map.c_str()); - std::string err; - - MapSetting s; - if (!parse_map_setting_file(map + "/setting.txt", s, &err)) { - line("setting.txt", false, err); - return 1; - } - line("setting.txt", true, - "MapSize " + std::to_string(s.map_size_x) + "x" + std::to_string(s.map_size_y) + - " CellScale " + std::to_string(s.cell_scale) + " HeightScale " + - std::to_string(s.height_scale) + " env=" + s.environment); - - // TextureSet:setting 里是 `textureset\metin2_A1.txt`,实盘在 assets/textureset/textureset/ 且小写 - { - std::string rel = s.texture_set; - for (auto& c : rel) - if (c == '\\') c = '/'; - for (auto& c : rel) c = (char)std::tolower((unsigned char)c); - std::string p = assets + "/textureset/" + rel; - TextureSet ts; - if (parse_texture_set_file(p, ts, &err)) - line("TextureSet", true, - std::to_string(ts.layers.size()) + " layers (+1 empty = runtime " + - std::to_string(ts.runtime_count()) + ")"); - else - line("TextureSet", false, p + " : " + err); - } - - // 每个区块 - int chunks_found = 0, hm_ok = 0, tile_ok = 0, attr_ok = 0, water_ok = 0, area_ok = 0; - long total_objs = 0; - std::map crc_hist; - for (int tx = 0; tx < s.map_size_x; ++tx) { - for (int ty = 0; ty < s.map_size_y; ++ty) { - std::string dir = map + "/" + m2coord::tile_dir(tx, ty); - std::string e; - HeightMap hm; - TileMap tm; - AttrMap am; - WaterMap wm; - AreaData ad; - bool any = false; - if (load_height_map(dir + "/height.raw", hm, &e)) { ++hm_ok; any = true; } - if (load_tile_map(dir + "/tile.raw", tm, &e)) ++tile_ok; - if (load_attr_map(dir + "/attr.atr", am, &e)) ++attr_ok; - if (load_water_map(dir + "/water.wtr", wm, &e)) ++water_ok; - if (parse_area_data_file(dir + "/areadata.txt", ad, &e)) { - ++area_ok; - total_objs += (long)ad.objects.size(); - for (auto& o : ad.objects) crc_hist[o.crc]++; - } - if (any) ++chunks_found; - } - } - int n = s.chunk_count(); - line("chunk dirs", chunks_found == n, - std::to_string(chunks_found) + "/" + std::to_string(n)); - line("height.raw", hm_ok == n, std::to_string(hm_ok) + "/" + std::to_string(n) + " as 131x131"); - line("tile.raw", tile_ok == n, std::to_string(tile_ok) + "/" + std::to_string(n) + " as 258x258"); - line("attr.atr", attr_ok == n, std::to_string(attr_ok) + "/" + std::to_string(n) + " magic 2634"); - line("water.wtr", water_ok == n, std::to_string(water_ok) + "/" + std::to_string(n) + " magic 5426"); - line("areadata.txt", area_ok == n, std::to_string(area_ok) + "/" + std::to_string(n) + " parsed"); - - std::printf(" ---- AreaData: %ld objects, %zu distinct Property CRCs ----\n", - total_objs, crc_hist.size()); - - // splat(区块 000000) - { - TileMap tm; - std::string e; - if (load_tile_map(map + "/000000/tile.raw", tm, &e)) { - SplatSet ss; - build_splat(tm, 18, ss); - std::string used; - for (auto& L : ss.layers) - used += std::to_string(L.layer) + "(" + std::to_string(L.coverage) + ") "; - line("splat 000000", !ss.layers.empty(), - std::to_string(ss.layers.size()) + " used layers: " + used); - } - } - - // .msenv(虚拟路径 environment\ -> ETC/ymir work/environment/) - Environment env; - { - std::string p = assets + "/ETC/ymir work/environment/" + s.environment; - for (auto& c : p) c = (c == '\\') ? '/' : (char)std::tolower((unsigned char)c); - // 只小写文件名部分即可,这里整体小写对 macOS/实盘均成立 - std::string p2 = assets + "/ETC/ymir work/environment/" + s.environment; - std::string lp = p2; - for (auto& c : lp) c = (char)std::tolower((unsigned char)c); - if (parse_environment_file(lp, env, &err)) - line(".msenv", true, - s.environment + " : fog=" + (env.fog.enable ? "on" : "off") + " gradient=" + - std::to_string(env.sky.gradient.size()) + " rows, cloudtex=" + - env.sky.cloud_texture); - else - line(".msenv", false, lp + " : " + err); - } - - // Property CRC 注册表 - PropertyRegistry reg; - if (reg.scan(assets + "/Property", &err)) { - std::string bytype; - for (auto& [k, v] : reg.type_counts) bytype += k + "=" + std::to_string(v) + " "; - line("Property registry", reg.parse_failed == 0, - std::to_string(reg.by_crc.size()) + " CRCs (" + std::to_string(reg.files_scanned) + - " files, " + std::to_string(reg.parse_failed) + " failed, " + - std::to_string(reg.crc_collisions) + " collisions) [" + bytype + "]"); - // areadata 的 CRC 覆盖率 - long hit = 0, total = 0; - std::set missing; - for (auto& [crc, cnt] : crc_hist) { - total++; - if (reg.find(crc)) hit++; - else missing.insert(crc); - } - line("AreaData CRC coverage", missing.empty(), - std::to_string(hit) + "/" + std::to_string(total) + " distinct CRCs resolve" + - (missing.empty() ? "" : " (missing e.g. " + std::to_string(*missing.begin()) + ")")); - } else { - line("Property registry", false, err); - } - - // AssetResolver - AssetResolver res; - if (res.build(assets, AssetResolver::default_priority(), &err)) { - line("AssetResolver", true, - std::to_string(res.files_indexed) + " files, " + - std::to_string(res.by_ymir.size()) + " ymir keys, " + - std::to_string(res.ymir_conflicts) + " conflicts"); - // TextureSet 图层贴图解析率 - TextureSet ts2; - std::string rel = s.texture_set, e3; - for (auto& c : rel) c = (c == '\\') ? '/' : (char)std::tolower((unsigned char)c); - if (parse_texture_set_file(assets + "/textureset/" + rel, ts2, &e3)) { - int miss = 0; - for (auto& L : ts2.layers) - if (res.resolve(L.texture, nullptr).empty()) ++miss; - line("TextureSet -> assets", miss == 0, - std::to_string(ts2.layers.size() - miss) + "/" + - std::to_string(ts2.layers.size()) + " layer textures resolve"); - } - // Property 引用的模型文件解析率(buildingfile / treefile / effectfile) - int pref = 0, pmiss = 0; - for (auto& [crc, p] : reg.by_crc) { - for (const char* k : {"buildingfile", "treefile", "effectfile", "modelfile"}) { - std::string v = p.get(k); - if (v.empty()) continue; - ++pref; - if (res.resolve(v, nullptr).empty()) ++pmiss; - } - } - line("Property models -> assets", true, - std::to_string(pref - pmiss) + "/" + std::to_string(pref) + - " resolve (misses incl. .spt trees / missing packs)"); - } else { - line("AssetResolver", false, err); - } - - std::printf("\n== summary: %d ok, %d err ==\n", g_ok, g_bad); - return g_bad ? 1 : 0; -} diff --git a/tools/root/atlasinfo.txt b/tools/root/atlasinfo.txt deleted file mode 100644 index d33f65d9..00000000 --- a/tools/root/atlasinfo.txt +++ /dev/null @@ -1,110 +0,0 @@ -map_a2 256000 665600 6 6 -map_b2 102400 51200 6 6 -map_c2 665600 281600 6 6 -map_n_snowm_01 358400 153600 6 6 -metin2_map_a1 409600 896000 4 5 -metin2_map_a3 307200 819200 4 4 -metin2_map_b1 0 102400 4 5 -metin2_map_b3 102400 204800 4 4 -metin2_map_c1 921600 204800 4 5 -metin2_map_c3 819200 204800 4 4 -metin2_map_deviltower1 204800 665600 3 3 -metin2_map_milgyo 537600 51200 4 4 -metin2_map_n_desert_01 204800 486400 6 6 -metin2_map_n_flame_01 588800 614400 6 6 -metin2_map_spiderdungeon 51200 486400 3 3 -metin2_map_spiderdungeon_02 665600 435200 4 4 -metin2_map_t1 0 25600 3 3 -metin2_map_t2 6400 0 1 1 -metin2_map_t3 32000 0 1 1 -metin2_map_t4 57600 0 1 1 -metin2_map_t5 793600 0 1 1 -metin2_map_monkeydungeon 819200 51200 3 3 -metin2_map_monkeydungeon 768000 435200 3 3 -metin2_map_monkeydungeon 844800 435200 3 3 -metin2_map_monkeydungeon 921600 435200 3 3 -metin2_map_monkeydungeon_02 128000 640000 3 3 -metin2_map_monkeydungeon_03 128000 716800 3 3 -metin2_map_wedding_01 819200 0 1 1 -metin2_map_guild_01 128000 0 2 2 -metin2_map_guild_02 179200 0 2 2 -metin2_map_guild_03 230400 0 2 2 -metin2_map_trent 281600 0 2 2 -metin2_map_trent02 1049600 0 4 4 -gm_guild_build 83200 0 1 1 -metin2_map_duel 844800 0 1 1 -season1/metin2_map_WL_01 1049600 716800 6 6 -season1/metin2_map_nusluck01 819200 716800 4 4 -season1/metin2_map_oxevent 870400 0 2 2 -season1/metin2_map_sungzi 921600 0 2 2 -metin2_map_bf 972800 0 2 2 -metin2_map_bf_02 921600 51200 2 2 -metin2_map_bf_03 972800 51200 2 2 -metin2_map_sungzi_flame_pass01 1024000 102400 4 4 -metin2_map_sungzi_flame_pass02 1024000 204800 4 4 -metin2_map_sungzi_flame_pass03 1024000 307200 4 4 -season1/metin2_map_sungzi_flame_hill_01 1126400 102400 2 4 -season1/metin2_map_sungzi_flame_hill_02 1126400 204800 2 4 -season1/metin2_map_sungzi_flame_hill_03 1126400 307200 2 4 -season1/metin2_map_sungzi_snow 1152000 0 3 3 -season1/metin2_map_sungzi_snow_pass01 1177600 102400 2 4 -season1/metin2_map_sungzi_snow_pass02 1177600 204800 2 4 -season1/metin2_map_sungzi_snow_pass03 1177600 307200 2 4 -season1/metin2_map_sungzi_desert_01 1228800 0 4 4 -season1/metin2_map_sungzi_desert_hill_01 1228800 102400 2 4 -season1/metin2_map_sungzi_desert_hill_02 1228800 204800 2 4 -season1/metin2_map_sungzi_desert_hill_03 1228800 307200 2 4 -season1/metin2_map_sungzi_milgyo 1331200 0 3 3 -season1/metin2_map_sungzi 1408000 0 3 3 -season1/metin2_map_sungzi_snow 1484800 0 3 3 -season1/metin2_map_sungzi_desert_01 1561600 0 3 3 -season1/metin2_map_sungzi_milgyo_pass01 1280000 102400 2 4 -season1/metin2_map_sungzi_milgyo_pass02 1280000 204800 2 4 -season1/metin2_map_sungzi_milgyo_pass03 1280000 307200 2 4 -season1/metin2_map_sungzi_flame_hill_01 1331200 102400 2 4 -season1/metin2_map_sungzi_flame_hill_02 1331200 204800 2 4 -season1/metin2_map_sungzi_flame_hill_03 1331200 307200 2 4 -season1/metin2_map_sungzi_snow_pass01 1382400 102400 2 4 -season1/metin2_map_sungzi_snow_pass02 1382400 204800 2 4 -season1/metin2_map_sungzi_snow_pass03 1382400 307200 2 4 -season1/metin2_map_sungzi_desert_hill_01 1433600 102400 2 4 -season1/metin2_map_sungzi_desert_hill_02 1433600 204800 2 4 -season1/metin2_map_sungzi_desert_hill_03 1433600 307200 2 4 -season1/metin2_map_ew02 256000 51200 4 4 -season2/metin2_map_empirewar01 972800 102400 2 2 -season2/metin2_map_empirewar02 921600 153600 2 2 -season2/metin2_map_empirewar03 972800 153600 2 2 -season2/map_n_snowm_02 0 1049600 6 6 -season2/metin2_map_milgyo_a 153600 1049600 4 4 -season2/metin2_map_n_desert_02 307200 1049600 6 6 -season2/metin2_map_n_flame_02 460800 1049600 6 6 -season2/metin2_map_a2_1 614400 1049600 6 6 -season2/metin2_map_trent_a 768000 1049600 2 2 -season2/metin2_map_trent02_a 921600 1049600 3 3 -season2/metin2_map_skipia_dungeon_01 0 1203200 6 6 -metin2_map_skipia_dungeon_02 153600 1203200 6 6 -season2/metin2_map_skipia_dungeon_01 0 1356800 6 6 -season2/metin2_map_skipia_dungeon_01 0 1510400 6 6 -season2/metin2_map_skipia_dungeon_01 0 1664000 6 6 -metin2_map_skipia_dungeon_02 153600 1356800 6 6 -metin2_map_skipia_dungeon_02 153600 1510400 6 6 -metin2_map_skipia_dungeon_02 153600 1664000 6 6 -season2/metin2_map_empirewar01 665600 230400 2 2 -season2/metin2_map_empirewar02 716800 230400 2 2 -season2/metin2_map_empirewar03 768000 230400 2 2 -season1/metin2_map_oxevent 742400 0 2 2 -metin2_map_skipia_dungeon_boss 819200 1049600 2 2 -metin2_map_skipia_dungeon_boss 819200 1100800 2 2 -metin2_map_skipia_dungeon_boss2 819200 1152000 2 2 -metin2_map_skipia_dungeon_boss 819200 1203200 2 2 -metin2_map_devilsCatacomb 307200 1203200 8 8 -metin2_map_spiderdungeon_03 51200 563200 3 3 -Metin2_map_CapeDragonHead 1024000 1664000 6 6 -metin2_map_Mt_Thunder 1126400 1510400 4 6 -metin2_map_dawnmistwood 1177600 1664000 7 4 -metin2_map_BayBlackSand 1049600 1510400 3 6 -metin2_guild_village_01 204800 204800 2 2 -metin2_guild_village_02 614400 384000 2 2 -metin2_guild_village_03 256000 819200 2 2 -metin2_map_n_flame_dungeon_01 742400 614400 3 3 -metin2_map_n_snow_dungeon_01 512000 153600 4 3 \ No newline at end of file diff --git a/tools/root/colorinfo.py b/tools/root/colorinfo.py deleted file mode 100644 index 76de6f1f..00000000 --- a/tools/root/colorinfo.py +++ /dev/null @@ -1,37 +0,0 @@ -CHAT_RGB_TALK = (255, 255, 255) -CHAT_RGB_INFO = (255, 200, 200) -CHAT_RGB_NOTICE = (255, 230, 186) -CHAT_RGB_PARTY = (0, 255, 228) -CHAT_RGB_GUILD = (253, 255, 124) -#CHAT_RGB_GUILD = (231, 215, 255) -CHAT_RGB_COMMAND = (167, 255, 212) -CHAT_RGB_SHOUT = (167, 255, 212) -CHAT_RGB_WHISPER = (74, 225, 74) - -CHR_NAME_RGB_MOB = (235, 22, 9) -CHR_NAME_RGB_NPC = (122, 231, 93) -CHR_NAME_RGB_PC = (255, 215, 76) -CHR_NAME_RGB_PK = (180, 100, 0) -CHR_NAME_RGB_PVP = (238, 54, 223) -CHR_NAME_RGB_PARTY = (128, 192, 255) -CHR_NAME_RGB_WARP = (136, 218, 241) -CHR_NAME_RGB_WAYPOINT = (255, 255, 255) - -CHR_NAME_RGB_EMPIRE_MOB = (235, 22, 9) -CHR_NAME_RGB_EMPIRE_NPC = (122, 231, 93) -CHR_NAME_RGB_EMPIRE_PC_A = (157, 0, 0) -CHR_NAME_RGB_EMPIRE_PC_B = (222, 160, 47) -CHR_NAME_RGB_EMPIRE_PC_C = (23, 30, 138) - - - - -TITLE_RGB_GOOD_4 = ( 0, 204, 255) -TITLE_RGB_GOOD_3 = ( 0, 144, 255) -TITLE_RGB_GOOD_2 = ( 92, 110, 255) -TITLE_RGB_GOOD_1 = (155, 155, 255) -TITLE_RGB_NORMAL = (255, 255, 255) -TITLE_RGB_EVIL_1 = (207, 117, 0) -TITLE_RGB_EVIL_2 = (235, 83, 0) -TITLE_RGB_EVIL_3 = (227, 0, 0) -TITLE_RGB_EVIL_4 = (255, 0, 0) diff --git a/tools/root/consolemodule.py b/tools/root/consolemodule.py deleted file mode 100644 index 679bee67..00000000 --- a/tools/root/consolemodule.py +++ /dev/null @@ -1,905 +0,0 @@ -import app -import grp -import wndMgr -import ui -import os -import sys -import stat -import chrmgr -import chr -import net -import background -import snd -import net -import player -import localeInfo -import uiScriptLocale - -class Console(object): - def __init__(self, output): - self.dirNameList = [] - self.fileNameList = [] - - self.output = output - self.curPathName = "D:\\Ymir Work\\" - self.collision = 0 - - self.bgPartDict = { - "terrain":background.PART_TERRAIN, - "object":background.PART_OBJECT, - "cloud":background.PART_CLOUD, - "tree":background.PART_TREE, - "water":background.PART_WATER, - "sky":background.PART_SKY, - } - - self.bgSortDict = { - "distance":background.DISTANCE_SORT, - "texture":background.TEXTURE_SORT, - } - - self.game = 0 - - def Close(self): - self.output = 0 - - def BindGameClass(self, game): - self.game = game - - def Exit(self): - "Exit Program" - app.Exit() - - def EnablePerformanceTime(self, mode, isEnable): - app.EnablePerformanceTime(mode, int(isEnable)) - - def ReloadLocale(self): - "Reload Locale" - import app - if app.ReloadLocale(): - self.Print("RELOAD LOCALE OK") - else: - self.Print("RELOAD LOCALE FAILED") - - def ReloadDevel(self): - "ReloadDevel" - import consoleModule - import uiGuild - import uiInventory - reload(uiGuild) - self.Print("ReloadGuild") - reload(uiInventory) - self.Print("ReloadInventory") - - def ShowPerformanceInfo(self): - "Shows Performance Info" - self.Print(app.GetInfo(app.INFO_ACTOR)) - self.Print(app.GetInfo(app.INFO_ITEM)) - self.Print(app.GetInfo(app.INFO_EFFECT)) - self.Print(app.GetInfo(app.INFO_TEXTTAIL)) - - def Disconnect(self): - "Disconnect by sending unknown packet" - net.SendStrangePacket() - - def ToggleActorDirectionLine(self): - "Shows character's direction line" - chrmgr.ToggleDirectionLine() - - def RegisterCharacterEffect(self, effectType, effectFileName): - "Set character's effect state (state number, bone name, effect filename/number)" - if effectFileName.isdigit(): - effectFileName = self.GetFileName(int(effectFileName)) - - effectFullPathFileName = self.GetFullPathName(effectFileName) - chrmgr.RegisterEffect(chrmgr.EFFECT_STATE+int(effectType), "", effectFullPathFileName) - self.Print("effect state %d: %s" % (int(effectType), effectFullPathFileName)) - - def SetCharacterAffect(self, affectType, isVisible): - "Set character's affect (number, visiblity 1|0)" - chrmgr.SetAffect(-1, int(affectType), int(isVisible)) - self.Print("affect set %d: %d" % (int(affectType), int(isVisible))) - - def SetCharacterEmoticon(self, EmoticonNum): - "Show emoticon (number)" - chrmgr.SetEmoticon(-1, int(EmoticonNum)) - self.Print("Emoticon %d: %d" % (int(EmoticonNum), int(isVisible))) - - def ShowPickedCharacterInfo(self): - "Show information of picked character" - vid=chrmgr.GetPickedVID() - info=chrmgr.GetVIDInfo(vid) - self.Print(info) - - def ShowCharacterInfo(self, arg): - "Show information of character (vid)" - if arg.isdigit(): - vid=int(arg) - else: - vid=0 - - info=chrmgr.GetVIDInfo(vid) - self.Print(info) - - def SetWeaponTraceTexture(self, arg): - "Sets sword afterimage texture (filename)" - if arg.isdigit(): - textureFileName = self.GetFileName(int(arg)) - else: - textureFileName = arg - - chr.WeaponTraceSetTexture(textureFileName) - - def SetAutoCameraRotationSpeed(self, arg): - "Auto camera rotation speed (angle per sec)" - spd=float(arg) - player.SetAutoCameraRotationSpeed(spd) - - self.Print("Auto camera rotation speed: %f" % (spd)) - - def SetWeaponTraceMode(self, *mode): - "Sword afterimage mode (0 = Use alpha, 1 = Use texture)" - if mode and mode[0].isdigit() and int(mode[0]): - chr.WeaponTraceUseTexture() - else: - chr.WeaponTraceUseAlpha() - - def SetCollision(self, *mode): - "Show collison objects (0 | 1)" - if mode and mode[0].isdigit(): - self.collision = int(mode[0]) - else: - self.collision = not self.collision - - def SetMovingSpeed(self, arg): - "Set walking speed" - chrmgr.SetMovingSpeed(int(arg)) - - def SetMusicVolume(self, arg): - "Set BGM volumn (0 ~ 1.0)" - snd.SetMusicVolume(float(arg)) - - def SetSoundVolume(self, arg): - "Set Effect sound volumn (0 ~ 1.0)" - snd.SetSoundVolume(float(arg)) - - def SetSoundScale(self, arg): - "3D Sound scale (default : 200)" - snd.SetSoundScale(int(arg)) - - def SetAmbienceSoundScale(self, arg): - "3D Ambience sound scale (default : 200)" - snd.SetAmbienceSoundScale(int(arg)) - - def SetCoolTime(self): - "Cooltime toggle" - flag = player.ToggleCoolTime() - if flag: - self.Print("Cooltime will be applied") - else: - self.Print("Cooltime disabled") - - def SetLevelLimit(self): - "Sets Level limit" - flag = player.ToggleLevelLimit() - if flag: - self.Print("Level limit will be applied") - else: - self.Print("Level limit disabled") - - def ShowCursor(self): - app.ShowCursor() - - def HideCursor(self): - app.HideCursor() - - def Print(self, msg): - self.output.Print(msg) - - def RefreshPath(self): - self.SetPath(self.curPathName) - - def SetPath(self, newPathName): - if '\\'!=newPathName[-1]: - newPathName=newPathName+'\\' - - if os.access(newPathName, os.R_OK)==0: - self.Print(newPathName+" Cannot find path") - return - - nameList=os.listdir(newPathName) - - dirNameList=[] - fileNameList=[] - for sName in nameList: - mode=os.stat(newPathName+sName)[stat.ST_MODE] - if stat.S_ISDIR(mode): - dirNameList.append(sName) - else: - fileNameList.append(sName) - - self.curPathName=newPathName - self.dirNameList=dirNameList - self.fileNameList=fileNameList - - self.ShowPath() - - def GetPath(self): - return self.curPathName - - def GetDirName(self, iDir): - if (len(self.dirNameList)>iDir): - return self.dirNameList[iDir] - else: - print((len(self.dirNameList))) - return "" - - def GetFileName(self, iFile): - if (len(self.fileNameList)>iFile): - return self.fileNameList[iFile] - else: - print((len(self.fileNameList))) - return "" - - def MoveParentPath(self): - "Go to Parent directory" - newPathName=self.GetPath() - - lastPos=-1 - if '\\'==newPathName[-1]: - lastPos=-2 - - lastPos=newPathName.rfind('\\', 0, lastPos) - if 0>lastPos: - self.Print("Here is root") - return - - newPathName=newPathName[0:lastPos]+'\\' - - self.SetPath(newPathName) - - def GetFullPathName(self, sPathName): - sParentPathName=self.GetPath() - - if '\\'!=sParentPathName[-1]: - sParentPathName=sParentPathName+'\\' - - return sParentPathName+sPathName - - def MoveChildPath(self, directory): - "[Directory name/number] change to child directory" - if ""==directory: - self.Print("You need directory name or number") - return - - if directory.isdigit(): - directory=self.GetDirName(int(directory)) - - newPathName=self.GetFullPathName(directory) - - self.SetPath(newPathName) - - def SetHitEffect(self, arg): - "Sets hit effect" - if arg.isdigit(): - effectFileName = self.GetFileName(int(arg)) - else: - effectFileName = arg - - effectFullPathFileName=self.GetFullPathName(EffectFileName) - chrmgr.RegisterEffect(chrmgr.EFFECT_HIT, "", effectFullPathFileName) - - self.Print("Hit effect: "+effectFullPathFileName) - - def SetStunEffect(self, arg): - "Sets stun effect" - if arg.isdigit(): - effectFileName = self.GetFileName(int(arg)) - else: - effectFileName = arg - - effectFullPathFileName = self.GetFullPathName(effectFileName) - chrmgr.RegisterEffect(chrmgr.EFFECT_STUN, "Bip01 Head", effectFullPathFileName) - - self.Print("Stun effect: "+effectFullPathFileName) - - def SetDustEffect(self, arg): - "Sets dirt effect" - if arg.isdigit(): - effectFileName = self.GetFileName(int(arg)) - else: - effectFileName = arg - - effectFullPathFileName = self.GetFullPathName(effectFileName) - chrmgr.RegisterEffect(chrmgr.EFFECT_DUST, "", effectFullPathFileName) - - self.Print("Dirt effect: "+effectFullPathFileName) - - def SetDustGap(self, arg): - "Sets dirt effect gap" - if arg.isdigit() == 0: - self.Print("Dirt effect gap argument must be a number") - else: - gap = int(arg) - chrmgr.SetDustGap(gap) - self.Print("Dirt effect gap: %d" % (gap)) - - def ShowBackgroundPart(self, arg): - "Show background part" - try: - background.SetVisiblePart(self.bgPartDict[arg], 1); - except KeyError: - self.Print("Unknown part: ", arg); - except: - raise - - def HideBackgroundPart(self, arg): - "Hide background part" - try: - background.SetVisiblePart(self.bgPartDict[arg], 0); - except KeyError: - self.Print("Unknown part: ", arg); - except: - raise - - def SetShadowLevel(self, arg): - "Shadow level setting (0~5)" - if arg.isdigit() == 0: - self.Print("Shadow setting must be a number") - else: - level = int(arg) - - if level < 0 or level > 5: - self.Print("Shadow level range is 0~5") - else: - background.SetShadowLevel(level) - self.Print("Shadow level: %d" % (level)) - - def SetSplatLimit(self, arg): - "Splat number limit" - if arg.isdigit() == 0: - self.Print("Splat number limit must be a number") - else: - limit = int(arg) - - background.SetSplatLimit(limit) - self.Print("Splat number limit: %d" % (limit)) - - def SelectViewDistanceNum(self, arg): - "View distance (0~4)" - if arg.isdigit() == 0: - self.Print("Enter between 0 to 4") - else: - settingnum = int(arg) - - if settingnum < 0 or settingnum > 4: - self.Print("View distance range is 0 to 4") - - else: - background.SelectViewDistanceNum(settingnum) - self.Print("View distance: %d" % (settingnum)) - - def SetBGLoading(self, bBGLoading): - "Background loading (0, 1)" - bResultBoolean = int(bBGLoading) - - if bResultBoolean != 0 and bResultBoolean != 1: - self.Print("Enter 0 or 1") - else: - background.SetBGLoading(bResultBoolean) - self.Print("Background loading: %d" % (bResultBoolean)) - - def SetTerrainRenderSort(self, arg): - "Terrain rendering type" - try: - background.SetRenderSort(self.bgSortDict[arg]); - except KeyError: - self.Print("Unknown part: ", arg); - except: - raise - - def SetTransparentTree(self, arg): - "Tree's leaf transparency" - bTransparent = int(arg) - try: - background.SetTransparentTree(bTransparent); - except KeyError: - self.Print("must be 0 or 1: ", bTransparent); - except: - raise - - def WarpTest(self, warpX, warpY): - "WarpTest : warp dwX dwY" - iWarpX = int(warpX) - iWarpY = int(warpY) - try: - background.Destroy() - background.Initialize() - background.WarpTest(iWarpX, iWarpY); - background.RegisterEnvironmentData(0, "d:/ymir work/environment/b3.msenv") - background.SetEnvironmentData(0) - background.SetShadowLevel(background.SHADOW_ALL) - except: - import exception - exception.Abort("consoleModule.Console.WarpTest") - - def ToggleDebugInfo(self): - "Show DebugInfo" - net.ToggleGameDebugInfo() - - def ShowPath(self): - "Show current path" - self.Print("Current path is "+self.GetPath()) - - def ShowList(self): - "Show current path's list" - self.ShowDirList() - self.ShowFileList() - - def ShowDirList(self): - "Show current path's child directories" - self.Print(self.GetPath()+" directories:") - self.ShowNameList(self.dirNameList) - self.Print("") - - def ShowFileList(self, Filter=[]): - "Show current path's files (extension filter)" - self.Print(self.GetPath()+" files:") - self.ShowNameList(self.fileNameList, Filter) - self.Print("") - - def ShowEffectList(self): - "Show current path's effect" - self.Print(self.GetPath()+" effects:") - self.ShowNameList(self.fileNameList, ["mse"]) - self.Print("") - - def ShowWeb(self): - "ShowWeb" - if app.IsWebPageMode(): - app.HideWebPage() - else: - app.ShowWebPage("http://wiki.metin.co.kr/metin1help/01.htm", (0, 0, 320, 600)) - - def ShowUI(self): - "Shows UI" - self.game.CheckGameButton() - self.game.interface.ShowDefaultWindows() - self.game.interface.wndChat.Show() - - def HideUI(self): - "Hides UI" - self.game.interface.HideAllWindows() - self.game.interface.wndChat.Hide() - - def SetCameraSpeed(self, percentage): - "Sets camera speed (Default = 100)" - app.SetCameraSpeed(int(percentage)) - - def SaveCameraSetting(self, filename): - "Save current camera attributes (filename)" - app.SaveCameraSetting(filename) - - def LoadCameraSetting(self, filename): - "Load camera attributes (filename)" - if not app.LoadCameraSetting(filename): - self.Print("Could not load camera attribute") - - def SetDefaultCamera(self): - "Return to default camera attribute" - app.SetDefaultCamera() - - def ShowClock(self, second): - self.game.ShowClock(int(second)) - - def HideClock(self): - self.game.HideClock() - - def ShowNotice(self): - app.SetVisibleNotice(TRUE) - self.Print("Show Notice") - - def HideNotice(self): - app.SetVisibleNotice(FALSE) - self.Print("Hide Notice") - - def SetSight(self, range): - "Set Force Sight Range" - app.SetSightRange(int(range)) - - def SetComboType(self, type): - chr.testSetComboType(int(type)) - - def SetSkillGroupFake(self, index): - """테스트 코드""" - net.SetSkillGroupFake(int(index)) - self.Print(" SetSkillGroupFake : %d" % int(index)) - - def SetEmpireLanguageMode(self, mode): - net.SetEmpireLanguageMode(int(mode)) - self.Print(" SetEmpireLanguageMode : %d" % int(mode)) - - def SetCharacterRenderModeTypeAdd(self, color): - vid = player.GetTargetVID() - print((" -> SetCharacterRenderModeTypeAdd", vid, color)) - chr.testSetAddRenderMode(vid, int(color,16)) - - def SetCharacterRenderModeTypeMod(self, color): - vid = player.GetTargetVID() - print((" -> SetCharacterRenderModeTypeMod", vid, color, int(color,16))) - chr.testSetModulateRenderMode(vid, int(color,16)) - - def SetCharacterRenderModeTypeAddRGB(self, r, g, b): - vid = player.GetTargetVID() - print((" -> SetCharacterRenderModeTypeAddRGB", vid, r, g, b)) - chr.testSetAddRenderModeRGB(vid, float(r)/255.0, float(g)/255.0, float(b)/255.0) - - def SetCharacterRenderModeTypeModRGB(self, r, g, b): - vid = player.GetTargetVID() - print((" -> SetCharacterRenderModeTypeModRGB", vid, r, g, b)) - chr.testSetModulateRenderModeRGB(vid, float(r)/255.0, float(g)/255.0, float(b)/255.0) - - def SetCharacterRenderModeSpecular(self, alpha): - vid = player.GetTargetVID() - print((" -> SetCharacterRenderModeSpecular", vid, alpha)) - chr.testSetSpecularRenderMode(vid, float(alpha)) - - def RestoreCharacterRenderModeType(self): - vid = player.GetTargetVID() - chr.testRestoreRenderMode(vid) - - - def ShowNameList(self, lstsName, lstsFilter=None): - if len(lstsName)==0: - self.Print("None") - return - - if lstsFilter: - isFilter=1 - else: - isFilter=0 - - sLine="" - iCol=0 - - iName=0 - for sName in lstsName: - if isFilter: - iDotPos=sName.rfind('.', 0, -1) - if iDotPos<0: - iName=iName+1 - continue - - if (sName[iDotPos+1:] in lstsFilter)==0: - iName=iName+1 - continue - - sLine=sLine+"%3d %-15s " % (iName, sName) - - if iCol>4: - iCol=0 - self.Print(sLine) - sLine="" - - iCol=iCol+1 - - iName=iName+1 - - if ""!=sLine: - self.Print(sLine) - -class ConsoleWindow(ui.Window): - - BACK_GROUND_COLOR = grp.GenerateColor(0.0, 0.0, 0.0, 0.5) - EDIT_LINE_COLOR = grp.GenerateColor(0.0, 0.0, 0.0, 1.0) - BUTTON_COLOR = grp.GenerateColor(1.0, 1.0, 1.0, 1.0) - HEIGHT = 200 - LINE_STEP = 15 - MAX_LINE_COUNT = 50 - - class ConsoleEditLine(ui.EditLine): - def __init__(self): - ui.EditLine.__init__(self) - self.eventReturn = 0 - self.eventEscape = 0 - def __del__(self): - ui.EditLine.__del__(self) - - def SetReturnEvent(self, event): - self.eventReturn = event - - def SetEscapeEvent(self, event): - self.eventEscape = event - - def OnIMEReturn(self): - text = self.GetText() - - if len(text) > 0: - self.eventReturn(text) - - else: - wndMgr.KillFocus() - self.eventEscape() - - self.SetText("") - return TRUE - - def OnPressEscapeKey(self): - self.SetText("") - wndMgr.KillFocus() - self.eventEscape() - return TRUE - - class ResizingButton(ui.DragButton): - - BUTTON_NORMAL_COLOR = grp.GenerateColor(0.3320, 0.2929, 0.2578, 1.0) - BUTTON_OVER_COLOR = grp.GenerateColor(0.5320, 0.4929, 0.4578, 1.0) - BUTTON_LIGHT_OUTLINE_COLOR = grp.GenerateColor(0.6666, 0.6509, 0.6313, 1.0) - BUTTON_DARK_OUTLINE_COLOR = grp.GenerateColor(0.1647, 0.1450, 0.1294, 1.0) - - def __init__(self): - ui.DragButton.__init__(self) - self.AddFlag("limit") - self.AddFlag("restrict_x") - - def __del__(self): - ui.DragButton.__del__(self) - - def __init__(self): - ui.Window.__init__(self) - - self.TextList = [] - self.game = 0 - self.Console = Console(self) - - self.ResizingButton = self.ResizingButton() - self.ResizingButton.SetParent(self) - self.ResizingButton.SetSize(15, 15) - self.ResizingButton.SetPosition(100, 100) - self.ResizingButton.Show() - - self.EditLine = self.ConsoleEditLine() - self.EditLine.SetParent(self) - self.EditLine.SetMax(100) - self.EditLine.SetFontName(localeInfo.UI_DEF_FONT) - self.EditLine.SetText("") - self.EditLine.Show() - - from _weakref import ref - - self.ResizingButton.SetMoveEvent(lambda s = ref(self): s().UpdatePosition()) - self.EditLine.SetReturnEvent(lambda x,s = ref(self): s().ProcessCommand(x)) - self.EditLine.SetEscapeEvent(lambda s = ref(self): s().CloseWindow()) - - self.UpdatePosition() - - self.functionDict = {} - self.InitFunction() - - def __del__(self): - ui.Window.__del__(self) - - def BindGameClass(self, game): - self.Console.BindGameClass(game) - - def Close(self): - self.Console.Close() - self.ResizingButton = 0 - self.EditLine = 0 - - def SetConsoleSize(self, width, height): - self.ResizingButton.SetPosition(width-20, height-20) - self.UpdatePosition() - - def OnRender(self): - grp.SetColor(self.BACK_GROUND_COLOR) - grp.RenderBar(self.gx, self.gy, self.width, self.height) - - grp.SetColor(ConsoleWindow.EDIT_LINE_COLOR) - grp.RenderBar(self.gxEditLine-2, self.gyEditLine-3, self.width - 40, 17) - - grp.SetColor(ConsoleWindow.BUTTON_COLOR) - grp.RenderBar(self.gxButton-2, self.gyButton-3, self.widthButton, self.heightButton) - - def UpdatePosition(self): - - self.width = self.GetWidth() - self.height = self.GetHeight() - self.widthButton = self.ResizingButton.GetWidth() - self.heightButton = self.ResizingButton.GetHeight() - (self.gx, self.gy) = self.GetGlobalPosition() - (self.gxButton, self.gyButton) = self.ResizingButton.GetGlobalPosition() - - self.SetSize(self.gxButton - self.gx + 20, self.gyButton - self.gy + 20) - - self.EditLine.SetSize(self.width-30, 16) - self.EditLine.SetPosition(7, self.height-20) - (self.gxEditLine, self.gyEditLine) = self.EditLine.GetGlobalPosition() - - ##### - - yPosition = (self.height-20) - self.LINE_STEP - ItemCount = len(self.TextList) - - for i in range(ItemCount): - TextLine = self.TextList[ItemCount-i-1] - - TextLine.SetPosition(10, yPosition) - yPosition -= self.LINE_STEP - - if yPosition < 0: - TextLine.Hide() - else: - TextLine.Show() - - def OpenWindow(self): - - self.EditLine.SetFocus() - - self.Show() - self.Console.RefreshPath() - - def CloseWindow(self): - self.Hide() - - ## NOTE : 이곳에서 Command를 처리합니다 - [levites] - def ProcessCommand(self, text): - - if '/' == text[0]: - net.SendChatPacket(text) - return - - Console=self.Console - Console.Print(">> "+text) - - lstsArg=text.split() - if len(lstsArg)==0: - return - - sCmd=lstsArg[0] - - if sCmd in self.functionDict: - try: - self.functionDict[sCmd](self.Console, *lstsArg[1:]) - except Exception as e: - Console.Print(str(e)) - #self.Console.Print(e) - #self.Console.Print(self.functionDict[sCmd].__doc__) - else: - if sCmd == 'help' or sCmd == 'h': - try: - k = lstsArg[1] - v = self.functionDict[k] - argcount = v.__func__.__code__.co_argcount - 1 # -1 for self - if v.__func__.__code__.co_flags & 4: - argcount+=1 - argnames = v.__func__.__code__.co_varnames[1:argcount+1] - if argcount: - Console.Print("%s(%s) : %s" % (k,argcount, v.__doc__)) - Console.Print(" arg : %s" % argnames) - else: - Console.Print("%s : %s" % (k,v.__doc__)) - except: - for k,v in list(self.functionDict.items()): - argcount = v.__func__.__code__.co_argcount - 1 # -1 for self - if v.__func__.__code__.co_flags & 4: - argcount+=1 - if argcount: - Console.Print("%s(%s) : %s" % (k,argcount, v.__doc__)) - else: - Console.Print("%s : %s" % (k,v.__doc__)) - Console.Print("? : All commands list") - Console.Print("h : Help for all commands") - Console.Print("h blah : Help for blah") - - Console.Print("") - elif sCmd == '?': - list = list(self.functionDict.keys()) - list.sort() - Console.ShowNameList(list) - pass - - def InitFunction(self): - #self.AddFunction("help", Console.PrintHelp) - #self.AddFunction("?", Console.PrintHelp) - - self.AddFunction("exit", Console.Exit) - self.AddFunction("mvol", Console.SetMusicVolume) - self.AddFunction("svol", Console.SetSoundVolume) - self.AddFunction("snds", Console.SetSoundScale) - self.AddFunction("asnds", Console.SetAmbienceSoundScale) - self.AddFunction("mspd", Console.SetMovingSpeed) - self.AddFunction("pwd", Console.ShowPath) - self.AddFunction("ls", Console.ShowList) - self.AddFunction("shadow", Console.SetShadowLevel) - self.AddFunction("splat", Console.SetSplatLimit) - self.AddFunction("distance", Console.SelectViewDistanceNum) - self.AddFunction("bgloading", Console.SetBGLoading) - self.AddFunction("terrainrender", Console.SetTerrainRenderSort) - self.AddFunction("transtree", Console.SetTransparentTree) - self.AddFunction("stune", Console.SetStunEffect) - self.AddFunction("duste", Console.SetDustEffect) - self.AddFunction("dustt", Console.SetDustGap) - self.AddFunction("hite", Console.SetHitEffect) - self.AddFunction("cd", Console.MoveChildPath) - self.AddFunction("up", Console.MoveParentPath) - self.AddFunction("lsd", Console.ShowDirList) - self.AddFunction("lsf", Console.ShowFileList) - self.AddFunction("lse", Console.ShowEffectList) - self.AddFunction("show", Console.ShowBackgroundPart) - self.AddFunction("hide", Console.HideBackgroundPart) - self.AddFunction("debuginfo", Console.ToggleDebugInfo) - - self.AddFunction("collision", Console.SetCollision) - self.AddFunction("colli", Console.SetCollision) - - #self.AddFunction("wt", Console.SetWeaponTrace) - self.AddFunction("wtt", Console.SetWeaponTraceTexture) - self.AddFunction("wtm", Console.SetWeaponTraceMode) - - self.AddFunction("disconnect", Console.Disconnect) - self.AddFunction("autorot", Console.SetAutoCameraRotationSpeed) - - self.AddFunction("dirline", Console.ToggleActorDirectionLine) - self.AddFunction("pickc", Console.ShowPickedCharacterInfo) - self.AddFunction("infoc", Console.ShowCharacterInfo) - self.AddFunction("regchre", Console.RegisterCharacterEffect) - self.AddFunction("setchra", Console.SetCharacterAffect) - self.AddFunction("emoticon", Console.SetCharacterEmoticon) - self.AddFunction("perfinfo", Console.ShowPerformanceInfo) - self.AddFunction("reload_locale", Console.ReloadLocale) - self.AddFunction("re", Console.ReloadDevel) - self.AddFunction("perftime", Console.EnablePerformanceTime) - self.AddFunction("cooltime", Console.SetCoolTime) - self.AddFunction("levellimit", Console.SetLevelLimit) - self.AddFunction("showcursor", Console.ShowCursor) - self.AddFunction("hidecursor", Console.HideCursor) - - self.AddFunction("warp", Console.WarpTest) - self.AddFunction("web", Console.ShowWeb) - - self.AddFunction("showui", Console.ShowUI) - self.AddFunction("hideui", Console.HideUI) - - self.AddFunction("setcspd", Console.SetCameraSpeed) - self.AddFunction("savecmr", Console.SaveCameraSetting) - self.AddFunction("loadcmr", Console.LoadCameraSetting) - self.AddFunction("setdefcmr", Console.SetDefaultCamera) - - self.AddFunction("showclock", Console.ShowClock) - self.AddFunction("hideclock", Console.HideClock) - - self.AddFunction("setsight", Console.SetSight) - - self.AddFunction("setcombotype", Console.SetComboType) - self.AddFunction("setsk_fake", Console.SetSkillGroupFake) - - self.AddFunction("trans", Console.SetEmpireLanguageMode) - - self.AddFunction("shownotice", Console.ShowNotice) - self.AddFunction("hidenotice", Console.HideNotice) - - self.AddFunction("setrmadd", Console.SetCharacterRenderModeTypeAdd) - self.AddFunction("setrmmod", Console.SetCharacterRenderModeTypeMod) - self.AddFunction("setrmaddrgb", Console.SetCharacterRenderModeTypeAddRGB) - self.AddFunction("setrmmodrgb", Console.SetCharacterRenderModeTypeModRGB) - self.AddFunction("setspec", Console.SetCharacterRenderModeSpecular) - self.AddFunction("restorerm", Console.RestoreCharacterRenderModeType) - - def AddFunction(self, cmd, func): - self.functionDict[cmd] = func - - def Print(self, text): - TextLine = ui.TextLine() - TextLine.SetParent(self) - TextLine.SetFontName(localeInfo.UI_DEF_FONT) - TextLine.Show() - TextLine.SetText(text) - self.TextList.append(TextLine) - - count = len(self.TextList) - if count > self.MAX_LINE_COUNT: - for i in range(count - self.MAX_LINE_COUNT): - del self.TextList[0] - - self.UpdatePosition() diff --git a/tools/root/constinfo.py b/tools/root/constinfo.py deleted file mode 100644 index 8c40fb73..00000000 --- a/tools/root/constinfo.py +++ /dev/null @@ -1,250 +0,0 @@ -# option -CONSOLE_ENABLE = 0 - -PVPMODE_ENABLE = 1 -PVPMODE_TEST_ENABLE = 0 -PVPMODE_ACCELKEY_ENABLE = 1 -PVPMODE_ACCELKEY_DELAY = 0.5 -PVPMODE_PROTECTED_LEVEL = 30 - -FOG_LEVEL0 = 4800.0 -FOG_LEVEL1 = 9600.0 -FOG_LEVEL2 = 12800.0 -FOG_LEVEL = FOG_LEVEL0 -FOG_LEVEL_LIST = [FOG_LEVEL0, FOG_LEVEL1, FOG_LEVEL2] - -CAMERA_MAX_DISTANCE_SHORT = 2500.0 -CAMERA_MAX_DISTANCE_LONG = 3500.0 -CAMERA_MAX_DISTANCE_LIST = [CAMERA_MAX_DISTANCE_SHORT, CAMERA_MAX_DISTANCE_LONG] -CAMERA_MAX_DISTANCE = CAMERA_MAX_DISTANCE_SHORT - -CHRNAME_COLOR_INDEX = 0 - -ENVIRONMENT_NIGHT = "d:/ymir work/environment/moonlight04.msenv" - -# constant -HIGH_PRICE = 500000 -MIDDLE_PRICE = 50000 -ERROR_METIN_STONE = 28960 -SUB2_LOADING_ENABLE = 1 -EXPANDED_COMBO_ENABLE = 1 -CONVERT_EMPIRE_LANGUAGE_ENABLE = 1 -USE_ITEM_WEAPON_TABLE_ATTACK_BONUS = 0 -ADD_DEF_BONUS_ENABLE = 1 -LOGIN_COUNT_LIMIT_ENABLE = 0 - -USE_SKILL_EFFECT_UPGRADE_ENABLE = 1 - -VIEW_OTHER_EMPIRE_PLAYER_TARGET_BOARD = 1 -GUILD_MONEY_PER_GSP = 100 -GUILD_WAR_TYPE_SELECT_ENABLE = 1 -TWO_HANDED_WEAPON_ATT_SPEED_DECREASE_VALUE = 0 - -HAIR_COLOR_ENABLE = 1 -ARMOR_SPECULAR_ENABLE = 1 -WEAPON_SPECULAR_ENABLE = 1 -KEEP_ACCOUNT_CONNETION_ENABLE = 1 -MINIMAP_POSITIONINFO_ENABLE = 0 -CONVERT_EMPIRE_LANGUAGE_ENABLE = 0 -USE_ITEM_WEAPON_TABLE_ATTACK_BONUS = 0 -ADD_DEF_BONUS_ENABLE = 0 -LOGIN_COUNT_LIMIT_ENABLE = 0 -PVPMODE_PROTECTED_LEVEL = 15 -TWO_HANDED_WEAPON_ATT_SPEED_DECREASE_VALUE = 10 - -# MR-3: Define max quickslot slots number for scripts -QUICKSLOT_MAX_NUM = 36 -# MR-3: -- END OF -- Define max quickslot slots number for scripts - -isItemQuestionDialog = 0 - -def GET_ITEM_QUESTION_DIALOG_STATUS(): - global isItemQuestionDialog - return isItemQuestionDialog - -def SET_ITEM_QUESTION_DIALOG_STATUS(flag): - global isItemQuestionDialog - isItemQuestionDialog = flag - -import app -import net - -# MR-10: Add accessorySocketTimeCache for real-time remaining time display of accessory sockets. -# Cache for accessory/belt socket timers so they persist across UI reloads. -if not hasattr(app, "_accessorySocketTimeCache"): - app._accessorySocketTimeCache = {} -ACCESSORY_SOCKET_TIME_CACHE = app._accessorySocketTimeCache -# MR-10: -- END OF -- Add accessorySocketTimeCache for real-time remaining time display of accessory sockets. - -######################## - -def SET_DEFAULT_FOG_LEVEL(): - global FOG_LEVEL - app.SetMinFog(FOG_LEVEL) - -def SET_FOG_LEVEL_INDEX(index): - global FOG_LEVEL - global FOG_LEVEL_LIST - try: - FOG_LEVEL=FOG_LEVEL_LIST[index] - except IndexError: - FOG_LEVEL=FOG_LEVEL_LIST[0] - app.SetMinFog(FOG_LEVEL) - -def GET_FOG_LEVEL_INDEX(): - global FOG_LEVEL - global FOG_LEVEL_LIST - return FOG_LEVEL_LIST.index(FOG_LEVEL) - -######################## - -def SET_DEFAULT_CAMERA_MAX_DISTANCE(): - global CAMERA_MAX_DISTANCE - app.SetCameraMaxDistance(CAMERA_MAX_DISTANCE) - -def SET_CAMERA_MAX_DISTANCE_INDEX(index): - global CAMERA_MAX_DISTANCE - global CAMERA_MAX_DISTANCE_LIST - try: - CAMERA_MAX_DISTANCE=CAMERA_MAX_DISTANCE_LIST[index] - except: - CAMERA_MAX_DISTANCE=CAMERA_MAX_DISTANCE_LIST[0] - - app.SetCameraMaxDistance(CAMERA_MAX_DISTANCE) - -def GET_CAMERA_MAX_DISTANCE_INDEX(): - global CAMERA_MAX_DISTANCE - global CAMERA_MAX_DISTANCE_LIST - return CAMERA_MAX_DISTANCE_LIST.index(CAMERA_MAX_DISTANCE) - -######################## - -import chrmgr -import player -import app - -def SET_DEFAULT_CHRNAME_COLOR(): - global CHRNAME_COLOR_INDEX - chrmgr.SetEmpireNameMode(CHRNAME_COLOR_INDEX) - -def SET_CHRNAME_COLOR_INDEX(index): - global CHRNAME_COLOR_INDEX - CHRNAME_COLOR_INDEX=index - chrmgr.SetEmpireNameMode(index) - -def GET_CHRNAME_COLOR_INDEX(): - global CHRNAME_COLOR_INDEX - return CHRNAME_COLOR_INDEX - -def SET_VIEW_OTHER_EMPIRE_PLAYER_TARGET_BOARD(index): - global VIEW_OTHER_EMPIRE_PLAYER_TARGET_BOARD - VIEW_OTHER_EMPIRE_PLAYER_TARGET_BOARD = index - -def GET_VIEW_OTHER_EMPIRE_PLAYER_TARGET_BOARD(): - global VIEW_OTHER_EMPIRE_PLAYER_TARGET_BOARD - return VIEW_OTHER_EMPIRE_PLAYER_TARGET_BOARD - -def SET_DEFAULT_CONVERT_EMPIRE_LANGUAGE_ENABLE(): - global CONVERT_EMPIRE_LANGUAGE_ENABLE - net.SetEmpireLanguageMode(CONVERT_EMPIRE_LANGUAGE_ENABLE) - -def SET_DEFAULT_USE_ITEM_WEAPON_TABLE_ATTACK_BONUS(): - global USE_ITEM_WEAPON_TABLE_ATTACK_BONUS - player.SetWeaponAttackBonusFlag(USE_ITEM_WEAPON_TABLE_ATTACK_BONUS) - -def SET_DEFAULT_USE_SKILL_EFFECT_ENABLE(): - global USE_SKILL_EFFECT_UPGRADE_ENABLE - app.SetSkillEffectUpgradeEnable(USE_SKILL_EFFECT_UPGRADE_ENABLE) - -def SET_TWO_HANDED_WEAPON_ATT_SPEED_DECREASE_VALUE(): - global TWO_HANDED_WEAPON_ATT_SPEED_DECREASE_VALUE - app.SetTwoHandedWeaponAttSpeedDecreaseValue(TWO_HANDED_WEAPON_ATT_SPEED_DECREASE_VALUE) - -######################## -import item - -ACCESSORY_MATERIAL_LIST = [50623, 50624, 50625, 50626, 50627, 50628, 50629, 50630, 50631, 50632, 50633, 50634, 50635, 50636, 50637, 50638] -#ACCESSORY_MATERIAL_LIST = [50623, 50623, 50624, 50624, 50625, 50625, 50626, 50627, 50628, 50629, 50630, 50631, 50632, 50633, -# 50623, 50623, 50624, 50624, ] -JewelAccessoryInfos = [ - # jewel wrist neck ear - [ 50634, 14420, 16220, 17220 ], - [ 50635, 14500, 16500, 17500 ], - [ 50636, 14520, 16520, 17520 ], - [ 50637, 14540, 16540, 17540 ], - [ 50638, 14560, 16560, 17560 ], - ] -def GET_ACCESSORY_MATERIAL_VNUM(vnum, subType): - ret = vnum - item_base = (vnum // 10) * 10 - for info in JewelAccessoryInfos: - if item.ARMOR_WRIST == subType: - if info[1] == item_base: - return info[0] - elif item.ARMOR_NECK == subType: - if info[2] == item_base: - return info[0] - elif item.ARMOR_EAR == subType: - if info[3] == item_base: - return info[0] - - if vnum >= 16210 and vnum <= 16219: - return 50625 - - if item.ARMOR_WRIST == subType: - WRIST_ITEM_VNUM_BASE = 14000 - ret -= WRIST_ITEM_VNUM_BASE - elif item.ARMOR_NECK == subType: - NECK_ITEM_VNUM_BASE = 16000 - ret -= NECK_ITEM_VNUM_BASE - elif item.ARMOR_EAR == subType: - EAR_ITEM_VNUM_BASE = 17000 - ret -= EAR_ITEM_VNUM_BASE - - type = ret // 20 - - if type < 0 or type >= len(ACCESSORY_MATERIAL_LIST): - type = (ret - 170) // 20 - - if type < 0 or type >= len(ACCESSORY_MATERIAL_LIST): - return 0 - - return ACCESSORY_MATERIAL_LIST[type] - -################################################################## -## Belt item type and belt socket item handling -## Belt socket system is identical to accessories, so must use hardcoding approach similar to accessory handling - -def GET_BELT_MATERIAL_VNUM(vnum, subType = 0): - # Currently all belts can only insert one item type (#18900) - return 18900 - -################################################################## -## Auto-potions (HP: #72723 ~ #72726, SP: #72727 ~ #72730) - -# Check if vnum is an auto-potion -def IS_AUTO_POTION(itemVnum): - return IS_AUTO_POTION_HP(itemVnum) or IS_AUTO_POTION_SP(itemVnum) - -# Check if vnum is an HP auto-potion -def IS_AUTO_POTION_HP(itemVnum): - if 72723 <= itemVnum and 72726 >= itemVnum: - return 1 - elif itemVnum >= 76021 and itemVnum <= 76022: ## Gift item: Fire Dragon's Blessing - return 1 - elif itemVnum == 79012: - return 1 - - return 0 - -# Check if vnum is an SP auto-potion -def IS_AUTO_POTION_SP(itemVnum): - if 72727 <= itemVnum and 72730 >= itemVnum: - return 1 - elif itemVnum >= 76004 and itemVnum <= 76005: ## Gift item: Water Dragon's Blessing - return 1 - elif itemVnum == 79013: - return 1 - - return 0 - diff --git a/tools/root/debuginfo.py b/tools/root/debuginfo.py deleted file mode 100644 index d2bfd71f..00000000 --- a/tools/root/debuginfo.py +++ /dev/null @@ -1,10 +0,0 @@ -g_isDebugMode=0 - -def SetDebugMode(isDebugMode): - global g_isDebugMode - g_isDebugMode=isDebugMode - -def IsDebugMode(): - global g_isDebugMode - return g_isDebugMode - diff --git a/tools/root/dragon_soul_refine_settings.py b/tools/root/dragon_soul_refine_settings.py deleted file mode 100644 index e589c38f..00000000 --- a/tools/root/dragon_soul_refine_settings.py +++ /dev/null @@ -1,47 +0,0 @@ -import item - -# default_grade_need_count = [3, 3, 3, 3] -default_grade_need_count = [15, 10, 5, 3] -default_grade_fee = [30000, 50000, 70000, 100000] -default_step_need_count = [4, 3, 2, 1] -default_step_fee = [20000, 30000, 40000, 50000] - -strength_fee = { - item.MATERIAL_DS_REFINE_NORMAL : 10000, - item.MATERIAL_DS_REFINE_BLESSED : 20000, - item.MATERIAL_DS_REFINE_HOLLY : 30000, -} - -# Maximum strength value for each grade and step of refinement -# table(GRADE, STEP) = max strength. -default_strength_max_table = [ - [2, 2, 3, 3, 4], - [3, 3, 3, 4, 4], - [4, 4, 4, 4, 4], - [4, 4, 4, 4, 5], - [4, 4, 4, 5, 6], -] - -# For the current plan, strength enhancement is excluded, and enhancement fee is not determined yet, -# so it is not added to dragon_soul_refine_info. -# (Even if enhancement data exists, we want to be able to exclude it if needed) -# If you want to set different enhancement fees for different dragon soul types in other servers, -# and if you want different enhancement fees for each dragon soul type, -# you need to modify the client code. -default_refine_info = { - "grade_need_count" : default_grade_need_count, - "grade_fee" : default_grade_fee, - "step_need_count" : default_step_need_count, - "step_fee" : default_step_fee, - "strength_max_table" : default_strength_max_table, -} - -dragon_soul_refine_info = { - 11 : default_refine_info, - 12 : default_refine_info, - 13 : default_refine_info, - 14 : default_refine_info, - 15 : default_refine_info, - 16 : default_refine_info, -} - diff --git a/tools/root/emotion.py b/tools/root/emotion.py deleted file mode 100644 index 6eea5f78..00000000 --- a/tools/root/emotion.py +++ /dev/null @@ -1,263 +0,0 @@ -import localeInfo -import player -import chrmgr -import chr - -EMOTION_VERSION = 2 - -if EMOTION_VERSION == 2: - EMOTION_CLAP = 1 - EMOTION_CONGRATULATION = 2 - EMOTION_FORGIVE = 3 - EMOTION_ANGRY = 4 - EMOTION_ATTRACTIVE = 5 - EMOTION_SAD = 6 - EMOTION_SHY = 7 - EMOTION_CHEERUP = 8 - EMOTION_BANTER = 9 - EMOTION_JOY = 10 - EMOTION_CHEERS_1 = 11 - EMOTION_CHEERS_2 = 12 - EMOTION_DANCE_1 = 13 - EMOTION_DANCE_2 = 14 - EMOTION_DANCE_3 = 15 - EMOTION_DANCE_4 = 16 - EMOTION_DANCE_5 = 17 - EMOTION_DANCE_6 = 18 - EMOTION_KISS = 51 - EMOTION_FRENCH_KISS = 52 - EMOTION_SLAP = 53 - - EMOTION_DICT = {} - - ICON_DICT = { - EMOTION_CLAP : "d:/ymir work/ui/game/windows/emotion_clap.sub", - EMOTION_CHEERS_1 : "d:/ymir work/ui/game/windows/emotion_cheers_1.sub", - EMOTION_CHEERS_2 : "d:/ymir work/ui/game/windows/emotion_cheers_2.sub", - - EMOTION_DANCE_1 : "icon/action/dance1.tga", - EMOTION_DANCE_2 : "icon/action/dance2.tga", - - EMOTION_CONGRATULATION : "icon/action/congratulation.tga", - EMOTION_FORGIVE : "icon/action/forgive.tga", - EMOTION_ANGRY : "icon/action/angry.tga", - EMOTION_ATTRACTIVE : "icon/action/attractive.tga", - EMOTION_SAD : "icon/action/sad.tga", - EMOTION_SHY : "icon/action/shy.tga", - EMOTION_CHEERUP : "icon/action/cheerup.tga", - EMOTION_BANTER : "icon/action/banter.tga", - EMOTION_JOY : "icon/action/joy.tga", - EMOTION_DANCE_1 : "icon/action/dance1.tga", - EMOTION_DANCE_2 : "icon/action/dance2.tga", - EMOTION_DANCE_3 : "icon/action/dance3.tga", - EMOTION_DANCE_4 : "icon/action/dance4.tga", - EMOTION_DANCE_5 : "icon/action/dance5.tga", - EMOTION_DANCE_6 : "icon/action/dance6.tga", - - EMOTION_KISS : "d:/ymir work/ui/game/windows/emotion_kiss.sub", - EMOTION_FRENCH_KISS : "d:/ymir work/ui/game/windows/emotion_french_kiss.sub", - EMOTION_SLAP : "d:/ymir work/ui/game/windows/emotion_slap.sub", - } - - ANI_DICT = { - chr.MOTION_CLAP : "clap.msa", - chr.MOTION_CHEERS_1 : "cheers_1.msa", - chr.MOTION_CHEERS_2 : "cheers_2.msa", - chr.MOTION_DANCE_1 : "dance_1.msa", - chr.MOTION_DANCE_2 : "dance_2.msa", - chr.MOTION_DANCE_3 : "dance_3.msa", - chr.MOTION_DANCE_4 : "dance_4.msa", - chr.MOTION_DANCE_5 : "dance_5.msa", - chr.MOTION_DANCE_6 : "dance_6.msa", - chr.MOTION_CONGRATULATION : "congratulation.msa", - chr.MOTION_FORGIVE : "forgive.msa", - chr.MOTION_ANGRY : "angry.msa", - chr.MOTION_ATTRACTIVE : "attractive.msa", - chr.MOTION_SAD : "sad.msa", - chr.MOTION_SHY : "shy.msa", - chr.MOTION_CHEERUP : "cheerup.msa", - chr.MOTION_BANTER : "banter.msa", - chr.MOTION_JOY : "joy.msa", - chr.MOTION_FRENCH_KISS_WITH_WARRIOR : "french_kiss_with_warrior.msa", - chr.MOTION_FRENCH_KISS_WITH_ASSASSIN : "french_kiss_with_assassin.msa", - chr.MOTION_FRENCH_KISS_WITH_SURA : "french_kiss_with_sura.msa", - chr.MOTION_FRENCH_KISS_WITH_SHAMAN : "french_kiss_with_shaman.msa", - chr.MOTION_KISS_WITH_WARRIOR : "kiss_with_warrior.msa", - chr.MOTION_KISS_WITH_ASSASSIN : "kiss_with_assassin.msa", - chr.MOTION_KISS_WITH_SURA : "kiss_with_sura.msa", - chr.MOTION_KISS_WITH_SHAMAN : "kiss_with_shaman.msa", - chr.MOTION_SLAP_HIT_WITH_WARRIOR : "slap_hit.msa", - chr.MOTION_SLAP_HIT_WITH_ASSASSIN : "slap_hit.msa", - chr.MOTION_SLAP_HIT_WITH_SURA : "slap_hit.msa", - chr.MOTION_SLAP_HIT_WITH_SHAMAN : "slap_hit.msa", - chr.MOTION_SLAP_HURT_WITH_WARRIOR : "slap_hurt.msa", - chr.MOTION_SLAP_HURT_WITH_ASSASSIN : "slap_hurt.msa", - chr.MOTION_SLAP_HURT_WITH_SURA : "slap_hurt.msa", - chr.MOTION_SLAP_HURT_WITH_SHAMAN : "slap_hurt.msa", - } - -elif EMOTION_VERSION == 1: - EMOTION_CLAP = 1 - EMOTION_CHEERS_1 = 2 - EMOTION_CHEERS_2 = 3 - EMOTION_DANCE_1 = 4 - EMOTION_DANCE_2 = 5 - EMOTION_KISS = 51 - EMOTION_FRENCH_KISS = 52 - EMOTION_SLAP = 53 - - EMOTION_DICT = {} - - ICON_DICT = { - EMOTION_CLAP : "d:/ymir work/ui/game/windows/emotion_clap.sub", - EMOTION_CHEERS_1 : "d:/ymir work/ui/game/windows/emotion_cheers_1.sub", - EMOTION_CHEERS_2 : "d:/ymir work/ui/game/windows/emotion_cheers_2.sub", - - EMOTION_DANCE_1 : "icon/action/dance1.tga", - EMOTION_DANCE_2 : "icon/action/dance2.tga", - - EMOTION_KISS : "d:/ymir work/ui/game/windows/emotion_kiss.sub", - EMOTION_FRENCH_KISS : "d:/ymir work/ui/game/windows/emotion_french_kiss.sub", - EMOTION_SLAP : "d:/ymir work/ui/game/windows/emotion_slap.sub", - } - - ANI_DICT = { - chr.MOTION_CLAP : "clap.msa", - chr.MOTION_CHEERS_1 : "cheers_1.msa", - chr.MOTION_CHEERS_2 : "cheers_2.msa", - chr.MOTION_DANCE_1 : "dance_1.msa", - chr.MOTION_DANCE_2 : "dance_2.msa", - chr.MOTION_FRENCH_KISS_WITH_WARRIOR : "french_kiss_with_warrior.msa", - chr.MOTION_FRENCH_KISS_WITH_ASSASSIN : "french_kiss_with_assassin.msa", - chr.MOTION_FRENCH_KISS_WITH_SURA : "french_kiss_with_sura.msa", - chr.MOTION_FRENCH_KISS_WITH_SHAMAN : "french_kiss_with_shaman.msa", - chr.MOTION_KISS_WITH_WARRIOR : "kiss_with_warrior.msa", - chr.MOTION_KISS_WITH_ASSASSIN : "kiss_with_assassin.msa", - chr.MOTION_KISS_WITH_SURA : "kiss_with_sura.msa", - chr.MOTION_KISS_WITH_SHAMAN : "kiss_with_shaman.msa", - chr.MOTION_SLAP_HIT_WITH_WARRIOR : "slap_hit.msa", - chr.MOTION_SLAP_HIT_WITH_ASSASSIN : "slap_hit.msa", - chr.MOTION_SLAP_HIT_WITH_SURA : "slap_hit.msa", - chr.MOTION_SLAP_HIT_WITH_SHAMAN : "slap_hit.msa", - chr.MOTION_SLAP_HURT_WITH_WARRIOR : "slap_hurt.msa", - chr.MOTION_SLAP_HURT_WITH_ASSASSIN : "slap_hurt.msa", - chr.MOTION_SLAP_HURT_WITH_SURA : "slap_hurt.msa", - chr.MOTION_SLAP_HURT_WITH_SHAMAN : "slap_hurt.msa", - } -else: - EMOTION_CLAP = 1 - EMOTION_CHEERS_1 = 2 - EMOTION_CHEERS_2 = 3 - EMOTION_KISS = 51 - EMOTION_FRENCH_KISS = 52 - EMOTION_SLAP = 53 - - EMOTION_DICT = {} - - ICON_DICT = { - EMOTION_CLAP : "d:/ymir work/ui/game/windows/emotion_clap.sub", - EMOTION_CHEERS_1 : "d:/ymir work/ui/game/windows/emotion_cheers_1.sub", - EMOTION_CHEERS_2 : "d:/ymir work/ui/game/windows/emotion_cheers_2.sub", - - EMOTION_KISS : "d:/ymir work/ui/game/windows/emotion_kiss.sub", - EMOTION_FRENCH_KISS : "d:/ymir work/ui/game/windows/emotion_french_kiss.sub", - EMOTION_SLAP : "d:/ymir work/ui/game/windows/emotion_slap.sub", - } - - ANI_DICT = { - chr.MOTION_CLAP : "clap.msa", - chr.MOTION_CHEERS_1 : "cheers_1.msa", - chr.MOTION_CHEERS_2 : "cheers_2.msa", - chr.MOTION_FRENCH_KISS_WITH_WARRIOR : "french_kiss_with_warrior.msa", - chr.MOTION_FRENCH_KISS_WITH_ASSASSIN : "french_kiss_with_assassin.msa", - chr.MOTION_FRENCH_KISS_WITH_SURA : "french_kiss_with_sura.msa", - chr.MOTION_FRENCH_KISS_WITH_SHAMAN : "french_kiss_with_shaman.msa", - chr.MOTION_KISS_WITH_WARRIOR : "kiss_with_warrior.msa", - chr.MOTION_KISS_WITH_ASSASSIN : "kiss_with_assassin.msa", - chr.MOTION_KISS_WITH_SURA : "kiss_with_sura.msa", - chr.MOTION_KISS_WITH_SHAMAN : "kiss_with_shaman.msa", - chr.MOTION_SLAP_HIT_WITH_WARRIOR : "slap_hit.msa", - chr.MOTION_SLAP_HIT_WITH_ASSASSIN : "slap_hit.msa", - chr.MOTION_SLAP_HIT_WITH_SURA : "slap_hit.msa", - chr.MOTION_SLAP_HIT_WITH_SHAMAN : "slap_hit.msa", - chr.MOTION_SLAP_HURT_WITH_WARRIOR : "slap_hurt.msa", - chr.MOTION_SLAP_HURT_WITH_ASSASSIN : "slap_hurt.msa", - chr.MOTION_SLAP_HURT_WITH_SURA : "slap_hurt.msa", - chr.MOTION_SLAP_HURT_WITH_SHAMAN : "slap_hurt.msa", - } - - -def _RebuildLocaleStrings(): - global EMOTION_DICT - if EMOTION_VERSION == 2: - EMOTION_DICT = { - EMOTION_CLAP : {"name": localeInfo.EMOTION_CLAP, "command":"/clap"}, - EMOTION_DANCE_1 : {"name": localeInfo.EMOTION_DANCE_1, "command":"/dance1"}, - EMOTION_DANCE_2 : {"name": localeInfo.EMOTION_DANCE_2, "command":"/dance2"}, - EMOTION_DANCE_3 : {"name": localeInfo.EMOTION_DANCE_3, "command":"/dance3"}, - EMOTION_DANCE_4 : {"name": localeInfo.EMOTION_DANCE_4, "command":"/dance4"}, - EMOTION_DANCE_5 : {"name": localeInfo.EMOTION_DANCE_5, "command":"/dance5"}, - EMOTION_DANCE_6 : {"name": localeInfo.EMOTION_DANCE_6, "command":"/dance6"}, - EMOTION_CONGRATULATION : {"name": localeInfo.EMOTION_CONGRATULATION, "command":"/congratulation"}, - EMOTION_FORGIVE : {"name": localeInfo.EMOTION_FORGIVE, "command":"/forgive"}, - EMOTION_ANGRY : {"name": localeInfo.EMOTION_ANGRY, "command":"/angry"}, - EMOTION_ATTRACTIVE : {"name": localeInfo.EMOTION_ATTRACTIVE, "command":"/attractive"}, - EMOTION_SAD : {"name": localeInfo.EMOTION_SAD, "command":"/sad"}, - EMOTION_SHY : {"name": localeInfo.EMOTION_SHY, "command":"/shy"}, - EMOTION_CHEERUP : {"name": localeInfo.EMOTION_CHEERUP, "command":"/cheerup"}, - EMOTION_BANTER : {"name": localeInfo.EMOTION_BANTER, "command":"/banter"}, - EMOTION_JOY : {"name": localeInfo.EMOTION_JOY, "command":"/joy"}, - EMOTION_CHEERS_1 : {"name": localeInfo.EMOTION_CHEERS_1, "command":"/cheer1"}, - EMOTION_CHEERS_2 : {"name": localeInfo.EMOTION_CHEERS_2, "command":"/cheer2"}, - EMOTION_KISS : {"name": localeInfo.EMOTION_CLAP_KISS, "command":"/kiss"}, - EMOTION_FRENCH_KISS : {"name": localeInfo.EMOTION_FRENCH_KISS, "command":"/french_kiss"}, - EMOTION_SLAP : {"name": localeInfo.EMOTION_SLAP, "command":"/slap"}, - } - elif EMOTION_VERSION == 1: - EMOTION_DICT = { - EMOTION_CLAP : {"name": localeInfo.EMOTION_CLAP, "command":"/clap"}, - EMOTION_CHEERS_1 : {"name": localeInfo.EMOTION_CHEERS_1, "command":"/cheer1"}, - EMOTION_CHEERS_2 : {"name": localeInfo.EMOTION_CHEERS_2, "command":"/cheer2"}, - EMOTION_DANCE_1 : {"name": localeInfo.EMOTION_DANCE_1, "command":"/dance1"}, - EMOTION_DANCE_2 : {"name": localeInfo.EMOTION_DANCE_2, "command":"/dance2"}, - EMOTION_KISS : {"name": localeInfo.EMOTION_CLAP_KISS, "command":"/kiss"}, - EMOTION_FRENCH_KISS : {"name": localeInfo.EMOTION_FRENCH_KISS, "command":"/french_kiss"}, - EMOTION_SLAP : {"name": localeInfo.EMOTION_SLAP, "command":"/slap"}, - } - else: - EMOTION_DICT = { - EMOTION_CLAP : {"name": localeInfo.EMOTION_CLAP, "command":"/clap"}, - EMOTION_CHEERS_1 : {"name": localeInfo.EMOTION_CHEERS_1, "command":"/cheer1"}, - EMOTION_CHEERS_2 : {"name": localeInfo.EMOTION_CHEERS_2, "command":"/cheer2"}, - EMOTION_KISS : {"name": localeInfo.EMOTION_CLAP_KISS, "command":"/kiss"}, - EMOTION_FRENCH_KISS : {"name": localeInfo.EMOTION_FRENCH_KISS, "command":"/french_kiss"}, - EMOTION_SLAP : {"name": localeInfo.EMOTION_SLAP, "command":"/slap"}, - } - -_RebuildLocaleStrings() -localeInfo.RegisterReloadCallback(_RebuildLocaleStrings) - -def __RegisterSharedEmotionAnis(mode, path): - chrmgr.SetPathName(path) - chrmgr.RegisterMotionMode(mode) - - for key, val in list(ANI_DICT.items()): - chrmgr.RegisterMotionData(mode, key, val) - -def RegisterEmotionAnis(path): - actionPath = path + "action/" - weddingPath = path + "wedding/" - - __RegisterSharedEmotionAnis(chr.MOTION_MODE_GENERAL, actionPath) - __RegisterSharedEmotionAnis(chr.MOTION_MODE_WEDDING_DRESS, actionPath) - - chrmgr.SetPathName(weddingPath) - chrmgr.RegisterMotionMode(chr.MOTION_MODE_WEDDING_DRESS) - chrmgr.RegisterMotionData(chr.MOTION_MODE_WEDDING_DRESS, chr.MOTION_WAIT, "wait.msa") - chrmgr.RegisterMotionData(chr.MOTION_MODE_WEDDING_DRESS, chr.MOTION_WALK, "walk.msa") - chrmgr.RegisterMotionData(chr.MOTION_MODE_WEDDING_DRESS, chr.MOTION_RUN, "walk.msa") - -def RegisterEmotionIcons(): - for key, val in list(ICON_DICT.items()): - player.RegisterEmotionIcon(key, val) - diff --git a/tools/root/exception.py b/tools/root/exception.py deleted file mode 100644 index 29933fb7..00000000 --- a/tools/root/exception.py +++ /dev/null @@ -1,38 +0,0 @@ -def GetExceptionString(excTitle): - - import sys - (excType, excMsg, excTraceBack)=sys.exc_info() - - excText="" - excText+=chr(10) - - import traceback - traceLineList=traceback.extract_tb(excTraceBack) - - for traceLine in traceLineList: - if traceLine[3]: - excText+="%s(line:%d) %s - %s" % (traceLine[0], traceLine[1], traceLine[2], traceLine[3]) - else: - excText+="%s(line:%d) %s" % (traceLine[0], traceLine[1], traceLine[2]) - - excText+=chr(10) - - excText+=chr(10) - excText+="%s - %s:%s" % (excTitle, excType, excMsg) - excText+=chr(10) - - return excText - -def Abort(excTitle): - import dbg - excText=GetExceptionString(excTitle) - - dbg.TraceError(excText) - - import app - app.Abort() - - import sys - sys.exit() - - return 0 diff --git a/tools/root/game.py b/tools/root/game.py deleted file mode 100644 index e584410a..00000000 --- a/tools/root/game.py +++ /dev/null @@ -1,2232 +0,0 @@ -import os -import app -import dbg -import grp -import item -import background -import chr -import chrmgr -import player -import snd -import chat -import textTail -import snd -import net -import effect -import wndMgr -import fly -import systemSetting -import quest -import guild -import skill -import messenger -import localeInfo -import constInfo -import exchange -import ime - -import ui -import uiCommon -import uiPhaseCurtain -import uiMapNameShower -import uiAffectShower -import uiPlayerGauge -import uiCharacter -import uiTarget - -# PRIVATE_SHOP_PRICE_LIST -import uiPrivateShopBuilder -# END_OF_PRIVATE_SHOP_PRICE_LIST - -import mouseModule -import consoleModule -import localeInfo - -import playerSettingModule -import interfaceModule - -import musicInfo -import debugInfo -import stringCommander - -from _weakref import proxy - -# SCREENSHOT_CWDSAVE -SCREENSHOT_CWDSAVE = False -SCREENSHOT_DIR = None - -cameraDistance = 1550.0 -cameraPitch = 27.0 -cameraRotation = 0.0 -cameraHeight = 100.0 - -testAlignment = 0 - -class GameWindow(ui.ScriptWindow): - def __init__(self, stream): - ui.ScriptWindow.__init__(self, "GAME") - self.SetWindowName("game") - net.SetPhaseWindow(net.PHASE_WINDOW_GAME, self) - player.SetGameWindow(self) - - self.quickSlotPageIndex = 0 - self.lastPKModeSendedTime = 0 - self.pressNumber = None - - self.guildWarQuestionDialog = None - self.interface = None - self.targetBoard = None - self.console = None - self.mapNameShower = None - self.affectShower = None - self.playerGauge = None - - self.stream = stream - self.interface = interfaceModule.Interface() - self.interface.MakeInterface() - self.interface.ShowDefaultWindows() - - self.curtain = uiPhaseCurtain.PhaseCurtain() - self.curtain.speed = 0.03 - self.curtain.Hide() - - self.targetBoard = uiTarget.TargetBoard() - self.targetBoard.SetWhisperEvent(ui.__mem_func__(self.interface.OpenWhisperDialog)) - self.targetBoard.Hide() - - self.console = consoleModule.ConsoleWindow() - self.console.BindGameClass(self) - self.console.SetConsoleSize(wndMgr.GetScreenWidth(), 200) - self.console.Hide() - - self.mapNameShower = uiMapNameShower.MapNameShower() - self.affectShower = uiAffectShower.AffectShower() - - self.playerGauge = uiPlayerGauge.PlayerGauge(self) - self.playerGauge.Hide() - - #wj 2014.1.2. ESC key prioritizes closing DropQuestionDialog. However, itemDropQuestionDialog not initially declared, causing ERROR, so declared and initialized in init. - self.itemDropQuestionDialog = None - - self.__SetQuickSlotMode() - - self.__ServerCommand_Build() - self.__ProcessPreservedServerCommand() - - def __del__(self): - player.SetGameWindow(0) - net.ClearPhaseWindow(net.PHASE_WINDOW_GAME, self) - ui.ScriptWindow.__del__(self) - - def Open(self): - app.SetFrameSkip(1) - - self.SetSize(wndMgr.GetScreenWidth(), wndMgr.GetScreenHeight()) - - self.quickSlotPageIndex = 0 - self.PickingCharacterIndex = -1 - self.PickingItemIndex = -1 - self.consoleEnable = False - self.isShowDebugInfo = False - self.ShowNameFlag = False - - self.enableXMasBoom = False - self.startTimeXMasBoom = 0.0 - self.indexXMasBoom = 0 - - global cameraDistance, cameraPitch, cameraRotation, cameraHeight - - app.SetCamera(cameraDistance, cameraPitch, cameraRotation, cameraHeight) - - constInfo.SET_DEFAULT_CAMERA_MAX_DISTANCE() - constInfo.SET_DEFAULT_CHRNAME_COLOR() - constInfo.SET_DEFAULT_FOG_LEVEL() - constInfo.SET_DEFAULT_CONVERT_EMPIRE_LANGUAGE_ENABLE() - constInfo.SET_DEFAULT_USE_ITEM_WEAPON_TABLE_ATTACK_BONUS() - constInfo.SET_DEFAULT_USE_SKILL_EFFECT_ENABLE() - - # TWO_HANDED_WEAPON_ATTACK_SPEED_UP - constInfo.SET_TWO_HANDED_WEAPON_ATT_SPEED_DECREASE_VALUE() - # END_OF_TWO_HANDED_WEAPON_ATTACK_SPEED_UP - - import event - event.SetLeftTimeString(localeInfo.UI_LEFT_TIME) - - textTail.EnablePKTitle(constInfo.PVPMODE_ENABLE) - - if constInfo.PVPMODE_TEST_ENABLE: - self.testPKMode = ui.TextLine() - self.testPKMode.SetFontName(localeInfo.UI_DEF_FONT) - self.testPKMode.SetPosition(0, 15) - self.testPKMode.SetWindowHorizontalAlignCenter() - self.testPKMode.SetHorizontalAlignCenter() - self.testPKMode.SetFeather() - self.testPKMode.SetOutline() - self.testPKMode.Show() - - self.testAlignment = ui.TextLine() - self.testAlignment.SetFontName(localeInfo.UI_DEF_FONT) - self.testAlignment.SetPosition(0, 35) - self.testAlignment.SetWindowHorizontalAlignCenter() - self.testAlignment.SetHorizontalAlignCenter() - self.testAlignment.SetFeather() - self.testAlignment.SetOutline() - self.testAlignment.Show() - - self.__BuildKeyDict() - self.__BuildDebugInfo() - - # PRIVATE_SHOP_PRICE_LIST - uiPrivateShopBuilder.Clear() - # END_OF_PRIVATE_SHOP_PRICE_LIST - - # UNKNOWN_UPDATE - exchange.InitTrading() - # END_OF_UNKNOWN_UPDATE - - if debugInfo.IsDebugMode(): - self.ToggleDebugInfo() - - ## Sound - snd.SetMusicVolume(systemSetting.GetMusicVolume()) - snd.SetSoundVolume(systemSetting.GetSoundVolume()) - - netFieldMusicFileName = net.GetFieldMusicFileName() - if netFieldMusicFileName: - snd.FadeInMusic("BGM/" + netFieldMusicFileName) - elif musicInfo.fieldMusic != "": - snd.FadeInMusic("BGM/" + musicInfo.fieldMusic) - - self.__SetQuickSlotMode() - self.__SelectQuickPage(self.quickSlotPageIndex) - - self.SetFocus() - self.Show() - app.ShowCursor() - - net.SendEnterGamePacket() - - # START_GAME_ERROR_EXIT - try: - self.StartGame() - except: - import exception - exception.Abort("GameWindow.Open") - # END_OF_START_GAME_ERROR_EXIT - - # Cache list of items that NPC can craft via cube system - # ex) cubeInformation[20383] = [ {"rewordVNUM": 72723, "rewordCount": 1, "materialInfo": "101,1&102,2", "price": 999 }, ... ] - self.cubeInformation = {} - self.currentCubeNPC = 0 - - def Close(self): - self.Hide() - - global cameraDistance, cameraPitch, cameraRotation, cameraHeight - (cameraDistance, cameraPitch, cameraRotation, cameraHeight) = app.GetCamera() - - if musicInfo.fieldMusic != "": - snd.FadeOutMusic("BGM/" + musicInfo.fieldMusic) - - self.onPressKeyDict = None - self.onClickKeyDict = None - - chat.Close() - snd.StopAllSound() - grp.InitScreenEffect() - chr.Destroy() - textTail.Clear() - quest.Clear() - background.Destroy() - guild.Destroy() - messenger.Destroy() - skill.ClearSkillData() - wndMgr.Unlock() - mouseModule.mouseController.DeattachObject() - - if self.guildWarQuestionDialog: - self.guildWarQuestionDialog.Close() - - self.guildNameBoard = None - self.partyRequestQuestionDialog = None - self.partyInviteQuestionDialog = None - self.guildInviteQuestionDialog = None - self.guildWarQuestionDialog = None - self.messengerAddFriendQuestion = None - - # UNKNOWN_UPDATE - self.itemDropQuestionDialog = None - # END_OF_UNKNOWN_UPDATE - - # QUEST_CONFIRM - self.confirmDialog = None - # END_OF_QUEST_CONFIRM - - self.PrintCoord = None - self.FrameRate = None - self.Pitch = None - self.Splat = None - self.TextureNum = None - self.ObjectNum = None - self.ViewDistance = None - self.PrintMousePos = None - - self.ClearDictionary() - - self.playerGauge = None - self.mapNameShower = None - self.affectShower = None - - if self.console: - self.console.BindGameClass(0) - self.console.Close() - self.console=None - - if self.targetBoard: - self.targetBoard.Destroy() - self.targetBoard = None - - if self.interface: - self.interface.HideAllWindows() - self.interface.Close() - self.interface=None - - player.ClearSkillDict() - player.ResetCameraRotation() - - self.KillFocus() - app.HideCursor() - - print("---------------------------------------------------------------------------- CLOSE GAME WINDOW") - - def __BuildKeyDict(self): - onPressKeyDict = {} - - ##PressKey continuously applies while key is held. - - ## Used for number shortcut quickslots (subsequent numbers also reserved for quickslots) - ## F12 is client debug key, should not be used here. - onPressKeyDict[app.DIK_1] = lambda: self.__PressNumKey(1) - onPressKeyDict[app.DIK_2] = lambda: self.__PressNumKey(2) - onPressKeyDict[app.DIK_3] = lambda: self.__PressNumKey(3) - onPressKeyDict[app.DIK_4] = lambda: self.__PressNumKey(4) - onPressKeyDict[app.DIK_5] = lambda: self.__PressNumKey(5) - onPressKeyDict[app.DIK_6] = lambda: self.__PressNumKey(6) - onPressKeyDict[app.DIK_7] = lambda: self.__PressNumKey(7) - onPressKeyDict[app.DIK_8] = lambda: self.__PressNumKey(8) - onPressKeyDict[app.DIK_9] = lambda: self.__PressNumKey(9) - onPressKeyDict[app.DIK_F1] = lambda: self.__PressQuickSlot(4) - onPressKeyDict[app.DIK_F2] = lambda: self.__PressQuickSlot(5) - onPressKeyDict[app.DIK_F3] = lambda: self.__PressQuickSlot(6) - onPressKeyDict[app.DIK_F4] = lambda: self.__PressQuickSlot(7) - - onPressKeyDict[app.DIK_LALT] = lambda: self.ShowName() - onPressKeyDict[app.DIK_LCONTROL] = lambda: self.ShowMouseImage() - onPressKeyDict[app.DIK_SYSRQ] = lambda: self.SaveScreen() - onPressKeyDict[app.DIK_SPACE] = lambda: self.StartAttack() - - #Character movement keys - onPressKeyDict[app.DIK_UP] = lambda: self.MoveUp() - onPressKeyDict[app.DIK_DOWN] = lambda: self.MoveDown() - onPressKeyDict[app.DIK_LEFT] = lambda: self.MoveLeft() - onPressKeyDict[app.DIK_RIGHT] = lambda: self.MoveRight() - onPressKeyDict[app.DIK_W] = lambda: self.MoveUp() - onPressKeyDict[app.DIK_S] = lambda: self.MoveDown() - onPressKeyDict[app.DIK_A] = lambda: self.MoveLeft() - # MR-3: Keyboard-enabled deck toggling - onPressKeyDict[app.DIK_D] = lambda: self.__PressDKey() - # MR-3: -- END OF -- Keyboard-enabled deck toggling - - onPressKeyDict[app.DIK_E] = lambda: app.RotateCamera(app.CAMERA_TO_POSITIVE) - onPressKeyDict[app.DIK_R] = lambda: app.ZoomCamera(app.CAMERA_TO_NEGATIVE) - #onPressKeyDict[app.DIK_F] = lambda: app.ZoomCamera(app.CAMERA_TO_POSITIVE) - onPressKeyDict[app.DIK_T] = lambda: app.PitchCamera(app.CAMERA_TO_NEGATIVE) - onPressKeyDict[app.DIK_G] = lambda: self.__PressGKey() - onPressKeyDict[app.DIK_Q] = lambda: self.__PressQKey() - - onPressKeyDict[app.DIK_NUMPAD9] = lambda: app.MovieResetCamera() - onPressKeyDict[app.DIK_NUMPAD4] = lambda: app.MovieRotateCamera(app.CAMERA_TO_NEGATIVE) - onPressKeyDict[app.DIK_NUMPAD6] = lambda: app.MovieRotateCamera(app.CAMERA_TO_POSITIVE) - onPressKeyDict[app.DIK_PGUP] = lambda: app.MovieZoomCamera(app.CAMERA_TO_NEGATIVE) - onPressKeyDict[app.DIK_PGDN] = lambda: app.MovieZoomCamera(app.CAMERA_TO_POSITIVE) - onPressKeyDict[app.DIK_NUMPAD8] = lambda: app.MoviePitchCamera(app.CAMERA_TO_NEGATIVE) - onPressKeyDict[app.DIK_NUMPAD2] = lambda: app.MoviePitchCamera(app.CAMERA_TO_POSITIVE) - onPressKeyDict[app.DIK_GRAVE] = lambda: self.PickUpItem() - onPressKeyDict[app.DIK_Z] = lambda: self.PickUpItem() - # MR-3: Keyboard-enabled deck toggling - onPressKeyDict[app.DIK_C] = lambda: self.__PressCKey() - # MR-3: -- END OF -- Keyboard-enabled deck toggling - onPressKeyDict[app.DIK_V] = lambda state = "SKILL": self.interface.ToggleCharacterWindow(state) - #onPressKeyDict[app.DIK_B] = lambda state = "EMOTICON": self.interface.ToggleCharacterWindow(state) - onPressKeyDict[app.DIK_N] = lambda state = "QUEST": self.interface.ToggleCharacterWindow(state) - onPressKeyDict[app.DIK_I] = lambda: self.interface.ToggleInventoryWindow() - onPressKeyDict[app.DIK_O] = lambda: self.interface.ToggleDragonSoulWindowWithNoInfo() - onPressKeyDict[app.DIK_M] = lambda: self.interface.PressMKey() - #onPressKeyDict[app.DIK_H] = lambda: self.interface.OpenHelpWindow() - onPressKeyDict[app.DIK_ADD] = lambda: self.interface.MiniMapScaleUp() - onPressKeyDict[app.DIK_SUBTRACT] = lambda: self.interface.MiniMapScaleDown() - onPressKeyDict[app.DIK_L] = lambda: self.interface.ToggleChatLogWindow() - onPressKeyDict[app.DIK_COMMA] = lambda: self.ShowConsole() # "`" key - onPressKeyDict[app.DIK_LSHIFT] = lambda: self.__SetQuickPageMode() - - onPressKeyDict[app.DIK_J] = lambda: self.__PressJKey() - onPressKeyDict[app.DIK_H] = lambda: self.__PressHKey() - onPressKeyDict[app.DIK_B] = lambda: self.__PressBKey() - onPressKeyDict[app.DIK_F] = lambda: self.__PressFKey() - - # CUBE_TEST - #onPressKeyDict[app.DIK_K] = lambda : self.interface.OpenCubeWindow() - # CUBE_TEST_END - - self.onPressKeyDict = onPressKeyDict - - onClickKeyDict = {} - onClickKeyDict[app.DIK_UP] = lambda : self.StopUp() - onClickKeyDict[app.DIK_DOWN] = lambda : self.StopDown() - onClickKeyDict[app.DIK_LEFT] = lambda : self.StopLeft() - onClickKeyDict[app.DIK_RIGHT] = lambda : self.StopRight() - onClickKeyDict[app.DIK_SPACE] = lambda : self.EndAttack() - - onClickKeyDict[app.DIK_W] = lambda : self.StopUp() - onClickKeyDict[app.DIK_S] = lambda : self.StopDown() - onClickKeyDict[app.DIK_A] = lambda : self.StopLeft() - onClickKeyDict[app.DIK_D] = lambda : self.StopRight() - onClickKeyDict[app.DIK_Q] = lambda: app.RotateCamera(app.CAMERA_STOP) - onClickKeyDict[app.DIK_E] = lambda: app.RotateCamera(app.CAMERA_STOP) - onClickKeyDict[app.DIK_R] = lambda: app.ZoomCamera(app.CAMERA_STOP) - onClickKeyDict[app.DIK_F] = lambda: app.ZoomCamera(app.CAMERA_STOP) - onClickKeyDict[app.DIK_T] = lambda: app.PitchCamera(app.CAMERA_STOP) - onClickKeyDict[app.DIK_G] = lambda: self.__ReleaseGKey() - onClickKeyDict[app.DIK_NUMPAD4] = lambda: app.MovieRotateCamera(app.CAMERA_STOP) - onClickKeyDict[app.DIK_NUMPAD6] = lambda: app.MovieRotateCamera(app.CAMERA_STOP) - onClickKeyDict[app.DIK_PGUP] = lambda: app.MovieZoomCamera(app.CAMERA_STOP) - onClickKeyDict[app.DIK_PGDN] = lambda: app.MovieZoomCamera(app.CAMERA_STOP) - onClickKeyDict[app.DIK_NUMPAD8] = lambda: app.MoviePitchCamera(app.CAMERA_STOP) - onClickKeyDict[app.DIK_NUMPAD2] = lambda: app.MoviePitchCamera(app.CAMERA_STOP) - onClickKeyDict[app.DIK_LALT] = lambda: self.HideName() - onClickKeyDict[app.DIK_LCONTROL] = lambda: self.HideMouseImage() - onClickKeyDict[app.DIK_LSHIFT] = lambda: self.__SetQuickSlotMode() - - #if constInfo.PVPMODE_ACCELKEY_ENABLE: - # onClickKeyDict[app.DIK_B] = lambda: self.ChangePKMode() - - self.onClickKeyDict=onClickKeyDict - - # MR-3: Keyboard-enabled deck toggling - def __PressCKey(self): - if app.IsPressed(app.DIK_LCONTROL) or app.IsPressed(app.DIK_RCONTROL): - if self.interface.wndDragonSoul: - self.interface.wndDragonSoul.ActivateButtonClick(0) - else: - self.interface.ToggleCharacterWindow("STATUS") - - def __PressDKey(self): - if app.IsPressed(app.DIK_LCONTROL) or app.IsPressed(app.DIK_RCONTROL): - if self.interface.wndDragonSoul: - self.interface.wndDragonSoul.ActivateButtonClick(1) - else: - self.MoveRight() - # MR-3: -- END OF -- Keyboard-enabled deck toggling - - def __PressNumKey(self,num): - if app.IsPressed(app.DIK_LCONTROL) or app.IsPressed(app.DIK_RCONTROL): - - if num >= 1 and num <= 9: - if(chrmgr.IsPossibleEmoticon(-1)): - chrmgr.SetEmoticon(-1,int(num)-1) - net.SendEmoticon(int(num)-1) - else: - if num >= 1 and num <= 4: - self.pressNumber(num-1) - - def __ClickBKey(self): - if app.IsPressed(app.DIK_LCONTROL) or app.IsPressed(app.DIK_RCONTROL): - return - else: - if constInfo.PVPMODE_ACCELKEY_ENABLE: - self.ChangePKMode() - - - def __PressJKey(self): - if app.IsPressed(app.DIK_LCONTROL) or app.IsPressed(app.DIK_RCONTROL): - if player.IsMountingHorse(): - net.SendChatPacket("/unmount") - else: - #net.SendChatPacket("/user_horse_ride") - if not uiPrivateShopBuilder.IsBuildingPrivateShop(): - for i in range(player.INVENTORY_PAGE_SIZE): - if player.GetItemIndex(i) in (71114, 71116, 71118, 71120): - net.SendItemUsePacket(i) - break - def __PressHKey(self): - if app.IsPressed(app.DIK_LCONTROL) or app.IsPressed(app.DIK_RCONTROL): - net.SendChatPacket("/user_horse_ride") - else: - self.interface.OpenHelpWindow() - - def __PressBKey(self): - if app.IsPressed(app.DIK_LCONTROL) or app.IsPressed(app.DIK_RCONTROL): - net.SendChatPacket("/user_horse_back") - else: - state = "EMOTICON" - self.interface.ToggleCharacterWindow(state) - - def __PressFKey(self): - if app.IsPressed(app.DIK_LCONTROL) or app.IsPressed(app.DIK_RCONTROL): - net.SendChatPacket("/user_horse_feed") - else: - app.ZoomCamera(app.CAMERA_TO_POSITIVE) - - def __PressGKey(self): - if app.IsPressed(app.DIK_LCONTROL) or app.IsPressed(app.DIK_RCONTROL): - net.SendChatPacket("/ride") - else: - if self.ShowNameFlag: - self.interface.ToggleGuildWindow() - else: - app.PitchCamera(app.CAMERA_TO_POSITIVE) - - def __ReleaseGKey(self): - app.PitchCamera(app.CAMERA_STOP) - - def __PressQKey(self): - if app.IsPressed(app.DIK_LCONTROL) or app.IsPressed(app.DIK_RCONTROL): - if 0==interfaceModule.IsQBHide: - interfaceModule.IsQBHide = 1 - self.interface.HideAllQuestButton() - else: - interfaceModule.IsQBHide = 0 - self.interface.ShowAllQuestButton() - else: - app.RotateCamera(app.CAMERA_TO_NEGATIVE) - - def __SetQuickSlotMode(self): - self.pressNumber=ui.__mem_func__(self.__PressQuickSlot) - - def __SetQuickPageMode(self): - self.pressNumber=ui.__mem_func__(self.__SelectQuickPage) - - def __PressQuickSlot(self, localSlotIndex): - if app.IsRTL(): - if 0 <= localSlotIndex and localSlotIndex < 4: - player.RequestUseLocalQuickSlot(3-localSlotIndex) - else: - player.RequestUseLocalQuickSlot(11-localSlotIndex) - else: - player.RequestUseLocalQuickSlot(localSlotIndex) - - def __SelectQuickPage(self, pageIndex): - self.quickSlotPageIndex = pageIndex - player.SetQuickPage(pageIndex) - - def ToggleDebugInfo(self): - self.isShowDebugInfo = not self.isShowDebugInfo - - if self.isShowDebugInfo: - self.PrintCoord.Show() - self.FrameRate.Show() - self.Pitch.Show() - self.Splat.Show() - self.TextureNum.Show() - self.ObjectNum.Show() - self.ViewDistance.Show() - self.PrintMousePos.Show() - else: - self.PrintCoord.Hide() - self.FrameRate.Hide() - self.Pitch.Hide() - self.Splat.Hide() - self.TextureNum.Hide() - self.ObjectNum.Hide() - self.ViewDistance.Hide() - self.PrintMousePos.Hide() - - def __BuildDebugInfo(self): - ## Character Position Coordinate - self.PrintCoord = ui.TextLine() - self.PrintCoord.SetFontName(localeInfo.UI_DEF_FONT) - self.PrintCoord.SetPosition(wndMgr.GetScreenWidth() - 270, 0) - - ## Frame Rate - self.FrameRate = ui.TextLine() - self.FrameRate.SetFontName(localeInfo.UI_DEF_FONT) - self.FrameRate.SetPosition(wndMgr.GetScreenWidth() - 270, 20) - - ## Camera Pitch - self.Pitch = ui.TextLine() - self.Pitch.SetFontName(localeInfo.UI_DEF_FONT) - self.Pitch.SetPosition(wndMgr.GetScreenWidth() - 270, 40) - - ## Splat - self.Splat = ui.TextLine() - self.Splat.SetFontName(localeInfo.UI_DEF_FONT) - self.Splat.SetPosition(wndMgr.GetScreenWidth() - 270, 60) - - ## - self.PrintMousePos = ui.TextLine() - self.PrintMousePos.SetFontName(localeInfo.UI_DEF_FONT) - self.PrintMousePos.SetPosition(wndMgr.GetScreenWidth() - 270, 80) - - # TextureNum - self.TextureNum = ui.TextLine() - self.TextureNum.SetFontName(localeInfo.UI_DEF_FONT) - self.TextureNum.SetPosition(wndMgr.GetScreenWidth() - 270, 100) - - # Number of rendered objects - self.ObjectNum = ui.TextLine() - self.ObjectNum.SetFontName(localeInfo.UI_DEF_FONT) - self.ObjectNum.SetPosition(wndMgr.GetScreenWidth() - 270, 120) - - # View distance - self.ViewDistance = ui.TextLine() - self.ViewDistance.SetFontName(localeInfo.UI_DEF_FONT) - self.ViewDistance.SetPosition(0, 0) - - def __NotifyError(self, msg): - chat.AppendChat(chat.CHAT_TYPE_INFO, msg) - - def ChangePKMode(self): - - if not app.IsPressed(app.DIK_LCONTROL): - return - - if player.GetStatus(player.LEVEL) 5000: - answer = False - - net.SendPartyInviteAnswerPacket(partyLeaderVID, answer) - - self.partyInviteQuestionDialog.Close() - self.partyInviteQuestionDialog = None - - def AddPartyMember(self, pid, name): - self.interface.AddPartyMember(pid, name) - - def UpdatePartyMemberInfo(self, pid): - self.interface.UpdatePartyMemberInfo(pid) - - def RemovePartyMember(self, pid): - self.interface.RemovePartyMember(pid) - self.__RefreshTargetBoard() - - def LinkPartyMember(self, pid, vid): - self.interface.LinkPartyMember(pid, vid) - - def UnlinkPartyMember(self, pid): - self.interface.UnlinkPartyMember(pid) - - def UnlinkAllPartyMember(self): - self.interface.UnlinkAllPartyMember() - - def ExitParty(self): - self.interface.ExitParty() - self.RefreshTargetBoardByVID(self.targetBoard.GetTargetVID()) - - def ChangePartyParameter(self, distributionMode): - self.interface.ChangePartyParameter(distributionMode) - - ## Messenger - def OnMessengerAddFriendQuestion(self, name): - messengerAddFriendQuestion = uiCommon.QuestionDialog2() - messengerAddFriendQuestion.SetText1(localeInfo.MESSENGER_DO_YOU_ACCEPT_ADD_FRIEND_1 % (name)) - messengerAddFriendQuestion.SetText2(localeInfo.MESSENGER_DO_YOU_ACCEPT_ADD_FRIEND_2) - messengerAddFriendQuestion.SetAcceptEvent(ui.__mem_func__(self.OnAcceptAddFriend)) - messengerAddFriendQuestion.SetCancelEvent(ui.__mem_func__(self.OnDenyAddFriend)) - - messengerAddFriendQuestion.OnPressEscapeKey = ui.__mem_func__(self.OnDenyAddFriend) # ESC �� deny - - messengerAddFriendQuestion.Open() - messengerAddFriendQuestion.name = name - self.messengerAddFriendQuestion = messengerAddFriendQuestion - - def OnAcceptAddFriend(self): - name = self.messengerAddFriendQuestion.name - net.SendChatPacket("/messenger_auth y " + name) - self.OnCloseAddFriendQuestionDialog() - return True - - def OnDenyAddFriend(self): - name = self.messengerAddFriendQuestion.name - net.SendChatPacket("/messenger_auth n " + name) - self.OnCloseAddFriendQuestionDialog() - return True - - def OnCloseAddFriendQuestionDialog(self): - self.messengerAddFriendQuestion.Close() - self.messengerAddFriendQuestion = None - return True - - ## SafeBox - def OpenSafeboxWindow(self, size): - self.interface.OpenSafeboxWindow(size) - - def RefreshSafebox(self): - self.interface.RefreshSafebox() - - def RefreshSafeboxMoney(self): - self.interface.RefreshSafeboxMoney() - - # ITEM_MALL - def OpenMallWindow(self, size): - self.interface.OpenMallWindow(size) - - def RefreshMall(self): - self.interface.RefreshMall() - # END_OF_ITEM_MALL - - ## Guild - def RecvGuildInviteQuestion(self, guildID, guildName): - guildInviteQuestionDialog = uiCommon.QuestionDialog() - guildInviteQuestionDialog.SetText(guildName + localeInfo.GUILD_DO_YOU_JOIN) - guildInviteQuestionDialog.SetAcceptEvent(lambda arg=True: self.AnswerGuildInvite(arg)) - guildInviteQuestionDialog.SetCancelEvent(lambda arg=False: self.AnswerGuildInvite(arg)) - guildInviteQuestionDialog.Open() - guildInviteQuestionDialog.guildID = guildID - self.guildInviteQuestionDialog = guildInviteQuestionDialog - - def AnswerGuildInvite(self, answer): - - if not self.guildInviteQuestionDialog: - return - - guildLeaderVID = self.guildInviteQuestionDialog.guildID - net.SendGuildInviteAnswerPacket(guildLeaderVID, answer) - - self.guildInviteQuestionDialog.Close() - self.guildInviteQuestionDialog = None - - - def DeleteGuild(self): - self.interface.DeleteGuild() - - ## Clock - def ShowClock(self, second): - self.interface.ShowClock(second) - - def HideClock(self): - self.interface.HideClock() - - ## Emotion - def BINARY_ActEmotion(self, emotionIndex): - if self.interface.wndCharacter: - self.interface.wndCharacter.ActEmotion(emotionIndex) - - ############################################################################################### - ############################################################################################### - ## Keyboard Functions - - def CheckFocus(self): - if False == self.IsFocus(): - if True == self.interface.IsOpenChat(): - self.interface.ToggleChat() - - self.SetFocus() - - def SaveScreen(self): - print("save screen") - - # SCREENSHOT_CWDSAVE - if SCREENSHOT_CWDSAVE: - if not os.path.exists(os.getcwd()+os.sep+"screenshot"): - os.mkdir(os.getcwd()+os.sep+"screenshot") - - (succeeded, name) = grp.SaveScreenShotToPath(os.getcwd()+os.sep+"screenshot"+os.sep) - elif SCREENSHOT_DIR: - (succeeded, name) = grp.SaveScreenShot(SCREENSHOT_DIR) - else: - (succeeded, name) = grp.SaveScreenShot() - # END_OF_SCREENSHOT_CWDSAVE - - if succeeded: - pass - """ - chat.AppendChat(chat.CHAT_TYPE_INFO, name + localeInfo.SCREENSHOT_SAVE1) - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.SCREENSHOT_SAVE2) - """ - else: - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.SCREENSHOT_SAVE_FAILURE) - - def ShowConsole(self): - if debugInfo.IsDebugMode() or True == self.consoleEnable: - player.EndKeyWalkingImmediately() - self.console.OpenWindow() - - def ShowName(self): - self.ShowNameFlag = True - self.playerGauge.EnableShowAlways() - player.SetQuickPage(self.quickSlotPageIndex+1) - - # ADD_ALWAYS_SHOW_NAME - def __IsShowName(self): - - if systemSetting.IsAlwaysShowName(): - return True - - if self.ShowNameFlag: - return True - - return False - # END_OF_ADD_ALWAYS_SHOW_NAME - - def HideName(self): - self.ShowNameFlag = False - self.playerGauge.DisableShowAlways() - player.SetQuickPage(self.quickSlotPageIndex) - - def ShowMouseImage(self): - self.interface.ShowMouseImage() - - def HideMouseImage(self): - self.interface.HideMouseImage() - - def StartAttack(self): - player.SetAttackKeyState(True) - - def EndAttack(self): - player.SetAttackKeyState(False) - - def MoveUp(self): - player.SetSingleDIKKeyState(app.DIK_UP, True) - - def MoveDown(self): - player.SetSingleDIKKeyState(app.DIK_DOWN, True) - - def MoveLeft(self): - player.SetSingleDIKKeyState(app.DIK_LEFT, True) - - def MoveRight(self): - player.SetSingleDIKKeyState(app.DIK_RIGHT, True) - - def StopUp(self): - player.SetSingleDIKKeyState(app.DIK_UP, False) - - def StopDown(self): - player.SetSingleDIKKeyState(app.DIK_DOWN, False) - - def StopLeft(self): - player.SetSingleDIKKeyState(app.DIK_LEFT, False) - - def StopRight(self): - player.SetSingleDIKKeyState(app.DIK_RIGHT, False) - - def PickUpItem(self): - player.PickCloseItem() - - ############################################################################################### - ############################################################################################### - ## Event Handler - - def OnKeyDown(self, key): - if self.interface.wndWeb and self.interface.wndWeb.IsShow(): - return - - if key == app.DIK_ESC: - self.RequestDropItem(False) - constInfo.SET_ITEM_QUESTION_DIALOG_STATUS(0) - - try: - self.onPressKeyDict[key]() - except KeyError: - pass - except: - raise - - return True - - def OnKeyUp(self, key): - try: - self.onClickKeyDict[key]() - except KeyError: - pass - except: - raise - - return True - - def OnMouseLeftButtonDown(self): - if self.interface.BUILD_OnMouseLeftButtonDown(): - return - - if mouseModule.mouseController.isAttached(): - self.CheckFocus() - else: - hyperlink = ui.GetHyperlink() - if hyperlink: - return - else: - self.CheckFocus() - player.SetMouseState(player.MBT_LEFT, player.MBS_PRESS); - - return True - - def OnMouseLeftButtonUp(self): - - if self.interface.BUILD_OnMouseLeftButtonUp(): - return - - if mouseModule.mouseController.isAttached(): - - attachedType = mouseModule.mouseController.GetAttachedType() - attachedItemIndex = mouseModule.mouseController.GetAttachedItemIndex() - attachedItemSlotPos = mouseModule.mouseController.GetAttachedSlotNumber() - attachedItemCount = mouseModule.mouseController.GetAttachedItemCount() - - ## QuickSlot - if player.SLOT_TYPE_QUICK_SLOT == attachedType: - player.RequestDeleteGlobalQuickSlot(attachedItemSlotPos) - - ## Inventory - elif player.SLOT_TYPE_INVENTORY == attachedType: - - if player.ITEM_MONEY == attachedItemIndex: - self.__PutMoney(attachedType, attachedItemCount, self.PickingCharacterIndex) - else: - self.__PutItem(attachedType, attachedItemIndex, attachedItemSlotPos, attachedItemCount, self.PickingCharacterIndex) - - ## DragonSoul - elif player.SLOT_TYPE_DRAGON_SOUL_INVENTORY == attachedType: - self.__PutItem(attachedType, attachedItemIndex, attachedItemSlotPos, attachedItemCount, self.PickingCharacterIndex) - - mouseModule.mouseController.DeattachObject() - - else: - hyperlink = ui.GetHyperlink() - if hyperlink: - if app.IsPressed(app.DIK_LALT): - link = chat.GetLinkFromHyperlink(hyperlink) - ime.PasteString(link) - else: - self.interface.MakeHyperlinkTooltip(hyperlink) - return - else: - player.SetMouseState(player.MBT_LEFT, player.MBS_CLICK) - - #player.EndMouseWalking() - return True - - def __PutItem(self, attachedType, attachedItemIndex, attachedItemSlotPos, attachedItemCount, dstChrID): - if player.SLOT_TYPE_INVENTORY == attachedType or player.SLOT_TYPE_DRAGON_SOUL_INVENTORY == attachedType: - attachedInvenType = player.SlotTypeToInvenType(attachedType) - if True == chr.HasInstance(self.PickingCharacterIndex) and player.GetMainCharacterIndex() != dstChrID: - if player.IsEquipmentSlot(attachedItemSlotPos) and player.SLOT_TYPE_DRAGON_SOUL_INVENTORY != attachedType: - self.stream.popupWindow.Close() - self.stream.popupWindow.Open(localeInfo.EXCHANGE_FAILURE_EQUIP_ITEM, 0, localeInfo.UI_OK) - else: - # MR-3: Auto-deactivate auto potions before moving out (dragging onto character) - if attachedType == player.SLOT_TYPE_INVENTORY: - itemVnum = player.GetItemIndex(attachedInvenType, attachedItemSlotPos) - - if constInfo.IS_AUTO_POTION(itemVnum): - metinSocket = [player.GetItemMetinSocket(attachedInvenType, attachedItemSlotPos, j) for j in range(player.METIN_SOCKET_MAX_NUM)] - isActivated = (0 != int(metinSocket[0])) - - if isActivated: - net.SendItemUsePacket(attachedItemSlotPos) - # MR-3: -- END OF -- Auto-deactivate auto potions before moving out - if chr.IsNPC(dstChrID): - net.SendGiveItemPacket(dstChrID, attachedInvenType, attachedItemSlotPos, attachedItemCount) - else: - net.SendExchangeStartPacket(dstChrID) - net.SendExchangeItemAddPacket(attachedInvenType, attachedItemSlotPos, 0) - else: - self.__DropItem(attachedType, attachedItemIndex, attachedItemSlotPos, attachedItemCount) - - def __PutMoney(self, attachedType, attachedMoney, dstChrID): - if True == chr.HasInstance(dstChrID) and player.GetMainCharacterIndex() != dstChrID: - net.SendExchangeStartPacket(dstChrID) - net.SendExchangeElkAddPacket(attachedMoney) - else: - self.__DropMoney(attachedType, attachedMoney) - - def __DropMoney(self, attachedType, attachedMoney): - # PRIVATESHOP_DISABLE_ITEM_DROP - Prevent item dropping while private shop is open - if uiPrivateShopBuilder.IsBuildingPrivateShop(): - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.DROP_ITEM_FAILURE_PRIVATE_SHOP) - return - # END_OF_PRIVATESHOP_DISABLE_ITEM_DROP - - if attachedMoney>=1000: - self.stream.popupWindow.Close() - self.stream.popupWindow.Open(localeInfo.DROP_MONEY_FAILURE_1000_OVER, 0, localeInfo.UI_OK) - return - - itemDropQuestionDialog = uiCommon.QuestionDialog() - itemDropQuestionDialog.SetText(localeInfo.DO_YOU_DROP_MONEY % (attachedMoney)) - itemDropQuestionDialog.SetAcceptEvent(lambda arg=True: self.RequestDropItem(arg)) - itemDropQuestionDialog.SetCancelEvent(lambda arg=False: self.RequestDropItem(arg)) - itemDropQuestionDialog.Open() - itemDropQuestionDialog.dropType = attachedType - itemDropQuestionDialog.dropCount = attachedMoney - itemDropQuestionDialog.dropNumber = player.ITEM_MONEY - self.itemDropQuestionDialog = itemDropQuestionDialog - - def __DropItem(self, attachedType, attachedItemIndex, attachedItemSlotPos, attachedItemCount): - # PRIVATESHOP_DISABLE_ITEM_DROP - Prevent item dropping while private shop is open - if uiPrivateShopBuilder.IsBuildingPrivateShop(): - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.DROP_ITEM_FAILURE_PRIVATE_SHOP) - return - # END_OF_PRIVATESHOP_DISABLE_ITEM_DROP - - if player.SLOT_TYPE_INVENTORY == attachedType and player.IsEquipmentSlot(attachedItemSlotPos): - self.stream.popupWindow.Close() - self.stream.popupWindow.Open(localeInfo.DROP_ITEM_FAILURE_EQUIP_ITEM, 0, localeInfo.UI_OK) - - else: - if player.SLOT_TYPE_INVENTORY == attachedType: - dropItemIndex = player.GetItemIndex(attachedItemSlotPos) - - item.SelectItem(dropItemIndex) - dropItemName = item.GetItemName() - - ## Question Text - questionText = localeInfo.HOW_MANY_ITEM_DO_YOU_DROP(dropItemName, attachedItemCount) - - ## Dialog - itemDropQuestionDialog = uiCommon.QuestionDialog() - itemDropQuestionDialog.SetText(questionText) - itemDropQuestionDialog.SetAcceptEvent(lambda arg=True: self.RequestDropItem(arg)) - itemDropQuestionDialog.SetCancelEvent(lambda arg=False: self.RequestDropItem(arg)) - itemDropQuestionDialog.Open() - itemDropQuestionDialog.dropType = attachedType - itemDropQuestionDialog.dropNumber = attachedItemSlotPos - itemDropQuestionDialog.dropCount = attachedItemCount - self.itemDropQuestionDialog = itemDropQuestionDialog - - constInfo.SET_ITEM_QUESTION_DIALOG_STATUS(1) - elif player.SLOT_TYPE_DRAGON_SOUL_INVENTORY == attachedType: - dropItemIndex = player.GetItemIndex(player.DRAGON_SOUL_INVENTORY, attachedItemSlotPos) - - item.SelectItem(dropItemIndex) - dropItemName = item.GetItemName() - - ## Question Text - questionText = localeInfo.HOW_MANY_ITEM_DO_YOU_DROP(dropItemName, attachedItemCount) - - ## Dialog - itemDropQuestionDialog = uiCommon.QuestionDialog() - itemDropQuestionDialog.SetText(questionText) - itemDropQuestionDialog.SetAcceptEvent(lambda arg=True: self.RequestDropItem(arg)) - itemDropQuestionDialog.SetCancelEvent(lambda arg=False: self.RequestDropItem(arg)) - itemDropQuestionDialog.Open() - itemDropQuestionDialog.dropType = attachedType - itemDropQuestionDialog.dropNumber = attachedItemSlotPos - itemDropQuestionDialog.dropCount = attachedItemCount - self.itemDropQuestionDialog = itemDropQuestionDialog - - constInfo.SET_ITEM_QUESTION_DIALOG_STATUS(1) - - def RequestDropItem(self, answer): - if not self.itemDropQuestionDialog: - return - - if answer: - dropType = self.itemDropQuestionDialog.dropType - dropCount = self.itemDropQuestionDialog.dropCount - dropNumber = self.itemDropQuestionDialog.dropNumber - - if player.SLOT_TYPE_INVENTORY == dropType: - if dropNumber == player.ITEM_MONEY: - net.SendGoldDropPacketNew(dropCount) - snd.PlaySound("sound/ui/money.wav") - else: - # PRIVATESHOP_DISABLE_ITEM_DROP - self.__SendDropItemPacket(dropNumber, dropCount) - # END_OF_PRIVATESHOP_DISABLE_ITEM_DROP - elif player.SLOT_TYPE_DRAGON_SOUL_INVENTORY == dropType: - # PRIVATESHOP_DISABLE_ITEM_DROP - self.__SendDropItemPacket(dropNumber, dropCount, player.DRAGON_SOUL_INVENTORY) - # END_OF_PRIVATESHOP_DISABLE_ITEM_DROP - - self.itemDropQuestionDialog.Close() - self.itemDropQuestionDialog = None - - constInfo.SET_ITEM_QUESTION_DIALOG_STATUS(0) - - # PRIVATESHOP_DISABLE_ITEM_DROP - def __SendDropItemPacket(self, itemVNum, itemCount, itemInvenType = player.INVENTORY): - if uiPrivateShopBuilder.IsBuildingPrivateShop(): - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.DROP_ITEM_FAILURE_PRIVATE_SHOP) - return - - net.SendItemDropPacketNew(itemInvenType, itemVNum, itemCount) - # END_OF_PRIVATESHOP_DISABLE_ITEM_DROP - - def OnMouseRightButtonDown(self): - - self.CheckFocus() - - if True == mouseModule.mouseController.isAttached(): - mouseModule.mouseController.DeattachObject() - - else: - player.SetMouseState(player.MBT_RIGHT, player.MBS_PRESS) - - return True - - def OnMouseRightButtonUp(self): - if True == mouseModule.mouseController.isAttached(): - return True - - player.SetMouseState(player.MBT_RIGHT, player.MBS_CLICK) - return True - - def OnMouseMiddleButtonDown(self): - player.SetMouseMiddleButtonState(player.MBS_PRESS) - - def OnMouseMiddleButtonUp(self): - player.SetMouseMiddleButtonState(player.MBS_CLICK) - - def OnUpdate(self): - app.UpdateGame() - - if self.mapNameShower.IsShow(): - self.mapNameShower.Update() - - if self.isShowDebugInfo: - self.UpdateDebugInfo() - - if self.enableXMasBoom: - self.__XMasBoom_Update() - - self.interface.BUILD_OnUpdate() - - - def UpdateDebugInfo(self): - # - # Output character coordinates and FPS - (x, y, z) = player.GetMainCharacterPosition() - - nUpdateTime = app.GetUpdateTime() - nUpdateFPS = app.GetUpdateFPS() - nRenderFPS = app.GetRenderFPS() - nFaceCount = app.GetFaceCount() - fFaceSpeed = app.GetFaceSpeed() - nST = background.GetRenderShadowTime() - - (fAveRT, nCurRT) = app.GetRenderTime() - (iNum, fFogStart, fFogEnd, fFarCilp) = background.GetDistanceSetInfo() - (iPatch, iSplat, fSplatRatio, sTextureNum) = background.GetRenderedSplatNum() - - if iPatch == 0: - iPatch = 1 - - #(dwRenderedThing, dwRenderedCRC) = background.GetRenderedGraphicThingInstanceNum() - - self.PrintCoord.SetText("Coordinate: %.2f %.2f %.2f ATM: %d" % (x, y, z, app.GetAvailableTextureMemory() / (1024 * 1024))) - xMouse, yMouse = wndMgr.GetMousePosition() - self.PrintMousePos.SetText("MousePosition: %d %d" % (xMouse, yMouse)) - - self.FrameRate.SetText("UFPS: %3d UT: %3d FS %.2f" % (nUpdateFPS, nUpdateTime, fFaceSpeed)) - - if fAveRT > 1.0: - self.Pitch.SetText("RFPS: %3d RT: %.2f(%3d) FC: %d(%.2f) " % (nRenderFPS, fAveRT, nCurRT, nFaceCount, nFaceCount / fAveRT)) - - self.Splat.SetText("PATCH: %d SPLAT: %d BAD (%.2f)" % (iPatch, iSplat, fSplatRatio)) - #self.Pitch.SetText("Pitch: %.2f" % (app.GetCameraPitch()) - #self.TextureNum.SetText("TN : %s" % (sTextureNum)) - #self.ObjectNum.SetText("GTI : %d, CRC : %d" % (dwRenderedThing, dwRenderedCRC)) - self.ViewDistance.SetText("Num : %d, FS : %f, FE : %f, FC : %f" % (iNum, fFogStart, fFogEnd, fFarCilp)) - - def OnRender(self): - app.RenderGame() - - if self.console.Console.collision: - background.RenderCollision() - chr.RenderCollision() - - (x, y) = app.GetCursorPosition() - - ######################## - # Picking - ######################## - textTail.UpdateAllTextTail() - - if True == wndMgr.IsPickedWindow(self.hWnd): - - self.PickingCharacterIndex = chr.Pick() - - if -1 != self.PickingCharacterIndex: - textTail.ShowCharacterTextTail(self.PickingCharacterIndex) - if 0 != self.targetBoard.GetTargetVID(): - textTail.ShowCharacterTextTail(self.targetBoard.GetTargetVID()) - - # ADD_ALWAYS_SHOW_NAME - if not self.__IsShowName(): - self.PickingItemIndex = item.Pick() - if -1 != self.PickingItemIndex: - textTail.ShowItemTextTail(self.PickingItemIndex) - # END_OF_ADD_ALWAYS_SHOW_NAME - - ## Show all name in the range - - # ADD_ALWAYS_SHOW_NAME - if self.__IsShowName(): - textTail.ShowAllTextTail() - self.PickingItemIndex = textTail.Pick(x, y) - # END_OF_ADD_ALWAYS_SHOW_NAME - - textTail.UpdateShowingTextTail() - textTail.ArrangeTextTail() - - if -1 != self.PickingItemIndex: - textTail.SelectItemName(self.PickingItemIndex) - - grp.PopState() - grp.SetInterfaceRenderState() - - textTail.Render() - textTail.HideAllTextTail() - - def OnPressEscapeKey(self): - if app.TARGET == app.GetCursor(): - app.SetCursor(app.NORMAL) - - elif True == mouseModule.mouseController.isAttached(): - mouseModule.mouseController.DeattachObject() - - else: - self.interface.OpenSystemDialog() - - return True - - def OnIMEReturn(self): - if app.IsPressed(app.DIK_LSHIFT): - self.interface.OpenWhisperDialogWithoutTarget() - else: - self.interface.ToggleChat() - return True - - def OnPressExitKey(self): - self.interface.ToggleSystemDialog() - return True - - ## BINARY CALLBACK - ###################################################################################### - - # WEDDING - def BINARY_LoverInfo(self, name, lovePoint): - if self.interface.wndMessenger: - self.interface.wndMessenger.OnAddLover(name, lovePoint) - if self.affectShower: - self.affectShower.SetLoverInfo(name, lovePoint) - - def BINARY_UpdateLovePoint(self, lovePoint): - if self.interface.wndMessenger: - self.interface.wndMessenger.OnUpdateLovePoint(lovePoint) - if self.affectShower: - self.affectShower.OnUpdateLovePoint(lovePoint) - # END_OF_WEDDING - - # QUEST_CONFIRM - def BINARY_OnQuestConfirm(self, msg, timeout, pid): - confirmDialog = uiCommon.QuestionDialogWithTimeLimit() - confirmDialog.Open(msg, timeout) - confirmDialog.SetAcceptEvent(lambda answer=True, pid=pid: net.SendQuestConfirmPacket(answer, pid) or self.confirmDialog.Hide()) - confirmDialog.SetCancelEvent(lambda answer=False, pid=pid: net.SendQuestConfirmPacket(answer, pid) or self.confirmDialog.Hide()) - self.confirmDialog = confirmDialog - # END_OF_QUEST_CONFIRM - - # GIFT command - def Gift_Show(self): - self.interface.ShowGift() - - # CUBE - def BINARY_Cube_Open(self, npcVNUM): - self.currentCubeNPC = npcVNUM - - self.interface.OpenCubeWindow() - - - if npcVNUM not in self.cubeInformation: - net.SendChatPacket("/cube r_info") - else: - cubeInfoList = self.cubeInformation[npcVNUM] - - i = 0 - for cubeInfo in cubeInfoList: - self.interface.wndCube.AddCubeResultItem(cubeInfo["vnum"], cubeInfo["count"]) - - j = 0 - for materialList in cubeInfo["materialList"]: - for materialInfo in materialList: - itemVnum, itemCount = materialInfo - self.interface.wndCube.AddMaterialInfo(i, j, itemVnum, itemCount) - j = j + 1 - - i = i + 1 - - self.interface.wndCube.Refresh() - - def BINARY_Cube_Close(self): - self.interface.CloseCubeWindow() - - # Update required gold, expected product VNUM and count information - def BINARY_Cube_UpdateInfo(self, gold, itemVnum, count): - self.interface.UpdateCubeInfo(gold, itemVnum, count) - - def BINARY_Cube_Succeed(self, itemVnum, count): - print("Cube crafting successful") - self.interface.SucceedCubeWork(itemVnum, count) - pass - - def BINARY_Cube_Failed(self): - print("Cube crafting failed") - self.interface.FailedCubeWork() - pass - - def BINARY_Cube_ResultList(self, npcVNUM, listText): - # ResultList Text Format: 72723,1/72725,1/72730.1/50001,5 - list separated by "/" character - #print listText - - if npcVNUM == 0: - npcVNUM = self.currentCubeNPC - - self.cubeInformation[npcVNUM] = [] - - try: - for eachInfoText in listText.split("/"): - eachInfo = eachInfoText.split(",") - itemVnum = int(eachInfo[0]) - itemCount = int(eachInfo[1]) - - self.cubeInformation[npcVNUM].append({"vnum": itemVnum, "count": itemCount}) - self.interface.wndCube.AddCubeResultItem(itemVnum, itemCount) - - resultCount = len(self.cubeInformation[npcVNUM]) - requestCount = 7 - modCount = resultCount % requestCount - splitCount = resultCount // requestCount - - for i in range(splitCount): - #print("/cube r_info %d %d" % (i * requestCount, requestCount)) - net.SendChatPacket("/cube r_info %d %d" % (i * requestCount, requestCount)) - - if 0 < modCount: - #print("/cube r_info %d %d" % (splitCount * requestCount, modCount)) - net.SendChatPacket("/cube r_info %d %d" % (splitCount * requestCount, modCount)) - - except RuntimeError as msg: - dbg.TraceError(msg) - return 0 - - pass - - def BINARY_Cube_MaterialInfo(self, startIndex, listCount, listText): - # Material Text Format : 125,1|126,2|127,2|123,5&555,5&555,4/120000 - try: - #print listText - - if 3 > len(listText): - dbg.TraceError("Wrong Cube Material Infomation") - return 0 - - - - eachResultList = listText.split("@") - - cubeInfo = self.cubeInformation[self.currentCubeNPC] - - itemIndex = 0 - for eachResultText in eachResultList: - cubeInfo[startIndex + itemIndex]["materialList"] = [[], [], [], [], []] - materialList = cubeInfo[startIndex + itemIndex]["materialList"] - - gold = 0 - splitResult = eachResultText.split("/") - if 1 < len(splitResult): - gold = int(splitResult[1]) - - #print "splitResult : ", splitResult - eachMaterialList = splitResult[0].split("&") - - i = 0 - for eachMaterialText in eachMaterialList: - complicatedList = eachMaterialText.split("|") - - if 0 < len(complicatedList): - for complicatedText in complicatedList: - (itemVnum, itemCount) = complicatedText.split(",") - itemVnum = int(itemVnum) - itemCount = int(itemCount) - self.interface.wndCube.AddMaterialInfo(itemIndex + startIndex, i, itemVnum, itemCount) - - materialList[i].append((itemVnum, itemCount)) - - else: - itemVnum, itemCount = eachMaterialText.split(",") - itemVnum = int(itemVnum) - itemCount = int(itemCount) - self.interface.wndCube.AddMaterialInfo(itemIndex + startIndex, i, itemVnum, itemCount) - - materialList[i].append((itemVnum, itemCount)) - - i = i + 1 - - - - itemIndex = itemIndex + 1 - - self.interface.wndCube.Refresh() - - - except RuntimeError as msg: - dbg.TraceError(msg) - return 0 - - pass - - # END_OF_CUBE - - # Dragon Soul Stone - def BINARY_Highlight_Item(self, inven_type, inven_pos): - self.interface.Highligt_Item(inven_type, inven_pos) - - def BINARY_DragonSoulGiveQuilification(self): - self.interface.DragonSoulGiveQuilification() - - def BINARY_DragonSoulRefineWindow_Open(self): - self.interface.OpenDragonSoulRefineWindow() - - def BINARY_DragonSoulRefineWindow_RefineFail(self, reason, inven_type, inven_pos): - self.interface.FailDragonSoulRefine(reason, inven_type, inven_pos) - - def BINARY_DragonSoulRefineWindow_RefineSucceed(self, inven_type, inven_pos): - self.interface.SucceedDragonSoulRefine(inven_type, inven_pos) - - # END of DRAGON SOUL REFINE WINDOW - - def BINARY_SetBigMessage(self, message): - self.interface.bigBoard.SetTip(message) - - def BINARY_SetTipMessage(self, message): - self.interface.tipBoard.SetTip(message) - - def BINARY_AppendNotifyMessage(self, type): - if not type in localeInfo.NOTIFY_MESSAGE: - return - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.NOTIFY_MESSAGE[type]) - - def BINARY_ItemGet(self, itemName, itemCount): - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.ITEM_GET(itemName)) - - def BINARY_ItemGetFromParty(self, itemName, fromName, itemCount): - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.ITEM_GET_FROM_PARTY((fromName, itemName))) - - def BINARY_ItemDeliverToParty(self, itemName, toName, itemCount): - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.ITEM_DELIVER_TO_PARTY((toName, itemName))) - - def BINARY_Guild_EnterGuildArea(self, areaID): - self.interface.BULID_EnterGuildArea(areaID) - - def BINARY_Guild_ExitGuildArea(self, areaID): - self.interface.BULID_ExitGuildArea(areaID) - - def BINARY_GuildWar_OnSendDeclare(self, guildID): - pass - - def BINARY_GuildWar_OnRecvDeclare(self, guildID, warType): - mainCharacterName = player.GetMainCharacterName() - masterName = guild.GetGuildMasterName() - if mainCharacterName == masterName: - self.__GuildWar_OpenAskDialog(guildID, warType) - - def BINARY_GuildWar_OnRecvPoint(self, gainGuildID, opponentGuildID, point): - self.interface.OnRecvGuildWarPoint(gainGuildID, opponentGuildID, point) - - def BINARY_GuildWar_OnStart(self, guildSelf, guildOpp): - self.interface.OnStartGuildWar(guildSelf, guildOpp) - - def BINARY_GuildWar_OnEnd(self, guildSelf, guildOpp): - self.interface.OnEndGuildWar(guildSelf, guildOpp) - - def BINARY_BettingGuildWar_SetObserverMode(self, isEnable): - self.interface.BINARY_SetObserverMode(isEnable) - - def BINARY_BettingGuildWar_UpdateObserverCount(self, observerCount): - self.interface.wndMiniMap.UpdateObserverCount(observerCount) - - def __GuildWar_UpdateMemberCount(self, guildID1, memberCount1, guildID2, memberCount2, observerCount): - guildID1 = int(guildID1) - guildID2 = int(guildID2) - memberCount1 = int(memberCount1) - memberCount2 = int(memberCount2) - observerCount = int(observerCount) - - self.interface.UpdateMemberCount(guildID1, memberCount1, guildID2, memberCount2) - self.interface.wndMiniMap.UpdateObserverCount(observerCount) - - def __GuildWar_OpenAskDialog(self, guildID, warType): - - guildName = guild.GetGuildName(guildID) - - # REMOVED_GUILD_BUG_FIX - if "Noname" == guildName: - return - # END_OF_REMOVED_GUILD_BUG_FIX - - import uiGuild - questionDialog = uiGuild.AcceptGuildWarDialog() - questionDialog.SAFE_SetAcceptEvent(self.__GuildWar_OnAccept) - questionDialog.SAFE_SetCancelEvent(self.__GuildWar_OnDecline) - questionDialog.Open(guildName, warType) - - self.guildWarQuestionDialog = questionDialog - - def __GuildWar_CloseAskDialog(self): - self.guildWarQuestionDialog.Close() - self.guildWarQuestionDialog = None - - def __GuildWar_OnAccept(self): - - guildName = self.guildWarQuestionDialog.GetGuildName() - - net.SendChatPacket("/war " + guildName) - self.__GuildWar_CloseAskDialog() - - return 1 - - def __GuildWar_OnDecline(self): - - guildName = self.guildWarQuestionDialog.GetGuildName() - - net.SendChatPacket("/nowar " + guildName) - self.__GuildWar_CloseAskDialog() - - return 1 - ## BINARY CALLBACK - ###################################################################################### - - def __ServerCommand_Build(self): - serverCommandList={ - "ConsoleEnable" : self.__Console_Enable, - "DayMode" : self.__DayMode_Update, - "PRESERVE_DayMode" : self.__PRESERVE_DayMode_Update, - "CloseRestartWindow" : self.__RestartDialog_Close, - "OpenPrivateShop" : self.__PrivateShop_Open, - "PartyHealReady" : self.PartyHealReady, - "ShowMeSafeboxPassword" : self.AskSafeboxPassword, - "CloseSafebox" : self.CommandCloseSafebox, - - # ITEM_MALL - "CloseMall" : self.CommandCloseMall, - "ShowMeMallPassword" : self.AskMallPassword, - "item_mall" : self.__ItemMall_Open, - # END_OF_ITEM_MALL - - "RefineSuceeded" : self.RefineSuceededMessage, - "RefineFailed" : self.RefineFailedMessage, - "xmas_snow" : self.__XMasSnow_Enable, - "xmas_boom" : self.__XMasBoom_Enable, - "xmas_song" : self.__XMasSong_Enable, - "xmas_tree" : self.__XMasTree_Enable, - "newyear_boom" : self.__XMasBoom_Enable, - "PartyRequest" : self.__PartyRequestQuestion, - "PartyRequestDenied" : self.__PartyRequestDenied, - "horse_state" : self.__Horse_UpdateState, - "hide_horse_state" : self.__Horse_HideState, - "WarUC" : self.__GuildWar_UpdateMemberCount, - "test_server" : self.__EnableTestServerFlag, - "mall" : self.__InGameShop_Show, - - # WEDDING - "lover_login" : self.__LoginLover, - "lover_logout" : self.__LogoutLover, - "lover_near" : self.__LoverNear, - "lover_far" : self.__LoverFar, - "lover_divorce" : self.__LoverDivorce, - "PlayMusic" : self.__PlayMusic, - # END_OF_WEDDING - - # PRIVATE_SHOP_PRICE_LIST - "MyShopPriceList" : self.__PrivateShop_PriceList, - # END_OF_PRIVATE_SHOP_PRICE_LIST - } - - self.serverCommander=stringCommander.Analyzer() - for serverCommandItem in list(serverCommandList.items()): - self.serverCommander.SAFE_RegisterCallBack( - serverCommandItem[0], serverCommandItem[1] - ) - - def BINARY_ServerCommand_Run(self, line): - #dbg.TraceError(line) - try: - #print " BINARY_ServerCommand_Run", line - return self.serverCommander.Run(line) - except RuntimeError as msg: - dbg.TraceError(msg) - return 0 - - def __ProcessPreservedServerCommand(self): - try: - command = net.GetPreservedServerCommand() - while command: - print((" __ProcessPreservedServerCommand", command)) - self.serverCommander.Run(command) - command = net.GetPreservedServerCommand() - except RuntimeError as msg: - dbg.TraceError(msg) - return 0 - - def PartyHealReady(self): - self.interface.PartyHealReady() - - def AskSafeboxPassword(self): - self.interface.AskSafeboxPassword() - - # ITEM_MALL - def AskMallPassword(self): - self.interface.AskMallPassword() - - def __ItemMall_Open(self): - self.interface.OpenItemMall(); - - def CommandCloseMall(self): - self.interface.CommandCloseMall() - # END_OF_ITEM_MALL - - # MR-15: Update refine messages - def RefineSuceededMessage(self, arg = None): - snd.PlaySound("sound/ui/make_soket.wav") - self.PopupMessage(localeInfo.REFINE_SUCCESS) - - def RefineFailedMessage(self, arg = None): - snd.PlaySound("sound/ui/jaeryun_fail.wav") - # Use local refine_type and choose popup text similar to uirefine.OpenQuestionDialog - try: - refine_type = int(arg) if arg is not None else None - except Exception: - refine_type = None - - if refine_type == 3: - # type 3: show first special destroy-with-bonus message - self.PopupMessage(localeInfo.REFINE_FAILURE_KEEP_GRADE) - elif refine_type == 2: - # type 2: downgrade warning - self.PopupMessage(localeInfo.REFINE_FAILURE_GRADE_DOWN) - else: - self.PopupMessage(localeInfo.REFINE_FAILURE_DEL_ITEM) - # MR-15: -- END OF -- Update refine messages - - def CommandCloseSafebox(self): - self.interface.CommandCloseSafebox() - - # PRIVATE_SHOP_PRICE_LIST - def __PrivateShop_PriceList(self, itemVNum, itemPrice): - uiPrivateShopBuilder.SetPrivateShopItemPrice(itemVNum, itemPrice) - # END_OF_PRIVATE_SHOP_PRICE_LIST - - def __Horse_HideState(self): - self.affectShower.SetHorseState(0, 0, 0) - - def __Horse_UpdateState(self, level, health, battery): - self.affectShower.SetHorseState(int(level), int(health), int(battery)) - - def __IsXMasMap(self): - mapDict = ( "metin2_map_n_flame_01", - "metin2_map_n_desert_01", - "metin2_map_spiderdungeon", - "metin2_map_deviltower1", ) - - if background.GetCurrentMapName() in mapDict: - return False - - return True - - def __XMasSnow_Enable(self, mode): - - self.__XMasSong_Enable(mode) - - if "1"==mode: - - if not self.__IsXMasMap(): - return - - print("XMAS_SNOW ON") - background.EnableSnow(1) - - else: - print("XMAS_SNOW OFF") - background.EnableSnow(0) - - def __XMasBoom_Enable(self, mode): - if "1"==mode: - - if not self.__IsXMasMap(): - return - - print("XMAS_BOOM ON") - self.__DayMode_Update("dark") - self.enableXMasBoom = True - self.startTimeXMasBoom = app.GetTime() - else: - print("XMAS_BOOM OFF") - self.__DayMode_Update("light") - self.enableXMasBoom = False - - def __XMasTree_Enable(self, grade): - - print(("XMAS_TREE ", grade)) - background.SetXMasTree(int(grade)) - - def __XMasSong_Enable(self, mode): - if "1"==mode: - print("XMAS_SONG ON") - - XMAS_BGM = "xmas.mp3" - - if app.IsExistFile("BGM/" + XMAS_BGM)==1: - if musicInfo.fieldMusic != "": - snd.FadeOutMusic("BGM/" + musicInfo.fieldMusic) - - musicInfo.fieldMusic=XMAS_BGM - snd.FadeInMusic("BGM/" + musicInfo.fieldMusic) - - else: - print("XMAS_SONG OFF") - - if musicInfo.fieldMusic != "": - snd.FadeOutMusic("BGM/" + musicInfo.fieldMusic) - - musicInfo.fieldMusic=musicInfo.METIN2THEMA - snd.FadeInMusic("BGM/" + musicInfo.fieldMusic) - - def __RestartDialog_Close(self): - self.interface.CloseRestartDialog() - - def __Console_Enable(self): - constInfo.CONSOLE_ENABLE = True - self.consoleEnable = True - app.EnableSpecialCameraMode() - ui.EnablePaste(True) - - ## PrivateShop - def __PrivateShop_Open(self): - self.interface.OpenPrivateShopInputNameDialog() - - def BINARY_PrivateShop_Appear(self, vid, text): - self.interface.AppearPrivateShop(vid, text) - - def BINARY_PrivateShop_Disappear(self, vid): - self.interface.DisappearPrivateShop(vid) - - ## DayMode - def __PRESERVE_DayMode_Update(self, mode): - if "light"==mode: - background.SetEnvironmentData(0) - elif "dark"==mode: - - if not self.__IsXMasMap(): - return - - background.RegisterEnvironmentData(1, constInfo.ENVIRONMENT_NIGHT) - background.SetEnvironmentData(1) - - def __DayMode_Update(self, mode): - if "light"==mode: - self.curtain.SAFE_FadeOut(self.__DayMode_OnCompleteChangeToLight) - elif "dark"==mode: - - if not self.__IsXMasMap(): - return - - self.curtain.SAFE_FadeOut(self.__DayMode_OnCompleteChangeToDark) - - def __DayMode_OnCompleteChangeToLight(self): - background.SetEnvironmentData(0) - self.curtain.FadeIn() - - def __DayMode_OnCompleteChangeToDark(self): - background.RegisterEnvironmentData(1, constInfo.ENVIRONMENT_NIGHT) - background.SetEnvironmentData(1) - self.curtain.FadeIn() - - ## XMasBoom - def __XMasBoom_Update(self): - - self.BOOM_DATA_LIST = ( (2, 5), (5, 2), (7, 3), (10, 3), (20, 5) ) - if self.indexXMasBoom >= len(self.BOOM_DATA_LIST): - return - - boomTime = self.BOOM_DATA_LIST[self.indexXMasBoom][0] - boomCount = self.BOOM_DATA_LIST[self.indexXMasBoom][1] - - if app.GetTime() - self.startTimeXMasBoom > boomTime: - - self.indexXMasBoom += 1 - - for i in range(boomCount): - self.__XMasBoom_Boom() - - def __XMasBoom_Boom(self): - x, y, z = player.GetMainCharacterPosition() - randX = app.GetRandom(-150, 150) - randY = app.GetRandom(-150, 150) - - snd.PlaySound3D(x + randX, -y + randY, z, "sound/common/etc/salute.mp3") - - def __PartyRequestQuestion(self, vid): - vid = int(vid) - partyRequestQuestionDialog = uiCommon.QuestionDialog() - partyRequestQuestionDialog.SetText(chr.GetNameByVID(vid) + localeInfo.PARTY_DO_YOU_ACCEPT) - partyRequestQuestionDialog.SetAcceptText(localeInfo.UI_ACCEPT) - partyRequestQuestionDialog.SetCancelText(localeInfo.UI_DENY) - partyRequestQuestionDialog.SetAcceptEvent(lambda arg=True: self.__AnswerPartyRequest(arg)) - partyRequestQuestionDialog.SetCancelEvent(lambda arg=False: self.__AnswerPartyRequest(arg)) - partyRequestQuestionDialog.Open() - partyRequestQuestionDialog.vid = vid - self.partyRequestQuestionDialog = partyRequestQuestionDialog - - def __AnswerPartyRequest(self, answer): - if not self.partyRequestQuestionDialog: - return - - vid = self.partyRequestQuestionDialog.vid - - if answer: - net.SendChatPacket("/party_request_accept " + str(vid)) - else: - net.SendChatPacket("/party_request_deny " + str(vid)) - - self.partyRequestQuestionDialog.Close() - self.partyRequestQuestionDialog = None - - def __PartyRequestDenied(self): - self.PopupMessage(localeInfo.PARTY_REQUEST_DENIED) - - def __EnableTestServerFlag(self): - app.EnableTestServerFlag() - - def __InGameShop_Show(self, url): - self.interface.OpenWebWindow(url) - - # WEDDING - def __LoginLover(self): - if self.interface.wndMessenger: - self.interface.wndMessenger.OnLoginLover() - - def __LogoutLover(self): - if self.interface.wndMessenger: - self.interface.wndMessenger.OnLogoutLover() - if self.affectShower: - self.affectShower.HideLoverState() - - def __LoverNear(self): - if self.affectShower: - self.affectShower.ShowLoverState() - - def __LoverFar(self): - if self.affectShower: - self.affectShower.HideLoverState() - - def __LoverDivorce(self): - if self.interface.wndMessenger: - self.interface.wndMessenger.ClearLoverInfo() - if self.affectShower: - self.affectShower.ClearLoverState() - - def __PlayMusic(self, flag, filename): - flag = int(flag) - if flag: - snd.FadeOutAllMusic() - musicInfo.SaveLastPlayFieldMusic() - snd.FadeInMusic("BGM/" + filename) - else: - snd.FadeOutAllMusic() - musicInfo.LoadLastPlayFieldMusic() - snd.FadeInMusic("BGM/" + musicInfo.fieldMusic) - - # END_OF_WEDDING - - def SkillClearCoolTime(self, slotIndex): - self.interface.SkillClearCoolTime(slotIndex) - diff --git a/tools/root/grpblk.txt b/tools/root/grpblk.txt deleted file mode 100644 index e62967ab..00000000 --- a/tools/root/grpblk.txt +++ /dev/null @@ -1,15 +0,0 @@ -nv4_disp.dll 0006000e 000a1628 -nv4_disp.dll 0006000e 000a1460 -nv4_disp.dll 0006000e 000a14b7 -nv4_disp.dll 0006000e.000a1620 -nv4_disp.dll 0006000e.000a1628 -nv4_disp.dll 0006000e.000a1a25 -nv4_disp.dll 0006000e.000110ff -nv4_disp.dll 0006000e.000a1133 -nv4_disp.dll 0006000e.000a11ab -nv4_disp.dll 0006000e.000a1629 -nv4_disp.dll 0006000e.000a1820 -nv4_disp.dll 0006000e.000a14b7 -NVDD32.DLL 0004000d.00010b7e -ialmdd.dll 0004000d.000a0db6 -ialmdd.dll 0004000d.00010cc0 diff --git a/tools/root/interfacemodule.py b/tools/root/interfacemodule.py deleted file mode 100644 index 45f8d7cb..00000000 --- a/tools/root/interfacemodule.py +++ /dev/null @@ -1,1751 +0,0 @@ -## -## Interface -## -import constInfo -import systemSetting -import wndMgr -import chat -import app -import player -import uiTaskBar -import uiCharacter -import uiInventory -import uiDragonSoul -import uiChat -import uiMessenger -import guild - -import ui -import uiHelp -import uiWhisper -import uiPointReset -import uiShop -import uiExchange -import uiSystem -import uiRestart -import uiToolTip -import uiMiniMap -import uiParty -import uiSafebox -import uiGuild -import uiQuest -import uiPrivateShopBuilder -import uiCommon -import uiRefine -import uiEquipmentDialog -import uiGameButton -import uiTip -import uiCube -import miniMap -# ACCESSORY_REFINE_ADD_METIN_STONE -import uiselectitem -# END_OF_ACCESSORY_REFINE_ADD_METIN_STONE -import uiScriptLocale - -import event -import localeInfo - -IsQBHide = 0 -class Interface(object): - CHARACTER_STATUS_TAB = 1 - CHARACTER_SKILL_TAB = 2 - - def __init__(self): - systemSetting.SetInterfaceHandler(self) - self.windowOpenPosition = 0 - self.dlgWhisperWithoutTarget = None - self.inputDialog = None - self.tipBoard = None - self.bigBoard = None - # MR-11: Suppress quest button when quest dialog is open to prevent quest button flashing - self.questButtonSuppressed = False - # MR-11: -- END OF -- Suppress quest button when quest dialog is open to prevent quest button flashing - - # ITEM_MALL - self.mallPageDlg = None - # END_OF_ITEM_MALL - - self.wndWeb = None - self.wndTaskBar = None - self.wndCharacter = None - self.wndInventory = None - self.wndExpandedTaskBar = None - self.wndDragonSoul = None - self.wndDragonSoulRefine = None - self.wndChat = None - self.wndMessenger = None - self.wndMiniMap = None - self.wndGuild = None - self.wndGuildBuilding = None - - self.listGMName = {} - self.wndQuestWindow = {} - self.wndQuestWindowNewKey = 0 - self.privateShopAdvertisementBoardDict = {} - self.guildScoreBoardDict = {} - self.equipmentDialogDict = {} - event.SetInterfaceWindow(self) - - def __del__(self): - systemSetting.DestroyInterfaceHandler() - event.SetInterfaceWindow(None) - - ################################ - ## Make Windows & Dialogs - def __MakeUICurtain(self): - wndUICurtain = ui.Bar("TOP_MOST") - wndUICurtain.SetSize(wndMgr.GetScreenWidth(), wndMgr.GetScreenHeight()) - wndUICurtain.SetColor(0x77000000) - wndUICurtain.Hide() - self.wndUICurtain = wndUICurtain - - def __MakeMessengerWindow(self): - self.wndMessenger = uiMessenger.MessengerWindow() - - from _weakref import proxy - self.wndMessenger.SetWhisperButtonEvent(lambda n,i=proxy(self):i.OpenWhisperDialog(n)) - self.wndMessenger.SetGuildButtonEvent(ui.__mem_func__(self.ToggleGuildWindow)) - - def __MakeGuildWindow(self): - self.wndGuild = uiGuild.GuildWindow() - - def __MakeChatWindow(self): - wndChat = uiChat.ChatWindow() - - wndChat.SetSize(wndChat.CHAT_WINDOW_WIDTH, 0) - wndChat.SetPosition(wndMgr.GetScreenWidth() // 2 - wndChat.CHAT_WINDOW_WIDTH // 2, wndMgr.GetScreenHeight() - wndChat.EDIT_LINE_HEIGHT - 37) - wndChat.SetHeight(200) - wndChat.Refresh() - wndChat.Show() - - self.wndChat = wndChat - self.wndChat.BindInterface(self) - self.wndChat.SetSendWhisperEvent(ui.__mem_func__(self.OpenWhisperDialogWithoutTarget)) - self.wndChat.SetOpenChatLogEvent(ui.__mem_func__(self.ToggleChatLogWindow)) - - def __MakeTaskBar(self): - wndTaskBar = uiTaskBar.TaskBar() - wndTaskBar.LoadWindow() - self.wndTaskBar = wndTaskBar - self.wndTaskBar.SetToggleButtonEvent(uiTaskBar.TaskBar.BUTTON_CHARACTER, ui.__mem_func__(self.ToggleCharacterWindowStatusPage)) - self.wndTaskBar.SetToggleButtonEvent(uiTaskBar.TaskBar.BUTTON_INVENTORY, ui.__mem_func__(self.ToggleInventoryWindow)) - self.wndTaskBar.SetToggleButtonEvent(uiTaskBar.TaskBar.BUTTON_MESSENGER, ui.__mem_func__(self.ToggleMessenger)) - self.wndTaskBar.SetToggleButtonEvent(uiTaskBar.TaskBar.BUTTON_SYSTEM, ui.__mem_func__(self.ToggleSystemDialog)) - if uiTaskBar.TaskBar.IS_EXPANDED: - self.wndTaskBar.SetToggleButtonEvent(uiTaskBar.TaskBar.BUTTON_EXPAND, ui.__mem_func__(self.ToggleExpandedButton)) - self.wndExpandedTaskBar = uiTaskBar.ExpandedTaskBar() - self.wndExpandedTaskBar.LoadWindow() - self.wndExpandedTaskBar.SetToggleButtonEvent(uiTaskBar.ExpandedTaskBar.BUTTON_DRAGON_SOUL, ui.__mem_func__(self.ToggleDragonSoulWindow)) - - else: - self.wndTaskBar.SetToggleButtonEvent(uiTaskBar.TaskBar.BUTTON_CHAT, ui.__mem_func__(self.ToggleChat)) - - self.wndEnergyBar = None - import app - if app.ENABLE_ENERGY_SYSTEM: - wndEnergyBar = uiTaskBar.EnergyBar() - wndEnergyBar.LoadWindow() - self.wndEnergyBar = wndEnergyBar - - def __MakeParty(self): - wndParty = uiParty.PartyWindow() - wndParty.Hide() - self.wndParty = wndParty - - def __MakeGameButtonWindow(self): - wndGameButton = uiGameButton.GameButtonWindow() - wndGameButton.SetTop() - wndGameButton.Show() - wndGameButton.SetButtonEvent("STATUS", ui.__mem_func__(self.__OnClickStatusPlusButton)) - wndGameButton.SetButtonEvent("SKILL", ui.__mem_func__(self.__OnClickSkillPlusButton)) - wndGameButton.SetButtonEvent("QUEST", ui.__mem_func__(self.__OnClickQuestButton)) - wndGameButton.SetButtonEvent("HELP", ui.__mem_func__(self.__OnClickHelpButton)) - wndGameButton.SetButtonEvent("BUILD", ui.__mem_func__(self.__OnClickBuildButton)) - - self.wndGameButton = wndGameButton - - def __IsChatOpen(self): - return True - - def __MakeWindows(self): - wndCharacter = uiCharacter.CharacterWindow() - wndInventory = uiInventory.InventoryWindow() - wndInventory.BindInterfaceClass(self) - if app.ENABLE_DRAGON_SOUL_SYSTEM: - wndDragonSoul = uiDragonSoul.DragonSoulWindow() - wndDragonSoul.BindInterfaceClass(self) - wndDragonSoulRefine = uiDragonSoul.DragonSoulRefineWindow() - else: - wndDragonSoul = None - wndDragonSoulRefine = None - - wndMiniMap = uiMiniMap.MiniMap() - wndSafebox = uiSafebox.SafeboxWindow() - - # ITEM_MALL - wndMall = uiSafebox.MallWindow() - self.wndMall = wndMall - # END_OF_ITEM_MALL - - wndChatLog = uiChat.ChatLogWindow() - wndChatLog.BindInterface(self) - - self.wndCharacter = wndCharacter - self.wndInventory = wndInventory - self.wndDragonSoul = wndDragonSoul - self.wndDragonSoulRefine = wndDragonSoulRefine - self.wndMiniMap = wndMiniMap - self.wndSafebox = wndSafebox - self.wndChatLog = wndChatLog - - if app.ENABLE_DRAGON_SOUL_SYSTEM: - self.wndDragonSoul.SetDragonSoulRefineWindow(self.wndDragonSoulRefine) - self.wndDragonSoulRefine.SetInventoryWindows(self.wndInventory, self.wndDragonSoul) - self.wndInventory.SetDragonSoulRefineWindow(self.wndDragonSoulRefine) - - def __MakeDialogs(self): - self.dlgExchange = uiExchange.ExchangeDialog() - self.dlgExchange.LoadDialog() - self.dlgExchange.SetCenterPosition() - self.dlgExchange.Hide() - - self.dlgPointReset = uiPointReset.PointResetDialog() - self.dlgPointReset.LoadDialog() - self.dlgPointReset.Hide() - - self.dlgShop = uiShop.ShopDialog() - self.dlgShop.LoadDialog() - self.dlgShop.Hide() - - self.dlgRestart = uiRestart.RestartDialog() - self.dlgRestart.LoadDialog() - self.dlgRestart.Hide() - - self.dlgSystem = uiSystem.SystemDialog() - self.dlgSystem.LoadDialog() - self.dlgSystem.SetOpenHelpWindowEvent(ui.__mem_func__(self.OpenHelpWindow)) - - self.dlgSystem.Hide() - - self.dlgPassword = uiSafebox.PasswordDialog() - self.dlgPassword.Hide() - - self.hyperlinkItemTooltip = uiToolTip.HyperlinkItemToolTip() - self.hyperlinkItemTooltip.Hide() - - self.tooltipItem = uiToolTip.ItemToolTip() - self.tooltipItem.Hide() - - self.tooltipSkill = uiToolTip.SkillToolTip() - self.tooltipSkill.Hide() - - self.privateShopBuilder = uiPrivateShopBuilder.PrivateShopBuilder() - self.privateShopBuilder.Hide() - - self.dlgRefineNew = uiRefine.RefineDialogNew() - self.dlgRefineNew.Hide() - - def __MakeHelpWindow(self): - self.wndHelp = uiHelp.HelpWindow() - self.wndHelp.LoadDialog() - self.wndHelp.SetCloseEvent(ui.__mem_func__(self.CloseHelpWindow)) - self.wndHelp.Hide() - - def __MakeTipBoard(self): - self.tipBoard = uiTip.TipBoard() - self.tipBoard.Hide() - - self.bigBoard = uiTip.BigBoard() - self.bigBoard.Hide() - - def __MakeWebWindow(self): - import uiWeb - self.wndWeb = uiWeb.WebWindow() - self.wndWeb.LoadWindow() - self.wndWeb.Hide() - - def __MakeCubeWindow(self): - self.wndCube = uiCube.CubeWindow() - self.wndCube.LoadWindow() - self.wndCube.Hide() - - def __MakeCubeResultWindow(self): - self.wndCubeResult = uiCube.CubeResultWindow() - self.wndCubeResult.LoadWindow() - self.wndCubeResult.Hide() - - # ACCESSORY_REFINE_ADD_METIN_STONE - def __MakeItemSelectWindow(self): - self.wndItemSelect = uiselectitem.SelectItemWindow() - self.wndItemSelect.Hide() - # END_OF_ACCESSORY_REFINE_ADD_METIN_STONE - - def MakeInterface(self): - self.__MakeMessengerWindow() - self.__MakeGuildWindow() - self.__MakeChatWindow() - self.__MakeParty() - self.__MakeWindows() - self.__MakeDialogs() - - self.__MakeUICurtain() - self.__MakeTaskBar() - self.__MakeGameButtonWindow() - self.__MakeHelpWindow() - self.__MakeTipBoard() - self.__MakeWebWindow() - self.__MakeCubeWindow() - self.__MakeCubeResultWindow() - - - # ACCESSORY_REFINE_ADD_METIN_STONE - self.__MakeItemSelectWindow() - # END_OF_ACCESSORY_REFINE_ADD_METIN_STONE - - self.questButtonList = [] - self.whisperButtonList = [] - self.whisperDialogDict = {} - self.privateShopAdvertisementBoardDict = {} - - self.wndMessenger.InitializeHandler() - - self.wndInventory.SetItemToolTip(self.tooltipItem) - - if app.ENABLE_DRAGON_SOUL_SYSTEM: - self.wndDragonSoul.SetItemToolTip(self.tooltipItem) - self.wndDragonSoulRefine.SetItemToolTip(self.tooltipItem) - - self.wndSafebox.SetItemToolTip(self.tooltipItem) - self.wndCube.SetItemToolTip(self.tooltipItem) - self.wndCubeResult.SetItemToolTip(self.tooltipItem) - - # ITEM_MALL - self.wndMall.SetItemToolTip(self.tooltipItem) - # END_OF_ITEM_MALL - - self.wndCharacter.SetSkillToolTip(self.tooltipSkill) - self.wndTaskBar.SetItemToolTip(self.tooltipItem) - self.wndTaskBar.SetSkillToolTip(self.tooltipSkill) - self.wndGuild.SetSkillToolTip(self.tooltipSkill) - - # ACCESSORY_REFINE_ADD_METIN_STONE - self.wndItemSelect.SetItemToolTip(self.tooltipItem) - # END_OF_ACCESSORY_REFINE_ADD_METIN_STONE - - self.dlgShop.SetItemToolTip(self.tooltipItem) - self.dlgExchange.SetItemToolTip(self.tooltipItem) - self.privateShopBuilder.SetItemToolTip(self.tooltipItem) - - self.__InitWhisper() - self.DRAGON_SOUL_IS_QUALIFIED = False - - def MakeHyperlinkTooltip(self, hyperlink): - tokens = hyperlink.split(":") - if tokens and len(tokens): - type = tokens[0] - if "item" == type: - self.hyperlinkItemTooltip.SetHyperlinkItem(tokens) - - ## Make Windows & Dialogs - ################################ - - def Close(self): - if self.dlgWhisperWithoutTarget: - self.dlgWhisperWithoutTarget.Destroy() - del self.dlgWhisperWithoutTarget - - if "QuestCurtain" in uiQuest.QuestDialog.__dict__: - uiQuest.QuestDialog.QuestCurtain.Close() - - if self.wndQuestWindow: - for key, eachQuestWindow in list(self.wndQuestWindow.items()): - eachQuestWindow.nextCurtainMode = -1 - eachQuestWindow.CloseSelf() - eachQuestWindow = None - self.wndQuestWindow = {} - - if self.wndChat: - self.wndChat.Destroy() - - if self.wndTaskBar: - self.wndTaskBar.Destroy() - - if self.wndExpandedTaskBar: - self.wndExpandedTaskBar.Destroy() - - if self.wndEnergyBar: - self.wndEnergyBar.Destroy() - - if self.wndCharacter: - self.wndCharacter.Destroy() - - if self.wndInventory: - self.wndInventory.Destroy() - - if self.wndDragonSoul: - self.wndDragonSoul.Destroy() - - if self.wndDragonSoulRefine: - self.wndDragonSoulRefine.Destroy() - - if self.dlgExchange: - self.dlgExchange.Destroy() - - if self.dlgPointReset: - self.dlgPointReset.Destroy() - - if self.dlgShop: - self.dlgShop.Destroy() - - if self.dlgRestart: - self.dlgRestart.Destroy() - - if self.dlgSystem: - self.dlgSystem.Destroy() - - if self.dlgPassword: - self.dlgPassword.Destroy() - - if self.wndMiniMap: - self.wndMiniMap.Destroy() - - if self.wndSafebox: - self.wndSafebox.Destroy() - - if self.wndWeb: - self.wndWeb.Destroy() - self.wndWeb = None - - if self.wndMall: - self.wndMall.Destroy() - - if self.wndParty: - self.wndParty.Destroy() - - if self.wndHelp: - self.wndHelp.Destroy() - - if self.wndCube: - self.wndCube.Destroy() - - if self.wndCubeResult: - self.wndCubeResult.Destroy() - - if self.wndMessenger: - self.wndMessenger.Destroy() - - if self.wndGuild: - self.wndGuild.Destroy() - - if self.privateShopBuilder: - self.privateShopBuilder.Destroy() - - if self.dlgRefineNew: - self.dlgRefineNew.Destroy() - - if self.wndGuildBuilding: - self.wndGuildBuilding.Destroy() - - if self.wndGameButton: - self.wndGameButton.Destroy() - - # ITEM_MALL - if self.mallPageDlg: - self.mallPageDlg.Destroy() - # END_OF_ITEM_MALL - - # ACCESSORY_REFINE_ADD_METIN_STONE - if self.wndItemSelect: - self.wndItemSelect.Destroy() - # END_OF_ACCESSORY_REFINE_ADD_METIN_STONE - - self.wndChatLog.Destroy() - for btn in self.questButtonList: - btn.SetEvent(0) - for btn in self.whisperButtonList: - btn.SetEvent(0) - for dlg in list(self.whisperDialogDict.values()): - dlg.Destroy() - for brd in list(self.guildScoreBoardDict.values()): - brd.Destroy() - for dlg in list(self.equipmentDialogDict.values()): - dlg.Destroy() - - # ITEM_MALL - del self.mallPageDlg - # END_OF_ITEM_MALL - - del self.wndGuild - del self.wndMessenger - del self.wndUICurtain - del self.wndChat - del self.wndTaskBar - if self.wndExpandedTaskBar: - del self.wndExpandedTaskBar - del self.wndEnergyBar - del self.wndCharacter - del self.wndInventory - if self.wndDragonSoul: - del self.wndDragonSoul - if self.wndDragonSoulRefine: - del self.wndDragonSoulRefine - del self.dlgExchange - del self.dlgPointReset - del self.dlgShop - del self.dlgRestart - del self.dlgSystem - del self.dlgPassword - del self.hyperlinkItemTooltip - del self.tooltipItem - del self.tooltipSkill - del self.wndMiniMap - del self.wndSafebox - del self.wndMall - del self.wndParty - del self.wndHelp - del self.wndCube - del self.wndCubeResult - del self.privateShopBuilder - del self.inputDialog - del self.wndChatLog - del self.dlgRefineNew - del self.wndGuildBuilding - del self.wndGameButton - del self.tipBoard - del self.bigBoard - del self.wndItemSelect - - self.questButtonList = [] - self.whisperButtonList = [] - self.whisperDialogDict = {} - self.privateShopAdvertisementBoardDict = {} - self.guildScoreBoardDict = {} - self.equipmentDialogDict = {} - - uiChat.DestroyChatInputSetWindow() - - ## Skill - def OnUseSkill(self, slotIndex, coolTime): - self.wndCharacter.OnUseSkill(slotIndex, coolTime) - self.wndTaskBar.OnUseSkill(slotIndex, coolTime) - self.wndGuild.OnUseSkill(slotIndex, coolTime) - - def OnActivateSkill(self, slotIndex): - self.wndCharacter.OnActivateSkill(slotIndex) - self.wndTaskBar.OnActivateSkill(slotIndex) - - def OnDeactivateSkill(self, slotIndex): - self.wndCharacter.OnDeactivateSkill(slotIndex) - self.wndTaskBar.OnDeactivateSkill(slotIndex) - - def OnChangeCurrentSkill(self, skillSlotNumber): - self.wndTaskBar.OnChangeCurrentSkill(skillSlotNumber) - - def SkillClearCoolTime(self, slotIndex): - self.wndCharacter.SkillClearCoolTime(slotIndex) - self.wndTaskBar.SkillClearCoolTime(slotIndex) - - def SelectMouseButtonEvent(self, dir, event): - self.wndTaskBar.SelectMouseButtonEvent(dir, event) - - ## Refresh - def RefreshAlignment(self): - self.wndCharacter.RefreshAlignment() - - def RefreshStatus(self): - self.wndTaskBar.RefreshStatus() - self.wndCharacter.RefreshStatus() - self.wndInventory.RefreshStatus() - if self.wndEnergyBar: - self.wndEnergyBar.RefreshStatus() - if app.ENABLE_DRAGON_SOUL_SYSTEM: - self.wndDragonSoul.RefreshStatus() - - def RefreshStamina(self): - self.wndTaskBar.RefreshStamina() - - def RefreshSkill(self): - self.wndCharacter.RefreshSkill() - self.wndTaskBar.RefreshSkill() - - def RefreshInventory(self): - self.wndTaskBar.RefreshQuickSlot() - self.wndInventory.RefreshItemSlot() - if app.ENABLE_DRAGON_SOUL_SYSTEM: - self.wndDragonSoul.RefreshItemSlot() - - def RefreshCharacter(self): ## Refresh character face in Character page, full body in Inventory page, etc. - self.wndCharacter.RefreshCharacter() - self.wndTaskBar.RefreshQuickSlot() - - def RefreshQuest(self): - self.wndCharacter.RefreshQuest() - - def RefreshSafebox(self): - self.wndSafebox.RefreshSafebox() - - # ITEM_MALL - def RefreshMall(self): - self.wndMall.RefreshMall() - - def OpenItemMall(self): - if not self.mallPageDlg: - self.mallPageDlg = uiShop.MallPageDialog() - - self.mallPageDlg.Open() - # END_OF_ITEM_MALL - - def RefreshMessenger(self): - self.wndMessenger.RefreshMessenger() - - def RefreshGuildInfoPage(self): - self.wndGuild.RefreshGuildInfoPage() - - def RefreshGuildBoardPage(self): - self.wndGuild.RefreshGuildBoardPage() - - def RefreshGuildMemberPage(self): - self.wndGuild.RefreshGuildMemberPage() - - def RefreshGuildMemberPageGradeComboBox(self): - self.wndGuild.RefreshGuildMemberPageGradeComboBox() - - def RefreshGuildSkillPage(self): - self.wndGuild.RefreshGuildSkillPage() - - def RefreshGuildGradePage(self): - self.wndGuild.RefreshGuildGradePage() - - def DeleteGuild(self): - self.wndMessenger.ClearGuildMember() - self.wndGuild.DeleteGuild() - - def OnBlockMode(self, mode): - self.dlgSystem.OnBlockMode(mode) - - ## Calling Functions - # PointReset - def OpenPointResetDialog(self): - self.dlgPointReset.Show() - self.dlgPointReset.SetTop() - - def ClosePointResetDialog(self): - self.dlgPointReset.Close() - - # Shop - def OpenShopDialog(self, vid): - self.wndInventory.Show() - self.wndInventory.SetTop() - self.dlgShop.Open(vid) - self.dlgShop.SetTop() - - def CloseShopDialog(self): - self.dlgShop.Close() - - def RefreshShopDialog(self): - self.dlgShop.Refresh() - - ## Quest - def OpenCharacterWindowQuestPage(self): - self.wndCharacter.Show() - self.wndCharacter.SetState("QUEST") - - def OpenQuestWindow(self, skin, idx): - - wnds = () - - q = uiQuest.QuestDialog(skin, idx) - q.SetWindowName("QuestWindow" + str(idx)) - q.Show() - if skin: - q.Lock() - wnds = self.__HideWindows() - - # UNKNOWN_UPDATE - q.AddOnDoneEvent(lambda tmp_self, args=wnds: self.__ShowWindows(args)) - # END_OF_UNKNOWN_UPDATE - - if skin: - q.AddOnCloseEvent(q.Unlock) - q.AddOnCloseEvent(lambda key = self.wndQuestWindowNewKey:ui.__mem_func__(self.RemoveQuestDialog)(key)) - self.wndQuestWindow[self.wndQuestWindowNewKey] = q - - self.wndQuestWindowNewKey = self.wndQuestWindowNewKey + 1 - - # END_OF_UNKNOWN_UPDATE - - def RemoveQuestDialog(self, key): - del self.wndQuestWindow[key] - - ## Exchange - def StartExchange(self): - self.dlgExchange.OpenDialog() - self.dlgExchange.Refresh() - - def EndExchange(self): - self.dlgExchange.CloseDialog() - - def RefreshExchange(self): - self.dlgExchange.Refresh() - - ## Party - def AddPartyMember(self, pid, name): - self.wndParty.AddPartyMember(pid, name) - - self.__ArrangeQuestButton() - - def UpdatePartyMemberInfo(self, pid): - self.wndParty.UpdatePartyMemberInfo(pid) - - def RemovePartyMember(self, pid): - self.wndParty.RemovePartyMember(pid) - - ## Quest position adjustment - self.__ArrangeQuestButton() - - def LinkPartyMember(self, pid, vid): - self.wndParty.LinkPartyMember(pid, vid) - - def UnlinkPartyMember(self, pid): - self.wndParty.UnlinkPartyMember(pid) - - def UnlinkAllPartyMember(self): - self.wndParty.UnlinkAllPartyMember() - - def ExitParty(self): - self.wndParty.ExitParty() - - ## Quest position adjustment - self.__ArrangeQuestButton() - - def PartyHealReady(self): - self.wndParty.PartyHealReady() - - def ChangePartyParameter(self, distributionMode): - self.wndParty.ChangePartyParameter(distributionMode) - - ## Safebox - def AskSafeboxPassword(self): - if self.wndSafebox.IsShow(): - return - - # SAFEBOX_PASSWORD - self.dlgPassword.SetTitle(localeInfo.PASSWORD_TITLE) - self.dlgPassword.SetSendMessage("/safebox_password ") - # END_OF_SAFEBOX_PASSWORD - - self.dlgPassword.ShowDialog() - - def OpenSafeboxWindow(self, size): - self.dlgPassword.CloseDialog() - self.wndSafebox.ShowWindow(size) - - def RefreshSafeboxMoney(self): - self.wndSafebox.RefreshSafeboxMoney() - - def CommandCloseSafebox(self): - self.wndSafebox.CommandCloseSafebox() - - # ITEM_MALL - def AskMallPassword(self): - if self.wndMall.IsShow(): - return - self.dlgPassword.SetTitle(localeInfo.MALL_PASSWORD_TITLE) - self.dlgPassword.SetSendMessage("/mall_password ") - self.dlgPassword.ShowDialog() - - def OpenMallWindow(self, size): - self.dlgPassword.CloseDialog() - self.wndMall.ShowWindow(size) - - def CommandCloseMall(self): - self.wndMall.CommandCloseMall() - # END_OF_ITEM_MALL - - ## Guild - def OnStartGuildWar(self, guildSelf, guildOpp): - self.wndGuild.OnStartGuildWar(guildSelf, guildOpp) - - guildWarScoreBoard = uiGuild.GuildWarScoreBoard() - guildWarScoreBoard.Open(guildSelf, guildOpp) - guildWarScoreBoard.Show() - self.guildScoreBoardDict[uiGuild.GetGVGKey(guildSelf, guildOpp)] = guildWarScoreBoard - - def OnEndGuildWar(self, guildSelf, guildOpp): - self.wndGuild.OnEndGuildWar(guildSelf, guildOpp) - - key = uiGuild.GetGVGKey(guildSelf, guildOpp) - - if key not in self.guildScoreBoardDict: - return - - self.guildScoreBoardDict[key].Destroy() - del self.guildScoreBoardDict[key] - - # GUILDWAR_MEMBER_COUNT - def UpdateMemberCount(self, gulidID1, memberCount1, guildID2, memberCount2): - key = uiGuild.GetGVGKey(gulidID1, guildID2) - - if key not in self.guildScoreBoardDict: - return - - self.guildScoreBoardDict[key].UpdateMemberCount(gulidID1, memberCount1, guildID2, memberCount2) - # END_OF_GUILDWAR_MEMBER_COUNT - - def OnRecvGuildWarPoint(self, gainGuildID, opponentGuildID, point): - key = uiGuild.GetGVGKey(gainGuildID, opponentGuildID) - if key not in self.guildScoreBoardDict: - return - - guildBoard = self.guildScoreBoardDict[key] - guildBoard.SetScore(gainGuildID, opponentGuildID, point) - - ## PK Mode - def OnChangePKMode(self): - self.wndCharacter.RefreshAlignment() - self.dlgSystem.OnChangePKMode() - - ## Refine - def OpenRefineDialog(self, targetItemPos, nextGradeItemVnum, cost, prob, type): - self.dlgRefineNew.Open(targetItemPos, nextGradeItemVnum, cost, prob, type) - - def AppendMaterialToRefineDialog(self, vnum, count): - self.dlgRefineNew.AppendMaterial(vnum, count) - - ## Show & Hide - def ShowDefaultWindows(self): - self.wndTaskBar.Show() - self.wndMiniMap.Show() - self.wndMiniMap.ShowMiniMap() - if self.wndEnergyBar: - self.wndEnergyBar.Show() - - def ShowAllWindows(self): - self.wndTaskBar.Show() - self.wndCharacter.Show() - self.wndInventory.Show() - if app.ENABLE_DRAGON_SOUL_SYSTEM: - self.wndDragonSoul.Show() - self.wndDragonSoulRefine.Show() - self.wndChat.Show() - self.wndMiniMap.Show() - if self.wndEnergyBar: - self.wndEnergyBar.Show() - if self.wndExpandedTaskBar: - self.wndExpandedTaskBar.Show() - self.wndExpandedTaskBar.SetTop() - - def HideAllWindows(self): - if self.wndTaskBar: - self.wndTaskBar.Hide() - - if self.wndEnergyBar: - self.wndEnergyBar.Hide() - - if self.wndCharacter: - self.wndCharacter.Hide() - - if self.wndInventory: - self.wndInventory.Hide() - - if app.ENABLE_DRAGON_SOUL_SYSTEM: - self.wndDragonSoul.Hide() - self.wndDragonSoulRefine.Hide() - - if self.wndChat: - self.wndChat.Hide() - - if self.wndMiniMap: - self.wndMiniMap.Hide() - - if self.wndMessenger: - self.wndMessenger.Hide() - - if self.wndGuild: - self.wndGuild.Hide() - - if self.wndExpandedTaskBar: - self.wndExpandedTaskBar.Hide() - - - def ShowMouseImage(self): - self.wndTaskBar.ShowMouseImage() - - def HideMouseImage(self): - self.wndTaskBar.HideMouseImage() - - def ToggleChat(self): - if True == self.wndChat.IsEditMode(): - self.wndChat.CloseChat() - else: - # Chat input disabled when webpage is open - if self.wndWeb and self.wndWeb.IsShow(): - pass - else: - self.wndChat.OpenChat() - - def IsOpenChat(self): - return self.wndChat.IsEditMode() - - def SetChatFocus(self): - self.wndChat.SetChatFocus() - - def OpenRestartDialog(self): - self.dlgRestart.OpenDialog() - self.dlgRestart.SetTop() - - def CloseRestartDialog(self): - self.dlgRestart.Close() - - def ToggleSystemDialog(self): - if False == self.dlgSystem.IsShow(): - self.dlgSystem.OpenDialog() - self.dlgSystem.SetTop() - else: - self.dlgSystem.Close() - - def OpenSystemDialog(self): - self.dlgSystem.OpenDialog() - self.dlgSystem.SetTop() - - def ToggleMessenger(self): - if self.wndMessenger.IsShow(): - self.wndMessenger.Hide() - else: - self.wndMessenger.SetTop() - self.wndMessenger.Show() - - def ToggleMiniMap(self): - if app.IsPressed(app.DIK_LSHIFT) or app.IsPressed(app.DIK_RSHIFT): - if False == self.wndMiniMap.isShowMiniMap(): - self.wndMiniMap.ShowMiniMap() - self.wndMiniMap.SetTop() - else: - self.wndMiniMap.HideMiniMap() - - else: - self.wndMiniMap.ToggleAtlasWindow() - - def PressMKey(self): - if app.IsPressed(app.DIK_LALT) or app.IsPressed(app.DIK_RALT): - self.ToggleMessenger() - - else: - self.ToggleMiniMap() - - def SetMapName(self, mapName): - self.wndMiniMap.SetMapName(mapName) - - def MiniMapScaleUp(self): - self.wndMiniMap.ScaleUp() - - def MiniMapScaleDown(self): - self.wndMiniMap.ScaleDown() - - def ToggleCharacterWindow(self, state): - if False == player.IsObserverMode(): - if False == self.wndCharacter.IsShow(): - self.OpenCharacterWindowWithState(state) - else: - if state == self.wndCharacter.GetState(): - self.wndCharacter.OverOutItem() - self.wndCharacter.Hide() - else: - self.wndCharacter.SetState(state) - - def OpenCharacterWindowWithState(self, state): - if False == player.IsObserverMode(): - self.wndCharacter.SetState(state) - self.wndCharacter.Show() - self.wndCharacter.SetTop() - - def ToggleCharacterWindowStatusPage(self): - self.ToggleCharacterWindow("STATUS") - - def ToggleInventoryWindow(self): - if False == player.IsObserverMode(): - if False == self.wndInventory.IsShow(): - self.wndInventory.Show() - self.wndInventory.SetTop() - else: - self.wndInventory.OverOutItem() - self.wndInventory.Close() - - def ToggleExpandedButton(self): - if False == player.IsObserverMode(): - if False == self.wndExpandedTaskBar.IsShow(): - self.wndExpandedTaskBar.Show() - self.wndExpandedTaskBar.SetTop() - else: - self.wndExpandedTaskBar.Close() - - # Dragon soul - def DragonSoulActivate(self, deck): - if app.ENABLE_DRAGON_SOUL_SYSTEM: - self.wndDragonSoul.ActivateDragonSoulByExtern(deck) - - def DragonSoulDeactivate(self): - if app.ENABLE_DRAGON_SOUL_SYSTEM: - self.wndDragonSoul.DeactivateDragonSoul() - - def Highligt_Item(self, inven_type, inven_pos): - if player.DRAGON_SOUL_INVENTORY == inven_type: - if app.ENABLE_DRAGON_SOUL_SYSTEM: - self.wndDragonSoul.HighlightSlot(inven_pos) - - def DragonSoulGiveQuilification(self): - self.DRAGON_SOUL_IS_QUALIFIED = True - self.wndExpandedTaskBar.SetToolTipText(uiTaskBar.ExpandedTaskBar.BUTTON_DRAGON_SOUL, uiScriptLocale.TASKBAR_DRAGON_SOUL) - - def ToggleDragonSoulWindow(self): - if False == player.IsObserverMode(): - if app.ENABLE_DRAGON_SOUL_SYSTEM: - if False == self.wndDragonSoul.IsShow(): - if self.DRAGON_SOUL_IS_QUALIFIED: - self.wndDragonSoul.Show() - else: - try: - self.wndPopupDialog.SetText(localeInfo.DRAGON_SOUL_UNQUALIFIED) - self.wndPopupDialog.Open() - except: - self.wndPopupDialog = uiCommon.PopupDialog() - self.wndPopupDialog.SetText(localeInfo.DRAGON_SOUL_UNQUALIFIED) - self.wndPopupDialog.Open() - else: - self.wndDragonSoul.Close() - - def ToggleDragonSoulWindowWithNoInfo(self): - if False == player.IsObserverMode(): - if app.ENABLE_DRAGON_SOUL_SYSTEM: - if False == self.wndDragonSoul.IsShow(): - if self.DRAGON_SOUL_IS_QUALIFIED: - self.wndDragonSoul.Show() - else: - self.wndDragonSoul.Close() - - def FailDragonSoulRefine(self, reason, inven_type, inven_pos): - if False == player.IsObserverMode(): - if app.ENABLE_DRAGON_SOUL_SYSTEM: - if True == self.wndDragonSoulRefine.IsShow(): - self.wndDragonSoulRefine.RefineFail(reason, inven_type, inven_pos) - - def SucceedDragonSoulRefine(self, inven_type, inven_pos): - if False == player.IsObserverMode(): - if app.ENABLE_DRAGON_SOUL_SYSTEM: - if True == self.wndDragonSoulRefine.IsShow(): - self.wndDragonSoulRefine.RefineSucceed(inven_type, inven_pos) - - def OpenDragonSoulRefineWindow(self): - if False == player.IsObserverMode(): - if app.ENABLE_DRAGON_SOUL_SYSTEM: - if False == self.wndDragonSoulRefine.IsShow(): - self.wndDragonSoulRefine.Show() - if None != self.wndDragonSoul: - if False == self.wndDragonSoul.IsShow(): - self.wndDragonSoul.Show() - - def CloseDragonSoulRefineWindow(self): - if False == player.IsObserverMode(): - if app.ENABLE_DRAGON_SOUL_SYSTEM: - if True == self.wndDragonSoulRefine.IsShow(): - self.wndDragonSoulRefine.Close() - - # Dragon soul end - - def ToggleGuildWindow(self): - if not self.wndGuild.IsShow(): - if self.wndGuild.CanOpen(): - self.wndGuild.Open() - else: - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.GUILD_YOU_DO_NOT_JOIN) - else: - self.wndGuild.OverOutItem() - self.wndGuild.Hide() - - def ToggleChatLogWindow(self): - if self.wndChatLog.IsShow(): - self.wndChatLog.Hide() - else: - self.wndChatLog.Show() - - def CheckGameButton(self): - if self.wndGameButton: - self.wndGameButton.CheckGameButton() - - def __OnClickStatusPlusButton(self): - self.ToggleCharacterWindow("STATUS") - - def __OnClickSkillPlusButton(self): - self.ToggleCharacterWindow("SKILL") - - def __OnClickQuestButton(self): - self.ToggleCharacterWindow("QUEST") - - def __OnClickHelpButton(self): - player.SetPlayTime(1) - self.CheckGameButton() - self.OpenHelpWindow() - - def __OnClickBuildButton(self): - self.BUILD_OpenWindow() - - def OpenHelpWindow(self): - self.wndUICurtain.Show() - self.wndHelp.Open() - - def CloseHelpWindow(self): - self.wndUICurtain.Hide() - self.wndHelp.Close() - - def OpenWebWindow(self, url): - self.wndWeb.Open(url) - - # Close chat when opening webpage - self.wndChat.CloseChat() - - # show GIFT - def ShowGift(self): - self.wndTaskBar.ShowGift() - - def CloseWbWindow(self): - self.wndWeb.Close() - - def OpenCubeWindow(self): - self.wndCube.Open() - - if FALSE == self.wndInventory.IsShow(): - self.wndInventory.Show() - - def UpdateCubeInfo(self, gold, itemVnum, count): - self.wndCube.UpdateInfo(gold, itemVnum, count) - - def CloseCubeWindow(self): - self.wndCube.Close() - - def FailedCubeWork(self): - self.wndCube.Refresh() - - def SucceedCubeWork(self, itemVnum, count): - self.wndCube.Clear() - - print(("Cube crafting successful! [%d:%d]" % (itemVnum, count))) - - if 0: # Skip showing result message - self.wndCubeResult.SetPosition(*self.wndCube.GetGlobalPosition()) - self.wndCubeResult.SetCubeResultItem(itemVnum, count) - self.wndCubeResult.Open() - self.wndCubeResult.SetTop() - - def __HideWindows(self): - hideWindows = self.wndTaskBar,\ - self.wndCharacter,\ - self.wndInventory,\ - self.wndMiniMap,\ - self.wndGuild,\ - self.wndMessenger,\ - self.wndChat,\ - self.wndParty,\ - self.wndGameButton, - - if self.wndEnergyBar: - hideWindows += self.wndEnergyBar, - - if self.wndExpandedTaskBar: - hideWindows += self.wndExpandedTaskBar, - - if app.ENABLE_DRAGON_SOUL_SYSTEM: - hideWindows += self.wndDragonSoul,\ - self.wndDragonSoulRefine, - - hideWindows = [x for x in hideWindows if x.IsShow()] - - list([x.Hide() for x in hideWindows]) - - import sys - - # MR-11: Suppress quest button when quest dialog is open to prevent quest button flashing - self.questButtonSuppressed = True - # MR-11: -- END OF -- Suppress quest button when quest dialog is open to prevent quest button flashing - - self.HideAllQuestButton() - self.HideAllWhisperButton() - - if self.wndChat.IsEditMode(): - self.wndChat.CloseChat() - - return hideWindows - - def __ShowWindows(self, wnds): - import sys - - list([x.Show() for x in wnds]) - - # MR-11: Suppress quest button when quest dialog is open to prevent quest button flashing - self.questButtonSuppressed = False - # MR-11: -- END OF -- Suppress quest button when quest dialog is open to prevent quest button flashing - - global IsQBHide - - if not IsQBHide: - self.ShowAllQuestButton() - else: - self.HideAllQuestButton() - - self.ShowAllWhisperButton() - - def BINARY_OpenAtlasWindow(self): - if self.wndMiniMap: - self.wndMiniMap.ShowAtlas() - - def BINARY_SetObserverMode(self, flag): - self.wndGameButton.SetObserverMode(flag) - - # ACCESSORY_REFINE_ADD_METIN_STONE - def BINARY_OpenSelectItemWindow(self): - self.wndItemSelect.Open() - # END_OF_ACCESSORY_REFINE_ADD_METIN_STONE - - ##################################################################################### - ### Private Shop ### - - def OpenPrivateShopInputNameDialog(self): - #if player.IsInSafeArea(): - # chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.CANNOT_OPEN_PRIVATE_SHOP_IN_SAFE_AREA) - # return - - inputDialog = uiCommon.InputDialog() - inputDialog.SetTitle(localeInfo.PRIVATE_SHOP_INPUT_NAME_DIALOG_TITLE) - inputDialog.SetMaxLength(32) - inputDialog.SetAcceptEvent(ui.__mem_func__(self.OpenPrivateShopBuilder)) - inputDialog.SetCancelEvent(ui.__mem_func__(self.ClosePrivateShopInputNameDialog)) - inputDialog.Open() - self.inputDialog = inputDialog - - def ClosePrivateShopInputNameDialog(self): - self.inputDialog = None - return True - - def OpenPrivateShopBuilder(self): - - if not self.inputDialog: - return True - - if not len(self.inputDialog.GetText()): - return True - - self.privateShopBuilder.Open(self.inputDialog.GetText()) - self.ClosePrivateShopInputNameDialog() - return True - - def AppearPrivateShop(self, vid, text): - - board = uiPrivateShopBuilder.PrivateShopAdvertisementBoard() - board.Open(vid, text) - - self.privateShopAdvertisementBoardDict[vid] = board - - def DisappearPrivateShop(self, vid): - - if vid not in self.privateShopAdvertisementBoardDict: - return - - del self.privateShopAdvertisementBoardDict[vid] - uiPrivateShopBuilder.DeleteADBoard(vid) - - ##################################################################################### - ### Equipment ### - - def OpenEquipmentDialog(self, vid): - dlg = uiEquipmentDialog.EquipmentDialog() - dlg.SetItemToolTip(self.tooltipItem) - dlg.SetCloseEvent(ui.__mem_func__(self.CloseEquipmentDialog)) - dlg.Open(vid) - - self.equipmentDialogDict[vid] = dlg - - def SetEquipmentDialogItem(self, vid, slotIndex, vnum, count): - if not vid in self.equipmentDialogDict: - return - self.equipmentDialogDict[vid].SetEquipmentDialogItem(slotIndex, vnum, count) - - def SetEquipmentDialogSocket(self, vid, slotIndex, socketIndex, value): - if not vid in self.equipmentDialogDict: - return - self.equipmentDialogDict[vid].SetEquipmentDialogSocket(slotIndex, socketIndex, value) - - def SetEquipmentDialogAttr(self, vid, slotIndex, attrIndex, type, value): - if not vid in self.equipmentDialogDict: - return - self.equipmentDialogDict[vid].SetEquipmentDialogAttr(slotIndex, attrIndex, type, value) - - def CloseEquipmentDialog(self, vid): - if not vid in self.equipmentDialogDict: - return - del self.equipmentDialogDict[vid] - - ##################################################################################### - - ##################################################################################### - ### Quest ### - def BINARY_ClearQuest(self, index): - btn = self.__FindQuestButton(index) - - if 0 != btn: - self.__DestroyQuestButton(btn) - - def RecvQuest(self, index, name): - # QUEST_LETTER_IMAGE - self.BINARY_RecvQuest(index, name, "file", localeInfo.GetLetterImageName()) - # END_OF_QUEST_LETTER_IMAGE - - def BINARY_RecvQuest(self, index, name, iconType, iconName): - - btn = self.__FindQuestButton(index) - if 0 != btn: - self.__DestroyQuestButton(btn) - - btn = uiWhisper.WhisperButton() - - # QUEST_LETTER_IMAGE - ## Quest image replacement - import item - - # MR-7: Fix quest letter icon flashing - if "item" == iconType: - item.SelectItem(int(iconName)) - buttonImageFileName = item.GetIconImageFileName() - else: - buttonImageFileName = iconName - - if "highlight" == iconType: - btn.SetUpVisual("locale/ymir_ui/highlighted_quest.tga") - btn.SetOverVisual("locale/ymir_ui/highlighted_quest_r.tga") - btn.SetDownVisual("locale/ymir_ui/highlighted_quest_r.tga") - else: - btn.SetUpVisual(localeInfo.GetLetterCloseImageName()) - btn.SetOverVisual(localeInfo.GetLetterOpenImageName()) - btn.SetDownVisual(localeInfo.GetLetterOpenImageName()) - - btn.Flash() - # MR-7: -- END OF -- Fix quest letter icon flashing - # END_OF_QUEST_LETTER_IMAGE - - if app.IsRTL(): - btn.SetToolTipText(name, 0, 35) - btn.ToolTipText.SetHorizontalAlignCenter() - else: - btn.SetToolTipText(name, -20, 35) - btn.ToolTipText.SetHorizontalAlignLeft() - - btn.SetEvent(ui.__mem_func__(self.__StartQuest), btn) - - # MR-1: Hide quest button when quest dialog is open to prevent quest button flashing - if IsQBHide or self.questButtonSuppressed: - btn.Hide() - else: - btn.Show() - # MR-1: -- END OF -- Hide quest button when quest dialog is open to prevent quest button flashing - - btn.index = index - btn.name = name - - self.questButtonList.insert(0, btn) - self.__ArrangeQuestButton() - - #chat.AppendChat(chat.CHAT_TYPE_NOTICE, localeInfo.QUEST_APPEND) - - def __ArrangeQuestButton(self): - screenWidth = wndMgr.GetScreenWidth() - screenHeight = wndMgr.GetScreenHeight() - - ## Quest position adjustment - if self.wndParty.IsShow(): - xPos = 100 + 30 - else: - xPos = 20 - - if app.IsRTL(): - xPos = xPos + 15 - - yPos = 170 * screenHeight // 600 - yCount = (screenHeight - 330) // 63 - count = 0 - - for btn in self.questButtonList: - btn.SetPosition(xPos + (int(count // yCount) * 100), yPos + (count % yCount * 63)) - - count += 1 - - global IsQBHide - - # MR-1: Hide quest button when quest dialog is open to prevent quest button flashing - if IsQBHide or self.questButtonSuppressed: - btn.Hide() - else: - btn.Show() - # MR-1: -- END OF -- Hide quest button when quest dialog is open to prevent quest button flashing - - def __StartQuest(self, btn): - event.QuestButtonClick(btn.index) - self.__DestroyQuestButton(btn) - - def __FindQuestButton(self, index): - for btn in self.questButtonList: - if btn.index == index: - return btn - - return 0 - - def __DestroyQuestButton(self, btn): - btn.SetEvent(0) - self.questButtonList.remove(btn) - self.__ArrangeQuestButton() - - def HideAllQuestButton(self): - for btn in self.questButtonList: - btn.Hide() - - def ShowAllQuestButton(self): - for btn in self.questButtonList: - btn.Show() - ##################################################################################### - - ##################################################################################### - ### Whisper ### - - def __InitWhisper(self): - chat.InitWhisper(self) - - ## Opens unnamed whisper dialog when "Send Message" is clicked in chat window - ## Managed separately from WhisperDialogDict because it has no name - def OpenWhisperDialogWithoutTarget(self): - if not self.dlgWhisperWithoutTarget: - dlgWhisper = uiWhisper.WhisperDialog(self.MinimizeWhisperDialog, self.CloseWhisperDialog) - dlgWhisper.BindInterface(self) - dlgWhisper.LoadDialog() - dlgWhisper.OpenWithoutTarget(self.RegisterTemporaryWhisperDialog) - dlgWhisper.SetPosition(self.windowOpenPosition*30,self.windowOpenPosition*30) - dlgWhisper.Show() - self.dlgWhisperWithoutTarget = dlgWhisper - - self.windowOpenPosition = (self.windowOpenPosition+1) % 5 - - else: - self.dlgWhisperWithoutTarget.SetTop() - self.dlgWhisperWithoutTarget.OpenWithoutTarget(self.RegisterTemporaryWhisperDialog) - - ## Adds window to WhisperDialogDict when name is determined in unnamed dialog - def RegisterTemporaryWhisperDialog(self, name): - if not self.dlgWhisperWithoutTarget: - return - - btn = self.__FindWhisperButton(name) - if 0 != btn: - self.__DestroyWhisperButton(btn) - - elif name in self.whisperDialogDict: - oldDialog = self.whisperDialogDict[name] - oldDialog.Destroy() - del self.whisperDialogDict[name] - - self.whisperDialogDict[name] = self.dlgWhisperWithoutTarget - self.dlgWhisperWithoutTarget.OpenWithTarget(name) - self.dlgWhisperWithoutTarget = None - self.__CheckGameMaster(name) - - ## Opens whisper window directly with name when "1:1 Chat" is clicked in character menu - def OpenWhisperDialog(self, name): - if name not in self.whisperDialogDict: - dlg = self.__MakeWhisperDialog(name) - dlg.OpenWithTarget(name) - dlg.chatLine.SetFocus() - dlg.Show() - - self.__CheckGameMaster(name) - btn = self.__FindWhisperButton(name) - if 0 != btn: - self.__DestroyWhisperButton(btn) - - ## Shows button when receiving message from another character - def RecvWhisper(self, name): - if name not in self.whisperDialogDict: - btn = self.__FindWhisperButton(name) - if 0 == btn: - btn = self.__MakeWhisperButton(name) - btn.Flash() - - chat.AppendChat(chat.CHAT_TYPE_NOTICE, localeInfo.RECEIVE_MESSAGE % (name)) - - else: - btn.Flash() - elif self.IsGameMasterName(name): - dlg = self.whisperDialogDict[name] - dlg.SetGameMasterLook() - - def MakeWhisperButton(self, name): - self.__MakeWhisperButton(name) - - ## Opens window when button is clicked - def ShowWhisperDialog(self, btn): - try: - self.__MakeWhisperDialog(btn.name) - dlgWhisper = self.whisperDialogDict[btn.name] - dlgWhisper.OpenWithTarget(btn.name) - dlgWhisper.Show() - self.__CheckGameMaster(btn.name) - except: - import dbg - dbg.TraceError("interface.ShowWhisperDialog - Failed to find key") - - ## Reset button - self.__DestroyWhisperButton(btn) - - ## Called when minimize command is executed in WhisperDialog window - ## Minimizes the window - def MinimizeWhisperDialog(self, name): - - if 0 != name: - self.__MakeWhisperButton(name) - - self.CloseWhisperDialog(name) - - ## Called when close command is executed in WhisperDialog window - ## Destroys the window - def CloseWhisperDialog(self, name): - - if 0 == name: - - if self.dlgWhisperWithoutTarget: - self.dlgWhisperWithoutTarget.Destroy() - self.dlgWhisperWithoutTarget = None - - return - - try: - dlgWhisper = self.whisperDialogDict[name] - dlgWhisper.Destroy() - del self.whisperDialogDict[name] - except: - import dbg - dbg.TraceError("interface.CloseWhisperDialog - Failed to find key") - - ## Rearranges buttons when button count changes - def __ArrangeWhisperButton(self): - screenWidth = wndMgr.GetScreenWidth() - screenHeight = wndMgr.GetScreenHeight() - - xPos = screenWidth - 70 - yPos = 170 * screenHeight // 600 - yCount = (screenHeight - 330) // 63 - #yCount = (screenHeight - 285) // 63 - - count = 0 - - for button in self.whisperButtonList: - button.SetPosition(xPos + (int(count // yCount) * -50), yPos + (count % yCount * 63)) - - count += 1 - - ## Finds and returns Whisper button by name - ## Buttons are not stored in dictionary because sorting would lose order - ## This prevents tooltips from being covered by other buttons - def __FindWhisperButton(self, name): - for button in self.whisperButtonList: - if button.name == name: - return button - - return 0 - - ## Creates window - def __MakeWhisperDialog(self, name): - dlgWhisper = uiWhisper.WhisperDialog(self.MinimizeWhisperDialog, self.CloseWhisperDialog) - dlgWhisper.BindInterface(self) - dlgWhisper.LoadDialog() - dlgWhisper.SetPosition(self.windowOpenPosition*30,self.windowOpenPosition*30) - self.whisperDialogDict[name] = dlgWhisper - - self.windowOpenPosition = (self.windowOpenPosition+1) % 5 - - return dlgWhisper - - ## Creates button - def __MakeWhisperButton(self, name): - whisperButton = uiWhisper.WhisperButton() - whisperButton.SetUpVisual("d:/ymir work/ui/game/windows/btn_mail_up.sub") - whisperButton.SetOverVisual("d:/ymir work/ui/game/windows/btn_mail_up.sub") - whisperButton.SetDownVisual("d:/ymir work/ui/game/windows/btn_mail_up.sub") - if self.IsGameMasterName(name): - whisperButton.SetToolTipTextWithColor(name, 0xffffa200) - else: - whisperButton.SetToolTipText(name) - whisperButton.ToolTipText.SetHorizontalAlignCenter() - whisperButton.SetEvent(ui.__mem_func__(self.ShowWhisperDialog), whisperButton) - whisperButton.Show() - whisperButton.name = name - - self.whisperButtonList.insert(0, whisperButton) - self.__ArrangeWhisperButton() - - return whisperButton - - def __DestroyWhisperButton(self, button): - button.SetEvent(0) - self.whisperButtonList.remove(button) - self.__ArrangeWhisperButton() - - def HideAllWhisperButton(self): - for btn in self.whisperButtonList: - btn.Hide() - - def ShowAllWhisperButton(self): - for btn in self.whisperButtonList: - btn.Show() - - def __CheckGameMaster(self, name): - if name not in self.listGMName: - return - if name in self.whisperDialogDict: - dlg = self.whisperDialogDict[name] - dlg.SetGameMasterLook() - - def RegisterGameMasterName(self, name): - if name in self.listGMName: - return - self.listGMName[name] = "GM" - - def IsGameMasterName(self, name): - if name in self.listGMName: - return True - else: - return False - - ##################################################################################### - - ##################################################################################### - ### Guild Building ### - - def BUILD_OpenWindow(self): - self.wndGuildBuilding = uiGuild.BuildGuildBuildingWindow() - self.wndGuildBuilding.Open() - self.wndGuildBuilding.wnds = self.__HideWindows() - self.wndGuildBuilding.SetCloseEvent(ui.__mem_func__(self.BUILD_CloseWindow)) - - def BUILD_CloseWindow(self): - self.__ShowWindows(self.wndGuildBuilding.wnds) - self.wndGuildBuilding = None - - def BUILD_OnUpdate(self): - if not self.wndGuildBuilding: - return - - if self.wndGuildBuilding.IsPositioningMode(): - import background - x, y, z = background.GetPickingPoint() - self.wndGuildBuilding.SetBuildingPosition(x, y, z) - - def BUILD_OnMouseLeftButtonDown(self): - if not self.wndGuildBuilding: - return - - # GUILD_BUILDING - if self.wndGuildBuilding.IsPositioningMode(): - self.wndGuildBuilding.SettleCurrentPosition() - return True - elif self.wndGuildBuilding.IsPreviewMode(): - pass - else: - return True - # END_OF_GUILD_BUILDING - return False - - def BUILD_OnMouseLeftButtonUp(self): - if not self.wndGuildBuilding: - return - - if not self.wndGuildBuilding.IsPreviewMode(): - return True - - return False - - def BULID_EnterGuildArea(self, areaID): - # GUILD_BUILDING - mainCharacterName = player.GetMainCharacterName() - masterName = guild.GetGuildMasterName() - - if mainCharacterName != masterName: - return - - if areaID != player.GetGuildID(): - return - # END_OF_GUILD_BUILDING - - self.wndGameButton.ShowBuildButton() - - def BULID_ExitGuildArea(self, areaID): - self.wndGameButton.HideBuildButton() - - ##################################################################################### - - def IsEditLineFocus(self): - if self.ChatWindow.chatLine.IsFocus(): - return 1 - - if self.ChatWindow.chatToLine.IsFocus(): - return 1 - - return 0 - - def EmptyFunction(self): - pass - - def UseDSSButtonEffect(self, enable): - if self.wndInventory: - self.wndInventory.UseDSSButtonEffect(enable) - -if __name__ == "__main__": - - import app - import wndMgr - import systemSetting - import mouseModule - import grp - import ui - import localeInfo - - app.SetMouseHandler(mouseModule.mouseController) - app.SetHairColorEnable(True) - wndMgr.SetMouseHandler(mouseModule.mouseController) - wndMgr.SetScreenSize(systemSetting.GetWidth(), systemSetting.GetHeight()) - app.Create(localeInfo.APP_TITLE, systemSetting.GetWidth(), systemSetting.GetHeight(), 1) - mouseModule.mouseController.Create() - - class TestGame(ui.Window): - def __init__(self): - ui.Window.__init__(self) - - localeInfo.LoadLocaleData() - player.SetItemData(0, 27001, 10) - player.SetItemData(1, 27004, 10) - - self.interface = Interface() - self.interface.MakeInterface() - self.interface.ShowDefaultWindows() - self.interface.RefreshInventory() - #self.interface.OpenCubeWindow() - - def __del__(self): - ui.Window.__del__(self) - - def OnUpdate(self): - app.UpdateGame() - - def OnRender(self): - app.RenderGame() - grp.PopState() - grp.SetInterfaceRenderState() - - game = TestGame() - game.SetSize(systemSetting.GetWidth(), systemSetting.GetHeight()) - game.Show() - - app.Loop() diff --git a/tools/root/introcreate.py b/tools/root/introcreate.py deleted file mode 100644 index 2514f388..00000000 --- a/tools/root/introcreate.py +++ /dev/null @@ -1,671 +0,0 @@ -import chr -import grp -import app -import net -import snd -import wndMgr -import event -import systemSetting -import localeInfo - -import ui -import networkModule -import math -import snd -import musicInfo -import playerSettingModule -import uiScriptLocale -import uiToolTip - -MAN = 0 -WOMAN = 1 -SHAPE0 = 0 -SHAPE1 = 1 -PAGE_COUNT = 2 -SLOT_COUNT = 4 -BASE_CHR_ID = 3 - -class CreateCharacterWindow(ui.Window): - - SLOT_ROTATION = [135.0, 225.0, 315.0, 45.0] - - - CREATE_STAT_POINT = 0 - - STAT_CON = 0 - STAT_INT = 1 - STAT_STR = 2 - STAT_DEX = 3 - - STAT_DESCRIPTION = {} # populated by _RebuildLocaleStrings() - - START_STAT = ( ## CON INT STR DEX - [ 4, 3, 6, 3, ], ## Warrior - [ 3, 3, 4, 6, ], ## Assassin - [ 3, 5, 5, 3, ], ## Sura - [ 4, 6, 3, 3, ], ## Shaman - [ 4, 3, 6, 3, ], ## Warrior - [ 3, 3, 4, 6, ], ## Assassin - [ 3, 5, 5, 3, ], ## Sura - [ 4, 6, 3, 3, ], ## Shaman - ) - - DESCRIPTION_FILE_NAME = () # populated by _RebuildLocaleStrings() - - @staticmethod - def _RebuildLocaleStrings(): - CreateCharacterWindow.STAT_DESCRIPTION = { - CreateCharacterWindow.STAT_CON : localeInfo.STAT_TOOLTIP_CON, - CreateCharacterWindow.STAT_INT : localeInfo.STAT_TOOLTIP_INT, - CreateCharacterWindow.STAT_STR : localeInfo.STAT_TOOLTIP_STR, - CreateCharacterWindow.STAT_DEX : localeInfo.STAT_TOOLTIP_DEX, - } - CreateCharacterWindow.DESCRIPTION_FILE_NAME = ( - uiScriptLocale.JOBDESC_WARRIOR_PATH, - uiScriptLocale.JOBDESC_ASSASSIN_PATH, - uiScriptLocale.JOBDESC_SURA_PATH, - uiScriptLocale.JOBDESC_SHAMAN_PATH, - ) - - class DescriptionBox(ui.Window): - def __init__(self): - ui.Window.__init__(self) - self.descIndex = 0 - def __del__(self): - ui.Window.__del__(self) - def SetIndex(self, index): - self.descIndex = index - def OnRender(self): - event.RenderEventSet(self.descIndex) - - class CharacterRenderer(ui.Window): - def OnRender(self): - grp.ClearDepthBuffer() - grp.SetGameRenderState() - grp.PushState() - grp.SetOmniLight() - - screenWidth = wndMgr.GetScreenWidth() - screenHeight = wndMgr.GetScreenHeight() - newScreenWidth = float(screenWidth - 270) - newScreenHeight = float(screenHeight) - - grp.SetViewport(270.0/screenWidth, 0.0, newScreenWidth/screenWidth, newScreenHeight/screenHeight) - - app.SetCenterPosition(0.0, 0.0, 0.0) - app.SetCamera(1550.0, 15.0, 180.0, 95.0) - grp.SetPerspective(10.0, newScreenWidth/newScreenHeight, 1000.0, 3000.0) - - (x, y) = app.GetCursorPosition() - grp.SetCursorPosition(x, y) - - chr.Deform() - chr.Render() - - grp.RestoreViewport() - grp.PopState() - grp.SetInterfaceRenderState() - - def __init__(self, stream): - print("NEW CREATE WINDOW ----------------------------------------------------------------------------") - ui.Window.__init__(self) - net.SetPhaseWindow(net.PHASE_WINDOW_CREATE, self) - - self.stream=stream - - def __del__(self): - print("---------------------------------------------------------------------------- DELETE CREATE WINDOW") - - net.SetPhaseWindow(net.PHASE_WINDOW_CREATE, 0) - ui.Window.__del__(self) - - def Open(self): - print("OPEN CREATE WINDOW ----------------------------------------------------------------------------") - - playerSettingModule.LoadGameData("INIT") - - self.reservingRaceIndex = -1 - self.reservingShapeIndex = -1 - self.reservingStartTime = 0 - self.stat = [0, 0, 0, 0] - - self.gender = 0 - self.slot = -1 - self.shapeList = [ - [0, 0, 0, 0], - [0, 0, 0, 0]] - - self.descIndex = 0 - - try: - dlgBoard = ui.ScriptWindow() - pythonScriptLoader = ui.PythonScriptLoader() - - if app.IsRTL(): - pythonScriptLoader.LoadScriptFile(dlgBoard, uiScriptLocale.LOCALE_UISCRIPT_PATH + "createcharacterwindow.py") - else: - pythonScriptLoader.LoadScriptFile(dlgBoard, "UIScript/createcharacterwindow.py") - - except: - import exception - exception.Abort("CreateCharacterWindow.Open.LoadObject") - - try: - getChild = dlgBoard.GetChild - - self.NameList = [] - self.NameList.append(getChild("name_warrior")) - self.NameList.append(getChild("name_assassin")) - self.NameList.append(getChild("name_sura")) - self.NameList.append(getChild("name_shaman")) - - self.GaugeList = [] - self.GaugeList.append(getChild("hth_gauge")) - self.GaugeList.append(getChild("int_gauge")) - self.GaugeList.append(getChild("str_gauge")) - self.GaugeList.append(getChild("dex_gauge")) - - self.btnCreate = getChild("create_button") - self.btnCancel = getChild("cancel_button") - self.btnPrev = getChild("prev_button") - self.btnNext = getChild("next_button") - self.btnLeft = getChild("left_button") - self.btnRight = getChild("right_button") - self.textBoard = getChild("text_board") - - self.genderButtonList = [] - self.genderButtonList.append(getChild("gender_button_01")) - self.genderButtonList.append(getChild("gender_button_02")) - - self.shapeButtonList = [] - self.shapeButtonList.append(getChild("shape_button_01")) - self.shapeButtonList.append(getChild("shape_button_02")) - - self.editCharacterName = getChild("character_name_value") - - self.statValue = [] - self.statValue.append(getChild("hth_value")) - self.statValue.append(getChild("int_value")) - self.statValue.append(getChild("str_value")) - self.statValue.append(getChild("dex_value")) - - getChild("hth_button").ShowToolTip = lambda arg=self.STAT_CON: self.OverInStatButton(arg) - getChild("hth_button").HideToolTip = lambda arg=self.STAT_CON: self.OverOutStatButton() - getChild("int_button").ShowToolTip = lambda arg=self.STAT_INT: self.OverInStatButton(arg) - getChild("int_button").HideToolTip = lambda arg=self.STAT_INT: self.OverOutStatButton() - getChild("str_button").ShowToolTip = lambda arg=self.STAT_STR: self.OverInStatButton(arg) - getChild("str_button").HideToolTip = lambda arg=self.STAT_STR: self.OverOutStatButton() - getChild("dex_button").ShowToolTip = lambda arg=self.STAT_DEX: self.OverInStatButton(arg) - getChild("dex_button").HideToolTip = lambda arg=self.STAT_DEX: self.OverOutStatButton() - - getChild("hth_button").Hide() - getChild("int_button").Hide() - getChild("str_button").Hide() - getChild("dex_button").Hide() - - self.backGround = getChild("BackGround") - - except: - import exception - exception.Abort("CreateCharacterWindow.Open.BindObject") - - self.btnCreate.SetEvent(ui.__mem_func__(self.CreateCharacter)) - self.btnCancel.SetEvent(ui.__mem_func__(self.CancelCreate)) - self.btnPrev.SetEvent(ui.__mem_func__(self.PrevDescriptionPage)) - self.btnNext.SetEvent(ui.__mem_func__(self.NextDescriptionPage)) - self.btnLeft.SetEvent(ui.__mem_func__(self.__DecreaseSlotIndex)) - self.btnRight.SetEvent(ui.__mem_func__(self.__IncreaseSlotIndex)) - - self.genderButtonList[0].SetEvent(ui.__mem_func__(self.__SelectGender), MAN) - self.genderButtonList[1].SetEvent(ui.__mem_func__(self.__SelectGender), WOMAN) - - self.shapeButtonList[0].SetEvent(ui.__mem_func__(self.__SelectShape), SHAPE0) - self.shapeButtonList[1].SetEvent(ui.__mem_func__(self.__SelectShape), SHAPE1) - self.editCharacterName.SetReturnEvent(ui.__mem_func__(self.CreateCharacter)) - self.editCharacterName.SetEscapeEvent(ui.__mem_func__(self.CancelCreate)) - self.dlgBoard = dlgBoard - - self.curRotation = [] + self.SLOT_ROTATION - self.destRotation = [] + self.SLOT_ROTATION - self.curNameAlpha = [0.0, 0.0, 0.0, 0.0, 0.0] - self.destNameAlpha = [0.0, 0.0, 0.0, 0.0, 0.0] - self.curGauge = [0.0, 0.0, 0.0, 0.0] - self.destGauge = [0.0, 0.0, 0.0, 0.0] - - self.descriptionBox = self.DescriptionBox() - self.descriptionBox.Show() - - self.chrRenderer = self.CharacterRenderer() - self.chrRenderer.SetParent(self.backGround) - self.chrRenderer.Show() - - self.toolTip = uiToolTip.ToolTip() - self.toolTip.ClearToolTip() - - self.editCharacterName.SetText("") - - self.EnableWindow() - self.__SelectSlot(0) - - app.SetCamera(500.0, 10.0, 180.0, 95.0) - - self.__MakeCharacter(0, 0, playerSettingModule.RACE_WARRIOR_M) - self.__MakeCharacter(0, 1, playerSettingModule.RACE_ASSASSIN_M) - self.__MakeCharacter(0, 2, playerSettingModule.RACE_SURA_M) - self.__MakeCharacter(0, 3, playerSettingModule.RACE_SHAMAN_M) - - self.__MakeCharacter(1, 0, playerSettingModule.RACE_WARRIOR_W) - self.__MakeCharacter(1, 1, playerSettingModule.RACE_ASSASSIN_W) - self.__MakeCharacter(1, 2, playerSettingModule.RACE_SURA_W) - self.__MakeCharacter(1, 3, playerSettingModule.RACE_SHAMAN_W) - - self.__SelectGender(app.GetRandom(MAN, WOMAN)) - self.__SelectShape(0) - self.__SelectSlot(app.GetRandom(0, 3)) - - self.dlgBoard.Show() - self.Show() - - if musicInfo.createMusic != "": - snd.SetMusicVolume(systemSetting.GetMusicVolume()) - snd.FadeInMusic("BGM/"+musicInfo.createMusic) - - app.ShowCursor() - - def Close(self): - print("---------------------------------------------------------------------------- CLOSE CREATE WINDOW") - - self.editCharacterName.Enable() - self.dlgBoard.ClearDictionary() - self.stream=0 - self.shapeButtonList = [] - self.genderButtonList = [] - self.btnCreate = 0 - self.btnCancel = 0 - self.btnPrev = 0 - self.btnNext = 0 - self.btnLeft = 0 - self.btnRight = 0 - self.textBoard = 0 - self.editCharacterName = 0 - self.backGround = None - - if musicInfo.createMusic != "": - snd.FadeOutMusic("BGM/"+musicInfo.createMusic) - - for id in range(BASE_CHR_ID + SLOT_COUNT * PAGE_COUNT): - chr.DeleteInstance(id) - - self.dlgBoard.Hide() - self.Hide() - - app.HideCursor() - event.Destroy() - - def EnableWindow(self): - self.reservingRaceIndex = -1 - self.reservingShapeIndex = -1 - self.btnCreate.Enable() - self.btnCancel.Enable() - self.btnPrev.Enable() - self.btnNext.Enable() - self.btnLeft.Enable() - self.btnRight.Enable() - - self.editCharacterName.SetFocus() - self.editCharacterName.Enable() - - for page in range(PAGE_COUNT): - for slot in range(SLOT_COUNT): - chr_id = self.__GetSlotChrID(page, slot) - chr.SelectInstance(chr_id) - chr.BlendLoopMotion(chr.MOTION_INTRO_WAIT, 0.1) - - def DisableWindow(self): - self.btnCreate.Disable() - self.btnCancel.Disable() - self.btnPrev.Disable() - self.btnNext.Disable() - self.btnLeft.Disable() - self.btnRight.Disable() - self.editCharacterName.Disable() - - self.btnCreate.SetUp() - - ## Manage Character - def __GetSlotChrID(self, page, slot): - return BASE_CHR_ID + page * SLOT_COUNT + slot - - def __MakeCharacter(self, page, slot, race): - - chr_id = self.__GetSlotChrID(page, slot) - - chr.CreateInstance(chr_id) - chr.SelectInstance(chr_id) - chr.SetVirtualID(chr_id) - - chr.SetRace(race) - chr.SetArmor(0) - chr.SetHair(0) - - chr.Refresh() - chr.SetMotionMode(chr.MOTION_MODE_GENERAL) - chr.SetLoopMotion(chr.MOTION_INTRO_WAIT) - - chr.SetRotation(0.0) - chr.Hide() - - def __SelectGender(self, gender): - for button in self.genderButtonList: - button.SetUp() - - self.genderButtonList[gender].Down() - - self.gender = gender - - if gender == MAN: - for i in range(SLOT_COUNT): - chr.SelectInstance(self.__GetSlotChrID(0, i)) - chr.Show() - for i in range(SLOT_COUNT): - chr.SelectInstance(self.__GetSlotChrID(1, i)) - chr.Hide() - else: - for i in range(SLOT_COUNT): - chr.SelectInstance(self.__GetSlotChrID(0, i)) - chr.Hide() - for i in range(SLOT_COUNT): - chr.SelectInstance(self.__GetSlotChrID(1, i)) - chr.Show() - - def __SelectShape(self, shape): - self.shapeList[self.gender][self.slot] = shape - - for button in self.shapeButtonList: - button.SetUp() - - self.shapeButtonList[shape].Down() - - chr_id = self.__GetSlotChrID(self.gender, self.slot) - chr.SelectInstance(chr_id) - chr.ChangeShape(shape) - chr.SetMotionMode(chr.MOTION_MODE_GENERAL) - chr.SetLoopMotion(chr.MOTION_INTRO_WAIT) - - def GetSlotIndex(self): - return self.slot - - def RefreshStat(self): - statSummary = self.stat[0] + self.stat[1] + self.stat[2] + self.stat[3] - self.destGauge = ( - float(self.stat[0])/float(statSummary), - float(self.stat[1])/float(statSummary), - float(self.stat[2])/float(statSummary), - float(self.stat[3])/float(statSummary), - ) - - for i in range(4): - self.statValue[i].SetText(str(self.stat[i])) - - def __SelectSlot(self, slot): - - if slot < 0: - return - - if slot >= SLOT_COUNT: - return - - if self.slot == slot: - return - - self.slot = slot - self.ResetStat() - - for i in range(SLOT_COUNT): - self.destNameAlpha[i] = 0.0 - - self.destNameAlpha[slot] = 1.0 - - for i in range(SLOT_COUNT): - self.destRotation[(i+self.slot)%SLOT_COUNT] = self.SLOT_ROTATION[i] - - if self.IsShow(): - snd.PlaySound("sound/ui/click.wav") - - event.ClearEventSet(self.descIndex) - self.descIndex = event.RegisterEventSet(self.DESCRIPTION_FILE_NAME[self.slot]) - - if app.IsRTL(): - event.SetEventSetWidth(self.descIndex, 170) - - chr_id = self.__GetSlotChrID(self.gender, slot) - if chr.HasInstance(chr_id): - chr.SelectInstance(chr_id) - self.__SelectShape(self.shapeList[self.gender][slot]) - - def CreateCharacter(self): - - if -1 != self.reservingRaceIndex: - return - - textName = self.editCharacterName.GetText() - if False == self.__CheckCreateCharacter(textName): - return - - if musicInfo.selectMusic != "": - snd.FadeLimitOutMusic("BGM/"+musicInfo.selectMusic, systemSetting.GetMusicVolume()*0.05) - - self.DisableWindow() - - - chr_id = self.__GetSlotChrID(self.gender, self.slot) - - chr.SelectInstance(chr_id) - - self.reservingRaceIndex = chr.GetRace() - - self.reservingShapeIndex = self.shapeList[self.gender][self.slot] - self.reservingStartTime = app.GetTime() - - for eachSlot in range(SLOT_COUNT): - - sel_id = self.__GetSlotChrID(self.gender, eachSlot) - - chr.SelectInstance(sel_id) - - if eachSlot == self.slot: - chr.PushOnceMotion(chr.MOTION_INTRO_SELECTED) - else: - chr.PushOnceMotion(chr.MOTION_INTRO_NOT_SELECTED) - - def CancelCreate(self): - self.stream.SetSelectCharacterPhase() - - def __DecreaseSlotIndex(self): - slotIndex = (self.GetSlotIndex() - 1 + SLOT_COUNT) % SLOT_COUNT - self.__SelectSlot(slotIndex) - - def __IncreaseSlotIndex(self): - slotIndex = (self.GetSlotIndex() + 1) % SLOT_COUNT - self.__SelectSlot(slotIndex) - - def PrevDescriptionPage(self): - if True == event.IsWait(self.descIndex): - if event.GetVisibleStartLine(self.descIndex)-5 >= 0: - event.SetVisibleStartLine(self.descIndex, event.GetVisibleStartLine(self.descIndex)-5) - event.Skip(self.descIndex) - else: - event.Skip(self.descIndex) - - def NextDescriptionPage(self): - if True == event.IsWait(self.descIndex): - event.SetVisibleStartLine(self.descIndex, event.GetVisibleStartLine(self.descIndex)+5) - event.Skip(self.descIndex) - else: - event.Skip(self.descIndex) - - def __CheckCreateCharacter(self, name): - if len(name) == 0: - self.PopupMessage(localeInfo.CREATE_INPUT_NAME, self.EnableWindow) - return False - - if name.find(localeInfo.CREATE_GM_NAME)!=-1: - self.PopupMessage(localeInfo.CREATE_ERROR_GM_NAME, self.EnableWindow) - return False - - if net.IsInsultIn(name): - self.PopupMessage(localeInfo.CREATE_ERROR_INSULT_NAME, self.EnableWindow) - return False - - return True - - def ResetStat(self): - for i in range(4): - self.stat[i] = self.START_STAT[self.slot][i] - self.lastStatPoint = self.CREATE_STAT_POINT - self.RefreshStat() - - ## Event - def OnCreateSuccess(self): - self.stream.SetSelectCharacterPhase() - - def OnCreateFailure(self, type): - if 1 == type: - self.PopupMessage(localeInfo.CREATE_EXIST_SAME_NAME, self.EnableWindow) - else: - self.PopupMessage(localeInfo.CREATE_FAILURE, self.EnableWindow) - - def OnKeyDown(self, key): - - if key == 2: - self.__SelectSlot(0) - if key == 3: - self.__SelectSlot(1) - if key == 4: - self.__SelectSlot(2) - if key == 5: - self.__SelectSlot(3) - - if 203 == key: - self.__DecreaseSlotIndex() - if 205 == key: - self.__IncreaseSlotIndex() - - if 59 == key: - self.__SelectGender(MAN_PAGE) - if 60 == key: - self.__SelectGender(WOMAN_PAGE) - - return True - - def OnUpdate(self): - chr.Update() - - (xposEventSet, yposEventSet) = self.textBoard.GetGlobalPosition() - event.UpdateEventSet(self.descIndex, xposEventSet+7, -(yposEventSet+7)) - self.descriptionBox.SetIndex(self.descIndex) - - for i in range(4): - self.curNameAlpha[i] += (self.destNameAlpha[i] - self.curNameAlpha[i]) / 10.0 - self.NameList[i].SetAlpha(self.curNameAlpha[i]) - - for i in range(4): - self.curGauge[i] += (self.destGauge[i] - self.curGauge[i]) / 10.0 - if abs(self.curGauge[i] - self.destGauge[i]) < 0.005: - self.curGauge[i] = self.destGauge[i] - self.GaugeList[i].SetPercentage(self.curGauge[i], 1.0) - - for page in range(PAGE_COUNT): - for i in range(SLOT_COUNT): - chr.SelectInstance(self.__GetSlotChrID(page, i)) - - distance = 50.0 - rotRadian = self.curRotation[i] * (math.pi*2) / 360.0 - x = distance*math.sin(rotRadian) + distance*math.cos(rotRadian) - y = distance*math.cos(rotRadian) - distance*math.sin(rotRadian) - chr.SetPixelPosition(int(x), int(y), 30) - - if abs(self.destRotation[i] - self.curRotation[i]) < 1.0: - self.curRotation[i] = self.destRotation[i] - - dir = app.GetRotatingDirection(self.destRotation[i], self.curRotation[i]) - rot = app.GetDegreeDifference(self.destRotation[i], self.curRotation[i]) - - if app.DEGREE_DIRECTION_RIGHT == dir: - self.curRotation[i] += rot / 10.0 - elif app.DEGREE_DIRECTION_LEFT == dir: - self.curRotation[i] -= rot / 10.0 - - self.curRotation[i] = (self.curRotation[i] + 360.0) % 360.0 - - ########################################################### - if -1 != self.reservingRaceIndex: - if app.GetTime() - self.reservingStartTime >= 1.5: - - chrSlot=self.stream.GetCharacterSlot() - textName = self.editCharacterName.GetText() - raceIndex = self.reservingRaceIndex - shapeIndex = self.reservingShapeIndex - - startStat = self.START_STAT[self.reservingRaceIndex] - statCon = self.stat[0] - startStat[0] - statInt = self.stat[1] - startStat[1] - statStr = self.stat[2] - startStat[2] - statDex = self.stat[3] - startStat[3] - - net.SendCreateCharacterPacket(chrSlot, textName, raceIndex, shapeIndex, statCon, statInt, statStr, statDex) - - self.reservingRaceIndex = -1 - - ########################################################### - - def EmptyFunc(self): - pass - - def PopupMessage(self, msg, func=0): - if not func: - func=self.EmptyFunc - - self.stream.popupWindow.Close() - self.stream.popupWindow.Open(msg, func, localeInfo.UI_OK) - - def OnPressExitKey(self): - self.CancelCreate() - return True - - def OverInStatButton(self, stat): - if stat not in self.STAT_DESCRIPTION: - return - - self.toolTip.ClearToolTip() - self.toolTip.AppendTextLine(self.STAT_DESCRIPTION[stat]) - self.toolTip.Show() - - def OverOutStatButton(self): - self.toolTip.Hide() - -CreateCharacterWindow._RebuildLocaleStrings() -localeInfo.RegisterReloadCallback(CreateCharacterWindow._RebuildLocaleStrings) - -if __name__ == "__main__": - - import app - import wndMgr - import systemSetting - import mouseModule - import networkModule - - app.SetMouseHandler(mouseModule.mouseController) - app.SetHairColorEnable(True) - wndMgr.SetMouseHandler(mouseModule.mouseController) - wndMgr.SetScreenSize(systemSetting.GetWidth(), systemSetting.GetHeight()) - app.Create(localeInfo.APP_TITLE, systemSetting.GetWidth(), systemSetting.GetHeight(), 1) - mouseModule.mouseController.Create() - - mainStream = networkModule.MainStream() - mainStream.Create() - - test = CreateCharacterWindow(mainStream) - test.Open() - - app.Loop() diff --git a/tools/root/introempire.py b/tools/root/introempire.py deleted file mode 100644 index ed0b34ef..00000000 --- a/tools/root/introempire.py +++ /dev/null @@ -1,259 +0,0 @@ -import ui -import net -import wndMgr -import dbg -import app -import event -import _weakref -import localeInfo -import uiScriptLocale - -class SelectEmpireWindow(ui.ScriptWindow): - - EMPIRE_DESCRIPTION_TEXT_FILE_NAME = { - net.EMPIRE_A : uiScriptLocale.EMPIREDESC_A, - net.EMPIRE_B : uiScriptLocale.EMPIREDESC_B, - net.EMPIRE_C : uiScriptLocale.EMPIREDESC_C, } - - class EmpireButton(ui.Window): - def __init__(self, owner, arg): - ui.Window.__init__(self) - self.owner = owner - self.arg = arg - def OnMouseOverIn(self): - self.owner.OnOverInEmpire(self.arg) - def OnMouseOverOut(self): - self.owner.OnOverOutEmpire(self.arg) - def OnMouseLeftButtonDown(self): - if self.owner.empireID != self.arg: - self.owner.OnSelectEmpire(self.arg) - - class DescriptionBox(ui.Window): - def __init__(self): - ui.Window.__init__(self) - self.descIndex = 0 - def __del__(self): - ui.Window.__del__(self) - def SetIndex(self, index): - self.descIndex = index - def OnRender(self): - event.RenderEventSet(self.descIndex) - - def __init__(self, stream): - print("NEW EMPIRE WINDOW ----------------------------------------------------------------------------") - ui.ScriptWindow.__init__(self) - net.SetPhaseWindow(net.PHASE_WINDOW_EMPIRE, self) - - self.stream=stream - self.empireID=app.GetRandom(1, 3) - self.descIndex=0 - self.empireArea = {} - self.empireAreaFlag = {} - self.empireFlag = {} - self.empireAreaButton = {} - self.empireAreaCurAlpha = { net.EMPIRE_A:0.0, net.EMPIRE_B:0.0, net.EMPIRE_C:0.0 } - self.empireAreaDestAlpha = { net.EMPIRE_A:0.0, net.EMPIRE_B:0.0, net.EMPIRE_C:0.0 } - self.empireAreaFlagCurAlpha = { net.EMPIRE_A:0.0, net.EMPIRE_B:0.0, net.EMPIRE_C:0.0 } - self.empireAreaFlagDestAlpha = { net.EMPIRE_A:0.0, net.EMPIRE_B:0.0, net.EMPIRE_C:0.0 } - self.empireFlagCurAlpha = { net.EMPIRE_A:0.0, net.EMPIRE_B:0.0, net.EMPIRE_C:0.0 } - self.empireFlagDestAlpha = { net.EMPIRE_A:0.0, net.EMPIRE_B:0.0, net.EMPIRE_C:0.0 } - - def __del__(self): - ui.ScriptWindow.__del__(self) - net.SetPhaseWindow(net.PHASE_WINDOW_EMPIRE, 0) - print("---------------------------------------------------------------------------- DELETE EMPIRE WINDOW") - - def Close(self): - print("---------------------------------------------------------------------------- CLOSE EMPIRE WINDOW") - - self.ClearDictionary() - self.leftButton = None - self.rightButton = None - self.selectButton = None - self.exitButton = None - self.textBoard = None - self.descriptionBox = None - self.empireArea = None - self.empireAreaButton = None - - self.KillFocus() - self.Hide() - - app.HideCursor() - event.Destroy() - - def Open(self): - print("OPEN EMPIRE WINDOW ----------------------------------------------------------------------------") - - self.SetSize(wndMgr.GetScreenWidth(), wndMgr.GetScreenHeight()) - self.SetWindowName("SelectEmpireWindow") - self.Show() - - if app.IsRTL(): - selectPath = uiScriptLocale.LOCALE_UISCRIPT_PATH + "SelectEmpireWindow.py" - else: - selectPath = "UIScript/SelectEmpireWindow.py" - - if not self.__LoadScript(selectPath): - dbg.TraceError("SelectCharacterWindow.Open - __LoadScript Error") - return - - self.OnSelectEmpire(self.empireID) - self.__CreateButtons() - self.__CreateDescriptionBox() - app.ShowCursor() - - def __CreateButtons(self): - for key, img in list(self.empireArea.items()): - - img.SetAlpha(0.0) - - (x, y) = img.GetGlobalPosition() - btn = self.EmpireButton(_weakref.proxy(self), key) - btn.SetParent(self) - btn.SetPosition(x, y) - btn.SetSize(img.GetWidth(), img.GetHeight()) - btn.Show() - self.empireAreaButton[key] = btn - - def __CreateDescriptionBox(self): - self.descriptionBox = self.DescriptionBox() - self.descriptionBox.Show() - - def OnOverInEmpire(self, arg): - self.empireAreaDestAlpha[arg] = 1.0 - - def OnOverOutEmpire(self, arg): - if arg != self.empireID: - self.empireAreaDestAlpha[arg] = 0.0 - - def OnSelectEmpire(self, arg): - for key in list(self.empireArea.keys()): - self.empireAreaDestAlpha[key] = 0.0 - self.empireAreaFlagDestAlpha[key] = 0.0 - self.empireFlagDestAlpha[key] = 0.0 - self.empireAreaDestAlpha[arg] = 1.0 - self.empireAreaFlagDestAlpha[arg] = 1.0 - self.empireFlagDestAlpha[arg] = 1.0 - self.empireID = arg - - event.ClearEventSet(self.descIndex) - if arg in self.EMPIRE_DESCRIPTION_TEXT_FILE_NAME: - self.descIndex = event.RegisterEventSet(self.EMPIRE_DESCRIPTION_TEXT_FILE_NAME[arg]) - - if app.IsRTL(): - event.SetEventSetWidth(self.descIndex, 170) - else: - event.SetRestrictedCount(self.descIndex, 35) - - def PrevDescriptionPage(self): - if True == event.IsWait(self.descIndex): - if event.GetVisibleStartLine(self.descIndex)-5 >= 0: - event.SetVisibleStartLine(self.descIndex, event.GetVisibleStartLine(self.descIndex)-5) - event.Skip(self.descIndex) - else: - event.Skip(self.descIndex) - - def NextDescriptionPage(self): - if True == event.IsWait(self.descIndex): - event.SetVisibleStartLine(self.descIndex, event.GetVisibleStartLine(self.descIndex)+5) - event.Skip(self.descIndex) - else: - event.Skip(self.descIndex) - - def __LoadScript(self, fileName): - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, fileName) - except: - import exception - exception.Abort("SelectEmpireWindow.__LoadScript.LoadObject") - - try: - GetObject=self.GetChild - self.leftButton = GetObject("left_button") - self.rightButton = GetObject("right_button") - self.selectButton = GetObject("select_button") - self.exitButton = GetObject("exit_button") - self.textBoard = GetObject("text_board") - self.empireArea[net.EMPIRE_A] = GetObject("EmpireArea_A") - self.empireArea[net.EMPIRE_B] = GetObject("EmpireArea_B") - self.empireArea[net.EMPIRE_C] = GetObject("EmpireArea_C") - self.empireAreaFlag[net.EMPIRE_A] = GetObject("EmpireAreaFlag_A") - self.empireAreaFlag[net.EMPIRE_B] = GetObject("EmpireAreaFlag_B") - self.empireAreaFlag[net.EMPIRE_C] = GetObject("EmpireAreaFlag_C") - self.empireFlag[net.EMPIRE_A] = GetObject("EmpireFlag_A") - self.empireFlag[net.EMPIRE_B] = GetObject("EmpireFlag_B") - self.empireFlag[net.EMPIRE_C] = GetObject("EmpireFlag_C") - GetObject("prev_text_button").SetEvent(ui.__mem_func__(self.PrevDescriptionPage)) - GetObject("next_text_button").SetEvent(ui.__mem_func__(self.NextDescriptionPage)) - except: - import exception - exception.Abort("SelectEmpireWindow.__LoadScript.BindObject") - - self.selectButton.SetEvent(ui.__mem_func__(self.ClickSelectButton)) - self.exitButton.SetEvent(ui.__mem_func__(self.ClickExitButton)) - self.leftButton.SetEvent(ui.__mem_func__(self.ClickLeftButton)) - self.rightButton.SetEvent(ui.__mem_func__(self.ClickRightButton)) - for flag in list(self.empireAreaFlag.values()): - flag.SetAlpha(0.0) - for flag in list(self.empireFlag.values()): - flag.SetAlpha(0.0) - - return 1 - - def ClickLeftButton(self): - self.empireID-=1 - if self.empireID<1: - self.empireID=3 - - self.OnSelectEmpire(self.empireID) - - def ClickRightButton(self): - self.empireID+=1 - if self.empireID>3: - self.empireID=1 - - self.OnSelectEmpire(self.empireID) - - def ClickSelectButton(self): - net.SendSelectEmpirePacket(self.empireID) - self.stream.SetSelectCharacterPhase() - - def ClickExitButton(self): - self.stream.SetLoginPhase() - - def OnUpdate(self): - (xposEventSet, yposEventSet) = self.textBoard.GetGlobalPosition() - event.UpdateEventSet(self.descIndex, xposEventSet+7, -(yposEventSet+7)) - self.descriptionBox.SetIndex(self.descIndex) - - self.__UpdateAlpha(self.empireArea, self.empireAreaCurAlpha, self.empireAreaDestAlpha) - self.__UpdateAlpha(self.empireAreaFlag, self.empireAreaFlagCurAlpha, self.empireAreaFlagDestAlpha) - self.__UpdateAlpha(self.empireFlag, self.empireFlagCurAlpha, self.empireFlagDestAlpha) - - def __UpdateAlpha(self, dict, curAlphaDict, destAlphaDict): - for key, img in list(dict.items()): - - curAlpha = curAlphaDict[key] - destAlpha = destAlphaDict[key] - - if abs(destAlpha - curAlpha) / 10 > 0.0001: - curAlpha += (destAlpha - curAlpha) / 7 - else: - curAlpha = destAlpha - - curAlphaDict[key] = curAlpha - img.SetAlpha(curAlpha) - - def OnPressEscapeKey(self): - self.ClickExitButton() - return True - -class ReselectEmpireWindow(SelectEmpireWindow): - def ClickSelectButton(self): - net.SendSelectEmpirePacket(self.empireID) - self.stream.SetCreateCharacterPhase() - - def ClickExitButton(self): - self.stream.SetSelectCharacterPhase() diff --git a/tools/root/introloading.py b/tools/root/introloading.py deleted file mode 100644 index 90c06ab8..00000000 --- a/tools/root/introloading.py +++ /dev/null @@ -1,358 +0,0 @@ -import ui -import uiScriptLocale -import net -import app -import dbg -import player -import background -import wndMgr - -import localeInfo -import chrmgr -import colorInfo -import constInfo - -import playerSettingModule -import stringCommander -import emotion - -#################################### -# 빠른 실행을 위한 모듈 로딩 분담 -#################################### -import uiRefine -import uiToolTip -import uiAttachMetin -import uiPickMoney -import uiChat -import uiMessenger -import uiHelp -import uiWhisper -import uiPointReset -import uiShop -import uiExchange -import uiSystem -import uiOption -import uiRestart -#################################### - -class LoadingWindow(ui.ScriptWindow): - def __init__(self, stream): - print("NEW LOADING WINDOW -------------------------------------------------------------------------------") - ui.Window.__init__(self) - net.SetPhaseWindow(net.PHASE_WINDOW_LOAD, self) - - self.stream=stream - self.loadingImage=0 - self.loadingGage=0 - self.errMsg=0 - self.update=0 - self.playerX=0 - self.playerY=0 - self.loadStepList=[] - - def __del__(self): - print("---------------------------------------------------------------------------- DELETE LOADING WINDOW") - net.SetPhaseWindow(net.PHASE_WINDOW_LOAD, 0) - ui.Window.__del__(self) - - def Open(self): - print("OPEN LOADING WINDOW -------------------------------------------------------------------------------") - - #app.HideCursor() - - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "UIScript/LoadingWindow.py") - except: - import exception - exception.Abort("LodingWindow.Open - LoadScriptFile Error") - - try: - self.loadingImage=self.GetChild("BackGround") - self.errMsg=self.GetChild("ErrorMessage") - self.loadingGage=self.GetChild("FullGage") - except: - import exception - exception.Abort("LodingWindow.Open - LoadScriptFile Error") - - self.errMsg.Hide() - - # Loading merged together - imgFileNameDict = { - # Base - 0 : "d:/ymir work/uiloading/base/background_loading_warrior.sub", - 1 : "d:/ymir work/uiloading/base/background_loading_shaman.sub", - 2 : "d:/ymir work/uiloading/base/background_loading_sura.sub", - 3 : "d:/ymir work/uiloading/base/background_loading_assassin.sub", - 4 : "d:/ymir work/uiloading/base/background_loading_assassin2.sub", - 5 : "d:/ymir work/uiloading/base/background_loading_assassin3.sub", - 6 : "d:/ymir work/uiloading/base/background_loading_sura2.sub", - 7 : "d:/ymir work/uiloading/base/background_loading_assassin3.sub", - # Grotto - 8 : "d:/ymir work/uiloading/grotto/background_loading_samahi1.sub", - 9 : "d:/ymir work/uiloading/grotto/background_loading_warrior5.sub", - 10 : "d:/ymir work/uiloading/grotto/background_loading_warriorghist1.sub", - # Catacomb - 11 : "d:/ymir work/uiloading/catacomb/loading0.sub", - 12 : "d:/ymir work/uiloading/catacomb/loading1.sub", - 13 : "d:/ymir work/uiloading/catacomb/loading2.sub", - 14 : "d:/ymir work/uiloading/catacomb/loading3.sub", - # Dark Dragons - 15 : "d:/ymir work/uiloading/dark_dragons/loading0.sub", - 16 : "d:/ymir work/uiloading/dark_dragons/loading1.sub", - 17 : "d:/ymir work/uiloading/dark_dragons/loading2.sub", - 18 : "d:/ymir work/uiloading/dark_dragons/loading3.sub", - # Purgatory - 19 : "d:/ymir work/uiloading/purgatory/loading0.sub", - 20 : "d:/ymir work/uiloading/purgatory/loading1.sub", - 21 : "d:/ymir work/uiloading/purgatory/loading2.sub", - 22 : "d:/ymir work/uiloading/purgatory/loading3.sub", - } - - try: - imgFileName = imgFileNameDict[app.GetRandom(0, len(imgFileNameDict) - 1)] - self.loadingImage.LoadImage(imgFileName) - - except: - print(("LoadingWindow.Open.LoadImage - %s File Load Error" % (imgFileName))) - self.loadingImage.Hide() - - - width = float(wndMgr.GetScreenWidth()) / float(self.loadingImage.GetWidth()) - height = float(wndMgr.GetScreenHeight()) / float(self.loadingImage.GetHeight()) - - self.loadingImage.SetScale(width, height) - self.loadingGage.SetPercentage(2, 100) - - self.Show() - - chrSlot=self.stream.GetCharacterSlot() - net.SendSelectCharacterPacket(chrSlot) - - app.SetFrameSkip(0) - - def Close(self): - print("---------------------------------------------------------------------------- CLOSE LOADING WINDOW") - - app.SetFrameSkip(1) - - self.loadStepList=[] - self.loadingImage=0 - self.loadingGage=0 - self.errMsg=0 - self.ClearDictionary() - self.Hide() - - def OnPressEscapeKey(self): - app.SetFrameSkip(1) - self.stream.SetLoginPhase() - return True - - def __SetNext(self, next): - if next: - self.update=ui.__mem_func__(next) - else: - self.update=0 - - def __SetProgress(self, p): - if self.loadingGage: - self.loadingGage.SetPercentage(2+98*p/100, 100) - - def DEBUG_LoadData(self, playerX, playerY): - self.playerX=playerX - self.playerY=playerY - - self.__RegisterSkill() ## 로딩 중간에 실행 하면 문제 발생 - self.__RegisterTitleName() - self.__RegisterColor() - self.__InitData() - self.__LoadMap() - self.__LoadSound() - self.__LoadEffect() - self.__LoadWarrior() - self.__LoadAssassin() - self.__LoadSura() - self.__LoadShaman() - self.__LoadSkill() - self.__LoadEnemy() - self.__LoadNPC() - self.__StartGame() - - def LoadData(self, playerX, playerY): - self.playerX=playerX - self.playerY=playerY - - self.__RegisterDungeonMapName() - self.__RegisterSkill() ## 로딩 중간에 실행 하면 문제 발생 - self.__RegisterTitleName() - self.__RegisterColor() - self.__RegisterEmotionIcon() - - self.loadStepList=[ - (0, ui.__mem_func__(self.__InitData)), - (10, ui.__mem_func__(self.__LoadMap)), - (30, ui.__mem_func__(self.__LoadSound)), - (40, ui.__mem_func__(self.__LoadEffect)), - (50, ui.__mem_func__(self.__LoadWarrior)), - (60, ui.__mem_func__(self.__LoadAssassin)), - (70, ui.__mem_func__(self.__LoadSura)), - (80, ui.__mem_func__(self.__LoadShaman)), - (90, ui.__mem_func__(self.__LoadSkill)), - (93, ui.__mem_func__(self.__LoadEnemy)), - (97, ui.__mem_func__(self.__LoadNPC)), - - # GUILD_BUILDING - (98, ui.__mem_func__(self.__LoadGuildBuilding)), - # END_OF_GUILD_BUILDING - - (100, ui.__mem_func__(self.__StartGame)), - ] - - self.__SetProgress(0) - #self.__SetNext(self.__LoadMap) - - def OnUpdate(self): - if len(self.loadStepList)>0: - (progress, runFunc)=self.loadStepList[0] - - try: - runFunc() - except: - self.errMsg.Show() - self.loadStepList=[] - - ## 이곳에서 syserr.txt 를 보낸다. - - import dbg - dbg.TraceError(" !!! Failed to load game data : STEP [%d]" % (progress)) - - #import shutil - #import os - #shutil.copyfile("syserr.txt", "errorlog.txt") - #os.system("errorlog.exe") - - app.Exit() - - return - - self.loadStepList.pop(0) - - self.__SetProgress(progress) - - def __InitData(self): - playerSettingModule.LoadGameData("INIT") - - def __RegisterDungeonMapName(self): - background.RegisterDungeonMapName("metin2_map_spiderdungeon") - background.RegisterDungeonMapName("metin2_map_monkeydungeon") - background.RegisterDungeonMapName("metin2_map_monkeydungeon_02") - background.RegisterDungeonMapName("metin2_map_monkeydungeon_03") - background.RegisterDungeonMapName("metin2_map_deviltower1") - - def __RegisterSkill(self): - - race = net.GetMainActorRace() - group = net.GetMainActorSkillGroup() - empire = net.GetMainActorEmpire() - - playerSettingModule.RegisterSkill(race, group, empire) - - def __RegisterTitleName(self): - for i in range(len(localeInfo.TITLE_NAME_LIST)): - chrmgr.RegisterTitleName(i, localeInfo.TITLE_NAME_LIST[i]) - - def __RegisterColor(self): - - ## Name - NAME_COLOR_DICT = { - chrmgr.NAMECOLOR_PC : colorInfo.CHR_NAME_RGB_PC, - chrmgr.NAMECOLOR_NPC : colorInfo.CHR_NAME_RGB_NPC, - chrmgr.NAMECOLOR_MOB : colorInfo.CHR_NAME_RGB_MOB, - chrmgr.NAMECOLOR_PVP : colorInfo.CHR_NAME_RGB_PVP, - chrmgr.NAMECOLOR_PK : colorInfo.CHR_NAME_RGB_PK, - chrmgr.NAMECOLOR_PARTY : colorInfo.CHR_NAME_RGB_PARTY, - chrmgr.NAMECOLOR_WARP : colorInfo.CHR_NAME_RGB_WARP, - chrmgr.NAMECOLOR_WAYPOINT : colorInfo.CHR_NAME_RGB_WAYPOINT, - - chrmgr.NAMECOLOR_EMPIRE_MOB : colorInfo.CHR_NAME_RGB_EMPIRE_MOB, - chrmgr.NAMECOLOR_EMPIRE_NPC : colorInfo.CHR_NAME_RGB_EMPIRE_NPC, - chrmgr.NAMECOLOR_EMPIRE_PC+1 : colorInfo.CHR_NAME_RGB_EMPIRE_PC_A, - chrmgr.NAMECOLOR_EMPIRE_PC+2 : colorInfo.CHR_NAME_RGB_EMPIRE_PC_B, - chrmgr.NAMECOLOR_EMPIRE_PC+3 : colorInfo.CHR_NAME_RGB_EMPIRE_PC_C, - } - for name, rgb in list(NAME_COLOR_DICT.items()): - chrmgr.RegisterNameColor(name, rgb[0], rgb[1], rgb[2]) - - ## Title - TITLE_COLOR_DICT = ( colorInfo.TITLE_RGB_GOOD_4, - colorInfo.TITLE_RGB_GOOD_3, - colorInfo.TITLE_RGB_GOOD_2, - colorInfo.TITLE_RGB_GOOD_1, - colorInfo.TITLE_RGB_NORMAL, - colorInfo.TITLE_RGB_EVIL_1, - colorInfo.TITLE_RGB_EVIL_2, - colorInfo.TITLE_RGB_EVIL_3, - colorInfo.TITLE_RGB_EVIL_4, ) - count = 0 - for rgb in TITLE_COLOR_DICT: - chrmgr.RegisterTitleColor(count, rgb[0], rgb[1], rgb[2]) - count += 1 - - def __RegisterEmotionIcon(self): - emotion.RegisterEmotionIcons() - - def __LoadMap(self): - net.Warp(self.playerX, self.playerY) - - def __LoadSound(self): - playerSettingModule.LoadGameData("SOUND") - - def __LoadEffect(self): - playerSettingModule.LoadGameData("EFFECT") - - def __LoadWarrior(self): - playerSettingModule.LoadGameData("WARRIOR") - - def __LoadAssassin(self): - playerSettingModule.LoadGameData("ASSASSIN") - - def __LoadSura(self): - playerSettingModule.LoadGameData("SURA") - - def __LoadShaman(self): - playerSettingModule.LoadGameData("SHAMAN") - - def __LoadSkill(self): - playerSettingModule.LoadGameData("SKILL") - - def __LoadEnemy(self): - playerSettingModule.LoadGameData("ENEMY") - - def __LoadNPC(self): - playerSettingModule.LoadGameData("NPC") - - # GUILD_BUILDING - def __LoadGuildBuilding(self): - playerSettingModule.LoadGuildBuildingList(localeInfo.GUILD_BUILDING_LIST_TXT) - # END_OF_GUILD_BUILDING - - def __StartGame(self): - background.SetViewDistanceSet(background.DISTANCE0, 25600) - """ - background.SetViewDistanceSet(background.DISTANCE1, 19200) - background.SetViewDistanceSet(background.DISTANCE2, 12800) - background.SetViewDistanceSet(background.DISTANCE3, 9600) - background.SetViewDistanceSet(background.DISTANCE4, 6400) - """ - background.SelectViewDistanceNum(background.DISTANCE0) - - app.SetGlobalCenterPosition(self.playerX, self.playerY) - - net.StartGame() - -def _ReloadTitleNames(): - for i in range(len(localeInfo.TITLE_NAME_LIST)): - chrmgr.RegisterTitleName(i, localeInfo.TITLE_NAME_LIST[i]) - chrmgr.RefreshAllPCTextTail() - -localeInfo.RegisterReloadCallback(_ReloadTitleNames) diff --git a/tools/root/intrologin.py b/tools/root/intrologin.py deleted file mode 100644 index 77b3cf99..00000000 --- a/tools/root/intrologin.py +++ /dev/null @@ -1,1136 +0,0 @@ -import dbg -import app -import net -import ui -import ime -import snd -import wndMgr -import musicInfo -import serverInfo -import systemSetting -import ServerStateChecker -import localeInfo -import constInfo -import uiCommon -import time -import serverCommandParser -import ime -import uiScriptLocale -import debugInfo - -# Multi-language hot-reload system -from uilocaleselector import LocaleSelector - -LOGIN_DELAY_SEC = 0.0 -SKIP_LOGIN_PHASE = False -SKIP_LOGIN_PHASE_SUPPORT_CHANNEL = False -FULL_BACK_IMAGE = False - -VIRTUAL_KEYBOARD_NUM_KEYS = 46 -VIRTUAL_KEYBOARD_RAND_KEY = True - -def Suffle(src): - if VIRTUAL_KEYBOARD_RAND_KEY: - items = [item for item in src] - - itemCount = len(items) - for oldPos in range(itemCount): - newPos = app.GetRandom(0, itemCount-1) - items[newPos], items[oldPos] = items[oldPos], items[newPos] - - return "".join(items) - else: - return src - -def IsLoginDelay(): - global LOGIN_DELAY_SEC - if LOGIN_DELAY_SEC > 0.0: - return True - else: - return False - -def GetLoginDelay(): - global LOGIN_DELAY_SEC - return LOGIN_DELAY_SEC - -app.SetGuildMarkPath("test") - -############################################################################### -# Multi-Language Hot-Reload System -# All locale selector and hot-reload logic moved to: -# - uilocaleselector.py (UI component) -# - uilocalechange.py (hot-reload manager) -############################################################################### - -class ConnectingDialog(ui.ScriptWindow): - - def __init__(self): - ui.ScriptWindow.__init__(self) - self.__LoadDialog() - self.eventTimeOver = lambda *arg: None - self.eventExit = lambda *arg: None - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def __LoadDialog(self): - try: - PythonScriptLoader = ui.PythonScriptLoader() - PythonScriptLoader.LoadScriptFile(self, "UIScript/ConnectingDialog.py") - - self.board = self.GetChild("board") - self.message = self.GetChild("message") - self.countdownMessage = self.GetChild("countdown_message") - - except: - import exception - exception.Abort("ConnectingDialog.LoadDialog.BindObject") - - def Open(self, waitTime): - curTime = time.clock() - self.endTime = curTime + waitTime - - self.Lock() - self.SetCenterPosition() - self.SetTop() - self.Show() - - def Close(self): - self.Unlock() - self.Hide() - - def Destroy(self): - self.Hide() - self.ClearDictionary() - - def SetText(self, text): - self.message.SetText(text) - - def SetCountDownMessage(self, waitTime): - self.countdownMessage.SetText("%.0f%s" % (waitTime, localeInfo.SECOND)) - - def SAFE_SetTimeOverEvent(self, event): - self.eventTimeOver = ui.__mem_func__(event) - - def SAFE_SetExitEvent(self, event): - self.eventExit = ui.__mem_func__(event) - - def OnUpdate(self): - lastTime = max(0, self.endTime - time.clock()) - if 0 == lastTime: - self.Close() - self.eventTimeOver() - else: - self.SetCountDownMessage(self.endTime - time.clock()) - - def OnPressExitKey(self): - #self.eventExit() - return True - -class LoginWindow(ui.ScriptWindow): - def __init__(self, stream): - print("NEW LOGIN WINDOW ----------------------------------------------------------------------------") - ui.ScriptWindow.__init__(self) - net.SetPhaseWindow(net.PHASE_WINDOW_LOGIN, self) - net.SetAccountConnectorHandler(self) - - self.lastLoginTime = 0 - self.inputDialog = None - self.connectingDialog = None - self.stream=stream - self.isNowCountDown=False - self.isStartError=False - - self.xServerBoard = 0 - self.yServerBoard = 0 - - self.loadingImage = None - - self.virtualKeyboard = None - self.virtualKeyboardMode = "ALPHABET" - self.virtualKeyboardIsUpper = False - self.timeOutMsg = False #Fix - - # Multi-language hot-reload system - self.localeSelector = None - - def __del__(self): - net.ClearPhaseWindow(net.PHASE_WINDOW_LOGIN, self) - net.SetAccountConnectorHandler(0) - ui.ScriptWindow.__del__(self) - print("---------------------------------------------------------------------------- DELETE LOGIN WINDOW") - - def Open(self): - ServerStateChecker.Create(self) - - print("LOGIN WINDOW OPEN ----------------------------------------------------------------------------") - - self.loginFailureMsgDict={ - #"DEFAULT" : localeInfo.LOGIN_FAILURE_UNKNOWN, - - "ALREADY" : localeInfo.LOGIN_FAILURE_ALREAY, - "NOID" : localeInfo.LOGIN_FAILURE_NOT_EXIST_ID, - "WRONGPWD" : localeInfo.LOGIN_FAILURE_WRONG_PASSWORD, - "FULL" : localeInfo.LOGIN_FAILURE_TOO_MANY_USER, - "SHUTDOWN" : localeInfo.LOGIN_FAILURE_SHUTDOWN, - "REPAIR" : localeInfo.LOGIN_FAILURE_REPAIR_ID, - "BLOCK" : localeInfo.LOGIN_FAILURE_BLOCK_ID, - "BESAMEKEY" : localeInfo.LOGIN_FAILURE_BE_SAME_KEY, - "NOTAVAIL" : localeInfo.LOGIN_FAILURE_NOT_AVAIL, - "NOBILL" : localeInfo.LOGIN_FAILURE_NOBILL, - "BLKLOGIN" : localeInfo.LOGIN_FAILURE_BLOCK_LOGIN, - "WEBBLK" : localeInfo.LOGIN_FAILURE_WEB_BLOCK, - "BADSCLID" : localeInfo.LOGIN_FAILURE_WRONG_SOCIALID, - "AGELIMIT" : localeInfo.LOGIN_FAILURE_SHUTDOWN_TIME, - } - - self.loginFailureFuncDict = { - "WRONGPWD" : self.__DisconnectAndInputPassword, - "QUIT" : app.Exit, - } - - self.SetSize(wndMgr.GetScreenWidth(), wndMgr.GetScreenHeight()) - self.SetWindowName("LoginWindow") - - if app.IsRTL(): - selectPath = uiScriptLocale.LOCALE_UISCRIPT_PATH + "LoginWindow.py" - else: - selectPath = "UIScript/LoginWindow.py" - - if not self.__LoadScript(selectPath): - dbg.TraceError("SelectCharacterWindow.Open - __LoadScript Error") - return - - # Changed .xml -> .py because pack.Get does not allow .xml extension - self.__LoadLoginInfo("loginInfo.py") - - if app.loggined: - self.loginFailureFuncDict = { - "WRONGPWD" : app.Exit, - "WRONGMAT" : app.Exit, - "QUIT" : app.Exit, - } - - if musicInfo.loginMusic != "": - snd.SetMusicVolume(systemSetting.GetMusicVolume()) - snd.FadeInMusic("BGM/"+musicInfo.loginMusic) - - snd.SetSoundVolume(systemSetting.GetSoundVolume()) - - # pevent key "[" "]" - ime.AddExceptKey(91) - ime.AddExceptKey(93) - - self.Show() - - global SKIP_LOGIN_PHASE - if SKIP_LOGIN_PHASE: - if self.isStartError: - self.connectBoard.Hide() - self.loginBoard.Hide() - self.serverBoard.Hide() - self.PopupNotifyMessage(localeInfo.LOGIN_CONNECT_FAILURE, self.__ExitGame) - return - - if self.loginInfo: - self.serverBoard.Hide() - else: - self.__RefreshServerList() - self.__OpenServerBoard() - else: - connectingIP = self.stream.GetConnectAddr() - if connectingIP: - self.__OpenLoginBoard() - else: - self.__RefreshServerList() - self.__OpenServerBoard() - - app.ShowCursor() - - def Close(self): - - if self.connectingDialog: - self.connectingDialog.Close() - self.connectingDialog = None - - ServerStateChecker.Initialize(self) - - print("---------------------------------------------------------------------------- CLOSE LOGIN WINDOW ") - # - # Check both since BGM stops if selectMusic is not set. - # - if musicInfo.loginMusic != "" and musicInfo.selectMusic != "": - snd.FadeOutMusic("BGM/"+musicInfo.loginMusic) - - ## NOTE : idEditLine and pwdEditLine have interconnected events - ## Events must be forcibly initialized - [levites] - self.idEditLine.SetTabEvent(0) - self.idEditLine.SetReturnEvent(0) - self.pwdEditLine.SetReturnEvent(0) - self.pwdEditLine.SetTabEvent(0) - - self.connectBoard = None - self.loginBoard = None - self.idEditLine = None - self.pwdEditLine = None - self.inputDialog = None - self.connectingDialog = None - self.loadingImage = None - - if self.localeSelector: - self.localeSelector.Destroy() - self.localeSelector = None - - self.serverBoard = None - self.serverList = None - self.channelList = None - - self.VIRTUAL_KEY_ALPHABET_LOWERS = None - self.VIRTUAL_KEY_ALPHABET_UPPERS = None - self.VIRTUAL_KEY_SYMBOLS = None - self.VIRTUAL_KEY_NUMBERS = None - - # VIRTUAL_KEYBOARD_BUG_FIX - if self.virtualKeyboard: - for keyIndex in range(0, VIRTUAL_KEYBOARD_NUM_KEYS+1): - key = self.GetChild2("key_%d" % keyIndex) - if key: - key.SetEvent(None) - - self.GetChild("key_space").SetEvent(None) - self.GetChild("key_backspace").SetEvent(None) - self.GetChild("key_enter").SetEvent(None) - self.GetChild("key_shift").SetToggleDownEvent(None) - self.GetChild("key_shift").SetToggleUpEvent(None) - self.GetChild("key_at").SetToggleDownEvent(None) - self.GetChild("key_at").SetToggleUpEvent(None) - - self.virtualKeyboard = None - - self.KillFocus() - self.Hide() - - self.stream.popupWindow.Close() - self.loginFailureFuncDict=None - - ime.ClearExceptKey() - - app.HideCursor() - - def __SaveChannelInfo(self): - try: - with open("config/channel.inf", "w") as file: - file.write("%d %d %d" % (self.__GetServerID(), self.__GetChannelID(), self.__GetRegionID())) - except: - print("LoginWindow.__SaveChannelInfo - SaveError") - - def __LoadChannelInfo(self): - try: - with open("config/channel.inf", "r") as file: - lines=file.readlines() - - if len(lines)>0: - tokens=lines[0].split() - - selServerID=int(tokens[0]) - selChannelID=int(tokens[1]) - - if len(tokens) == 3: - regionID = int(tokens[2]) - - return regionID, selServerID, selChannelID - - except: - print("LoginWindow.__LoadChannelInfo - OpenError") - return -1, -1, -1 - - def __ExitGame(self): - app.Exit() - - def SetIDEditLineFocus(self): - if self.idEditLine != None: - self.idEditLine.SetFocus() - - def SetPasswordEditLineFocus(self): - if self.pwdEditLine != None: - self.pwdEditLine.SetFocus() - - def OnEndCountDown(self): - self.isNowCountDown = False - self.timeOutMsg = False - self.OnConnectFailure() - - def OnConnectFailure(self): - - if self.isNowCountDown: - return - - snd.PlaySound("sound/ui/loginfail.wav") - - if self.connectingDialog: - self.connectingDialog.Close() - self.connectingDialog = None - - if app.loggined: - self.PopupNotifyMessage(localeInfo.LOGIN_CONNECT_FAILURE, self.__ExitGame) - elif self.timeOutMsg: - self.PopupNotifyMessage(localeInfo.LOGIN_FAILURE_TIMEOUT, self.SetPasswordEditLineFocus) - else: - self.PopupNotifyMessage(localeInfo.LOGIN_CONNECT_FAILURE, self.SetPasswordEditLineFocus) - - def OnHandShake(self): - if not IsLoginDelay(): - snd.PlaySound("sound/ui/loginok.wav") - self.PopupDisplayMessage(localeInfo.LOGIN_CONNECT_SUCCESS) - - def OnLoginStart(self): - if not IsLoginDelay(): - self.PopupDisplayMessage(localeInfo.LOGIN_PROCESSING) - - def OnLoginFailure(self, error): - if self.connectingDialog: - self.connectingDialog.Close() - self.connectingDialog = None - - try: - loginFailureMsg = self.loginFailureMsgDict[error] - except KeyError: - loginFailureMsg = localeInfo.LOGIN_FAILURE_UNKNOWN + error - - - #0000685: [M2EU] ID/password guessing bug fix: always set focus to password field - loginFailureFunc=self.loginFailureFuncDict.get(error, self.SetPasswordEditLineFocus) - - if app.loggined: - self.PopupNotifyMessage(loginFailureMsg, self.__ExitGame) - else: - self.PopupNotifyMessage(loginFailureMsg, loginFailureFunc) - - snd.PlaySound("sound/ui/loginfail.wav") - - def __DisconnectAndInputID(self): - if self.connectingDialog: - self.connectingDialog.Close() - self.connectingDialog = None - - self.SetIDEditLineFocus() - net.Disconnect() - - def __DisconnectAndInputPassword(self): - if self.connectingDialog: - self.connectingDialog.Close() - self.connectingDialog = None - - self.SetPasswordEditLineFocus() - net.Disconnect() - - def __LoadScript(self, fileName): - import dbg - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, fileName) - except: - import exception - exception.Abort("LoginWindow.__LoadScript.LoadObject") - try: - GetObject=self.GetChild - self.serverBoard = GetObject("ServerBoard") - self.serverList = GetObject("ServerList") - self.channelList = GetObject("ChannelList") - self.serverSelectButton = GetObject("ServerSelectButton") - self.serverExitButton = GetObject("ServerExitButton") - self.connectBoard = GetObject("ConnectBoard") - self.loginBoard = GetObject("LoginBoard") - self.idText = GetObject("ID_Text") - self.idEditLine = GetObject("ID_EditLine") - self.pwdText = GetObject("Password_Text") - self.pwdEditLine = GetObject("Password_EditLine") - self.serverInfo = GetObject("ConnectName") - self.selectConnectButton = GetObject("SelectConnectButton") - self.loginButton = GetObject("LoginButton") - self.loginExitButton = GetObject("LoginExitButton") - - self.virtualKeyboard = self.GetChild2("VirtualKeyboard") - - if self.virtualKeyboard: - self.VIRTUAL_KEY_ALPHABET_UPPERS = Suffle(localeInfo.VIRTUAL_KEY_ALPHABET_UPPERS) - self.VIRTUAL_KEY_ALPHABET_LOWERS = "".join([localeInfo.VIRTUAL_KEY_ALPHABET_LOWERS[localeInfo.VIRTUAL_KEY_ALPHABET_UPPERS.index(e)] for e in self.VIRTUAL_KEY_ALPHABET_UPPERS]) - self.VIRTUAL_KEY_SYMBOLS = Suffle(localeInfo.VIRTUAL_KEY_SYMBOLS) - self.VIRTUAL_KEY_NUMBERS = Suffle(localeInfo.VIRTUAL_KEY_NUMBERS) - self.__VirtualKeyboard_SetAlphabetMode() - - self.GetChild("key_space").SetEvent(lambda : self.__VirtualKeyboard_PressKey(' ')) - self.GetChild("key_backspace").SetEvent(lambda : self.__VirtualKeyboard_PressBackspace()) - self.GetChild("key_enter").SetEvent(lambda : self.__VirtualKeyboard_PressReturn()) - self.GetChild("key_shift").SetToggleDownEvent(lambda : self.__VirtualKeyboard_SetUpperMode()) - self.GetChild("key_shift").SetToggleUpEvent(lambda : self.__VirtualKeyboard_SetLowerMode()) - self.GetChild("key_at").SetToggleDownEvent(lambda : self.__VirtualKeyboard_SetSymbolMode()) - self.GetChild("key_at").SetToggleUpEvent(lambda : self.__VirtualKeyboard_SetAlphabetMode()) - - # Create locale selector (only if it doesn't exist - during hot-reload we keep the old one) - if not self.localeSelector: - self.localeSelector = LocaleSelector() - self.localeSelector.Create(self) - self.localeSelector.SetLocaleChangedEvent(ui.__mem_func__(self.__OnLocaleChanged)) - - except: - import exception - exception.Abort("LoginWindow.__LoadScript.BindObject") - - self.selectConnectButton.SetEvent(ui.__mem_func__(self.__OnClickSelectConnectButton)) - - self.serverBoard.OnKeyUp = ui.__mem_func__(self.__ServerBoard_OnKeyUp) - self.xServerBoard, self.yServerBoard = self.serverBoard.GetLocalPosition() - - self.serverSelectButton.SetEvent(ui.__mem_func__(self.__OnClickSelectServerButton)) - self.serverExitButton.SetEvent(ui.__mem_func__(self.__OnClickExitButton)) - - self.loginButton.SetEvent(ui.__mem_func__(self.__OnClickLoginButton)) - self.loginExitButton.SetEvent(ui.__mem_func__(self.__OnClickExitButton)) - - self.serverList.SetEvent(ui.__mem_func__(self.__OnSelectServer)) - - self.idEditLine.SetReturnEvent(ui.__mem_func__(self.pwdEditLine.SetFocus)) - self.idEditLine.SetTabEvent(ui.__mem_func__(self.pwdEditLine.SetFocus)) - - self.pwdEditLine.SetReturnEvent(ui.__mem_func__(self.__OnClickLoginButton)) - self.pwdEditLine.SetTabEvent(ui.__mem_func__(self.idEditLine.SetFocus)) - self.pwdEditLine.SetSecretMode(1) - return 1 - - def __VirtualKeyboard_SetKeys(self, keyCodes): - uiDefFontBackup = localeInfo.UI_DEF_FONT - localeInfo.UI_DEF_FONT = localeInfo.UI_DEF_FONT_LARGE - - keyIndex = 1 - for keyCode in keyCodes: - key = self.GetChild2("key_%d" % keyIndex) - if key: - key.SetEvent(lambda x=keyCode: self.__VirtualKeyboard_PressKey(x)) - key.SetText(keyCode) - key.ButtonText.SetFontColor(0, 0, 0) - keyIndex += 1 - - for keyIndex in range(keyIndex, VIRTUAL_KEYBOARD_NUM_KEYS+1): - key = self.GetChild2("key_%d" % keyIndex) - if key: - key.SetEvent(lambda x=' ': self.__VirtualKeyboard_PressKey(x)) - key.SetText(' ') - - localeInfo.UI_DEF_FONT = uiDefFontBackup - - def __VirtualKeyboard_PressKey(self, code): - ime.PasteString(code) - - #if self.virtualKeyboardMode == "ALPHABET" and self.virtualKeyboardIsUpper: - # self.__VirtualKeyboard_SetLowerMode() - - def __VirtualKeyboard_PressBackspace(self): - ime.PasteBackspace() - - def __VirtualKeyboard_PressReturn(self): - ime.PasteReturn() - - def __VirtualKeyboard_SetUpperMode(self): - self.virtualKeyboardIsUpper = True - - if self.virtualKeyboardMode == "ALPHABET": - self.__VirtualKeyboard_SetKeys(self.VIRTUAL_KEY_ALPHABET_UPPERS) - elif self.virtualKeyboardMode == "NUMBER": - self.__VirtualKeyboard_SetKeys(self.VIRTUAL_KEY_SYMBOLS) - else: - self.__VirtualKeyboard_SetKeys(self.VIRTUAL_KEY_NUMBERS) - - def __VirtualKeyboard_SetLowerMode(self): - self.virtualKeyboardIsUpper = False - - if self.virtualKeyboardMode == "ALPHABET": - self.__VirtualKeyboard_SetKeys(self.VIRTUAL_KEY_ALPHABET_LOWERS) - elif self.virtualKeyboardMode == "NUMBER": - self.__VirtualKeyboard_SetKeys(self.VIRTUAL_KEY_NUMBERS) - else: - self.__VirtualKeyboard_SetKeys(self.VIRTUAL_KEY_SYMBOLS) - - def __VirtualKeyboard_SetAlphabetMode(self): - self.virtualKeyboardIsUpper = False - self.virtualKeyboardMode = "ALPHABET" - self.__VirtualKeyboard_SetKeys(self.VIRTUAL_KEY_ALPHABET_LOWERS) - - def __VirtualKeyboard_SetNumberMode(self): - self.virtualKeyboardIsUpper = False - self.virtualKeyboardMode = "NUMBER" - self.__VirtualKeyboard_SetKeys(self.VIRTUAL_KEY_NUMBERS) - - def __VirtualKeyboard_SetSymbolMode(self): - self.virtualKeyboardIsUpper = False - self.virtualKeyboardMode = "SYMBOL" - self.__VirtualKeyboard_SetKeys(self.VIRTUAL_KEY_SYMBOLS) - - def Connect(self, id, pwd): - - if IsLoginDelay(): - loginDelay = GetLoginDelay() - self.connectingDialog = ConnectingDialog() - self.connectingDialog.Open(loginDelay) - self.connectingDialog.SAFE_SetTimeOverEvent(self.OnEndCountDown) - self.connectingDialog.SAFE_SetExitEvent(self.OnPressExitKey) - self.isNowCountDown = True - - else: - self.stream.popupWindow.Close() - self.stream.popupWindow.Open(localeInfo.LOGIN_CONNETING, self.SetPasswordEditLineFocus, localeInfo.UI_CANCEL) - - self.stream.SetLoginInfo(id, pwd) - self.stream.Connect() - - def __OnClickExitButton(self): - self.stream.SetPhaseWindow(0) - - def __OnLocaleChanged(self, newLocaleCode): - """Handle locale change - save config, reload, and refresh UI""" - import dbg - - # Remember old RTL state to detect direction change - wasRTL = app.IsRTL() - - # 1) Save locale code to config/locale.cfg - try: - import os - if not os.path.exists("config"): - os.makedirs("config") - with open("config/locale.cfg", "w") as f: - f.write(newLocaleCode) - dbg.TraceError("Saved new locale to config: %s" % newLocaleCode) - except Exception as e: - dbg.TraceError("Failed to save locale.cfg: %s" % str(e)) - return - - # 2) Call C++ to reload locale data (C++ data + Python modules) - if not app.ReloadLocale(): - dbg.TraceError("app.ReloadLocale() failed") - return - - dbg.TraceError("Locale changed successfully, refreshing UI...") - - # 3) If RTL/LTR direction changed, reload UI script in-place - # (different UI scripts, element positioning, text alignment) - if wasRTL != app.IsRTL(): - dbg.TraceError("RTL/LTR direction changed, reloading UI script...") - - # Save current state before Close() destroys references - wasOnLoginBoard = self.connectBoard and self.connectBoard.IsShow() - savedId = self.idEditLine.GetText() if self.idEditLine else "" - savedPwd = self.pwdEditLine.GetText() if self.pwdEditLine else "" - - # Rebuild popup dialog for new direction - self.stream.popupWindow.Destroy() - self.stream.CreatePopupDialog() - - # Close and reopen with correct RTL/LTR script - self.Close() - self.Open() - - # Restore the board the user was on - if wasOnLoginBoard: - self.__OpenLoginBoard() - if savedId: - self.idEditLine.SetText(savedId) - if savedPwd: - self.pwdEditLine.SetText(savedPwd) - else: - self.__RefreshServerList() - self.__OpenServerBoard() - return - - # 4) Same direction - just refresh text elements - self.__RefreshLocaleUI() - - def __RefreshLocaleUI(self): - """ - Refresh all UI text elements after locale change - - Uses the generic uiLocaleRefresh module to update all visible text elements - without needing to reload the entire UI. - """ - import uiScriptLocale - import uiLocaleRefresh - - try: - # Refresh button and text elements using element mapping - elementMapping = { - self.serverInfo: "LOGIN_DEFAULT_SERVERADDR", - self.selectConnectButton: "LOGIN_SELECT_BUTTON", - self.loginButton: "LOGIN_CONNECT", - self.loginExitButton: "LOGIN_EXIT", - self.serverSelectButton: "OK", - self.serverExitButton: "LOGIN_SELECT_EXIT", - self.idText: "LOGIN_ID", - self.pwdText: "LOGIN_PASSWORD", - } - uiLocaleRefresh.RefreshByMapping(elementMapping) - - # Refresh ServerBoard Title (special case - accessed via GetChild) - try: - serverBoardTitle = self.GetChild("Title") - serverBoardTitle.SetText(uiScriptLocale.LOGIN_SELECT_TITLE) - except: - pass - - # Rebuild login error message dictionary with new locale strings - loginFailureTemplate = { - "ALREADY" : "LOGIN_FAILURE_ALREAY", - "NOID" : "LOGIN_FAILURE_NOT_EXIST_ID", - "WRONGPWD" : "LOGIN_FAILURE_WRONG_PASSWORD", - "FULL" : "LOGIN_FAILURE_TOO_MANY_USER", - "SHUTDOWN" : "LOGIN_FAILURE_SHUTDOWN", - "REPAIR" : "LOGIN_FAILURE_REPAIR_ID", - "BLOCK" : "LOGIN_FAILURE_BLOCK_ID", - "BESAMEKEY" : "LOGIN_FAILURE_BE_SAME_KEY", - "NOTAVAIL" : "LOGIN_FAILURE_NOT_AVAIL", - "NOBILL" : "LOGIN_FAILURE_NOBILL", - "BLKLOGIN" : "LOGIN_FAILURE_BLOCK_LOGIN", - "WEBBLK" : "LOGIN_FAILURE_WEB_BLOCK", - "BADSCLID" : "LOGIN_FAILURE_WRONG_SOCIALID", - "AGELIMIT" : "LOGIN_FAILURE_SHUTDOWN_TIME", - } - self.loginFailureMsgDict = uiLocaleRefresh.RebuildDictionary(loginFailureTemplate, "localeInfo") - - # Recreate locale selector to ensure it's on top with updated text - if self.localeSelector: - self.localeSelector.Destroy() - self.localeSelector = None - - self.localeSelector = LocaleSelector() - self.localeSelector.Create(self) - self.localeSelector.SetLocaleChangedEvent(ui.__mem_func__(self.__OnLocaleChanged)) - self.localeSelector.Show() - self.localeSelector.SetTop() - - except Exception as e: - dbg.TraceError("LoginWindow.__RefreshLocaleUI failed: %s" % str(e)) - - def __SetServerInfo(self, name): - net.SetServerInfo(name.strip()) - self.serverInfo.SetText(name) - - def __LoadLoginInfo(self, loginInfoFileName): - # This should not work in production - if not debugInfo.IsDebugMode(): - app.loggined = FALSE - else: - try: - loginInfo={} - exec(compile(open(loginInfoFileName, "rb").read(), loginInfoFileName, 'exec'), loginInfo) - except IOError: - print((\ - "For automatic login, please create" + loginInfoFileName + "file\n"\ - "\n"\ - "Contents:\n"\ - "================================================================\n"\ - "addr=address\n"\ - "port=port number\n"\ - "id=user ID\n"\ - "pwd=password\n"\ - "slot=character selection index (if absent or -1, no auto-selection)\n"\ - "autoLogin=enable auto login\n" - "autoSelect=enable auto select\n" - "locale=(ymir) works as ymir for LC_Ymir. Works as korea if not specified\n" - )); - - id=loginInfo.get("id", "") - pwd=loginInfo.get("pwd", "") - - addr=loginInfo.get("addr", "") - port=loginInfo.get("port", 0) - account_addr=loginInfo.get("account_addr", addr) - account_port=loginInfo.get("account_port", port) - - locale = loginInfo.get("locale", "") - - if addr and port: - net.SetMarkServer(addr, port) - - net.SetServerInfo(addr+":"+str(port)) - self.serverInfo.SetText("K:"+addr+":"+str(port)) - - slot=loginInfo.get("slot", 0) - isAutoLogin=loginInfo.get("auto", 0) - isAutoLogin=loginInfo.get("autoLogin", 0) - isAutoSelect=loginInfo.get("autoSelect", 0) - - self.stream.SetCharacterSlot(slot) - self.stream.SetConnectInfo(addr, port, account_addr, account_port) - self.stream.isAutoLogin=isAutoLogin - self.stream.isAutoSelect=isAutoSelect - - self.id = None - self.pwd = None - self.loginnedServer = None - self.loginnedChannel = None - app.loggined = FALSE - - self.loginInfo = loginInfo - - if self.id and self.pwd: - app.loggined = TRUE - - if isAutoLogin: - self.Connect(id, pwd) - - print("==================================================================================") - print(("Auto login: %s - %s:%d %s" % (loginInfoFileName, addr, port, id))) - print("==================================================================================") - - - def PopupDisplayMessage(self, msg): - self.stream.popupWindow.Close() - self.stream.popupWindow.Open(msg) - - def PopupNotifyMessage(self, msg, func=0): - if not func: - func=self.EmptyFunc - - self.stream.popupWindow.Close() - self.stream.popupWindow.Open(msg, func, localeInfo.UI_OK) - - def __OnCloseInputDialog(self): - if self.inputDialog: - self.inputDialog.Close() - self.inputDialog = None - return True - - def OnPressExitKey(self): - self.stream.popupWindow.Close() - self.stream.SetPhaseWindow(0) - return True - - def OnExit(self): - self.stream.popupWindow.Close() - - def OnUpdate(self): - ServerStateChecker.Update() - - def EmptyFunc(self): - pass - - ##################################################################################### - - def __ServerBoard_OnKeyUp(self, key): - if self.serverBoard.IsShow(): - if app.DIK_RETURN==key: - self.__OnClickSelectServerButton() - return True - - def __GetRegionID(self): - return 0 - - def __GetServerID(self): - return self.serverList.GetSelectedItem() - - def __GetChannelID(self): - return self.channelList.GetSelectedItem() - - # SEVER_LIST_BUG_FIX - def __ServerIDToServerIndex(self, regionID, targetServerID): - try: - regionDict = serverInfo.REGION_DICT[regionID] - except KeyError: - return -1 - - retServerIndex = 0 - for eachServerID, regionDataDict in list(regionDict.items()): - if eachServerID == targetServerID: - return retServerIndex - - retServerIndex += 1 - - return -1 - - def __ChannelIDToChannelIndex(self, channelID): - return channelID - 1 - # END_OF_SEVER_LIST_BUG_FIX - - def __OpenServerBoard(self): - - loadRegionID, loadServerID, loadChannelID = self.__LoadChannelInfo() - - serverIndex = self.__ServerIDToServerIndex(loadRegionID, loadServerID) - channelIndex = self.__ChannelIDToChannelIndex(loadChannelID) - - self.serverList.SelectItem(serverIndex) - - if channelIndex >= 0: - self.channelList.SelectItem(channelIndex) - - ## Temporary fix for Show/Hide code issue - [levites] - self.serverBoard.SetPosition(self.xServerBoard, self.yServerBoard) - self.serverBoard.Show() - self.connectBoard.Hide() - self.loginBoard.Hide() - - if self.virtualKeyboard: - self.virtualKeyboard.Hide() - - if app.loggined and not SKIP_LOGIN_PHASE_SUPPORT_CHANNEL: - self.serverList.SelectItem(self.loginnedServer-1) - self.channelList.SelectItem(self.loginnedChannel-1) - self.__OnClickSelectServerButton() - - def __OpenLoginBoard(self): - - # self.serverExitButton.SetEvent(ui.__mem_func__(self.__OnClickExitServerButton)) - self.serverExitButton.SetText(localeInfo.UI_CLOSE) - - self.serverBoard.SetPosition(self.xServerBoard, wndMgr.GetScreenHeight()) - self.serverBoard.Hide() - - if self.virtualKeyboard: - self.virtualKeyboard.Show() - - if app.loggined: - self.Connect(self.id, self.pwd) - self.connectBoard.Hide() - self.loginBoard.Hide() - elif not self.stream.isAutoLogin: - self.connectBoard.Show() - self.loginBoard.Show() - - ## if users have the login infomation, then don't initialize.2005.9 haho - if self.idEditLine == None: - self.idEditLine.SetText("") - if self.pwdEditLine == None: - self.pwdEditLine.SetText("") - - self.idEditLine.SetFocus() - - global SKIP_LOGIN_PHASE - if SKIP_LOGIN_PHASE: - if not self.loginInfo: - self.connectBoard.Hide() - - def __OnSelectRegionGroup(self): - self.__RefreshServerList() - - def __OnSelectSettlementArea(self): - # SEVER_LIST_BUG_FIX - regionID = self.__GetRegionID() - serverID = self.serverListOnRegionBoard.GetSelectedItem() - - serverIndex = self.__ServerIDToServerIndex(regionID, serverID) - self.serverList.SelectItem(serverIndex) - # END_OF_SEVER_LIST_BUG_FIX - - self.__OnSelectServer() - - def __RefreshServerList(self): - regionID = self.__GetRegionID() - - if regionID not in serverInfo.REGION_DICT: - return - - self.serverList.ClearItem() - - regionDict = serverInfo.REGION_DICT[regionID] - - # SEVER_LIST_BUG_FIX - visible_index = 1 - for id, regionDataDict in list(regionDict.items()): - name = regionDataDict.get("name", "noname") - try: - server_id = serverInfo.SERVER_ID_DICT[id] - except: - server_id = visible_index - - self.serverList.InsertItem(id, " %02d. %s" % (int(server_id), name)) - visible_index += 1 - # END_OF_SEVER_LIST_BUG_FIX - - def __OnSelectServer(self): - self.__OnCloseInputDialog() - self.__RequestServerStateList() - self.__RefreshServerStateList() - - def __RequestServerStateList(self): - regionID = self.__GetRegionID() - serverID = self.__GetServerID() - - try: - channelDict = serverInfo.REGION_DICT[regionID][serverID]["channel"] - except: - print((" __RequestServerStateList - serverInfo.REGION_DICT(%d, %d)" % (regionID, serverID))) - return - - ServerStateChecker.Initialize(); - for id, channelDataDict in list(channelDict.items()): - key=channelDataDict["key"] - ip=channelDataDict["ip"] - udp_port=channelDataDict["udp_port"] - ServerStateChecker.AddChannel(key, ip, udp_port) - - ServerStateChecker.Request() - - def __RefreshServerStateList(self): - - regionID = self.__GetRegionID() - serverID = self.__GetServerID() - bakChannelID = self.channelList.GetSelectedItem() - - self.channelList.ClearItem() - - try: - channelDict = serverInfo.REGION_DICT[regionID][serverID]["channel"] - except: - print((" __RequestServerStateList - serverInfo.REGION_DICT(%d, %d)" % (regionID, serverID))) - return - - for channelID, channelDataDict in list(channelDict.items()): - channelName = channelDataDict["name"] - channelState = channelDataDict["state"] - self.channelList.InsertItem(channelID, " %s %s" % (channelName, channelState)) - - self.channelList.SelectItem(bakChannelID-1) - - def __GetChannelName(self, regionID, selServerID, selChannelID): - try: - return serverInfo.REGION_DICT[regionID][selServerID]["channel"][selChannelID]["name"] - except KeyError: - if 9==selChannelID: - return localeInfo.CHANNEL_PVP - else: - return localeInfo.CHANNEL_NORMAL % (selChannelID) - - def NotifyChannelState(self, addrKey, state): - try: - stateName=serverInfo.STATE_DICT[state] - except: - stateName=serverInfo.STATE_NONE - - regionID=self.__GetRegionID() - serverID=self.__GetServerID() - channelID=addrKey%10 - - try: - serverInfo.REGION_DICT[regionID][serverID]["channel"][channelID]["state"] = stateName - self.__RefreshServerStateList() - - except: - import exception - exception.Abort(localeInfo.CHANNEL_NOT_FIND_INFO) - - def __OnClickExitServerButton(self): - print("exit server") - self.__OpenLoginBoard() - - def __OnClickSelectRegionButton(self): - regionID = self.__GetRegionID() - serverID = self.__GetServerID() - - if (regionID not in serverInfo.REGION_DICT): - self.PopupNotifyMessage(localeInfo.CHANNEL_SELECT_REGION) - return - - if (serverID not in serverInfo.REGION_DICT[regionID]): - self.PopupNotifyMessage(localeInfo.CHANNEL_SELECT_SERVER) - return - - self.__SaveChannelInfo() - - self.serverExitButton.SetEvent(ui.__mem_func__(self.__OnClickExitServerButton)) - self.serverExitButton.SetText(localeInfo.UI_CLOSE) - - self.__RefreshServerList() - self.__OpenServerBoard() - - def __OnClickSelectServerButton(self): - regionID = self.__GetRegionID() - serverID = self.__GetServerID() - channelID = self.__GetChannelID() - - if (regionID not in serverInfo.REGION_DICT): - self.PopupNotifyMessage(localeInfo.CHANNEL_SELECT_REGION) - return - - if (serverID not in serverInfo.REGION_DICT[regionID]): - self.PopupNotifyMessage(localeInfo.CHANNEL_SELECT_SERVER) - return - - try: - channelDict = serverInfo.REGION_DICT[regionID][serverID]["channel"] - except KeyError: - return - - try: - state = channelDict[channelID]["state"] - except KeyError: - self.PopupNotifyMessage(localeInfo.CHANNEL_SELECT_CHANNEL) - return - - # Entry is prohibited if status equals FULL - if state == serverInfo.STATE_DICT[3]: - self.PopupNotifyMessage(localeInfo.CHANNEL_NOTIFY_FULL) - return - - self.__SaveChannelInfo() - - try: - serverName = serverInfo.REGION_DICT[regionID][serverID]["name"] - channelName = serverInfo.REGION_DICT[regionID][serverID]["channel"][channelID]["name"] - addrKey = serverInfo.REGION_DICT[regionID][serverID]["channel"][channelID]["key"] - except: - print((" ERROR __OnClickSelectServerButton(%d, %d, %d)" % (regionID, serverID, channelID))) - serverName = localeInfo.CHANNEL_EMPTY_SERVER - channelName = localeInfo.CHANNEL_NORMAL % channelID - - self.__SetServerInfo("%s, %s " % (serverName, channelName)) - - try: - ip = serverInfo.REGION_DICT[regionID][serverID]["channel"][channelID]["ip"] - tcp_port = serverInfo.REGION_DICT[regionID][serverID]["channel"][channelID]["tcp_port"] - except: - import exception - exception.Abort("LoginWindow.__OnClickSelectServerButton - server selection failed") - - try: - account_ip = serverInfo.REGION_AUTH_SERVER_DICT[regionID][serverID]["ip"] - account_port = serverInfo.REGION_AUTH_SERVER_DICT[regionID][serverID]["port"] - except: - account_ip = 0 - account_port = 0 - - try: - markKey = regionID*1000 + serverID*10 - markAddrValue=serverInfo.MARKADDR_DICT[markKey] - net.SetMarkServer(markAddrValue["ip"], markAddrValue["tcp_port"]) - app.SetGuildMarkPath(markAddrValue["mark"]) - # GUILD_SYMBOL - app.SetGuildSymbolPath(markAddrValue["symbol_path"]) - # END_OF_GUILD_SYMBOL - - except: - import exception - exception.Abort("LoginWindow.__OnClickSelectServerButton - mark information missing") - - self.stream.SetConnectInfo(ip, tcp_port, account_ip, account_port) - self.__OpenLoginBoard() - - def __OnClickSelectConnectButton(self): - self.__RefreshServerList() - self.__OpenServerBoard() - - def __OnClickLoginButton(self): - id = self.idEditLine.GetText() - pwd = self.pwdEditLine.GetText() - - if len(id)==0: - self.PopupNotifyMessage(localeInfo.LOGIN_INPUT_ID, self.SetIDEditLineFocus) - return - - if len(pwd)==0: - self.PopupNotifyMessage(localeInfo.LOGIN_INPUT_PASSWORD, self.SetPasswordEditLineFocus) - return - - self.Connect(id, pwd) - - def SameLogin_OpenUI(self): - self.stream.popupWindow.Close() - self.stream.popupWindow.Open(localeInfo.LOGIN_FAILURE_SAMELOGIN, 0, localeInfo.UI_OK) diff --git a/tools/root/introselect.py b/tools/root/introselect.py deleted file mode 100644 index aa56a8b0..00000000 --- a/tools/root/introselect.py +++ /dev/null @@ -1,781 +0,0 @@ -import chr -import grp -import app -import math -import wndMgr -import snd -import net -import systemSetting -import localeInfo -import chr - -import ui -import uiScriptLocale -import networkModule -import musicInfo -import playerSettingModule - -#################################### -# 빠른 실행을 위한 모듈 로딩 분담 -#################################### -import uiCommon -import uiMapNameShower -import uiAffectShower -import uiPlayerGauge -import uiCharacter -import uiTarget -import consoleModule - -# interface module이 문제야... -import interfaceModule -import uiTaskBar -import uiInventory - -################################### - -LEAVE_BUTTON_FOR_POTAL = False -NOT_NEED_DELETE_CODE = False -ENABLE_ENGNUM_DELETE_CODE = False - -################################### - -class SelectCharacterWindow(ui.Window): - - # SLOT4 - #SLOT_ROTATION = ( 140.0, 260.0, 20.0 ) - #SLOT_COUNT = 3 - SLOT_ROTATION = [135.0, 225.0, 315.0, 45.0] - SLOT_COUNT = 4 - CHARACTER_TYPE_COUNT = 4 - - EMPIRE_NAME = {} # populated by _RebuildLocaleStrings() - - @staticmethod - def _RebuildLocaleStrings(): - SelectCharacterWindow.EMPIRE_NAME = { - net.EMPIRE_A : localeInfo.EMPIRE_A, - net.EMPIRE_B : localeInfo.EMPIRE_B, - net.EMPIRE_C : localeInfo.EMPIRE_C, - } - - class CharacterRenderer(ui.Window): - def OnRender(self): - grp.ClearDepthBuffer() - - grp.SetGameRenderState() - grp.PushState() - grp.SetOmniLight() - - screenWidth = wndMgr.GetScreenWidth() - screenHeight = wndMgr.GetScreenHeight() - newScreenWidth = float(screenWidth - 270) - newScreenHeight = float(screenHeight) - - grp.SetViewport(270.0/screenWidth, 0.0, newScreenWidth/screenWidth, newScreenHeight/screenHeight) - - app.SetCenterPosition(0.0, 0.0, 0.0) - app.SetCamera(1550.0, 15.0, 180.0, 95.0) - grp.SetPerspective(10.0, newScreenWidth/newScreenHeight, 1000.0, 3000.0) - - (x, y) = app.GetCursorPosition() - grp.SetCursorPosition(x, y) - - chr.Deform() - chr.Render() - - grp.RestoreViewport() - grp.PopState() - grp.SetInterfaceRenderState() - - def __init__(self, stream): - ui.Window.__init__(self) - net.SetPhaseWindow(net.PHASE_WINDOW_SELECT, self) - - self.stream=stream - self.slot = self.stream.GetCharacterSlot() - - self.openLoadingFlag = False - self.startIndex = -1 - self.startReservingTime = 0 - - self.flagDict = {} - self.curRotation = [] - self.destRotation = [] - for rot in self.SLOT_ROTATION: - self.curRotation.append(rot) - self.destRotation.append(rot) - - self.curNameAlpha = [] - self.destNameAlpha = [] - for i in range(self.CHARACTER_TYPE_COUNT): - self.curNameAlpha.append(0.0) - self.destNameAlpha.append(0.0) - - self.curGauge = [0.0, 0.0, 0.0, 0.0] - self.destGauge = [0.0, 0.0, 0.0, 0.0] - - self.dlgBoard = 0 - self.changeNameFlag = False - self.nameInputBoard = None - self.sendedChangeNamePacket = False - - self.startIndex = -1 - self.isLoad = 0 - - def __del__(self): - ui.Window.__del__(self) - net.SetPhaseWindow(net.PHASE_WINDOW_SELECT, 0) - - def Open(self): - if app.IsRTL(): - selectPath = uiScriptLocale.LOCALE_UISCRIPT_PATH + "selectcharacterwindow.py" - else: - selectPath = "UIScript/selectcharacterwindow.py" - - if not self.__LoadBoardDialog(selectPath): - import dbg - dbg.TraceError("SelectCharacterWindow.Open - __LoadScript Error") - return - - if not self.__LoadQuestionDialog("uiscript/questiondialog.py"): - return - - playerSettingModule.LoadGameData("INIT") - - self.InitCharacterBoard() - - self.btnStart.Enable() - self.btnCreate.Enable() - self.btnDelete.Enable() - self.btnExit.Enable() - self.btnLeft.Enable() - self.btnRight.Enable() - - self.dlgBoard.Show() - self.SetWindowName("SelectCharacterWindow") - self.Show() - - if self.slot>=0: - self.SelectSlot(self.slot) - - if musicInfo.selectMusic != "": - snd.SetMusicVolume(systemSetting.GetMusicVolume()) - snd.FadeInMusic("BGM/"+musicInfo.selectMusic) - - app.SetCenterPosition(0.0, 0.0, 0.0) - app.SetCamera(1550.0, 15.0, 180.0, 95.0) - - self.isLoad=1 - self.Refresh() - - if self.stream.isAutoSelect: - chrSlot=self.stream.GetCharacterSlot() - self.SelectSlot(chrSlot) - self.StartGame() - - self.HideAllFlag() - self.SetEmpire(net.GetEmpireID()) - - app.ShowCursor() - - def Close(self): - if musicInfo.selectMusic != "": - snd.FadeOutMusic("BGM/"+musicInfo.selectMusic) - - self.stream.popupWindow.Close() - - if self.dlgBoard: - self.dlgBoard.ClearDictionary() - - self.empireName = None - self.flagDict = {} - self.dlgBoard = None - self.btnStart = None - self.btnCreate = None - self.btnDelete = None - self.btnExit = None - self.btnLeft = None - self.btnRight = None - self.backGround = None - - self.dlgQuestion.ClearDictionary() - self.dlgQuestion = None - self.dlgQuestionText = None - self.dlgQuestionAcceptButton = None - self.dlgQuestionCancelButton = None - self.privateInputBoard = None - self.nameInputBoard = None - - chr.DeleteInstance(0) - chr.DeleteInstance(1) - chr.DeleteInstance(2) - chr.DeleteInstance(3) - - self.Hide() - self.KillFocus() - - app.HideCursor() - - def SetEmpire(self, id): - self.empireName.SetText(self.EMPIRE_NAME.get(id, "")) - if id in self.flagDict: - self.flagDict[id].Show() - - def HideAllFlag(self): - for flag in list(self.flagDict.values()): - flag.Hide() - - def Refresh(self): - if not self.isLoad: - return - - # SLOT4 - indexArray = (3, 2, 1, 0) - for index in indexArray: - id=net.GetAccountCharacterSlotDataInteger(index, net.ACCOUNT_CHARACTER_SLOT_ID) - race=net.GetAccountCharacterSlotDataInteger(index, net.ACCOUNT_CHARACTER_SLOT_RACE) - form=net.GetAccountCharacterSlotDataInteger(index, net.ACCOUNT_CHARACTER_SLOT_FORM) - name=net.GetAccountCharacterSlotDataString(index, net.ACCOUNT_CHARACTER_SLOT_NAME) - hair=net.GetAccountCharacterSlotDataInteger(index, net.ACCOUNT_CHARACTER_SLOT_HAIR) - - if id: - self.MakeCharacter(index, id, name, race, form, hair) - self.SelectSlot(index) - - self.SelectSlot(self.slot) - - def GetCharacterSlotID(self, slotIndex): - return net.GetAccountCharacterSlotDataInteger(slotIndex, net.ACCOUNT_CHARACTER_SLOT_ID) - - def __LoadQuestionDialog(self, fileName): - self.dlgQuestion = ui.ScriptWindow() - - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self.dlgQuestion, fileName) - except: - import exception - exception.Abort("SelectCharacterWindow.LoadQuestionDialog.LoadScript") - - try: - GetObject=self.dlgQuestion.GetChild - self.dlgQuestionText=GetObject("message") - self.dlgQuestionAcceptButton=GetObject("accept") - self.dlgQuestionCancelButton=GetObject("cancel") - except: - import exception - exception.Abort("SelectCharacterWindow.LoadQuestionDialog.BindObject") - - self.dlgQuestionText.SetText(localeInfo.SELECT_DO_YOU_DELETE_REALLY) - self.dlgQuestionAcceptButton.SetEvent(ui.__mem_func__(self.RequestDeleteCharacter)) - self.dlgQuestionCancelButton.SetEvent(ui.__mem_func__(self.dlgQuestion.Hide)) - return 1 - - def __LoadBoardDialog(self, fileName): - self.dlgBoard = ui.ScriptWindow() - - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self.dlgBoard, fileName) - except: - import exception - exception.Abort("SelectCharacterWindow.LoadBoardDialog.LoadScript") - - try: - GetObject=self.dlgBoard.GetChild - - self.btnStart = GetObject("start_button") - self.btnCreate = GetObject("create_button") - self.btnDelete = GetObject("delete_button") - self.btnExit = GetObject("exit_button") - - self.CharacterName = GetObject("character_name_value") - self.CharacterLevel = GetObject("character_level_value") - self.PlayTime = GetObject("character_play_time_value") - self.CharacterHTH = GetObject("character_hth_value") - self.CharacterINT = GetObject("character_int_value") - self.CharacterSTR = GetObject("character_str_value") - self.CharacterDEX = GetObject("character_dex_value") - self.GuildName = GetObject("GuildName") - - self.NameList = [] - self.NameList.append(GetObject("name_warrior")) - self.NameList.append(GetObject("name_assassin")) - self.NameList.append(GetObject("name_sura")) - self.NameList.append(GetObject("name_shaman")) - - self.GaugeList = [] - self.GaugeList.append(GetObject("gauge_hth")) - self.GaugeList.append(GetObject("gauge_int")) - self.GaugeList.append(GetObject("gauge_str")) - self.GaugeList.append(GetObject("gauge_dex")) - - self.btnLeft = GetObject("left_button") - self.btnRight = GetObject("right_button") - - self.empireName = GetObject("EmpireName") - self.flagDict[net.EMPIRE_A] = GetObject("EmpireFlag_A") - self.flagDict[net.EMPIRE_B] = GetObject("EmpireFlag_B") - self.flagDict[net.EMPIRE_C] = GetObject("EmpireFlag_C") - - self.backGround = GetObject("BackGround") - - except: - import exception - exception.Abort("SelectCharacterWindow.LoadBoardDialog.BindObject") - - for name in self.NameList: - name.SetAlpha(0.0) - - self.btnStart.SetEvent(ui.__mem_func__(self.StartGame)) - self.btnCreate.SetEvent(ui.__mem_func__(self.CreateCharacter)) - self.btnExit.SetEvent(ui.__mem_func__(self.ExitSelect)) - - - - if NOT_NEED_DELETE_CODE: - self.btnDelete.SetEvent(ui.__mem_func__(self.PopupDeleteQuestion)) - else: - self.btnDelete.SetEvent(ui.__mem_func__(self.InputPrivateCode)) - - self.btnLeft.SetEvent(ui.__mem_func__(self.DecreaseSlotIndex)) - self.btnRight.SetEvent(ui.__mem_func__(self.IncreaseSlotIndex)) - - self.chrRenderer = self.CharacterRenderer() - self.chrRenderer.SetParent(self.backGround) - self.chrRenderer.Show() - - return 1 - - def SameLoginDisconnect(self): - self.stream.popupWindow.Close() - self.stream.popupWindow.Open(localeInfo.LOGIN_FAILURE_SAMELOGIN, self.ExitSelect, localeInfo.UI_OK) - #self.stream.popupWindow.Open(localeInfo.LOGIN_FAILURE_ALREAY, app.Exit, localeInfo.UI_OK) - - def MakeCharacter(self, index, id, name, race, form, hair): - if 0 == id: - return - - chr.CreateInstance(index) - chr.SelectInstance(index) - chr.SetVirtualID(index) - chr.SetNameString(name) - - chr.SetRace(race) - chr.SetArmor(form) - chr.SetHair(hair) - - chr.Refresh() - chr.SetMotionMode(chr.MOTION_MODE_GENERAL) - chr.SetLoopMotion(chr.MOTION_INTRO_WAIT) - - chr.SetRotation(0.0) - - ## Manage Character - def StartGame(self): - - if self.sendedChangeNamePacket: - return - - if self.changeNameFlag: - self.OpenChangeNameDialog() - return - - if -1 != self.startIndex: - return - - if musicInfo.selectMusic != "": - snd.FadeLimitOutMusic("BGM/"+musicInfo.selectMusic, systemSetting.GetMusicVolume()*0.05) - - self.btnStart.SetUp() - self.btnCreate.SetUp() - self.btnDelete.SetUp() - self.btnExit.SetUp() - self.btnLeft.SetUp() - self.btnRight.SetUp() - - self.btnStart.Disable() - self.btnCreate.Disable() - self.btnDelete.Disable() - self.btnExit.Disable() - self.btnLeft.Disable() - self.btnRight.Disable() - self.dlgQuestion.Hide() - - self.stream.SetCharacterSlot(self.slot) - - self.startIndex = self.slot - self.startReservingTime = app.GetTime() - - for i in range(self.SLOT_COUNT): - - if False == chr.HasInstance(i): - continue - - chr.SelectInstance(i) - - if i == self.slot: - self.slot=self.slot - chr.PushOnceMotion(chr.MOTION_INTRO_SELECTED, 0.1) - continue - - chr.PushOnceMotion(chr.MOTION_INTRO_NOT_SELECTED, 0.1) - - def OpenChangeNameDialog(self): - import uiCommon - nameInputBoard = uiCommon.InputDialogWithDescription() - nameInputBoard.SetTitle(localeInfo.SELECT_CHANGE_NAME_TITLE) - nameInputBoard.SetAcceptEvent(ui.__mem_func__(self.AcceptInputName)) - nameInputBoard.SetCancelEvent(ui.__mem_func__(self.CancelInputName)) - nameInputBoard.SetMaxLength(chr.PLAYER_NAME_MAX_LEN) - nameInputBoard.SetBoardWidth(200) - nameInputBoard.SetDescription(localeInfo.SELECT_INPUT_CHANGING_NAME) - nameInputBoard.Open() - nameInputBoard.slot = self.slot - self.nameInputBoard = nameInputBoard - - def OnChangeName(self, id, name): - self.SelectSlot(id) - self.sendedChangeNamePacket = False - self.PopupMessage(localeInfo.SELECT_CHANGED_NAME) - - def AcceptInputName(self): - changeName = self.nameInputBoard.GetText() - if not changeName: - return - - self.sendedChangeNamePacket = True - net.SendChangeNamePacket(self.nameInputBoard.slot, changeName) - return self.CancelInputName() - - def CancelInputName(self): - self.nameInputBoard.Close() - self.nameInputBoard = None - return True - - def OnCreateFailure(self, type): - self.sendedChangeNamePacket = False - if 0 == type: - self.PopupMessage(localeInfo.SELECT_CHANGE_FAILURE_STRANGE_NAME) - elif 1 == type: - self.PopupMessage(localeInfo.SELECT_CHANGE_FAILURE_ALREADY_EXIST_NAME) - elif 100 == type: - self.PopupMessage(localeInfo.SELECT_CHANGE_FAILURE_STRANGE_INDEX) - - def CreateCharacter(self): - id = self.GetCharacterSlotID(self.slot) - if 0==id: - self.stream.SetCharacterSlot(self.slot) - - EMPIRE_MODE = 1 - - if EMPIRE_MODE: - if self.__AreAllSlotEmpty(): - self.stream.SetReselectEmpirePhase() - else: - self.stream.SetCreateCharacterPhase() - - else: - self.stream.SetCreateCharacterPhase() - - def __AreAllSlotEmpty(self): - for iSlot in range(self.SLOT_COUNT): - if 0!=net.GetAccountCharacterSlotDataInteger(iSlot, net.ACCOUNT_CHARACTER_SLOT_ID): - return 0 - return 1 - - def PopupDeleteQuestion(self): - id = self.GetCharacterSlotID(self.slot) - if 0 == id: - return - - self.dlgQuestion.Show() - self.dlgQuestion.SetTop() - - def RequestDeleteCharacter(self): - self.dlgQuestion.Hide() - - id = self.GetCharacterSlotID(self.slot) - if 0 == id: - self.PopupMessage(localeInfo.SELECT_EMPTY_SLOT) - return - - net.SendDestroyCharacterPacket(self.slot, "1234567") - self.PopupMessage(localeInfo.SELECT_DELEING) - - def InputPrivateCode(self): - - import uiCommon - privateInputBoard = uiCommon.InputDialogWithDescription() - privateInputBoard.SetTitle(localeInfo.INPUT_PRIVATE_CODE_DIALOG_TITLE) - privateInputBoard.SetAcceptEvent(ui.__mem_func__(self.AcceptInputPrivateCode)) - privateInputBoard.SetCancelEvent(ui.__mem_func__(self.CancelInputPrivateCode)) - - if ENABLE_ENGNUM_DELETE_CODE: - pass - else: - privateInputBoard.SetNumberMode() - - privateInputBoard.SetSecretMode() - privateInputBoard.SetMaxLength(7) - - privateInputBoard.SetBoardWidth(250) - privateInputBoard.SetDescription(localeInfo.INPUT_PRIVATE_CODE_DIALOG_DESCRIPTION) - privateInputBoard.Open() - self.privateInputBoard = privateInputBoard - - def AcceptInputPrivateCode(self): - privateCode = self.privateInputBoard.GetText() - if not privateCode: - return - - id = self.GetCharacterSlotID(self.slot) - if 0 == id: - self.PopupMessage(localeInfo.SELECT_EMPTY_SLOT) - return - - net.SendDestroyCharacterPacket(self.slot, privateCode) - self.PopupMessage(localeInfo.SELECT_DELEING) - - self.CancelInputPrivateCode() - return True - - def CancelInputPrivateCode(self): - self.privateInputBoard = None - return True - - def OnDeleteSuccess(self, slot): - self.PopupMessage(localeInfo.SELECT_DELETED) - self.DeleteCharacter(slot) - - def OnDeleteFailure(self): - self.PopupMessage(localeInfo.SELECT_CAN_NOT_DELETE) - - def DeleteCharacter(self, index): - chr.DeleteInstance(index) - self.SelectSlot(self.slot) - - def ExitSelect(self): - self.dlgQuestion.Hide() - - if LEAVE_BUTTON_FOR_POTAL: - if app.loggined: - self.stream.SetPhaseWindow(0) - else: - self.stream.setloginphase() - else: - self.stream.SetLoginPhase() - - self.Hide() - - def GetSlotIndex(self): - return self.slot - - def DecreaseSlotIndex(self): - slotIndex = (self.GetSlotIndex() - 1 + self.SLOT_COUNT) % self.SLOT_COUNT - self.SelectSlot(slotIndex) - - def IncreaseSlotIndex(self): - slotIndex = (self.GetSlotIndex() + 1) % self.SLOT_COUNT - self.SelectSlot(slotIndex) - - def SelectSlot(self, index): - - if index < 0: - return - if index >= self.SLOT_COUNT: - return - - self.slot = index - - chr.SelectInstance(self.slot) - - for i in range(self.CHARACTER_TYPE_COUNT): - self.destNameAlpha[i] = 0.0 - - for i in range(self.SLOT_COUNT): - self.destRotation[(i+self.slot)%self.SLOT_COUNT] = self.SLOT_ROTATION[i] - - self.destGauge = [0.0, 0.0, 0.0, 0.0] - - id=net.GetAccountCharacterSlotDataInteger(self.slot, net.ACCOUNT_CHARACTER_SLOT_ID) - if 0 != id: - - self.btnStart.Show() - self.btnDelete.Show() - self.btnCreate.Hide() - - playTime=net.GetAccountCharacterSlotDataInteger(self.slot, net.ACCOUNT_CHARACTER_SLOT_PLAYTIME) - level=net.GetAccountCharacterSlotDataInteger(self.slot, net.ACCOUNT_CHARACTER_SLOT_LEVEL) - race=net.GetAccountCharacterSlotDataInteger(self.slot, net.ACCOUNT_CHARACTER_SLOT_RACE) - valueHTH=net.GetAccountCharacterSlotDataInteger(self.slot, net.ACCOUNT_CHARACTER_SLOT_HTH) - valueINT=net.GetAccountCharacterSlotDataInteger(self.slot, net.ACCOUNT_CHARACTER_SLOT_INT) - valueSTR=net.GetAccountCharacterSlotDataInteger(self.slot, net.ACCOUNT_CHARACTER_SLOT_STR) - valueDEX=net.GetAccountCharacterSlotDataInteger(self.slot, net.ACCOUNT_CHARACTER_SLOT_DEX) - name=net.GetAccountCharacterSlotDataString(self.slot, net.ACCOUNT_CHARACTER_SLOT_NAME) - guildID=net.GetAccountCharacterSlotDataInteger(self.slot, net.ACCOUNT_CHARACTER_SLOT_GUILD_ID) - guildName=net.GetAccountCharacterSlotDataString(self.slot, net.ACCOUNT_CHARACTER_SLOT_GUILD_NAME) - self.changeNameFlag=net.GetAccountCharacterSlotDataInteger(self.slot, net.ACCOUNT_CHARACTER_SLOT_CHANGE_NAME_FLAG) - - job = chr.RaceToJob(race) - if job >= 0 and job < self.CHARACTER_TYPE_COUNT: - self.destNameAlpha[job] = 1.0 - - self.CharacterName.SetText(name) - self.CharacterLevel.SetText(str(level)) - - self.PlayTime.SetText(str(playTime)) - self.CharacterHTH.SetText(str(valueHTH)) - self.CharacterINT.SetText(str(valueINT)) - self.CharacterSTR.SetText(str(valueSTR)) - self.CharacterDEX.SetText(str(valueDEX)) - - if guildName: - self.GuildName.SetText(guildName) - else: - self.GuildName.SetText(localeInfo.SELECT_NOT_JOIN_GUILD) - - # statesSummary = float(valueHTH + valueINT + valueSTR + valueDEX) - # if statesSummary > 0.0: - # self.destGauge = [ - # float(valueHTH) / statesSummary, - # float(valueINT) / statesSummary, - # float(valueSTR) / statesSummary, - # float(valueDEX) / statesSummary - # ] - - - statesSummary = float(valueHTH + valueINT + valueSTR + valueDEX) - if statesSummary > 0.0: - self.destGauge =[ - float(valueHTH) / 90, - float(valueINT) / 90, - float(valueSTR) / 90, - float(valueDEX) / 90 - ] - - else: - - self.InitCharacterBoard() - - def InitCharacterBoard(self): - - self.btnStart.Hide() - self.btnDelete.Hide() - self.btnCreate.Show() - - self.CharacterName.SetText("") - self.CharacterLevel.SetText("") - self.PlayTime.SetText("") - self.CharacterHTH.SetText("") - self.CharacterINT.SetText("") - self.CharacterSTR.SetText("") - self.CharacterDEX.SetText("") - self.GuildName.SetText(localeInfo.SELECT_NOT_JOIN_GUILD) - - ## Event - def OnKeyDown(self, key): - - if 1 == key: - self.ExitSelect() - if 2 == key: - self.SelectSlot(0) - if 3 == key: - self.SelectSlot(1) - if 4 == key: - self.SelectSlot(2) - if 5 == key: - self.SelectSlot(3) - - if 28 == key: - - id = net.GetAccountCharacterSlotDataInteger(self.slot, net.ACCOUNT_CHARACTER_SLOT_ID) - if 0 == id: - self.CreateCharacter() - - else: - self.StartGame() - - if 203 == key: - self.slot = (self.GetSlotIndex() - 1 + self.SLOT_COUNT) % self.SLOT_COUNT - self.SelectSlot(self.slot) - if 205 == key: - self.slot = (self.GetSlotIndex() + 1) % self.SLOT_COUNT - self.SelectSlot(self.slot) - - return True - - def OnUpdate(self): - chr.Update() - - for i in range(4): - self.curGauge[i] += (self.destGauge[i] - self.curGauge[i]) / 10.0 - if abs(self.curGauge[i] - self.destGauge[i]) < 0.005: - self.curGauge[i] = self.destGauge[i] - self.GaugeList[i].SetPercentage(self.curGauge[i], 1.0) - - for i in range(self.CHARACTER_TYPE_COUNT): - self.curNameAlpha[i] += (self.destNameAlpha[i] - self.curNameAlpha[i]) / 10.0 - self.NameList[i].SetAlpha(self.curNameAlpha[i]) - - for i in range(self.SLOT_COUNT): - - if False == chr.HasInstance(i): - continue - - chr.SelectInstance(i) - - distance = 50.0 - rotRadian = self.curRotation[i] * (math.pi*2) / 360.0 - x = distance*math.sin(rotRadian) + distance*math.cos(rotRadian) - y = distance*math.cos(rotRadian) - distance*math.sin(rotRadian) - chr.SetPixelPosition(int(x), int(y), 30) - - ##### - - dir = app.GetRotatingDirection(self.destRotation[i], self.curRotation[i]) - rot = app.GetDegreeDifference(self.destRotation[i], self.curRotation[i]) - - if app.DEGREE_DIRECTION_RIGHT == dir: - self.curRotation[i] += rot / 10.0 - elif app.DEGREE_DIRECTION_LEFT == dir: - self.curRotation[i] -= rot / 10.0 - - self.curRotation[i] = (self.curRotation[i] + 360.0) % 360.0 - - ####################################################### - if -1 != self.startIndex: - - ## Temporary - ## BackGroundLoading이 지원 될때까지 임시로.. - if app.GetTime() - self.startReservingTime > 3.0: - if False == self.openLoadingFlag: - chrSlot=self.stream.GetCharacterSlot() - net.DirectEnter(chrSlot) - self.openLoadingFlag = True - - playTime=net.GetAccountCharacterSlotDataInteger(self.slot, net.ACCOUNT_CHARACTER_SLOT_PLAYTIME) - - import player - player.SetPlayTime(playTime) - import chat - chat.Clear() ## 들어갈때 Chat 을 초기화. 임시 Pos. - ## Temporary - ####################################################### - - def EmptyFunc(self): - pass - - def PopupMessage(self, msg, func=0): - if not func: - func=self.EmptyFunc - - self.stream.popupWindow.Close() - self.stream.popupWindow.Open(msg, func, localeInfo.UI_OK) - - def OnPressExitKey(self): - self.ExitSelect() - return True - -SelectCharacterWindow._RebuildLocaleStrings() -localeInfo.RegisterReloadCallback(SelectCharacterWindow._RebuildLocaleStrings) diff --git a/tools/root/localeinfo.py b/tools/root/localeinfo.py deleted file mode 100644 index b01434d0..00000000 --- a/tools/root/localeinfo.py +++ /dev/null @@ -1,481 +0,0 @@ -import app -import dbg - -APP_GET_LOCALE_PATH = app.GetLocalePath() -APP_GET_LOCALE_PATH_COMMON = app.GetLocalePathCommon() - -APP_TITLE = 'METIN2' - -BLEND_POTION_NO_TIME = 'BLEND_POTION_NO_TIME' -BLEND_POTION_NO_INFO = 'BLEND_POTION_NO_INFO' - -LOGIN_FAILURE_WRONG_SOCIALID = 'LOGIN_FAILURE_WRONG_SOCIALID' -LOGIN_FAILURE_SHUTDOWN_TIME = 'LOGIN_FAILURE_SHUTDOWN_TIME' - -GUILD_MEMBER_COUNT_INFINITY = 'INFINITY' -GUILD_MARK_MIN_LEVEL = '3' -GUILD_BUILDING_LIST_TXT = '{:s}/GuildBuildingList.txt'.format(APP_GET_LOCALE_PATH) -FN_GM_MARK = '{:s}/effect/gm.mse'.format(APP_GET_LOCALE_PATH_COMMON) - -MAP_TREE2 = 'MAP_TREE2' - -ERROR_MARK_UPLOAD_NEED_RECONNECT = 'UploadMark: Reconnect to game' -ERROR_MARK_CHECK_NEED_RECONNECT = 'CheckMark: Reconnect to game' - -VIRTUAL_KEY_ALPHABET_LOWERS = r"[1234567890]/qwertyuiop\=asdfghjkl;`'zxcvbnm.," -VIRTUAL_KEY_ALPHABET_UPPERS = r"{1234567890}?QWERTYUIOP|+ASDFGHJKL:~'ZXCVBNM<>" -VIRTUAL_KEY_SYMBOLS = "!@#$%^&*()_+|{}:'<>?~" -VIRTUAL_KEY_NUMBERS = "1234567890-=\\[];',./`" -VIRTUAL_KEY_SYMBOLS_BR = "!@#$%^&*()_+|{}:'<>?~aaaaeeeiioooouuc" - -# Hot-reload callback registry -_reloadCallbacks = [] - -def RegisterReloadCallback(callback): - """Register a function to be called after locale strings are reloaded.""" - if callback not in _reloadCallbacks: - _reloadCallbacks.append(callback) - -# Multi-language hot-reload support -def LoadLocaleData(): - """ - Reload all game locale text strings from locale_game.txt - - Called by app.ReloadLocale() when the user changes language. - Reloads locale_game.txt and rebuilds all derived data structures. - - NOTE: Does NOT fire reload callbacks. The C++ reload chain calls - localeInfo.LoadLocaleData() first, then uiScriptLocale.LoadLocaleData() - second. Callbacks are fired by uiScriptLocale.LoadLocaleData() after - BOTH modules are fully reloaded, so callbacks can safely read from - either module. - - Returns: - True on success, False on failure - """ - try: - global APP_GET_LOCALE_PATH, APP_GET_LOCALE_PATH_COMMON - APP_GET_LOCALE_PATH = app.GetLocalePath() - APP_GET_LOCALE_PATH_COMMON = app.GetLocalePathCommon() - - localeFilePath = "{:s}/locale_game.txt".format(APP_GET_LOCALE_PATH) - LoadLocaleFile(localeFilePath, globals()) - - _RebuildDerivedData() - - return True - except Exception as e: - dbg.TraceError("localeInfo.LoadLocaleData failed: %s" % str(e)) - return False - -def FireReloadCallbacks(): - """ - Fire all registered reload callbacks. - - Called by uiScriptLocale.LoadLocaleData() after both locale modules - are fully reloaded, ensuring callbacks see fresh data from both - localeInfo and uiScriptLocale. - """ - for cb in _reloadCallbacks: - try: - cb() - except Exception as e: - dbg.TraceError("localeInfo reload callback failed: %s" % str(e)) - -# Load locale_game.txt -def LoadLocaleFile(srcFileName, localeDict): - def SNA(text): - def f(x): - return text - return f - - def SA(text): - def f(x): - return text % x - return f - - def SAN(text): - def f(x): - return text % x - return f - - def SAA(text): - def f(x): - return text % x - return f - - funcDict = {"SA": SA, "SNA": SNA, "SAA": SAA, "SAN": SAN} - lineIndex = 1 - - try: - lines = pack_open(srcFileName, "r").readlines() - except IOError: - dbg.LogBox("LoadLocaleError(%(srcFileName)s)" % locals()) - app.Abort() - - for line in lines: - if line.count("\t") == 0: - continue - - try: - tokens = line[:-1].split("\t") - if len(tokens) == 2: - localeDict[tokens[0]] = tokens[1] - elif len(tokens) >= 3: - type = tokens[2].strip() - if type: - if type in funcDict: - localeDict[tokens[0]] = funcDict[type](tokens[1]) - else: - localeDict[tokens[0]] = tokens[1] - else: - localeDict[tokens[0]] = tokens[1] - else: - raise RuntimeError("Unknown TokenSize") - - lineIndex += 1 - except: - dbg.LogBox("%s: line(%d): %s" % (srcFileName, lineIndex, line), "Error") - raise - -LoadLocaleFile("{:s}/locale_game.txt".format(APP_GET_LOCALE_PATH), globals()) - -try: - currentLocalePath = app.GetLocalePath() - if not app.LoadLocaleData(currentLocalePath): - dbg.TraceError("localeInfo: Failed to load C++ locale data from %s" % currentLocalePath) -except Exception as e: - dbg.TraceError("localeInfo: Error loading C++ locale data: %s" % str(e)) - -def _RebuildDerivedData(): - """Rebuild all derived dicts/tuples/lists from current locale strings.""" - global GUILD_BUILDING_LIST_TXT, FN_GM_MARK - global OPTION_PVPMODE_MESSAGE_DICT, WHISPER_ERROR, error - global JOBINFO_TITLE - global GUILDWAR_NORMAL_DESCLIST, GUILDWAR_WARP_DESCLIST, GUILDWAR_CTF_DESCLIST - global MODE_NAME_LIST, TITLE_NAME_LIST, LEVEL_LIST, HEALTH_LIST - global USE_SKILL_ERROR_TAIL_DICT, NOTIFY_MESSAGE, ATTACK_ERROR_TAIL_DICT - global SHOT_ERROR_TAIL_DICT, USE_SKILL_ERROR_CHAT_DICT - global SHOP_ERROR_DICT, STAT_MINUS_DESCRIPTION, MINIMAP_ZONE_NAME_DICT - - GUILD_BUILDING_LIST_TXT = '{:s}/GuildBuildingList.txt'.format(APP_GET_LOCALE_PATH) - FN_GM_MARK = '{:s}/effect/gm.mse'.format(APP_GET_LOCALE_PATH_COMMON) - - # Option pvp messages - OPTION_PVPMODE_MESSAGE_DICT = { - 0: PVP_MODE_NORMAL, - 1: PVP_MODE_REVENGE, - 2: PVP_MODE_KILL, - 3: PVP_MODE_PROTECT, - 4: PVP_MODE_GUILD, - } - - # Whisper messages - WHISPER_ERROR = { - 1: CANNOT_WHISPER_NOT_LOGON, - 2: CANNOT_WHISPER_DEST_REFUSE, - 3: CANNOT_WHISPER_SELF_REFUSE, - } - - # Exception of graphic device. - error = dict( - CREATE_WINDOW = GAME_INIT_ERROR_MAIN_WINDOW, - CREATE_CURSOR = GAME_INIT_ERROR_CURSOR, - CREATE_NETWORK = GAME_INIT_ERROR_NETWORK, - CREATE_ITEM_PROTO = GAME_INIT_ERROR_ITEM_PROTO, - CREATE_MOB_PROTO = GAME_INIT_ERROR_MOB_PROTO, - CREATE_NO_DIRECTX = GAME_INIT_ERROR_DIRECTX, - CREATE_DEVICE = GAME_INIT_ERROR_GRAPHICS_NOT_EXIST, - CREATE_NO_APPROPRIATE_DEVICE = GAME_INIT_ERROR_GRAPHICS_BAD_PERFORMANCE, - CREATE_FORMAT = GAME_INIT_ERROR_GRAPHICS_NOT_SUPPORT_32BIT, - NO_ERROR = str() - ) - - # Job information (none, skill_group1, skill_group2) - JOBINFO_TITLE = [ - [JOB_WARRIOR0, JOB_WARRIOR1, JOB_WARRIOR2,], - [JOB_ASSASSIN0, JOB_ASSASSIN1, JOB_ASSASSIN2,], - [JOB_SURA0, JOB_SURA1, JOB_SURA2,], - [JOB_SHAMAN0, JOB_SHAMAN1, JOB_SHAMAN2,], - ] - - #if app.ENABLE_WOLFMAN_CHARACTER: - #JOBINFO_TITLE += [[JOB_WOLFMAN0,JOB_WOLFMAN1,JOB_WOLFMAN2,],] - - # Guild war description - GUILDWAR_NORMAL_DESCLIST = (GUILD_WAR_USE_NORMAL_MAP, GUILD_WAR_LIMIT_30MIN, GUILD_WAR_WIN_CHECK_SCORE) - # Guild war warp description - GUILDWAR_WARP_DESCLIST = (GUILD_WAR_USE_BATTLE_MAP, GUILD_WAR_WIN_WIPE_OUT_GUILD, GUILD_WAR_REWARD_POTION) - # Guild war flag description - GUILDWAR_CTF_DESCLIST = (GUILD_WAR_USE_BATTLE_MAP, GUILD_WAR_WIN_TAKE_AWAY_FLAG1, GUILD_WAR_WIN_TAKE_AWAY_FLAG2, GUILD_WAR_REWARD_POTION) - - # Mode of pvp options - MODE_NAME_LIST = (PVP_OPTION_NORMAL, PVP_OPTION_REVENGE, PVP_OPTION_KILL, PVP_OPTION_PROTECT,) - # Title name of alignment - TITLE_NAME_LIST = (PVP_LEVEL0, PVP_LEVEL1, PVP_LEVEL2, PVP_LEVEL3, PVP_LEVEL4, PVP_LEVEL5, PVP_LEVEL6, PVP_LEVEL7, PVP_LEVEL8,) - - # Horse levels - LEVEL_LIST = (str(), HORSE_LEVEL1, HORSE_LEVEL2, HORSE_LEVEL3) - # Horse health - HEALTH_LIST = (HORSE_HEALTH0, HORSE_HEALTH1, HORSE_HEALTH2, HORSE_HEALTH3) - - # Use-skill messages - USE_SKILL_ERROR_TAIL_DICT = { - 'IN_SAFE': CANNOT_SKILL_SELF_IN_SAFE, - 'NEED_TARGET': CANNOT_SKILL_NEED_TARGET, - 'NEED_EMPTY_BOTTLE': CANNOT_SKILL_NEED_EMPTY_BOTTLE, - 'NEED_POISON_BOTTLE': CANNOT_SKILL_NEED_POISON_BOTTLE, - 'REMOVE_FISHING_ROD': CANNOT_SKILL_REMOVE_FISHING_ROD, - 'NOT_YET_LEARN': CANNOT_SKILL_NOT_YET_LEARN, - 'NOT_MATCHABLE_WEAPON': CANNOT_SKILL_NOT_MATCHABLE_WEAPON, - 'WAIT_COOLTIME': CANNOT_SKILL_WAIT_COOLTIME, - 'NOT_ENOUGH_HP': CANNOT_SKILL_NOT_ENOUGH_HP, - 'NOT_ENOUGH_SP': CANNOT_SKILL_NOT_ENOUGH_SP, - 'CANNOT_USE_SELF': CANNOT_SKILL_USE_SELF, - 'ONLY_FOR_ALLIANCE': CANNOT_SKILL_ONLY_FOR_ALLIANCE, - 'CANNOT_ATTACK_ENEMY_IN_SAFE_AREA': CANNOT_SKILL_DEST_IN_SAFE, - 'CANNOT_APPROACH': CANNOT_SKILL_APPROACH, - 'CANNOT_ATTACK': CANNOT_SKILL_ATTACK, - 'ONLY_FOR_CORPSE': CANNOT_SKILL_ONLY_FOR_CORPSE, - 'EQUIP_FISHING_ROD': CANNOT_SKILL_EQUIP_FISHING_ROD, - 'NOT_HORSE_SKILL': CANNOT_SKILL_NOT_HORSE_SKILL, - 'HAVE_TO_RIDE': CANNOT_SKILL_HAVE_TO_RIDE, - } - - # Notify messages - NOTIFY_MESSAGE = { - 'CANNOT_EQUIP_SHOP': CANNOT_EQUIP_IN_SHOP, - 'CANNOT_EQUIP_EXCHANGE': CANNOT_EQUIP_IN_EXCHANGE, - } - - # Attack messages - ATTACK_ERROR_TAIL_DICT = { - 'IN_SAFE': CANNOT_ATTACK_SELF_IN_SAFE, - 'DEST_IN_SAFE': CANNOT_ATTACK_DEST_IN_SAFE, - } - - # Shot messages - SHOT_ERROR_TAIL_DICT = { - 'EMPTY_ARROW': CANNOT_SHOOT_EMPTY_ARROW, - 'IN_SAFE': CANNOT_SHOOT_SELF_IN_SAFE, - 'DEST_IN_SAFE': CANNOT_SHOOT_DEST_IN_SAFE, - } - - # Skill messages - USE_SKILL_ERROR_CHAT_DICT = { - 'NEED_EMPTY_BOTTLE': SKILL_NEED_EMPTY_BOTTLE, - 'NEED_POISON_BOTTLE': SKILL_NEED_POISON_BOTTLE, - 'ONLY_FOR_GUILD_WAR': SKILL_ONLY_FOR_GUILD_WAR, - } - - # Shop/private-shop messages - SHOP_ERROR_DICT = { - 'NOT_ENOUGH_MONEY': SHOP_NOT_ENOUGH_MONEY, - 'SOLDOUT': SHOP_SOLDOUT, - 'INVENTORY_FULL': SHOP_INVENTORY_FULL, - 'INVALID_POS': SHOP_INVALID_POS, - 'NOT_ENOUGH_MONEY_EX': SHOP_NOT_ENOUGH_MONEY_EX, - } - - # Character status description - STAT_MINUS_DESCRIPTION = { - 'HTH-': STAT_MINUS_CON, - 'INT-': STAT_MINUS_INT, - 'STR-': STAT_MINUS_STR, - 'DEX-': STAT_MINUS_DEX, - } - - # MR-11: Complete map name list - # Map names - MINIMAP_ZONE_NAME_DICT = { - 'metin2_map_a1': MAP_A1, - 'map_a2': MAP_A2, - 'metin2_map_a3': MAP_A3, - 'metin2_map_b1': MAP_B1, - 'map_b2': MAP_B2, - 'metin2_map_b3': MAP_B3, - 'metin2_map_c1': MAP_C1, - 'map_c2': MAP_C2, - 'metin2_map_c3': MAP_C3, - 'map_n_snowm_01': MAP_SNOW, - 'metin2_map_n_flame_01': MAP_FLAME, - 'metin2_map_n_desert_01': MAP_DESERT, - 'metin2_map_milgyo': MAP_TEMPLE, - 'metin2_map_monkeydungeon': MAP_MONKEY_DUNGEON, - 'metin2_map_monkeydungeon_02': MAP_MONKEY_DUNGEON2, - 'metin2_map_monkeydungeon_03': MAP_MONKEY_DUNGEON3, - 'metin2_map_spiderdungeon': MAP_SPIDER, - 'metin2_map_spiderdungeon_02': MAP_SPIDERDUNGEON_02, - 'metin2_map_spiderdungeon_03': MAP_SPIDERDUNGEON_03, - 'metin2_map_deviltower1': MAP_DEVILTOWER1, - 'metin2_map_devilsCatacomb': MAP_DEVILCATACOMB, - 'metin2_map_guild_01': MAP_GUILD_01, - 'metin2_map_guild_02': MAP_GUILD_02, - 'metin2_map_guild_03': MAP_GUILD_03, - 'metin2_guild_village_01': GUILD_VILLAGE_01, - 'metin2_guild_village_02': GUILD_VILLAGE_02, - 'metin2_guild_village_03': GUILD_VILLAGE_03, - 'metin2_map_trent': MAP_TREE, - 'metin2_map_trent02': MAP_TREE2, - 'season1/metin2_map_WL_01': MAP_WL, - 'season1/metin2_map_nusluck01': MAP_NUSLUCK, - 'season1/metin2_map_oxevent': MAP_OXEVENT, - 'metin2_map_wedding_01': MAP_WEDDING_01, - 'metin2_map_bf': MAP_BATTLE_FIELD, - 'metin2_map_bf_02': MAP_BATTLE_FIELD, - 'metin2_map_bf_03': MAP_BATTLE_FIELD, - 'Metin2_map_CapeDragonHead': MAP_CAPE, - 'metin2_map_Mt_Thunder': MAP_THUNDER, - 'metin2_map_dawnmistwood': MAP_DAWN, - 'metin2_map_BayBlackSand': MAP_BAY, - 'metin2_map_n_flame_dungeon_01': MAP_N_FLAME_DUNGEON_01, - 'metin2_map_n_snow_dungeon_01': MAP_N_SNOW_DUNGEON_01, - 'metin2_map_duel': MAP_DUEL, - 'season2/metin2_map_skipia_dungeon_01': MAP_SKIPIA_DUNGEON_01, - 'metin2_map_skipia_dungeon_02': MAP_SKIPIA_DUNGEON_02, - 'metin2_map_skipia_dungeon_boss': MAP_SKIPIA_DUNGEON_BOSS, - 'metin2_map_skipia_dungeon_boss2': MAP_SKIPIA_DUNGEON_BOSS_2, - } - # MR-11: -- END OF -- Complete map name list - -_RebuildDerivedData() - -# Path of quest icon file -def GetLetterImageName(): - return "season1/icon/scroll_close.tga" - -def GetLetterOpenImageName(): - return "season1/icon/scroll_open.tga" - -def GetLetterCloseImageName(): - return "season1/icon/scroll_close.tga" - -# Sell item question -def DO_YOU_SELL_ITEM(sellItemName, sellItemCount, sellItemPrice): - return DO_YOU_SELL_ITEM2 % (sellItemName, sellItemCount, NumberToMoneyString(sellItemPrice)) if (sellItemCount > 1) else DO_YOU_SELL_ITEM1 % (sellItemName, NumberToMoneyString(sellItemPrice)) - -# Buy item question -def DO_YOU_BUY_ITEM(buyItemName, buyItemCount, buyItemPrice): - return DO_YOU_BUY_ITEM2 % (buyItemName, buyItemCount, buyItemPrice) if (buyItemCount > 1) else DO_YOU_BUY_ITEM1 % (buyItemName, buyItemPrice) - -# Notify when you can't attach a specific item. -def REFINE_FAILURE_CAN_NOT_ATTACH(attachedItemName): - return REFINE_FAILURE_CAN_NOT_ATTACH0 % (attachedItemName) - -def REFINE_FAILURE_NO_SOCKET(attachedItemName): - return REFINE_FAILURE_NO_SOCKET0 % (attachedItemName) - -# Drop item question -def REFINE_FAILURE_NO_GOLD_SOCKET(attachedItemName): - return REFINE_FAILURE_NO_GOLD_SOCKET0 % (attachedItemName) - -# Drop item question -def HOW_MANY_ITEM_DO_YOU_DROP(dropItemName, dropItemCount): - return HOW_MANY_ITEM_DO_YOU_DROP2 % (dropItemName, dropItemCount) if (dropItemCount > 1) else HOW_MANY_ITEM_DO_YOU_DROP1 % (dropItemName) - -# Fishing notify when looks like the fish is hooked. -def FISHING_NOTIFY(isFish, fishName): - return FISHING_NOTIFY1 % (fishName) if isFish else FISHING_NOTIFY2 % (fishName) - -# Fishing notify when you capture a fish. -def FISHING_SUCCESS(isFish, fishName): - return FISHING_SUCCESS1 % (fishName) if isFish else FISHING_SUCCESS2 % (fishName) - -# Convert a integer amount into a string and add . as separator for money. -def NumberToMoneyString(n): - return '0 {:s}'.format(MONETARY_UNIT0) if (n <= 0) else '{:s} {:s}'.format('.'.join([(i - 3) < 0 and str(n)[:i] or str(n)[i - 3 : i] for i in range(len(str(n)) % 3, len(str(n)) + 1, 3) if i]), MONETARY_UNIT0) - -# Convert a integer amount into a string and add . as separator for secondary coin. -def NumberToSecondaryCoinString(n): - return '0 {:s}'.format(MONETARY_UNIT_JUN) if (n <= 0) else '{:s} {:s}'.format('.'.join([(i - 3) < 0 and str(n)[:i] or str(n)[i - 3: i] for i in range(len(str(n)) % 3, len(str(n)) + 1, 3) if i]), MONETARY_UNIT_JUN) - -# Return the title of alignment by points. -def GetAlignmentTitleName(alignment): - if alignment >= 12000: - return TITLE_NAME_LIST[0] - elif alignment >= 8000: - return TITLE_NAME_LIST[1] - elif alignment >= 4000: - return TITLE_NAME_LIST[2] - elif alignment >= 1000: - return TITLE_NAME_LIST[3] - elif alignment >= 0: - return TITLE_NAME_LIST[4] - elif alignment > -4000: - return TITLE_NAME_LIST[5] - elif alignment > -8000: - return TITLE_NAME_LIST[6] - elif alignment > -12000: - return TITLE_NAME_LIST[7] - - return TITLE_NAME_LIST[8] - -# Convert seconds to Days-Hours-Minutes -def SecondToDHM(time): - if time < 60: - return '0' + MINUTE - - minute = (time // 60) % 60 - hour = ((time // 60) // 60) % 24 - day = ((time // 60) // 60) // 24 - - text = '' - - if day > 0: - text += str(day) + DAY - text += ' ' - - if hour > 0: - text += str(hour) + HOUR - text += ' ' - - if minute > 0: - text += str(minute) + MINUTE - return text - -# Convert seconds to Hours-Minutes -def SecondToHM(time): - if time < 60: - return '0' + MINUTE - - minute = (time // 60) % 60 - hour = (time // 60) // 60 - - text = '' - if hour > 0: - text += str(hour) + HOUR - if hour > 0: - text += ' ' - - if minute > 0: - text += str(minute) + MINUTE - return text - -# Convert seconds to Days-Hours-Minutes-Seconds in real time -def RTSecondToDHMS(time): - text = "" - - d = time // (24 * 3600) - time %= (24 * 3600) - h = time // 3600 - time %= 3600 - m = time // 60 - s = time % 60 - - if d or not text: - if d: - text += str(d) + " " + DAY + (", " if h or m or s else "") - - if h or not text: - if h: - text += str(h) + " " + HOUR + (", " if m or s else "") - - if m or not text: - if m: - text += str(m) + " " + MINUTE + (", " if s else "") - - if s or not text: - if s: - text += str(s) + " " + SECOND - - return text.strip() diff --git a/tools/root/makepackscript_onlyrootnopython.txt b/tools/root/makepackscript_onlyrootnopython.txt deleted file mode 100644 index 66095d88..00000000 --- a/tools/root/makepackscript_onlyrootnopython.txt +++ /dev/null @@ -1,102 +0,0 @@ -FolderName "pack" - -List ExcludedFolderNameList -{ - "CVS" -} -List ExcludedFileNameList -{ - "vssver.scc" - "syserr.txt" - "soundscript.txt" - "log.txt" - "Test.py" - "Prototype[OffLine].py" - "loginInfo.py" - "error_lookup.py" - "errorlog.txt" - "makepackscript.txt" - "makepackscript_onlyroot.txt" - "moviemakepackscript.txt" - "build_mottable.py" - "uitest.py" - "packall.txt" - "packitem.txt" - "packpc.txt" - "packroot.txt" - "test.txt" - "test2.txt" - "quest_test.py" -} -List SecurityExtNameList -{ - "txt" - "msk" - "msa" - "msm" - "py" -} -List CompressExtNameList -{ - "txt" - "msk" - "mss" - "mse" - "msf" - "msa" - "spt" - "atr" - "dds" - "raw" - "wtr" - "mde" - "tga" -} - -Group RootPackItemList -{ - Group ItemProto - { - FileName "*item_proto" - Fixed TRUE - } - Group mob_proto - { - FileName "*mob_proto" - Fixed TRUE - } - Group TextureSet - { - FileName "TextureSet/*.txt" - Fixed TRUE - } - Group TextFiles - { - FileName "*.txt" - Fixed TRUE - } - Group TextFiles - { - FileName "*.tbl" - Fixed TRUE - } - Group KoreanFiles - { - FileName "*.cvt" - Fixed TRUE - } - Group ModelFiles - { - FileName "*.msm" - Fixed TRUE - } -} - -Group PackList -{ - Group UIScript - { - PathName "UIScript/*" - Fixed TRUE - } -} diff --git a/tools/root/mousemodule.py b/tools/root/mousemodule.py deleted file mode 100644 index 6f00c6a5..00000000 --- a/tools/root/mousemodule.py +++ /dev/null @@ -1,405 +0,0 @@ -import app -import grp -import grpImage -import item -import wndMgr -import player - -import skill -import dbg -import grpText - -import ui - -import systemSetting - -import localeInfo - -## Mouse Controller -## When operating the mouse cursor, you can exchange information with the attached Object. - -class CursorImage(object): - def __init__(self): - self.handle = 0 - - def __init__(self, imageName): - self.handle = 0 - self.LoadImage(imageName) - - # MR-10: Fix mouse destruction - def __del__(self): - try: - if grpImage and self.handle and hasattr(grpImage, "Delete"): - grpImage.Delete(self.handle) - except: - pass - # MR-10: -- END OF -- Fix mouse destruction - - def LoadImage(self, imageName): - try: - self.handle = grpImage.Generate(imageName) - - except: - import sys - dbg.TraceError("%s %s" % (sys.exc_info()[0], sys.exc_info()[1])) - self.handle = 0 - - def DeleteImage(self): - if self.handle: - grpImage.Delete(self.handle) - - def IsImage(self): - if self.handle: - return True - - return False - - def SetPosition(self, x, y): - if self.handle: - grpImage.SetPosition(self.handle, x, y) - - def Render(self): - if self.handle: - grpImage.Render(self.handle) - -class CMouseController(object): - - def __init__(self): - - self.x = 0 - self.y = 0 - - self.IsSoftwareCursor = False - self.curCursorName = "" - self.curCursorImage = 0 - self.cursorPosX = 0 - self.cursorPosY = 0 - - self.AttachedIconHandle = 0 - self.AttachedOwner = 0 - self.AttachedFlag = False - self.AttachedType = 0 - self.AttachedSlotNumber = 0 - self.AttachedCount = 1 - self.AttachedIconHalfWidth = 0 - self.AttachedIconHalfHeight = 0 - self.LastAttachedSlotNumber = 0 - - self.countNumberLine = None - - self.DeattachObject() - - self.callbackDict = {} - - def __del__(self): - self.callbackDict = {} - - def Create(self): - self.IsSoftwareCursor = systemSetting.IsSoftwareCursor() - - self.cursorDict = { - app.NORMAL : CursorImage("D:/Ymir Work/UI/Cursor/cursor.sub"), - app.ATTACK : CursorImage("D:/Ymir Work/UI/Cursor/cursor_attack.sub"), - app.TARGET : CursorImage("D:/Ymir Work/UI/Cursor/cursor_attack.sub"), - app.TALK : CursorImage("D:/Ymir Work/UI/Cursor/cursor_talk.sub"), - app.CANT_GO : CursorImage("D:/Ymir Work/UI/Cursor/cursor_no.sub"), - app.PICK : CursorImage("D:/Ymir Work/UI/Cursor/cursor_pick.sub"), - app.DOOR : CursorImage("D:/Ymir Work/UI/Cursor/cursor_door.sub"), - app.CHAIR : CursorImage("D:/Ymir Work/UI/Cursor/cursor_chair.sub"), - app.MAGIC : CursorImage("D:/Ymir Work/UI/Cursor/cursor_chair.sub"), - app.BUY : CursorImage("D:/Ymir Work/UI/Cursor/cursor_buy.sub"), - app.SELL : CursorImage("D:/Ymir Work/UI/Cursor/cursor_sell.sub"), - app.CAMERA_ROTATE : CursorImage("D:/Ymir Work/UI/Cursor/cursor_camera_rotate.sub"), - app.HSIZE : CursorImage("D:/Ymir Work/UI/Cursor/cursor_hsize.sub"), - app.VSIZE : CursorImage("D:/Ymir Work/UI/Cursor/cursor_vsize.sub"), - app.HVSIZE : CursorImage("D:/Ymir Work/UI/Cursor/cursor_hvsize.sub"), - } - self.cursorPosDict = { - app.NORMAL : (0, 0), - app.TARGET : (0, 0), - app.ATTACK : (0, 0), - app.TALK : (0, 0), - app.CANT_GO : (0, 0), - app.PICK : (0, 0), - app.DOOR : (0, 0), - app.CHAIR : (0, 0), - app.MAGIC : (0, 0), - app.BUY : (0, 0), - app.SELL : (0, 0), - app.CAMERA_ROTATE : (0, 0), - app.HSIZE : (-16, -16), - app.VSIZE : (-16, -16), - app.HVSIZE : (-16, -16), - } - - app.SetCursor(app.NORMAL) - - """ - AttachedCountTextLineHandle = grpText.Generate() - grpText.SetFontName(AttachedCountTextLineHandle, localeInfo.UI_DEF_FONT_SMALL) - grpText.SetText(AttachedCountTextLineHandle, "1234") - grpText.SetPosition(AttachedCountTextLineHandle, 100, 100) - grpText.SetOutline(AttachedCountTextLineHandle, True) - grpText.SetFontColor(AttachedCountTextLineHandle, 1.0, 1.0, 1.0) - grpText.SetHorizontalAlign(AttachedCountTextLineHandle, wndMgr.TEXT_HORIZONTAL_ALIGN_CENTER) - self.AttachedCountTextLineHandle = AttachedCountTextLineHandle - """ - - self.countNumberLine = ui.NumberLine("CURTAIN") - self.countNumberLine.SetHorizontalAlignCenter() - self.countNumberLine.Hide() - - return True - - # Cursor Control - def ChangeCursor(self, cursorNum): - try: - self.curCursorNum = cursorNum - self.curCursorImage = self.cursorDict[cursorNum] - (self.cursorPosX, self.cursorPosY) = self.cursorPosDict[cursorNum] - - if False == self.curCursorImage.IsImage(): - self.curCursorNum = app.NORMAL - self.curCursorImage = self.cursorDict[app.NORMAL] - - except KeyError: - dbg.TraceError("mouseModule.MouseController.SetCursor - Invalid cursor number [%d]" % cursorNum) - self.curCursorName = app.NORMAL - self.curCursorImage = self.cursorDict[app.NORMAL] - - # Attaching - def AttachObject(self, Owner, Type, SlotNumber, ItemIndex, count = 0): - - self.LastAttachedSlotNumber = self.AttachedSlotNumber - - self.AttachedFlag = True - self.AttachedOwner = Owner - self.AttachedType = Type - self.AttachedSlotNumber = SlotNumber - self.AttachedItemIndex = ItemIndex - self.AttachedCount = count - self.countNumberLine.SetNumber("") - self.countNumberLine.Hide() - - if count > 1: - self.countNumberLine.SetNumber(str(count)) - self.countNumberLine.Show() - - try: - - width = 1 - height = 1 - - if Type == player.SLOT_TYPE_INVENTORY or\ - Type == player.SLOT_TYPE_PRIVATE_SHOP or\ - Type == player.SLOT_TYPE_SHOP or\ - Type == player.SLOT_TYPE_SAFEBOX or\ - Type == player.SLOT_TYPE_MALL or\ - Type == player.SLOT_TYPE_DRAGON_SOUL_INVENTORY: - - item.SelectItem(self.AttachedItemIndex) - self.AttachedIconHandle = item.GetIconInstance() - - if not self.AttachedIconHandle: - self.AttachedIconHandle = 0 - self.DeattachObject() - return - - (width, height) = item.GetItemSize() - - elif Type == player.SLOT_TYPE_SKILL: - skillGrade = player.GetSkillGrade(SlotNumber) - self.AttachedIconHandle = skill.GetIconInstanceNew(self.AttachedItemIndex, skillGrade) - - elif Type == player.SLOT_TYPE_EMOTION: - image = player.GetEmotionIconImage(ItemIndex) - self.AttachedIconHandle = grpImage.GenerateFromHandle(image) - - elif Type == player.SLOT_TYPE_QUICK_SLOT: - (quickSlotType, position) = player.GetGlobalQuickSlot(SlotNumber) - - if quickSlotType == player.SLOT_TYPE_INVENTORY: - - itemIndex = player.GetItemIndex(position) - item.SelectItem(itemIndex) - self.AttachedIconHandle = item.GetIconInstance() - (width, height) = item.GetItemSize() - - elif quickSlotType == player.SLOT_TYPE_SKILL: - skillIndex = player.GetSkillIndex(position) - skillGrade = player.GetSkillGrade(position) - self.AttachedIconHandle = skill.GetIconInstanceNew(skillIndex, skillGrade) - - elif quickSlotType == player.SLOT_TYPE_EMOTION: - image = player.GetEmotionIconImage(position) - self.AttachedIconHandle = grpImage.GenerateFromHandle(image) - - if not self.AttachedIconHandle: - self.DeattachObject() - return - - self.AttachedIconHalfWidth = grpImage.GetWidth(self.AttachedIconHandle) / 2 - self.AttachedIconHalfHeight = grpImage.GetHeight(self.AttachedIconHandle) / 2 - self.AttachedIconHalfWidth = grpImage.GetWidth(self.AttachedIconHandle) / 2 - self.AttachedIconHalfHeight = grpImage.GetHeight(self.AttachedIconHandle) / 2 - wndMgr.AttachIcon(self.AttachedType, self.AttachedItemIndex, self.AttachedSlotNumber, width, height) - - except Exception as e: - dbg.TraceError("mouseModule.py: AttachObject : " + str(e)) - self.AttachedIconHandle = 0 - - def IsAttachedMoney(self): - if True == self.isAttached(): - if player.ITEM_MONEY == self.GetAttachedItemIndex(): - return True - - return False - - def GetAttachedMoneyAmount(self): - if True == self.isAttached(): - if player.ITEM_MONEY == self.GetAttachedItemIndex(): - return self.GetAttachedItemCount() - return 0 - - def AttachMoney(self, owner, type, count): - - self.LastAttachedSlotNumber = self.AttachedSlotNumber - - self.AttachedFlag = True - self.AttachedOwner = owner - self.AttachedType = type - self.AttachedSlotNumber = -1 - self.AttachedItemIndex = player.ITEM_MONEY - self.AttachedCount = count - self.AttachedIconHandle = grpImage.Generate("icon/item/money.tga") - self.AttachedIconHalfWidth = grpImage.GetWidth(self.AttachedIconHandle) / 2 - self.AttachedIconHalfHeight = grpImage.GetHeight(self.AttachedIconHandle) / 2 - wndMgr.AttachIcon(self.AttachedType, self.AttachedItemIndex, self.AttachedSlotNumber, 1, 1) - - if count > 1: - self.countNumberLine.SetNumber(str(count)) - self.countNumberLine.Show() - #grpText.SetText(self.AttachedCountTextLineHandle, str(count)) - - def DeattachObject(self): - - self.ClearCallBack() - self.LastAttachedSlotNumber = self.AttachedSlotNumber - - if self.AttachedIconHandle != 0: - - if self.AttachedType == player.SLOT_TYPE_INVENTORY or\ - self.AttachedType == player.SLOT_TYPE_PRIVATE_SHOP or\ - self.AttachedType == player.SLOT_TYPE_SHOP or\ - self.AttachedType == player.SLOT_TYPE_SAFEBOX or\ - self.AttachedType == player.SLOT_TYPE_MALL: - - item.DeleteIconInstance(self.AttachedIconHandle) - - elif self.AttachedType == player.SLOT_TYPE_SKILL: - skill.DeleteIconInstance(self.AttachedIconHandle) - - elif self.AttachedType == player.SLOT_TYPE_EMOTION: - grpImage.Delete(self.AttachedIconHandle) - - self.AttachedFlag = False - self.AttachedType = -1 - self.AttachedItemIndex = -1 - self.AttachedSlotNumber = -1 - self.AttachedIconHandle = 0 - wndMgr.SetAttachingFlag(False) - - if self.countNumberLine: - self.countNumberLine.Hide() - - def isAttached(self): - return self.AttachedFlag - - def GetAttachedOwner(self): - - if False == self.isAttached(): - return 0 - - return self.AttachedOwner - - def GetAttachedType(self): - - if False == self.isAttached(): - return player.SLOT_TYPE_NONE - - return self.AttachedType - - def GetAttachedSlotNumber(self): - - if False == self.isAttached(): - return 0 - - return self.AttachedSlotNumber - - def GetLastAttachedSlotNumber(self): - - return self.LastAttachedSlotNumber - - def GetAttachedItemIndex(self): - - if False == self.isAttached(): - return 0 - - return self.AttachedItemIndex - - def GetAttachedItemCount(self): - - if False == self.isAttached(): - return 0 - - return self.AttachedCount - - # Update - def Update(self, x, y): - - self.x = x - self.y = y - - if True == self.isAttached(): - if 0 != self.AttachedIconHandle: - grpImage.SetDiffuseColor(self.AttachedIconHandle, 1.0, 1.0, 1.0, 0.5) - grpImage.SetPosition(self.AttachedIconHandle, self.x - self.AttachedIconHalfWidth, self.y - self.AttachedIconHalfHeight) - self.countNumberLine.SetPosition(self.x, self.y - self.AttachedIconHalfHeight - 3) - - if self.IsSoftwareCursor: - if 0 != self.curCursorImage: - self.curCursorImage.SetPosition(self.x + self.cursorPosX, self.y + self.cursorPosY) - - # Render - def Render(self): - - if True == self.isAttached(): - if 0 != self.AttachedIconHandle: - grpImage.Render(self.AttachedIconHandle) - - if self.IsSoftwareCursor: - if True == app.IsShowCursor(): - if 0 != self.curCursorImage: - self.curCursorImage.Render() - else: - if False == app.IsShowCursor(): - if True == app.IsLiarCursorOn(): - if 0 != self.curCursorImage: - self.curCursorImage.SetPosition(self.x + self.cursorPosX, self.y + self.cursorPosY) - self.curCursorImage.Render() - - def SetCallBack(self, type, event=lambda *arg:None): - self.callbackDict[type] = event - - def RunCallBack(self, type, *arg): - - if type not in self.callbackDict: - self.DeattachObject() - return - - self.callbackDict[type]() - - def ClearCallBack(self): - self.callbackDict = {} - -mouseController = CMouseController() diff --git a/tools/root/msm/assassin_m.msm b/tools/root/msm/assassin_m.msm deleted file mode 100644 index b345e107..00000000 --- a/tools/root/msm/assassin_m.msm +++ /dev/null @@ -1,1530 +0,0 @@ -ScriptType RaceDataScript - -BaseModelFileName "d:/ymir work/pc2/assassin/assassin_novice.GR2" - - -Group HairData -{ - PathName "d:/ymir Work/pc2/assassin/" - - HairDataCount 61 - Group HairData00 - { - HairIndex 0 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "assassin_hair_01.dds" - } - Group HairData01 - { - HairIndex 1 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "assassin_hair_01_white.dds" - } - Group HairData02 - { - HairIndex 2 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "assassin_hair_01_gold.dds" - } - Group HairData03 - { - HairIndex 3 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "assassin_hair_01_red.dds" - } - Group HairData04 - { - HairIndex 4 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "assassin_hair_01_brown.dds" - } - Group HairData05 - { - HairIndex 5 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "assassin_hair_01_black.dds" - } - Group HairData06 - { - HairIndex 2001 - Model "hair/hair_2_1.gr2" - SourceSkin "hair/hair_2_1.dds" - TargetSkin "hair/hair_2_1.dds" - } - Group HairData07 - { - HairIndex 2002 - Model "hair/hair_2_1.gr2" - SourceSkin "hair/hair_2_1.dds" - TargetSkin "hair/hair_2_2.dds" - } - Group HairData08 - { - HairIndex 2003 - Model "hair/hair_2_1.gr2" - SourceSkin "hair/hair_2_1.dds" - TargetSkin "hair/hair_2_3.dds" - } - Group HairData09 - { - HairIndex 2004 - Model "hair/hair_2_1.gr2" - SourceSkin "hair/hair_2_1.dds" - TargetSkin "hair/hair_2_4.dds" - } - Group HairData10 - { - HairIndex 2005 - Model "hair/hair_3_1.gr2" - SourceSkin "hair/hair_3_1.dds" - TargetSkin "hair/hair_3_1.dds" - } - Group HairData11 - { - HairIndex 2006 - Model "hair/hair_3_1.gr2" - SourceSkin "hair/hair_3_1.dds" - TargetSkin "hair/hair_3_2.dds" - } - Group HairData12 - { - HairIndex 2007 - Model "hair/hair_3_1.gr2" - SourceSkin "hair/hair_3_1.dds" - TargetSkin "hair/hair_3_3.dds" - } - Group HairData13 - { - HairIndex 2008 - Model "hair/hair_3_1.gr2" - SourceSkin "hair/hair_3_1.dds" - TargetSkin "hair/hair_3_4.dds" - } - Group HairData14 - { - HairIndex 2009 - Model "hair/hair_4_1.gr2" - SourceSkin "hair/hair_4_1.dds" - TargetSkin "hair/hair_4_1.dds" - } - Group HairData15 - { - HairIndex 2010 - Model "hair/hair_4_1.gr2" - SourceSkin "hair/hair_4_1.dds" - TargetSkin "hair/hair_4_2.dds" - } - Group HairData16 - { - HairIndex 2011 - Model "hair/hair_4_1.gr2" - SourceSkin "hair/hair_4_1.dds" - TargetSkin "hair/hair_4_3.dds" - } - Group HairData17 - { - HairIndex 2012 - Model "hair/hair_4_1.gr2" - SourceSkin "hair/hair_4_1.dds" - TargetSkin "hair/hair_4_4.dds" - } - - Group HairData18 - { - HairIndex 2013 - Model "hair/hair_6_1.gr2" - SourceSkin "hair/hair_6_1.dds" - TargetSkin "hair/hair_6_1.dds" - } - Group HairData19 - { - HairIndex 2014 - Model "hair/hair_5_1.gr2" - SourceSkin "hair/hair_5_1.dds" - TargetSkin "hair/hair_5_1.dds" - } - Group HairData20 - { - HairIndex 2015 - Model "hair/hair_7_1.gr2" - SourceSkin "hair/hair_7_1.dds" - TargetSkin "hair/hair_7_1.dds" - } - Group HairData21 - { - HairIndex 2016 - Model "hair/hair_8_1.gr2" - SourceSkin "hair/hair_8_1.dds" - TargetSkin "hair/hair_8_1.dds" - } - Group HairData22 - { - HairIndex 2017 - Model "hair/hair_9_1.gr2" - SourceSkin "hair/hair_9_1.dds" - TargetSkin "hair/hair_9_1.dds" - } - Group HairData23 - { - HairIndex 2018 - Model "hair/hair_10_1.gr2" - SourceSkin "hair/hair_10_1.dds" - TargetSkin "hair/hair_10_1.dds" - } - Group HairData24 - { - HairIndex 5001 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_1.dds" - } - Group HairData25 - { - HairIndex 5002 - Model "hair/hair_14_1.gr2" - SourceSkin "hair/hair_14_1.dds" - TargetSkin "hair/hair_14_1.dds" - } - Group HairData26 - { - HairIndex 5005 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_1.dds" - } - Group HairData27 - { - HairIndex 5003 - Model "hair/hair_16_1.gr2" - SourceSkin "hair/hair_16_1.dds" - TargetSkin "hair/hair_16_1.dds" - } - Group HairData28 - { - HairIndex 5004 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_1.dds" - } - Group HairData29 - { - HairIndex 5027 - Model "hair/hair_20_1.gr2" - SourceSkin "hair/hair_20_1.dds" - TargetSkin "hair/hair_20_1.dds" - } - Group HairData30 - { - HairIndex 5023 - Model "hair/hair_13_1.gr2" - SourceSkin "hair/hair_13_1.dds" - TargetSkin "hair/hair_13_1.dds" - } - Group HairData31 - { - HairIndex 5024 - Model "hair/hair_18_1.gr2" - SourceSkin "hair/hair_18_1.dds" - TargetSkin "hair/hair_18_1.dds" - } - Group HairData32 - { - HairIndex 5025 - Model "hair/hair_19_1.gr2" - SourceSkin "hair/hair_19_1.dds" - TargetSkin "hair/hair_19_1.dds" - } - Group HairData33 - { - HairIndex 5028 - Model "hair/hair_22_1.gr2" - SourceSkin "hair/hair_22_1.dds" - TargetSkin "hair/hair_22_3.dds" - } - Group HairData34 - { - HairIndex 5029 - Model "hair/hair_22_1.gr2" - SourceSkin "hair/hair_22_1.dds" - TargetSkin "hair/hair_22_2.dds" - } - Group HairData35 - { - HairIndex 5030 - Model "hair/hair_22_1.gr2" - SourceSkin "hair/hair_22_1.dds" - TargetSkin "hair/hair_22_1.dds" - } - Group HairData36 - { - HairIndex 5031 - Model "hair/hair_23_1.gr2" - SourceSkin "hair/hair_23_1.dds" - TargetSkin "hair/hair_23_1.dds" - } - Group HairData37 - { - HairIndex 5033 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_1.dds" - } - Group HairData38 - { - HairIndex 5035 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_2.dds" - } - Group HairData39 - { - HairIndex 5037 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_3.dds" - } - Group HairData40 - { - HairIndex 5039 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_4.dds" - } - Group HairData41 - { - HairIndex 5041 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_5.dds" - } - Group HairData42 - { - HairIndex 5026 - Model "hair/hair_21_1.gr2" - SourceSkin "hair/hair_21_1.dds" - TargetSkin "hair/hair_21_1.dds" - } - Group HairData43 - { - HairIndex 5045 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_2.dds" - } - Group HairData44 - { - HairIndex 5046 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_3.dds" - } - Group HairData45 - { - HairIndex 5047 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_4.dds" - } - Group HairData46 - { - HairIndex 5048 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_5.dds" - } - Group HairData47 - { - HairIndex 5049 - Model "hair/hair_28_1.gr2" - SourceSkin "hair/hair_28_1.dds" - TargetSkin "hair/hair_28_1.dds" - } - Group HairData48 - { - HairIndex 5050 - Model "hair/hair_28_1.gr2" - SourceSkin "hair/hair_28_1.dds" - TargetSkin "hair/hair_28_1.dds" - } - Group HairData49 - { - HairIndex 5051 - Model "hair/hair_29_1.gr2" - SourceSkin "hair/hair_29_1.dds" - TargetSkin "hair/hair_29_1.dds" - } - Group HairData50 - { - HairIndex 5052 - Model "hair/hair_30_1.gr2" - SourceSkin "hair/hair_30_1.dds" - TargetSkin "hair/hair_30_1.dds" - } - Group HairData51 - { - HairIndex 5053 - Model "hair/hair_31_1.gr2" - SourceSkin "hair/hair_31_1.dds" - TargetSkin "hair/hair_31_1.dds" - } - Group HairData52 - { - HairIndex 5054 - Model "hair/hair_32_1.gr2" - SourceSkin "hair/hair_32_1.dds" - TargetSkin "hair/hair_32_1.dds" - } - Group HairData53 - { - HairIndex 5055 - Model "hair/hair_14_1.gr2" - SourceSkin "hair/hair_14_1.dds" - TargetSkin "hair/hair_14_2.dds" - } - Group HairData54 - { - HairIndex 5057 - Model "hair/hair_33_1.gr2" - SourceSkin "hair/hair_33_1.dds" - TargetSkin "hair/hair_33_1.dds" - } - Group HairData55 - { - HairIndex 5059 - Model "hair/hair_34_1.gr2" - SourceSkin "hair/hair_34_1.dds" - TargetSkin "hair/hair_34_1.dds" - } - Group HairData56 - { - HairIndex 5061 - Model "hair/hair_35_1.gr2" - SourceSkin "hair/hair_35_1.dds" - TargetSkin "hair/hair_35_1.dds" - } - Group HairData57 - { - HairIndex 5063 - Model "hair/hair_37_1.gr2" - SourceSkin "hair/hair_37_1.dds" - TargetSkin "hair/hair_37_1.dds" - } - Group HairData58 - { - HairIndex 5064 - Model "hair/hair_36_1.gr2" - SourceSkin "hair/hair_36_1.dds" - TargetSkin "hair/hair_36_1.dds" - } - Group HairData59 - { - HairIndex 5065 - Model "hair/hair_38_1.gr2" - SourceSkin "hair/hair_38_1.dds" - TargetSkin "hair/hair_38_1.dds" - } - - Group HairData60 - { - HairIndex 5022 - Model "hair/hair_12_1.gr2" - SourceSkin "hair/hair_12_1.dds" - TargetSkin "hair/hair_12_1.dds" - } -} - -Group ShapeData -{ - PathName "d:/ymir Work/pc2/assassin/" - - ShapeDataCount 146 - - Group ShapeData00 - { - ShapeIndex 0 - - Model "assassin_novice.GR2" - SourceSkin "assassin_novice_red.dds" - TargetSkin "assassin_novice_red.dds" - } - Group ShapeData01 - { - ShapeIndex 1 - - Model "assassin_novice.GR2" - SourceSkin "assassin_novice_red.dds" - TargetSkin "assassin_novice_green.dds" - } - Group ShapeData02 - { - ShapeIndex 3 - Model "assassin_tanma.GR2" - SourceSkin "assassin_tanma.DDS" - TargetSkin "assassin_tanma.dds" - } - Group ShapeData03 - { - ShapeIndex 4 - Model "assassin_tanma.GR2" - SourceSkin "assassin_tanma.DDS" - TargetSkin "assassin_geukseom.dds" - } - Group ShapeData04 - { - ShapeIndex 5 - Model "assassin_tanma.GR2" - SourceSkin "assassin_tanma.DDS" - TargetSkin "assassin_dahong.dds" - } - Group ShapeData05 - { - ShapeIndex 6 - Model "assassin_biyeong.GR2" - SourceSkin "assassin_biyeong.DDS" - TargetSkin "assassin_biyeong.DDS" - } - Group ShapeData06 - { - ShapeIndex 7 - Model "assassin_biyeong.GR2" - SourceSkin "assassin_biyeong.DDS" - TargetSkin "assassin_yeongrin.DDS" - } - Group ShapeData07 - { - ShapeIndex 8 - Model "assassin_biyeong.GR2" - SourceSkin "assassin_biyeong.DDS" - TargetSkin "assassin_jeoksal.DDS" - } - Group ShapeData08 - { - ShapeIndex 9 - Model "assassin_yonga.GR2" - SourceSkin "assassin_yonga.DDS" - TargetSkin "assassin_yonga.DDS" - } - Group ShapeData09 - { - ShapeIndex 10 - Model "assassin_yonga.GR2" - SourceSkin "assassin_yonga.DDS" - TargetSkin "assassin_salpung.DDS" - } - Group ShapeData10 - { - ShapeIndex 11 - Model "assassin_bihyeon.GR2" - SourceSkin "assassin_bihyeon.DDS" - TargetSkin "assassin_bihyeon.DDS" - } - Group ShapeData11 - { - SpecialPath "d:/ymir work/monster/wolf/" - - ShapeIndex 100 - Model "wolf.gr2" - SourceSkin "wolf.dds" - } - Group ShapeData12 - { - SpecialPath "d:/ymir work/monster/wild_boar/" - - ShapeIndex 101 - Model "wild_boar.gr2" - SourceSkin "wild_boar.dds" - } - Group ShapeData13 - { - SpecialPath "d:/ymir work/monster/bear/" - - ShapeIndex 102 - Model "bear.gr2" - SourceSkin "bear.dds" - } - Group ShapeData14 - { - SpecialPath "d:/ymir work/monster/tiger/" - - ShapeIndex 103 - Model "tiger.gr2" - SourceSkin "tiger.dds" - } - Group ShapeData15 - { - SpecialPath "d:/ymir work/pc2/assassin/" - - ShapeIndex 201 - Model "assassin_marry_01.GR2" - SourceSkin "assassin_marry_01.dds" - TargetSkin "assassin_marry_01.dds" - } - Group ShapeData16 - { - ShapeIndex 12 - Model "assassin_4-1.gr2" - SourceSkin "assassin_4-1.dds" - TargetSkin "assassin_4-1.dds" - - } - Group ShapeData17 - { - ShapeIndex 24 - Model "assassin_lord.GR2" - SourceSkin "assassin_queen01.dds" - TargetSkin "assassin_queen01.dds" - } - Group ShapeData18 - { - ShapeIndex 14 - Model "assassin_tanma.GR2" - SourceSkin "assassin_tanma.DDS" - TargetSkin "assassin_1-1_tanma_a.DDS" - } - Group ShapeData19 - { - ShapeIndex 15 - Model "assassin_tanma.GR2" - SourceSkin "assassin_tanma.DDS" - TargetSkin "assassin_1-2_geukseom_a.DDS" - } - Group ShapeData20 - { - ShapeIndex 16 - Model "assassin_tanma.GR2" - SourceSkin "assassin_tanma.DDS" - TargetSkin "assassin_1-3_dahong_a.DDS" - } - Group ShapeData21 - { - ShapeIndex 17 - Model "assassin_biyeong.GR2" - SourceSkin "assassin_biyeong.DDS" - TargetSkin "assassin_2-1_biyeong_a.DDS" - } - Group ShapeData22 - { - ShapeIndex 18 - Model "assassin_biyeong.GR2" - SourceSkin "assassin_biyeong.DDS" - TargetSkin "assassin_2-2_yeongrin_a.DDS" - } - Group ShapeData23 - { - ShapeIndex 19 - Model "assassin_biyeong.GR2" - SourceSkin "assassin_biyeong.DDS" - TargetSkin "assassin_2-3_jeoksal_a.DDS" - } - Group ShapeData24 - { - ShapeIndex 20 - Model "assassin_yonga.GR2" - SourceSkin "assassin_yonga.DDS" - TargetSkin "assassin_3-1_yonga_a.DDS" - } - Group ShapeData25 - { - ShapeIndex 21 - Model "assassin_yonga.GR2" - SourceSkin "assassin_yonga.DDS" - TargetSkin "assassin_salpung_a.dds" - } - Group ShapeData26 - { - ShapeIndex 25 - Model "assassin_lord.GR2" - SourceSkin "assassin_queen01.dds" - TargetSkin "assassin_queen02.dds" - } - Group ShapeData27 - { - SpecialPath "d:/ymir Work/pc2/assassin/" - - ShapeIndex 26 - Model "assassin_4-1.GR2" - SourceSkin "assassin_4-1.dds" - TargetSkin "assassin_4-2.dds" - } - Group ShapeData28 - { - - ShapeIndex 27 - Model "assassin_event1.GR2" - SourceSkin "assassin_event1_yellow.dds" - TargetSkin "assassin_event1_red.dds" - } - Group ShapeData29 - { - - ShapeIndex 28 - Model "assassin_event1.GR2" - SourceSkin "assassin_event1_yellow.dds" - TargetSkin "assassin_event1_yellow.dds" - } - Group ShapeData30 - { - - ShapeIndex 29 - Model "assassin_event1.GR2" - SourceSkin "assassin_event1_yellow.dds" - TargetSkin "assassin_event1_blue.dds" - } - Group ShapeData31 - { - ShapeIndex 30 - Model "assassin_tanma.gr2" - SourceSkin "assassin_tanma.dds" - TargetSkin "assassin_costume1.dds" - } - Group ShapeData32 - { - ShapeIndex 40031 - Model "assassin_rabbit1.GR2" - SourceSkin "assassin_rabbit1.dds" - TargetSkin "assassin_rabbit1.dds" - } - Group ShapeData33 - { - - ShapeIndex 40033 - Model "assassin_fencing1_Germany.GR2" - SourceSkin "assasin_fencing1_Germany.dds" - TargetSkin "assassin_fencing1_London.dds" - } - Group ShapeData34 - { - ShapeIndex 40034 - Model "assassin_fencing1_Germany.GR2" - SourceSkin "assasin_fencing1_Germany.dds" - TargetSkin "assasin_fencing1_Germany.dds" - } - Group ShapeData35 - { - ShapeIndex 40035 - Model "assassin_fencing1_Germany.GR2" - SourceSkin "assasin_fencing1_Germany.dds" - TargetSkin "assassin_fencing1_Turkey.dds" - } - Group ShapeData36 - { - ShapeIndex 40036 - Model "assassin_fencing1_Germany.GR2" - SourceSkin "assasin_fencing1_Germany.dds" - TargetSkin "assassin_fencing1_Brazil.dds" - } - Group ShapeData37 - { - ShapeIndex 40037 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_soccer1_London.dds" - } - Group ShapeData38 - { - ShapeIndex 40038 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assasin_soccer1_Germany.dds" - } - Group ShapeData39 - { - ShapeIndex 40039 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_soccer1_Turkey.dds" - } - Group ShapeData40 - { - ShapeIndex 40040 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_soccer1_Brazil.dds" - } - Group ShapeData41 - { - ShapeIndex 40041 - Model "assassin_boxing1_Germany.GR2" - SourceSkin "assassin_boxing1_Germany.dds" - TargetSkin "assassin_boxing1_London.dds" - } - Group ShapeData42 - { - ShapeIndex 40042 - Model "assassin_boxing1_Germany.GR2" - SourceSkin "assassin_boxing1_Germany.dds" - TargetSkin "assassin_boxing1_Germany.dds" - } - Group ShapeData43 - { - ShapeIndex 40043 - Model "assassin_boxing1_Germany.GR2" - SourceSkin "assassin_boxing1_Germany.dds" - TargetSkin "assassin_boxing1_Turkey.dds" - } - Group ShapeData44 - { - ShapeIndex 40044 - Model "assassin_boxing1_Germany.GR2" - SourceSkin "assassin_boxing1_Germany.dds" - TargetSkin "assassin_boxing1_Brazil.dds" - } - Group ShapeData45 - { - ShapeIndex 40032 - Model "assassin_assasin1.GR2" - SourceSkin "assassin_assasin1.dds" - TargetSkin "assassin_assasin1.dds" - } - Group ShapeData46 - { - ShapeIndex 40045 - Model "assassin_fencing1_Germany.GR2" - SourceSkin "assasin_fencing1_Germany.dds" - TargetSkin "assassin_fencing1_France.dds" - } - Group ShapeData47 - { - ShapeIndex 40046 - Model "assassin_fencing1_Germany.GR2" - SourceSkin "assasin_fencing1_Germany.dds" - TargetSkin "assassin_fencing1_Italy.dds" - } - Group ShapeData48 - { - ShapeIndex 40047 - Model "assassin_fencing1_Germany.GR2" - SourceSkin "assasin_fencing1_Germany.dds" - TargetSkin "assassin_fencing1_Poland.dds" - } - Group ShapeData49 - { - ShapeIndex 40048 - Model "assassin_fencing1_Germany.GR2" - SourceSkin "assasin_fencing1_Germany.dds" - TargetSkin "assassin_fencing1_Romania.dds" - } - Group ShapeData50 - { - ShapeIndex 40049 - Model "assassin_fencing1_Germany.GR2" - SourceSkin "assasin_fencing1_Germany.dds" - TargetSkin "assassin_fencing1_Spain.dds" - } - Group ShapeData51 - { - ShapeIndex 40050 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_soccer1_France.dds" - } - Group ShapeData52 - { - ShapeIndex 40051 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_soccer1_Italy.dds" - } - Group ShapeData53 - { - ShapeIndex 40052 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_soccer1_Poland.dds" - } - Group ShapeData54 - { - ShapeIndex 40053 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_soccer1_Romania.dds" - } - Group ShapeData55 - { - ShapeIndex 40054 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_soccer1_Spain.dds" - } - Group ShapeData56 - { - ShapeIndex 40055 - Model "assassin_boxing1_Germany.GR2" - SourceSkin "assassin_boxing1_Germany.dds" - TargetSkin "assassin_boxing1_France.dds" - } - Group ShapeData57 - { - ShapeIndex 40056 - Model "assassin_boxing1_Germany.GR2" - SourceSkin "assassin_boxing1_Germany.dds" - TargetSkin "assassin_boxing1_Italy.dds" - } - Group ShapeData58 - { - ShapeIndex 40057 - Model "assassin_boxing1_Germany.GR2" - SourceSkin "assassin_boxing1_Germany.dds" - TargetSkin "assassin_boxing1_Poland.dds" - } - Group ShapeData59 - { - ShapeIndex 40058 - Model "assassin_boxing1_Germany.GR2" - SourceSkin "assassin_boxing1_Germany.dds" - TargetSkin "assassin_boxing1_Romania.dds" - } - Group ShapeData60 - { - ShapeIndex 40059 - Model "assassin_boxing1_Germany.GR2" - SourceSkin "assassin_boxing1_Germany.dds" - TargetSkin "assassin_boxing1_Spain.dds" - } - Group ShapeData61 - { - ShapeIndex 40065 - Model "assassin_halloween1.GR2" - SourceSkin "assassin_halloween1.dds" - TargetSkin "assassin_halloween1.dds" - } - Group ShapeData62 - { - ShapeIndex 13 - Model "assassin_5_1.gr2" - SourceSkin "assassin_5_1.dds" - TargetSkin "assassin_5_1.dds" - } - Group ShapeData63 - { - ShapeIndex 40062 - Model "assassin_salsa1.GR2" - SourceSkin "assassin_salsa1.dds" - TargetSkin "assassin_salsa1.dds" - } - Group ShapeData64 - { - ShapeIndex 40063 - Model "assassin_Springwear1.GR2" - SourceSkin "assassin_Springwear1.dds" - TargetSkin "assassin_Springwear1.dds" - } - Group ShapeData65 - { - ShapeIndex 40061 - Model "assassin_tailcoat1.gr2" - SourceSkin "assassin_tailcoat1.dds" - TargetSkin "assassin_tailcoat1.dds" - } - Group ShapeData66 - { - ShapeIndex 40069 - Model "assassin_deer1.gr2" - SourceSkin "assassin_deer1.dds" - TargetSkin "assassin_deer1.dds" - } - Group ShapeData67 - { - ShapeIndex 40066 - Model "assassin_santa1_black.gr2" - SourceSkin "assassin_santa1_black.dds" - TargetSkin "assassin_santa1_red.dds" - } - Group ShapeData68 - { - ShapeIndex 40067 - Model "assassin_santa1_black.gr2" - SourceSkin "assassin_santa1_black.dds" - TargetSkin "assassin_santa1_green.dds" - } - Group ShapeData69 - { - ShapeIndex 40068 - Model "assassin_santa1_black.gr2" - SourceSkin "assassin_santa1_black.dds" - TargetSkin "assassin_santa1_black.dds" - } - Group ShapeData70 - { - ShapeIndex 40070 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA01.dds" - } - Group ShapeData71 - { - ShapeIndex 40071 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA02.dds" - } - Group ShapeData72 - { - ShapeIndex 40072 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA03.dds" - } - Group ShapeData73 - { - ShapeIndex 40073 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA04.dds" - } - Group ShapeData74 - { - ShapeIndex 40074 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA05.dds" - } - Group ShapeData75 - { - ShapeIndex 40075 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA06.dds" - } - Group ShapeData76 - { - ShapeIndex 40076 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA07.dds" - } - Group ShapeData77 - { - ShapeIndex 40077 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA08.dds" - } - Group ShapeData78 - { - ShapeIndex 40078 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA09.dds" - } - Group ShapeData79 - { - ShapeIndex 40079 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA10.dds" - } - Group ShapeData80 - { - ShapeIndex 40080 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA11.dds" - } - Group ShapeData81 - { - ShapeIndex 40081 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA12.dds" - } - Group ShapeData82 - { - ShapeIndex 40082 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA13.dds" - } - Group ShapeData83 - { - ShapeIndex 40083 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA14.dds" - } - Group ShapeData84 - { - ShapeIndex 40084 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA15.dds" - } - Group ShapeData85 - { - ShapeIndex 40085 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA16.dds" - } - Group ShapeData86 - { - ShapeIndex 40086 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA17.dds" - } - Group ShapeData87 - { - ShapeIndex 40087 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA18.dds" - } - Group ShapeData88 - { - ShapeIndex 40088 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA19.dds" - } - Group ShapeData89 - { - ShapeIndex 40089 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA20.dds" - } - Group ShapeData90 - { - ShapeIndex 40090 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA21.dds" - } - Group ShapeData91 - { - ShapeIndex 40091 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA22.dds" - } - Group ShapeData92 - { - ShapeIndex 40092 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA23.dds" - } - Group ShapeData93 - { - ShapeIndex 40093 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA24.dds" - } - Group ShapeData94 - { - ShapeIndex 40094 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA25.dds" - } - Group ShapeData95 - { - ShapeIndex 40095 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA26.dds" - } - Group ShapeData96 - { - ShapeIndex 40096 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA27.dds" - } - Group ShapeData97 - { - ShapeIndex 40097 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA28.dds" - } - Group ShapeData98 - { - ShapeIndex 40098 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA29.dds" - } - Group ShapeData99 - { - ShapeIndex 40099 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA30.dds" - } - Group ShapeData100 - { - ShapeIndex 40100 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA31.dds" - } - Group ShapeData101 - { - ShapeIndex 40101 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA32.dds" - } - Group ShapeData102 - { - ShapeIndex 40064 - Model "assassin_samurai1.GR2" - SourceSkin "assassin_samurai1.dds" - TargetSkin "assassin_samurai1.dds" - } - Group ShapeData103 - { - ShapeIndex 40106 - Model "assassin_rabbit1.GR2" - SourceSkin "assassin_rabbit1.dds" - TargetSkin "assassin_rabbit1_black.dds" - } - Group ShapeData104 - { - ShapeIndex 40107 - Model "assassin_rabbit1.GR2" - SourceSkin "assassin_rabbit1.dds" - TargetSkin "assassin_rabbit1_blue.dds" - } - Group ShapeData105 - { - ShapeIndex 40108 - Model "assassin_rabbit1.GR2" - SourceSkin "assassin_rabbit1.dds" - TargetSkin "assassin_rabbit1_green.dds" - } - Group ShapeData106 - { - ShapeIndex 40109 - Model "assassin_rabbit1.GR2" - SourceSkin "assassin_rabbit1.dds" - TargetSkin "assassin_rabbit1_pink.dds" - } - Group ShapeData107 - { - ShapeIndex 40110 - Model "assassin_BlackSnake1.GR2" - SourceSkin "assassin_BlackSnake1.dds" - TargetSkin "assassin_BlackSnake1.dds" - } - Group ShapeData108 - { - ShapeIndex 40111 - Model "assassin_BlackSnake1.GR2" - SourceSkin "assassin_BlackSnake1.dds" - TargetSkin "assassin_BlackSnake1.dds" - } - Group ShapeData109 - { - ShapeIndex 40112 - Model "assassin_assasin1.GR2" - SourceSkin "assassin_assasin1.dds" - TargetSkin "assassin_assasin2.dds" - } - Group ShapeData110 - { - ShapeIndex 40114 - Model "assassin_pwahuang1.GR2" - SourceSkin "assassin_pwahuang1.dds" - TargetSkin "assassin_pwahuang1.dds" - } - Group ShapeData111 - { - ShapeIndex 40116 - Model "assassin_halloween2.GR2" - SourceSkin "assassin_halloween2.dds" - TargetSkin "assassin_halloween2.dds" - } - Group ShapeData112 - { - - ShapeIndex 40118 - Model "assassin_assasin1.GR2" - SourceSkin "assassin_assasin1.dds" - TargetSkin "assassin_assassin3 .dds" - } - - Group ShapeData113 - { - - ShapeIndex 40060 - Model "assasin_capoeira1.GR2" - SourceSkin "assasin_capoeira1.dds" - TargetSkin "assasin_capoeira1.dds" - } - Group ShapeData114 - { - ShapeIndex 40120 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC01.dds" - } - Group ShapeData115 - { - ShapeIndex 40122 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC02.dds" - } - Group ShapeData116 - { - ShapeIndex 40124 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC03.dds" - } - Group ShapeData117 - { - ShapeIndex 40126 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC04.dds" - } - Group ShapeData118 - { - ShapeIndex 40128 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC05.dds" - } - Group ShapeData119 - { - ShapeIndex 40130 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC06.dds" - } - Group ShapeData120 - { - ShapeIndex 40132 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC07.dds" - } - Group ShapeData121 - { - ShapeIndex 40134 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC08.dds" - } - Group ShapeData122 - { - ShapeIndex 40136 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC09.dds" - } - Group ShapeData123 - { - ShapeIndex 40138 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC10.dds" - } - Group ShapeData124 - { - ShapeIndex 40140 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC11.dds" - } - Group ShapeData125 - { - ShapeIndex 40142 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC12.dds" - } - Group ShapeData126 - { - ShapeIndex 40144 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC13.dds" - } - Group ShapeData127 - { - ShapeIndex 40146 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC14.dds" - } - Group ShapeData128 - { - ShapeIndex 40148 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC15.dds" - } - Group ShapeData129 - { - ShapeIndex 40150 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC16.dds" - } - Group ShapeData130 - { - ShapeIndex 40152 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC17.dds" - } - Group ShapeData131 - { - ShapeIndex 40154 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC18.dds" - } - Group ShapeData132 - { - ShapeIndex 40156 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC19.dds" - } - Group ShapeData133 - { - ShapeIndex 40158 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC20.dds" - } - Group ShapeData134 - { - ShapeIndex 40160 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC21.dds" - } - Group ShapeData135 - { - ShapeIndex 40162 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC22.dds" - } - Group ShapeData136 - { - ShapeIndex 40164 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC23.dds" - } - Group ShapeData137 - { - ShapeIndex 40166 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC24.dds" - } - Group ShapeData138 - { - ShapeIndex 40168 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC25.dds" - } - Group ShapeData139 - { - ShapeIndex 40170 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC26.dds" - } - Group ShapeData140 - { - ShapeIndex 40172 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC27.dds" - } - Group ShapeData141 - { - ShapeIndex 40174 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC28.dds" - } - Group ShapeData142 - { - ShapeIndex 40176 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC29.dds" - } - Group ShapeData143 - { - ShapeIndex 40178 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC30.dds" - } - Group ShapeData144 - { - ShapeIndex 40180 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC31.dds" - } - Group ShapeData145 - { - ShapeIndex 40182 - Model "assasin_soccer1_Germany.GR2" - SourceSkin "assasin_soccer1_Germany.dds" - TargetSkin "assassin_WC32.dds" - } - -} - -Group AttachingData -{ - AttachingDataCount 2 - - Group AttachingData00 - { - AttachingDataType 1 - - isAttaching 0 - AttachingModelIndex 0 - AttachingBoneName "Bip01" - - CollisionType 1 - - SphereDataCount 1 - Group SphereData00 - { - Radius 40.000000 - Position 0.000000 0.000000 90.000000 - } - } - - Group AttachingData01 - { - AttachingDataType 1 - - isAttaching 0 - AttachingModelIndex 0 - AttachingBoneName "Bip01" - - CollisionType 3 - - SphereDataCount 1 - Group SphereData00 - { - Radius 70.000000 - Position 0.000000 0.000000 90.000000 - } - } -} diff --git a/tools/root/msm/assassin_w.msm b/tools/root/msm/assassin_w.msm deleted file mode 100644 index e3d1a344..00000000 --- a/tools/root/msm/assassin_w.msm +++ /dev/null @@ -1,1627 +0,0 @@ -ScriptType RaceDataScript - -BaseModelFileName "D:/YMIR WORK/pc/assassin/assassin_novice.GR2" - - -Group HairData -{ - PathName "d:/ymir Work/pc/assassin/" - - HairDataCount 75 - Group HairData00 - { - HairIndex 0 - Model "hair/hair_1_1.gr2" - SourceSkin "assassin_hair_01.dds" - TargetSkin "assassin_hair_01.dds" - } - Group HairData01 - { - HairIndex 1 - Model "hair/hair_1_1.gr2" - SourceSkin "assassin_hair_01.dds" - TargetSkin "assassin_hair_01_white.dds" - } - Group HairData02 - { - HairIndex 2 - Model "hair/hair_1_1.gr2" - SourceSkin "assassin_hair_01.dds" - TargetSkin "assassin_hair_01_gold.dds" - } - Group HairData03 - { - HairIndex 3 - Model "hair/hair_1_1.gr2" - SourceSkin "assassin_hair_01.dds" - TargetSkin "assassin_hair_01_red.dds" - } - Group HairData04 - { - HairIndex 4 - Model "hair/hair_1_1.gr2" - SourceSkin "assassin_hair_01.dds" - TargetSkin "assassin_hair_01_brown.dds" - } - Group HairData05 - { - HairIndex 5 - Model "hair/hair_1_1.gr2" - SourceSkin "assassin_hair_01.dds" - TargetSkin "assassin_hair_01_black.dds" - } - Group HairData06 - { - HairIndex 2001 - Model "hair/hair_2_1.gr2" - SourceSkin "hair/hair_2_1.dds" - TargetSkin "hair/hair_2_1.dds" - } - Group HairData07 - { - HairIndex 2002 - Model "hair/hair_2_2.gr2" - SourceSkin "hair/hair_2_2.dds" - TargetSkin "hair/hair_2_2.dds" - } - Group HairData08 - { - HairIndex 2003 - Model "hair/hair_2_3.gr2" - SourceSkin "hair/hair_2_3.dds" - TargetSkin "hair/hair_2_3.dds" - } - Group HairData09 - { - HairIndex 2004 - Model "hair/hair_2_4.gr2" - SourceSkin "hair/hair_2_4.dds" - TargetSkin "hair/hair_2_4.dds" - } - Group HairData10 - { - HairIndex 2005 - Model "hair/hair_3_1.gr2" - SourceSkin "hair/hair_3_1.dds" - TargetSkin "hair/hair_3_1.dds" - } - Group HairData11 - { - HairIndex 2006 - Model "hair/hair_3_2.gr2" - SourceSkin "hair/hair_3_2.dds" - TargetSkin "hair/hair_3_2.dds" - } - Group HairData12 - { - HairIndex 2007 - Model "hair/hair_3_3.gr2" - SourceSkin "hair/hair_3_3.dds" - TargetSkin "hair/hair_3_3.dds" - } - Group HairData13 - { - HairIndex 2008 - Model "hair/hair_3_4.gr2" - SourceSkin "hair/hair_3_4.dds" - TargetSkin "hair/hair_3_4.dds" - } - Group HairData14 - { - HairIndex 2009 - Model "hair/hair_4_1.gr2" - SourceSkin "hair/hair_4_1.dds" - TargetSkin "hair/hair_4_1.dds" - } - Group HairData15 - { - HairIndex 2010 - Model "hair/hair_4_2.gr2" - SourceSkin "hair/hair_4_2.dds" - TargetSkin "hair/hair_4_2.dds" - } - Group HairData16 - { - HairIndex 2011 - Model "hair/hair_4_3.gr2" - SourceSkin "hair/hair_4_3.dds" - TargetSkin "hair/hair_4_3.dds" - } - Group HairData17 - { - HairIndex 2012 - Model "hair/hair_4_4.gr2" - SourceSkin "hair/hair_4_4.dds" - TargetSkin "hair/hair_4_4.dds" - } - - Group HairData18 - { - HairIndex 2013 - Model "hair/hair_6_1.gr2" - SourceSkin "hair/hair_6_1.dds" - TargetSkin "hair/hair_6_1.dds" - } - Group HairData19 - { - HairIndex 2014 - Model "hair/hair_5_1.gr2" - SourceSkin "hair/hair_5_1.dds" - TargetSkin "hair/hair_5_1.dds" - } - Group HairData20 - { - HairIndex 2015 - Model "hair/hair_7_1.gr2" - SourceSkin "hair/hair_7_1.dds" - TargetSkin "hair/hair_7_1.dds" - } - Group HairData21 - { - HairIndex 2016 - Model "hair/hair_8_1.gr2" - SourceSkin "hair/hair_8_1.dds" - TargetSkin "hair/hair_8_1.dds" - } - Group HairData22 - { - HairIndex 2017 - Model "hair/hair_9_1.gr2" - SourceSkin "hair/hair_9_1.dds" - TargetSkin "hair/hair_9_1.dds" - } - Group HairData23 - { - HairIndex 2018 - Model "hair/hair_10_1.gr2" - SourceSkin "hair/hair_10_1.dds" - TargetSkin "hair/hair_10_1.dds" - } - Group HairData24 - { - HairIndex 5001 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_1.dds" - } - Group HairData25 - { - HairIndex 5002 - Model "hair/hair_14_1.gr2" - SourceSkin "hair/hair_14_1.dds" - TargetSkin "hair/hair_14_1.dds" - } - Group HairData26 - { - HairIndex 5005 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_1.dds" - } - Group HairData27 - { - HairIndex 5003 - Model "hair/hair_16_1.gr2" - SourceSkin "hair/hair_16_1.dds" - TargetSkin "hair/hair_16_1.dds" - } - Group HairData28 - { - HairIndex 5004 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_1.dds" - } - Group HairData29 - { - HairIndex 5006 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_2.dds" - } - Group HairData30 - { - HairIndex 5007 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_3.dds" - } - Group HairData31 - { - HairIndex 5008 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_4.dds" - } - Group HairData32 - { - HairIndex 5009 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_5.dds" - } - Group HairData33 - { - HairIndex 5010 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_6.dds" - } - Group HairData34 - { - HairIndex 5011 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_7.dds" - } - Group HairData35 - { - HairIndex 5012 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_8.dds" - } - Group HairData36 - { - HairIndex 5013 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_9.dds" - } - Group HairData37 - { - HairIndex 5014 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_2.dds" - } - Group HairData38 - { - HairIndex 5015 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_3.dds" - } - Group HairData39 - { - HairIndex 5016 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_4.dds" - } - Group HairData40 - { - HairIndex 5017 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_5.dds" - } - Group HairData41 - { - HairIndex 5018 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_6.dds" - } - Group HairData42 - { - HairIndex 5019 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_7.dds" - } - Group HairData43 - { - HairIndex 5020 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_8.dds" - } - Group HairData44 - { - HairIndex 5021 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_9.dds" - } - Group HairData45 - { - HairIndex 5027 - Model "hair/hair_20_1.gr2" - SourceSkin "hair/hair_20_1.dds" - TargetSkin "hair/hair_20_1.dds" - } - Group HairData46 - { - HairIndex 5023 - Model "hair/hair_13_1.gr2" - SourceSkin "hair/hair_13_1.dds" - TargetSkin "hair/hair_13_1.dds" - } - Group HairData47 - { - HairIndex 5024 - Model "hair/hair_18_1.gr2" - SourceSkin "hair/hair_18_1.dds" - TargetSkin "hair/hair_18_1.dds" - } - Group HairData48 - { - HairIndex 5025 - Model "hair/hair_19_1.gr2" - SourceSkin "hair/hair_19_1.dds" - TargetSkin "hair/hair_19_1.dds" - } - Group HairData49 - { - HairIndex 5030 - Model "hair/hair_22_1.gr2" - SourceSkin "hair/hair_22_1.dds" - TargetSkin "hair/hair_22_1.dds" - } - Group HairData50 - { - HairIndex 5031 - Model "hair/hair_23_1.gr2" - SourceSkin "hair/hair_23_1.dds" - TargetSkin "hair/hair_23_1.dds" - } - Group HairData51 - { - HairIndex 5034 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_1.dds" - } - Group HairData52 - { - HairIndex 5036 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_2.dds" - } - Group HairData53 - { - HairIndex 5038 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_3.dds" - } - Group HairData54 - { - HairIndex 5040 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_4.dds" - } - Group HairData55 - { - HairIndex 5042 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_5.dds" - } - Group HairData56 - { - HairIndex 5026 - Model "hair/hair_21_1.gr2" - SourceSkin "hair/hair_21_1.dds" - TargetSkin "hair/hair_21_1.dds" - } - Group HairData57 - { - HairIndex 5045 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_2.dds" - } - Group HairData58 - { - HairIndex 5046 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_3.dds" - } - Group HairData59 - { - HairIndex 5047 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_4.dds" - } - Group HairData60 - { - HairIndex 5048 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_5.dds" - } - Group HairData61 - { - HairIndex 5049 - Model "hair/hair_28_1.gr2" - SourceSkin "hair/hair_28_1.dds" - TargetSkin "hair/hair_28_1.dds" - } - Group HairData62 - { - HairIndex 5050 - Model "hair/hair_28_1.gr2" - SourceSkin "hair/hair_28_1.dds" - TargetSkin "hair/hair_28_1.dds" - } - Group HairData63 - { - HairIndex 5051 - Model "hair/hair_29_1.gr2" - SourceSkin "hair/hair_29_1.dds" - TargetSkin "hair/hair_29_1.dds" - } - Group HairData64 - { - HairIndex 5052 - Model "hair/hair_30_1.gr2" - SourceSkin "hair/hair_30_1.dds" - TargetSkin "hair/hair_30_1.dds" - } - Group HairData65 - { - HairIndex 5053 - Model "hair/hair_31_1.gr2" - SourceSkin "hair/hair_31_1.dds" - TargetSkin "hair/hair_31_1.dds" - } - Group HairData66 - { - HairIndex 5054 - Model "hair/hair_32_1.gr2" - SourceSkin "hair/hair_32_1.dds" - TargetSkin "hair/hair_32_1.dds" - } - Group HairData67 - { - HairIndex 5056 - Model "hair/hair_14_1.gr2" - SourceSkin "hair/hair_14_1.dds" - TargetSkin "hair/hair_14_2.dds" - } - Group HairData68 - { - HairIndex 5058 - Model "hair/hair_33_1.gr2" - SourceSkin "hair/hair_33_1.dds" - TargetSkin "hair/hair_33_1.dds" - } - Group HairData69 - { - HairIndex 5060 - Model "hair/hair_34_1.gr2" - SourceSkin "hair/hair_34_1.dds" - TargetSkin "hair/hair_34_1.dds" - } - Group HairData70 - { - HairIndex 5062 - Model "hair/hair_35_1.gr2" - SourceSkin "hair/hair_35_1.dds" - TargetSkin "hair/hair_35_1.dds" - } - Group HairData71 - { - HairIndex 5063 - Model "hair/hair_37_1.gr2" - SourceSkin "hair/hair_37_1.dds" - TargetSkin "hair/hair_37_1.dds" - } - Group HairData72 - { - HairIndex 5064 - Model "hair/hair_36_1.gr2" - SourceSkin "hair/hair_36_1.dds" - TargetSkin "hair/hair_36_1.dds" - } - Group HairData73 - { - HairIndex 5065 - Model "hair/hair_38_1.gr2" - SourceSkin "hair/hair_38_1.dds" - TargetSkin "hair/hair_38_1.dds" - } - Group HairData74 - { - HairIndex 5022 - Model "hair/hair_12_1.gr2" - SourceSkin "hair/hair_12_1.dds" - TargetSkin "hair/hair_12_1.dds" - } - -} - -Group ShapeData -{ - PathName "d:/ymir Work/pc/assassin/" - - ShapeDataCount 146 - - Group ShapeData00 - { - ShapeIndex 0 - - Model "assassin_novice.GR2" - SourceSkin "assassin_novice_red.dds" - TargetSkin "assassin_novice_red.dds" - } - Group ShapeData01 - { - ShapeIndex 1 - - Model "assassin_novice.GR2" - SourceSkin "assassin_novice_red.dds" - TargetSkin "assassin_novice_green.dds" - } - Group ShapeData02 - { - ShapeIndex 3 - Model "assassin_tanma.GR2" - SourceSkin "assassin_tanma.DDS" - TargetSkin "assassin_tanma.dds" - } - Group ShapeData03 - { - ShapeIndex 4 - Model "assassin_tanma.GR2" - SourceSkin "assassin_tanma.DDS" - TargetSkin "assassin_geukseom.dds" - } - Group ShapeData04 - { - ShapeIndex 5 - Model "assassin_tanma.GR2" - SourceSkin "assassin_tanma.DDS" - TargetSkin "assassin_dahong.dds" - } - Group ShapeData05 - { - ShapeIndex 6 - Model "assassin_biyeong.GR2" - SourceSkin "assassin_biyeong.DDS" - TargetSkin "assassin_biyeong.DDS" - } - Group ShapeData06 - { - ShapeIndex 7 - Model "assassin_biyeong.GR2" - SourceSkin "assassin_biyeong.DDS" - TargetSkin "assassin_yeongrin.DDS" - } - Group ShapeData07 - { - ShapeIndex 8 - Model "assassin_biyeong.GR2" - SourceSkin "assassin_biyeong.DDS" - TargetSkin "assassin_jeoksal.DDS" - } - Group ShapeData08 - { - ShapeIndex 9 - Model "assassin_yonga.GR2" - SourceSkin "assassin_yonga.DDS" - TargetSkin "assassin_yonga.DDS" - } - Group ShapeData09 - { - ShapeIndex 10 - Model "assassin_yonga.GR2" - SourceSkin "assassin_yonga.DDS" - TargetSkin "assassin_salpung.DDS" - } - Group ShapeData10 - { - ShapeIndex 11 - Model "assassin_bihyeon.GR2" - SourceSkin "assassin_bihyeon.DDS" - TargetSkin "assassin_bihyeon.DDS" - } - Group ShapeData11 - { - SpecialPath "d:/ymir work/monster/wolf/" - - ShapeIndex 100 - Model "wolf.gr2" - SourceSkin "wolf.dds" - } - Group ShapeData12 - { - SpecialPath "d:/ymir work/monster/wild_boar/" - - ShapeIndex 101 - Model "wild_boar.gr2" - SourceSkin "wild_boar.dds" - } - Group ShapeData13 - { - SpecialPath "d:/ymir work/monster/bear/" - - ShapeIndex 102 - Model "bear.gr2" - SourceSkin "bear.dds" - } - Group ShapeData14 - { - SpecialPath "d:/ymir work/monster/tiger/" - - ShapeIndex 103 - Model "tiger.gr2" - SourceSkin "tiger.dds" - } - Group ShapeData15 - { - SpecialPath "d:/ymir work/pc/assassin/" - - ShapeIndex 201 - Model "assassin_marry_01.GR2" - SourceSkin "assassin_marry_01.dds" - TargetSkin "assassin_marry_01.dds" - } - Group ShapeData16 - { - ShapeIndex 12 - Model "assassin_4-1.GR2" - SourceSkin "assassin_4-1.DDS" - TargetSkin "assassin_4-1.DDS" - } - Group ShapeData17 - { - ShapeIndex 24 - Model "assassin_lord.GR2" - SourceSkin "assassin_queen01.dds" - TargetSkin "assassin_queen01.dds" - } - Group ShapeData18 - { - ShapeIndex 14 - Model "assassin_tanma.GR2" - SourceSkin "assassin_tanma.DDS" - TargetSkin "assassin_1-1_tanma_a.DDS" - } - Group ShapeData19 - { - ShapeIndex 15 - Model "assassin_tanma.GR2" - SourceSkin "assassin_tanma.DDS" - TargetSkin "assassin_1-2_geukseom_a.DDS" - } - Group ShapeData20 - { - ShapeIndex 16 - Model "assassin_tanma.GR2" - SourceSkin "assassin_tanma.DDS" - TargetSkin "assassin_1-3_dahong_a.DDS" - } - Group ShapeData21 - { - ShapeIndex 17 - Model "assassin_biyeong.GR2" - SourceSkin "assassin_biyeong.DDS" - TargetSkin "assassin_2-1_biyeong_a.DDS" - } - Group ShapeData22 - { - ShapeIndex 18 - Model "assassin_biyeong.GR2" - SourceSkin "assassin_biyeong.DDS" - TargetSkin "assassin_2-2_yeongrin_a.DDS" - } - Group ShapeData23 - { - ShapeIndex 19 - Model "assassin_biyeong.GR2" - SourceSkin "assassin_biyeong.DDS" - TargetSkin "assassin_2-3_jeoksal_a.DDS" - } - Group ShapeData24 - { - ShapeIndex 20 - Model "assassin_yonga.GR2" - SourceSkin "assassin_yonga.DDS" - TargetSkin "assassin_3-1_yonga_a.DDS" - } - Group ShapeData25 - { - ShapeIndex 21 - Model "assassin_yonga.GR2" - SourceSkin "assassin_yonga.DDS" - TargetSkin "assassin_salpung_a.dds" - } - Group ShapeData26 - { - ShapeIndex 25 - Model "assassin_lord.GR2" - SourceSkin "assassin_queen01.dds" - TargetSkin "assassin_queen02.dds" - } - Group ShapeData27 - { - SpecialPath "d:/ymir Work/pc/assassin/" - - ShapeIndex 26 - Model "assassin_4-1.GR2" - SourceSkin "assassin_4-1.dds" - TargetSkin "assassin_4-2.dds" - } - Group ShapeData28 - { - - ShapeIndex 27 - Model "assassin_event1.GR2" - SourceSkin "assassin_event1_yellow.dds" - TargetSkin "assassin_event1_red.dds" - } - Group ShapeData29 - { - - ShapeIndex 28 - Model "assassin_event1.GR2" - SourceSkin "assassin_event1_yellow.dds" - TargetSkin "assassin_event1_yellow.dds" - } - Group ShapeData30 - { - - ShapeIndex 29 - Model "assassin_event1.GR2" - SourceSkin "assassin_event1_yellow.dds" - TargetSkin "assassin_event1_blue.dds" - - } - - Group ShapeData31 - { - ShapeIndex 30 - Model "assassin_tanma.gr2" - SourceSkin "assassin_tanma.dds" - TargetSkin "assassin_costume1.dds" - } - Group ShapeData32 - { - ShapeIndex 40031 - Model "assassin_rabbit1.gr2" - SourceSkin "assassin_rabbit1.dds" - TargetSkin "assassin_rabbit1.dds" - } - Group ShapeData33 - { - - ShapeIndex 40033 - Model "assassin_fencing1_Germany.GR2" - SourceSkin "assassin_fencing1_Germany.dds" - TargetSkin "assassin_fencing1_London.dds" - } - Group ShapeData34 - { - ShapeIndex 40034 - Model "assassin_fencing1_Germany.GR2" - SourceSkin "assassin_fencing1_Germany.dds" - TargetSkin "assassin_fencing1_Germany.dds" - } - Group ShapeData35 - { - ShapeIndex 40035 - Model "assassin_fencing1_Germany.GR2" - SourceSkin "assassin_fencing1_Germany.dds" - TargetSkin "assassin_fencing1_Turkey.dds" - } - Group ShapeData36 - { - ShapeIndex 40036 - Model "assassin_fencing1_Germany.GR2" - SourceSkin "assassin_fencing1_Germany.dds" - TargetSkin "assassin_fencing1_Brazil.dds" - } - Group ShapeData37 - { - ShapeIndex 40037 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_soccer1_London.dds" - } - Group ShapeData38 - { - ShapeIndex 40038 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_soccer1_Germany.dds" - } - Group ShapeData39 - { - ShapeIndex 40039 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_soccer1_Turkey.dds" - } - Group ShapeData40 - { - ShapeIndex 40040 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_soccer1_Brazil.dds" - } - Group ShapeData41 - { - ShapeIndex 40041 - Model "assassin_boxing1_Germany.gr2" - SourceSkin "assassin_boxing1_Germany.dds" - TargetSkin "assassin_boxing1_London.dds" - } - Group ShapeData42 - { - ShapeIndex 40042 - Model "assassin_boxing1_Germany.gr2" - SourceSkin "assassin_boxing1_Germany.dds" - TargetSkin "assassin_boxing1_Germany.dds" - } - Group ShapeData43 - { - ShapeIndex 40043 - Model "assassin_boxing1_Germany.gr2" - SourceSkin "assassin_boxing1_Germany.dds" - TargetSkin "assassin_boxing1_Turkey.dds" - } - Group ShapeData44 - { - ShapeIndex 40044 - Model "assassin_boxing1_Germany.gr2" - SourceSkin "assassin_boxing1_Germany.dds" - TargetSkin "assassin_boxing1_Brazil.dds" - } - Group ShapeData45 - { - ShapeIndex 40032 - Model "assassin_assasin1.gr2" - SourceSkin "assassin_assasin1.dds" - TargetSkin "assassin_assasin1.dds" - } - Group ShapeData46 - { - ShapeIndex 40045 - Model "assassin_fencing1_Germany.GR2" - SourceSkin "assassin_fencing1_Germany.dds" - TargetSkin "assassin_fencing1_France.dds" - } - Group ShapeData47 - { - ShapeIndex 40046 - Model "assassin_fencing1_Germany.GR2" - SourceSkin "assassin_fencing1_Germany.dds" - TargetSkin "assassin_fencing1_Italy.dds" - } - Group ShapeData48 - { - ShapeIndex 40047 - Model "assassin_fencing1_Germany.GR2" - SourceSkin "assassin_fencing1_Germany.dds" - TargetSkin "assassin_fencing1_Poland.dds" - } - Group ShapeData49 - { - ShapeIndex 40048 - Model "assassin_fencing1_Germany.GR2" - SourceSkin "assassin_fencing1_Germany.dds" - TargetSkin "assassin_fencing1_Romania.dds" - } - Group ShapeData50 - { - ShapeIndex 40049 - Model "assassin_fencing1_Germany.GR2" - SourceSkin "assassin_fencing1_Germany.dds" - TargetSkin "assassin_fencing1_Spain.dds" - } - - Group ShapeData51 - { - ShapeIndex 40050 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_soccer1_France.dds" - } - Group ShapeData52 - { - ShapeIndex 40051 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_soccer1_Italy.dds" - } - Group ShapeData53 - { - ShapeIndex 40052 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_soccer1_Poland.dds" - } - Group ShapeData54 - { - ShapeIndex 40053 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_soccer1_Romania.dds" - } - Group ShapeData55 - { - ShapeIndex 40054 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_soccer1_Spain.dds" - } - Group ShapeData56 - { - ShapeIndex 40055 - Model "assassin_boxing1_Germany.gr2" - SourceSkin "assassin_boxing1_Germany.dds" - TargetSkin "assassin_boxing1_France.dds" - } - Group ShapeData57 - { - ShapeIndex 40056 - Model "assassin_boxing1_Germany.gr2" - SourceSkin "assassin_boxing1_Germany.dds" - TargetSkin "assassin_boxing1_Italy.dds" - } - Group ShapeData58 - { - ShapeIndex 40057 - Model "assassin_boxing1_Germany.gr2" - SourceSkin "assassin_boxing1_Germany.dds" - TargetSkin "assassin_boxing1_Poland.dds" - } - Group ShapeData59 - { - ShapeIndex 40058 - Model "assassin_boxing1_Germany.gr2" - SourceSkin "assassin_boxing1_Germany.dds" - TargetSkin "assassin_boxing1_Romania.dds" - } - Group ShapeData60 - { - ShapeIndex 40059 - Model "assassin_boxing1_Germany.gr2" - SourceSkin "assassin_boxing1_Germany.dds" - TargetSkin "assassin_boxing1_Spain.dds" - } - Group ShapeData61 - { - ShapeIndex 40065 - Model "assassin_halloween1.gr2" - SourceSkin "assassin_halloween1.dds" - TargetSkin "assassin_halloween1.dds" - } - Group ShapeData62 - { - ShapeIndex 13 - Model "assassin_5_1.GR2" - SourceSkin "assassin_5_1.DDS" - TargetSkin "assassin_5_1.DDS" - } - Group ShapeData63 - { - ShapeIndex 40062 - Model "assassin_salsa1.GR2" - SourceSkin "assassin_salsa1.dds" - TargetSkin "assassin_salsa1.dds" - } - Group ShapeData64 - { - ShapeIndex 40063 - Model "assassin_Springwear1.GR2" - SourceSkin "assassin_Springwear1.dds" - TargetSkin "assassin_Springwear1.dds" - } - Group ShapeData65 - { - ShapeIndex 40061 - Model "assassin_tailcoat1.gr2" - SourceSkin "assassin_tailcoat1.dds" - TargetSkin "assassin_tailcoat1.ddsS" - } - Group ShapeData66 - { - ShapeIndex 40069 - Model "assassin_deer1.gr2" - SourceSkin "assassin_deer1.dds" - TargetSkin "assassin_deer1.dds" - } - Group ShapeData67 - { - ShapeIndex 40066 - Model "assassin_santa1_black.gr2" - SourceSkin "assassin_santa1_black.dds" - TargetSkin "assassin_santa1_red.dds" - } - Group ShapeData68 - { - ShapeIndex 40067 - Model "assassin_santa1_black.gr2" - SourceSkin "assassin_santa1_black.dds" - TargetSkin "assassin_santa1_green.dds" - } - Group ShapeData69 - { - ShapeIndex 40068 - Model "assassin_santa1_black.gr2" - SourceSkin "assassin_santa1_black.dds" - TargetSkin "assassin_santa1_black.dds" - } - Group ShapeData70 - { - ShapeIndex 40070 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA01.dds" - } - Group ShapeData71 - { - ShapeIndex 40071 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA02.dds" - } - Group ShapeData72 - { - ShapeIndex 40072 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA03.dds" - } - Group ShapeData73 - { - ShapeIndex 40073 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA04.dds" - } - Group ShapeData74 - { - ShapeIndex 40074 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA05.dds" - } - Group ShapeData75 - { - ShapeIndex 40075 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA06.dds" - } - Group ShapeData76 - { - ShapeIndex 40076 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA07.dds" - } - Group ShapeData77 - { - ShapeIndex 40077 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA08.dds" - } - Group ShapeData78 - { - ShapeIndex 40078 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA09.dds" - } - Group ShapeData79 - { - ShapeIndex 40079 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA10.dds" - } - Group ShapeData80 - { - ShapeIndex 40080 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA11.dds" - } - Group ShapeData81 - { - ShapeIndex 40081 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA12.dds" - } - Group ShapeData82 - { - ShapeIndex 40082 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA13.dds" - } - Group ShapeData83 - { - ShapeIndex 40083 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA14.dds" - } - Group ShapeData84 - { - ShapeIndex 40084 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA15.dds" - } - Group ShapeData85 - { - ShapeIndex 40085 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA16.dds" - } - Group ShapeData86 - { - ShapeIndex 40086 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA17.dds" - } - Group ShapeData87 - { - ShapeIndex 40087 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA18.dds" - } - Group ShapeData88 - { - ShapeIndex 40088 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA19.dds" - } - Group ShapeData89 - { - ShapeIndex 40089 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA20.dds" - } - Group ShapeData90 - { - ShapeIndex 40090 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA21.dds" - } - Group ShapeData91 - { - ShapeIndex 40091 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA22.dds" - } - Group ShapeData92 - { - ShapeIndex 40092 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA23.dds" - } - Group ShapeData93 - { - ShapeIndex 40093 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA24.dds" - } - Group ShapeData94 - { - ShapeIndex 40094 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA25.dds" - } - Group ShapeData95 - { - ShapeIndex 40095 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA26.dds" - } - Group ShapeData96 - { - ShapeIndex 40096 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA27.dds" - } - Group ShapeData97 - { - ShapeIndex 40097 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA28.dds" - } - Group ShapeData98 - { - ShapeIndex 40098 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA29.dds" - } - Group ShapeData99 - { - ShapeIndex 40099 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA30.dds" - } - Group ShapeData100 - { - ShapeIndex 40100 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA31.dds" - } - Group ShapeData101 - { - ShapeIndex 40101 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_UEFA32.dds" - } - Group ShapeData102 - { - ShapeIndex 40064 - Model "assassin_samurai1.GR2" - SourceSkin "assassin_samurai1.dds" - TargetSkin "assassin_samurai1.dds" - } - Group ShapeData103 - { - ShapeIndex 40106 - Model "assassin_rabbit1.GR2" - SourceSkin "assassin_rabbit1.dds" - TargetSkin "assassin_rabbit1_black.dds" - } - Group ShapeData104 - { - ShapeIndex 40107 - Model "assassin_rabbit1.GR2" - SourceSkin "assassin_rabbit1.dds" - TargetSkin "assassin_rabbit1_blue.dds" - } - Group ShapeData105 - { - ShapeIndex 40108 - Model "assassin_rabbit1.GR2" - SourceSkin "assassin_rabbit1.dds" - TargetSkin "assassin_rabbit1_green.dds" - } - Group ShapeData106 - { - ShapeIndex 40109 - Model "assassin_rabbit1.GR2" - SourceSkin "assassin_rabbit1.dds" - TargetSkin "assassin_rabbit1_pink.dds" - } - Group ShapeData107 - { - ShapeIndex 40110 - Model "assassin_BlackSnake1.GR2" - SourceSkin "assassin_BlackSnake1.dds" - TargetSkin "assassin_BlackSnake1.dds" - } - Group ShapeData108 - { - ShapeIndex 40111 - Model "assassin_BlackSnake1.GR2" - SourceSkin "assassin_BlackSnake1.dds" - TargetSkin "assassin_BlackSnake1.dds" - } - Group ShapeData109 - { - ShapeIndex 40113 - Model "assassin_assasin1.GR2" - SourceSkin "assassin_assasin1.dds" - TargetSkin "assassin_assasin2.dds" - } - Group ShapeData110 - { - ShapeIndex 40115 - Model "assassin_pwahuang1.GR2" - SourceSkin "assassin_pwahuang1.dds" - TargetSkin "assassin_pwahuang1.dds" - } - Group ShapeData111 - { - ShapeIndex 40117 - Model "assassin_halloween2.GR2" - SourceSkin "assassin_halloween2.dds" - TargetSkin "assassin_halloween2.dds" - } - Group ShapeData112 - { - ShapeIndex 40119 - Model "assassin_assasin1.gr2" - SourceSkin "assassin_assasin1.dds" - TargetSkin "assassin_assassin3.dds" - } - Group ShapeData113 - { - ShapeIndex 40060 - Model "assasin_capoeira1.GR2" - SourceSkin "assasin_capoeira1.dds" - TargetSkin "assasin_capoeira1.dds" - } - Group ShapeData114 - { - ShapeIndex 40121 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC01.dds" - } - Group ShapeData115 - { - ShapeIndex 40123 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC02.dds" - } - Group ShapeData116 - { - ShapeIndex 40125 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC03.dds" - } - Group ShapeData117 - { - ShapeIndex 40127 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC04.dds" - } - Group ShapeData118 - { - ShapeIndex 40129 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC05.dds" - } - Group ShapeData119 - { - ShapeIndex 40131 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC06.dds" - } - Group ShapeData120 - { - ShapeIndex 40133 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC07.dds" - } - Group ShapeData121 - { - ShapeIndex 40135 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC08.dds" - } - Group ShapeData122 - { - ShapeIndex 40137 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC09.dds" - } - Group ShapeData123 - { - ShapeIndex 40139 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC10.dds" - } - Group ShapeData124 - { - ShapeIndex 40141 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC11.dds" - } - Group ShapeData125 - { - ShapeIndex 40143 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC12.dds" - } - Group ShapeData126 - { - ShapeIndex 40145 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC13.dds" - } - Group ShapeData127 - { - ShapeIndex 40147 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC14.dds" - } - Group ShapeData128 - { - ShapeIndex 40149 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC15.dds" - } - Group ShapeData129 - { - ShapeIndex 40151 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC16.dds" - } - Group ShapeData130 - { - ShapeIndex 40153 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC17.dds" - } - Group ShapeData131 - { - ShapeIndex 40155 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC18.dds" - } - Group ShapeData132 - { - ShapeIndex 40157 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC19.dds" - } - Group ShapeData133 - { - ShapeIndex 40159 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC20.dds" - } - Group ShapeData134 - { - ShapeIndex 40161 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC21.dds" - } - Group ShapeData135 - { - ShapeIndex 40163 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC22.dds" - } - Group ShapeData136 - { - ShapeIndex 40165 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC23.dds" - } - Group ShapeData137 - { - ShapeIndex 40167 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC24.dds" - } - Group ShapeData138 - { - ShapeIndex 40169 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC25.dds" - } - Group ShapeData139 - { - ShapeIndex 40171 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC26.dds" - } - Group ShapeData140 - { - ShapeIndex 40173 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC27.dds" - } - Group ShapeData141 - { - ShapeIndex 40175 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC28.dds" - } - Group ShapeData142 - { - ShapeIndex 40177 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC29.dds" - } - Group ShapeData143 - { - ShapeIndex 40179 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC30.dds" - } - Group ShapeData144 - { - ShapeIndex 40181 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC31.dds" - } - Group ShapeData145 - { - ShapeIndex 40183 - Model "assassin_soccer1_Germany.GR2" - SourceSkin "assassin_soccer1_Germany.dds" - TargetSkin "assassin_WC32.dds" - } - -} - -Group AttachingData -{ - AttachingDataCount 2 - - Group AttachingData00 - { - AttachingDataType 1 - - isAttaching 0 - AttachingModelIndex 0 - AttachingBoneName "Bip01" - - CollisionType 1 - - SphereDataCount 1 - Group SphereData00 - { - Radius 40.000000 - Position 0.000000 0.000000 90.000000 - } - } - - Group AttachingData01 - { - AttachingDataType 1 - - isAttaching 0 - AttachingModelIndex 0 - AttachingBoneName "Bip01" - - CollisionType 3 - - SphereDataCount 1 - Group SphereData00 - { - Radius 70.000000 - Position 0.000000 0.000000 90.000000 - } - } -} diff --git a/tools/root/msm/shaman_m.msm b/tools/root/msm/shaman_m.msm deleted file mode 100644 index a54c6aa3..00000000 --- a/tools/root/msm/shaman_m.msm +++ /dev/null @@ -1,1594 +0,0 @@ -ScriptType RaceDataScript - -BaseModelFileName "D:/YMIR WORK/pc2/shaman/shaman_novice.GR2" - -Group HairData -{ - PathName "d:/ymir Work/pc2/shaman/" - - HairDataCount 61 - Group HairData00 - { - HairIndex 0 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "shaman_hair_01.dds" - } - Group HairData01 - { - HairIndex 1 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "shaman_hair_01_white.dds" - } - Group HairData02 - { - HairIndex 2 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "shaman_hair_01_gold.dds" - } - Group HairData03 - { - HairIndex 3 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "shaman_hair_01_red.dds" - } - Group HairData04 - { - HairIndex 4 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "shaman_hair_01_brown.dds" - } - Group HairData05 - { - HairIndex 5 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "shaman_hair_01_black.dds" - } - Group HairData06 - { - HairIndex 4001 - Model "hair/hair_2_1.gr2" - SourceSkin "hair/hair_2_1.dds" - TargetSkin "hair/hair_2_1.dds" - } - Group HairData07 - { - HairIndex 4002 - Model "hair/hair_2_1.gr2" - SourceSkin "hair/hair_2_1.dds" - TargetSkin "hair/hair_2_2.dds" - } - Group HairData08 - { - HairIndex 4003 - Model "hair/hair_2_1.gr2" - SourceSkin "hair/hair_2_1.dds" - TargetSkin "hair/hair_2_3.dds" - } - Group HairData09 - { - HairIndex 4004 - Model "hair/hair_2_1.gr2" - SourceSkin "hair/hair_2_1.dds" - TargetSkin "hair/hair_2_4.dds" - } - Group HairData10 - { - HairIndex 4005 - Model "hair/hair_3_1.gr2" - SourceSkin "hair/hair_3_1.dds" - TargetSkin "hair/hair_3_1.dds" - } - Group HairData11 - { - HairIndex 4006 - Model "hair/hair_3_1.gr2" - SourceSkin "hair/hair_3_1.dds" - TargetSkin "hair/hair_3_2.dds" - } - Group HairData12 - { - HairIndex 4007 - Model "hair/hair_3_1.gr2" - SourceSkin "hair/hair_3_1.dds" - TargetSkin "hair/hair_3_3.dds" - } - Group HairData13 - { - HairIndex 4008 - Model "hair/hair_3_1.gr2" - SourceSkin "hair/hair_3_1.dds" - TargetSkin "hair/hair_3_4.dds" - } - Group HairData14 - { - HairIndex 4009 - Model "hair/hair_4_1.gr2" - SourceSkin "hair/hair_4_1.dds" - TargetSkin "hair/hair_4_1.dds" - } - Group HairData15 - { - HairIndex 4010 - Model "hair/hair_4_1.gr2" - SourceSkin "hair/hair_4_1.dds" - TargetSkin "hair/hair_4_2.dds" - } - Group HairData16 - { - HairIndex 4011 - Model "hair/hair_4_1.gr2" - SourceSkin "hair/hair_4_1.dds" - TargetSkin "hair/hair_4_3.dds" - } - Group HairData17 - { - HairIndex 4012 - Model "hair/hair_4_1.gr2" - SourceSkin "hair/hair_4_1.dds" - TargetSkin "hair/hair_4_4.dds" - } - Group HairData18 - { - HairIndex 4013 - Model "hair/hair_6_1.gr2" - SourceSkin "hair/hair_6_1.dds" - TargetSkin "hair/hair_6_1.dds" - } - Group HairData19 - { - HairIndex 4014 - Model "hair/hair_5_1.gr2" - SourceSkin "hair/hair_5_1.dds" - TargetSkin "hair/hair_5_1.dds" - } - Group HairData20 - { - HairIndex 4015 - Model "hair/hair_7_1.gr2" - SourceSkin "hair/hair_7_1.dds" - TargetSkin "hair/hair_7_1.dds" - } - Group HairData21 - { - HairIndex 4016 - Model "hair/hair_8_1.gr2" - SourceSkin "hair/hair_8_1.dds" - TargetSkin "hair/hair_8_1.dds" - } - Group HairData22 - { - - HairIndex 4017 - Model "hair/hair_9_1.gr2" - SourceSkin "hair/hair_9_1.dds" - TargetSkin "hair/hair_9_1.dds" - } - Group HairData23 - { - - HairIndex 4018 - Model "hair/hair_10_1.gr2" - SourceSkin "hair/hair_10_1.dds" - TargetSkin "hair/hair_10_1.dds" - } - Group HairData24 - { - - HairIndex 5001 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_1.dds" - } - Group HairData25 - { - - HairIndex 5002 - Model "hair/hair_14_1.gr2" - SourceSkin "hair/hair_14_1.dds" - TargetSkin "hair/hair_14_1.dds" - } - - Group HairData26 - { - - HairIndex 5005 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_1.dds" - } - Group HairData27 - { - - HairIndex 5003 - Model "hair/hair_16_1.gr2" - SourceSkin "hair/hair_16_1.dds" - TargetSkin "hair/hair_16_1.dds" - } - Group HairData28 - { - - HairIndex 5004 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_1.dds" - } - Group HairData29 - { - - HairIndex 5027 - Model "hair/hair_20_1.gr2" - SourceSkin "hair/hair_20_1.dds" - TargetSkin "hair/hair_20_1.dds" - } - Group HairData30 - { - - HairIndex 5023 - Model "hair/hair_13_1.gr2" - SourceSkin "hair/hair_13_1.dds" - TargetSkin "hair/hair_13_1.dds" - } - Group HairData31 - { - - HairIndex 5024 - Model "hair/hair_18_1.gr2" - SourceSkin "hair/hair_18_1.dds" - TargetSkin "hair/hair_18_1.dds" - } - Group HairData32 - { - - HairIndex 5025 - Model "hair/hair_19_1.gr2" - SourceSkin "hair/hair_19_1.dds" - TargetSkin "hair/hair_19_1.dds" - } - Group HairData33 - { - HairIndex 5028 - Model "hair/hair_22_1.gr2" - SourceSkin "hair/hair_22_1.dds" - TargetSkin "hair/hair_22_3.dds" - } - Group HairData34 - { - HairIndex 5029 - Model "hair/hair_22_1.gr2" - SourceSkin "hair/hair_22_1.dds" - TargetSkin "hair/hair_22_2.dds" - } - Group HairData35 - { - HairIndex 5030 - Model "hair/hair_22_1.gr2" - SourceSkin "hair/hair_22_1.dds" - TargetSkin "hair/hair_22_1.dds" - } - Group HairData36 - { - HairIndex 5031 - Model "hair/hair_23_1.gr2" - SourceSkin "hair/hair_23_1.dds" - TargetSkin "hair/hair_23_1.dds" - } - Group HairData37 - { - HairIndex 5033 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_1.dds" - } - Group HairData38 - { - HairIndex 5035 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_2.dds" - } - Group HairData39 - { - HairIndex 5037 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_3.dds" - } - Group HairData40 - { - HairIndex 5039 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_4.dds" - } - Group HairData41 - { - HairIndex 5041 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_5.dds" - } - Group HairData42 - { - HairIndex 5026 - Model "hair/hair_21_1.gr2" - SourceSkin "hair/hair_21_1.dds" - TargetSkin "hair/hair_21_1.dds" - } - Group HairData43 - { - HairIndex 5045 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_2.dds" - } - Group HairData44 - { - HairIndex 5046 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_3.dds" - } - Group HairData45 - { - HairIndex 5047 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_4.dds" - } - Group HairData46 - { - HairIndex 5048 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_5.dds" - } - Group HairData47 - { - HairIndex 5049 - Model "hair/hair_28_1.gr2" - SourceSkin "hair/hair_28_1.dds" - TargetSkin "hair/hair_28_1.dds" - } - Group HairData48 - { - HairIndex 5050 - Model "hair/hair_28_1.gr2" - SourceSkin "hair/hair_28_1.dds" - TargetSkin "hair/hair_28_1.dds" - } - Group HairData49 - { - HairIndex 5051 - Model "hair/hair_29_1.gr2" - SourceSkin "hair/hair_29_1.dds" - TargetSkin "hair/hair_29_1.dds" - } - Group HairData50 - { - HairIndex 5052 - Model "hair/hair_30_1.gr2" - SourceSkin "hair/hair_30_1.dds" - TargetSkin "hair/hair_30_1.dds" - } - Group HairData51 - { - HairIndex 5053 - Model "hair/hair_31_1.gr2" - SourceSkin "hair/hair_31_1.dds" - TargetSkin "hair/hair_31_1.dds" - } - Group HairData52 - { - HairIndex 5054 - Model "hair/hair_32_1.gr2" - SourceSkin "hair/hair_32_1.dds" - TargetSkin "hair/hair_32_1.dds" - } - Group HairData53 - { - HairIndex 5055 - Model "hair/hair_14_1.gr2" - SourceSkin "hair/hair_14_1.dds" - TargetSkin "hair/hair_14_2.dds" - } - Group HairData54 - { - HairIndex 5057 - Model "hair/hair_33_1.gr2" - SourceSkin "hair/hair_33_1.dds" - TargetSkin "hair/hair_33_1.dds" - } - Group HairData55 - { - HairIndex 5059 - Model "hair/hair_34_1.gr2" - SourceSkin "hair/hair_34_1.dds" - TargetSkin "hair/hair_34_1.dds" - } - Group HairData56 - { - HairIndex 5061 - Model "hair/hair_35_1.gr2" - SourceSkin "hair/hair_35_1.dds" - TargetSkin "hair/hair_35_1.dds" - } - Group HairData57 - { - HairIndex 5063 - Model "hair/hair_37_1.gr2" - SourceSkin "hair/hair_37_1.dds" - TargetSkin "hair/hair_37_1.dds" - } - Group HairData58 - { - HairIndex 5064 - Model "hair/hair_36_1.gr2" - SourceSkin "hair/hair_36_1.dds" - TargetSkin "hair/hair_36_1.dds" - } - Group HairData59 - { - HairIndex 5065 - Model "hair/hair_38_1.gr2" - SourceSkin "hair/hair_38_1.dds" - TargetSkin "hair/hair_38_1.dds" - } - - Group HairData60 - { - HairIndex 5022 - Model "hair/hair_12_1.gr2" - SourceSkin "hair/hair_12_1.dds" - TargetSkin "hair/hair_12_1.dds" - } - -} - -Group ShapeData -{ - PathName "d:/ymir Work/pc2/shaman/" - - ShapeDataCount 146 - - Group ShapeData00 - { - ShapeIndex 0 - - Model "shaman_novice.GR2" - } - Group ShapeData01 - { - ShapeIndex 1 - - Model "shaman_novice.GR2" - SourceSkin "shaman_novice_red.dds" - TargetSkin "shaman_novice_green.dds" - } - Group ShapeData02 - { - ShapeIndex 3 - Model "shaman_cheongnang.GR2" - SourceSkin "shaman_cheongnang.dds" - TargetSkin "shaman_cheongnang.dds" - } - Group ShapeData03 - { - ShapeIndex 4 - Model "shaman_cheongnang.GR2" - SourceSkin "shaman_cheongnang.dds" - TargetSkin "shaman_nabong.dds" - } - Group ShapeData04 - { - ShapeIndex 5 - Model "shaman_cheongnang.GR2" - SourceSkin "shaman_cheongnang.dds" - TargetSkin "shaman_bihong.dds" - } - Group ShapeData05 - { - ShapeIndex 6 - Model "shaman_miyeom.GR2" - SourceSkin "shaman_miyeom.dds" - TargetSkin "shaman_miyeom.dds" - } - Group ShapeData06 - { - ShapeIndex 7 - Model "shaman_miyeom.GR2" - SourceSkin "shaman_miyeom.dds" - TargetSkin "shaman_seocheon.dds" - } - Group ShapeData07 - { - ShapeIndex 8 - Model "shaman_miyeom.GR2" - SourceSkin "shaman_miyeom.dds" - TargetSkin "shaman_ilseon.dds" - } - Group ShapeData08 - { - ShapeIndex 9 - Model "shaman_cheonryun.GR2" - SourceSkin "shaman_cheonryun.dds" - TargetSkin "shaman_cheonryun.dds" - } - Group ShapeData09 - { - ShapeIndex 10 - Model "shaman_cheonryun.GR2" - SourceSkin "shaman_cheonryun.dds" - TargetSkin "shaman_amyo.dds" - } - Group ShapeData10 - { - ShapeIndex 11 - Model "shaman_cheonryun.GR2" - SourceSkin "shaman_cheonryun.dds" - TargetSkin "shaman_bongsin.dds" - } - Group ShapeData11 - { - SpecialPath "d:/ymir work/monster/wolf/" - - ShapeIndex 100 - Model "wolf.gr2" - SourceSkin "wolf.dds" - } - Group ShapeData12 - { - SpecialPath "d:/ymir work/monster/wild_boar/" - - ShapeIndex 101 - Model "wild_boar.gr2" - SourceSkin "wild_boar.dds" - } - Group ShapeData13 - { - SpecialPath "d:/ymir work/monster/bear/" - - ShapeIndex 102 - Model "bear.gr2" - SourceSkin "bear.dds" - } - Group ShapeData14 - { - SpecialPath "d:/ymir work/monster/tiger/" - - ShapeIndex 103 - Model "tiger.gr2" - SourceSkin "tiger.dds" - } - Group ShapeData15 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 201 - Model "shaman_marry_01.gr2" - SourceSkin "shaman_marry_01.dds" - TargetSkin "shaman_marry_01.dds" - } - Group ShapeData16 - { - ShapeIndex 12 - Model "shaman_4-1.GR2" - SourceSkin "shaman_4-1.dds" - TargetSkin "shaman_4-1.dds" - } - - - Group ShapeData17 - { - ShapeIndex 14 - Model "shaman_cheongnang.GR2" - SourceSkin "shaman_cheongnang.dds" - TargetSkin "shaman_1-1cheongnang_a.DDS" - } - Group ShapeData18 - { - ShapeIndex 15 - Model "shaman_cheongnang.GR2" - SourceSkin "shaman_cheongnang.dds" - TargetSkin "shaman_1-2_nabong_a.DDS" - } - Group ShapeData19 - { - ShapeIndex 16 - Model "shaman_cheongnang.GR2" - SourceSkin "shaman_cheongnang.dds" - TargetSkin "shaman_bihong_a.dds" - } - Group ShapeData20 - { - ShapeIndex 17 - Model "shaman_miyeom.GR2" - SourceSkin "shaman_miyeom.dds" - TargetSkin "shaman_2-1_miyeon_a.DDS" - } - Group ShapeData21 - { - ShapeIndex 18 - Model "shaman_miyeom.GR2" - SourceSkin "shaman_miyeom.dds" - TargetSkin "shaman_2-2_seocheon_a.DDS" - } - Group ShapeData22 - { - ShapeIndex 19 - Model "shaman_miyeom.GR2" - SourceSkin "shaman_miyeom.dds" - TargetSkin "shaman_2-3_ilseon_a.DDS" - } - Group ShapeData23 - { - ShapeIndex 20 - Model "shaman_cheonryun.GR2" - SourceSkin "shaman_cheonryun.dds" - TargetSkin "shaman_3-1_cheonryun_a.DDS" - } - Group ShapeData24 - { - ShapeIndex 21 - Model "shaman_cheonryun.GR2" - SourceSkin "shaman_cheonryun.dds" - TargetSkin "shaman_3-2_amyo_a.DDS" - } - Group ShapeData25 - { - ShapeIndex 24 - Model "shaman_lord.GR2" - SourceSkin "shaman_queen01.dds" - TargetSkin "shaman_queen01.dds" - } - Group ShapeData26 - { - ShapeIndex 25 - Model "shaman_lord.GR2" - SourceSkin "shaman_queen01.dds" - TargetSkin "shaman_queen02.dds" - } - Group ShapeData27 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 26 - Model "shaman_4-1.GR2" - SourceSkin "shaman_4-1.dds" - TargetSkin "shaman_4-2.dds" - } - Group ShapeData28 - { - - ShapeIndex 27 - Model "shaman_event1.GR2" - SourceSkin "shaman_event1_yellow.dds" - TargetSkin "shaman_event1_red.dds" - } - Group ShapeData29 - { - - ShapeIndex 28 - Model "shaman_event1.GR2" - SourceSkin "shaman_event1_yellow.dds" - TargetSkin "shaman_event1_yellow.dds" - } - Group ShapeData30 - { - - ShapeIndex 29 - Model "shaman_event1.GR2" - SourceSkin "shaman_event1_yellow.dds" - TargetSkin "shaman_event1_blue.dds" - } - Group ShapeData31 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 30 - Model "shaman_cheongnang.gr2" - SourceSkin "shaman_cheongnang.dds" - TargetSkin "shaman_costume1.dds" - } - Group ShapeData32 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40031 - Model "shaman_rabbit1.GR2" - SourceSkin "shaman_rabbit1.dds" - TargetSkin "shaman_rabbit1.dds" - } - Group ShapeData33 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40033 - Model "shaman_fencing1_Germany.GR2" - SourceSkin "shaman_fencing1_Germany.dds" - TargetSkin "shaman_fencing1_London.dds" - } - Group ShapeData34 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40034 - Model "shaman_fencing1_Germany.GR2" - SourceSkin "shaman_fencing1_Germany.dds" - TargetSkin "shaman_fencing1_Germany.dds" - } - Group ShapeData35 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40035 - Model "shaman_fencing1_Germany.GR2" - SourceSkin "shaman_fencing1_Germany.dds" - TargetSkin "shaman_fencing1_Turkey.dds" - } - Group ShapeData36 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40036 - Model "shaman_fencing1_Germany.GR2" - SourceSkin "shaman_fencing1_Germany.dds" - TargetSkin "shaman_fencing1_Brazil.dds" - } - Group ShapeData37 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40037 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_soccer1_London.dds" - } - Group ShapeData38 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40038 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_soccer1_Germany.dds" - } - Group ShapeData39 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40039 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_soccer1_Turkey.dds" - } - Group ShapeData40 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40040 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_soccer1_Brazil.dds" - } - Group ShapeData41 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40041 - Model "shaman_boxing1_Germany.GR2" - SourceSkin "shaman_boxing1_Germany.dds" - TargetSkin "shaman_boxing1_London.dds" - } - Group ShapeData42 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40042 - Model "shaman_boxing1_Germany.GR2" - SourceSkin "shaman_boxing1_Germany.dds" - TargetSkin "shaman_boxing1_Germany.dds" - } - Group ShapeData43 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40043 - Model "shaman_boxing1_Germany.GR2" - SourceSkin "shaman_boxing1_Germany.dds" - TargetSkin "shaman_boxing1_Turkey.dds" - } - Group ShapeData44 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40044 - Model "shaman_boxing1_Germany.GR2" - SourceSkin "shaman_boxing1_Germany.dds" - TargetSkin "shaman_boxing1_Brazil.dds" - } - Group ShapeData45 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40032 - Model "shaman_assasin1.GR2" - SourceSkin "shaman_assassin1.dds" - TargetSkin "shaman_assassin1.dds" - } - Group ShapeData46 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40045 - Model "shaman_fencing1_Germany.GR2" - SourceSkin "shaman_fencing1_Germany.dds" - TargetSkin "shaman_fencing1_France.dds" - } - Group ShapeData47 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40046 - Model "shaman_fencing1_Germany.GR2" - SourceSkin "shaman_fencing1_Germany.dds" - TargetSkin "shaman_fencing1_Italy.dds" - } - Group ShapeData48 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40047 - Model "shaman_fencing1_Germany.GR2" - SourceSkin "shaman_fencing1_Germany.dds" - TargetSkin "shaman_fencing1_Poland.dds" - } - Group ShapeData49 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40048 - Model "shaman_fencing1_Germany.GR2" - SourceSkin "shaman_fencing1_Germany.dds" - TargetSkin "shaman_fencing1_Romania.dds" - } - Group ShapeData50 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40049 - Model "shaman_fencing1_Germany.GR2" - SourceSkin "shaman_fencing1_Germany.dds" - TargetSkin "shaman_fencing1_Spain.dds" - } - Group ShapeData51 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40050 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_soccer1_France.dds" - } - Group ShapeData52 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - ShapeIndex 40051 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_soccer1_Italy.dds" - } - Group ShapeData53 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40052 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_soccer1_Poland.dds" - } - Group ShapeData54 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40053 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_soccer1_Romania.dds" - } - Group ShapeData55 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - ShapeIndex 40054 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_soccer1_Spain.dds" - } - Group ShapeData56 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40055 - Model "shaman_boxing1_Germany.GR2" - SourceSkin "shaman_boxing1_Germany.dds" - TargetSkin "shaman_boxing1_France.dds" - } - Group ShapeData57 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40056 - Model "shaman_boxing1_Germany.GR2" - SourceSkin "shaman_boxing1_Germany.dds" - TargetSkin "shaman_boxing1_Italy.dds" - } - Group ShapeData58 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40057 - Model "shaman_boxing1_Germany.GR2" - SourceSkin "shaman_boxing1_Germany.dds" - TargetSkin "shaman_boxing1_Poland.dds" - } - Group ShapeData59 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - ShapeIndex 40058 - Model "shaman_boxing1_Germany.GR2" - SourceSkin "shaman_boxing1_Germany.dds" - TargetSkin "shaman_boxing1_Romania.dds" - } - Group ShapeData60 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40059 - Model "shaman_boxing1_Germany.GR2" - SourceSkin "shaman_boxing1_Germany.dds" - TargetSkin "shaman_boxing1_Spain.dds" - } - Group ShapeData61 - { - SpecialPath "d:/ymir Work/pc2/shaman/" - - ShapeIndex 40065 - Model "shaman_halloween1.GR2" - SourceSkin "shaman_halloween1.dds" - TargetSkin "shaman_halloween1.dds" - } - Group ShapeData62 - { - ShapeIndex 13 - Model "shaman_5_1.GR2" - SourceSkin "shaman_5_1.dds" - TargetSkin "shaman_5_1.dds" - } - Group ShapeData63 - { - ShapeIndex 40062 - Model "shaman_salsa1.GR2" - SourceSkin "shaman_salsa1.dds" - TargetSkin "shaman_salsa1.dds" - } - Group ShapeData64 - { - ShapeIndex 40063 - Model "shaman_Springwear1.GR2" - SourceSkin "shaman_Springwear1.dds" - TargetSkin "shaman_Springwear1.dds" - } - Group ShapeData65 - { - ShapeIndex 40061 - Model "shaman_tailcoat1.GR2" - SourceSkin "shaman_tailcoat1.dds" - TargetSkin "shaman_tailcoat1.dds" - } - Group ShapeData66 - { - ShapeIndex 40069 - Model "shaman_deer1.gr2" - SourceSkin "shaman_deer1.dds" - TargetSkin "shaman_deer1.dds" - } - Group ShapeData67 - { - ShapeIndex 40066 - Model "shaman_santa1_black.gr2" - SourceSkin "shaman_santa1_black.dds" - TargetSkin "shaman_santa1_red.dds" - } - Group ShapeData68 - { - ShapeIndex 40067 - Model "shaman_santa1_black.gr2" - SourceSkin "shaman_santa1_black.dds" - TargetSkin "shaman_santa1_green.dds" - } - Group ShapeData69 - { - ShapeIndex 40068 - Model "shaman_santa1_black.gr2" - SourceSkin "shaman_santa1_black.dds" - TargetSkin "shaman_santa1_black.dds" - } - Group ShapeData70 - { - ShapeIndex 40070 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA01.dds" - } - Group ShapeData71 - { - ShapeIndex 40071 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA02.dds" - } - Group ShapeData72 - { - ShapeIndex 40072 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA03.dds" - } - Group ShapeData73 - { - ShapeIndex 40073 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA04.dds" - } - Group ShapeData74 - { - ShapeIndex 40074 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA05.dds" - } - Group ShapeData75 - { - ShapeIndex 40075 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA06.dds" - } - Group ShapeData76 - { - ShapeIndex 40076 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA07.dds" - } - Group ShapeData77 - { - ShapeIndex 40077 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA08.dds" - } - Group ShapeData78 - { - ShapeIndex 40078 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA09.dds" - } - Group ShapeData79 - { - ShapeIndex 40079 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA10.dds" - } - Group ShapeData80 - { - ShapeIndex 40080 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA11.dds" - } - Group ShapeData81 - { - ShapeIndex 40081 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA12.dds" - } - Group ShapeData82 - { - ShapeIndex 40082 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA13.dds" - } - Group ShapeData83 - { - ShapeIndex 40083 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA14.dds" - } - Group ShapeData84 - { - ShapeIndex 40084 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA15.dds" - } - Group ShapeData85 - { - ShapeIndex 40085 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA16.dds" - } - Group ShapeData86 - { - ShapeIndex 40086 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA17.dds" - } - Group ShapeData87 - { - ShapeIndex 40087 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA18.dds" - } - Group ShapeData88 - { - ShapeIndex 40088 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA19.dds" - } - Group ShapeData89 - { - ShapeIndex 40089 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA20.dds" - } - Group ShapeData90 - { - ShapeIndex 40090 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA21.dds" - } - Group ShapeData91 - { - ShapeIndex 40091 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA22.dds" - } - Group ShapeData92 - { - ShapeIndex 40092 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA23.dds" - } - Group ShapeData93 - { - ShapeIndex 40093 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA24.dds" - } - Group ShapeData94 - { - ShapeIndex 40094 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA25.dds" - } - Group ShapeData95 - { - ShapeIndex 40095 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA26.dds" - } - Group ShapeData96 - { - ShapeIndex 40096 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA27.dds" - } - Group ShapeData97 - { - ShapeIndex 40097 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA28.dds" - } - Group ShapeData98 - { - ShapeIndex 40098 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA29.dds" - } - Group ShapeData99 - { - ShapeIndex 40099 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA30.dds" - } - Group ShapeData100 - { - ShapeIndex 40100 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA31.dds" - } - Group ShapeData101 - { - ShapeIndex 40101 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA32.dds" - } - Group ShapeData102 - { - ShapeIndex 40064 - Model "shaman_samurai1.GR2" - SourceSkin "shaman_samurai1.dds" - TargetSkin "shaman_samurai1.dds" - } - Group ShapeData103 - { - ShapeIndex 40106 - Model "shaman_rabbit1.GR2" - SourceSkin "shaman_rabbit1.dds" - TargetSkin "shaman_rabbit1_black.dds" - } - Group ShapeData104 - { - ShapeIndex 40107 - Model "shaman_rabbit1.GR2" - SourceSkin "shaman_rabbit1.dds" - TargetSkin "shaman_rabbit1_blue.dds" - } - Group ShapeData105 - { - ShapeIndex 40108 - Model "shaman_rabbit1.GR2" - SourceSkin "shaman_rabbit1.dds" - TargetSkin "shaman_rabbit1_green.dds" - } - Group ShapeData106 - { - ShapeIndex 40109 - Model "shaman_rabbit1.GR2" - SourceSkin "shaman_rabbit1.dds" - TargetSkin "shaman_rabbit1_pink.dds" - } - Group ShapeData107 - { - ShapeIndex 40110 - Model "shaman_BlackSnake1.GR2" - SourceSkin "shaman_BlackSnake1.dds" - TargetSkin "shaman_BlackSnake1.dds" - } - Group ShapeData108 - { - ShapeIndex 40111 - Model "shaman_BlackSnake1.GR2" - SourceSkin "shaman_BlackSnake1.dds" - TargetSkin "shaman_BlackSnake1.dds" - } - Group ShapeData109 - { - ShapeIndex 40112 - Model "shaman_assasin1.GR2" - SourceSkin "shaman_assassin1.dds" - TargetSkin "shaman_assassin2.dds" - } - Group ShapeData110 - { - ShapeIndex 40114 - Model "shaman_pwahuang1.GR2" - SourceSkin "shaman_pwahuang1.dds" - TargetSkin "shaman_pwahuang1.dds" - } - Group ShapeData111 - { - ShapeIndex 40116 - Model "shaman_halloween2.GR2" - SourceSkin "shaman_halloween2.dds" - TargetSkin "shaman_halloween2.dds" - } - Group ShapeData112 - { - ShapeIndex 40118 - Model "shaman_assasin1.GR2" - SourceSkin "shaman_assassin1.dds" - TargetSkin "shaman_assassin3.dds" - } - Group ShapeData113 - { - ShapeIndex 40060 - Model "shaman_capoeira1.gr2" - SourceSkin "shaman_capoeira1.dds" - TargetSkin "shaman_capoeira1.dds" - } - Group ShapeData114 - { - ShapeIndex 40120 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC01.dds" - } - Group ShapeData115 - { - ShapeIndex 40122 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC02.dds" - } - Group ShapeData116 - { - ShapeIndex 40124 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC03.dds" - } - Group ShapeData117 - { - ShapeIndex 40126 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC04.dds" - } - Group ShapeData118 - { - ShapeIndex 40128 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC05.dds" - } - Group ShapeData119 - { - ShapeIndex 40130 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC06.dds" - } - Group ShapeData120 - { - ShapeIndex 40132 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC07.dds" - } - Group ShapeData121 - { - ShapeIndex 40134 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC08.dds" - } - Group ShapeData122 - { - ShapeIndex 40136 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC09.dds" - } - Group ShapeData123 - { - ShapeIndex 40138 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC10.dds" - } - Group ShapeData124 - { - ShapeIndex 40140 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC11.dds" - } - Group ShapeData125 - { - ShapeIndex 40142 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC12.dds" - } - Group ShapeData126 - { - ShapeIndex 40144 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC13.dds" - } - Group ShapeData127 - { - ShapeIndex 40146 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC14.dds" - } - Group ShapeData128 - { - ShapeIndex 40148 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC15.dds" - } - Group ShapeData129 - { - ShapeIndex 40150 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC16.dds" - } - Group ShapeData130 - { - ShapeIndex 40152 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC17.dds" - } - Group ShapeData131 - { - ShapeIndex 40154 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC18.dds" - } - Group ShapeData132 - { - ShapeIndex 40156 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC19.dds" - } - Group ShapeData133 - { - ShapeIndex 40158 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC20.dds" - } - Group ShapeData134 - { - ShapeIndex 40160 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC21.dds" - } - Group ShapeData135 - { - ShapeIndex 40162 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC22.dds" - } - Group ShapeData136 - { - ShapeIndex 40164 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC23.dds" - } - Group ShapeData137 - { - ShapeIndex 40166 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC24.dds" - } - Group ShapeData138 - { - ShapeIndex 40168 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC25.dds" - } - Group ShapeData139 - { - ShapeIndex 40170 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC26.dds" - } - Group ShapeData140 - { - ShapeIndex 40172 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC27.dds" - } - Group ShapeData141 - { - ShapeIndex 40174 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC28.dds" - } - Group ShapeData142 - { - ShapeIndex 40176 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC29.dds" - } - Group ShapeData143 - { - ShapeIndex 40178 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC30.dds" - } - Group ShapeData144 - { - ShapeIndex 40180 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC31.dds" - } - Group ShapeData145 - { - ShapeIndex 40182 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC32.dds" - } -} - -Group AttachingData -{ - AttachingDataCount 2 - - Group AttachingData00 - { - AttachingDataType 1 - - isAttaching 0 - AttachingModelIndex 0 - AttachingBoneName "Bip01" - - CollisionType 1 - - SphereDataCount 1 - Group SphereData00 - { - Radius 40.000000 - Position 0.000000 0.000000 90.000000 - } - } - - Group AttachingData01 - { - AttachingDataType 1 - - isAttaching 0 - AttachingModelIndex 0 - AttachingBoneName "Bip01" - - CollisionType 3 - - SphereDataCount 1 - Group SphereData00 - { - Radius 70.000000 - Position 0.000000 0.000000 90.000000 - } - } -} diff --git a/tools/root/msm/shaman_w.msm b/tools/root/msm/shaman_w.msm deleted file mode 100644 index 0be6d8d9..00000000 --- a/tools/root/msm/shaman_w.msm +++ /dev/null @@ -1,1628 +0,0 @@ -ScriptType RaceDataScript - -BaseModelFileName "D:/YMIR WORK/pc/shaman/shaman_novice.GR2" - -Group HairData -{ - PathName "d:/ymir Work/pc/shaman/" - - HairDataCount 75 - Group HairData00 - { - HairIndex 0 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "shaman_hair_01.dds" - } - Group HairData01 - { - HairIndex 1 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "shaman_hair_01_white.dds" - } - Group HairData02 - { - HairIndex 2 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "shaman_hair_01_gold.dds" - } - Group HairData03 - { - HairIndex 3 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "shaman_hair_01_red.dds" - } - Group HairData04 - { - HairIndex 4 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "shaman_hair_01_brown.dds" - } - Group HairData05 - { - HairIndex 5 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "shaman_hair_01_black.dds" - } - Group HairData06 - { - HairIndex 4001 - Model "hair/hair_2_1.gr2" - SourceSkin "hair/hair_2_1.dds" - TargetSkin "hair/hair_2_1.dds" - } - Group HairData07 - { - HairIndex 4002 - Model "hair/hair_2_2.gr2" - SourceSkin "hair/hair_2_2.dds" - TargetSkin "hair/hair_2_2.dds" - } - Group HairData08 - { - HairIndex 4003 - Model "hair/hair_2_3.gr2" - SourceSkin "hair/hair_2_3.dds" - TargetSkin "hair/hair_2_3.dds" - } - Group HairData09 - { - HairIndex 4004 - Model "hair/hair_2_4.gr2" - SourceSkin "hair/hair_2_4.dds" - TargetSkin "hair/hair_2_4.dds" - } - Group HairData10 - { - HairIndex 4005 - Model "hair/hair_3_1.gr2" - SourceSkin "hair/hair_3_1.dds" - TargetSkin "hair/hair_3_1.dds" - } - Group HairData11 - { - HairIndex 4006 - Model "hair/hair_3_2.gr2" - SourceSkin "hair/hair_3_2.dds" - TargetSkin "hair/hair_3_2.dds" - } - Group HairData12 - { - HairIndex 4007 - Model "hair/hair_3_3.gr2" - SourceSkin "hair/hair_3_3.dds" - TargetSkin "hair/hair_3_3.dds" - } - Group HairData13 - { - HairIndex 4008 - Model "hair/hair_3_4.gr2" - SourceSkin "hair/hair_3_4.dds" - TargetSkin "hair/hair_3_4.dds" - } - Group HairData14 - { - HairIndex 4009 - Model "hair/hair_4_1.gr2" - SourceSkin "hair/hair_4_1.dds" - TargetSkin "hair/hair_4_1.dds" - } - Group HairData15 - { - HairIndex 4010 - Model "hair/hair_4_2.gr2" - SourceSkin "hair/hair_4_2.dds" - TargetSkin "hair/hair_4_2.dds" - } - Group HairData16 - { - HairIndex 4011 - Model "hair/hair_4_3.gr2" - SourceSkin "hair/hair_4_3.dds" - TargetSkin "hair/hair_4_3.dds" - } - Group HairData17 - { - HairIndex 4012 - Model "hair/hair_4_4.gr2" - SourceSkin "hair/hair_4_4.dds" - TargetSkin "hair/hair_4_4.dds" - } - Group HairData18 - { - HairIndex 4013 - Model "hair/hair_6_1.gr2" - SourceSkin "hair/hair_6_1.dds" - TargetSkin "hair/hair_6_1.dds" - } - Group HairData19 - { - HairIndex 4014 - Model "hair/hair_5_1.gr2" - SourceSkin "hair/hair_5_1.dds" - TargetSkin "hair/hair_5_1.dds" - } - Group HairData20 - { - HairIndex 4015 - Model "hair/hair_7_1.gr2" - SourceSkin "hair/hair_7_1.dds" - TargetSkin "hair/hair_7_1.dds" - } - Group HairData21 - { - HairIndex 4016 - Model "hair/hair_8_1.gr2" - SourceSkin "hair/hair_8_1.dds" - TargetSkin "hair/hair_8_1.dds" - } - Group HairData22 - { - HairIndex 4017 - Model "hair/hair_9_1.gr2" - SourceSkin "hair/hair_9_1.dds" - TargetSkin "hair/hair_9_1.dds" - } - Group HairData23 - { - HairIndex 4018 - Model "hair/hair_10_1.gr2" - SourceSkin "hair/hair_10_1.dds" - TargetSkin "hair/hair_10_1.dds" - } - Group HairData24 - { - HairIndex 5001 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_1.dds" - } - Group HairData25 - { - HairIndex 5002 - Model "hair/hair_14_1.gr2" - SourceSkin "hair/hair_14_1.dds" - TargetSkin "hair/hair_14_1.dds" - } - Group HairData26 - { - HairIndex 5008 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_1.dds" - } - - Group HairData27 - { - HairIndex 5003 - Model "hair/hair_16_1.gr2" - SourceSkin "hair/hair_16_1.dds" - TargetSkin "hair/hair_16_1.dds" - } - Group HairData28 - { - HairIndex 5016 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_1.dds" - } - Group HairData29 - { - HairIndex 5005 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_2.dds" - } - Group HairData30 - { - HairIndex 5007 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_3.dds" - } - Group HairData31 - { - HairIndex 5006 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_4.dds" - } - Group HairData32 - { - HairIndex 5009 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_5.dds" - } - Group HairData33 - { - HairIndex 5010 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_6.dds" - } - Group HairData34 - { - HairIndex 5011 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_7.dds" - } - Group HairData35 - { - HairIndex 5012 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_8.dds" - } - Group HairData36 - { - HairIndex 5013 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_9.dds" - } - Group HairData37 - { - HairIndex 5004 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_2.dds" - } - Group HairData38 - { - HairIndex 5015 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_3.dds" - } - Group HairData39 - { - HairIndex 5014 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_4.dds" - } - Group HairData40 - { - HairIndex 5017 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_5.dds" - } - Group HairData41 - { - HairIndex 5018 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_6.dds" - } - Group HairData42 - { - HairIndex 5019 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_7.dds" - } - Group HairData43 - { - HairIndex 5020 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_8.dds" - } - Group HairData44 - { - HairIndex 5021 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_9.dds" - } - Group HairData45 - { - HairIndex 5027 - Model "hair/hair_20_1.gr2" - SourceSkin "hair/hair_20_1.dds" - TargetSkin "hair/hair_20_1.dds" - } - Group HairData46 - { - HairIndex 5023 - Model "hair/hair_13_1.gr2" - SourceSkin "hair/hair_13_1.dds" - TargetSkin "hair/hair_13_1.dds" - } - - Group HairData47 - { - HairIndex 5024 - Model "hair/hair_18_1.gr2" - SourceSkin "hair/hair_18_1.dds" - TargetSkin "hair/hair_18_1.dds" - } - - Group HairData48 - { - HairIndex 5025 - Model "hair/hair_19_1.gr2" - SourceSkin "hair/hair_19_1.dds" - TargetSkin "hair/hair_19_1.dds" - } - Group HairData49 - { - HairIndex 5030 - Model "hair/hair_22_1.gr2" - SourceSkin "hair/hair_22_1.dds" - TargetSkin "hair/hair_22_1.dds" - } - Group HairData50 - { - HairIndex 5031 - Model "hair/hair_23_1.gr2" - SourceSkin "hair/hair_23_1.dds" - TargetSkin "hair/hair_23_1.dds" - } - Group HairData51 - { - HairIndex 5034 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_1.dds" - } - Group HairData52 - { - HairIndex 5036 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_2.dds" - } - Group HairData53 - { - HairIndex 5038 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_3.dds" - } - Group HairData54 - { - HairIndex 5040 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_4.dds" - } - Group HairData55 - { - HairIndex 5042 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_5.dds" - } - Group HairData56 - { - HairIndex 5026 - Model "hair/hair_21_1.gr2" - SourceSkin "hair/hair_21_1.dds" - TargetSkin "hair/hair_21_1.dds" - } - Group HairData57 - { - HairIndex 5045 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_2.dds" - } - Group HairData58 - { - HairIndex 5046 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_3.dds" - } - Group HairData59 - { - HairIndex 5047 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_4.dds" - } - Group HairData60 - { - HairIndex 5048 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_5.dds" - } - Group HairData61 - { - HairIndex 5049 - Model "hair/hair_28_1.gr2" - SourceSkin "hair/hair_28_1.dds" - TargetSkin "hair/hair_28_1.dds" - } - Group HairData62 - { - HairIndex 5050 - Model "hair/hair_28_1.gr2" - SourceSkin "hair/hair_28_1.dds" - TargetSkin "hair/hair_28_1.dds" - } - Group HairData63 - { - HairIndex 5051 - Model "hair/hair_29_1.gr2" - SourceSkin "hair/hair_29_1.dds" - TargetSkin "hair/hair_29_1.dds" - } - Group HairData64 - { - HairIndex 5052 - Model "hair/hair_30_1.gr2" - SourceSkin "hair/hair_30_1.dds" - TargetSkin "hair/hair_30_1.dds" - } - Group HairData65 - { - HairIndex 5053 - Model "hair/hair_31_1.gr2" - SourceSkin "hair/hair_31_1.dds" - TargetSkin "hair/hair_31_1.dds" - } - Group HairData66 - { - HairIndex 5054 - Model "hair/hair_32_1.gr2" - SourceSkin "hair/hair_32_1.dds" - TargetSkin "hair/hair_32_1.dds" - } - Group HairData67 - { - HairIndex 5056 - Model "hair/hair_14_1.gr2" - SourceSkin "hair/hair_14_1.dds" - TargetSkin "hair/hair_14_2.dds" - } - Group HairData68 - { - HairIndex 5058 - Model "hair/hair_33_1.gr2" - SourceSkin "hair/hair_33_1.dds" - TargetSkin "hair/hair_33_1.dds" - } - Group HairData69 - { - HairIndex 5060 - Model "hair/hair_34_1.gr2" - SourceSkin "hair/hair_34_1.dds" - TargetSkin "hair/hair_34_1.dds" - } - Group HairData70 - { - HairIndex 5062 - Model "hair/hair_35_1.GR2" - SourceSkin "hair/hair_35_1.dds" - TargetSkin "hair/hair_35_1.dds" - } - Group HairData71 - { - HairIndex 5063 - Model "hair/hair_37_1.GR2" - SourceSkin "hair/hair_37_1.dds" - TargetSkin "hair/hair_37_1.dds" - } - Group HairData72 - { - HairIndex 5064 - Model "hair/hair_36_1.GR2" - SourceSkin "hair/hair_36_1.dds" - TargetSkin "hair/hair_36_1.dds" - } - Group HairData73 - { - HairIndex 5065 - Model "hair/hair_38_1.GR2" - SourceSkin "hair/hair_38_1.dds" - TargetSkin "hair/hair_38_1.dds" - } - Group HairData74 - { - HairIndex 5022 - Model "hair/hair_12_1.GR2" - SourceSkin "hair/hair_12_1.dds" - TargetSkin "hair/hair_12_1.dds" - } -} - -Group ShapeData -{ - PathName "d:/ymir Work/pc/shaman/" - - ShapeDataCount 146 - - Group ShapeData00 - { - ShapeIndex 0 - - Model "shaman_novice.GR2" - } - Group ShapeData01 - { - ShapeIndex 1 - - Model "shaman_novice.GR2" - SourceSkin "shaman_novice_red.dds" - TargetSkin "shaman_novice_green.dds" - } - Group ShapeData02 - { - ShapeIndex 3 - Model "shaman_cheongnang.GR2" - SourceSkin "shaman_cheongnang.dds" - TargetSkin "shaman_cheongnang.dds" - } - Group ShapeData03 - { - ShapeIndex 4 - Model "shaman_cheongnang.GR2" - SourceSkin "shaman_cheongnang.dds" - TargetSkin "shaman_nabong.dds" - } - Group ShapeData04 - { - ShapeIndex 5 - Model "shaman_cheongnang.GR2" - SourceSkin "shaman_cheongnang.dds" - TargetSkin "shaman_bihong.dds" - } - Group ShapeData05 - { - ShapeIndex 6 - Model "shaman_miyeom.GR2" - SourceSkin "shaman_miyeom.dds" - TargetSkin "shaman_miyeom.dds" - } - Group ShapeData06 - { - ShapeIndex 7 - Model "shaman_miyeom.GR2" - SourceSkin "shaman_miyeom.dds" - TargetSkin "shaman_seocheon.dds" - } - Group ShapeData07 - { - ShapeIndex 8 - Model "shaman_miyeom.GR2" - SourceSkin "shaman_miyeom.dds" - TargetSkin "shaman_ilseon.dds" - } - Group ShapeData08 - { - ShapeIndex 9 - Model "shaman_cheonryun.GR2" - SourceSkin "shaman_cheonryun.dds" - TargetSkin "shaman_cheonryun.dds" - } - Group ShapeData09 - { - ShapeIndex 10 - Model "shaman_cheonryun.GR2" - SourceSkin "shaman_cheonryun.dds" - TargetSkin "shaman_amyo.dds" - } - Group ShapeData10 - { - ShapeIndex 11 - Model "shaman_bongsin.GR2" - SourceSkin "shaman_bongsin.dds" - TargetSkin "shaman_bongsin.dds" - } - Group ShapeData11 - { - SpecialPath "d:/ymir work/monster/wolf/" - - ShapeIndex 100 - Model "wolf.gr2" - SourceSkin "wolf.dds" - } - Group ShapeData12 - { - SpecialPath "d:/ymir work/monster/wild_boar/" - - ShapeIndex 101 - Model "wild_boar.gr2" - SourceSkin "wild_boar.dds" - } - Group ShapeData13 - { - SpecialPath "d:/ymir work/monster/bear/" - - ShapeIndex 102 - Model "bear.gr2" - SourceSkin "bear.dds" - } - Group ShapeData14 - { - SpecialPath "d:/ymir work/monster/tiger/" - - ShapeIndex 103 - Model "tiger.gr2" - SourceSkin "tiger.dds" - } - Group ShapeData15 - { - SpecialPath "d:/ymir Work/pc/shaman/" - - ShapeIndex 201 - Model "shaman_marry_01.gr2" - SourceSkin "shaman_marry_01.dds" - TargetSkin "shaman_marry_01.dds" - } - Group ShapeData16 - { - ShapeIndex 12 - Model "shaman_4-1.GR2" - SourceSkin "shaman_4-1.dds" - TargetSkin "shaman_4-1.dds" - } - - - Group ShapeData17 - { - ShapeIndex 14 - Model "shaman_cheongnang.GR2" - SourceSkin "shaman_cheongnang.dds" - TargetSkin "shaman_1-1cheongnang_a.DDS" - } - Group ShapeData18 - { - ShapeIndex 15 - Model "shaman_cheongnang.GR2" - SourceSkin "shaman_cheongnang.dds" - TargetSkin "shaman_1-2_nabong_a.DDS" - } - Group ShapeData19 - { - ShapeIndex 16 - Model "shaman_cheongnang.GR2" - SourceSkin "shaman_cheongnang.dds" - TargetSkin "shaman_bihong_a.dds" - } - Group ShapeData20 - { - ShapeIndex 17 - Model "shaman_miyeom.GR2" - SourceSkin "shaman_miyeom.dds" - TargetSkin "shaman_2-1_miyeon_a.DDS" - } - Group ShapeData21 - { - ShapeIndex 18 - Model "shaman_miyeom.GR2" - SourceSkin "shaman_miyeom.dds" - TargetSkin "shaman_2-2_seocheon_a.DDS" - } - Group ShapeData22 - { - ShapeIndex 19 - Model "shaman_miyeom.GR2" - SourceSkin "shaman_miyeom.dds" - TargetSkin "shaman_2-3_ilseon_a.DDS" - } - Group ShapeData23 - { - ShapeIndex 20 - Model "shaman_cheonryun.GR2" - SourceSkin "shaman_cheonryun.dds" - TargetSkin "shaman_3-1_cheonryun_a.DDS" - } - Group ShapeData24 - { - ShapeIndex 21 - Model "shaman_cheonryun.GR2" - SourceSkin "shaman_cheonryun.dds" - TargetSkin "shaman_3-2_amyo_a.DDS" - } - Group ShapeData25 - { - SpecialPath "d:/ymir Work/pc/shaman/" - - ShapeIndex 24 - Model "shaman_lord.GR2" - SourceSkin "shaman_queen01.dds" - TargetSkin "shaman_queen01.dds" - } - Group ShapeData26 - { - SpecialPath "d:/ymir Work/pc/shaman/" - - ShapeIndex 25 - Model "shaman_lord.GR2" - SourceSkin "shaman_queen01.dds" - TargetSkin "shaman_queen02.dds" - } - - Group ShapeData27 - { - SpecialPath "d:/ymir Work/pc/shaman/" - - ShapeIndex 26 - Model "shaman_4-1.GR2" - SourceSkin "shaman_4-1.dds" - TargetSkin "shaman_4-2.dds" - } - Group ShapeData28 - { - ShapeIndex 27 - Model "shaman_event1.GR2" - SourceSkin "shaman_event1_yellow.dds" - TargetSkin "shaman_event1_red.dds" - } - Group ShapeData29 - { - - ShapeIndex 28 - Model "shaman_event1.GR2" - SourceSkin "shaman_event1_yellow.dds" - TargetSkin "shaman_event1_yellow.dds" - } - Group ShapeData30 - { - - ShapeIndex 29 - Model "shaman_event1.GR2" - SourceSkin "shaman_event1_yellow.dds" - TargetSkin "shaman_event1_blue.dds" - } - Group ShapeData31 - { - ShapeIndex 30 - Model "shaman_cheongnang.gr2" - SourceSkin "shaman_cheongnang.dds" - TargetSkin "shaman_costume1.dds" - } - Group ShapeData32 - { - ShapeIndex 40031 - Model "shaman_rabbit1.GR2" - SourceSkin "shaman_rabbit1.dds" - TargetSkin "shaman_rabbit1.dds" - } - Group ShapeData33 - { - ShapeIndex 40033 - Model "shaman_fencing1_Germany.GR2" - SourceSkin "shaman_fencing1_Germany.dds" - TargetSkin "shaman_fencing1_London.dds" - } - Group ShapeData34 - { - ShapeIndex 40034 - Model "shaman_fencing1_Germany.GR2" - SourceSkin "shaman_fencing1_Germany.dds" - TargetSkin "shaman_fencing1_Germany.dds" - } - Group ShapeData35 - { - ShapeIndex 40035 - Model "shaman_fencing1_Germany.GR2" - SourceSkin "shaman_fencing1_Germany.dds" - TargetSkin "shaman_fencing1_Turkey.dds" - } - Group ShapeData36 - { - ShapeIndex 40036 - Model "shaman_fencing1_Germany.GR2" - SourceSkin "shaman_fencing1_Germany.dds" - TargetSkin "shaman_fencing1_Brazil.dds" - } - Group ShapeData37 - { - ShapeIndex 40037 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_soccer1_London.dds" - } - Group ShapeData38 - { - ShapeIndex 40038 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_soccer1_Germany.dds" - } - Group ShapeData39 - { - ShapeIndex 40039 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_soccer1_Turkey.dds" - } - Group ShapeData40 - { - ShapeIndex 40040 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_soccer1_Brazil.dds" - } - Group ShapeData41 - { - ShapeIndex 40041 - Model "shaman_boxing1_Germany.GR2" - SourceSkin "shaman_boxing1_Germany.dds" - TargetSkin "shaman_boxing1_London.dds" - } - Group ShapeData42 - { - ShapeIndex 40042 - Model "shaman_boxing1_Germany.GR2" - SourceSkin "shaman_boxing1_Germany.dds" - TargetSkin "shaman_boxing1_Germany.dds" - } - Group ShapeData43 - { - ShapeIndex 40043 - Model "shaman_boxing1_Germany.GR2" - SourceSkin "shaman_boxing1_Germany.dds" - TargetSkin "shaman_boxing1_Turkey.dds" - } - Group ShapeData44 - { - ShapeIndex 40044 - Model "shaman_boxing1_Germany.GR2" - SourceSkin "shaman_boxing1_Germany.dds" - TargetSkin "shaman_boxing1_Brazil.dds" - } - Group ShapeData45 - { - ShapeIndex 40032 - Model "shaman_assasin1.GR2" - SourceSkin "shaman_assassin1.dds" - TargetSkin "shaman_assassin1.dds" - } - Group ShapeData46 - { - ShapeIndex 40045 - Model "shaman_fencing1_Germany.GR2" - SourceSkin "shaman_fencing1_Germany.dds" - TargetSkin "shaman_fencing1_France.dds" - } - Group ShapeData47 - { - ShapeIndex 40046 - Model "shaman_fencing1_Germany.GR2" - SourceSkin "shaman_fencing1_Germany.dds" - TargetSkin "shaman_fencing1_Italy.dds" - } - Group ShapeData48 - { - ShapeIndex 40047 - Model "shaman_fencing1_Germany.GR2" - SourceSkin "shaman_fencing1_Germany.dds" - TargetSkin "shaman_fencing1_Poland.dds" - } - Group ShapeData49 - { - ShapeIndex 40048 - Model "shaman_fencing1_Germany.GR2" - SourceSkin "shaman_fencing1_Germany.dds" - TargetSkin "shaman_fencing1_Romania.dds" - } - Group ShapeData50 - { - ShapeIndex 40049 - Model "shaman_fencing1_Germany.GR2" - SourceSkin "shaman_fencing1_Germany.dds" - TargetSkin "shaman_fencing1_Spain.dds" - } - Group ShapeData51 - { - ShapeIndex 40050 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_soccer1_France.dds" - } - Group ShapeData52 - { - ShapeIndex 40051 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_soccer1_Italy.dds" - } - Group ShapeData53 - { - ShapeIndex 40052 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_soccer1_Poland.dds" - } - Group ShapeData54 - { - ShapeIndex 40053 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_soccer1_Romania.dds" - } - Group ShapeData55 - { - ShapeIndex 40054 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_soccer1_Spain.dds" - } - Group ShapeData56 - { - ShapeIndex 40055 - Model "shaman_boxing1_Germany.GR2" - SourceSkin "shaman_boxing1_Germany.dds" - TargetSkin "shaman_boxing1_France.dds" - } - Group ShapeData57 - { - ShapeIndex 40056 - Model "shaman_boxing1_Germany.GR2" - SourceSkin "shaman_boxing1_Germany.dds" - TargetSkin "shaman_boxing1_Italy.dds" - } - Group ShapeData58 - { - ShapeIndex 40057 - Model "shaman_boxing1_Germany.GR2" - SourceSkin "shaman_boxing1_Germany.dds" - TargetSkin "shaman_boxing1_Poland.dds" - } - Group ShapeData59 - { - ShapeIndex 40058 - Model "shaman_boxing1_Germany.GR2" - SourceSkin "shaman_boxing1_Germany.dds" - TargetSkin "shaman_boxing1_Romania.dds" - - } - Group ShapeData60 - { - ShapeIndex 40059 - Model "shaman_boxing1_Germany.GR2" - SourceSkin "shaman_boxing1_Germany.dds" - TargetSkin "shaman_boxing1_Spain.dds" - - } - Group ShapeData61 - { - ShapeIndex 40065 - Model "shaman_halloween1.GR2" - SourceSkin "shaman_halloween1.dds" - TargetSkin "shaman_halloween1.dds" - - } - Group ShapeData62 - { - ShapeIndex 13 - Model "shaman_5_1.GR2" - SourceSkin "shaman_5_1.dds" - TargetSkin "shaman_5_1.dds" - } - Group ShapeData63 - { - ShapeIndex 40062 - Model "shaman_salsa1.GR2" - SourceSkin "shaman_salsa1.dds" - TargetSkin "shaman_salsa1.dds" - } - Group ShapeData64 - { - ShapeIndex 40063 - Model "shaman_Springwear1.GR2" - SourceSkin "shaman_Springwear1.dds" - TargetSkin "shaman_Springwear1.dds" - } - Group ShapeData65 - { - ShapeIndex 40061 - Model "shaman_tailcoat1.GR2" - SourceSkin "shaman_tailcoat1.dds" - TargetSkin "shaman_tailcoat1.dds" - } - Group ShapeData66 - { - ShapeIndex 40069 - Model "shaman_deer1.gr2" - SourceSkin "shaman_deer1.dds" - TargetSkin "shaman_deer1.dds" - } - Group ShapeData67 - { - ShapeIndex 40066 - Model "shaman_santa1_black.gr2" - SourceSkin "shaman_santa1_black.dds" - TargetSkin "shaman_santa1_red.dds" - } - Group ShapeData68 - { - ShapeIndex 40067 - Model "shaman_santa1_black.gr2" - SourceSkin "shaman_santa1_black.dds" - TargetSkin "shaman_santa1_green.dds" - } - Group ShapeData69 - { - ShapeIndex 40068 - Model "shaman_santa1_black.gr2" - SourceSkin "shaman_santa1_black.dds" - TargetSkin "shaman_santa1_black.dds" - } - Group ShapeData70 - { - ShapeIndex 40070 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA01.dds" - } - Group ShapeData71 - { - ShapeIndex 40071 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA02.dds" - } - Group ShapeData72 - { - ShapeIndex 40072 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA03.dds" - } - Group ShapeData73 - { - ShapeIndex 40073 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA04.dds" - } - Group ShapeData74 - { - ShapeIndex 40074 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA05.dds" - } - Group ShapeData75 - { - ShapeIndex 40075 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA06.dds" - } - Group ShapeData76 - { - ShapeIndex 40076 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA07.dds" - } - Group ShapeData77 - { - ShapeIndex 40077 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA08.dds" - } - Group ShapeData78 - { - ShapeIndex 40078 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA09.dds" - } - Group ShapeData79 - { - ShapeIndex 40079 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA10.dds" - } - Group ShapeData80 - { - ShapeIndex 40080 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA11.dds" - } - Group ShapeData81 - { - ShapeIndex 40081 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA12.dds" - } - Group ShapeData82 - { - ShapeIndex 40082 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA13.dds" - } - Group ShapeData83 - { - ShapeIndex 40083 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA14.dds" - } - Group ShapeData84 - { - ShapeIndex 40084 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA15.dds" - } - Group ShapeData85 - { - ShapeIndex 40085 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA16.dds" - } - Group ShapeData86 - { - ShapeIndex 40086 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA17.dds" - } - Group ShapeData87 - { - ShapeIndex 40087 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA18.dds" - } - Group ShapeData88 - { - ShapeIndex 40088 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA19.dds" - } - Group ShapeData89 - { - ShapeIndex 40089 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA20.dds" - } - Group ShapeData90 - { - ShapeIndex 40090 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA21.dds" - } - Group ShapeData91 - { - ShapeIndex 40091 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA22.dds" - } - Group ShapeData92 - { - ShapeIndex 40092 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA23.dds" - } - Group ShapeData93 - { - ShapeIndex 40093 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA24.dds" - } - Group ShapeData94 - { - ShapeIndex 40094 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA25.dds" - } - Group ShapeData95 - { - ShapeIndex 40095 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA26.dds" - } - Group ShapeData96 - { - ShapeIndex 40096 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA27.dds" - } - Group ShapeData97 - { - ShapeIndex 40097 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA28.dds" - } - Group ShapeData98 - { - ShapeIndex 40098 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA29.dds" - } - Group ShapeData99 - { - ShapeIndex 40099 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA30.dds" - } - Group ShapeData100 - { - ShapeIndex 40100 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA31.dds" - } - Group ShapeData101 - { - ShapeIndex 40101 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_UEFA32.dds" - } - Group ShapeData102 - { - ShapeIndex 40064 - Model "shaman_samurai1.GR2" - SourceSkin "shaman_samurai1.dds" - TargetSkin "shaman_samurai1.dds" - } - Group ShapeData103 - { - ShapeIndex 40106 - Model "shaman_rabbit1.GR2" - SourceSkin "shaman_rabbit1.dds" - TargetSkin "shaman_rabbit1_black.dds" - } - Group ShapeData104 - { - ShapeIndex 40107 - Model "shaman_rabbit1.GR2" - SourceSkin "shaman_rabbit1.dds" - TargetSkin "shaman_rabbit1_blue.dds" - } - Group ShapeData105 - { - ShapeIndex 40108 - Model "shaman_rabbit1.GR2" - SourceSkin "shaman_rabbit1.dds" - TargetSkin "shaman_rabbit1_green.dds" - } - Group ShapeData106 - { - ShapeIndex 40109 - Model "shaman_rabbit1.GR2" - SourceSkin "shaman_rabbit1.dds" - TargetSkin "shaman_rabbit1_pink.dds" - } - Group ShapeData107 - { - ShapeIndex 40110 - Model "shaman_BlackSnake1.GR2" - SourceSkin "shaman_BlackSnake1.dds" - TargetSkin "shaman_BlackSnake1.dds" - } - Group ShapeData108 - { - ShapeIndex 40111 - Model "shaman_BlackSnake1.GR2" - SourceSkin "shaman_BlackSnake1.dds" - TargetSkin "shaman_BlackSnake1.dds" - } - Group ShapeData109 - { - ShapeIndex 40113 - Model "shaman_assasin1.GR2" - SourceSkin "shaman_assassin1.dds" - TargetSkin "shaman_assassin2.dds" - } - Group ShapeData110 - { - ShapeIndex 40115 - Model "shaman_pwahuang1.GR2" - SourceSkin "shaman_pwahuang1.dds" - TargetSkin "shaman_pwahuang1.dds" - } - Group ShapeData111 - { - ShapeIndex 40117 - Model "shaman_halloween2.GR2" - SourceSkin "shaman_halloween2.dds" - TargetSkin "shaman_halloween2.dds" - } - Group ShapeData112 - { - ShapeIndex 40119 - Model "shaman_assasin1.GR2" - SourceSkin "shaman_assassin1.dds" - TargetSkin "shaman_assassin3.dds" - } - Group ShapeData113 - { - ShapeIndex 40060 - Model "shaman_capoeira1.GR2" - SourceSkin "shaman_capoeira1.dds" - TargetSkin "shaman_capoeira1.dds" - } - Group ShapeData114 - { - ShapeIndex 40121 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC01.dds" - } - Group ShapeData115 - { - ShapeIndex 40123 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC02.dds" - } - Group ShapeData116 - { - ShapeIndex 40125 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC03.dds" - } - Group ShapeData117 - { - ShapeIndex 40127 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC04.dds" - } - Group ShapeData118 - { - ShapeIndex 40129 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC05.dds" - } - Group ShapeData119 - { - ShapeIndex 40131 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC06.dds" - } - Group ShapeData120 - { - ShapeIndex 40133 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC07.dds" - } - Group ShapeData121 - { - ShapeIndex 40135 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC08.dds" - } - Group ShapeData122 - { - ShapeIndex 40137 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC09.dds" - } - Group ShapeData123 - { - ShapeIndex 40139 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC10.dds" - } - Group ShapeData124 - { - ShapeIndex 40141 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC11.dds" - } - Group ShapeData125 - { - ShapeIndex 40143 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC12.dds" - } - Group ShapeData126 - { - ShapeIndex 40145 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC13.dds" - } - Group ShapeData127 - { - ShapeIndex 40147 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC14.dds" - } - Group ShapeData128 - { - ShapeIndex 40149 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC15.dds" - } - Group ShapeData129 - { - ShapeIndex 40151 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC16.dds" - } - Group ShapeData130 - { - ShapeIndex 40153 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC17.dds" - } - Group ShapeData131 - { - ShapeIndex 40155 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC18.dds" - } - Group ShapeData132 - { - ShapeIndex 40157 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC19.dds" - } - Group ShapeData133 - { - ShapeIndex 40159 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC20.dds" - } - Group ShapeData134 - { - ShapeIndex 40161 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC21.dds" - } - Group ShapeData135 - { - ShapeIndex 40163 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC22.dds" - } - Group ShapeData136 - { - ShapeIndex 40165 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC23.dds" - } - Group ShapeData137 - { - ShapeIndex 40167 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC24.dds" - } - Group ShapeData138 - { - ShapeIndex 40169 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC25.dds" - } - Group ShapeData139 - { - ShapeIndex 40171 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC26.dds" - } - Group ShapeData140 - { - ShapeIndex 40173 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC27.dds" - } - Group ShapeData141 - { - ShapeIndex 40175 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC28.dds" - } - Group ShapeData142 - { - ShapeIndex 40177 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC29.dds" - } - Group ShapeData143 - { - ShapeIndex 40179 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC30.dds" - } - Group ShapeData144 - { - ShapeIndex 40181 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC31.dds" - } - Group ShapeData145 - { - ShapeIndex 40183 - Model "shaman_soccer1_Germany.GR2" - SourceSkin "shaman_soccer1_Germany.dds" - TargetSkin "shaman_WC32.dds" - } -} -Group AttachingData -{ - AttachingDataCount 2 - - Group AttachingData00 - { - AttachingDataType 1 - - isAttaching 0 - AttachingModelIndex 0 - AttachingBoneName "Bip01" - - CollisionType 1 - - SphereDataCount 1 - Group SphereData00 - { - Radius 40.000000 - Position 0.000000 0.000000 90.000000 - } - } - - Group AttachingData01 - { - AttachingDataType 1 - - isAttaching 0 - AttachingModelIndex 0 - AttachingBoneName "Bip01" - - CollisionType 3 - - SphereDataCount 1 - Group SphereData00 - { - Radius 70.000000 - Position 0.000000 0.000000 90.000000 - } - } -} diff --git a/tools/root/msm/sura_m.msm b/tools/root/msm/sura_m.msm deleted file mode 100644 index 0dfffe1e..00000000 --- a/tools/root/msm/sura_m.msm +++ /dev/null @@ -1,1593 +0,0 @@ -ScriptType RaceDataScript - -BaseModelFileName "D:/YMIR WORK/pc/sura/sura_novice.GR2" - -Group HairData -{ - PathName "d:/ymir Work/pc/sura/" - - HairDataCount 61 - Group HairData00 - { - HairIndex 0 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "sura_hair_01.dds" - } - Group HairData01 - { - HairIndex 1 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "sura_hair_01_white.dds" - } - Group HairData02 - { - HairIndex 2 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "sura_hair_01_gold.dds" - } - Group HairData03 - { - HairIndex 3 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "sura_hair_01_red.dds" - } - Group HairData04 - { - HairIndex 4 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "sura_hair_01_brown.dds" - } - Group HairData05 - { - HairIndex 5 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "sura_hair_01_black.dds" - } - Group HairData06 - { - HairIndex 3001 - Model "hair/hair_2_1.gr2" - SourceSkin "hair/hair_2_1.dds" - TargetSkin "hair/hair_2_1.dds" - } - Group HairData07 - { - HairIndex 3002 - Model "hair/hair_2_2.gr2" - SourceSkin "hair/hair_2_2.dds" - TargetSkin "hair/hair_2_2.dds" - } - Group HairData08 - { - HairIndex 3003 - Model "hair/hair_2_3.gr2" - SourceSkin "hair/hair_2_3.dds" - TargetSkin "hair/hair_2_3.dds" - } - Group HairData09 - { - HairIndex 3004 - Model "hair/hair_2_4.gr2" - SourceSkin "hair/hair_2_4.dds" - TargetSkin "hair/hair_2_4.dds" - } - Group HairData10 - { - HairIndex 3005 - Model "hair/hair_3_1.gr2" - SourceSkin "hair/hair_3_1.dds" - TargetSkin "hair/hair_3_1.dds" - } - Group HairData11 - { - HairIndex 3006 - Model "hair/hair_3_2.gr2" - SourceSkin "hair/hair_3_2.dds" - TargetSkin "hair/hair_3_2.dds" - } - Group HairData12 - { - HairIndex 3007 - Model "hair/hair_3_3.gr2" - SourceSkin "hair/hair_3_3.dds" - TargetSkin "hair/hair_3_3.dds" - } - Group HairData13 - { - HairIndex 3008 - Model "hair/hair_3_4.gr2" - SourceSkin "hair/hair_3_4.dds" - TargetSkin "hair/hair_3_4.dds" - } - Group HairData14 - { - HairIndex 3009 - Model "hair/hair_4_1.gr2" - SourceSkin "hair/hair_4_1.dds" - TargetSkin "hair/hair_4_1.dds" - } - Group HairData15 - { - HairIndex 3010 - Model "hair/hair_4_2.gr2" - SourceSkin "hair/hair_4_2.dds" - TargetSkin "hair/hair_4_2.dds" - } - Group HairData16 - { - HairIndex 3011 - Model "hair/hair_4_3.gr2" - SourceSkin "hair/hair_4_3.dds" - TargetSkin "hair/hair_4_3.dds" - } - Group HairData17 - { - HairIndex 3012 - Model "hair/hair_4_4.gr2" - SourceSkin "hair/hair_4_4.dds" - TargetSkin "hair/hair_4_4.dds" - } - Group HairData18 - { - HairIndex 3013 - Model "hair/hair_6_1.gr2" - SourceSkin "hair/hair_6_1.dds" - TargetSkin "hair/hair_6_1.dds" - } - Group HairData19 - { - HairIndex 3014 - Model "hair/hair_5_1.gr2" - SourceSkin "hair/hair_5_1.dds" - TargetSkin "hair/hair_5_1.dds" - } - Group HairData20 - { - HairIndex 3015 - Model "hair/hair_7_1.gr2" - SourceSkin "hair/hair_7_1.dds" - TargetSkin "hair/hair_7_1.dds" - } - Group HairData21 - { - HairIndex 3016 - Model "hair/hair_8_1.gr2" - SourceSkin "hair/hair_8_1.dds" - TargetSkin "hair/hair_8_1.dds" - } - Group HairData22 - { - HairIndex 3017 - Model "hair/hair_9_1.gr2" - SourceSkin "hair/hair_9_1.dds" - TargetSkin "hair/hair_9_1.dds" - } - Group HairData23 - { - HairIndex 3018 - Model "hair/hair_10_1.gr2" - SourceSkin "hair/hair_10_1.dds" - TargetSkin "hair/hair_10_1.dds" - } - Group HairData24 - { - HairIndex 5001 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_1.dds" - } - Group HairData25 - { - HairIndex 5002 - Model "hair/hair_14_1.gr2" - SourceSkin "hair/hair_14_1.dds" - TargetSkin "hair/hair_14_1.dds" - } - Group HairData26 - { - HairIndex 5005 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_1.dds" - } - Group HairData27 - { - HairIndex 5003 - Model "hair/hair_16_1.gr2" - SourceSkin "hair/hair_16_1.dds" - TargetSkin "hair/hair_16_1.dds" - } - Group HairData28 - { - HairIndex 5004 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_1.dds" - } - Group HairData29 - { - HairIndex 5027 - Model "hair/hair_20_1.gr2" - SourceSkin "hair/hair_20_1.dds" - TargetSkin "hair/hair_20_1.dds" - } - Group HairData30 - { - HairIndex 5023 - Model "hair/hair_13_1.gr2" - SourceSkin "hair/hair_13_1.dds" - TargetSkin "hair/hair_13_1.dds" - } - Group HairData31 - { - HairIndex 5024 - Model "hair/hair_18_1.gr2" - SourceSkin "hair/hair_18_1.dds" - TargetSkin "hair/hair_18_1.dds" - } - Group HairData32 - { - HairIndex 5025 - Model "hair/hair_19_1.gr2" - SourceSkin "hair/hair_19_1.dds" - TargetSkin "hair/hair_19_1.dds" - } - Group HairData33 - { - HairIndex 5028 - Model "hair/hair_22_1.gr2" - SourceSkin "hair/hair_22_1.dds" - TargetSkin "hair/hair_22_3.dds" - } - Group HairData34 - { - HairIndex 5029 - Model "hair/hair_22_1.gr2" - SourceSkin "hair/hair_22_1.dds" - TargetSkin "hair/hair_22_2.dds" - } - Group HairData35 - { - HairIndex 5030 - Model "hair/hair_22_1.gr2" - SourceSkin "hair/hair_22_1.dds" - TargetSkin "hair/hair_22_1.dds" - } - Group HairData36 - { - HairIndex 5031 - Model "hair/hair_23_1.gr2" - SourceSkin "hair/hair_23_1.dds" - TargetSkin "hair/hair_23_1.dds" - } - Group HairData37 - { - HairIndex 5033 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_1.dds" - } - Group HairData38 - { - HairIndex 5035 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_2.dds" - } - Group HairData39 - { - HairIndex 5037 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_3.dds" - } - Group HairData40 - { - HairIndex 5039 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_4.dds" - } - Group HairData41 - { - HairIndex 5041 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_5.dds" - } - Group HairData42 - { - HairIndex 5026 - Model "hair/hair_21_1.gr2" - SourceSkin "hair/hair_21_1.dds" - TargetSkin "hair/hair_21_1.dds" - } - Group HairData43 - { - HairIndex 5045 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_2.dds" - } - Group HairData44 - { - HairIndex 5046 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_3.dds" - } - Group HairData45 - { - HairIndex 5047 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_4.dds" - } - Group HairData46 - { - HairIndex 5048 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_5.dds" - } - Group HairData47 - { - HairIndex 5049 - Model "hair/hair_28_1.gr2" - SourceSkin "hair/hair_28_1.dds" - TargetSkin "hair/hair_28_1.dds" - } - Group HairData48 - { - HairIndex 5050 - Model "hair/hair_28_1.gr2" - SourceSkin "hair/hair_28_1.dds" - TargetSkin "hair/hair_28_1.dds" - } - Group HairData49 - { - HairIndex 5051 - Model "hair/hair_29_1.gr2" - SourceSkin "hair/hair_29_1.dds" - TargetSkin "hair/hair_29_1.dds" - } - Group HairData50 - { - HairIndex 5052 - Model "hair/hair_30_1.gr2" - SourceSkin "hair/hair_30_1.dds" - TargetSkin "hair/hair_30_1.dds" - } - Group HairData51 - { - HairIndex 5053 - Model "hair/hair_31_1.gr2" - SourceSkin "hair/hair_31_1.dds" - TargetSkin "hair/hair_31_1.dds" - } - Group HairData52 - { - HairIndex 5054 - Model "hair/hair_32_1.gr2" - SourceSkin "hair/hair_32_1.dds" - TargetSkin "hair/hair_32_1.dds" - } - Group HairData53 - { - HairIndex 5055 - Model "hair/hair_14_1.gr2" - SourceSkin "hair/hair_14_1.dds" - TargetSkin "hair/hair_14_2.dds" - } - Group HairData54 - { - HairIndex 5057 - Model "hair/hair_33_1.gr2" - SourceSkin "hair/hair_33_1.dds" - TargetSkin "hair/hair_33_1.dds" - } - Group HairData55 - { - HairIndex 5059 - Model "hair/hair_34_1.gr2" - SourceSkin "hair/hair_34_1.dds" - TargetSkin "hair/hair_34_1.dds" - } - Group HairData56 - { - HairIndex 5061 - Model "hair/hair_35_1.gr2" - SourceSkin "hair/hair_35_1.dds" - TargetSkin "hair/hair_35_1.dds" - } - Group HairData57 - { - HairIndex 5063 - Model "hair/hair_37_1.gr2" - SourceSkin "hair/hair_37_1.dds" - TargetSkin "hair/hair_37_1.dds" - } - Group HairData58 - { - HairIndex 5064 - Model "hair/hair_36_1.gr2" - SourceSkin "hair/hair_36_1.dds" - TargetSkin "hair/hair_36_1.dds" - } - Group HairData59 - { - HairIndex 5065 - Model "hair/hair_38_1.gr2" - SourceSkin "hair/hair_38_1.dds" - TargetSkin "hair/hair_38_1.dds" - } - Group HairData60 - { - HairIndex 5022 - Model "hair/hair_12_1.gr2" - SourceSkin "hair/hair_12_1.dds" - TargetSkin "hair/hair_12_1.dds" - } -} - -Group ShapeData -{ - PathName "d:/ymir Work/pc/sura/" - - ShapeDataCount 146 - - Group ShapeData00 - { - ShapeIndex 0 - - Model "sura_novice.GR2" - SourceSkin "sura_novice_black.dds" - TargetSkin "sura_novice_black.dds" - } - Group ShapeData01 - { - ShapeIndex 1 - - Model "sura_novice.GR2" - SourceSkin "sura_novice_black.dds" - TargetSkin "sura_novice_blue.dds" - } - Group ShapeData02 - { - ShapeIndex 3 - Model "sura_jinhon.GR2" - SourceSkin "sura_jinhon.dds" - TargetSkin "sura_jinhon.dds" - } - Group ShapeData03 - { - ShapeIndex 4 - Model "sura_jinhon.GR2" - SourceSkin "sura_jinhon.dds" - TargetSkin "sura_mageuk.dds" - } - Group ShapeData04 - { - ShapeIndex 5 - Model "sura_jinhon.GR2" - SourceSkin "sura_jinhon.dds" - TargetSkin "sura_biun.dds" - } - Group ShapeData05 - { - ShapeIndex 6 - Model "sura_saryeong.GR2" - SourceSkin "sura_saryeong.dds" - TargetSkin "sura_saryeong.dds" - - SourceSkin2 "sura_saryeong_cloak.dds" - TargetSkin2 "sura_saryeong_cloak.dds" - } - Group ShapeData06 - { - ShapeIndex 7 - Model "sura_saryeong.GR2" - SourceSkin "sura_saryeong.dds" - TargetSkin "sura_eumyang.dds" - - SourceSkin2 "sura_saryeong_cloak.dds" - TargetSkin2 "sura_saryeong_cloak.dds" - } - Group ShapeData07 - { - ShapeIndex 8 - Model "sura_saryeong.GR2" - SourceSkin "sura_saryeong.dds" - TargetSkin "sura_heukbi.dds" - - SourceSkin2 "sura_saryeong_cloak.dds" - TargetSkin2 "sura_saryeong_cloak.dds" - } - Group ShapeData08 - { - ShapeIndex 9 - Model "sura_unra.GR2" - SourceSkin "sura_unra.dds" - TargetSkin "sura_unra.dds" - - SourceSkin2 "sura_unra_cloak.dds" - TargetSkin2 "sura_unra_cloak.dds" - } - Group ShapeData09 - { - ShapeIndex 10 - Model "sura_unra.GR2" - SourceSkin "sura_unra.dds" - TargetSkin "sura_gwimyeon.dds" - - SourceSkin2 "sura_unra_cloak.dds" - TargetSkin2 "sura_unra_cloak.dds" - - } - Group ShapeData10 - { - ShapeIndex 11 - Model "sura_maryeong.GR2" - SourceSkin "sura_maryeong.dds" - TargetSkin "sura_maryeong.dds" - - SourceSkin2 "sura_unra_cloak.dds" - TargetSkin2 "sura_unra_cloak.dds" - - } - Group ShapeData11 - { - SpecialPath "d:/ymir work/monster/wolf/" - - ShapeIndex 100 - Model "wolf.gr2" - SourceSkin "wolf.dds" - } - Group ShapeData12 - { - SpecialPath "d:/ymir work/monster/wild_boar/" - - ShapeIndex 101 - Model "wild_boar.gr2" - SourceSkin "wild_boar.dds" - } - Group ShapeData13 - { - SpecialPath "d:/ymir work/monster/bear/" - - ShapeIndex 102 - Model "bear.gr2" - SourceSkin "bear.dds" - } - Group ShapeData14 - { - SpecialPath "d:/ymir work/monster/tiger/" - - ShapeIndex 103 - Model "tiger.gr2" - SourceSkin "tiger.dds" - } - Group ShapeData15 - { - SpecialPath "d:/ymir work/pc/sura/" - - ShapeIndex 201 - Model "sura_marry_01.gr2" - SourceSkin "sura_marry_01.dds" - TargetSkin "sura_marry_01.dds" - } - Group ShapeData16 - { - ShapeIndex 12 - Model "sura_4-1.GR2" - SourceSkin "sura_4-1.dds" - TargetSkin "sura_4-1.dds" - } - - - Group ShapeData17 - { - ShapeIndex 14 - Model "sura_jinhon.GR2" - SourceSkin "sura_jinhon.dds" - TargetSkin "sura_1-1_jinhon copy_a.DDS" - } - Group ShapeData18 - { - ShapeIndex 15 - Model "sura_jinhon.GR2" - SourceSkin "sura_jinhon.dds" - TargetSkin "sura_1-2_mageuk_a.DDS" - } - Group ShapeData19 - { - ShapeIndex 16 - Model "sura_jinhon.GR2" - SourceSkin "sura_jinhon.dds" - TargetSkin "sura_1-3_biun_a.DDS" - } - - Group ShapeData20 - { - ShapeIndex 17 - Model "sura_saryeong.GR2" - SourceSkin "sura_saryeong.dds" - TargetSkin "sura_2-1_saryeong_a.DDS" - } - Group ShapeData21 - { - ShapeIndex 18 - Model "sura_saryeong.GR2" - SourceSkin "sura_saryeong.dds" - TargetSkin "sura_2-2_eumyang_a.DDS" - } - Group ShapeData22 - { - ShapeIndex 19 - Model "sura_saryeong.GR2" - SourceSkin "sura_saryeong.dds" - TargetSkin "sura_2-3_heukbi_a.DDS" - } - Group ShapeData23 - { - ShapeIndex 20 - Model "sura_unra.GR2" - SourceSkin "sura_unra.dds" - TargetSkin "sura_3-1_unra_a.DDS" - - SourceSkin2 "sura_unra_cloak.dds" - TargetSkin2 "sura_unra_cloak.dds" - } - Group ShapeData24 - { - ShapeIndex 22 - Model "sura_maryeong.GR2" - SourceSkin "sura_maryeong.dds" - TargetSkin "sura_maryung_a.DDS" - } - Group ShapeData25 - { - SpecialPath "d:/ymir work/pc/sura/" - ShapeIndex 24 - Model "sura_lord.GR2" - SourceSkin "sura_king01.dds" - TargetSkin "sura_king01.dds" - - SourceSkin2 "sura_king01_cloak.dds" - TargetSkin2 "sura_king01_cloak.dds" - - - } - Group ShapeData26 - { - SpecialPath "d:/ymir work/pc/sura/" - ShapeIndex 25 - Model "sura_lord.GR2" - SourceSkin "sura_king01.dds" - TargetSkin "sura_king02.dds" - - SourceSkin2 "sura_king02_cloak.dds" - TargetSkin2 "sura_king02_cloak.dds" - } - - Group ShapeData27 - { - SpecialPath "d:/ymir work/pc/sura/" - ShapeIndex 26 - Model "sura_4-1.GR2" - SourceSkin "sura_4-1.dds" - TargetSkin "sura_4-2.dds" - } - Group ShapeData28 - { - - ShapeIndex 27 - Model "sura_event1.GR2" - SourceSkin "sura_event1_yellow.dds" - TargetSkin "sura_event1_red.dds" - } - Group ShapeData29 - { - - ShapeIndex 28 - Model "sura_event1.GR2" - SourceSkin "sura_event1_yellow.dds" - TargetSkin "sura_event1_yellow.dds" - } - Group ShapeData30 - { - - ShapeIndex 29 - Model "sura_event1.GR2" - SourceSkin "sura_event1_yellow.dds" - TargetSkin "sura_event1_blue.dds" - } - Group ShapeData31 - { - - ShapeIndex 30 - Model "sura_jinhon.gr2" - SourceSkin "sura_jinhon.dds" - TargetSkin "sura_costume1.dds" - } - Group ShapeData32 - { - - ShapeIndex 40031 - Model "sura_rabbit1.GR2" - SourceSkin "sura_rabbit1.dds" - TargetSkin "sura_rabbit1.dds" - } - Group ShapeData33 - { - - ShapeIndex 40033 - Model "sura_fencing1_Germany.GR2" - SourceSkin "sura_fencing1_Germany.dds" - TargetSkin "sura_fencing1_London.dds" - } - Group ShapeData34 - { - - ShapeIndex 40034 - Model "sura_fencing1_Germany.GR2" - SourceSkin "sura_fencing1_Germany.dds" - TargetSkin "sura_fencing1_Germany.dds" - } - Group ShapeData35 - { - - ShapeIndex 40035 - Model "sura_fencing1_Germany.GR2" - SourceSkin "sura_fencing1_Germany.dds" - TargetSkin "sura_fencing1_Turkey.dds" - } - Group ShapeData36 - { - - ShapeIndex 40036 - Model "sura_fencing1_Germany.GR2" - SourceSkin "sura_fencing1_Germany.dds" - TargetSkin "sura_fencing1_Brazil.dds" - } - Group ShapeData37 - { - - ShapeIndex 40037 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_soccer1_London.dds" - } - Group ShapeData38 - { - - ShapeIndex 40038 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_soccer1_Germany.dds" - } - Group ShapeData39 - { - - ShapeIndex 40039 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_soccer1_Turkey.dds" - } - Group ShapeData40 - { - - ShapeIndex 40040 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_soccer1_Brazil.dds" - } - Group ShapeData41 - { - - ShapeIndex 40041 - Model "sura_boxing1_Germany.GR2" - SourceSkin "sura_boxing1_Germany.dds" - TargetSkin "sura_boxing1_London.dds" - } - Group ShapeData42 - { - - ShapeIndex 40042 - Model "sura_boxing1_Germany.GR2" - SourceSkin "sura_boxing1_Germany.dds" - TargetSkin "sura_boxing1_Germany.dds" - } - Group ShapeData43 - { - - ShapeIndex 40043 - Model "sura_boxing1_Germany.GR2" - SourceSkin "sura_boxing1_Germany.dds" - TargetSkin "sura_boxing1_Turkey.dds" - } - Group ShapeData44 - { - - ShapeIndex 40044 - Model "sura_boxing1_Germany.GR2" - SourceSkin "sura_boxing1_Germany.dds" - TargetSkin "sura_boxing1_Brazil.dds" - } - Group ShapeData45 - { - - ShapeIndex 40032 - Model "sura_assassin1.GR2" - SourceSkin "sura_assassin1.dds" - TargetSkin "sura_assassin1.dds" - } - Group ShapeData46 - { - - ShapeIndex 40045 - Model "sura_fencing1_Germany.GR2" - SourceSkin "sura_fencing1_Germany.dds" - TargetSkin "sura_fencing1_France.dds" - } - Group ShapeData47 - { - - ShapeIndex 40046 - Model "sura_fencing1_Germany.GR2" - SourceSkin "sura_fencing1_Germany.dds" - TargetSkin "sura_fencing1_Italy.dds" - } - Group ShapeData48 - { - - ShapeIndex 40047 - Model "sura_fencing1_Germany.GR2" - SourceSkin "sura_fencing1_Germany.dds" - TargetSkin "sura_fencing1_Poland.dds" - } - Group ShapeData49 - { - - ShapeIndex 40048 - Model "sura_fencing1_Germany.GR2" - SourceSkin "sura_fencing1_Germany.dds" - TargetSkin "sura_fencing1_Romania.dds" - } - Group ShapeData50 - { - - ShapeIndex 40049 - Model "sura_fencing1_Germany.GR2" - SourceSkin "sura_fencing1_Germany.dds" - TargetSkin "sura_fencing1_Spain.dds" - } - - Group ShapeData51 - { - - ShapeIndex 40050 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_soccer1_France.dds" - } - Group ShapeData52 - { - - ShapeIndex 40051 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_soccer1_Italy.dds" - } - Group ShapeData53 - { - - ShapeIndex 40052 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_soccer1_Poland.dds" - } - Group ShapeData54 - { - - ShapeIndex 40053 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_soccer1_Romania.dds" - } - Group ShapeData55 - { - - ShapeIndex 40054 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_soccer1_Spain.dds" - } - - Group ShapeData56 - { - - ShapeIndex 40055 - Model "sura_boxing1_Germany.GR2" - SourceSkin "sura_boxing1_Germany.dds" - TargetSkin "sura_boxing1_France.dds" - } - Group ShapeData57 - { - - ShapeIndex 40056 - Model "sura_boxing1_Germany.GR2" - SourceSkin "sura_boxing1_Germany.dds" - TargetSkin "sura_boxing1_Italy.dds" - } - Group ShapeData58 - { - - ShapeIndex 40057 - Model "sura_boxing1_Germany.GR2" - SourceSkin "sura_boxing1_Germany.dds" - TargetSkin "sura_boxing1_Poland.dds" - } - Group ShapeData59 - { - - ShapeIndex 40058 - Model "sura_boxing1_Germany.GR2" - SourceSkin "sura_boxing1_Germany.dds" - TargetSkin "sura_boxing1_Romania.dds" - } - Group ShapeData60 - { - - ShapeIndex 40059 - Model "sura_boxing1_Germany.GR2" - SourceSkin "sura_boxing1_Germany.dds" - TargetSkin "sura_boxing1_Spain.dds" - } - Group ShapeData61 - { - - ShapeIndex 40065 - Model "sura_halloween1.GR2" - SourceSkin "sura_halloween1.dds" - TargetSkin "sura_halloween1.dds" - } - - Group ShapeData62 - { - ShapeIndex 13 - Model "sura_5_1.GR2" - SourceSkin "sura_5_1.dds" - TargetSkin "sura_5_1.dds" - } - Group ShapeData63 - { - ShapeIndex 40062 - Model "sura_salsa1.GR2" - SourceSkin "sura_salsa1.dds" - TargetSkin "sura_salsa1.dds" - } - Group ShapeData64 - { - ShapeIndex 40063 - Model "sura_Springwear1.GR2" - SourceSkin "sura_Springwear1.dds" - TargetSkin "sura_Springwear1.dds" - } - Group ShapeData65 - { - ShapeIndex 40061 - Model "sura_tailcoat1.GR2" - SourceSkin "sura_tailcoat1.dds" - TargetSkin "sura_tailcoat1.dds" - } - Group ShapeData66 - { - ShapeIndex 40069 - Model "sura_deer1.gr2" - SourceSkin "sura_deer1.dds" - TargetSkin "sura_deer1.dds" - } - Group ShapeData67 - { - ShapeIndex 40066 - Model "sura_santa1_black.gr2" - SourceSkin "sura_santa1_black.dds" - TargetSkin "sura_santa1_red.dds" - } - Group ShapeData68 - { - ShapeIndex 40067 - Model "sura_santa1_black.gr2" - SourceSkin "sura_santa1_black.dds" - TargetSkin "sura_santa1_green.dds" - } - Group ShapeData69 - { - ShapeIndex 40068 - Model "sura_santa1_black.gr2" - SourceSkin "sura_santa1_black.dds" - TargetSkin "sura_santa1_black.dds" - } - Group ShapeData70 - { - ShapeIndex 40070 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA01.dds" - } - Group ShapeData71 - { - ShapeIndex 40071 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA02.dds" - } - Group ShapeData72 - { - ShapeIndex 40072 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA03.dds" - } - Group ShapeData73 - { - ShapeIndex 40073 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA04.dds" - } - Group ShapeData74 - { - ShapeIndex 40074 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA05.dds" - } - Group ShapeData75 - { - ShapeIndex 40075 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA06.dds" - } - Group ShapeData76 - { - ShapeIndex 40076 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA07.dds" - } - Group ShapeData77 - { - ShapeIndex 40077 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA08.dds" - } - Group ShapeData78 - { - ShapeIndex 40078 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA09.dds" - } - Group ShapeData79 - { - ShapeIndex 40079 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA10.dds" - } - Group ShapeData80 - { - ShapeIndex 40080 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA11.dds" - } - Group ShapeData81 - { - ShapeIndex 40081 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA12.dds" - } - Group ShapeData82 - { - ShapeIndex 40082 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA13.dds" - } - Group ShapeData83 - { - ShapeIndex 40083 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA14.dds" - } - Group ShapeData84 - { - ShapeIndex 40084 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA15.dds" - } - Group ShapeData85 - { - ShapeIndex 40085 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA16.dds" - } - Group ShapeData86 - { - ShapeIndex 40086 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA17.dds" - } - Group ShapeData87 - { - ShapeIndex 40087 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA18.dds" - } - Group ShapeData88 - { - ShapeIndex 40088 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA19.dds" - } - Group ShapeData89 - { - ShapeIndex 40089 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA20.dds" - } - Group ShapeData90 - { - ShapeIndex 40090 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA21.dds" - } - Group ShapeData91 - { - ShapeIndex 40091 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA22.dds" - } - Group ShapeData92 - { - ShapeIndex 40092 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA23.dds" - } - Group ShapeData93 - { - ShapeIndex 40093 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA24.dds" - } - Group ShapeData94 - { - ShapeIndex 40094 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA25.dds" - } - Group ShapeData95 - { - ShapeIndex 40095 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA26.dds" - } - Group ShapeData96 - { - ShapeIndex 40096 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA27.dds" - } - Group ShapeData97 - { - ShapeIndex 40097 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA28.dds" - } - Group ShapeData98 - { - ShapeIndex 40098 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA29.dds" - } - Group ShapeData99 - { - ShapeIndex 40099 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA30.dds" - } - Group ShapeData100 - { - ShapeIndex 40100 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA31.dds" - } - Group ShapeData101 - { - ShapeIndex 40101 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA32.dds" - } - Group ShapeData102 - { - ShapeIndex 40064 - Model "sura_samurai1.GR2" - SourceSkin "sura_samurai1.dds" - TargetSkin "sura_samurai1.dds" - } - Group ShapeData103 - { - ShapeIndex 40106 - Model "sura_rabbit1.GR2" - SourceSkin "sura_rabbit1.dds" - TargetSkin "sura_rabbit1_black.dds" - } - Group ShapeData104 - { - ShapeIndex 40107 - Model "sura_rabbit1.GR2" - SourceSkin "sura_rabbit1.dds" - TargetSkin "sura_rabbit1_blue.dds" - } - Group ShapeData105 - { - ShapeIndex 40108 - Model "sura_rabbit1.GR2" - SourceSkin "sura_rabbit1.dds" - TargetSkin "sura_rabbit1_green.dds" - } - Group ShapeData106 - { - ShapeIndex 40109 - Model "sura_rabbit1.GR2" - SourceSkin "sura_rabbit1.dds" - TargetSkin "sura_rabbit1_pink.dds" - } - Group ShapeData107 - { - ShapeIndex 40110 - Model "sura_BlackSnake1.GR2" - SourceSkin "sura_BlackSnake1.dds" - TargetSkin "sura_BlackSnake1.dds" - } - Group ShapeData108 - { - ShapeIndex 40111 - Model "sura_BlackSnake1.GR2" - SourceSkin "sura_BlackSnake1.dds" - TargetSkin "sura_BlackSnake1.dds" - } - Group ShapeData109 - { - ShapeIndex 40112 - Model "sura_assassin1.GR2" - SourceSkin "sura_assassin1.dds" - TargetSkin "sura_assassin2.dds" - } - Group ShapeData110 - { - ShapeIndex 40114 - Model "sura_pwahuang1.GR2" - SourceSkin "sura_pwahuang1.dds" - TargetSkin "sura_pwahuang1.dds" - } - Group ShapeData111 - { - ShapeIndex 40116 - Model "sura_halloween2.GR2" - SourceSkin "sura_halloween2.dds" - TargetSkin "sura_halloween2.dds" - } - Group ShapeData112 - { - ShapeIndex 40118 - Model "sura_assassin1.GR2" - SourceSkin "sura_assassin1.dds" - TargetSkin "sura_assassin3.dds" - } - - Group ShapeData113 - { - ShapeIndex 40060 - Model "sura_capoeira1.gr2" - SourceSkin "sura_capoeira1.dds" - TargetSkin "sura_capoeira1.dds" - } - Group ShapeData114 - { - ShapeIndex 40120 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC01.dds" - } - Group ShapeData115 - { - ShapeIndex 40122 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC02.dds" - } - Group ShapeData116 - { - ShapeIndex 40124 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC03.dds" - } - Group ShapeData117 - { - ShapeIndex 40126 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC04.dds" - } - Group ShapeData118 - { - ShapeIndex 40128 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC05.dds" - } - Group ShapeData119 - { - ShapeIndex 40130 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC06.dds" - } - Group ShapeData120 - { - ShapeIndex 40132 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC07.dds" - } - Group ShapeData121 - { - ShapeIndex 40134 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC08.dds" - } - Group ShapeData122 - { - ShapeIndex 40136 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC09.dds" - } - Group ShapeData123 - { - ShapeIndex 40138 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC10.dds" - } - Group ShapeData124 - { - ShapeIndex 40140 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC11.dds" - } - Group ShapeData125 - { - ShapeIndex 40142 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC12.dds" - } - Group ShapeData126 - { - ShapeIndex 40144 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC13.dds" - } - Group ShapeData127 - { - ShapeIndex 40146 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC14.dds" - } - Group ShapeData128 - { - ShapeIndex 40148 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC15.dds" - } - Group ShapeData129 - { - ShapeIndex 40150 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC16.dds" - } - Group ShapeData130 - { - ShapeIndex 40152 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC17.dds" - } - Group ShapeData131 - { - ShapeIndex 40154 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC18.dds" - } - Group ShapeData132 - { - ShapeIndex 40156 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC19.dds" - } - Group ShapeData133 - { - ShapeIndex 40158 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC20.dds" - } - Group ShapeData134 - { - ShapeIndex 40160 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC21.dds" - } - Group ShapeData135 - { - ShapeIndex 40162 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC22.dds" - } - Group ShapeData136 - { - ShapeIndex 40164 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC23.dds" - } - Group ShapeData137 - { - ShapeIndex 40166 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC24.dds" - } - Group ShapeData138 - { - ShapeIndex 40168 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC25.dds" - } - Group ShapeData139 - { - ShapeIndex 40170 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC26.dds" - } - Group ShapeData140 - { - ShapeIndex 40172 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC27.dds" - } - Group ShapeData141 - { - ShapeIndex 40174 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC28.dds" - } - Group ShapeData142 - { - ShapeIndex 40176 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC29.dds" - } - Group ShapeData143 - { - ShapeIndex 40178 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC30.dds" - } - Group ShapeData144 - { - ShapeIndex 40180 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC31.dds" - } - Group ShapeData145 - { - ShapeIndex 40182 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC32.dds" - } - -} - -Group AttachingData -{ - AttachingDataCount 2 - - Group AttachingData00 - { - AttachingDataType 1 - - isAttaching 0 - AttachingModelIndex 0 - AttachingBoneName "Bip01" - - CollisionType 1 - - SphereDataCount 1 - Group SphereData00 - { - Radius 40.000000 - Position 0.000000 0.000000 90.000000 - } - } - - Group AttachingData01 - { - AttachingDataType 1 - - isAttaching 0 - AttachingModelIndex 0 - AttachingBoneName "Bip01" - - CollisionType 3 - - SphereDataCount 1 - Group SphereData00 - { - Radius 70.000000 - Position 0.000000 0.000000 90.000000 - } - } -} diff --git a/tools/root/msm/sura_w.msm b/tools/root/msm/sura_w.msm deleted file mode 100644 index 17d54627..00000000 --- a/tools/root/msm/sura_w.msm +++ /dev/null @@ -1,1692 +0,0 @@ -ScriptType RaceDataScript - -BaseModelFileName "d:/ymir work/pc2/sura/sura_novice.GR2" - -Group HairData -{ - PathName "d:/ymir Work/pc2/sura/" - - HairDataCount 75 - Group HairData00 - { - HairIndex 0 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "sura_hair_01.dds" - } - Group HairData01 - { - HairIndex 1 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "sura_hair_01_white.dds" - } - Group HairData02 - { - HairIndex 2 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "sura_hair_01_gold.dds" - } - Group HairData03 - { - HairIndex 3 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "sura_hair_01_red.dds" - } - Group HairData04 - { - HairIndex 4 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "sura_hair_01_brown.dds" - } - Group HairData05 - { - HairIndex 5 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "sura_hair_01_black.dds" - } - Group HairData06 - { - HairIndex 3001 - Model "hair/hair_2_1.gr2" - SourceSkin "hair/hair_2_1.dds" - TargetSkin "hair/hair_2_1.dds" - } - Group HairData07 - { - HairIndex 3002 - Model "hair/hair_2_1.gr2" - SourceSkin "hair/hair_2_1.dds" - TargetSkin "hair/hair_2_2.dds" - } - Group HairData08 - { - HairIndex 3003 - Model "hair/hair_2_1.gr2" - SourceSkin "hair/hair_2_1.dds" - TargetSkin "hair/hair_2_3.dds" - } - Group HairData09 - { - HairIndex 3004 - Model "hair/hair_2_1.gr2" - SourceSkin "hair/hair_2_1.dds" - TargetSkin "hair/hair_2_4.dds" - } - Group HairData10 - { - HairIndex 3005 - Model "hair/hair_3_1.gr2" - SourceSkin "hair/hair_3_1.dds" - TargetSkin "hair/hair_3_1.dds" - } - Group HairData11 - { - HairIndex 3006 - Model "hair/hair_3_1.gr2" - SourceSkin "hair/hair_3_1.dds" - TargetSkin "hair/hair_3_2.dds" - } - Group HairData12 - { - HairIndex 3007 - Model "hair/hair_3_1.gr2" - SourceSkin "hair/hair_3_1.dds" - TargetSkin "hair/hair_3_3.dds" - } - Group HairData13 - { - HairIndex 3008 - Model "hair/hair_3_1.gr2" - SourceSkin "hair/hair_3_1.dds" - TargetSkin "hair/hair_3_4.dds" - } - Group HairData14 - { - HairIndex 3009 - Model "hair/hair_4_1.gr2" - SourceSkin "hair/hair_4_1.dds" - TargetSkin "hair/hair_4_1.dds" - } - Group HairData15 - { - HairIndex 3010 - Model "hair/hair_4_1.gr2" - SourceSkin "hair/hair_4_1.dds" - TargetSkin "hair/hair_4_2.dds" - } - Group HairData16 - { - HairIndex 3011 - Model "hair/hair_4_1.gr2" - SourceSkin "hair/hair_4_1.dds" - TargetSkin "hair/hair_4_3.dds" - } - Group HairData17 - { - HairIndex 3012 - Model "hair/hair_4_1.gr2" - SourceSkin "hair/hair_4_1.dds" - TargetSkin "hair/hair_4_4.dds" - } - Group HairData18 - { - HairIndex 3013 - Model "hair/hair_6_1.gr2" - SourceSkin "hair/hair_6_1.dds" - TargetSkin "hair/hair_6_1.dds" - } - Group HairData19 - { - HairIndex 3014 - Model "hair/hair_5_1.gr2" - SourceSkin "hair/hair_5_1.dds" - TargetSkin "hair/hair_5_1.dds" - } - Group HairData20 - { - HairIndex 3015 - Model "hair/hair_7_1.gr2" - SourceSkin "hair/hair_7_1.dds" - TargetSkin "hair/hair_7_1.dds" - } - Group HairData21 - { - HairIndex 3016 - Model "hair/hair_8_1.gr2" - SourceSkin "hair/hair_8_1.dds" - TargetSkin "hair/hair_8_1.dds" - } - Group HairData22 - { - HairIndex 3017 - Model "hair/hair_9_1.gr2" - SourceSkin "hair/hair_9_1.dds" - TargetSkin "hair/hair_9_1.dds" - } - Group HairData23 - { - HairIndex 3018 - Model "hair/hair_10_1.gr2" - SourceSkin "hair/hair_10_1.dds" - TargetSkin "hair/hair_10_1.dds" - } - Group HairData24 - { - HairIndex 5001 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_1.dds" - } - Group HairData25 - { - HairIndex 5002 - Model "hair/hair_14_1.gr2" - SourceSkin "hair/hair_14_1.dds" - TargetSkin "hair/hair_14_1.dds" - } - Group HairData26 - { - HairIndex 5007 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_1.dds" - } - Group HairData27 - { - HairIndex 5003 - Model "hair/hair_16_1.gr2" - SourceSkin "hair/hair_16_1.dds" - TargetSkin "hair/hair_16_1.dds" - } - Group HairData28 - { - HairIndex 5015 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_1.dds" - } - Group HairData29 - { - HairIndex 5005 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_2.dds" - } - Group HairData30 - { - HairIndex 5006 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_3.dds" - } - Group HairData31 - { - HairIndex 5008 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_4.dds" - } - Group HairData32 - { - HairIndex 5009 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_5.dds" - } - Group HairData33 - { - HairIndex 5010 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_6.dds" - } - Group HairData34 - { - HairIndex 5011 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_7.dds" - } - Group HairData35 - { - HairIndex 5012 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_8.dds" - } - Group HairData36 - { - HairIndex 5013 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_9.dds" - } - Group HairData37 - { - HairIndex 5004 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_2.dds" - } - Group HairData38 - { - HairIndex 5014 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_3.dds" - } - Group HairData39 - { - HairIndex 5016 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_4.dds" - } - Group HairData40 - { - HairIndex 5017 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_5.dds" - } - Group HairData41 - { - HairIndex 5018 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_6.dds" - } - Group HairData42 - { - HairIndex 5019 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_7.dds" - } - Group HairData43 - { - HairIndex 5020 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_8.dds" - } - Group HairData44 - { - HairIndex 5021 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_9.dds" - } - Group HairData45 - { - HairIndex 5027 - Model "hair/hair_20_1.gr2" - SourceSkin "hair/hair_20_1.dds" - TargetSkin "hair/hair_20_1.dds" - } - Group HairData46 - { - HairIndex 5023 - Model "hair/hair_13_1.gr2" - SourceSkin "hair/hair_13_1.dds" - TargetSkin "hair/hair_13_1.dds" - } - Group HairData47 - { - HairIndex 5024 - Model "hair/hair_18_1.gr2" - SourceSkin "hair/hair_18_1.dds" - TargetSkin "hair/hair_18_1.dds" - } - Group HairData48 - { - HairIndex 5025 - Model "hair/hair_19_1.gr2" - SourceSkin "hair/hair_19_1.dds" - TargetSkin "hair/hair_19_1.dds" - } - Group HairData49 - { - HairIndex 5030 - Model "hair/hair_22_1.gr2" - SourceSkin "hair/hair_22_1.dds" - TargetSkin "hair/hair_22_1.dds" - } - Group HairData50 - { - HairIndex 5031 - Model "hair/hair_23_1.gr2" - SourceSkin "hair/hair_23_1.dds" - TargetSkin "hair/hair_23_1.dds" - } - Group HairData51 - { - HairIndex 5034 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_1.dds" - } - Group HairData52 - { - HairIndex 5036 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_2.dds" - } - Group HairData53 - { - HairIndex 5038 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_3.dds" - } - Group HairData54 - { - HairIndex 5040 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_4.dds" - } - Group HairData55 - { - HairIndex 5042 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_5.dds" - } - Group HairData56 - { - HairIndex 5026 - Model "hair/hair_21_1.gr2" - SourceSkin "hair/hair_21_1.dds" - TargetSkin "hair/hair_21_1.dds" - } - Group HairData57 - { - HairIndex 5045 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_2.dds" - } - Group HairData58 - { - HairIndex 5046 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_3.dds" - } - Group HairData59 - { - HairIndex 5047 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_4.dds" - } - Group HairData60 - { - HairIndex 5048 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_5.dds" - } - Group HairData61 - { - HairIndex 5049 - Model "hair/hair_28_1.gr2" - SourceSkin "hair/hair_28_1.dds" - TargetSkin "hair/hair_28_1.dds" - } - Group HairData62 - { - HairIndex 5050 - Model "hair/hair_28_1.gr2" - SourceSkin "hair/hair_28_1.dds" - TargetSkin "hair/hair_28_1.dds" - } - Group HairData63 - { - HairIndex 5051 - Model "hair/hair_29_1.gr2" - SourceSkin "hair/hair_29_1.dds" - TargetSkin "hair/hair_29_1.dds" - } - Group HairData64 - { - HairIndex 5052 - Model "hair/hair_30_1.gr2" - SourceSkin "hair/hair_30_1.dds" - TargetSkin "hair/hair_30_1.dds" - } - Group HairData65 - { - HairIndex 5053 - Model "hair/hair_31_1.gr2" - SourceSkin "hair/hair_31_1.dds" - TargetSkin "hair/hair_31_1.dds" - } - Group HairData66 - { - HairIndex 5054 - Model "hair/hair_32_1.gr2" - SourceSkin "hair/hair_32_1.dds" - TargetSkin "hair/hair_32_1.dds" - } - Group HairData67 - { - HairIndex 5056 - Model "hair/hair_14_1.gr2" - SourceSkin "hair/hair_14_1.dds" - TargetSkin "hair/hair_14_2.dds" - } - Group HairData68 - { - HairIndex 5058 - Model "hair/hair_33_1.gr2" - SourceSkin "hair/hair_33_1.dds" - TargetSkin "hair/hair_33_1.dds" - } - Group HairData69 - { - HairIndex 5060 - Model "hair/hair_34_1.gr2" - SourceSkin "hair/hair_34_1.dds" - TargetSkin "hair/hair_34_1.dds" - } - Group HairData70 - { - HairIndex 5062 - Model "hair/hair_35_1.gr2" - SourceSkin "hair/hair_35_1.dds" - TargetSkin "hair/hair_35_1.dds" - } - Group HairData71 - { - HairIndex 5063 - Model "hair/hair_37_1.gr2" - SourceSkin "hair/hair_37_1.dds" - TargetSkin "hair/hair_37_1.dds" - } - - Group HairData72 - { - HairIndex 5064 - Model "hair/hair_36_1.gr2" - SourceSkin "hair/hair_36_1.dds" - TargetSkin "hair/hair_36_1.dds" - } - - Group HairData73 - { - HairIndex 5065 - Model "hair/hair_38_1.gr2" - SourceSkin "hair/hair_38_1.dds" - TargetSkin "hair/hair_38_1.dds" - } - Group HairData74 - { - HairIndex 5022 - Model "hair/hair_12_1.gr2" - SourceSkin "hair/hair_12_1.dds" - TargetSkin "hair/hair_12_1.dds" - } -} - -Group ShapeData -{ - PathName "d:/ymir Work/pc2/sura/" - - ShapeDataCount 146 - - Group ShapeData00 - { - ShapeIndex 0 - - Model "sura_novice.GR2" - SourceSkin "sura_novice_red.dds" - TargetSkin "sura_novice_black.dds" - } - Group ShapeData01 - { - ShapeIndex 1 - - Model "sura_novice.GR2" - SourceSkin "sura_novice_red.dds" - TargetSkin "sura_novice_red.dds" - } - Group ShapeData02 - { - ShapeIndex 3 - Model "sura_jinhon.GR2" - SourceSkin "sura_jinhon.dds" - TargetSkin "sura_jinhon.dds" - } - Group ShapeData03 - { - ShapeIndex 4 - Model "sura_jinhon.GR2" - SourceSkin "sura_jinhon.dds" - TargetSkin "sura_mageuk.dds" - } - Group ShapeData04 - { - ShapeIndex 5 - Model "sura_jinhon.GR2" - SourceSkin "sura_jinhon.dds" - TargetSkin "sura_biun.dds" - } - Group ShapeData05 - { - ShapeIndex 6 - Model "sura_saryeong.GR2" - SourceSkin "sura_saryeong.dds" - TargetSkin "sura_saryeong.dds" - - SourceSkin2 "sura_saryeong_cloak.dds" - TargetSkin2 "sura_saryeong_cloak.dds" - } - Group ShapeData06 - { - ShapeIndex 7 - Model "sura_saryeong.GR2" - SourceSkin "sura_saryeong.dds" - TargetSkin "sura_eumyang.dds" - - SourceSkin2 "sura_saryeong_cloak.dds" - TargetSkin2 "sura_saryeong_cloak.dds" - } - Group ShapeData07 - { - ShapeIndex 8 - Model "sura_saryeong.GR2" - SourceSkin "sura_saryeong.dds" - TargetSkin "sura_heukbi.dds" - - SourceSkin2 "sura_saryeong_cloak.dds" - TargetSkin2 "sura_saryeong_cloak.dds" - } - Group ShapeData08 - { - ShapeIndex 9 - Model "sura_unra.GR2" - SourceSkin "sura_unra.dds" - TargetSkin "sura_unra.dds" - - SourceSkin2 "sura_unra_cloak.dds" - TargetSkin2 "sura_unra_cloak.dds" - } - Group ShapeData09 - { - ShapeIndex 10 - Model "sura_unra.GR2" - SourceSkin "sura_unra.dds" - TargetSkin "sura_gwimyeon.dds" - - SourceSkin2 "sura_unra_cloak.dds" - TargetSkin2 "sura_unra_cloak.dds" - - } - Group ShapeData10 - { - ShapeIndex 11 - Model "sura_unra.GR2" - SourceSkin "sura_unra.dds" - TargetSkin "sura_maryeong.dds" - - SourceSkin2 "sura_unra_cloak.dds" - TargetSkin2 "sura_unra_cloak.dds" - - } - Group ShapeData11 - { - SpecialPath "d:/ymir work/monster/wolf/" - - ShapeIndex 100 - Model "wolf.gr2" - SourceSkin "wolf.dds" - } - Group ShapeData12 - { - SpecialPath "d:/ymir work/monster/wild_boar/" - - ShapeIndex 101 - Model "wild_boar.gr2" - SourceSkin "wild_boar.dds" - } - Group ShapeData13 - { - SpecialPath "d:/ymir work/monster/bear/" - - ShapeIndex 102 - Model "bear.gr2" - SourceSkin "bear.dds" - } - Group ShapeData14 - { - SpecialPath "d:/ymir work/monster/tiger/" - - ShapeIndex 103 - Model "tiger.gr2" - SourceSkin "tiger.dds" - } - Group ShapeData15 - { - SpecialPath "d:/ymir work/pc2/sura/" - - ShapeIndex 201 - Model "sura_marry_01.gr2" - SourceSkin "sura_marry_01.dds" - TargetSkin "sura_marry_01.dds" - } - Group ShapeData16 - { - ShapeIndex 12 - Model "sura_4-1.GR2" - SourceSkin "sura_4-1.dds" - TargetSkin "sura_4-1.dds" - } - - - Group ShapeData17 - { - ShapeIndex 14 - Model "sura_jinhon.GR2" - SourceSkin "sura_jinhon.dds" - TargetSkin "sura_1-1_jinhon copy_a.DDS" - } - Group ShapeData18 - { - ShapeIndex 15 - Model "sura_jinhon.GR2" - SourceSkin "sura_jinhon.dds" - TargetSkin "sura_1-2_mageuk_a.DDS" - } - Group ShapeData19 - { - ShapeIndex 16 - Model "sura_jinhon.GR2" - SourceSkin "sura_jinhon.dds" - TargetSkin "sura_1-3_biun_a.DDS" - } - - Group ShapeData20 - { - ShapeIndex 17 - Model "sura_saryeong.GR2" - SourceSkin "sura_saryeong.dds" - TargetSkin "sura_2-1_saryeong_a.DDS" - } - Group ShapeData21 - { - ShapeIndex 18 - Model "sura_saryeong.GR2" - SourceSkin "sura_saryeong.dds" - TargetSkin "sura_2-2_eumyang_a.DDS" - } - Group ShapeData22 - { - ShapeIndex 19 - Model "sura_saryeong.GR2" - SourceSkin "sura_saryeong.dds" - TargetSkin "sura_2-3_heukbi_a.DDS" - } - Group ShapeData23 - { - ShapeIndex 20 - Model "sura_unra.GR2" - SourceSkin "sura_unra.dds" - TargetSkin "sura_3-1_unra_a.DDS" - - SourceSkin2 "sura_unra_cloak.dds" - TargetSkin2 "sura_unra_cloak.dds" - } - Group ShapeData24 - { - ShapeIndex 22 - Model "sura_maryeong.GR2" - SourceSkin "sura_maryeong.dds" - TargetSkin "sura_maryung_a.DDS" - } - Group ShapeData25 - { - ShapeIndex 24 - Model "sura_lord.GR2" - SourceSkin "sura_king01.dds" - TargetSkin "sura_king01.dds" - SourceSkin2 "sura_king01_cloak.dds" - TargetSkin2 "sura_king01_cloak.dds" - - - } - Group ShapeData26 - { - ShapeIndex 25 - Model "sura_lord.GR2" - SourceSkin "sura_king01.dds" - TargetSkin "sura_king02.dds" - SourceSkin2 "sura_king02_cloak.dds" - TargetSkin2 "sura_king02_cloak.dds" - - - } - - Group ShapeData27 - { - SpecialPath "d:/ymir work/pc2/sura/" - ShapeIndex 26 - Model "sura_4-1.GR2" - SourceSkin "sura_4-1.dds" - TargetSkin "sura_4-2.dds" - } - Group ShapeData28 - { - - ShapeIndex 27 - Model "sura_event1.GR2" - SourceSkin "sura_event1_yellow.dds" - TargetSkin "sura_event1_red.dds" - } - Group ShapeData29 - { - - ShapeIndex 28 - Model "sura_event1.GR2" - SourceSkin "sura_event1_yellow.dds" - TargetSkin "sura_event1_yellow.dds" - } - Group ShapeData30 - { - - ShapeIndex 29 - Model "sura_event1.GR2" - SourceSkin "sura_event1_yellow.dds" - TargetSkin "sura_event1_blue.dds" - } - Group ShapeData31 - { - ShapeIndex 30 - - Model "sura_jinhon.gr2" - SourceSkin "sura_jinhon.dds" - TargetSkin "sura_costume1.dds" - } - Group ShapeData32 - { - ShapeIndex 40031 - - Model "sura_rabbit1.GR2" - SourceSkin "sura_rabbit1.dds" - TargetSkin "sura_rabbit1.dds" - } - Group ShapeData33 - { - SpecialPath "d:/ymir work/pc2/sura/" - ShapeIndex 40033 - - Model "sura_fencing1_Germany.GR2" - SourceSkin "sura_fencing1_Germany.dds" - TargetSkin "sura_fencing1_London.dds" - } - Group ShapeData34 - { - ShapeIndex 40034 - - Model "sura_fencing1_Germany.GR2" - SourceSkin "sura_fencing1_Germany.dds" - TargetSkin "sura_fencing1_Germany.dds" - } - Group ShapeData35 - { - ShapeIndex 40035 - - Model "sura_fencing1_Germany.GR2" - SourceSkin "sura_fencing1_Germany.dds" - TargetSkin "sura_fencing1_Turkey.dds" - } - Group ShapeData36 - { - ShapeIndex 40036 - - Model "sura_fencing1_Germany.GR2" - SourceSkin "sura_fencing1_Germany.dds" - TargetSkin "sura_fencing1_Brazil.dds" - } - Group ShapeData37 - { - ShapeIndex 40037 - - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_soccer1_London.dds" - } - Group ShapeData38 - { - ShapeIndex 40038 - - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_soccer1_Germany.dds" - } - Group ShapeData39 - { - ShapeIndex 40039 - - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_soccer1_Turkey.dds" - } - Group ShapeData40 - { - ShapeIndex 40040 - - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_soccer1_Brazil.dds" - } - Group ShapeData41 - { - ShapeIndex 40041 - - Model "sura_boxing1_Germany.GR2" - SourceSkin "sura_boxing1_Germany.dds" - TargetSkin "sura_boxing1_London.dds" - } - Group ShapeData42 - { - ShapeIndex 40042 - - Model "sura_boxing1_Germany.GR2" - SourceSkin "sura_boxing1_Germany.dds" - TargetSkin "sura_boxing1_Germany.dds" - } - Group ShapeData43 - { - ShapeIndex 40043 - - Model "sura_boxing1_Germany.GR2" - SourceSkin "sura_boxing1_Germany.dds" - TargetSkin "sura_boxing1_Turkey.dds" - } - Group ShapeData44 - { - ShapeIndex 40044 - - Model "sura_boxing1_Germany.GR2" - SourceSkin "sura_boxing1_Germany.dds" - TargetSkin "sura_boxing1_Brazil.dds" - } - Group ShapeData45 - { - ShapeIndex 40032 - - Model "sura_assassin1.GR2" - SourceSkin "sura_assassin1.dds" - TargetSkin "sura_assassin1.dds" - } - Group ShapeData46 - { - SpecialPath "d:/ymir work/pc2/sura/" - ShapeIndex 40045 - - Model "sura_fencing1_Germany.GR2" - SourceSkin "sura_fencing1_Germany.dds" - TargetSkin "sura_fencing1_France.dds" - } - Group ShapeData47 - { - ShapeIndex 40046 - - Model "sura_fencing1_Germany.GR2" - SourceSkin "sura_fencing1_Germany.dds" - TargetSkin "sura_fencing1_Italy.dds" - } - Group ShapeData48 - { - ShapeIndex 40047 - - Model "sura_fencing1_Germany.GR2" - SourceSkin "sura_fencing1_Germany.dds" - TargetSkin "sura_fencing1_Poland.dds" - } - Group ShapeData49 - { - ShapeIndex 40048 - - Model "sura_fencing1_Germany.GR2" - SourceSkin "sura_fencing1_Germany.dds" - TargetSkin "sura_fencing1_Romania.dds" - } - Group ShapeData50 - { - ShapeIndex 40049 - - Model "sura_fencing1_Germany.GR2" - SourceSkin "sura_fencing1_Germany.dds" - TargetSkin "sura_fencing1_Spain.dds" - } - Group ShapeData51 - { - ShapeIndex 40050 - - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_soccer1_France.dds" - } - Group ShapeData52 - { - ShapeIndex 40051 - - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_soccer1_Italy.dds" - } - Group ShapeData53 - { - ShapeIndex 40052 - - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_soccer1_Poland.dds" - } - Group ShapeData54 - { - ShapeIndex 40053 - - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_soccer1_Romania.dds" - } - Group ShapeData55 - { - ShapeIndex 40054 - - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_soccer1_Spain.dds" - } - - Group ShapeData56 - { - ShapeIndex 40055 - - Model "sura_boxing1_Germany.GR2" - SourceSkin "sura_boxing1_Germany.dds" - TargetSkin "sura_boxing1_France.dds" - } - Group ShapeData57 - { - ShapeIndex 40056 - - Model "sura_boxing1_Germany.GR2" - SourceSkin "sura_boxing1_Germany.dds" - TargetSkin "sura_boxing1_Italy.dds" - } - Group ShapeData58 - { - ShapeIndex 40057 - - Model "sura_boxing1_Germany.GR2" - SourceSkin "sura_boxing1_Germany.dds" - TargetSkin "sura_boxing1_Poland.dds" - } - Group ShapeData59 - { - ShapeIndex 40058 - - Model "sura_boxing1_Germany.GR2" - SourceSkin "sura_boxing1_Germany.dds" - TargetSkin "sura_boxing1_Romania.dds" - } - Group ShapeData60 - { - ShapeIndex 40059 - - Model "sura_boxing1_Germany.GR2" - SourceSkin "sura_boxing1_Germany.dds" - TargetSkin "sura_boxing1_Spain.dds" - } - Group ShapeData61 - { - ShapeIndex 40065 - - Model "sura_halloween1.GR2" - SourceSkin "sura_halloween1.dds" - TargetSkin "sura_halloween1.dds" - } - - Group ShapeData62 - { - ShapeIndex 13 - Model "sura_5_1.GR2" - SourceSkin "sura_5_1.dds" - TargetSkin "sura_5_1.dds" - } - Group ShapeData63 - { - ShapeIndex 40062 - Model "sura_salsa1.GR2" - SourceSkin "sura_salsa1.dds" - TargetSkin "sura_salsa1.dds" - } - Group ShapeData64 - { - ShapeIndex 40063 - Model "sura_Springwear1.GR2" - SourceSkin "sura_Springwear1.dds" - TargetSkin "sura_Springwear1.dds" - } - Group ShapeData65 - { - ShapeIndex 40061 - Model "sura_tailcoat1.GR2" - SourceSkin "sura_tailcoat1.dds" - TargetSkin "sura_tailcoat1.dds" - } - Group ShapeData66 - { - ShapeIndex 40069 - Model "sura_deer1.gr2" - SourceSkin "sura_deer1.dds" - TargetSkin "sura_deer1.dds" - } - Group ShapeData67 - { - ShapeIndex 40066 - Model "sura_santa1_black.gr2" - SourceSkin "sura_santa1_black.dds" - TargetSkin "sura_santa1_red.dds" - } - Group ShapeData68 - { - ShapeIndex 40067 - Model "sura_santa1_black.gr2" - SourceSkin "sura_santa1_black.dds" - TargetSkin "sura_santa1_green.dds" - } - Group ShapeData69 - { - ShapeIndex 40068 - Model "sura_santa1_black.gr2" - SourceSkin "sura_santa1_black.dds" - TargetSkin "sura_santa1_black.dds" - } - Group ShapeData70 - { - ShapeIndex 40070 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA01.dds" - } - Group ShapeData71 - { - ShapeIndex 40071 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA02.dds" - } - Group ShapeData72 - { - ShapeIndex 40072 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA03.dds" - } - Group ShapeData73 - { - ShapeIndex 40073 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA04.dds" - } - Group ShapeData74 - { - ShapeIndex 40074 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA05.dds" - } - Group ShapeData75 - { - ShapeIndex 40075 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA06.dds" - } - Group ShapeData76 - { - ShapeIndex 40076 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA07.dds" - } - Group ShapeData77 - { - ShapeIndex 40077 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA08.dds" - } - Group ShapeData78 - { - ShapeIndex 40078 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA09.dds" - } - Group ShapeData79 - { - ShapeIndex 40079 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA10.dds" - } - Group ShapeData80 - { - ShapeIndex 40080 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA11.dds" - } - Group ShapeData81 - { - ShapeIndex 40081 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA12.dds" - } - Group ShapeData82 - { - ShapeIndex 40082 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA13.dds" - } - Group ShapeData83 - { - ShapeIndex 40083 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA14.dds" - } - Group ShapeData84 - { - ShapeIndex 40084 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA15.dds" - } - Group ShapeData85 - { - ShapeIndex 40085 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA16.dds" - } - Group ShapeData86 - { - ShapeIndex 40086 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA17.dds" - } - Group ShapeData87 - { - ShapeIndex 40087 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA18.dds" - } - Group ShapeData88 - { - ShapeIndex 40088 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA19.dds" - } - Group ShapeData89 - { - ShapeIndex 40089 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA20.dds" - } - Group ShapeData90 - { - ShapeIndex 40090 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA21.dds" - } - Group ShapeData91 - { - ShapeIndex 40091 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA22.dds" - } - Group ShapeData92 - { - ShapeIndex 40092 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA23.dds" - } - Group ShapeData93 - { - ShapeIndex 40093 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA24.dds" - } - Group ShapeData94 - { - ShapeIndex 40094 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA25.dds" - } - Group ShapeData95 - { - ShapeIndex 40095 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA26.dds" - } - Group ShapeData96 - { - ShapeIndex 40096 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA27.dds" - } - Group ShapeData97 - { - ShapeIndex 40097 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA28.dds" - } - Group ShapeData98 - { - ShapeIndex 40098 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA29.dds" - } - Group ShapeData99 - { - ShapeIndex 40099 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA30.dds" - } - Group ShapeData100 - { - ShapeIndex 40100 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA31.dds" - } - Group ShapeData101 - { - ShapeIndex 40101 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_UEFA32.dds" - } - Group ShapeData102 - { - ShapeIndex 40064 - Model "sura_samurai1.GR2" - SourceSkin "sura_samurai1.dds" - TargetSkin "sura_samurai1.dds" - } - Group ShapeData103 - { - ShapeIndex 40106 - Model "sura_rabbit1.GR2" - SourceSkin "sura_rabbit1.dds" - TargetSkin "sura_rabbit1_black.dds" - } - Group ShapeData104 - { - ShapeIndex 40107 - Model "sura_rabbit1.GR2" - SourceSkin "sura_rabbit1.dds" - TargetSkin "sura_rabbit1_blue.dds" - } - Group ShapeData105 - { - ShapeIndex 40108 - Model "sura_rabbit1.GR2" - SourceSkin "sura_rabbit1.dds" - TargetSkin "sura_rabbit1_green.dds" - } - Group ShapeData106 - { - ShapeIndex 40109 - Model "sura_rabbit1.GR2" - SourceSkin "sura_rabbit1.dds" - TargetSkin "sura_rabbit1_pink.dds" - } - Group ShapeData107 - { - ShapeIndex 40110 - Model "sura_BlackSnake1.GR2" - SourceSkin "sura_BlackSnake1.dds" - TargetSkin "sura_BlackSnake1.dds" - } - Group ShapeData108 - { - ShapeIndex 40111 - Model "sura_BlackSnake1.GR2" - SourceSkin "sura_BlackSnake1.dds" - TargetSkin "sura_BlackSnake1.dds" - } - Group ShapeData109 - { - ShapeIndex 40113 - Model "sura_assassin1.GR2" - SourceSkin "sura_assassin1.dds" - TargetSkin "sura_assassin2.dds" - } - Group ShapeData110 - { - ShapeIndex 40115 - Model "sura_pwahuang1.GR2" - SourceSkin "sura_pwahuang1.dds" - TargetSkin "sura_pwahuang1.dds" - } - Group ShapeData111 - { - ShapeIndex 40117 - Model "sura_halloween2.GR2" - SourceSkin "sura_halloween2.dds" - TargetSkin "sura_halloween2.dds" - } - Group ShapeData112 - { - ShapeIndex 40119 - Model "sura_assassin1.GR2" - SourceSkin "sura_assassin1.dds" - TargetSkin "sura_assassin3.dds" - } - Group ShapeData113 - { - ShapeIndex 40060 - Model "sura_capoeira1.gr2" - SourceSkin "sura_capoeira1.dds" - TargetSkin "sura_capoeira1.dds" - } - Group ShapeData114 - { - ShapeIndex 40121 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC01.dds" - } - Group ShapeData115 - { - ShapeIndex 40123 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC02.dds" - } - Group ShapeData116 - { - ShapeIndex 40125 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC03.dds" - } - Group ShapeData117 - { - ShapeIndex 40127 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC04.dds" - } - Group ShapeData118 - { - ShapeIndex 40129 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC05.dds" - } - Group ShapeData119 - { - ShapeIndex 40131 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC06.dds" - } - Group ShapeData120 - { - ShapeIndex 40133 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC07.dds" - } - Group ShapeData121 - { - ShapeIndex 40135 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC08.dds" - } - Group ShapeData122 - { - ShapeIndex 40137 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC09.dds" - } - Group ShapeData123 - { - ShapeIndex 40139 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC10.dds" - } - Group ShapeData124 - { - ShapeIndex 40141 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC11.dds" - } - Group ShapeData125 - { - ShapeIndex 40143 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC12.dds" - } - Group ShapeData126 - { - ShapeIndex 40145 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC13.dds" - } - Group ShapeData127 - { - ShapeIndex 40147 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC14.dds" - } - Group ShapeData128 - { - ShapeIndex 40149 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC15.dds" - } - Group ShapeData129 - { - ShapeIndex 40151 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC16.dds" - } - Group ShapeData130 - { - ShapeIndex 40153 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC17.dds" - } - Group ShapeData131 - { - ShapeIndex 40155 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC18.dds" - } - Group ShapeData132 - { - ShapeIndex 40157 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC19.dds" - } - Group ShapeData133 - { - ShapeIndex 40159 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC20.dds" - } - Group ShapeData134 - { - ShapeIndex 40161 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC21.dds" - } - Group ShapeData135 - { - ShapeIndex 40163 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC22.dds" - } - Group ShapeData136 - { - ShapeIndex 40165 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC23.dds" - } - Group ShapeData137 - { - ShapeIndex 40167 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC24.dds" - } - Group ShapeData138 - { - ShapeIndex 40169 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC25.dds" - } - Group ShapeData139 - { - ShapeIndex 40171 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC26.dds" - } - Group ShapeData140 - { - ShapeIndex 40173 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC27.dds" - } - Group ShapeData141 - { - ShapeIndex 40175 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC28.dds" - } - Group ShapeData142 - { - ShapeIndex 40177 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC29.dds" - } - Group ShapeData143 - { - ShapeIndex 40179 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC30.dds" - } - Group ShapeData144 - { - ShapeIndex 40181 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC31.dds" - } - Group ShapeData145 - { - ShapeIndex 40183 - Model "sura_soccer1_Germany.GR2" - SourceSkin "sura_soccer1_Germany.dds" - TargetSkin "sura_WC32.dds" - } - - -} - -Group AttachingData -{ - AttachingDataCount 2 - - Group AttachingData00 - { - AttachingDataType 1 - - isAttaching 0 - AttachingModelIndex 0 - AttachingBoneName "Bip01" - - CollisionType 1 - - SphereDataCount 1 - Group SphereData00 - { - Radius 40.000000 - Position 0.000000 0.000000 90.000000 - } - } - - Group AttachingData01 - { - AttachingDataType 1 - - isAttaching 0 - AttachingModelIndex 0 - AttachingBoneName "Bip01" - - CollisionType 3 - - SphereDataCount 1 - Group SphereData00 - { - Radius 70.000000 - Position 0.000000 0.000000 90.000000 - } - } -} diff --git a/tools/root/msm/warrior_m.msm b/tools/root/msm/warrior_m.msm deleted file mode 100644 index 52ea0927..00000000 --- a/tools/root/msm/warrior_m.msm +++ /dev/null @@ -1,1605 +0,0 @@ -ScriptType RaceDataScript - -BaseModelFileName "d:/ymir work/pc/warrior/warrior_novice.GR2" - -Group HairData -{ - PathName "d:/ymir Work/pc/warrior/" - - HairDataCount 61 - Group HairData00 - { - HairIndex 0 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "warrior_hair_01.dds" - } - Group HairData01 - { - HairIndex 1 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "warrior_hair_01_white.dds" - } - Group HairData02 - { - HairIndex 2 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "warrior_hair_01_gold.dds" - } - Group HairData03 - { - HairIndex 3 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "warrior_hair_01_red.dds" - } - Group HairData04 - { - HairIndex 4 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "warrior_hair_01_brown.dds" - } - Group HairData05 - { - HairIndex 5 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "warrior_hair_01_black.dds" - } - Group HairData06 - { - HairIndex 1001 - Model "hair/hair_2_1.gr2" - SourceSkin "hair/hair_2_1.dds" - TargetSkin "hair/hair_2_1.dds" - } - Group HairData07 - { - HairIndex 1002 - Model "hair/hair_2_2.gr2" - SourceSkin "hair/hair_2_2.dds" - TargetSkin "hair/hair_2_2.dds" - } - Group HairData08 - { - HairIndex 1003 - Model "hair/hair_2_3.gr2" - SourceSkin "hair/hair_2_3.dds" - TargetSkin "hair/hair_2_3.dds" - } - Group HairData09 - { - HairIndex 1004 - Model "hair/hair_2_4.gr2" - SourceSkin "hair/hair_2_4.dds" - TargetSkin "hair/hair_2_4.dds" - } - Group HairData10 - { - HairIndex 1005 - Model "hair/hair_3_1.gr2" - SourceSkin "hair/hair_3_1.dds" - TargetSkin "hair/hair_3_1.dds" - } - Group HairData11 - { - HairIndex 1006 - Model "hair/hair_3_2.gr2" - SourceSkin "hair/hair_3_2.dds" - TargetSkin "hair/hair_3_2.dds" - } - Group HairData12 - { - HairIndex 1007 - Model "hair/hair_3_3.gr2" - SourceSkin "hair/hair_3_3.dds" - TargetSkin "hair/hair_3_3.dds" - } - Group HairData13 - { - HairIndex 1008 - Model "hair/hair_3_4.gr2" - SourceSkin "hair/hair_3_4.dds" - TargetSkin "hair/hair_3_4.dds" - } - Group HairData14 - { - HairIndex 1009 - Model "hair/hair_4_1.gr2" - SourceSkin "hair/hair_4_1.dds" - TargetSkin "hair/hair_4_1.dds" - } - Group HairData15 - { - HairIndex 1010 - Model "hair/hair_4_2.gr2" - SourceSkin "hair/hair_4_2.dds" - TargetSkin "hair/hair_4_2.dds" - } - Group HairData16 - { - HairIndex 1011 - Model "hair/hair_4_3.gr2" - SourceSkin "hair/hair_4_3.dds" - TargetSkin "hair/hair_4_3.dds" - } - Group HairData17 - { - HairIndex 1012 - Model "hair/hair_4_4.gr2" - SourceSkin "hair/hair_4_4.dds" - TargetSkin "hair/hair_4_4.dds" - } - Group HairData18 - { - HairIndex 1013 - Model "hair/hair_6_1.gr2" - SourceSkin "hair/hair_6_1.dds" - TargetSkin "hair/hair_6_1.dds" - } - Group HairData19 - { - HairIndex 1014 - Model "hair/hair_5_1.gr2" - SourceSkin "hair/hair_5_1.dds" - TargetSkin "hair/hair_5_1.dds" - } - Group HairData20 - { - HairIndex 1015 - Model "hair/hair_7_1.gr2" - SourceSkin "hair/hair_7_1.dds" - TargetSkin "hair/hair_7_1.dds" - } - Group HairData21 - { - HairIndex 1016 - Model "hair/hair_8_1.gr2" - SourceSkin "hair/hair_8_1.dds" - TargetSkin "hair/hair_8_1.dds" - } - Group HairData22 - { - HairIndex 1017 - Model "hair/hair_9_1.gr2" - SourceSkin "hair/hair_9_1.dds" - TargetSkin "hair/hair_9_1.dds" - } - Group HairData23 - { - HairIndex 1018 - Model "hair/hair_10_1.gr2" - SourceSkin "hair/hair_10_1.dds" - TargetSkin "hair/hair_10_1.dds" - } - Group HairData24 - { - HairIndex 5001 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_1.dds" - } - Group HairData25 - { - HairIndex 5002 - Model "hair/hair_14_1.gr2" - SourceSkin "hair/hair_14_1.dds" - TargetSkin "hair/hair_14_1.dds" - } - Group HairData26 - { - HairIndex 5005 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_1.dds" - } - Group HairData27 - { - HairIndex 5003 - Model "hair/hair_16_1.gr2" - SourceSkin "hair/hair_16_1.dds" - TargetSkin "hair/hair_16_1.dds" - } - Group HairData28 - { - HairIndex 5004 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_1.dds" - } - Group HairData29 - { - HairIndex 5027 - Model "hair/hair_20_1.gr2" - SourceSkin "hair/hair_20_1.dds" - TargetSkin "hair/hair_20_1.dds" - } - Group HairData30 - { - HairIndex 5023 - Model "hair/hair_13_1.gr2" - SourceSkin "hair/hair_13_1.dds" - TargetSkin "hair/hair_13_1.dds" - } - Group HairData31 - { - HairIndex 5024 - Model "hair/hair_18_1.gr2" - SourceSkin "hair/hair_18_1.dds" - TargetSkin "hair/hair_18_1.dds" - } - Group HairData32 - { - HairIndex 5025 - Model "hair/hair_19_1.gr2" - SourceSkin "hair/hair_19_1.dds" - TargetSkin "hair/hair_19_1.dds" - } - Group HairData33 - { - HairIndex 5028 - Model "hair/hair_22_1.gr2" - SourceSkin "hair/hair_22_1.dds" - TargetSkin "hair/hair_22_3.dds" - } - Group HairData34 - { - HairIndex 5029 - Model "hair/hair_22_1.gr2" - SourceSkin "hair/hair_22_1.dds" - TargetSkin "hair/hair_22_2.dds" - } - Group HairData35 - { - HairIndex 5030 - Model "hair/hair_22_1.gr2" - SourceSkin "hair/hair_22_1.dds" - TargetSkin "hair/hair_22_1.dds" - } - Group HairData36 - { - HairIndex 5031 - Model "hair/hair_23_1.gr2" - SourceSkin "hair/hair_23_1.dds" - TargetSkin "hair/hair_23_1.dds" - } - Group HairData37 - { - HairIndex 5033 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_1.dds" - } - Group HairData38 - { - HairIndex 5035 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_2.dds" - } - Group HairData39 - { - HairIndex 5037 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_3.dds" - } - Group HairData40 - { - HairIndex 5039 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_4.dds" - } - Group HairData41 - { - HairIndex 5041 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_5.dds" - } - Group HairData42 - { - HairIndex 5026 - Model "hair/hair_21_1.gr2" - SourceSkin "hair/hair_21_1.dds" - TargetSkin "hair/hair_21_1.dds" - } - Group HairData43 - { - HairIndex 5045 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_2.dds" - } - Group HairData44 - { - HairIndex 5046 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_3.dds" - } - Group HairData45 - { - HairIndex 5047 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_4.dds" - } - Group HairData46 - { - HairIndex 5048 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_5.dds" - } - Group HairData47 - { - HairIndex 5049 - Model "hair/hair_28_1.gr2" - SourceSkin "hair/hair_28_1.dds" - TargetSkin "hair/hair_28_1.dds" - } - Group HairData48 - { - HairIndex 5050 - Model "hair/hair_28_1.gr2" - SourceSkin "hair/hair_28_1.dds" - TargetSkin "hair/hair_28_1.dds" - } - Group HairData49 - { - HairIndex 5051 - Model "hair/hair_29_1.gr2" - SourceSkin "hair/hair_29_1.dds" - TargetSkin "hair/hair_29_1.dds" - } - Group HairData50 - { - HairIndex 5052 - Model "hair/hair_30_1.gr2" - SourceSkin "hair/hair_30_1.dds" - TargetSkin "hair/hair_30_1.dds" - } - Group HairData51 - { - HairIndex 5053 - Model "hair/hair_31_1.gr2" - SourceSkin "hair/hair_31_1.dds" - TargetSkin "hair/hair_31_1.dds" - } - Group HairData52 - { - HairIndex 5054 - Model "hair/hair_32_1.gr2" - SourceSkin "hair/hair_32_1.dds" - TargetSkin "hair/hair_32_1.dds" - } - Group HairData53 - { - HairIndex 5055 - Model "hair/hair_14_1.gr2" - SourceSkin "hair/hair_14_1.dds" - TargetSkin "hair/hair_14_2.dds" - } - Group HairData54 - { - HairIndex 5057 - Model "hair/hair_33_1.gr2" - SourceSkin "hair/hair_33_1.dds" - TargetSkin "hair/hair_33_1.dds" - } - Group HairData55 - { - HairIndex 5059 - Model "hair/hair_34_1.gr2" - SourceSkin "hair/hair_34_1.dds" - TargetSkin "hair/hair_34_1.dds" - } - Group HairData56 - { - HairIndex 5061 - Model "hair/hair_35_1.gr2" - SourceSkin "hair/hair_35_1.dds" - TargetSkin "hair/hair_35_1.dds" - } - Group HairData57 - { - HairIndex 5063 - Model "hair/hair_37_1.gr2" - SourceSkin "hair/hair_37_1.dds" - TargetSkin "hair/hair_37_1.dds" - } - - Group HairData58 - { - HairIndex 5064 - Model "hair/hair_36_1.gr2" - SourceSkin "hair/hair_36_1.dds" - TargetSkin "hair/hair_36_1.dds" - } - - Group HairData59 - { - HairIndex 5065 - Model "hair/hair_38_1.gr2" - SourceSkin "hair/hair_38_1.dds" - TargetSkin "hair/hair_38_1.dds" - } - Group HairData60 - { - HairIndex 5022 - Model "hair/hair_12_1.gr2" - SourceSkin "hair/hair_12_1.dds" - TargetSkin "hair/hair_12_1.dds" - } - -} - -Group ShapeData -{ - PathName "d:/ymir Work/pc/warrior/" - - ShapeDataCount 146 - Group ShapeData00 - { - ShapeIndex 0 - - Model "warrior_novice.gr2" - SourceSkin "warrior_novice_red.dds" - TargetSkin "warrior_novice_red.dds" - } - Group ShapeData01 - { - ShapeIndex 1 - Model "warrior_novice.gr2" - SourceSkin "warrior_novice_red.dds" - TargetSkin "warrior_novice_blue.dds" - } - Group ShapeData02 - { - ShapeIndex 3 - Model "warrior_nahan.gr2" - SourceSkin "warrior_nahan.dds" - TargetSkin "warrior_nahan.dds" - } - Group ShapeData03 - { - ShapeIndex 4 - Model "warrior_nahan.gr2" - SourceSkin "warrior_nahan.dds" - TargetSkin "warrior_giryung.dds" - } - Group ShapeData04 - { - ShapeIndex 5 - Model "warrior_nahan.gr2" - SourceSkin "warrior_nahan.dds" - TargetSkin "warrior_jaho.dds" - } - Group ShapeData05 - { - ShapeIndex 6 - Model "warrior_saja.gr2" - SourceSkin "warrior_saja.dds" - TargetSkin "warrior_saja.dds" - - } - Group ShapeData06 - { - ShapeIndex 7 - Model "warrior_saja.gr2" - SourceSkin "warrior_saja.dds" - TargetSkin "warrior_jain.dds" - } - Group ShapeData07 - { - ShapeIndex 8 - Model "warrior_saja.gr2" - SourceSkin "warrior_saja.dds" - TargetSkin "warrior_moryong.dds" - } - Group ShapeData08 - { - ShapeIndex 9 - Model "warrior_cheongrin.gr2" - SourceSkin "warrior_cheongrin.dds" - TargetSkin "warrior_cheongrin.dds" - } - Group ShapeData09 - { - ShapeIndex 10 - Model "warrior_cheongrin.gr2" - SourceSkin "warrior_cheongrin.dds" - TargetSkin "warrior_geumrin.dds" - } - Group ShapeData10 - { - ShapeIndex 11 - Model "warrior_yongsin.GR2" - SourceSkin "warrior_yongsin.dds" - TargetSkin "warrior_yongsin.dds" - } - Group ShapeData11 - { - SpecialPath "d:/ymir work/monster/wolf/" - - ShapeIndex 100 - Model "wolf.gr2" - SourceSkin "wolf.dds" - } - Group ShapeData12 - { - SpecialPath "d:/ymir work/monster/wild_boar/" - - ShapeIndex 101 - Model "wild_boar.gr2" - SourceSkin "wild_boar.dds" - } - Group ShapeData13 - { - SpecialPath "d:/ymir work/monster/bear/" - - ShapeIndex 102 - Model "bear.gr2" - SourceSkin "bear.dds" - } - Group ShapeData14 - { - SpecialPath "d:/ymir work/monster/tiger/" - - ShapeIndex 103 - Model "tiger.gr2" - SourceSkin "tiger.dds" - } - Group ShapeData15 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 201 - Model "warrior_marry_01.gr2" - SourceSkin "warrior_marry_01.dds" - TargetSkin "warrior_marry_01.dds" - } - Group ShapeData16 - { - SpecialPath "d:/ymir Work/pc/warrior/" - ShapeIndex 12 - Model "warrior_4-1.GR2" - SourceSkin "warrior_4-1.dds" - TargetSkin "warrior_4-1.dds" - } - Group ShapeData17 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 24 - Model "warrior_lord.GR2" - SourceSkin "warrior_king01.dds" - TargetSkin "warrior_king01.dds" - } - - - Group ShapeData18 - { - ShapeIndex 14 - Model "warrior_nahan.gr2" - SourceSkin "warrior_nahan.dds" - TargetSkin "warrior_1-1_nahan_a.dds" - } - - Group ShapeData19 - { - ShapeIndex 15 - Model "warrior_nahan.gr2" - SourceSkin "warrior_nahan.dds" - TargetSkin "warrior_giryung_a.dds" - } - Group ShapeData20 - { - ShapeIndex 16 - Model "warrior_nahan.gr2" - SourceSkin "warrior_nahan.dds" - TargetSkin "warrior_jaho_a.dds" - } - - Group ShapeData21 - { - ShapeIndex 17 - Model "warrior_saja.gr2" - SourceSkin "warrior_saja.dds" - TargetSkin "warrior_saja_a.dds" - } - Group ShapeData22 - { - ShapeIndex 18 - Model "warrior_saja.gr2" - SourceSkin "warrior_saja.dds" - TargetSkin "warrior_jain_a.dds" - } - Group ShapeData23 - { - ShapeIndex 19 - Model "warrior_saja.gr2" - SourceSkin "warrior_saja.dds" - TargetSkin "warrior_2-3_moryong_a.DDS" - } - Group ShapeData24 - { - ShapeIndex 20 - Model "warrior_cheongrin.gr2" - SourceSkin "warrior_cheongrin.dds" - TargetSkin "warrior_3-1_cheongrin_a.dds" - } - Group ShapeData25 - { - ShapeIndex 21 - Model "warrior_cheongrin.gr2" - SourceSkin "warrior_cheongrin.dds" - TargetSkin "warrior_3-2_geumrin_a.dds" - } - Group ShapeData26 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 25 - Model "warrior_lord.GR2" - SourceSkin "warrior_king01.dds" - TargetSkin "warrior_king02.dds" - } - Group ShapeData27 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 26 - Model "warrior_4-1.GR2" - SourceSkin "warrior_4-1.dds" - TargetSkin "warrior_4-2.dds" - } - Group ShapeData28 - { - - ShapeIndex 27 - Model "warrior_event1.GR2" - SourceSkin "warrior_event1_yellow.dds" - TargetSkin "warrior_event1_red.dds" - } - Group ShapeData29 - { - - ShapeIndex 28 - Model "warrior_event1.GR2" - SourceSkin "warrior_event1_yellow.dds" - TargetSkin "warrior_event1_yellow.dds" - } - Group ShapeData30 - { - - ShapeIndex 29 - Model "warrior_event1.GR2" - SourceSkin "warrior_event1_yellow.dds" - TargetSkin "warrior_event1_blue.dds" - } - Group ShapeData31 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 30 - Model "warrior_nahan.gr2" - SourceSkin "warrior_nahan.dds" - TargetSkin "warrior_costume1.dds" - } - Group ShapeData32 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40031 - Model "warrior_rabbit1.GR2" - SourceSkin "warrior_rabbit1.dds" - TargetSkin "warrior_rabbit1.dds" - } - Group ShapeData33 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40033 - Model "warrior_fencing1_Germany.GR2" - SourceSkin "warrior_fencing1_Germany.dds" - TargetSkin "warrior_fencing1_London.dds" - } - Group ShapeData34 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40034 - Model "warrior_fencing1_Germany.GR2" - SourceSkin "warrior_fencing1_Germany.dds" - TargetSkin "warrior_fencing1_Germany.dds" - } - Group ShapeData35 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40035 - Model "warrior_fencing1_Germany.GR2" - SourceSkin "warrior_fencing1_Germany.dds" - TargetSkin "warrior_fencing1_Turkey.dds" - } - Group ShapeData36 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40036 - Model "warrior_fencing1_Germany.GR2" - SourceSkin "warrior_fencing1_Germany.dds" - TargetSkin "warrior_fencing1_Brazil.dds" - } - Group ShapeData37 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40037 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_soccer1_London.dds" - } - Group ShapeData38 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40038 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_soccer1_Germany.dds" - } - Group ShapeData39 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40039 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_soccer1_Turkey.dds" - } - Group ShapeData40 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40040 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_soccer1_Brazil.dds" - } - Group ShapeData41 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40041 - Model "warrior_boxing1_Germany.GR2" - SourceSkin "warrior_boxing1_Germany.dds" - TargetSkin "warrior_boxing1_London.dds" - } - Group ShapeData42 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40042 - Model "warrior_boxing1_Germany.GR2" - SourceSkin "warrior_boxing1_Germany.dds" - TargetSkin "warrior_boxing1_Germany.dds" - } - Group ShapeData43 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40043 - Model "warrior_boxing1_Germany.GR2" - SourceSkin "warrior_boxing1_Germany.dds" - TargetSkin "warrior_boxing1_Turkey.dds" - } - Group ShapeData44 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40044 - Model "warrior_boxing1_Germany.GR2" - SourceSkin "warrior_boxing1_Germany.dds" - TargetSkin "warrior_boxing1_Brazil.dds" - } - Group ShapeData45 - { - - ShapeIndex 40032 - Model "warrior_assasin1.GR2" - SourceSkin "warrior_assassin1.dds" - TargetSkin "warrior_assassin1.dds" - } - Group ShapeData46 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40045 - Model "warrior_fencing1_Germany.GR2" - SourceSkin "warrior_fencing1_Germany.dds" - TargetSkin "warrior_fencing1_France.dds" - } - Group ShapeData47 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40046 - Model "warrior_fencing1_Germany.GR2" - SourceSkin "warrior_fencing1_Germany.dds" - TargetSkin "warrior_fencing1_Italy.dds" - } - Group ShapeData48 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40047 - Model "warrior_fencing1_Germany.GR2" - SourceSkin "warrior_fencing1_Germany.dds" - TargetSkin "warrior_fencing1_Poland.dds" - } - Group ShapeData49 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40048 - Model "warrior_fencing1_Germany.GR2" - SourceSkin "warrior_fencing1_Germany.dds" - TargetSkin "warrior_fencing1_Romania.dds" - } - Group ShapeData50 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40049 - Model "warrior_fencing1_Germany.GR2" - SourceSkin "warrior_fencing1_Germany.dds" - TargetSkin "warrior_fencing1_Spain.dds" - } - Group ShapeData51 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40050 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_soccer1_France.dds" - } - Group ShapeData52 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40051 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_soccer1_Italy.dds" - } - Group ShapeData53 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40052 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_soccer1_Poland.dds" - } - Group ShapeData54 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40053 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_soccer1_Romania.dds" - } - Group ShapeData55 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40054 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_soccer1_Spain.dds" - } - Group ShapeData56 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40055 - Model "warrior_boxing1_Germany.GR2" - SourceSkin "warrior_boxing1_Germany.dds" - TargetSkin "warrior_boxing1_France.dds" - } - Group ShapeData57 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40056 - Model "warrior_boxing1_Germany.GR2" - SourceSkin "warrior_boxing1_Germany.dds" - TargetSkin "warrior_boxing1_Italy.dds" - } - Group ShapeData58 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40057 - Model "warrior_boxing1_Germany.GR2" - SourceSkin "warrior_boxing1_Germany.dds" - TargetSkin "warrior_boxing1_Poland.dds" - } - Group ShapeData59 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40058 - Model "warrior_boxing1_Germany.GR2" - SourceSkin "warrior_boxing1_Germany.dds" - TargetSkin "warrior_boxing1_Romaina.dds" - } - Group ShapeData60 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40059 - Model "warrior_boxing1_Germany.GR2" - SourceSkin "warrior_boxing1_Germany.dds" - TargetSkin "warrior_boxing1_Spain.dds" - } - Group ShapeData61 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40065 - Model "warrior_halloween1.GR2" - SourceSkin "warrior_halloween1.dds" - TargetSkin "warrior_halloween1.dds" - } - Group ShapeData62 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 13 - Model "warrior_5_1.GR2" - SourceSkin "warrior_5_1.dds" - TargetSkin "warrior_5_1.dds" - } - Group ShapeData63 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40062 - Model "warrior_salsa1.GR2" - SourceSkin "warrior_salsa1.dds" - TargetSkin "warrior_salsa1.dds" - } - Group ShapeData64 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40063 - Model "warrior_Springwear1.GR2" - SourceSkin "warrior_Springwear1.dds" - TargetSkin "warrior_Springwear1.dds" - } - Group ShapeData65 - { - SpecialPath "d:/ymir Work/pc/warrior/" - - ShapeIndex 40061 - Model "warrior_tailcoat1.gr2" - SourceSkin "warrior_tailcoat1.dds" - TargetSkin "warrior_tailcoat1.dds" - } - Group ShapeData66 - { - SpecialPath "d:/ymir Work/pc/warrior/" - ShapeIndex 40069 - Model "warrior_deer1.gr2" - SourceSkin "warrior_deer1.dds" - TargetSkin "warrior_deer1.dds" - } - Group ShapeData67 - { - SpecialPath "d:/ymir Work/pc/warrior/" - ShapeIndex 40066 - Model "warrior_santa1_black.gr2" - SourceSkin "warrior_santa1_black.dds" - TargetSkin "warrior_santa1_red.dds" - } - Group ShapeData68 - { - SpecialPath "d:/ymir Work/pc/warrior/" - ShapeIndex 40067 - Model "warrior_santa1_black.gr2" - SourceSkin "warrior_santa1_black.dds" - TargetSkin "warrior_santa1_green.dds" - } - Group ShapeData69 - { - SpecialPath "d:/ymir Work/pc/warrior/" - ShapeIndex 40068 - Model "warrior_santa1_black.gr2" - SourceSkin "warrior_santa1_black.dds" - TargetSkin "warrior_santa1_black.dds" - } - Group ShapeData70 - { - ShapeIndex 40070 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA01.dds" - } - Group ShapeData71 - { - ShapeIndex 40071 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA02.dds" - } - Group ShapeData72 - { - ShapeIndex 40072 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA03.dds" - } - Group ShapeData73 - { - ShapeIndex 40073 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA04.dds" - } - Group ShapeData74 - { - ShapeIndex 40074 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA05.dds" - } - Group ShapeData75 - { - ShapeIndex 40075 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA06.dds" - } - Group ShapeData76 - { - ShapeIndex 40076 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA07.dds" - } - Group ShapeData77 - { - ShapeIndex 40077 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA08.dds" - } - Group ShapeData78 - { - ShapeIndex 40078 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA09.dds" - } - Group ShapeData79 - { - ShapeIndex 40079 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA10.dds" - } - Group ShapeData80 - { - ShapeIndex 40080 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA11.dds" - } - Group ShapeData81 - { - ShapeIndex 40081 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA12.dds" - } - Group ShapeData82 - { - ShapeIndex 40082 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA13.dds" - } - Group ShapeData83 - { - ShapeIndex 40083 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA14.dds" - } - Group ShapeData84 - { - ShapeIndex 40084 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA15.dds" - } - Group ShapeData85 - { - ShapeIndex 40085 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA16.dds" - } - Group ShapeData86 - { - ShapeIndex 40086 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA17.dds" - } - Group ShapeData87 - { - ShapeIndex 40087 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA18.dds" - } - Group ShapeData88 - { - ShapeIndex 40088 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA19.dds" - } - Group ShapeData89 - { - ShapeIndex 40089 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA20.dds" - } - Group ShapeData90 - { - ShapeIndex 40090 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA21.dds" - } - Group ShapeData91 - { - ShapeIndex 40091 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA22.dds" - } - Group ShapeData92 - { - ShapeIndex 40092 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA23.dds" - } - Group ShapeData93 - { - ShapeIndex 40093 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA24.dds" - } - Group ShapeData94 - { - ShapeIndex 40094 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA25.dds" - } - Group ShapeData95 - { - ShapeIndex 40095 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA26.dds" - } - Group ShapeData96 - { - ShapeIndex 40096 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA27.dds" - } - Group ShapeData97 - { - ShapeIndex 40097 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA28.dds" - } - Group ShapeData98 - { - ShapeIndex 40098 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA29.dds" - } - Group ShapeData99 - { - ShapeIndex 40099 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA30.dds" - } - Group ShapeData100 - { - ShapeIndex 40100 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA31.dds" - } - Group ShapeData101 - { - ShapeIndex 40101 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA32.dds" - } - Group ShapeData102 - { - ShapeIndex 40064 - Model "warrior_samurai1.GR2" - SourceSkin "warrior_samurai1.dds" - TargetSkin "warrior_samurai1.dds" - } - Group ShapeData103 - { - ShapeIndex 40106 - Model "warrior_rabbit1.GR2" - SourceSkin "warrior_rabbit1.dds" - TargetSkin "warrior_rabbit1_black.dds" - } - Group ShapeData104 - { - ShapeIndex 40107 - Model "warrior_rabbit1.GR2" - SourceSkin "warrior_rabbit1.dds" - TargetSkin "warrior_rabbit1_blue.dds" - } - Group ShapeData105 - { - ShapeIndex 40108 - Model "warrior_rabbit1.GR2" - SourceSkin "warrior_rabbit1.dds" - TargetSkin "warrior_rabbit1_green.dds" - } - Group ShapeData106 - { - ShapeIndex 40109 - Model "warrior_rabbit1.GR2" - SourceSkin "warrior_rabbit1.dds" - TargetSkin "warrior_rabbit1_pink.dds" - } - Group ShapeData107 - { - ShapeIndex 40110 - Model "warrior_BlackSnake1.GR2" - SourceSkin "warrior_BlackSnake1.dds" - TargetSkin "warrior_BlackSnake1.dds" - } - Group ShapeData108 - { - ShapeIndex 40111 - Model "warrior_BlackSnake1.GR2" - SourceSkin "warrior_BlackSnake1.dds" - TargetSkin "warrior_BlackSnake1.dds" - } - Group ShapeData109 - { - ShapeIndex 40112 - Model "warrior_assasin1.GR2" - SourceSkin "warrior_assassin1.dds" - TargetSkin "warrior_assasin2.dds" - } - Group ShapeData110 - { - ShapeIndex 40114 - Model "warrior_pwahuang1.GR2" - SourceSkin "warrior_pwahuang1.dds" - TargetSkin "warrior_pwahuang1.dds" - } - Group ShapeData111 - { - ShapeIndex 40116 - Model "warrior_halloween2.GR2" - SourceSkin "warrior_halloween2.dds" - TargetSkin "warrior_halloween2.dds" - } - Group ShapeData112 - { - ShapeIndex 40118 - Model "warrior_assasin1.GR2" - SourceSkin "warrior_assassin1.dds" - TargetSkin "warrior_assassin3.dds" - } - Group ShapeData113 - { - ShapeIndex 40060 - Model "warrior_capoeira1.GR2" - SourceSkin "warrior_capoeira1.dds" - TargetSkin "warrior_capoeira1.dds" - } - Group ShapeData114 - { - ShapeIndex 40120 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC01.dds" - } - Group ShapeData115 - { - ShapeIndex 40122 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC02.dds" - } - Group ShapeData116 - { - ShapeIndex 40124 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC03.dds" - } - Group ShapeData117 - { - ShapeIndex 40126 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC04.dds" - } - Group ShapeData118 - { - ShapeIndex 40128 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC05.dds" - } - Group ShapeData119 - { - ShapeIndex 40130 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC06.dds" - } - Group ShapeData120 - { - ShapeIndex 40132 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC07.dds" - } - Group ShapeData121 - { - ShapeIndex 40134 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC08.dds" - } - Group ShapeData122 - { - ShapeIndex 40136 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC09.dds" - } - Group ShapeData123 - { - ShapeIndex 40138 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC10.dds" - } - Group ShapeData124 - { - ShapeIndex 40140 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC11.dds" - } - Group ShapeData125 - { - ShapeIndex 40142 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC12.dds" - } - Group ShapeData126 - { - ShapeIndex 40144 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC13.dds" - } - Group ShapeData127 - { - ShapeIndex 40146 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC14.dds" - } - Group ShapeData128 - { - ShapeIndex 40148 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC15.dds" - } - Group ShapeData129 - { - ShapeIndex 40150 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC16.dds" - } - Group ShapeData130 - { - ShapeIndex 40152 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC17.dds" - } - Group ShapeData131 - { - ShapeIndex 40154 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC18.dds" - } - Group ShapeData132 - { - ShapeIndex 40156 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC19.dds" - } - Group ShapeData133 - { - ShapeIndex 40158 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC20.dds" - } - Group ShapeData134 - { - ShapeIndex 40160 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC21.dds" - } - Group ShapeData135 - { - ShapeIndex 40162 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC22.dds" - } - Group ShapeData136 - { - ShapeIndex 40164 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC23.dds" - } - Group ShapeData137 - { - ShapeIndex 40166 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC24.dds" - } - Group ShapeData138 - { - ShapeIndex 40168 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC25.dds" - } - Group ShapeData139 - { - ShapeIndex 40170 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC26.dds" - } - Group ShapeData140 - { - ShapeIndex 40172 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC27.dds" - } - Group ShapeData141 - { - ShapeIndex 40174 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC28.dds" - } - Group ShapeData142 - { - ShapeIndex 40176 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC29.dds" - } - Group ShapeData143 - { - ShapeIndex 40178 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC30.dds" - } - Group ShapeData144 - { - ShapeIndex 40180 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC31.dds" - } - Group ShapeData145 - { - ShapeIndex 40182 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC32.dds" - } -} - -Group AttachingData -{ - AttachingDataCount 2 - - Group AttachingData00 - { - AttachingDataType 1 - - isAttaching 0 - AttachingModelIndex 0 - AttachingBoneName "Bip01" - - CollisionType 1 - - SphereDataCount 1 - Group SphereData00 - { - Radius 40.000000 - Position 0.000000 0.000000 100.000000 - } - } - - Group AttachingData01 - { - AttachingDataType 1 - - isAttaching 0 - AttachingModelIndex 0 - AttachingBoneName "Bip01" - - CollisionType 3 - - SphereDataCount 1 - Group SphereData00 - { - Radius 70.000000 - Position 0.000000 0.000000 100.000000 - } - } -} diff --git a/tools/root/msm/warrior_w.msm b/tools/root/msm/warrior_w.msm deleted file mode 100644 index 10d7172d..00000000 --- a/tools/root/msm/warrior_w.msm +++ /dev/null @@ -1,1690 +0,0 @@ -ScriptType RaceDataScript - -BaseModelFileName "d:/ymir work/pc2/warrior/warrior_novice.GR2" - -Group HairData -{ - PathName "d:/ymir Work/pc2/warrior/" - - HairDataCount 75 - Group HairData00 - { - HairIndex 0 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "warrior_hair_01.dds" - } - Group HairData01 - { - HairIndex 1 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "warrior_hair_01_white.dds" - } - Group HairData02 - { - HairIndex 2 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "warrior_hair_01_gold.dds" - } - Group HairData03 - { - HairIndex 3 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "warrior_hair_01_red.dds" - } - Group HairData04 - { - HairIndex 4 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "warrior_hair_01_brown.dds" - } - Group HairData05 - { - HairIndex 5 - Model "hair/hair_1_1.gr2" - SourceSkin "hair/hair_1_1.dds" - TargetSkin "warrior_hair_01_black.dds" - } - Group HairData06 - { - HairIndex 1001 - Model "hair/hair_2_1.gr2" - SourceSkin "hair/hair_2_1.dds" - TargetSkin "hair/hair_2_1.dds" - } - Group HairData07 - { - HairIndex 1002 - Model "hair/hair_2_1.gr2" - SourceSkin "hair/hair_2_1.dds" - TargetSkin "hair/hair_2_2.dds" - } - Group HairData08 - { - HairIndex 1003 - Model "hair/hair_2_1.gr2" - SourceSkin "hair/hair_2_1.dds" - TargetSkin "hair/hair_2_3.dds" - } - Group HairData09 - { - HairIndex 1004 - Model "hair/hair_2_1.gr2" - SourceSkin "hair/hair_2_1.dds" - TargetSkin "hair/hair_2_4.dds" - } - Group HairData10 - { - HairIndex 1005 - Model "hair/hair_3_1.gr2" - SourceSkin "hair/hair_3_1.dds" - TargetSkin "hair/hair_3_1.dds" - } - Group HairData11 - { - HairIndex 1006 - Model "hair/hair_3_1.gr2" - SourceSkin "hair/hair_3_1.dds" - TargetSkin "hair/hair_3_2.dds" - } - Group HairData12 - { - HairIndex 1007 - Model "hair/hair_3_1.gr2" - SourceSkin "hair/hair_3_1.dds" - TargetSkin "hair/hair_3_3.dds" - } - Group HairData13 - { - HairIndex 1008 - Model "hair/hair_3_1.gr2" - SourceSkin "hair/hair_3_1.dds" - TargetSkin "hair/hair_3_4.dds" - } - Group HairData14 - { - HairIndex 1009 - Model "hair/hair_4_1.gr2" - SourceSkin "hair/hair_4_1.dds" - TargetSkin "hair/hair_4_1.dds" - } - Group HairData15 - { - HairIndex 1010 - Model "hair/hair_4_1.gr2" - SourceSkin "hair/hair_4_1.dds" - TargetSkin "hair/hair_4_2.dds" - } - Group HairData16 - { - HairIndex 1011 - Model "hair/hair_4_1.gr2" - SourceSkin "hair/hair_4_1.dds" - TargetSkin "hair/hair_4_3.dds" - } - Group HairData17 - { - HairIndex 1012 - Model "hair/hair_4_1.gr2" - SourceSkin "hair/hair_4_1.dds" - TargetSkin "hair/hair_4_4.dds" - } - Group HairData18 - { - HairIndex 1013 - Model "hair/hair_6_1.gr2" - SourceSkin "hair/hair_6_1.dds" - TargetSkin "hair/hair_6_1.dds" - } - Group HairData19 - { - HairIndex 1014 - Model "hair/hair_5_1.gr2" - SourceSkin "hair/hair_5_1.dds" - TargetSkin "hair/hair_5_1.dds" - } - Group HairData20 - { - HairIndex 1015 - Model "hair/hair_7_1.gr2" - SourceSkin "hair/hair_7_1.dds" - TargetSkin "hair/hair_7_1.dds" - } - Group HairData21 - { - HairIndex 1016 - Model "hair/hair_8_1.gr2" - SourceSkin "hair/hair_8_1.dds" - TargetSkin "hair/hair_8_1.dds" - } - Group HairData22 - { - HairIndex 1017 - Model "hair/hair_9_1.gr2" - SourceSkin "hair/hair_9_1.dds" - TargetSkin "hair/hair_9_1.dds" - } - Group HairData23 - { - HairIndex 1018 - Model "hair/hair_10_1.gr2" - SourceSkin "hair/hair_10_1.dds" - TargetSkin "hair/hair_10_1.dds" - } - Group HairData24 - { - HairIndex 5001 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_1.dds" - } - Group HairData25 - { - HairIndex 5002 - Model "hair/hair_14_1.gr2" - SourceSkin "hair/hair_14_1.dds" - TargetSkin "hair/hair_14_1.dds" - } - Group HairData26 - { - HairIndex 5006 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_1.dds" - } - Group HairData27 - { - HairIndex 5003 - Model "hair/hair_16_1.gr2" - SourceSkin "hair/hair_16_1.dds" - TargetSkin "hair/hair_16_1.dds" - } - Group HairData28 - { - HairIndex 5014 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_1.dds" - } - - Group HairData29 - { - HairIndex 5005 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_2.dds" - } - Group HairData30 - { - HairIndex 5007 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_3.dds" - } - Group HairData31 - { - HairIndex 5008 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_4.dds" - } - Group HairData32 - { - HairIndex 5009 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_5.dds" - } - Group HairData33 - { - HairIndex 5010 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_6.dds" - } - Group HairData34 - { - HairIndex 5011 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_7.dds" - } - Group HairData35 - { - HairIndex 5012 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_8.dds" - } - Group HairData36 - { - HairIndex 5013 - Model "hair/hair_15_1.gr2" - SourceSkin "hair/hair_15_1.dds" - TargetSkin "hair/hair_15_9.dds" - } - Group HairData37 - { - HairIndex 5004 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_2.dds" - } - Group HairData38 - { - HairIndex 5015 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_3.dds" - } - Group HairData39 - { - HairIndex 5016 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_4.dds" - } - Group HairData40 - { - HairIndex 5017 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_5.dds" - } - Group HairData41 - { - HairIndex 5018 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_6.dds" - } - Group HairData42 - { - HairIndex 5019 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_7.dds" - } - Group HairData43 - { - HairIndex 5020 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_8.dds" - } - Group HairData44 - { - HairIndex 5021 - Model "hair/hair_17_1.gr2" - SourceSkin "hair/hair_17_1.dds" - TargetSkin "hair/hair_17_9.dds" - } - Group HairData45 - { - HairIndex 5027 - Model "hair/hair_20_1.gr2" - SourceSkin "hair/hair_20_1.dds" - TargetSkin "hair/hair_20_1.dds" - } - Group HairData46 - { - HairIndex 5023 - Model "hair/hair_13_1.gr2" - SourceSkin "hair/hair_13_1.dds" - TargetSkin "hair/hair_13_1.dds" - } - Group HairData47 - { - HairIndex 5024 - Model "hair/hair_18_1.gr2" - SourceSkin "hair/hair_18_1.dds" - TargetSkin "hair/hair_18_1.dds" - } - Group HairData48 - { - HairIndex 5025 - Model "hair/hair_19_1.gr2" - SourceSkin "hair/hair_19_1.dds" - TargetSkin "hair/hair_19_1.dds" - } - Group HairData49 - { - HairIndex 5030 - Model "hair/hair_22_1.gr2" - SourceSkin "hair/hair_22_1.dds" - TargetSkin "hair/hair_22_1.dds" - } - Group HairData50 - { - HairIndex 5031 - Model "hair/hair_23_1.gr2" - SourceSkin "hair/hair_23_1.dds" - TargetSkin "hair/hair_23_1.dds" - } - Group HairData51 - { - HairIndex 5034 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_1.dds" - } - Group HairData52 - { - HairIndex 5036 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_2.dds" - } - Group HairData53 - { - HairIndex 5038 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_3.dds" - } - Group HairData54 - { - HairIndex 5040 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_4.dds" - } - Group HairData55 - { - HairIndex 5042 - Model "hair/hair_24_1.gr2" - SourceSkin "hair/hair_24_1.dds" - TargetSkin "hair/hair_24_5.dds" - } - Group HairData56 - { - HairIndex 5026 - Model "hair/hair_21_1.gr2" - SourceSkin "hair/hair_21_1.dds" - TargetSkin "hair/hair_21_1.dds" - } - Group HairData57 - { - HairIndex 5045 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_2.dds" - } - Group HairData58 - { - HairIndex 5046 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_3.dds" - } - Group HairData59 - { - HairIndex 5047 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_4.dds" - } - Group HairData60 - { - HairIndex 5048 - Model "hair/hair_11_1.gr2" - SourceSkin "hair/hair_11_1.dds" - TargetSkin "hair/hair_11_5.dds" - } - Group HairData61 - { - HairIndex 5049 - Model "hair/hair_28_1.gr2" - SourceSkin "hair/hair_28_1.dds" - TargetSkin "hair/hair_28_1.dds" - } - Group HairData62 - { - HairIndex 5050 - Model "hair/hair_28_1.gr2" - SourceSkin "hair/hair_28_1.dds" - TargetSkin "hair/hair_28_1.dds" - } - Group HairData63 - { - HairIndex 5051 - Model "hair/hair_29_1.gr2" - SourceSkin "hair/hair_29_1.dds" - TargetSkin "hair/hair_29_1.dds" - } - Group HairData64 - { - HairIndex 5052 - Model "hair/hair_30_1.gr2" - SourceSkin "hair/hair_30_1.dds" - TargetSkin "hair/hair_30_1.dds" - } - Group HairData65 - { - HairIndex 5053 - Model "hair/hair_31_1.gr2" - SourceSkin "hair/hair_31_1.dds" - TargetSkin "hair/hair_31_1.dds" - } - Group HairData66 - { - HairIndex 5054 - Model "hair/hair_32_1.gr2" - SourceSkin "hair/hair_32_1.dds" - TargetSkin "hair/hair_32_1.dds" - } - Group HairData67 - { - HairIndex 5056 - Model "hair/hair_14_1.gr2" - SourceSkin "hair/hair_14_1.dds" - TargetSkin "hair/hair_14_2.dds" - } - Group HairData68 - { - HairIndex 5058 - Model "hair/hair_33_1.gr2" - SourceSkin "hair/hair_33_1.dds" - TargetSkin "hair/hair_33_1.dds" - } - Group HairData69 - { - HairIndex 5060 - Model "hair/hair_34_1.gr2" - SourceSkin "hair/hair_34_1.dds" - TargetSkin "hair/hair_34_1.dds" - } - Group HairData70 - { - HairIndex 5062 - Model "hair/hair_35_1.gr2" - SourceSkin "hair/hair_35_1.dds" - TargetSkin "hair/hair_35_1.dds" - } - Group HairData71 - { - HairIndex 5063 - Model "hair/hair_37_1.gr2" - SourceSkin "hair/hair_37_1.dds" - TargetSkin "hair/hair_37_1.dds" - } - - Group HairData72 - { - HairIndex 5064 - Model "hair/hair_36_1.gr2" - SourceSkin "hair/hair_36_1.dds" - TargetSkin "hair/hair_36_1.dds" - } - - Group HairData73 - { - HairIndex 5065 - Model "hair/hair_38_1.gr2" - SourceSkin "hair/hair_38_1.dds" - TargetSkin "hair/hair_38_1.dds" - } - Group HairData74 - { - HairIndex 5022 - Model "hair/hair_12_1.gr2" - SourceSkin "hair/hair_12_1.dds" - TargetSkin "hair/hair_12_1.dds" - } - -} - -Group ShapeData -{ - PathName "d:/ymir Work/pc2/warrior/" - - ShapeDataCount 146 - Group ShapeData00 - { - ShapeIndex 0 - - Model "warrior_novice.gr2" - SourceSkin "warrior_novice_red.dds" - TargetSkin "warrior_novice_red.dds" - } - Group ShapeData01 - { - ShapeIndex 1 - Model "warrior_novice.gr2" - SourceSkin "warrior_novice_red.dds" - TargetSkin "warrior_novice_blue.dds" - } - Group ShapeData02 - { - ShapeIndex 3 - Model "warrior_nahan.gr2" - SourceSkin "warrior_nahan.dds" - TargetSkin "warrior_nahan.dds" - } - Group ShapeData03 - { - ShapeIndex 4 - Model "warrior_nahan.gr2" - SourceSkin "warrior_nahan.dds" - TargetSkin "warrior_giryung.dds" - } - Group ShapeData04 - { - ShapeIndex 5 - Model "warrior_nahan.gr2" - SourceSkin "warrior_nahan.dds" - TargetSkin "warrior_jaho.dds" - } - Group ShapeData05 - { - ShapeIndex 6 - Model "warrior_saja.gr2" - SourceSkin "warrior_saja.dds" - TargetSkin "warrior_saja.dds" - - } - Group ShapeData06 - { - ShapeIndex 7 - Model "warrior_saja.gr2" - SourceSkin "warrior_saja.dds" - TargetSkin "warrior_jain.dds" - } - Group ShapeData07 - { - ShapeIndex 8 - Model "warrior_saja.gr2" - SourceSkin "warrior_saja.dds" - TargetSkin "warrior_moryong.dds" - } - Group ShapeData08 - { - ShapeIndex 9 - Model "warrior_cheongrin.gr2" - SourceSkin "warrior_cheongrin.dds" - TargetSkin "warrior_cheongrin.dds" - } - Group ShapeData09 - { - ShapeIndex 10 - Model "warrior_cheongrin.gr2" - SourceSkin "warrior_cheongrin.dds" - TargetSkin "warrior_geumrin.dds" - } - Group ShapeData10 - { - ShapeIndex 11 - Model "warrior_yongsin.GR2" - SourceSkin "warrior_yongsin.dds" - TargetSkin "warrior_yongsin.dds" - } - Group ShapeData11 - { - SpecialPath "d:/ymir work/monster/wolf/" - - ShapeIndex 100 - Model "wolf.gr2" - SourceSkin "wolf.dds" - } - Group ShapeData12 - { - SpecialPath "d:/ymir work/monster/wild_boar/" - - ShapeIndex 101 - Model "wild_boar.gr2" - SourceSkin "wild_boar.dds" - } - Group ShapeData13 - { - SpecialPath "d:/ymir work/monster/bear/" - - ShapeIndex 102 - Model "bear.gr2" - SourceSkin "bear.dds" - } - Group ShapeData14 - { - SpecialPath "d:/ymir work/monster/tiger/" - - ShapeIndex 103 - Model "tiger.gr2" - SourceSkin "tiger.dds" - } - Group ShapeData15 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 201 - Model "warrior_marry_01.gr2" - SourceSkin "warrior_marry_01.dds" - TargetSkin "warrior_marry_01.dds" - } - Group ShapeData16 - { - ShapeIndex 12 - Model "warrior_4-1.GR2" - SourceSkin "warrior_4-1.dds" - TargetSkin "warrior_4-1.dds" - } - Group ShapeData17 - { - ShapeIndex 24 - Model "warrior_lord.GR2" - SourceSkin "warrior_king01.dds" - TargetSkin "warrior_king01.dds" - } - - - Group ShapeData18 - { - ShapeIndex 14 - Model "warrior_nahan.gr2" - SourceSkin "warrior_nahan.dds" - TargetSkin "warrior_1-1_nahan_a.dds" - } - - Group ShapeData19 - { - ShapeIndex 15 - Model "warrior_nahan.gr2" - SourceSkin "warrior_nahan.dds" - TargetSkin "warrior_giryung_a.dds" - } - Group ShapeData20 - { - ShapeIndex 16 - Model "warrior_nahan.gr2" - SourceSkin "warrior_nahan.dds" - TargetSkin "warrior_jaho_a.dds" - } - - Group ShapeData21 - { - ShapeIndex 17 - Model "warrior_saja.gr2" - SourceSkin "warrior_saja.dds" - TargetSkin "warrior_saja_a.dds" - } - Group ShapeData22 - { - ShapeIndex 18 - Model "warrior_saja.gr2" - SourceSkin "warrior_saja.dds" - TargetSkin "warrior_jain_a.dds" - } - Group ShapeData23 - { - ShapeIndex 19 - Model "warrior_saja.gr2" - SourceSkin "warrior_saja.dds" - TargetSkin "warrior_2-3_moryong_a.DDS" - } - Group ShapeData24 - { - ShapeIndex 20 - Model "warrior_cheongrin.gr2" - SourceSkin "warrior_cheongrin.dds" - TargetSkin "warrior_3-1_cheongrin_a.dds" - } - Group ShapeData25 - { - ShapeIndex 21 - Model "warrior_cheongrin.gr2" - SourceSkin "warrior_cheongrin.dds" - TargetSkin "warrior_3-2_geumrin_a.dds" - } - Group ShapeData26 - { - ShapeIndex 25 - Model "warrior_lord.GR2" - SourceSkin "warrior_king01.dds" - TargetSkin "warrior_king02.dds" - } - Group ShapeData27 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 26 - Model "warrior_4-1.GR2" - SourceSkin "warrior_4-1.dds" - TargetSkin "warrior_4-2.dds" - } - Group ShapeData28 - { - - ShapeIndex 27 - Model "warrior_event1.GR2" - SourceSkin "warrior_event1_yellow.dds" - TargetSkin "warrior_event1_red.dds" - } - Group ShapeData29 - { - - ShapeIndex 28 - Model "warrior_event1.GR2" - SourceSkin "warrior_event1_yellow.dds" - TargetSkin "warrior_event1_yellow.dds" - } - Group ShapeData30 - { - - ShapeIndex 29 - Model "warrior_event1.GR2" - SourceSkin "warrior_event1_yellow.dds" - TargetSkin "warrior_event1_blue.dds" - } - Group ShapeData31 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 30 - Model "warrior_nahan.gr2" - SourceSkin "warrior_nahan.dds" - TargetSkin "warrior_costume1.dds" - } - Group ShapeData32 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40031 - Model "warrior_rabbit1.gr2" - SourceSkin "warrior_rabbit1.dds" - TargetSkin "warrior_rabbit1.dds" - } - Group ShapeData33 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40033 - Model "warrior_fencing1_Germany.gr2" - SourceSkin "warrior_fencing1_Germany.dds" - TargetSkin "warrior_fencing1_London.dds" - } - Group ShapeData34 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40034 - Model "warrior_fencing1_Germany.gr2" - SourceSkin "warrior_fencing1_Germany.dds" - TargetSkin "warrior_fencing1_Germany.dds" - } - Group ShapeData35 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40035 - Model "warrior_fencing1_Germany.gr2" - SourceSkin "warrior_fencing1_Germany.dds" - TargetSkin "warrior_fencing1_Turkey.dds" - } - Group ShapeData36 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40036 - Model "warrior_fencing1_Germany.gr2" - SourceSkin "warrior_fencing1_Germany.dds" - TargetSkin "warrior_fencing1_Brazil.dds" - } - Group ShapeData37 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40037 - Model "warrior_soccer1_Germany.gr2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_soccer1_London.dds" - } - Group ShapeData38 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40038 - Model "warrior_soccer1_Germany.gr2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_soccer1_Germany.dds" - } - Group ShapeData39 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40039 - Model "warrior_soccer1_Germany.gr2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_soccer1_Turkey.dds" - } - Group ShapeData40 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40040 - Model "warrior_soccer1_Germany.gr2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_soccer1_Brazil.dds" - } - Group ShapeData41 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40041 - Model "warrior_boxing1_Germany.gr2" - SourceSkin "warrior_boxing1_Germany.dds" - TargetSkin "warrior_boxing1_London.dds" - } - Group ShapeData42 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40042 - Model "warrior_boxing1_Germany.gr2" - SourceSkin "warrior_boxing1_Germany.dds" - TargetSkin "warrior_boxing1_Germany.dds" - } - Group ShapeData43 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40043 - Model "warrior_boxing1_Germany.gr2" - SourceSkin "warrior_boxing1_Germany.dds" - TargetSkin "warrior_boxing1_Turkey.dds" - } - Group ShapeData44 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40044 - Model "warrior_boxing1_Germany.gr2" - SourceSkin "warrior_boxing1_Germany.dds" - TargetSkin "warrior_boxing1_Brazil.dds" - } - Group ShapeData45 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40032 - Model "warrior_assassin1.gr2" - SourceSkin "warrior_assassin1.dds" - TargetSkin "warrior_assassin1.dds" - } - Group ShapeData46 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40045 - Model "warrior_fencing1_Germany.gr2" - SourceSkin "warrior_fencing1_Germany.dds" - TargetSkin "warrior_fencing1_France.dds" - } - Group ShapeData47 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40046 - Model "warrior_fencing1_Germany.gr2" - SourceSkin "warrior_fencing1_Germany.dds" - TargetSkin "warrior_fencing1_Italy.dds" - } - Group ShapeData48 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40047 - Model "warrior_fencing1_Germany.gr2" - SourceSkin "warrior_fencing1_Germany.dds" - TargetSkin "warrior_fencing1_Poland.dds" - } - Group ShapeData49 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40048 - Model "warrior_fencing1_Germany.gr2" - SourceSkin "warrior_fencing1_Germany.dds" - TargetSkin "warrior_fencing1_Romania.dds" - } - Group ShapeData50 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40049 - Model "warrior_fencing1_Germany.gr2" - SourceSkin "warrior_fencing1_Germany.dds" - TargetSkin "warrior_fencing1_Spain.dds" - } - Group ShapeData51 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40050 - Model "warrior_soccer1_Germany.gr2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_soccer1_France.dds" - } - Group ShapeData52 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40051 - Model "warrior_soccer1_Germany.gr2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_soccer1_Italy.dds" - } - Group ShapeData53 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40052 - Model "warrior_soccer1_Germany.gr2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_soccer1_Poland.dds" - } - Group ShapeData54 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40053 - Model "warrior_soccer1_Germany.gr2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_soccer1_Romania.dds" - } - Group ShapeData55 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40054 - Model "warrior_soccer1_Germany.gr2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_soccer1_Spain.dds" - } - Group ShapeData56 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40055 - Model "warrior_boxing1_Germany.gr2" - SourceSkin "warrior_boxing1_Germany.dds" - TargetSkin "warrior_boxing1_France.dds" - } - Group ShapeData57 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40056 - Model "warrior_boxing1_Germany.gr2" - SourceSkin "warrior_boxing1_Germany.dds" - TargetSkin "warrior_boxing1_Italy.dds" - } - Group ShapeData58 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40057 - Model "warrior_boxing1_Germany.gr2" - SourceSkin "warrior_boxing1_Germany.dds" - TargetSkin "warrior_boxing1_Poland.dds" - } - Group ShapeData59 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40058 - Model "warrior_boxing1_Germany.gr2" - SourceSkin "warrior_boxing1_Germany.dds" - TargetSkin "warrior_boxing1_Romania.dds" - } - Group ShapeData60 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40059 - Model "warrior_boxing1_Germany.gr2" - SourceSkin "warrior_boxing1_Germany.dds" - TargetSkin "warrior_boxing1_Spain.dds" - } - Group ShapeData61 - { - SpecialPath "d:/ymir Work/pc2/warrior/" - - ShapeIndex 40065 - Model "warrior_halloween1.gr2" - SourceSkin "warrior_halloween1.dds" - TargetSkin "warrior_halloween1.dds" - } - - Group ShapeData62 - { - ShapeIndex 13 - Model "warrior_5_1.GR2" - SourceSkin "warrior_5_1.dds" - TargetSkin "warrior_5_1.dds" - } - Group ShapeData63 - { - ShapeIndex 40062 - Model "warrior_salsa1.GR2" - SourceSkin "warrior_salsa1.dds" - TargetSkin "warrior_salsa1.dds" - } - Group ShapeData64 - { - ShapeIndex 40063 - Model "warrior_Springwear1.GR2" - SourceSkin "warrior_Springwear1.dds" - TargetSkin "warrior_Springwear1.dds" - } - Group ShapeData65 - { - ShapeIndex 40061 - Model "warrior_tailcoat1.gr2" - SourceSkin "warrior_tailcoat1.dds" - TargetSkin "warrior_tailcoat1.dds" - } - Group ShapeData66 - { - ShapeIndex 40069 - Model "warrior_deer1.gr2" - SourceSkin "warrior_deer1.dds" - TargetSkin "warrior_deer1.dds" - } - Group ShapeData67 - { - ShapeIndex 40066 - Model "warrior_santa1_black.gr2" - SourceSkin "warrior_santa1_black.dds" - TargetSkin "warrior_santa1_red.dds" - } - Group ShapeData68 - { - ShapeIndex 40067 - Model "warrior_santa1_black.gr2" - SourceSkin "warrior_santa1_black.dds" - TargetSkin "warrior_santa1_green.dds" - } - Group ShapeData69 - { - ShapeIndex 40068 - Model "warrior_santa1_black.gr2" - SourceSkin "warrior_santa1_black.dds" - TargetSkin "warrior_santa1_black.dds" - } - Group ShapeData70 - { - ShapeIndex 40070 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA01.dds" - } - Group ShapeData71 - { - ShapeIndex 40071 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA02.dds" - } - Group ShapeData72 - { - ShapeIndex 40072 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA03.dds" - } - Group ShapeData73 - { - ShapeIndex 40073 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA04.dds" - } - Group ShapeData74 - { - ShapeIndex 40074 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA05.dds" - } - Group ShapeData75 - { - ShapeIndex 40075 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA06.dds" - } - Group ShapeData76 - { - ShapeIndex 40076 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA07.dds" - } - Group ShapeData77 - { - ShapeIndex 40077 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA08.dds" - } - Group ShapeData78 - { - ShapeIndex 40078 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA09.dds" - } - Group ShapeData79 - { - ShapeIndex 40079 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA10.dds" - } - Group ShapeData80 - { - ShapeIndex 40080 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA11.dds" - } - Group ShapeData81 - { - ShapeIndex 40081 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA12.dds" - } - Group ShapeData82 - { - ShapeIndex 40082 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA13.dds" - } - Group ShapeData83 - { - ShapeIndex 40083 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA14.dds" - } - Group ShapeData84 - { - ShapeIndex 40084 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA15.dds" - } - Group ShapeData85 - { - ShapeIndex 40085 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA16.dds" - } - Group ShapeData86 - { - ShapeIndex 40086 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA17.dds" - } - Group ShapeData87 - { - ShapeIndex 40087 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA18.dds" - } - Group ShapeData88 - { - ShapeIndex 40088 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA19.dds" - } - Group ShapeData89 - { - ShapeIndex 40089 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA20.dds" - } - Group ShapeData90 - { - ShapeIndex 40090 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA21.dds" - } - Group ShapeData91 - { - ShapeIndex 40091 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA22.dds" - } - Group ShapeData92 - { - ShapeIndex 40092 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA23.dds" - } - Group ShapeData93 - { - ShapeIndex 40093 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA24.dds" - } - Group ShapeData94 - { - ShapeIndex 40094 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA25.dds" - } - Group ShapeData95 - { - ShapeIndex 40095 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA26.dds" - } - Group ShapeData96 - { - ShapeIndex 40096 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA27.dds" - } - Group ShapeData97 - { - ShapeIndex 40097 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA28.dds" - } - Group ShapeData98 - { - ShapeIndex 40098 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA29.dds" - } - Group ShapeData99 - { - ShapeIndex 40099 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA30.dds" - } - Group ShapeData100 - { - ShapeIndex 40100 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA31.dds" - } - Group ShapeData101 - { - ShapeIndex 40101 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_UEFA32.dds" - } - Group ShapeData102 - { - ShapeIndex 40064 - Model "warrior_samurai1.GR2" - SourceSkin "warrior_samurai1.dds" - TargetSkin "warrior_samurai1.dds" - } - Group ShapeData103 - { - ShapeIndex 40106 - Model "warrior_rabbit1.GR2" - SourceSkin "warrior_rabbit1.dds" - TargetSkin "warrior_rabbit1_black.dds" - } - Group ShapeData104 - { - ShapeIndex 40107 - Model "warrior_rabbit1.GR2" - SourceSkin "warrior_rabbit1.dds" - TargetSkin "warrior_rabbit1_blue.dds" - } - Group ShapeData105 - { - ShapeIndex 40108 - Model "warrior_rabbit1.GR2" - SourceSkin "warrior_rabbit1.dds" - TargetSkin "warrior_rabbit1_green.dds" - } - Group ShapeData106 - { - ShapeIndex 40109 - Model "warrior_rabbit1.GR2" - SourceSkin "warrior_rabbit1.dds" - TargetSkin "warrior_rabbit1_pink.dds" - } - Group ShapeData107 - { - ShapeIndex 40110 - Model "warrior_BlackSnake1.GR2" - SourceSkin "warrior_BlackSnake1.dds" - TargetSkin "warrior_BlackSnake1.dds" - } - Group ShapeData108 - { - ShapeIndex 40111 - Model "warrior_BlackSnake1.GR2" - SourceSkin "warrior_BlackSnake1.dds" - TargetSkin "warrior_BlackSnake1.dds" - } - Group ShapeData109 - { - ShapeIndex 40113 - Model "warrior_assassin1.GR2" - SourceSkin "warrior_assassin1.dds" - TargetSkin "warrior_assassin2.dds" - } - Group ShapeData110 - { - ShapeIndex 40115 - Model "warrior_pwahuang1.GR2" - SourceSkin "warrior_pwahuang1.dds" - TargetSkin "warrior_pwahuang1.dds" - } - Group ShapeData111 - { - ShapeIndex 40117 - Model "warrior_halloween2.GR2" - SourceSkin "warrior_halloween2.dds" - TargetSkin "warrior_halloween2.dds" - } - Group ShapeData112 - { - ShapeIndex 40119 - Model "warrior_assassin1.gr2" - SourceSkin "warrior_assassin1.dds" - TargetSkin "warrior_assassin3.DDS" - } - Group ShapeData113 - { - ShapeIndex 40060 - Model "warrior_capoeira1.GR2" - SourceSkin "warrior_capoeira1.dds" - TargetSkin "warrior_capoeira1.dds" - } - Group ShapeData114 - { - ShapeIndex 40121 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC01.dds" - } - Group ShapeData115 - { - ShapeIndex 40123 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC02.dds" - } - Group ShapeData116 - { - ShapeIndex 40125 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC03.dds" - } - Group ShapeData117 - { - ShapeIndex 40127 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC04.dds" - } - Group ShapeData118 - { - ShapeIndex 40129 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC05.dds" - } - Group ShapeData119 - { - ShapeIndex 40131 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC06.dds" - } - Group ShapeData120 - { - ShapeIndex 40133 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC07.dds" - } - Group ShapeData121 - { - ShapeIndex 40135 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC08.dds" - } - Group ShapeData122 - { - ShapeIndex 40137 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC09.dds" - } - Group ShapeData123 - { - ShapeIndex 40139 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC10.dds" - } - Group ShapeData124 - { - ShapeIndex 40141 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC11.dds" - } - Group ShapeData125 - { - ShapeIndex 40143 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC12.dds" - } - Group ShapeData126 - { - ShapeIndex 40145 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC13.dds" - } - Group ShapeData127 - { - ShapeIndex 40147 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC14.dds" - } - Group ShapeData128 - { - ShapeIndex 40149 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC15.dds" - } - Group ShapeData129 - { - ShapeIndex 40151 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC16.dds" - } - Group ShapeData130 - { - ShapeIndex 40153 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC17.dds" - } - Group ShapeData131 - { - ShapeIndex 40155 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC18.dds" - } - Group ShapeData132 - { - ShapeIndex 40157 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC19.dds" - } - Group ShapeData133 - { - ShapeIndex 40159 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC20.dds" - } - Group ShapeData134 - { - ShapeIndex 40161 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC21.dds" - } - Group ShapeData135 - { - ShapeIndex 40163 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC22.dds" - } - Group ShapeData136 - { - ShapeIndex 40165 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC23.dds" - } - Group ShapeData137 - { - ShapeIndex 40167 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC24.dds" - } - Group ShapeData138 - { - ShapeIndex 40169 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC25.dds" - } - Group ShapeData139 - { - ShapeIndex 40171 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC26.dds" - } - Group ShapeData140 - { - ShapeIndex 40173 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC27.dds" - } - Group ShapeData141 - { - ShapeIndex 40175 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC28.dds" - } - Group ShapeData142 - { - ShapeIndex 40177 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC29.dds" - } - Group ShapeData143 - { - ShapeIndex 40179 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC30.dds" - } - Group ShapeData144 - { - ShapeIndex 40181 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC31.dds" - } - Group ShapeData145 - { - ShapeIndex 40183 - Model "warrior_soccer1_Germany.GR2" - SourceSkin "warrior_soccer1_Germany.dds" - TargetSkin "warrior_WC32.dds" - } - -} - -Group AttachingData -{ - AttachingDataCount 2 - - Group AttachingData00 - { - AttachingDataType 1 - - isAttaching 0 - AttachingModelIndex 0 - AttachingBoneName "Bip01" - - CollisionType 1 - - SphereDataCount 1 - Group SphereData00 - { - Radius 40.000000 - Position 0.000000 0.000000 100.000000 - } - } - - Group AttachingData01 - { - AttachingDataType 1 - - isAttaching 0 - AttachingModelIndex 0 - AttachingBoneName "Bip01" - - CollisionType 3 - - SphereDataCount 1 - Group SphereData00 - { - Radius 70.000000 - Position 0.000000 0.000000 100.000000 - } - } -} diff --git a/tools/root/musicinfo.py b/tools/root/musicinfo.py deleted file mode 100644 index 4eb8ff05..00000000 --- a/tools/root/musicinfo.py +++ /dev/null @@ -1,27 +0,0 @@ -METIN2THEMA = "M2BG.mp3" - -loginMusic="login_window.mp3" -createMusic="characterselect.mp3" -selectMusic="characterselect.mp3" -fieldMusic=METIN2THEMA - -def SaveLastPlayFieldMusic(): - global fieldMusic - - try: - with open("BGM/lastplay.inf", "w") as lastPlayFile: - lastPlayFile.write(fieldMusic) - except IOError: - return - - -def LoadLastPlayFieldMusic(): - global fieldMusic - - try: - with open("BGM/lastplay.inf", "r") as lastPlayFile: - fieldMusic=lastPlayFile.read() - except IOError: - return - - diff --git a/tools/root/networkmodule.py b/tools/root/networkmodule.py deleted file mode 100644 index 601dd755..00000000 --- a/tools/root/networkmodule.py +++ /dev/null @@ -1,305 +0,0 @@ -################################################################################################### -# Network - -import app -import chr -import dbg -import net -import snd - -import chr -import chrmgr -import background -import player -import playerSettingModule - -import ui -import uiPhaseCurtain - -import localeInfo - -class PopupDialog(ui.ScriptWindow): - # MR-15: Multiline dialog messages - BASE_HEIGHT = 105 - BASE_WIDTH = 280 - BUTTON_Y = 63 - LINE_HEIGHT = 12 - # MR-15: -- END OF -- Multiline dialog messages - - def __init__(self): - print("NEW POPUP DIALOG ----------------------------------------------------------------------------") - ui.ScriptWindow.__init__(self) - self.CloseEvent = 0 - - def __del__(self): - print("---------------------------------------------------------------------------- DELETE POPUP DIALOG ") - ui.ScriptWindow.__del__(self) - - def LoadDialog(self): - PythonScriptLoader = ui.PythonScriptLoader() - PythonScriptLoader.LoadScriptFile(self, "UIScript/PopupDialog.py") - - def Open(self, Message, event = 0, ButtonName = None): - if ButtonName is None: - ButtonName = localeInfo.UI_CANCEL - - if True == self.IsShow(): - self.Close() - - self.Lock() - self.SetTop() - self.CloseEvent = event - - AcceptButton = self.GetChild("accept") - AcceptButton.SetText(ButtonName) - AcceptButton.SetEvent(ui.__mem_func__(self.Close)) - - # MR-15: Multiline dialog messages - messageWidget = self.GetChild("message") - messageWidget.SetText(Message) - - extraH = len(messageWidget.extraLines) * self.LINE_HEIGHT + 2 - newH = self.BASE_HEIGHT + extraH - self.SetSize(self.BASE_WIDTH, newH) - self.GetChild("board").SetSize(self.BASE_WIDTH, newH) - AcceptButton.SetPosition(0, self.BUTTON_Y + extraH) - - self.SetCenterPosition() - self.UpdateRect() - # MR-15: -- END OF -- Multiline dialog messages - self.Show() - - def Close(self): - - if False == self.IsShow(): - self.CloseEvent = 0 - return - - self.Unlock() - self.Hide() - - if 0 != self.CloseEvent: - self.CloseEvent() - self.CloseEvent = 0 - - def Destroy(self): - self.Close() - self.ClearDictionary() - - def OnPressEscapeKey(self): - self.Close() - return True - - def OnIMEReturn(self): - self.Close() - return True - -## -## Main Stream -## -class MainStream(object): - isChrData=0 - - def __init__(self): - print("NEWMAIN STREAM ----------------------------------------------------------------------------") - net.SetHandler(self) - net.SetTCPRecvBufferSize(128*1024) - net.SetTCPSendBufferSize(4096) - - self.id="" - self.pwd="" - self.addr="" - self.port=0 - self.account_addr=0 - self.account_port=0 - self.slot=0 - self.isAutoSelect=0 - self.isAutoLogin=0 - - self.curtain = 0 - self.curPhaseWindow = 0 - self.newPhaseWindow = 0 - - def __del__(self): - print("---------------------------------------------------------------------------- DELETE MAIN STREAM ") - - def Destroy(self): - if self.curPhaseWindow: - self.curPhaseWindow.Close() - self.curPhaseWindow = 0 - - if self.newPhaseWindow: - self.newPhaseWindow.Close() - self.newPhaseWindow = 0 - - self.popupWindow.Destroy() - self.popupWindow = 0 - - self.curtain = 0 - - def Create(self): - self.CreatePopupDialog() - - self.curtain = uiPhaseCurtain.PhaseCurtain() - - def SetPhaseWindow(self, newPhaseWindow): - if self.newPhaseWindow: - #print "Already in the process of changing to a new phase, skip", newPhaseWindow - self.__ChangePhaseWindow() - - self.newPhaseWindow=newPhaseWindow - - if self.curPhaseWindow: - #print "Change after fade out" - self.curtain.FadeOut(self.__ChangePhaseWindow) - else: - #print "Change immediately if there's no current phase" - self.__ChangePhaseWindow() - - def __ChangePhaseWindow(self): - oldPhaseWindow=self.curPhaseWindow - newPhaseWindow=self.newPhaseWindow - self.curPhaseWindow=0 - self.newPhaseWindow=0 - - if oldPhaseWindow: - oldPhaseWindow.Close() - - if newPhaseWindow: - newPhaseWindow.Open() - - self.curPhaseWindow=newPhaseWindow - - if self.curPhaseWindow: - self.curtain.FadeIn() - else: - app.Exit() - - def CreatePopupDialog(self): - self.popupWindow = PopupDialog() - self.popupWindow.LoadDialog() - self.popupWindow.SetCenterPosition() - self.popupWindow.Hide() - - - ## SelectPhase - ########################################################################################## - def SetLoginPhase(self): - net.Disconnect() - - import introLogin - self.SetPhaseWindow(introLogin.LoginWindow(self)) - - def SameLogin_SetLoginPhase(self): - net.Disconnect() - - import introLogin - introInst = introLogin.LoginWindow(self) - self.SetPhaseWindow(introInst) - introInst.SameLogin_OpenUI() - - def SetSelectEmpirePhase(self): - try: - import introEmpire - self.SetPhaseWindow(introEmpire.SelectEmpireWindow(self)) - except: - import exception - exception.Abort("networkModule.SetSelectEmpirePhase") - - - def SetReselectEmpirePhase(self): - try: - import introEmpire - self.SetPhaseWindow(introEmpire.ReselectEmpireWindow(self)) - except: - import exception - exception.Abort("networkModule.SetReselectEmpirePhase") - - def SetSelectCharacterPhase(self): - try: - localeInfo.LoadLocaleData() - import introSelect - self.popupWindow.Close() - self.SetPhaseWindow(introSelect.SelectCharacterWindow(self)) - except: - import exception - exception.Abort("networkModule.SetSelectCharacterPhase") - - def SetCreateCharacterPhase(self): - try: - import introCreate - self.SetPhaseWindow(introCreate.CreateCharacterWindow(self)) - except: - import exception - exception.Abort("networkModule.SetCreateCharacterPhase") - - def SetTestGamePhase(self, x, y): - try: - import introLoading - loadingPhaseWindow=introLoading.LoadingWindow(self) - loadingPhaseWindow.LoadData(x, y) - self.SetPhaseWindow(loadingPhaseWindow) - except: - import exception - exception.Abort("networkModule.SetLoadingPhase") - - - - def SetLoadingPhase(self): - try: - import introLoading - self.SetPhaseWindow(introLoading.LoadingWindow(self)) - except: - import exception - exception.Abort("networkModule.SetLoadingPhase") - - def SetGamePhase(self): - try: - import game - self.popupWindow.Close() - self.SetPhaseWindow(game.GameWindow(self)) - except: - raise - import exception - exception.Abort("networkModule.SetGamePhase") - - ################################ - # Functions used in python - - ## Login - def Connect(self): - import constInfo - if constInfo.KEEP_ACCOUNT_CONNETION_ENABLE: - net.ConnectToAccountServer(self.addr, self.port, self.account_addr, self.account_port) - else: - net.ConnectTCP(self.addr, self.port) - - #net.ConnectUDP(IP, Port) - - def SetConnectInfo(self, addr, port, account_addr=0, account_port=0): - self.addr = addr - self.port = port - self.account_addr = account_addr - self.account_port = account_port - - def GetConnectAddr(self): - return self.addr - - def SetLoginInfo(self, id, pwd): - self.id = id - self.pwd = pwd - net.SetLoginInfo(id, pwd) - - def CancelEnterGame(self): - pass - - ## Select - def SetCharacterSlot(self, slot): - self.slot=slot - - def GetCharacterSlot(self): - return self.slot - - ## Empty - def EmptyFunction(self): - pass diff --git a/tools/root/npclist.txt b/tools/root/npclist.txt deleted file mode 100644 index b86a1a80..00000000 --- a/tools/root/npclist.txt +++ /dev/null @@ -1,1473 +0,0 @@ -0 pony_normal pony -0 pony_member pony -0 pony_master pony -0 horse_normal horse -0 horse_member horse -0 horse_master horse -0 horse2_normal horse2 -0 horse2_member horse2 -0 horse2_master horse2 -0 boar boar -0 dog_god dog_god -0 fire_tiger fire_tiger -0 lion lion -0 boar_0 boar -0 dog_god_0 dog_god -0 fire_tiger_0 fire_tiger -0 lion_0 lion -0 boar_3 boar -0 dog_god_3 dog_god -0 fire_tiger_3 fire_tiger -0 lion_3 lion -0 fire_tiger_blue fire_tiger -0 fire_tiger_darkred fire_tiger -0 fire_tiger_gold fire_tiger -0 fire_tiger_green fire_tiger -0 fire_tiger_pied fire_tiger -0 fire_tiger_white fire_tiger -0 reindeer_male1 reindeer_male -0 reindeer_male2 reindeer_male -0 reindeer_male3 reindeer_male -0 reindeer_female1 reindeer_female -0 reindeer_female2 reindeer_female -0 reindeer_female3 reindeer_female -0 reindeer_young1 reindeer_young -0 goods_02 goods -0 bank_02 bank -0 diamond mineral -0 amber mineral -0 fossil_tree mineral -0 copper mineral -0 silver mineral -0 gold mineral -0 jade mineral -0 ebony mineral -0 white_gold mineral -0 quartz mineral -0 amethyst mineral -0 chunru mineral -0 pearl mineral -0 mineral2_sapphire mineral2 -0 mineral2_ruby mineral2 -0 mineral2_garnet mineral2 -0 mineral2_bery mineral2 -0 red_wild_boar wild_boar -0 wolf_gray wolf -0 wolf_blue wolf -0 bear_gray bear -0 bear_black bear -0 bear_brown bear -0 tiger_big tiger -0 tiger_god tiger -0 metinstone_01 metinstone -0 metinstone_02 metinstone -0 metinstone_03 metinstone -0 metinstone_04 metinstone -0 metinstone_05 metinstone -0 metinstone_06 metinstone -0 metinstone_07 metinstone -0 metinstone_08 metinstone -0 metinstone_09 metinstone -0 metinstone_10 metinstone_02 -0 metinstone_11 metinstone_02 -0 metinstone_12 metinstone_02 -0 metinstone_13 metinstone_02 -0 metinstone_14 metinstone_02 -0 metinstone_15 metinstone_02 -0 metinstone_egg01 metinstone_egg -0 christmas_tree_01 christmas_tree -0 christmas_tree_02 christmas_tree -0 christmas_tree_03 christmas_tree -0 flag_red guild_war_flag -0 flag_blue guild_war_flag -0 flag_yellow guild_war_flag -0 haitai fire_tiger_boss -0 monkey_range monkey -0 sura_skeleton1 sura_skeleton -0 sura_skeleton2 sura_skeleton -0 sura_skeleton3 sura_skeleton -0 sura_skeleton4 sura_skeleton -0 sura_skeleton5 sura_skeleton -0 starveling starveling -0 starveling2 starveling -0 starveling3 starveling -0 starveling4 starveling -0 starveling5 starveling -0 pwahuang1_2 pwahuang1 -0 jinno_patrol_spear_01 jinno_patrol_spear -0 gangyo_patrol_spear_01 gangyo_patrol_spear -0 spy1_01 spy1 -0 reindeer_young1_christmas1 reindeer_young -0 reindeer_male1_christmas1 reindeer_male -0 fire_ghost1 fire_ghost -0 fire_tiger_boss1 fire_tiger_boss -0 fire_man1 fire_man -0 fire_knight1 fire_knight -0 fire_king1 fire_king -0 ice_snow_monster1 ice_snow_monster -0 ice_snow_insect1 ice_snow_insect -0 ice_snow_man1 ice_snow_man -0 ice_snow_giant_man1 ice_snow_giant_man -0 ice_snow_golem1 ice_snow_golem -0 bridge_block_chain flame_bridge_block_chain -0 flame_npc flame_dungeon_npc -0 redthief2_officer_young2 redthief2_officer_young1 -0 unicorn1 unicorn -0 phoenix3 phoenix2 -0 pig_young1_white pig_young1 -0 dog_young1_white dog_young1 -0 tiger_young1_white tiger_young1 -0 lion_young1_white lion_young1 -0 turkey_1 turkey -0 turkey_2 turkey -0 turkey_3 turkey -0 dinosaur_1 dinosaur -0 dinosaur_2 dinosaur -0 dinosaur_3 dinosaur -0 leopard_black leopard -0 leopard_yellow leopard -0 leopard_young1_black leopard_young1 -0 leopard_young1_yellow leopard_young1 -101 stray_dog -102 wolf -103 wolf -104 wolf_blue -105 wolf_blue -106 wolf_gray -107 wolf_gray -108 wild_boar -109 red_wild_boar -110 bear -111 bear_gray -112 bear_black -113 bear_brown -114 tiger -115 tiger_big -131 wolf -132 wolf -133 wolf_blue -134 wolf_blue -135 wolf_gray -136 wolf_gray -137 wild_boar -138 red_wild_boar -139 bear -140 bear_gray -141 bear_black -142 bear_brown -143 tiger -144 tiger_big -151 wolf_blue -152 wolf_gray -153 red_wild_boar -154 bear_brown -155 tiger_big -171 stray_dog -172 wolf -173 wolf -174 wolf_blue -175 wolf_blue -176 wolf_gray -177 wolf_gray -178 wild_boar -179 red_wild_boar -180 bear -181 bear_gray -182 bear_black -183 bear_brown -184 tiger -185 tiger_big -191 mountain_dog_god -192 wild_boar_god -193 bear -194 tiger_god -301 bksoldier -302 bkarcher -303 bkknight -304 bkknight -331 bksoldier -332 bkarcher -333 bkknight -334 bkknight -351 bksoldier -352 bkarcher -353 bkknight -354 bkknight -391 bksecond -392 bkthird -393 bkfourth -394 bkboss -395 bksecond -396 bkthird -397 bkfourth -398 bkboss -401 thief1 -402 thief2 -403 thief3 -404 thiefboss1 -405 thiefboss2 -406 thiefboss3 -431 thief1 -432 thief2 -433 thief3 -434 thiefboss1 -435 thiefboss2 -436 thiefboss3 -451 thief1 -452 thief2 -453 thief3 -454 thiefboss1 -455 thiefboss2 -456 thiefboss3 -491 maenghwan -492 bou -493 gupae -494 chuhen -501 barbarian_infantry -502 barbarian_soldier -503 barbarian_bow -504 barbarian_knight -531 barbarian_infantry -532 barbarian_soldier -533 barbarian_bow -534 barbarian_knight -551 barbarian_infantry -552 barbarian_soldier -553 barbarian_bow -554 barbarian_knight -591 barbarian_boss -595 barbarian_bow -601 orc_soldier -602 orc_scouter -603 orc_knight -604 orc_magician -631 orc_soldier -632 orc_scouter -633 orc_knight -634 orc_magician -635 orc_general -636 orc_black -637 orc_bigblack -651 orc_soldier -652 orc_scouter -653 orc_knight -654 orc_magician -655 orc_general -656 orc_black -657 orc_bigblack -691 orc_lord -692 orc_lord -693 #season1/monster/orc_lord_e/ -701 milgyo_religionist -702 milgyo_nahan1 -703 milgyo_nahan2 -704 milgyo_nahan_general -705 milgyo_executor -706 milgyo_monster1 -707 milgyo_monster2 -731 milgyo_religionist -732 milgyo_nahan1 -733 milgyo_nahan2 -734 milgyo_nahan_general -735 milgyo_executor -736 milgyo_monster1 -737 milgyo_monster2 -751 milgyo_religionist -752 milgyo_nahan1 -753 milgyo_nahan2 -754 milgyo_nahan_general -755 milgyo_executor -756 milgyo_monster1 -757 milgyo_monster2 -771 milgyo_religionist -772 milgyo_nahan1 -773 milgyo_nahan2 -774 milgyo_nahan_general -775 milgyo_executor -776 milgyo_monster1 -777 milgyo_monster2 -791 milgyo_founder -792 milgyo_founder -793 milgyo_founder -794 milgyo_founder -795 #season1/monster/milgyo_founder_e/ -901 misterious_diseased_kid -902 misterious_diseased_dog -903 misterious_diseased_infector -904 misterious_diseased_sword -905 misterious_diseased_spear -906 misterious_diseased_bow -907 misterious_diseased_boss -931 misterious_diseased_kid -932 misterious_diseased_dog -933 misterious_diseased_infector -934 misterious_diseased_sword -935 misterious_diseased_spear -936 misterious_diseased_bow -937 misterious_diseased_boss -991 misterious_diseased_egg -992 misterious_diseased_host -993 misterious_diseased_bosshost -1001 skeleton_soldier_scythe -1002 skeleton_soldier_bow -1003 skeleton_soldier_spear -1004 skeleton_magician -1031 skeleton_soldier_scythe -1032 skeleton_soldier_bow -1033 skeleton_soldier_spear -1034 skeleton_magician -1035 spite_ghost -1036 chaos_ghost -1037 skeleton_general -1038 skeleton_bigboss -1039 skeleton_wizard -1040 immotal_ghost -1041 recycle_monster -1061 skeleton_soldier_scythe -1062 skeleton_soldier_bow -1063 skeleton_soldier_spear -1064 skeleton_magician -1065 spite_ghost -1066 chaos_ghost -1067 skeleton_general -1068 skeleton_bigboss -1069 skeleton_wizard -1070 immotal_ghost -1071 recycle_monster -1091 skeleton_king -1092 skeleton_king -1093 skeleton_god -1094 #season1/monster/skeleton_king_e/ -1095 #season1/monster/skeleton_god_e/ -1096 skeleton_king -1101 ice_snow_monster -1102 ice_snow_whale -1103 ice_snow_insect -1104 ice_snow_dog -1105 ice_snow_man -1106 ice_snow_giant_man -1107 ice_snow_golem -1131 ice_snow_monster -1132 ice_snow_whale -1133 ice_snow_insect -1134 ice_snow_dog -1135 ice_snow_man -1136 ice_snow_giant_man -1137 ice_snow_golem -1151 ice_snow_monster -1152 ice_snow_whale -1153 ice_snow_insect -1154 ice_snow_dog -1155 ice_snow_man -1156 ice_snow_giant_man -1157 ice_snow_golem -1171 ice_snow_monster -1172 ice_snow_whale -1173 ice_snow_insect -1174 ice_snow_dog -1175 ice_snow_man -1176 ice_snow_giant_man -1177 ice_snow_golem -1191 ice_snow_witch -1192 ice_snow_witch -1301 greenfrog_soldier -1302 greenfrog_general -1303 goblin_leafhead -1304 yellow_tigerman -1305 sugu_general -1306 yellow_tigerman -1307 #season1/monster/yellow_tigerman_e/ -1308 yellow_tigerman -1309 yellow_tigerman -1310 yellow_tigerman -1331 greenfrog_soldier -1332 greenfrog_general -1333 goblin_leafhead -1334 yellow_tigerman -1335 sugu_general -1401 mutant_1 -1402 mutant_2 -1403 mutant_3 -1501 golem_1 -1502 golem_2 -1503 golem_3 -1601 nersluck_1 -1602 nersluck_2 -1603 nersluck_3 -1901 fox_ninetail -1902 fox_ninetail -1903 #season1/monster/fox_ninetail_e/ -1904 fox_ninetail -1905 fox_ninetail -1906 fox_ninetail -2001 spider_young -2002 spider_poison -2003 spider_redpoison -2004 spider_nipper -2005 spider_soldier -2031 spider_young -2032 spider_poison -2033 spider_redpoison -2034 spider_nipper -2035 spider_soldier -2036 spider_soldier -2051 spider_young -2052 spider_poison -2053 spider_redpoison -2054 spider_nipper -2055 spider_soldier -2061 spider_young -2062 spider_poison -2063 spider_redpoison -2064 spider_nipper -2065 spider_soldier -2071 spider_young -2072 spider_poison -2073 spider_redpoison -2074 spider_nipper -2075 spider_soldier -2076 spider_soldier -2091 spider_queen -2092 spider_king -2093 #season1/monster/spider_queen_e/ -2094 #season1/monster/spider_queen_e/ -2095 spider_spawn -2101 fennec_fox -2102 evil_eye -2103 giant_scorpion -2104 scorpionman_sword -2105 scorpionman_bow -2106 snakeman_sword -2107 snakeman_bow -2108 outlaw -2131 scorpionman_sword -2132 scorpionman_bow -2133 snakeman_sword -2134 snakeman_bow -2135 outlaw -2151 fennec_fox -2152 evil_eye -2153 giant_scorpion -2154 scorpionman_sword -2155 scorpionman_bow -2156 snakeman_sword -2157 snakeman_bow -2158 outlaw -2191 giant_desert_turtle -2192 #season1/monster/giant_desert_turtle_e/ -2201 fire_tiger -2202 fire_ghost -2203 fire_tiger_boss -2204 fire_man -2205 fire_knight -2206 fire_king -2207 fire_king -2231 fire_tiger -2232 fire_ghost -2233 fire_tiger_boss -2234 fire_man -2235 fire_knight -2291 fire_dragon -2292 red_dragon -2293 red_dragon2 -2301 ent_trent -2302 ent_guru -2303 ent_hu -2304 ent_red -2305 ent_black -2306 ent_huge -2307 ent_elder -2311 ent_trent -2312 ent_guru -2313 ent_hu -2314 ent_red -2315 ent_black -2401 ch_footman -2402 ch_bowman -2403 ch_magician -2404 ch_officer -2411 ch_footman -2412 ch_bowman -2413 ch_magician -2414 ch_officer -2431 ch_footman -2432 ch_bowman -2433 ch_magician -2434 ch_officer -2451 ch_footman -2452 ch_bowman -2453 ch_magician -2454 ch_officer -2481 boar_young -2482 dog_god_young -2483 fire_tiger_young -2484 lion_young -2491 ch_general -2492 ch_general -2493 blue_dragon -2494 ch_general -2495 ch_general -2501 zombie_diseased_kid -2502 zombie_diseased_dog -2503 zombie_diseased_infector -2504 zombie_diseased_sword -2505 zombie_diseased_spear -2506 zombie_diseased_bow -2507 zombie_diseased_boss -2508 zombie_soldier_scythe -2509 zombie_soldier_bow -2510 zombie_soldier_spear -2511 zombie_magician -2512 zombie_bigboss -2513 zombie_ghost -2514 zombie_general -2541 zombie_soldier_scythe -2542 zombie_soldier_bow -2543 zombie_soldier_spear -2544 zombie_magician -2545 zombie_bigboss -2546 zombie_ghost -2547 zombie_general -2591 zombie_king -2592 zombie_king -2593 zombie_king -2594 zombie_king -2595 zombie_king -2596 zombie_king -2597 zombie_god -2598 zombie_bigboss2 -2600 gnoll_helhound -2601 gnoll_warrior -2602 gnoll_mage -2603 gnoll_commander -2620 gnoll_minotaur -2630 troll_warrior -2631 troll_archer -2632 troll_mage -2633 troll_commander -2650 troll_argus -2660 naga_soldier -2661 naga_archer -2662 naga_mage -2663 naga_warrior -2680 naga_commander -3001 gnoll_soldier -3002 gnoll_bow -3003 gnoll_soldier2 -3004 gnoll_magic -3005 gnoll_general -3090 gnoll_boss -3091 gnoll_boss2 -3101 cyclops_soldier -3102 cyclops_soldier2 -3103 cyclops_magic -3104 cyclops_officer -3105 cyclops_general -3190 cyclops_boss -3191 cyclops_boss2 -3201 manticore_soldier -3202 manticore_soldier2 -3203 manticore_magic -3204 manticore_officer -3205 manticore_general -3290 manticore_boss -3291 manticore_boss2 -3301 lemures_soldier -3302 lemures_soldier2 -3303 lemures_magic -3304 lemures_officer -3305 lemures_general -3390 lemures_boss -3391 lemures_boss2 -3401 triton_soldier -3402 triton_soldier2 -3403 triton_magic -3404 triton_officer -3405 triton_general -3490 triton_boss -3491 triton_boss2 -3501 redthief_bow -3502 redthief_soldier2 -3503 redthief_magic -3504 redthief_officer -3505 redthief_general -3551 redthief2_bow -3552 redthief2_soldier2 -3553 redthief2_magic -3554 redthief2_officer -3555 redthief2_general -3590 redthief_boss -3591 redthief_boss2 -3595 redthief2_boss -3596 redthief2_boss2 -3601 crustacean_soldier -3602 crustacean_bow -3603 crustacean_soldier2 -3604 crustacean_officer -3605 crustacean_general -3690 crustacean_boss -3691 crustacean_boss2 -3701 giant_soldier -3702 giant_soldier2 -3703 giant_magic -3704 giant_officer -3705 giant_general -3790 giant_boss -3791 giant_boss2 -3801 ogre_soldier -3802 ogre_bow -3803 ogre_officer -3804 ogre_magic -3805 ogre_general -3890 ogre_boss -3891 ogre_boss2 -3901 ent_boss1 -3902 ent_boss2 -3903 ent_boss3 -3904 giant_general -3905 bkfourth -3906 bkboss -3907 redthief2_magic -3908 redthief2_officer -3909 redthief2_general -3910 redthief_boss -3911 ent_huge -3912 ent_huge -3913 ent_huge -5001 japanese_pirate -5002 haitai -5003 monkey -5004 japanese_pirate -5101 monkey -5102 monkey_range -5103 monkey -5104 monkey -5111 monkey -5112 monkey_range -5113 monkey -5114 monkey -5115 stone_monkey -5116 stone_monkey -5121 monkey -5122 monkey_range -5123 monkey -5124 monkey -5125 stone_monkey -5126 gold_monkey -5127 gold_monkey -5131 monkey -5132 monkey_range -5133 monkey -5134 monkey -5141 monkey -5142 monkey_range -5143 monkey -5144 monkey -5145 stone_monkey -5146 stone_monkey -5151 monkey -5152 monkey_range -5153 monkey -5154 monkey -5155 stone_monkey -5156 gold_monkey -5157 gold_monkey -5161 stone_monkey -5162 gold_monkey -5163 god_monkey -6001 fire_ghost1 -6002 fire_tiger_boss1 -6003 fire_man1 -6004 fire_knight1 -6005 fire_king1 -6006 firegolem_soldier -6007 firegolem_magician -6008 firegolem_general -6009 firegolem_boss -6051 firegolem_boss -6091 yamachun_boss -6101 ice_snow_monster1 -6102 ice_snow_insect1 -6103 ice_snow_man1 -6104 ice_snow_giant_man1 -6105 ice_snow_golem1 -6106 icegolem_soldier -6107 icegolem_magician -6108 icegolem_general -6109 icegolem_boss -6151 icegolem_boss -6191 hanma_boss -6201 cyclops_soldier -6202 cyclops_soldier2 -6203 cyclops_magic -6204 cyclops_officer -6205 cyclops_general -6206 giant_soldier -6207 giant_soldier2 -6208 giant_magic -6209 giant_officer -6210 giant_general -6291 cyclops_boss -6293 cyclops_boss2 -6292 giant_boss -6294 giant_boss2 -6301 lemures_soldier -6302 lemures_soldier2 -6303 lemures_magic -6304 lemures_officer -6305 lemures_general -6306 ogre_soldier -6307 ogre_bow -6308 ogre_officer -6309 ogre_magic -6310 ogre_general -6391 lemures_boss -6392 lemures_boss2 -6393 ogre_boss -6394 ogre_boss2 -6395 japanese_pirate -7001 monkey -7002 monkey_range -7003 monkey -7004 monkey -7005 stone_monkey -7006 gold_monkey -7007 gold_monkey -7008 nersluck_1 -7009 nersluck_2 -7010 nersluck_3 -7012 evil_eye -7013 giant_scorpion -7014 scorpionman_sword -7015 scorpionman_bow -7016 snakeman_sword -7017 snakeman_bow -7018 outlaw -7019 fire_tiger -7020 fire_ghost -7021 fire_tiger_boss -7022 fire_man -7023 fire_knight -7024 ent_trent -7025 ent_guru -7026 ent_hu -7027 ent_red -7028 ent_black -7029 ice_snow_monster -7030 ice_snow_whale -7031 ice_snow_insect -7032 ice_snow_dog -7033 ice_snow_man -7034 ice_snow_giant_man -7035 ice_snow_golem -7036 ice_snow_monster -7037 ice_snow_whale -7038 ice_snow_insect -7039 ice_snow_dog -7040 ice_snow_man -7041 ice_snow_giant_man -7042 ice_snow_golem -7043 ice_snow_monster -7044 ice_snow_whale -7045 ice_snow_insect -7046 ice_snow_dog -7047 ice_snow_man -7048 ice_snow_giant_man -7049 ice_snow_golem -7050 evil_eye -7051 giant_scorpion -7052 scorpionman_sword -7053 scorpionman_bow -7054 snakeman_sword -7055 snakeman_bow -7056 outlaw -7057 evil_eye -7058 giant_scorpion -7059 scorpionman_sword -7060 scorpionman_bow -7061 snakeman_sword -7062 snakeman_bow -7063 outlaw -7064 evil_eye -7065 giant_scorpion -7066 scorpionman_sword -7067 scorpionman_bow -7068 snakeman_sword -7069 snakeman_bow -7070 outlaw -7071 fire_tiger -7072 fire_ghost -7073 fire_tiger_boss -7074 fire_man -7075 fire_knight -7076 fire_tiger -7077 fire_ghost -7078 fire_tiger_boss -7079 fire_man -7080 fire_knight -7081 fire_tiger -7082 fire_ghost -7083 fire_tiger_boss -7084 fire_man -7085 fire_knight -7086 ent_guru -7087 ent_hu -7088 ent_red -7089 ent_black -7090 ent_guru -7091 ent_hu -7092 ent_red -7093 ent_black -7094 ent_guru -7095 ent_hu -7096 ent_red -7097 ent_black -7101 #season1/npc/goldenfrog/ -7102 #season1/npc/goldenfrog/ -7103 #season1/npc/goldenfrog/ -7104 #season1/npc/goldenfrog/ -7105 #season1/npc/goldenfrog/ -7106 #season2/npc/signal_fire/ -7107 #season2/npc/signal_fire/ -7108 monkey -7109 monkey_range -7110 monkey -7111 monkey -7112 stone_monkey -7113 gold_monkey -7114 gold_monkey -7115 nersluck_1 -7116 nersluck_2 -7117 nersluck_3 -7118 fox_ninetail -7119 yellow_tigerman -8001 metinstone_01 -8002 metinstone_02 -8003 metinstone_03 -8004 metinstone_04 -8005 metinstone_05 -8006 metinstone_06 -8007 metinstone_07 -8008 metinstone_08 -8009 metinstone_09 -8010 metinstone_04 -8011 metinstone_05 -8012 metinstone_06 -8013 metinstone_07 -8014 metinstone_08 -8015 metinstone_04 -8016 metinstone_05 -8017 metinstone_06 -8018 metinstone_07 -8019 metinstone_08 -8020 metinstone_06 -8021 metinstone_07 -8022 metinstone_08 -8023 metinstone_09 -8024 metinstone_03 -8025 metinstone_04 -8026 metinstone_05 -8027 metinstone_06 -8028 metinstone_06 -8029 metinstone_06 -8030 metinstone_06 -8031 metinstone_09 -8032 metinstone_01 -8033 metinstone_06 -8034 metinstone_02 -8035 metinstone_10 -8036 metinstone_11 -8037 metinstone_12 -8038 metinstone_13 -8039 metinstone_14 -8040 metinstone_15 -8041 metinstone_egg01 -8042 metinstone_egg01 -8043 metinstone_egg01 -8044 metinstone_egg01 -8045 metinstone_egg01 -8046 metinstone_egg01 -8047 metinstone_egg01 -8048 metinstone_egg01 -8049 metinstone_egg01 -8050 metinstone_egg01 -8051 metinstone_10 -8052 metinstone_11 -8053 metinstone_12 -8054 metinstone_13 -8055 metinstone_14 -8056 metinstone_15 -8057 metinstone_12 -8058 metinstone_13 -8059 metinstone_14 -8060 metinstone_15 -8101 metinstone_01 -8102 metinstone_02 -8103 metinstone_03 -8104 metinstone_04 -8105 metinstone_05 -8106 metinstone_06 -8107 metinstone_07 -8108 metinstone_08 -8109 metinstone_09 -8110 metinstone_09 -8111 metinstone_09 -8112 metinstone_09 -8501 stray_dog -8502 wild_boar -8503 bear -8504 tiger_big -8505 orc_bigblack -8506 greenfrog_general -8507 outlaw -8508 milgyo_monster1 -8509 milgyo_monster2 -8510 fire_knight -8511 ice_snow_golem -8600 #season1/monster/orc_lord_e/ -8601 #season1/monster/orc_lord_e/ -8602 #season1/monster/milgyo_founder_e/ -8603 #season1/monster/milgyo_founder_e/ -8604 #season1/monster/skeleton_king_e/ -8605 #season1/monster/skeleton_king_e/ -8606 #season1/monster/skeleton_god_e/ -8607 #season1/monster/skeleton_god_e/ -8608 #season1/monster/fox_ninetail_e/ -8609 #season1/monster/fox_ninetail_e/ -8610 #season1/monster/yellow_tigerman_e/ -8611 #season1/monster/yellow_tigerman_e/ -8612 #season1/monster/spider_queen_e/ -8613 #season1/monster/spider_queen_e/ -8614 #season1/monster/giant_desert_turtle_e/ -8615 #season1/monster/giant_desert_turtle_e/ -8616 #season2/npc/ent_elder/ -9001 arms -9002 defence -9003 goods -9004 bank -9005 hotel_grandfa -9006 hotel_grandma -9007 arms -9008 defence -9009 sailor -9010 goods_02 -9011 bank_02 -9012 oldster -10001 warp -10002 warp -10003 warp -10004 warp -10005 warp -10006 warp -10007 warp -10008 warp -10009 warp -10010 warp -10011 warp -10012 warp -10013 warp -10014 warp -10015 warp -10016 warp -10017 warp -10018 warp -10019 warp -10020 warp -10021 warp -10022 warp -10023 warp -10024 warp -10025 warp -10026 warp -10027 warp -10028 warp -10029 warp -10030 warp -10031 warp -10032 warp -10033 warp -10034 warp -10035 warp -10036 warp -10037 warp -10038 warp -10039 warp -10040 warp -10041 warp -10042 warp -10043 warp -10044 warp -10045 warp -10046 warp -10047 warp -10048 warp -10049 warp -10050 warp -10051 warp -10052 warp -10053 warp -10054 warp -10055 warp -10056 warp -10057 warp -10058 warp -10059 warp -10060 warp -10061 warp -10062 warp -10063 warp -10064 warp -10065 warp -10066 warp -10067 warp -10068 warp -10069 warp -10070 warp -10071 warp -10072 warp -10073 warp -10074 warp -10075 warp -10076 warp -10077 warp -10078 warp -10079 warp -10080 warp -10081 warp -10082 warp -10083 warp -10084 warp -10085 warp -10086 warp -10087 warp -10088 warp -10089 warp -10090 warp -10091 warp -10092 warp -10093 warp -10094 warp -10095 warp -10096 warp -10097 warp -10098 warp -10099 warp -10100 warp -10101 warp -10102 warp -10103 warp -10104 warp -10105 warp -10501 warp -10502 warp -10503 warp -10504 warp -10505 warp -10506 warp -10507 warp -10508 warp -10509 warp -10510 warp -10511 warp -10512 warp -10513 warp -10514 warp -10515 warp -10516 warp -10517 warp -10518 warp -10519 warp -10520 warp -10521 warp -10522 warp -10523 warp -10524 warp -10601 warp -10602 warp -10603 warp -10604 warp -10605 warp -10606 warp -10607 warp -10608 warp -10609 warp -10610 warp -10611 warp -10612 warp -10613 warp -10614 warp -10615 warp -10616 warp -10617 warp -10618 warp -10619 warp -10620 warp -10621 warp -10622 warp -10623 warp -10624 warp -10625 warp -10626 warp -10701 warp -10702 warp -10703 warp -10704 warp -10705 warp -10706 warp -10707 warp -10708 warp -10709 warp -10710 warp -10711 warp -10712 warp -10713 warp -10714 warp -10715 warp -10716 warp -10717 warp -10718 warp -10719 warp -10720 warp -10721 warp -10722 warp -10723 warp -10724 warp -10725 warp -10726 warp -11000 gangyo_patrol_spear -11001 gangyo_patrol_bow -11002 jinno_patrol_spear -11003 jinno_patrol_bow -11004 sinsu_patrol_spear -11005 sinsu_patrol_bow -11100 gangyo_patrol_spear -11100 #season1/npc/sinsu_guard_spear/ -11101 gangyo_patrol_bow -11101 #season1/npc/sinsu_guard_bow/ -11102 jinno_patrol_spear -11102 #season1/npc/chenjo_guard_spear/ -11103 jinno_patrol_bow -11103 #season1/npc/chenjo_guard_bow/ -11104 sinsu_patrol_spear -11104 #season1/npc/jinno_guard_spear/ -11105 sinsu_patrol_bow -11105 #season1/npc/jinno_guard_bow/ -11106 gangyo_patrol_spear -11107 gangyo_patrol_bow -11108 jinno_patrol_spear -11109 jinno_patrol_bow -11110 sinsu_patrol_spear -11111 sinsu_patrol_bow -11112 gangyo_patrol_spear -11113 gangyo_patrol_bow -11114 jinno_patrol_spear -11115 jinno_patrol_bow -11116 sinsu_patrol_spear -11117 sinsu_patrol_bow -11505 #season1/npc/goldenfrog/ -11506 #season2/npc/signal_fire/ -11507 #season2/npc/signal_fire/ -11508 #season2/npc/signal_fire/ -11509 #season2/npc/signal_fire/ -11510 #season2/npc/signal_fire/ -12000 campfire -13000 wooden_door -13001 stone_door -20001 alchemist -20002 auntie -20003 baby_and_mom -20004 beggar -20005 ceramist -20006 girl_lost_elder_brother -20007 hotel_grandfa -20008 mr_restaurant -20009 oldster -20010 peddler -20011 plant_researcher -20012 rice_cake_seller -20013 sailor -20014 timid_boy -20015 woodcutter -20016 blacksmith -20017 musician -20018 doctor -20019 hunter -20020 old_pirate -20021 widow -20022 young_merchant -20023 bookworm -20024 yu_hwa_rang -20029 pony_normal -20030 pony_normal -20031 santa -20032 christmas_tree_01 -20033 christmas_tree_02 -20034 christmas_tree_03 -20035 flag_red -20036 flag_blue -20037 flag_yellow -20040 jinno_patrol_spear -20041 beggar -20042 peddler -20044 blacksmith -20045 blacksmith -20046 blacksmith -20047 diamond -20048 amber -20049 fossil_tree -20050 copper -20051 silver -20052 gold -20053 jade -20054 ebony -20055 pearl -20056 white_gold -20057 quartz -20058 amethyst -20059 chunru -20060 alchemist -20061 alchemist -20062 alchemist -20063 alchemist -20064 alchemist -20065 alchemist -20066 alchemist -20067 alchemist -20068 alchemist -20069 alchemist -20070 alchemist -20071 alchemist -20072 alchemist -20073 seal_stone -20073 seal_stone -20074 blacksmith -20075 blacksmith -20076 blacksmith -20077 jinno_patrol_spear -20078 jinno_patrol_spear -20079 jinno_patrol_spear -20080 plant_researcher -20081 seal_stone -20082 GM -20083 oldster -20084 #season1/npc/chagirap/ -20086 #season1/npc/wondaim/ -20087 #season1/npc/handaup/ -20088 #season1/npc/visamun/ -20089 #season1/npc/jinmoo/ -20090 #season1/npc/samahi/ -20091 #season1/npc/backchon/ -20092 #season1/npc/ayuka/ -20093 #season1/npc/visal/ -20094 #season1/npc/yejin/ -20095 #season1/npc/sinseon/ -20096 seal_stone -20097 #season2/npc/sinsu_warpgate/ -20098 #season2/npc/chenjo_warpgate/ -20099 #season2/npc/jinno_warpgate/ -20101 pony_normal -20102 pony_member -20103 pony_master -20104 horse_normal -20105 horse_member -20106 horse_master -20107 horse2_normal -20108 horse2_member -20109 horse2_master -20110 boar -20111 dog_god -20112 fire_tiger -20113 lion -20114 lion_white -20115 boar_2 -20116 dog_god_2 -20117 fire_tiger_2 -20118 lion_2 -20119 horse_event1 -20120 fire_tiger_blue -20121 fire_tiger_darkred -20122 fire_tiger_gold -20123 fire_tiger_green -20124 fire_tiger_pied -20125 fire_tiger_white -20126 santa -20201 boar_0 -20202 dog_god_0 -20203 fire_tiger_0 -20204 lion_0 -20205 boar_2 -20206 dog_god_2 -20207 fire_tiger_2 -20208 lion_2 -20209 boar_3 -20210 dog_god_3 -20211 fire_tiger_3 -20212 lion_3 -20213 reindeer_male1 -20214 reindeer_male2 -20215 reindeer_male3 -20216 reindeer_female1 -20217 reindeer_female2 -20218 reindeer_female3 -20219 horse_halloween1 -20220 reindeer_male1_christmas1 -20221 bear -20222 panda -20223 dinosaur_1 -20224 dinosaur_2 -20225 dinosaur_3 -20226 unicorn -20227 unicorn1 -20228 turkey_1 -20229 turkey_2 -20230 turkey_3 -20231 leopard_black -20232 leopard_yellow -20300 sinsu_patrol_spear -20301 sinsu_patrol_spear -20302 sinsu_patrol_spear -20303 sinsu_patrol_spear -20304 sinsu_patrol_spear -20305 sinsu_patrol_spear -20306 sinsu_patrol_spear -20307 sinsu_patrol_spear -20320 gangyo_patrol_spear -20321 gangyo_patrol_spear -20322 gangyo_patrol_spear -20323 gangyo_patrol_spear -20324 gangyo_patrol_spear -20325 gangyo_patrol_spear -20326 gangyo_patrol_spear -20327 gangyo_patrol_spear -20340 jinno_patrol_spear -20341 jinno_patrol_spear -20342 jinno_patrol_spear -20343 jinno_patrol_spear -20344 jinno_patrol_spear -20345 jinno_patrol_spear -20346 jinno_patrol_spear -20347 jinno_patrol_spear -20348 jinno_patrol_spear -20349 jinno_patrol_spear -20350 jinno_patrol_spear -20351 jinno_patrol_spear -20352 tombstone -20353 tombstone1 -20354 guard_leader -20355 guard_leader -20356 #season1/npc/mirinae_brother/ -20357 #season1/npc/moonstone/ -20358 #season1/npc/nnflower/ -20359 #season1/npc/mailbox/ -20360 #season1/npc/firestone/ -20361 #season1/npc/waterstone/ -20362 #season1/npc/treestone/ -20363 #season1/npc/steelstone/ -20364 #season1/npc/naoki/ -20365 #season1/npc/steelstone/ -20366 #season1/npc/keyholestone/ -20367 jinno_patrol_spear -20368 peddler -20369 leechung -20370 spy1 -20371 #season1/npc/waterstone/ -20372 tombstone -20373 jinno_patrol_spear -20374 jinno_patrol_spear -20375 npc_fence -20376 chagirap -20377 jinno_patrol_spear_01 -20378 gangyo_patrol_spear_01 -20379 spy1_01 -20380 eojiryu -20381 gilaso -20382 #season1/npc/nnflower/ -20383 blacksmith -20384 christmas_tree -20385 flame_npc -20386 seal_stone -20387 bridge_block_chain -20388 flame_door_npc -20389 #season1/npc/keyholestone/ -20390 #season1/npc/keyholestone/ -20391 #season1/npc/nnflower/ -20392 spy1_01 -20393 spy1 -20394 jinno_patrol_spear -20395 jinno_patrol_spear -20396 redguild_soldier -20397 ICE_lionstone -20398 ice_keybox -20399 ice_stonepillar -30000 privateshop -30001 privateshop2 -30101 zombie_key_stone -30102 zombie_god_stone -30103 zombie_security_stone -30104 zombie_warp_stone -30111 zombie_ghost_door -30112 zombie_ghost_door -30113 zombie_ghost_door -30114 zombie_ghost_door -30115 zombie_ghost_door -30116 zombie_ghost_door -30117 zombie_ghost_door -30118 zombie_ghost_door -30119 zombie_ghost_door -30120 obj_bag003 -30121 suraghost -30122 warriorghost -30123 worship_dragon -30124 sura_skeleton1 -30125 sura_skeleton2 -30126 sura_skeleton3 -30127 sura_skeleton4 -30128 sura_skeleton5 -30129 rabbit -30130 #season1/npc/waterstone/ -30301 mineral2 -30302 mineral2_ruby -30303 mineral2_garnet -30304 mineral2_bery -30305 mineral2_sapphire -33001 sura_skeleton3 -33002 historian -33003 starveling -33004 starveling2 -33005 starveling3 -33006 starveling4 -33007 starveling5 -33008 halloween1 -34001 phoenix1 -34002 reindeer_young1 -34003 phoenix2 -34004 pwahuang1 -34005 pig_young1 -34006 dog_young1 -34007 tiger_young1 -34008 lion_young1 -34009 pwahuang1_2 -34010 reindeer_young1_christmas1 -34011 bear_young1 -34012 panda_young1 -34013 redthief2_officer_young1 -34014 redthief2_officer_young2 -34015 halloween_bonedog1 -34016 phoenix3 -34017 pig_young1_white -34018 dog_young1_white -34019 tiger_young1_white -34020 lion_young1_white -34021 egg_pet -34022 rabbit_pet -34023 leopard_young1_black -34024 leopard_young1_yellow -34025 phoenix1 -50000 goods -50001 goods -50002 goods -33009 alchemist -33010 alchemist -33011 alchemist -33012 alchemist -33013 alchemist diff --git a/tools/root/playersettingmodule.py b/tools/root/playersettingmodule.py deleted file mode 100644 index d01c4da5..00000000 --- a/tools/root/playersettingmodule.py +++ /dev/null @@ -1,1459 +0,0 @@ -import chr -import chrmgr -import skill -import net -import item -import player -import effect -import constInfo -import localeInfo -import emotion - -import app - -JOB_WARRIOR = 0 -JOB_ASSASSIN = 1 -JOB_SURA = 2 -JOB_SHAMAN = 3 - -RACE_WARRIOR_M = 0 -RACE_ASSASSIN_W = 1 -RACE_SURA_M = 2 -RACE_SHAMAN_W = 3 -RACE_WARRIOR_W = 4 -RACE_ASSASSIN_M = 5 -RACE_SURA_W = 6 -RACE_SHAMAN_M = 7 - -COMBO_TYPE_1 = 0 -COMBO_TYPE_2 = 1 -COMBO_TYPE_3 = 2 - -COMBO_INDEX_1 = 0 -COMBO_INDEX_2 = 1 -COMBO_INDEX_3 = 2 -COMBO_INDEX_4 = 3 -COMBO_INDEX_5 = 4 -COMBO_INDEX_6 = 5 - -HORSE_SKILL_WILDATTACK = chr.MOTION_SKILL+121 -HORSE_SKILL_CHARGE = chr.MOTION_SKILL+122 -HORSE_SKILL_SPLASH = chr.MOTION_SKILL+123 - -GUILD_SKILL_DRAGONBLOOD = chr.MOTION_SKILL+101 -GUILD_SKILL_DRAGONBLESS = chr.MOTION_SKILL+102 -GUILD_SKILL_BLESSARMOR = chr.MOTION_SKILL+103 -GUILD_SKILL_SPPEDUP = chr.MOTION_SKILL+104 -GUILD_SKILL_DRAGONWRATH = chr.MOTION_SKILL+105 -GUILD_SKILL_MAGICUP = chr.MOTION_SKILL+106 - -PASSIVE_GUILD_SKILL_INDEX_LIST = ( 151, ) -ACTIVE_GUILD_SKILL_INDEX_LIST = ( 152, 153, 154, 155, 156, 157, ) - -NEW_678TH_SKILL_ENABLE = 0 -SKILL_INDEX_DICT = [] - -def DefineSkillIndexDict(): - global NEW_678TH_SKILL_ENABLE - global SKILL_INDEX_DICT - - SKILL_INDEX_DICT = { - JOB_WARRIOR : { - 1 : (1, 2, 3, 4, 5, 0, 0, 0, 137, 0, 138, 0, 139, 0,), - 2 : (16, 17, 18, 19, 20, 0, 0, 0, 137, 0, 138, 0, 139, 0,), - "SUPPORT" : (122, 123, 121, 124, 125, 129, 0, 0, 130, 131,), - }, - JOB_ASSASSIN : { - 1 : (31, 32, 33, 34, 35, 0, 0, 0, 137, 0, 138, 0, 139, 0, 140,), - 2 : (46, 47, 48, 49, 50, 0, 0, 0, 137, 0, 138, 0, 139, 0, 140,), - "SUPPORT" : (122, 123, 121, 124, 125, 129, 0, 0, 130, 131,), - }, - JOB_SURA : { - 1 : (61, 62, 63, 64, 65, 66, 0, 0, 137, 0, 138, 0, 139, 0,), - 2 : (76, 77, 78, 79, 80, 81, 0, 0, 137, 0, 138, 0, 139, 0,), - "SUPPORT" : (122, 123, 121, 124, 125, 129, 0, 0, 130, 131,), - }, - JOB_SHAMAN : { - 1 : (91, 92, 93, 94, 95, 96, 0, 0, 137, 0, 138, 0, 139, 0,), - 2 : (106, 107, 108, 109, 110, 111, 0, 0, 137, 0, 138, 0, 139, 0,), - "SUPPORT" : (122, 123, 121, 124, 125, 129, 0, 0, 130, 131,), - }, - } - -def RegisterSkill(race, group, empire=0): - - DefineSkillIndexDict() - - job = chr.RaceToJob(race) - - # Ensure group 0 exists (horse-only) when cooldown fix is on - if 0 not in SKILL_INDEX_DICT[job]: - # Assassin has 140 as well; others only 137-139 - SKILL_INDEX_DICT[job][0] = (0, 0, 0, 0, 0, 0, 0, 0, - 137, 0, 138, 0, 139, 0) + ((140,) if job == JOB_ASSASSIN else ()) - - ## Support Skills (Always register regardless of skill group) - if job in SKILL_INDEX_DICT: - supportSkillList = SKILL_INDEX_DICT[job].get("SUPPORT", ()) - - for i in range(len(supportSkillList)): - player.SetSkill(i + 100 + 1, supportSkillList[i]) - - ## Character Skill - if job in SKILL_INDEX_DICT: - - if group in SKILL_INDEX_DICT[job]: - - activeSkillList = SKILL_INDEX_DICT[job][group] - - for i in range(len(activeSkillList)): - skillIndex = activeSkillList[i] - - ## Skills 7 and 8 should not be set here - if i != 6 and i != 7: - player.SetSkill(i+1, skillIndex) - - supportSkillList = SKILL_INDEX_DICT[job]["SUPPORT"] - - for i in range(len(supportSkillList)): - player.SetSkill(i+100+1, supportSkillList[i]) - - ## Language Skill - if 0 != empire: - languageSkillList = [] - for i in range(3): - if (i+1) != empire: - languageSkillList.append(player.SKILL_INDEX_LANGUAGE1+i) - for i in range(len(languageSkillList)): - player.SetSkill(107+i, languageSkillList[i]) - - ## Guild Skill - for i in range(len(PASSIVE_GUILD_SKILL_INDEX_LIST)): - player.SetSkill(200+i, PASSIVE_GUILD_SKILL_INDEX_LIST[i]) - - for i in range(len(ACTIVE_GUILD_SKILL_INDEX_LIST)): - player.SetSkill(210+i, ACTIVE_GUILD_SKILL_INDEX_LIST[i]) - -def RegisterSkillAt(race, group, pos, num): - - DefineSkillIndexDict() - - job = chr.RaceToJob(race) - tmp = list(SKILL_INDEX_DICT[job][group]) - tmp[pos] = num - SKILL_INDEX_DICT[job][group] = tuple(tmp) - player.SetSkill(pos+1, num) - -FACE_IMAGE_DICT = { - RACE_WARRIOR_M : "d:/ymir work/ui/game/windows/face_warrior.sub", - RACE_ASSASSIN_W : "d:/ymir work/ui/game/windows/face_assassin.sub", - RACE_SURA_M : "d:/ymir work/ui/game/windows/face_sura.sub", - RACE_SHAMAN_W : "d:/ymir work/ui/game/windows/face_shaman.sub", -} - -isInitData=0 - -def SetGeneralMotions(mode, folder): - chrmgr.SetPathName(folder) - chrmgr.RegisterMotionMode(mode) - chrmgr.RegisterCacheMotionData(mode, chr.MOTION_WAIT, "wait.msa") - chrmgr.RegisterCacheMotionData(mode, chr.MOTION_WALK, "walk.msa") - chrmgr.RegisterCacheMotionData(mode, chr.MOTION_RUN, "run.msa") - chrmgr.RegisterCacheMotionData(mode, chr.MOTION_DAMAGE, "damage.msa", 50) - chrmgr.RegisterCacheMotionData(mode, chr.MOTION_DAMAGE, "damage_1.msa", 50) - chrmgr.RegisterCacheMotionData(mode, chr.MOTION_DAMAGE_BACK, "damage_2.msa", 50) - chrmgr.RegisterCacheMotionData(mode, chr.MOTION_DAMAGE_BACK, "damage_3.msa", 50) - chrmgr.RegisterCacheMotionData(mode, chr.MOTION_DAMAGE_FLYING, "damage_flying.msa") - chrmgr.RegisterCacheMotionData(mode, chr.MOTION_STAND_UP, "falling_stand.msa") - chrmgr.RegisterCacheMotionData(mode, chr.MOTION_DAMAGE_FLYING_BACK, "back_damage_flying.msa") - chrmgr.RegisterCacheMotionData(mode, chr.MOTION_STAND_UP_BACK, "back_falling_stand.msa") - chrmgr.RegisterCacheMotionData(mode, chr.MOTION_DEAD, "dead.msa") - chrmgr.RegisterCacheMotionData(mode, chr.MOTION_DIG, "dig.msa") - -def SetIntroMotions(mode, folder): - chrmgr.SetPathName(folder) - chrmgr.RegisterMotionMode(mode) - chrmgr.RegisterCacheMotionData(mode, chr.MOTION_INTRO_WAIT, "wait.msa") - chrmgr.RegisterCacheMotionData(mode, chr.MOTION_INTRO_SELECTED, "selected.msa") - chrmgr.RegisterCacheMotionData(mode, chr.MOTION_INTRO_NOT_SELECTED, "not_selected.msa") - - - -def __InitData(): - global isInitData - - if isInitData: - return - - isInitData = 1 - - chrmgr.SetDustGap(250) - chrmgr.SetHorseDustGap(500) - - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_DUST, "", "d:/ymir work/effect/etc/dust/dust.mse") - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_HORSE_DUST, "", "d:/ymir work/effect/etc/dust/running_dust.mse") - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_HIT, "", "d:/ymir work/effect/hit/blow_1/blow_1_low.mse") - - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_HPUP_RED, "", "d:/ymir work/effect/etc/recuperation/drugup_red.mse") - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_SPUP_BLUE, "", "d:/ymir work/effect/etc/recuperation/drugup_blue.mse") - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_SPEEDUP_GREEN, "", "d:/ymir work/effect/etc/recuperation/drugup_green.mse") - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_DXUP_PURPLE, "", "d:/ymir work/effect/etc/recuperation/drugup_purple.mse") - - # Auto potions HP, SP - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_AUTO_HPUP, "", "d:/ymir work/effect/etc/recuperation/autodrugup_red.mse") - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_AUTO_SPUP, "", "d:/ymir work/effect/etc/recuperation/autodrugup_blue.mse") - - # Ramadan Crescent Ring (71135) equip effect - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_RAMADAN_RING_EQUIP, "", "d:/ymir work/effect/etc/buff/buff_item1.mse") - - # Halloween candy equip effect - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_HALLOWEEN_CANDY_EQUIP, "", "d:/ymir work/effect/etc/buff/buff_item2.mse") - - # Happiness Ring equip effect - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_HAPPINESS_RING_EQUIP, "", "d:/ymir work/effect/etc/buff/buff_item3.mse") - - # Love Pendant equip effect - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_LOVE_PENDANT_EQUIP, "", "d:/ymir work/effect/etc/buff/buff_item4.mse") - - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_PENETRATE, "Bip01", "d:/ymir work/effect/hit/gwantong.mse") - #chrmgr.RegisterCacheEffect(chrmgr.EFFECT_BLOCK, "", "d:/ymir work/effect/etc/") - #chrmgr.RegisterCacheEffect(chrmgr.EFFECT_DODGE, "", "d:/ymir work/effect/etc/") - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_FIRECRACKER, "", "d:/ymir work/effect/etc/firecracker/newyear_firecracker.mse") - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_SPIN_TOP, "", "d:/ymir work/effect/etc/firecracker/paing_i.mse") - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_SELECT, "", "d:/ymir work/effect/etc/click/click_select.mse") - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_TARGET, "", "d:/ymir work/effect/etc/click/click_glow_select.mse") - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_STUN, "Bip01 Head", "d:/ymir work/effect/etc/stun/stun.mse") - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_CRITICAL, "Bip01 R Hand", "d:/ymir work/effect/hit/critical.mse") - player.RegisterCacheEffect(player.EFFECT_PICK, "d:/ymir work/effect/etc/click/click.mse") - - - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_DAMAGE_TARGET, "", "d:/ymir work/effect/affect/damagevalue/target.mse") - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_DAMAGE_NOT_TARGET, "", "d:/ymir work/effect/affect/damagevalue/nontarget.mse") - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_DAMAGE_SELFDAMAGE, "", "d:/ymir work/effect/affect/damagevalue/damage.mse") - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_DAMAGE_SELFDAMAGE2, "", "d:/ymir work/effect/affect/damagevalue/damage_1.mse") - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_DAMAGE_POISON, "", "d:/ymir work/effect/affect/damagevalue/poison.mse") - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_DAMAGE_MISS, "", "d:/ymir work/effect/affect/damagevalue/miss.mse") - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_DAMAGE_TARGETMISS, "", "d:/ymir work/effect/affect/damagevalue/target_miss.mse") - #chrmgr.RegisterCacheEffect(chrmgr.EFFECT_DAMAGE_CRITICAL, "", "d:/ymir work/effect/affect/damagevalue/critical.mse") - - #chrmgr.RegisterCacheEffect(chrmgr.EFFECT_SUCCESS, "", "season1/effect/success.mse") - #chrmgr.RegisterCacheEffect(chrmgr.EFFECT_FAIL, "", "season1/effect/fail.mse") - - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_PERCENT_DAMAGE1, "", "d:/ymir work/effect/hit/percent_damage1.mse") - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_PERCENT_DAMAGE2, "", "d:/ymir work/effect/hit/percent_damage2.mse") - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_PERCENT_DAMAGE3, "", "d:/ymir work/effect/hit/percent_damage3.mse") - - # Bravery cape effect - chrmgr.RegisterCacheEffect(chrmgr.EFFECT_AGGREGATE_MONSTER, "", "d:/ymir work/effect/etc/buff/buff_item9.mse") - - - - ############## - # WARRIOR - ############## - chrmgr.CreateRace(RACE_WARRIOR_M) - chrmgr.SelectRace(RACE_WARRIOR_M) - chrmgr.LoadLocalRaceData("msm/warrior_m.msm") - SetIntroMotions(chr.MOTION_MODE_GENERAL, "d:/ymir work/pc/warrior/intro/") - - chrmgr.CreateRace(RACE_WARRIOR_W) - chrmgr.SelectRace(RACE_WARRIOR_W) - chrmgr.LoadLocalRaceData("msm/warrior_w.msm") - SetIntroMotions(chr.MOTION_MODE_GENERAL, "d:/ymir work/pc2/warrior/intro/") - - - ############## - # ASSASSIN - ############## - chrmgr.CreateRace(RACE_ASSASSIN_W) - chrmgr.SelectRace(RACE_ASSASSIN_W) - chrmgr.LoadLocalRaceData("msm/assassin_w.msm") - SetIntroMotions(chr.MOTION_MODE_GENERAL, "d:/ymir work/pc/assassin/intro/") - - chrmgr.CreateRace(RACE_ASSASSIN_M) - chrmgr.SelectRace(RACE_ASSASSIN_M) - chrmgr.LoadLocalRaceData("msm/assassin_m.msm") - SetIntroMotions(chr.MOTION_MODE_GENERAL, "d:/ymir work/pc2/assassin/intro/") - - - ############## - # SURA - ############## - chrmgr.CreateRace(RACE_SURA_M) - chrmgr.SelectRace(RACE_SURA_M) - chrmgr.LoadLocalRaceData("msm/sura_m.msm") - SetIntroMotions(chr.MOTION_MODE_GENERAL, "d:/ymir work/pc/sura/intro/") - - chrmgr.CreateRace(RACE_SURA_W) - chrmgr.SelectRace(RACE_SURA_W) - chrmgr.LoadLocalRaceData("msm/sura_w.msm") - SetIntroMotions(chr.MOTION_MODE_GENERAL, "d:/ymir work/pc2/sura/intro/") - - - ############## - # SHAMAN - ############## - chrmgr.CreateRace(RACE_SHAMAN_W) - chrmgr.SelectRace(RACE_SHAMAN_W) - chrmgr.LoadLocalRaceData("msm/shaman_w.msm") - SetIntroMotions(chr.MOTION_MODE_GENERAL, "d:/ymir work/pc/shaman/intro/") - - chrmgr.CreateRace(RACE_SHAMAN_M) - chrmgr.SelectRace(RACE_SHAMAN_M) - chrmgr.LoadLocalRaceData("msm/shaman_m.msm") - SetIntroMotions(chr.MOTION_MODE_GENERAL, "d:/ymir work/pc2/shaman/intro/") - - - -def __LoadGameSound(): - item.SetUseSoundFileName(item.USESOUND_DEFAULT, "sound/ui/drop.wav") - item.SetUseSoundFileName(item.USESOUND_ACCESSORY, "sound/ui/equip_ring_amulet.wav") - item.SetUseSoundFileName(item.USESOUND_ARMOR, "sound/ui/equip_metal_armor.wav") - item.SetUseSoundFileName(item.USESOUND_BOW, "sound/ui/equip_bow.wav") - item.SetUseSoundFileName(item.USESOUND_WEAPON, "sound/ui/equip_metal_weapon.wav") - item.SetUseSoundFileName(item.USESOUND_POTION, "sound/ui/eat_potion.wav") - item.SetUseSoundFileName(item.USESOUND_PORTAL, "sound/ui/potal_scroll.wav") - - item.SetDropSoundFileName(item.DROPSOUND_DEFAULT, "sound/ui/drop.wav") - item.SetDropSoundFileName(item.DROPSOUND_ACCESSORY, "sound/ui/equip_ring_amulet.wav") - item.SetDropSoundFileName(item.DROPSOUND_ARMOR, "sound/ui/equip_metal_armor.wav") - item.SetDropSoundFileName(item.DROPSOUND_BOW, "sound/ui/equip_bow.wav") - item.SetDropSoundFileName(item.DROPSOUND_WEAPON, "sound/ui/equip_metal_weapon.wav") - -def __LoadGameEffect(): - chrmgr.RegisterEffect(chrmgr.EFFECT_SPAWN_APPEAR, "Bip01", "d:/ymir work/effect/etc/appear_die/monster_appear.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_SPAWN_DISAPPEAR, "Bip01", "d:/ymir work/effect/etc/appear_die/monster_die.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_FLAME_ATTACK, "equip_right_hand", "d:/ymir work/effect/hit/blow_flame/flame_3_weapon.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_FLAME_HIT, "", "d:/ymir work/effect/hit/blow_flame/flame_3_blow.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_FLAME_ATTACH, "", "d:/ymir work/effect/hit/blow_flame/flame_3_body.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_ELECTRIC_ATTACK, "equip_right", "d:/ymir work/effect/hit/blow_electric/light_1_weapon.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_ELECTRIC_HIT, "", "d:/ymir work/effect/hit/blow_electric/light_1_blow.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_ELECTRIC_ATTACH, "", "d:/ymir work/effect/hit/blow_electric/light_1_body.mse") - - chrmgr.RegisterEffect(chrmgr.EFFECT_LEVELUP, "", "d:/ymir work/effect/etc/levelup_1/level_up.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_SKILLUP, "", "d:/ymir work/effect/etc/skillup/skillup_1.mse") - - chrmgr.RegisterEffect(chrmgr.EFFECT_EMPIRE+1, "Bip01", "d:/ymir work/effect/etc/empire/empire_A.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_EMPIRE+2, "Bip01", "d:/ymir work/effect/etc/empire/empire_B.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_EMPIRE+3, "Bip01", "d:/ymir work/effect/etc/empire/empire_C.mse") - - chrmgr.RegisterEffect(chrmgr.EFFECT_WEAPON+1, "equip_right_hand", "d:/ymir work/pc/warrior/effect/geom_sword_loop.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_WEAPON+2, "equip_right_hand", "d:/ymir work/pc/warrior/effect/geom_spear_loop.mse") - - # LOCALE - chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+0, "Bip01", localeInfo.FN_GM_MARK) - # END_OF_LOCALE - - chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+3, "Bip01", "d:/ymir work/effect/hit/blow_poison/poison_loop.mse") ## Poison - chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+4, "", "d:/ymir work/effect/affect/slow.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+5, "Bip01 Head", "d:/ymir work/effect/etc/stun/stun_loop.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+6, "", "d:/ymir work/effect/etc/ready/ready.mse") - #chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+8, "", "d:/ymir work/guild/effect/10_construction.mse") - #chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+9, "", "d:/ymir work/guild/effect/20_construction.mse") - #chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+10, "", "d:/ymir work/guild/effect/20_upgrade.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+16, "", "d:/ymir work/pc/warrior/effect/gyeokgongjang_loop.mse") ## Heavy Anchor (duplicated below) - chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+17, "", "d:/ymir work/pc/assassin/effect/gyeonggong_loop.mse") ## Assassin - Lightness - chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+19, "Bip01 R Finger2", "d:/ymir work/pc/sura/effect/gwigeom_loop.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+20, "", "d:/ymir work/pc/sura/effect/fear_loop.mse") ## Sura - Fear - chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+21, "", "d:/ymir work/pc/sura/effect/jumagap_loop.mse") ## Sura - Armor Protection - chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+22, "", "d:/ymir work/pc/shaman/effect/3hosin_loop.mse") ## Shaman - Protection - chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+23, "", "d:/ymir work/pc/shaman/effect/boho_loop.mse") ## Shaman - Shield - chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+24, "", "d:/ymir work/pc/shaman/effect/10kwaesok_loop.mse") ## Shaman - Swiftness - chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+25, "", "d:/ymir work/pc/sura/effect/heuksin_loop.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+26, "", "d:/ymir work/pc/sura/effect/muyeong_loop.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+28, "Bip01", "d:/ymir work/effect/hit/blow_flame/flame_loop.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+29, "Bip01 R Hand", "d:/ymir work/pc/shaman/effect/6gicheon_hand.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+30, "Bip01 L Hand", "d:/ymir work/pc/shaman/effect/jeungryeok_hand.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+32, "Bip01 Head", "d:/ymir work/pc/sura/effect/pabeop_loop.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+33, "", "d:/ymir work/pc/warrior/effect/gyeokgongjang_loop.mse") ## Heavy Anchor (Fallen) - ## 34 Polymoph - chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+35, "", "d:/ymir work/effect/etc/guild_war_flag/flag_red.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+36, "", "d:/ymir work/effect/etc/guild_war_flag/flag_blue.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_AFFECT+37, "", "d:/ymir work/effect/etc/guild_war_flag/flag_yellow.mse") - - chrmgr.RegisterEffect(chrmgr.EFFECT_REFINED+1, "PART_WEAPON", "D:/ymir work/pc/common/effect/sword/sword_7.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_REFINED+2, "PART_WEAPON", "D:/ymir work/pc/common/effect/sword/sword_8.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_REFINED+3, "PART_WEAPON", "D:/ymir work/pc/common/effect/sword/sword_9.mse") - - chrmgr.RegisterEffect(chrmgr.EFFECT_REFINED+4, "PART_WEAPON_LEFT", "D:/ymir work/pc/common/effect/sword/sword_7_b.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_REFINED+5, "PART_WEAPON_LEFT", "D:/ymir work/pc/common/effect/sword/sword_8_b.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_REFINED+6, "PART_WEAPON_LEFT", "D:/ymir work/pc/common/effect/sword/sword_9_b.mse") - - chrmgr.RegisterEffect(chrmgr.EFFECT_REFINED+7, "PART_WEAPON", "D:/ymir work/pc/common/effect/sword/sword_7_f.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_REFINED+8, "PART_WEAPON", "D:/ymir work/pc/common/effect/sword/sword_8_f.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_REFINED+9, "PART_WEAPON", "D:/ymir work/pc/common/effect/sword/sword_9_f.mse") - - chrmgr.RegisterEffect(chrmgr.EFFECT_REFINED+10, "PART_WEAPON", "D:/ymir work/pc/common/effect/sword/sword_7_s.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_REFINED+11, "PART_WEAPON", "D:/ymir work/pc/common/effect/sword/sword_8_s.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_REFINED+12, "PART_WEAPON", "D:/ymir work/pc/common/effect/sword/sword_9_s.mse") - - chrmgr.RegisterEffect(chrmgr.EFFECT_REFINED+13, "PART_WEAPON_LEFT", "D:/ymir work/pc/common/effect/sword/sword_7_s.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_REFINED+14, "PART_WEAPON_LEFT", "D:/ymir work/pc/common/effect/sword/sword_8_s.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_REFINED+15, "PART_WEAPON_LEFT", "D:/ymir work/pc/common/effect/sword/sword_9_s.mse") - - chrmgr.RegisterEffect(chrmgr.EFFECT_REFINED+16, "Bip01", "D:/ymir work/pc/common/effect/armor/armor_7.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_REFINED+17, "Bip01", "D:/ymir work/pc/common/effect/armor/armor_8.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_REFINED+18, "Bip01", "D:/ymir work/pc/common/effect/armor/armor_9.mse") - - chrmgr.RegisterEffect(chrmgr.EFFECT_REFINED+19, "Bip01", "D:/ymir work/pc/common/effect/armor/armor-4-2-1.mse") - chrmgr.RegisterEffect(chrmgr.EFFECT_REFINED+20, "Bip01", "D:/ymir work/pc/common/effect/armor/armor-4-2-2.mse") - - ## FlyData - effect.RegisterIndexedFlyData(effect.FLY_EXP, effect.INDEX_FLY_TYPE_NORMAL, "d:/ymir work/effect/etc/gathering/ga_piece_yellow_small2.msf") ## Yellow (EXP) - effect.RegisterIndexedFlyData(effect.FLY_HP_MEDIUM, effect.INDEX_FLY_TYPE_NORMAL, "d:/ymir work/effect/etc/gathering/ga_piece_red_small.msf") ## Red (HP) small - effect.RegisterIndexedFlyData(effect.FLY_HP_BIG, effect.INDEX_FLY_TYPE_NORMAL, "d:/ymir work/effect/etc/gathering/ga_piece_red_big.msf") ## Red (HP) large - effect.RegisterIndexedFlyData(effect.FLY_SP_SMALL, effect.INDEX_FLY_TYPE_NORMAL, "d:/ymir work/effect/etc/gathering/ga_piece_blue_warrior_small.msf") ## Blue tail only - effect.RegisterIndexedFlyData(effect.FLY_SP_MEDIUM, effect.INDEX_FLY_TYPE_NORMAL, "d:/ymir work/effect/etc/gathering/ga_piece_blue_small.msf") ## Blue small - effect.RegisterIndexedFlyData(effect.FLY_SP_BIG, effect.INDEX_FLY_TYPE_NORMAL, "d:/ymir work/effect/etc/gathering/ga_piece_blue_big.msf") ## Blue large - effect.RegisterIndexedFlyData(effect.FLY_FIREWORK1, effect.INDEX_FLY_TYPE_FIRE_CRACKER, "d:/ymir work/effect/etc/firecracker/firecracker_1.msf") ## Firework 1 - effect.RegisterIndexedFlyData(effect.FLY_FIREWORK2, effect.INDEX_FLY_TYPE_FIRE_CRACKER, "d:/ymir work/effect/etc/firecracker/firecracker_2.msf") ## Firework 2 - effect.RegisterIndexedFlyData(effect.FLY_FIREWORK3, effect.INDEX_FLY_TYPE_FIRE_CRACKER, "d:/ymir work/effect/etc/firecracker/firecracker_3.msf") ## Firework 3 - effect.RegisterIndexedFlyData(effect.FLY_FIREWORK4, effect.INDEX_FLY_TYPE_FIRE_CRACKER, "d:/ymir work/effect/etc/firecracker/firecracker_4.msf") ## Firework 4 - effect.RegisterIndexedFlyData(effect.FLY_FIREWORK5, effect.INDEX_FLY_TYPE_FIRE_CRACKER, "d:/ymir work/effect/etc/firecracker/firecracker_5.msf") ## Firework 5 - effect.RegisterIndexedFlyData(effect.FLY_FIREWORK6, effect.INDEX_FLY_TYPE_FIRE_CRACKER, "d:/ymir work/effect/etc/firecracker/firecracker_6.msf") ## Firework 6 - effect.RegisterIndexedFlyData(effect.FLY_FIREWORK_XMAS, effect.INDEX_FLY_TYPE_FIRE_CRACKER, "d:/ymir work/effect/etc/firecracker/firecracker_xmas.msf") ## Firework X-Mas - effect.RegisterIndexedFlyData(effect.FLY_CHAIN_LIGHTNING, effect.INDEX_FLY_TYPE_NORMAL, "d:/ymir work/pc/shaman/effect/pokroe.msf") ## Chain Lightning - effect.RegisterIndexedFlyData(effect.FLY_HP_SMALL, effect.INDEX_FLY_TYPE_NORMAL, "d:/ymir work/effect/etc/gathering/ga_piece_red_smallest.msf") ## Red very small - effect.RegisterIndexedFlyData(effect.FLY_SKILL_MUYEONG, effect.INDEX_FLY_TYPE_AUTO_FIRE, "d:/ymir work/pc/sura/effect/muyeong_fly.msf") ## Shadowless - - ######################################################################################### - ## Emoticon - EmoticonStr = "d:/ymir work/effect/etc/emoticon/" - - chrmgr.RegisterEffect(chrmgr.EFFECT_EMOTICON+0, "", EmoticonStr+"sweat.mse") - net.RegisterEmoticonString("(sweat)") - - chrmgr.RegisterEffect(chrmgr.EFFECT_EMOTICON+1, "", EmoticonStr+"money.mse") - net.RegisterEmoticonString("(money)") - - chrmgr.RegisterEffect(chrmgr.EFFECT_EMOTICON+2, "", EmoticonStr+"happy.mse") - net.RegisterEmoticonString("(happy)") - - chrmgr.RegisterEffect(chrmgr.EFFECT_EMOTICON+3, "", EmoticonStr+"love_s.mse") - net.RegisterEmoticonString("(like)") - - chrmgr.RegisterEffect(chrmgr.EFFECT_EMOTICON+4, "", EmoticonStr+"love_l.mse") - net.RegisterEmoticonString("(love)") - - chrmgr.RegisterEffect(chrmgr.EFFECT_EMOTICON+5, "", EmoticonStr+"angry.mse") - net.RegisterEmoticonString("(angry)") - - chrmgr.RegisterEffect(chrmgr.EFFECT_EMOTICON+6, "", EmoticonStr+"aha.mse") - net.RegisterEmoticonString("(aha)") - - chrmgr.RegisterEffect(chrmgr.EFFECT_EMOTICON+7, "", EmoticonStr+"gloom.mse") - net.RegisterEmoticonString("(sad)") - - chrmgr.RegisterEffect(chrmgr.EFFECT_EMOTICON+8, "", EmoticonStr+"sorry.mse") - net.RegisterEmoticonString("(sorry)") - - chrmgr.RegisterEffect(chrmgr.EFFECT_EMOTICON+9, "", EmoticonStr+"!_mix_back.mse") - net.RegisterEmoticonString("(!)") - - chrmgr.RegisterEffect(chrmgr.EFFECT_EMOTICON+10, "", EmoticonStr+"question.mse") - net.RegisterEmoticonString("(?)") - - chrmgr.RegisterEffect(chrmgr.EFFECT_EMOTICON+11, "", EmoticonStr+"fish.mse") - net.RegisterEmoticonString("(fish)") - - - ## Emoticon - ######################################################################################### - - -def __LoadGameWarrior(): - __LoadGameWarriorEx(RACE_WARRIOR_M, "d:/ymir work/pc/warrior/") - __LoadGameWarriorEx(RACE_WARRIOR_W, "d:/ymir work/pc2/warrior/") - -def __LoadGameAssassin(): - __LoadGameAssassinEx(RACE_ASSASSIN_W, "d:/ymir work/pc/assassin/") - __LoadGameAssassinEx(RACE_ASSASSIN_M, "d:/ymir work/pc2/assassin/") - -def __LoadGameSura(): - __LoadGameSuraEx(RACE_SURA_M, "d:/ymir work/pc/sura/") - __LoadGameSuraEx(RACE_SURA_W, "d:/ymir work/pc2/sura/") - -def __LoadGameShaman(): - __LoadGameShamanEx(RACE_SHAMAN_W, "d:/ymir work/pc/shaman/") - __LoadGameShamanEx(RACE_SHAMAN_M, "d:/ymir work/pc2/shaman/") - -def __LoadGameWarriorEx(race, path): - - ## Warrior - ######################################################################################### - chrmgr.SelectRace(race) - - ## GENERAL MODE - SetGeneralMotions(chr.MOTION_MODE_GENERAL, path + "general/") - chrmgr.SetMotionRandomWeight(chr.MOTION_MODE_GENERAL, chr.MOTION_WAIT, 0, 70) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_WAIT, "wait_1.msa", 30) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_COMBO_ATTACK_1, "attack.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_COMBO_ATTACK_1, "attack_1.msa", 50) - - ## SKILL - chrmgr.SetPathName(path + "skill/") - for i in range(skill.SKILL_EFFECT_COUNT): - END_STRING = "" - if i != 0: END_STRING = "_%d" % (i+1) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+1, "samyeon" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+2, "palbang" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+3, "jeongwi" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+4, "geomgyeong" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+5, "tanhwan" + END_STRING + ".msa") - if NEW_678TH_SKILL_ENABLE: - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+6, "gihyeol" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+16, "gigongcham" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+17, "gyeoksan" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+18, "daejin" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+19, "cheongeun" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+20, "geompung" + END_STRING + ".msa") - if NEW_678TH_SKILL_ENABLE: - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+21, "noegeom" + END_STRING + ".msa") - - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, GUILD_SKILL_DRAGONBLOOD, "guild_yongsinuipi.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, GUILD_SKILL_DRAGONBLESS, "guild_yongsinuichukbok.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, GUILD_SKILL_BLESSARMOR, "guild_seonghwigap.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, GUILD_SKILL_SPPEDUP, "guild_gasokhwa.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, GUILD_SKILL_DRAGONWRATH, "guild_yongsinuibunno.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, GUILD_SKILL_MAGICUP, "guild_jumunsul.msa") - - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_GENERAL, COMBO_TYPE_1, 1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_GENERAL, COMBO_TYPE_1, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - - ## EMOTION - emotion.RegisterEmotionAnis(path) - - ## ONEHAND_SWORD BATTLE - chrmgr.SetPathName(path + "onehand_sword/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_ONEHAND_SWORD) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_WAIT, "wait.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_WAIT, "wait_1.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_WALK, "walk.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_RUN, "run.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_DAMAGE, "damage.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_DAMAGE, "damage_1.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_DAMAGE_BACK, "damage_2.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_DAMAGE_BACK, "damage_3.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_1, "combo_01.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_2, "combo_02.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_3, "combo_03.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_4, "combo_04.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_5, "combo_05.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_6, "combo_06.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_7, "combo_07.msa") - - ## Combo Type 1 - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_1, 4) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_4, chr.MOTION_COMBO_ATTACK_4) - ## Combo Type 2 - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, 5) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_4, chr.MOTION_COMBO_ATTACK_5) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_5, chr.MOTION_COMBO_ATTACK_7) - ## Combo Type 3 - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_3, 6) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_4, chr.MOTION_COMBO_ATTACK_5) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_5, chr.MOTION_COMBO_ATTACK_6) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_6, chr.MOTION_COMBO_ATTACK_4) - - ## TWOHAND_SWORD BATTLE - chrmgr.SetPathName(path + "twohand_sword/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_TWOHAND_SWORD) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_TWOHAND_SWORD, chr.MOTION_WAIT, "wait.msa", 70) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_TWOHAND_SWORD, chr.MOTION_WAIT, "wait_1.msa", 30) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_TWOHAND_SWORD, chr.MOTION_WALK, "walk.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_TWOHAND_SWORD, chr.MOTION_RUN, "run.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_TWOHAND_SWORD, chr.MOTION_DAMAGE, "damage.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_TWOHAND_SWORD, chr.MOTION_DAMAGE, "damage_1.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_TWOHAND_SWORD, chr.MOTION_DAMAGE_BACK, "damage_2.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_TWOHAND_SWORD, chr.MOTION_DAMAGE_BACK, "damage_3.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_TWOHAND_SWORD, chr.MOTION_COMBO_ATTACK_1, "combo_01.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_TWOHAND_SWORD, chr.MOTION_COMBO_ATTACK_2, "combo_02.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_TWOHAND_SWORD, chr.MOTION_COMBO_ATTACK_3, "combo_03.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_TWOHAND_SWORD, chr.MOTION_COMBO_ATTACK_4, "combo_04.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_TWOHAND_SWORD, chr.MOTION_COMBO_ATTACK_5, "combo_05.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_TWOHAND_SWORD, chr.MOTION_COMBO_ATTACK_6, "combo_06.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_TWOHAND_SWORD, chr.MOTION_COMBO_ATTACK_7, "combo_07.msa") - - ## Combo Type 1 - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_TWOHAND_SWORD, COMBO_TYPE_1, 4) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_TWOHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_TWOHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_TWOHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_TWOHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_4, chr.MOTION_COMBO_ATTACK_4) - ## Combo Type 2 - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_TWOHAND_SWORD, COMBO_TYPE_2, 5) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_TWOHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_TWOHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_TWOHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_TWOHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_4, chr.MOTION_COMBO_ATTACK_5) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_TWOHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_5, chr.MOTION_COMBO_ATTACK_7) - ## Combo Type 3 - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_TWOHAND_SWORD, COMBO_TYPE_3, 6) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_TWOHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_TWOHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_TWOHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_TWOHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_4, chr.MOTION_COMBO_ATTACK_5) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_TWOHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_5, chr.MOTION_COMBO_ATTACK_6) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_TWOHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_6, chr.MOTION_COMBO_ATTACK_4) - - ## FISHING - chrmgr.SetPathName(path + "fishing/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_FISHING) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_WAIT, "wait.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_WALK, "walk.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_RUN, "run.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_FISHING_THROW, "throw.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_FISHING_WAIT, "fishing_wait.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_FISHING_STOP, "fishing_cancel.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_FISHING_REACT, "fishing_react.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_FISHING_CATCH, "fishing_catch.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_FISHING_FAIL, "fishing_fail.msa") - - ## HORSE - chrmgr.SetPathName(path + "horse/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_HORSE) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_WAIT, "wait.msa", 90) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_WAIT, "wait_1.msa", 9) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_WAIT, "wait_2.msa", 1) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_WALK, "walk.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_RUN, "run.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_DAMAGE, "damage.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_DAMAGE_BACK, "damage.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_DEAD, "dead.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, HORSE_SKILL_CHARGE, "skill_charge.msa") - - ## HORSE_ONEHAND_SWORD - chrmgr.SetPathName(path + "horse_onehand_sword/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_HORSE_ONEHAND_SWORD) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_1, "combo_01.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_2, "combo_02.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_3, "combo_03.msa") - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, COMBO_TYPE_1, 3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, HORSE_SKILL_WILDATTACK, "skill_wildattack.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, HORSE_SKILL_SPLASH, "skill_splash.msa") - - ## HORSE_TWOHAND_SWORD - chrmgr.SetPathName(path + "horse_twohand_sword/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_HORSE_TWOHAND_SWORD) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_TWOHAND_SWORD, chr.MOTION_COMBO_ATTACK_1, "combo_01.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_TWOHAND_SWORD, chr.MOTION_COMBO_ATTACK_2, "combo_02.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_TWOHAND_SWORD, chr.MOTION_COMBO_ATTACK_3, "combo_03.msa") - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_HORSE_TWOHAND_SWORD, COMBO_TYPE_1, 3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_HORSE_TWOHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_HORSE_TWOHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_HORSE_TWOHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_TWOHAND_SWORD, HORSE_SKILL_WILDATTACK, "skill_wildattack.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_TWOHAND_SWORD, HORSE_SKILL_SPLASH, "skill_splash.msa") - - ## Bone - chrmgr.RegisterAttachingBoneName(chr.PART_WEAPON, "equip_right_hand") - -def __LoadGameAssassinEx(race, path): - ## Assassin - ######################################################################################### - chrmgr.SelectRace(race) - - ## GENERAL MOTION MODE - SetGeneralMotions(chr.MOTION_MODE_GENERAL, path + "general/") - chrmgr.SetMotionRandomWeight(chr.MOTION_MODE_GENERAL, chr.MOTION_WAIT, 0, 70) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_WAIT, "wait_1.msa", 30) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_COMBO_ATTACK_1, "attack.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_COMBO_ATTACK_1, "attack_1.msa", 50) - - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_GENERAL, COMBO_TYPE_1, 1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_GENERAL, COMBO_TYPE_1, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - - ## SKILL - chrmgr.SetPathName(path + "skill/") - for i in range(skill.SKILL_EFFECT_COUNT): - END_STRING = "" - if i != 0: END_STRING = "_%d" % (i+1) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+1, "amseup" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+2, "gungsin" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+3, "charyun" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+4, "eunhyeong" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+5, "sangong" + END_STRING + ".msa") - if NEW_678TH_SKILL_ENABLE: - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+6, "seomjeon" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+16, "yeonsa" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+17, "gwangyeok" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+18, "hwajo" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+19, "gyeonggong" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+20, "dokgigung" + END_STRING + ".msa") - if NEW_678TH_SKILL_ENABLE: - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+21, "seomgwang" + END_STRING + ".msa") - - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, GUILD_SKILL_DRAGONBLOOD, "guild_yongsinuipi.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, GUILD_SKILL_DRAGONBLESS, "guild_yongsinuichukbok.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, GUILD_SKILL_BLESSARMOR, "guild_seonghwigap.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, GUILD_SKILL_SPPEDUP, "guild_gasokhwa.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, GUILD_SKILL_DRAGONWRATH, "guild_yongsinuibunno.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, GUILD_SKILL_MAGICUP, "guild_jumunsul.msa") - - ## EMOTION - emotion.RegisterEmotionAnis(path) - - ## ONEHAND_SWORD BATTLE - chrmgr.SetPathName(path + "onehand_sword/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_ONEHAND_SWORD) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_WAIT, "wait.msa", 70) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_WAIT, "wait_1.msa", 30) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_WALK, "walk.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_RUN, "run.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_DAMAGE, "damage.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_DAMAGE, "damage_1.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_DAMAGE_BACK, "damage_2.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_DAMAGE_BACK, "damage_3.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_1, "combo_01.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_2, "combo_02.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_3, "combo_03.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_4, "combo_04.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_5, "combo_05.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_6, "combo_06.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_7, "combo_07.msa") - - ## Combo Type 1 - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_1, 4) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_4, chr.MOTION_COMBO_ATTACK_4) - ## Combo Type 2 - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, 5) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_4, chr.MOTION_COMBO_ATTACK_5) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_5, chr.MOTION_COMBO_ATTACK_7) - ## Combo Type 3 - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_3, 6) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_4, chr.MOTION_COMBO_ATTACK_5) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_5, chr.MOTION_COMBO_ATTACK_6) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_6, chr.MOTION_COMBO_ATTACK_4) - - ## DUALHAND_SWORD BATTLE - chrmgr.SetPathName(path + "dualhand_sword/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_DUALHAND_SWORD) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_DUALHAND_SWORD, chr.MOTION_WAIT, "wait.msa", 70) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_DUALHAND_SWORD, chr.MOTION_WAIT, "wait_1.msa", 30) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_DUALHAND_SWORD, chr.MOTION_WALK, "walk.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_DUALHAND_SWORD, chr.MOTION_RUN, "run.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_DUALHAND_SWORD, chr.MOTION_DAMAGE, "damage.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_DUALHAND_SWORD, chr.MOTION_DAMAGE, "damage_1.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_DUALHAND_SWORD, chr.MOTION_DAMAGE_BACK, "damage_2.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_DUALHAND_SWORD, chr.MOTION_DAMAGE_BACK, "damage_3.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_DUALHAND_SWORD, chr.MOTION_COMBO_ATTACK_1, "combo_01.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_DUALHAND_SWORD, chr.MOTION_COMBO_ATTACK_2, "combo_02.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_DUALHAND_SWORD, chr.MOTION_COMBO_ATTACK_3, "combo_03.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_DUALHAND_SWORD, chr.MOTION_COMBO_ATTACK_4, "combo_04.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_DUALHAND_SWORD, chr.MOTION_COMBO_ATTACK_5, "combo_05.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_DUALHAND_SWORD, chr.MOTION_COMBO_ATTACK_6, "combo_06.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_DUALHAND_SWORD, chr.MOTION_COMBO_ATTACK_7, "combo_07.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_DUALHAND_SWORD, chr.MOTION_COMBO_ATTACK_8, "combo_08.msa") - - ## Combo Type 1 - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_DUALHAND_SWORD, COMBO_TYPE_1, 4) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_DUALHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_DUALHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_DUALHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_DUALHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_4, chr.MOTION_COMBO_ATTACK_4) - ## Combo Type 2 - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_DUALHAND_SWORD, COMBO_TYPE_2, 5) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_DUALHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_DUALHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_DUALHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_DUALHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_4, chr.MOTION_COMBO_ATTACK_5) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_DUALHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_5, chr.MOTION_COMBO_ATTACK_7) - ## Combo Type 3 - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_DUALHAND_SWORD, COMBO_TYPE_3, 6) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_DUALHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_DUALHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_DUALHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_DUALHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_4, chr.MOTION_COMBO_ATTACK_5) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_DUALHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_5, chr.MOTION_COMBO_ATTACK_6) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_DUALHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_6, chr.MOTION_COMBO_ATTACK_8) - - ## BOW BATTLE - chrmgr.SetPathName(path + "bow/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_BOW) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_BOW, chr.MOTION_WAIT, "wait.msa", 70) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_BOW, chr.MOTION_WAIT, "wait_1.msa", 30) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_BOW, chr.MOTION_WALK, "walk.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_BOW, chr.MOTION_RUN, "run.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_BOW, chr.MOTION_DAMAGE, "damage.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_BOW, chr.MOTION_DAMAGE, "damage_1.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_BOW, chr.MOTION_DAMAGE_BACK, "damage_2.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_BOW, chr.MOTION_DAMAGE_BACK, "damage_3.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_BOW, chr.MOTION_COMBO_ATTACK_1, "attack.msa") - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_BOW, COMBO_TYPE_1, 1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_BOW, COMBO_TYPE_1, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - - ## FISHING - chrmgr.SetPathName(path + "fishing/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_FISHING) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_WAIT, "wait.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_WALK, "walk.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_RUN, "run.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_FISHING_THROW, "throw.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_FISHING_WAIT, "fishing_wait.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_FISHING_STOP, "fishing_cancel.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_FISHING_REACT, "fishing_react.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_FISHING_CATCH, "fishing_catch.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_FISHING_FAIL, "fishing_fail.msa") - - ## HORSE - chrmgr.SetPathName(path + "horse/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_HORSE) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_WAIT, "wait.msa", 90) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_WAIT, "wait_1.msa", 9) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_WAIT, "wait_2.msa", 1) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_WALK, "walk.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_RUN, "run.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_DAMAGE, "damage.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_DAMAGE_BACK, "damage.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_DEAD, "dead.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, HORSE_SKILL_CHARGE, "skill_charge.msa") - - ## HORSE_ONEHAND_SWORD - chrmgr.SetPathName(path + "horse_onehand_sword/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_HORSE_ONEHAND_SWORD) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_1, "combo_01.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_2, "combo_02.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_3, "combo_03.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, HORSE_SKILL_WILDATTACK, "skill_wildattack.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, HORSE_SKILL_SPLASH, "skill_splash.msa") - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, COMBO_TYPE_1, 3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - - ## HORSE_DUALHAND_SWORD - chrmgr.SetPathName(path + "horse_dualhand_sword/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_HORSE_DUALHAND_SWORD) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_DUALHAND_SWORD, chr.MOTION_COMBO_ATTACK_1, "combo_01.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_DUALHAND_SWORD, chr.MOTION_COMBO_ATTACK_2, "combo_02.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_DUALHAND_SWORD, chr.MOTION_COMBO_ATTACK_3, "combo_03.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_DUALHAND_SWORD, HORSE_SKILL_WILDATTACK, "skill_wildattack.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_DUALHAND_SWORD, HORSE_SKILL_SPLASH, "skill_splash.msa") - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_HORSE_DUALHAND_SWORD, COMBO_TYPE_1, 3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_HORSE_DUALHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_HORSE_DUALHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_HORSE_DUALHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - - ## HORSE_BOW - chrmgr.SetPathName(path + "horse_bow/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_HORSE_BOW) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_BOW, chr.MOTION_WAIT, "wait.msa", 90) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_BOW, chr.MOTION_WAIT, "wait_1.msa", 9) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_BOW, chr.MOTION_WAIT, "wait_2.msa", 1) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_BOW, chr.MOTION_RUN, "run.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_BOW, chr.MOTION_DAMAGE, "damage.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_BOW, chr.MOTION_DEAD, "dead.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_BOW, chr.MOTION_COMBO_ATTACK_1, "attack.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_BOW, HORSE_SKILL_WILDATTACK, "skill_wildattack.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_BOW, HORSE_SKILL_SPLASH, "skill_splash.msa") - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_HORSE_BOW, COMBO_TYPE_1, 1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_HORSE_BOW, COMBO_TYPE_1, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - - chrmgr.RegisterAttachingBoneName(chr.PART_WEAPON, "equip_right") - chrmgr.RegisterAttachingBoneName(chr.PART_WEAPON_LEFT, "equip_left") - -def __LoadGameSuraEx(race, path): - ## Sura - ######################################################################################### - chrmgr.SelectRace(race) - - ## GENERAL MOTION MODE - SetGeneralMotions(chr.MOTION_MODE_GENERAL, path + "general/") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_COMBO_ATTACK_1, "attack.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_COMBO_ATTACK_1, "attack_1.msa", 50) - - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_GENERAL, COMBO_TYPE_1, 1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_GENERAL, COMBO_TYPE_1, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - - ## SKILL - chrmgr.SetPathName(path + "skill/") - # chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+4, "geongon.msa") - - for i in range(skill.SKILL_EFFECT_COUNT): - END_STRING = "" - if i != 0: END_STRING = "_%d" % (i+1) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+1, "swaeryeong" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+2, "yonggwon" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+3, "gwigeom" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+4, "gongpo" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+5, "jumagap" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+6, "pabeop" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+16, "maryeong" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+17, "hwayeom" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+18, "muyeong" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+19, "heuksin" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+20, "tusok" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+21, "mahwan" + END_STRING + ".msa") - - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, GUILD_SKILL_DRAGONBLOOD, "guild_yongsinuipi.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, GUILD_SKILL_DRAGONBLESS, "guild_yongsinuichukbok.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, GUILD_SKILL_BLESSARMOR, "guild_seonghwigap.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, GUILD_SKILL_SPPEDUP, "guild_gasokhwa.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, GUILD_SKILL_DRAGONWRATH, "guild_yongsinuibunno.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, GUILD_SKILL_MAGICUP, "guild_jumunsul.msa") - - ## EMOTION - emotion.RegisterEmotionAnis(path) - - ## ONEHAND_SWORD BATTLE - chrmgr.SetPathName(path + "onehand_sword/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_ONEHAND_SWORD) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_WAIT, "wait.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_WALK, "walk.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_RUN, "run.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_DAMAGE, "damage.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_DAMAGE, "damage.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_DAMAGE, "damage_1.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_DAMAGE_BACK, "damage_2.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_DAMAGE_BACK, "damage_3.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_1, "combo_01.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_2, "combo_02.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_3, "combo_03.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_4, "combo_04.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_5, "combo_05.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_6, "combo_06.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_7, "combo_07.msa") - - ## Combo Type 1 - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_1, 4) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_4, chr.MOTION_COMBO_ATTACK_4) - ## Combo Type 2 - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, 5) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_4, chr.MOTION_COMBO_ATTACK_5) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_2, COMBO_INDEX_5, chr.MOTION_COMBO_ATTACK_7) - ## Combo Type 3 - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_3, 6) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_4, chr.MOTION_COMBO_ATTACK_5) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_5, chr.MOTION_COMBO_ATTACK_6) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_ONEHAND_SWORD, COMBO_TYPE_3, COMBO_INDEX_6, chr.MOTION_COMBO_ATTACK_4) - - ## FISHING - chrmgr.SetPathName(path + "fishing/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_FISHING) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_WAIT, "wait.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_WALK, "walk.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_RUN, "run.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_FISHING_THROW, "throw.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_FISHING_WAIT, "fishing_wait.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_FISHING_STOP, "fishing_cancel.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_FISHING_REACT, "fishing_react.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_FISHING_CATCH, "fishing_catch.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_FISHING_FAIL, "fishing_fail.msa") - - ## HORSE - chrmgr.SetPathName(path + "horse/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_HORSE) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_WAIT, "wait.msa", 90) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_WAIT, "wait_1.msa", 9) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_WAIT, "wait_2.msa", 1) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_WALK, "walk.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_RUN, "run.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_DAMAGE, "damage.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_DAMAGE_BACK, "damage.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_DEAD, "dead.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, HORSE_SKILL_CHARGE, "skill_charge.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, HORSE_SKILL_SPLASH, "skill_splash.msa") - - ## HORSE_ONEHAND_SWORD - chrmgr.SetPathName(path + "horse_onehand_sword/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_HORSE_ONEHAND_SWORD) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_1, "combo_01.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_2, "combo_02.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, chr.MOTION_COMBO_ATTACK_3, "combo_03.msa") - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, COMBO_TYPE_1, 3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, COMBO_TYPE_1, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_ONEHAND_SWORD, HORSE_SKILL_WILDATTACK, "skill_wildattack.msa") - - chrmgr.RegisterAttachingBoneName(chr.PART_WEAPON, "equip_right") - -def __LoadGameShamanEx(race, path): - ## Shaman - ######################################################################################### - chrmgr.SelectRace(race) - - ## GENERAL MOTION MODE - SetGeneralMotions(chr.MOTION_MODE_GENERAL, path + "general/") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_COMBO_ATTACK_1, "attack.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_COMBO_ATTACK_1, "attack_1.msa", 50) - - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_GENERAL, COMBO_TYPE_1, 1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_GENERAL, COMBO_TYPE_1, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - - ## EMOTION - emotion.RegisterEmotionAnis(path) - - ## Fan - chrmgr.SetPathName(path + "fan/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_FAN) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FAN, chr.MOTION_WAIT, "wait.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FAN, chr.MOTION_WALK, "walk.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FAN, chr.MOTION_RUN, "run.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FAN, chr.MOTION_DAMAGE, "damage.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FAN, chr.MOTION_DAMAGE, "damage_1.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FAN, chr.MOTION_DAMAGE_BACK, "damage_2.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FAN, chr.MOTION_DAMAGE_BACK, "damage_3.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FAN, chr.MOTION_COMBO_ATTACK_1, "combo_01.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FAN, chr.MOTION_COMBO_ATTACK_2, "combo_02.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FAN, chr.MOTION_COMBO_ATTACK_3, "combo_03.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FAN, chr.MOTION_COMBO_ATTACK_4, "combo_04.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FAN, chr.MOTION_COMBO_ATTACK_5, "combo_05.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FAN, chr.MOTION_COMBO_ATTACK_6, "combo_06.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FAN, chr.MOTION_COMBO_ATTACK_7, "combo_07.msa") - - ## Combo Type 1 - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_FAN, COMBO_TYPE_1, 4) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_FAN, COMBO_TYPE_1, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_FAN, COMBO_TYPE_1, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_FAN, COMBO_TYPE_1, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_FAN, COMBO_TYPE_1, COMBO_INDEX_4, chr.MOTION_COMBO_ATTACK_4) - ## Combo Type 2 - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_FAN, COMBO_TYPE_2, 5) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_FAN, COMBO_TYPE_2, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_FAN, COMBO_TYPE_2, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_FAN, COMBO_TYPE_2, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_FAN, COMBO_TYPE_2, COMBO_INDEX_4, chr.MOTION_COMBO_ATTACK_5) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_FAN, COMBO_TYPE_2, COMBO_INDEX_5, chr.MOTION_COMBO_ATTACK_7) - ## Combo Type 3 - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_FAN, COMBO_TYPE_3, 6) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_FAN, COMBO_TYPE_3, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_FAN, COMBO_TYPE_3, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_FAN, COMBO_TYPE_3, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_FAN, COMBO_TYPE_3, COMBO_INDEX_4, chr.MOTION_COMBO_ATTACK_5) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_FAN, COMBO_TYPE_3, COMBO_INDEX_5, chr.MOTION_COMBO_ATTACK_6) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_FAN, COMBO_TYPE_3, COMBO_INDEX_6, chr.MOTION_COMBO_ATTACK_4) - - ## Bell - chrmgr.SetPathName(path + "Bell/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_BELL) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_BELL, chr.MOTION_WAIT, "wait.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_BELL, chr.MOTION_WALK, "walk.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_BELL, chr.MOTION_RUN, "run.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_BELL, chr.MOTION_DAMAGE, "damage.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_BELL, chr.MOTION_DAMAGE, "damage_1.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_BELL, chr.MOTION_DAMAGE_BACK, "damage_2.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_BELL, chr.MOTION_DAMAGE_BACK, "damage_3.msa", 50) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_BELL, chr.MOTION_COMBO_ATTACK_1, "combo_01.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_BELL, chr.MOTION_COMBO_ATTACK_2, "combo_02.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_BELL, chr.MOTION_COMBO_ATTACK_3, "combo_03.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_BELL, chr.MOTION_COMBO_ATTACK_4, "combo_04.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_BELL, chr.MOTION_COMBO_ATTACK_5, "combo_05.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_BELL, chr.MOTION_COMBO_ATTACK_6, "combo_06.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_BELL, chr.MOTION_COMBO_ATTACK_7, "combo_07.msa") - - ## Combo Type 1 - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_BELL, COMBO_TYPE_1, 4) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_BELL, COMBO_TYPE_1, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_BELL, COMBO_TYPE_1, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_BELL, COMBO_TYPE_1, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_BELL, COMBO_TYPE_1, COMBO_INDEX_4, chr.MOTION_COMBO_ATTACK_4) - ## Combo Type 2 - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_BELL, COMBO_TYPE_2, 5) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_BELL, COMBO_TYPE_2, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_BELL, COMBO_TYPE_2, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_BELL, COMBO_TYPE_2, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_BELL, COMBO_TYPE_2, COMBO_INDEX_4, chr.MOTION_COMBO_ATTACK_5) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_BELL, COMBO_TYPE_2, COMBO_INDEX_5, chr.MOTION_COMBO_ATTACK_7) - ## Combo Type 3 - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_BELL, COMBO_TYPE_3, 6) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_BELL, COMBO_TYPE_3, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_BELL, COMBO_TYPE_3, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_BELL, COMBO_TYPE_3, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_BELL, COMBO_TYPE_3, COMBO_INDEX_4, chr.MOTION_COMBO_ATTACK_5) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_BELL, COMBO_TYPE_3, COMBO_INDEX_5, chr.MOTION_COMBO_ATTACK_6) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_BELL, COMBO_TYPE_3, COMBO_INDEX_6, chr.MOTION_COMBO_ATTACK_4) - - ## SKILL - chrmgr.SetPathName(path + "skill/") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+1, "bipabu.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+2, "yongpa.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+3, "paeryong.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+4, "hosin_target.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+5, "boho_target.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+6, "gicheon_target.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+16, "noejeon.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+17, "byeorak.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+18, "pokroe.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+19, "jeongeop_target.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+20, "kwaesok_target.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+21, "jeungryeok_target.msa") - #chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+10, "budong.msa") - - START_INDEX = 0 - # Up to skill.SKILL_EFFECT_COUNT - for i in (1, 2, 3): - END_STRING = "" - if i != 0: END_STRING = "_%d" % (i+1) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+1, "bipabu" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+2, "yongpa" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+3, "paeryong" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+4, "hosin" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+5, "boho" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+6, "gicheon" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+16, "noejeon" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+17, "byeorak" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+18, "pokroe" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+19, "jeongeop" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+20, "kwaesok" + END_STRING + ".msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+21, "jeungryeok" + END_STRING + ".msa") - #chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SKILL+(i*skill.SKILL_GRADEGAP)+10, "budong" + END_STRING + ".msa") - - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, GUILD_SKILL_DRAGONBLOOD, "guild_yongsinuipi.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, GUILD_SKILL_DRAGONBLESS, "guild_yongsinuichukbok.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, GUILD_SKILL_BLESSARMOR, "guild_seonghwigap.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, GUILD_SKILL_SPPEDUP, "guild_gasokhwa.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, GUILD_SKILL_DRAGONWRATH, "guild_yongsinuibunno.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_GENERAL, GUILD_SKILL_MAGICUP, "guild_jumunsul.msa") - - ## FISHING - chrmgr.SetPathName(path + "fishing/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_FISHING) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_WAIT, "wait.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_WALK, "walk.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_RUN, "run.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_FISHING_THROW, "throw.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_FISHING_WAIT, "fishing_wait.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_FISHING_STOP, "fishing_cancel.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_FISHING_REACT, "fishing_react.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_FISHING_CATCH, "fishing_catch.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_FISHING, chr.MOTION_FISHING_FAIL, "fishing_fail.msa") - - ## HORSE - chrmgr.SetPathName(path + "horse/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_HORSE) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_WAIT, "wait.msa", 90) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_WAIT, "wait_1.msa", 9) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_WAIT, "wait_2.msa", 1) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_WALK, "walk.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_RUN, "run.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_DAMAGE, "damage.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_DAMAGE_BACK, "damage.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, chr.MOTION_DEAD, "dead.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, HORSE_SKILL_CHARGE, "skill_charge.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE, HORSE_SKILL_SPLASH, "skill_splash.msa") - - ## HORSE_FAN - chrmgr.SetPathName(path + "horse_fan/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_HORSE_FAN) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_FAN, chr.MOTION_COMBO_ATTACK_1, "combo_01.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_FAN, chr.MOTION_COMBO_ATTACK_2, "combo_02.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_FAN, chr.MOTION_COMBO_ATTACK_3, "combo_03.msa") - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_HORSE_FAN, COMBO_TYPE_1, 3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_HORSE_FAN, COMBO_TYPE_1, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_HORSE_FAN, COMBO_TYPE_1, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_HORSE_FAN, COMBO_TYPE_1, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_FAN, HORSE_SKILL_WILDATTACK, "skill_wildattack.msa") - - ## HORSE_BELL - chrmgr.SetPathName(path + "horse_bell/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_HORSE_BELL) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_BELL, chr.MOTION_COMBO_ATTACK_1, "combo_01.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_BELL, chr.MOTION_COMBO_ATTACK_2, "combo_02.msa") - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_BELL, chr.MOTION_COMBO_ATTACK_3, "combo_03.msa") - chrmgr.ReserveComboAttackNew(chr.MOTION_MODE_HORSE_BELL, COMBO_TYPE_1, 3) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_HORSE_BELL, COMBO_TYPE_1, COMBO_INDEX_1, chr.MOTION_COMBO_ATTACK_1) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_HORSE_BELL, COMBO_TYPE_1, COMBO_INDEX_2, chr.MOTION_COMBO_ATTACK_2) - chrmgr.RegisterComboAttackNew(chr.MOTION_MODE_HORSE_BELL, COMBO_TYPE_1, COMBO_INDEX_3, chr.MOTION_COMBO_ATTACK_3) - chrmgr.RegisterCacheMotionData(chr.MOTION_MODE_HORSE_BELL, HORSE_SKILL_WILDATTACK, "skill_wildattack.msa") - - chrmgr.RegisterAttachingBoneName(chr.PART_WEAPON, "equip_right") - chrmgr.RegisterAttachingBoneName(chr.PART_WEAPON_LEFT, "equip_left") - - -def __LoadGameSkill(): - - try: - skill.LoadSkillData() - except: - import exception - exception.Abort("__LoadGameSkill") - -def __LoadGameEnemy(): - pass - -def __LoadGameNPC(): - try: - lines = pack_open("npclist.txt", "r").readlines() - except IOError: - import dbg - dbg.LogBox("LoadLocaleError(%(srcFileName)s)" % locals()) - app.Abort() - - for line in lines: - tokens = line[:-1].split("\t") - if len(tokens) == 0 or not tokens[0]: - continue - - try: - vnum = int(tokens[0]) - except ValueError: - import dbg - dbg.LogBox("LoadGameNPC() - %s - line #%d: %s" % (tokens, lines.index(line), line)) - app.Abort() - - try: - if vnum: - chrmgr.RegisterRaceName(vnum, tokens[1].strip()) - else: - chrmgr.RegisterRaceSrcName(tokens[1].strip(), tokens[2].strip()) - except IndexError: - import dbg - dbg.LogBox("LoadGameNPC() - %d, %s - line #%d: %s " % (vnum, tokens, lines.index(line), line)) - app.Abort() - - -# GUILD_BUILDING -def LoadGuildBuildingList(filename): - import uiGuild - uiGuild.BUILDING_DATA_LIST = [] - - handle = app.OpenTextFile(filename) - count = app.GetTextFileLineCount(handle) - for i in range(count): - line = app.GetTextFileLine(handle, i) - tokens = line.split("\t") - - TOKEN_VNUM = 0 - TOKEN_TYPE = 1 - TOKEN_NAME = 2 - TOKEN_LOCAL_NAME = 3 - NO_USE_TOKEN_SIZE_1 = 4 - NO_USE_TOKEN_SIZE_2 = 5 - NO_USE_TOKEN_SIZE_3 = 6 - NO_USE_TOKEN_SIZE_4 = 7 - TOKEN_X_ROT_LIMIT = 8 - TOKEN_Y_ROT_LIMIT = 9 - TOKEN_Z_ROT_LIMIT = 10 - TOKEN_PRICE = 11 - TOKEN_MATERIAL = 12 - TOKEN_NPC = 13 - TOKEN_GROUP = 14 - TOKEN_DEPEND_GROUP = 15 - TOKEN_ENABLE_FLAG = 16 - LIMIT_TOKEN_COUNT = 17 - - if not tokens[TOKEN_VNUM].isdigit(): - continue - - if len(tokens) < LIMIT_TOKEN_COUNT: - import dbg - dbg.TraceError("Strange token count [%d/%d] [%s]" % (len(tokens), LIMIT_TOKEN_COUNT, line)) - continue - - ENABLE_FLAG_TYPE_NOT_USE = False - ENABLE_FLAG_TYPE_USE = True - ENABLE_FLAG_TYPE_USE_BUT_HIDE = 2 - - if ENABLE_FLAG_TYPE_NOT_USE == int(tokens[TOKEN_ENABLE_FLAG]): - continue - - vnum = int(tokens[TOKEN_VNUM]) - type = tokens[TOKEN_TYPE] - name = tokens[TOKEN_NAME] - localName = tokens[TOKEN_LOCAL_NAME] - xRotLimit = int(tokens[TOKEN_X_ROT_LIMIT]) - yRotLimit = int(tokens[TOKEN_Y_ROT_LIMIT]) - zRotLimit = int(tokens[TOKEN_Z_ROT_LIMIT]) - price = tokens[TOKEN_PRICE] - material = tokens[TOKEN_MATERIAL] - - folderName = "" - if "HEADQUARTER" == type: - folderName = "headquarter" - elif "FACILITY" == type: - folderName = "facility" - elif "OBJECT" == type: - folderName = "object" - elif "WALL" == type: - folderName = "fence" - - materialList = ["0", "0", "0"] - if material: - if material[0] == "\"": - material = material[1:] - if material[-1] == "\"": - material = material[:-1] - for one in material.split("/"): - data = one.split(",") - if 2 != len(data): - continue - itemID = int(data[0]) - count = data[1] - - if itemID == uiGuild.MATERIAL_STONE_ID: - materialList[uiGuild.MATERIAL_STONE_INDEX] = count - elif itemID == uiGuild.MATERIAL_LOG_ID: - materialList[uiGuild.MATERIAL_LOG_INDEX] = count - elif itemID == uiGuild.MATERIAL_PLYWOOD_ID: - materialList[uiGuild.MATERIAL_PLYWOOD_INDEX] = count - - ## GuildSymbol is registered together with regular NPCs - import chrmgr - chrmgr.RegisterRaceSrcName(name, folderName) - chrmgr.RegisterRaceName(vnum, name) - - appendingData = { "VNUM":vnum, - "TYPE":type, - "NAME":name, - "LOCAL_NAME":localName, - "X_ROT_LIMIT":xRotLimit, - "Y_ROT_LIMIT":yRotLimit, - "Z_ROT_LIMIT":zRotLimit, - "PRICE":price, - "MATERIAL":materialList, - "SHOW" : True } - - if ENABLE_FLAG_TYPE_USE_BUT_HIDE == int(tokens[TOKEN_ENABLE_FLAG]): - appendingData["SHOW"] = False - - uiGuild.BUILDING_DATA_LIST.append(appendingData) - - app.CloseTextFile(handle) - -# END_OF_GUILD_BUILDING - -loadGameDataDict={ - "INIT" : __InitData, - "SOUND" : __LoadGameSound, - "EFFECT" : __LoadGameEffect, - "WARRIOR" : __LoadGameWarrior, - "ASSASSIN" : __LoadGameAssassin, - "SURA" : __LoadGameSura, - "SHAMAN" : __LoadGameShaman, - "SKILL" : __LoadGameSkill, - "ENEMY" : __LoadGameEnemy, - "NPC" : __LoadGameNPC, -} - -def LoadGameData(name): - global loadGameDataDict - - load=loadGameDataDict.get(name, 0) - if load: - loadGameDataDict[name]=0 - try: - load() - except: - print(name) - import exception - exception.Abort("LoadGameData") - raise - - -## NPC - -def SetMovingNPC(race, name): - chrmgr.CreateRace(race) - chrmgr.SelectRace(race) - - ## RESERVED - chrmgr.SetPathName("d:/ymir work/npc/" + name + "/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_GENERAL) - chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_WAIT, "wait.msa") - chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_WALK, "walk.msa") - chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_RUN, "run.msa") - chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_DEAD, "die.msa") - chrmgr.LoadRaceData(name + ".msm") - -def SetOneNPC(race, name): - chrmgr.CreateRace(race) - chrmgr.SelectRace(race) - - ## RESERVED - chrmgr.SetPathName("d:/ymir work/npc/" + name + "/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_GENERAL) - chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_WAIT, "wait.msa") - chrmgr.LoadRaceData(name + ".msm") - -def SetGuard(race, name): - chrmgr.CreateRace(race) - chrmgr.SelectRace(race) - - ## Script Data - chrmgr.SetPathName("d:/ymir work/npc/" + name + "/") - chrmgr.LoadRaceData(name + ".msm") - - ## GENERAL - chrmgr.RegisterMotionMode(chr.MOTION_MODE_GENERAL) - chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_SPAWN, "00.msa") - chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_WAIT, "00.msa") - chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_RUN, "03.msa") - - chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_DAMAGE, "30.msa", 50) - chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_DAMAGE, "30_1.msa", 50) - - chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_DAMAGE_BACK, "34.msa", 50) - chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_DAMAGE_BACK, "34_1.msa", 50) - - chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_DAMAGE_FLYING,"32.msa") - chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_STAND_UP, "33.msa") - - chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_DAMAGE_FLYING_BACK, "35.msa") - chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_STAND_UP_BACK, "36.msa") - - chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_DEAD, "31.msa") - chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_DEAD_BACK, "37.msa") - - chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_NORMAL_ATTACK, "20.msa") - - ## Attacking Data - chrmgr.RegisterNormalAttack(chr.MOTION_MODE_GENERAL, chr.MOTION_NORMAL_ATTACK) - -def SetWarp(race): - chrmgr.CreateRace(race) - chrmgr.SelectRace(race) - - chrmgr.SetPathName("d:/ymir work/npc/warp/") - chrmgr.LoadRaceData("warp.msm") - - ## GENERAL - chrmgr.RegisterMotionMode(chr.MOTION_MODE_GENERAL) - chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_WAIT, "wait.msa") - -def SetDoor(race, name): - chrmgr.CreateRace(race) - chrmgr.SelectRace(race) - chrmgr.SetPathName("d:/ymir work/npc/"+name+"/") - chrmgr.LoadRaceData(name + ".msm") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_GENERAL) - chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_WAIT, "close_wait.msa") - chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_DEAD, "open.msa") - -def SetGuildBuilding(race, name, grade): - chrmgr.CreateRace(race) - chrmgr.SelectRace(race) - chrmgr.SetPathName("d:/ymir work/guild/building/%s/" % name) - chrmgr.LoadRaceData("%s%02d.msm" % (name, grade)) - chrmgr.RegisterMotionMode(chr.MOTION_MODE_GENERAL) - #chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_DEAD, name + "_destruction.msa") \ No newline at end of file diff --git a/tools/root/prototype.py b/tools/root/prototype.py deleted file mode 100644 index 0b7b5288..00000000 --- a/tools/root/prototype.py +++ /dev/null @@ -1,61 +0,0 @@ -import dbg -import app -import localeInfo -import wndMgr -import systemSetting -import mouseModule -import networkModule -import uiCandidate -import constInfo -import musicInfo -import stringCommander - - - -#bind_me(locals().values()) - -def RunApp(): - musicInfo.LoadLastPlayFieldMusic() - - app.SetHairColorEnable(constInfo.HAIR_COLOR_ENABLE) - app.SetArmorSpecularEnable(constInfo.ARMOR_SPECULAR_ENABLE) - app.SetWeaponSpecularEnable(constInfo.WEAPON_SPECULAR_ENABLE) - - app.SetMouseHandler(mouseModule.mouseController) - wndMgr.SetMouseHandler(mouseModule.mouseController) - wndMgr.SetScreenSize(systemSetting.GetWidth(), systemSetting.GetHeight()) - - try: - app.Create(localeInfo.APP_TITLE, systemSetting.GetWidth(), systemSetting.GetHeight(), 1) - except RuntimeError as msg: - msg = str(msg) - if "CREATE_DEVICE" == msg: - dbg.LogBox("Sorry, Your system does not support 3D graphics,\r\nplease check your hardware and system configeration\r\nthen try again.") - else: - dbg.LogBox("Metin2.%s" % msg) - return - - app.SetCamera(1500.0, 30.0, 0.0, 180.0) - - #Gets and sets the floating-point control word - #app.SetControlFP() - - if not mouseModule.mouseController.Create(): - return - - mainStream = networkModule.MainStream() - mainStream.Create() - - #mainStream.SetLoadingPhase() - - mainStream.SetLoginPhase() - #mainStream.SetSelectCharacterPhase() - #mainStream.SetCreateCharacterPhase() - #mainStream.SetSelectEmpirePhase() - #mainStream.SetGamePhase() - app.Loop() - - mainStream.Destroy() - -RunApp() - diff --git a/tools/root/rootlibcythonizer.py b/tools/root/rootlibcythonizer.py deleted file mode 100644 index d5da07cd..00000000 --- a/tools/root/rootlibcythonizer.py +++ /dev/null @@ -1,39 +0,0 @@ -import sys -libpath = '..\\..\\Extern\\Py2Lib\\lib' -sys.path.append(libpath) - -#import utils -import imp -fp, pathname, description = imp.find_module('utils', [libpath]) -utils = imp.load_module('utils', fp, pathname, description) -import cythonizer - -pys = utils.findMatchedFiles(".", "*.py") -pys.remove('RootlibCythonizer.py') -moduleLst = cythonizer.run(pys, forceRecompile=True) -moduleNameLst = [] -sourceFileLst = [] -import os.path -for m in moduleLst: - for source in m.sources: - base, ext = os.path.splitext(source) - moduleName = base.split('/')[-1] - moduleNameLst.append(moduleName) - sourceFileLst.append(base + (".cpp" if "c++" == m.language else ".c")) - -import sourceWriter - -sourceFileName = sourceWriter.run(moduleNameLst, 'rootlib') -print(("%s create successful." % sourceFileName)) - -# not yet implemented. -#from distutils.dist import Distribution - -#dist = Distribution({'name' : 'test', 'libraries' : [('test', {'sources' : sourceFileLst})]}) - -#from builder import Builder -#cBuilder = Builder(dist) -#cBuilder.run() -#import builder -#builder.run(sourceFileLst, 'test') - diff --git a/tools/root/servercommandparser.py b/tools/root/servercommandparser.py deleted file mode 100644 index 6227f132..00000000 --- a/tools/root/servercommandparser.py +++ /dev/null @@ -1,58 +0,0 @@ -import net -import background -import stringCommander -import constInfo - -class ServerCommandParser(object): - - def __init__(self): - net.SetServerCommandParserWindow(self) - self.__ServerCommand_Build() - - def __ServerCommand_Build(self): - serverCommandList={ - "DayMode" : self.__DayMode_Update, - "xmas_snow" : self.__XMasSnow_Enable, - "xmas_boom" : self.__XMasBoom_Enable, - "xmas_tree" : self.__XMasTree_Enable, - "newyear_boom" : self.__XMasBoom_Enable, - "item_mall" : self.__ItemMall_Open, - - } - - self.serverCommander=stringCommander.Analyzer() - for serverCommandItem in list(serverCommandList.items()): - self.serverCommander.SAFE_RegisterCallBack( - serverCommandItem[0], serverCommandItem[1] - ) - - def BINARY_ServerCommand_Run(self, line): - try: - print((" BINARY_ServerCommand_Reserve", line)) - return self.serverCommander.Run(line) - except RuntimeError as msg: - import dbg - dbg.TraceError(msg) - return 0 - - def __PreserveCommand(self, line): - net.PreserveServerCommand(line) - - def __DayMode_Update(self, mode): - self.__PreserveCommand("PRESERVE_DayMode " + mode) - - def __ItemMall_Open(self): - self.__PreserveCommand("item_mall") - - ## 임시 - def __XMasBoom_Enable(self, mode): - if "1"==mode: - self.__PreserveCommand("PRESERVE_DayMode dark") - else: - self.__PreserveCommand("PRESERVE_DayMode light") - def __XMasSnow_Enable(self, mode): - self.__PreserveCommand("xmas_snow " + mode) - def __XMasTree_Enable(self, grade): - self.__PreserveCommand("xmas_tree " + grade) - -parserWnd = ServerCommandParser() diff --git a/tools/root/serverinfo.py b/tools/root/serverinfo.py deleted file mode 100644 index ad1e1d70..00000000 --- a/tools/root/serverinfo.py +++ /dev/null @@ -1,59 +0,0 @@ -SERVER_NAME = "Metin2" -SERVER_NAME_TEST = "Test" -SERVER_IP = "178.18.255.214" -SERVER_IP_TEST = "127.0.0.1" -CH1_NAME = "CH1" -CH2_NAME = "CH2" -CH3_NAME = "CH3" -CH4_NAME = "CH4" -PORT_1 = 11011 -PORT_2 = 11021 -PORT_3 = 11031 -PORT_4 = 11041 -PORT_AUTH = 11000 -PORT_MARK = 11011 - -STATE_NONE = "..." - -STATE_DICT = { - 0 : "....", - 1 : "NORM", - 2 : "BUSY", - 3 : "FULL" -} - -SERVER01_CHANNEL_DICT = { - 1:{"key":11,"name":CH1_NAME,"ip":SERVER_IP,"tcp_port":PORT_1,"udp_port":PORT_1,"state":STATE_NONE,}, - 2:{"key":12,"name":CH2_NAME,"ip":SERVER_IP,"tcp_port":PORT_2,"udp_port":PORT_2,"state":STATE_NONE,}, - 3:{"key":13,"name":CH3_NAME,"ip":SERVER_IP,"tcp_port":PORT_3,"udp_port":PORT_3,"state":STATE_NONE,}, - 4:{"key":14,"name":CH4_NAME,"ip":SERVER_IP,"tcp_port":PORT_4,"udp_port":PORT_4,"state":STATE_NONE,}, -} - -SERVER02_CHANNEL_DICT = { - 1:{"key":21,"name":CH1_NAME,"ip":SERVER_IP_TEST,"tcp_port":PORT_1,"udp_port":PORT_1,"state":STATE_NONE,}, - 2:{"key":22,"name":CH2_NAME,"ip":SERVER_IP_TEST,"tcp_port":PORT_2,"udp_port":PORT_2,"state":STATE_NONE,}, -} - -REGION_NAME_DICT = { - 0 : "", -} - -REGION_AUTH_SERVER_DICT = { - 0 : { - 1 : { "ip":SERVER_IP, "port":PORT_AUTH, }, - 2 : { "ip":SERVER_IP_TEST, "port":PORT_AUTH, }, - - } -} - -REGION_DICT = { - 0 : { - 1 : { "name" :SERVER_NAME, "channel" : SERVER01_CHANNEL_DICT, }, - 2 : { "name" :SERVER_NAME_TEST, "channel" : SERVER02_CHANNEL_DICT, }, - }, -} - -MARKADDR_DICT = { - 10 : { "ip" : SERVER_IP, "tcp_port" : PORT_MARK, "mark" : "10.tga", "symbol_path" : "10", }, - 20 : { "ip" : SERVER_IP_TEST, "tcp_port" : PORT_MARK, "mark" : "20.tga", "symbol_path" : "20", }, -} \ No newline at end of file diff --git a/tools/root/stringcommander.py b/tools/root/stringcommander.py deleted file mode 100644 index 36d00b8b..00000000 --- a/tools/root/stringcommander.py +++ /dev/null @@ -1,65 +0,0 @@ -import _weakref - -class CallBackFunction: - class __noarg_call__: - def __init__(self, cls, obj, func): - self.cls=cls - self.obj=_weakref.proxy(obj) - self.func=_weakref.proxy(func) - - def __call__(self, *arg): - return self.func(self.obj) - - class __arg_call__: - def __init__(self, cls, obj, func): - self.cls=cls - self.obj=_weakref.proxy(obj) - self.func=_weakref.proxy(func) - - def __call__(self, *arg): - return self.func(self.obj, *arg) - - def __init__(self, mfunc): - self.argCount=mfunc.__func__.__code__.co_argcount - - if self.argCount>1: - self.call=CallBackFunction.__arg_call__(mfunc.__self__.__class__, mfunc.__self__, mfunc.__func__) - else: - self.call=CallBackFunction.__noarg_call__(mfunc.__self__.__class__, mfunc.__self__, mfunc.__func__) - - def __call__(self, *arg): - return self.call(*arg) - - def GetArgumentCount(self): - return self.argCount - -class Analyzer: - def __init__(self): - self.cmdDict={} - - def SAFE_RegisterCallBack(self, cmd, callBackFunc): - self.cmdDict[cmd]=CallBackFunction(callBackFunc) - - def Run(self, line): - tokens=line.split() - - if len(tokens)==0: - return 1 - - cmd=tokens.pop(0) - - try: - callBackFunc=self.cmdDict[cmd] - except KeyError: - return 0 - - argCount=callBackFunc.GetArgumentCount()-1 - - if len(tokens)1: - self.call=__mem_func__.__arg_call__(mfunc.__self__.__class__, mfunc.__self__, mfunc.__func__) - else: - self.call=__mem_func__.__noarg_call__(mfunc.__self__.__class__, mfunc.__self__, mfunc.__func__) - - def __call__(self, *arg): - return self.call(*arg) - - -class Window(object): - def NoneMethod(cls): - pass - - NoneMethod = classmethod(NoneMethod) - - def __init__(self, layer = "UI"): - self.hWnd = None - self.parentWindow = 0 - self.onMouseLeftButtonUpEvent = None - self.RegisterWindow(layer) - self.Hide() - - def __del__(self): - if wndMgr and self.hWnd: - wndMgr.Destroy(self.hWnd) - - def RegisterWindow(self, layer): - self.hWnd = wndMgr.Register(self, layer) - - def Destroy(self): - pass - - def GetWindowHandle(self): - return self.hWnd - - def AddFlag(self, style): - wndMgr.AddFlag(self.hWnd, style) - - def IsRTL(self): - return wndMgr.IsRTL(self.hWnd) - - def SetWindowName(self, Name): - wndMgr.SetName(self.hWnd, Name) - - def GetWindowName(self): - return wndMgr.GetName(self.hWnd) - - def SetParent(self, parent): - wndMgr.SetParent(self.hWnd, parent.hWnd) - - def SetParentProxy(self, parent): - self.parentWindow=proxy(parent) - wndMgr.SetParent(self.hWnd, parent.hWnd) - - def GetParentProxy(self): - return self.parentWindow - - def SetPickAlways(self): - wndMgr.SetPickAlways(self.hWnd) - - def SetWindowHorizontalAlignLeft(self): - wndMgr.SetWindowHorizontalAlign(self.hWnd, wndMgr.HORIZONTAL_ALIGN_LEFT) - - def SetWindowHorizontalAlignCenter(self): - wndMgr.SetWindowHorizontalAlign(self.hWnd, wndMgr.HORIZONTAL_ALIGN_CENTER) - - def SetWindowHorizontalAlignRight(self): - wndMgr.SetWindowHorizontalAlign(self.hWnd, wndMgr.HORIZONTAL_ALIGN_RIGHT) - - def SetWindowVerticalAlignTop(self): - wndMgr.SetWindowVerticalAlign(self.hWnd, wndMgr.VERTICAL_ALIGN_TOP) - - def SetWindowVerticalAlignCenter(self): - wndMgr.SetWindowVerticalAlign(self.hWnd, wndMgr.VERTICAL_ALIGN_CENTER) - - def SetWindowVerticalAlignBottom(self): - wndMgr.SetWindowVerticalAlign(self.hWnd, wndMgr.VERTICAL_ALIGN_BOTTOM) - - def SetTop(self): - wndMgr.SetTop(self.hWnd) - - def Show(self): - wndMgr.Show(self.hWnd) - - def Hide(self): - wndMgr.Hide(self.hWnd) - - def Lock(self): - wndMgr.Lock(self.hWnd) - - def Unlock(self): - wndMgr.Unlock(self.hWnd) - - def IsShow(self): - return wndMgr.IsShow(self.hWnd) - - def UpdateRect(self): - wndMgr.UpdateRect(self.hWnd) - - def SetSize(self, width, height): - wndMgr.SetWindowSize(self.hWnd, width, height) - - def GetWidth(self): - return wndMgr.GetWindowWidth(self.hWnd) - - def GetHeight(self): - return wndMgr.GetWindowHeight(self.hWnd) - - def GetLocalPosition(self): - return wndMgr.GetWindowLocalPosition(self.hWnd) - - def GetGlobalPosition(self): - return wndMgr.GetWindowGlobalPosition(self.hWnd) - - def GetMouseLocalPosition(self): - return wndMgr.GetMouseLocalPosition(self.hWnd) - - def GetRect(self): - return wndMgr.GetWindowRect(self.hWnd) - - def SetPosition(self, x, y): - wndMgr.SetWindowPosition(self.hWnd, int(x), int(y)) - - def SetCenterPosition(self, x = 0, y = 0): - center_x = (wndMgr.GetScreenWidth() - self.GetWidth()) // 2 + int(x) - center_y = (wndMgr.GetScreenHeight() - self.GetHeight()) // 2 + int(y) - self.SetPosition(center_x, center_y) - - def IsFocus(self): - return wndMgr.IsFocus(self.hWnd) - - def SetFocus(self): - wndMgr.SetFocus(self.hWnd) - - def KillFocus(self): - wndMgr.KillFocus(self.hWnd) - - def GetChildCount(self): - return wndMgr.GetChildCount(self.hWnd) - - def IsIn(self): - return wndMgr.IsIn(self.hWnd) - - def SetOnMouseLeftButtonUpEvent(self, event): - self.onMouseLeftButtonUpEvent = event - - def OnMouseLeftButtonUp(self): - if self.onMouseLeftButtonUpEvent: - self.onMouseLeftButtonUpEvent() - - def EnableScissorRect(self): - wndMgr.EnableScissorRect(self.hWnd) - - def DisableScissorRect(self): - wndMgr.DisableScissorRect(self.hWnd) - - def IsScissorRectEnabled(self): - return wndMgr.IsScissorRectEnabled(self.hWnd) - -class ListBoxEx(Window): - - class Item(Window): - def __init__(self): - Window.__init__(self) - - def __del__(self): - Window.__del__(self) - - def SetParent(self, parent): - Window.SetParent(self, parent) - self.parent=proxy(parent) - - def OnMouseLeftButtonDown(self): - self.parent.SelectItem(self) - - def OnRender(self): - if self.parent.GetSelectedItem()==self: - self.OnSelectedRender() - - def OnSelectedRender(self): - x, y = self.GetGlobalPosition() - grp.SetColor(grp.GenerateColor(0.0, 0.0, 0.7, 0.7)) - grp.RenderBar(x, y, self.GetWidth(), self.GetHeight()) - - def __init__(self): - Window.__init__(self) - - self.viewItemCount=10 - self.basePos=0 - self.itemHeight=16 - self.itemStep=20 - self.selItem=0 - self.itemList=[] - self.onSelectItemEvent = lambda *arg: None - - if app.IsRTL(): - self.itemWidth=130 - else: - self.itemWidth=100 - - self.scrollBar=None - self.__UpdateSize() - - def __del__(self): - Window.__del__(self) - - def __UpdateSize(self): - height=self.itemStep*self.__GetViewItemCount() - - self.SetSize(self.itemWidth, height) - - def IsEmpty(self): - if len(self.itemList)==0: - return 1 - return 0 - - def SetItemStep(self, itemStep): - self.itemStep=itemStep - self.__UpdateSize() - - def SetItemSize(self, itemWidth, itemHeight): - self.itemWidth=itemWidth - self.itemHeight=itemHeight - self.__UpdateSize() - - def SetViewItemCount(self, viewItemCount): - self.viewItemCount=viewItemCount - - def SetSelectEvent(self, event): - self.onSelectItemEvent = event - - def SetBasePos(self, basePos): - for oldItem in self.itemList[self.basePos:self.basePos+self.viewItemCount]: - oldItem.Hide() - - self.basePos=basePos - - pos=basePos - for newItem in self.itemList[self.basePos:self.basePos+self.viewItemCount]: - (x, y)=self.GetItemViewCoord(pos, newItem.GetWidth()) - newItem.SetPosition(x, y) - newItem.Show() - pos+=1 - - def GetItemIndex(self, argItem): - return self.itemList.index(argItem) - - def GetSelectedItem(self): - return self.selItem - - def SelectIndex(self, index): - - if index >= len(self.itemList) or index < 0: - self.selItem = None - return - - try: - self.selItem=self.itemList[index] - except: - pass - - def SelectItem(self, selItem): - self.selItem=selItem - self.onSelectItemEvent(selItem) - - def RemoveAllItems(self): - self.selItem=None - self.itemList=[] - - if self.scrollBar: - self.scrollBar.SetPos(0) - - def RemoveItem(self, delItem): - if delItem==self.selItem: - self.selItem=None - - self.itemList.remove(delItem) - - def AppendItem(self, newItem): - newItem.SetParent(self) - newItem.SetSize(self.itemWidth, self.itemHeight) - - pos=len(self.itemList) - if self.__IsInViewRange(pos): - (x, y)=self.GetItemViewCoord(pos, newItem.GetWidth()) - newItem.SetPosition(x, y) - newItem.Show() - else: - newItem.Hide() - - self.itemList.append(newItem) - - def SetScrollBar(self, scrollBar): - scrollBar.SetScrollEvent(__mem_func__(self.__OnScroll)) - self.scrollBar=scrollBar - - def __OnScroll(self): - self.SetBasePos(int(self.scrollBar.GetPos()*self.__GetScrollLen())) - - def __GetScrollLen(self): - scrollLen=self.__GetItemCount()-self.__GetViewItemCount() - if scrollLen<0: - return 0 - - return scrollLen - - def __GetViewItemCount(self): - return self.viewItemCount - - def __GetItemCount(self): - return len(self.itemList) - - def GetItemViewCoord(self, pos, itemWidth): - if app.IsRTL(): - return (self.GetWidth()-itemWidth-10, (pos-self.basePos)*self.itemStep) - else: - return (0, (pos-self.basePos)*self.itemStep) - - def __IsInViewRange(self, pos): - if pos=self.basePos+self.viewItemCount: - return 0 - return 1 - -class CandidateListBox(ListBoxEx): - - HORIZONTAL_MODE = 0 - VERTICAL_MODE = 1 - - class Item(ListBoxEx.Item): - def __init__(self, text): - ListBoxEx.Item.__init__(self) - - self.textBox=TextLine() - self.textBox.SetParent(self) - self.textBox.SetText(text) - self.textBox.Show() - - def __del__(self): - ListBoxEx.Item.__del__(self) - - def __init__(self, mode = HORIZONTAL_MODE): - ListBoxEx.__init__(self) - self.itemWidth=32 - self.itemHeight=32 - self.mode = mode - - def __del__(self): - ListBoxEx.__del__(self) - - def SetMode(self, mode): - self.mode = mode - - def AppendItem(self, newItem): - ListBoxEx.AppendItem(self, newItem) - - def GetItemViewCoord(self, pos): - if self.mode == self.HORIZONTAL_MODE: - return ((pos-self.basePos)*self.itemStep, 0) - elif self.mode == self.VERTICAL_MODE: - return (0, (pos-self.basePos)*self.itemStep) - - -class TextLine(Window): - def __init__(self): - Window.__init__(self) - self.max = 0 - - # MR-15: Multiline dialog messages - self.extraLines = [] - self.textHAlign = None - self.textVAlign = None - # MR-15: -- END OF -- Multiline dialog messages - - self.SetFontName(localeInfo.UI_DEF_FONT) - - def __del__(self): - Window.__del__(self) - - def RegisterWindow(self, layer): - self.hWnd = wndMgr.RegisterTextLine(self, layer) - - def SetMax(self, max): - wndMgr.SetMax(self.hWnd, max) - - def SetLimitWidth(self, width): - wndMgr.SetLimitWidth(self.hWnd, width) - - def SetMultiLine(self): - wndMgr.SetMultiLine(self.hWnd, True) - - def SetHorizontalAlignArabic(self): - wndMgr.SetHorizontalAlign(self.hWnd, wndMgr.TEXT_HORIZONTAL_ALIGN_ARABIC) - - def SetHorizontalAlignLeft(self): - # MR-15: Multiline dialog messages - self.textHAlign = "left" - # MR-15: -- END OF -- Multiline dialog messages - - wndMgr.SetHorizontalAlign(self.hWnd, wndMgr.TEXT_HORIZONTAL_ALIGN_LEFT) - - def SetHorizontalAlignRight(self): - # MR-15: Multiline dialog messages - self.textHAlign = "right" - # MR-15: -- END OF -- Multiline dialog messages - - wndMgr.SetHorizontalAlign(self.hWnd, wndMgr.TEXT_HORIZONTAL_ALIGN_RIGHT) - - def SetHorizontalAlignCenter(self): - # MR-15: Multiline dialog messages - self.textHAlign = "center" - # MR-15: -- END OF -- Multiline dialog messages - - wndMgr.SetHorizontalAlign(self.hWnd, wndMgr.TEXT_HORIZONTAL_ALIGN_CENTER) - - def SetVerticalAlignTop(self): - # MR-15: Multiline dialog messages - self.textVAlign = "top" - # MR-15: -- END OF -- Multiline dialog messages - - wndMgr.SetVerticalAlign(self.hWnd, wndMgr.TEXT_VERTICAL_ALIGN_TOP) - - def SetVerticalAlignBottom(self): - # MR-15: Multiline dialog messages - self.textVAlign = "bottom" - # MR-15: -- END OF -- Multiline dialog messages - - wndMgr.SetVerticalAlign(self.hWnd, wndMgr.TEXT_VERTICAL_ALIGN_BOTTOM) - - def SetVerticalAlignCenter(self): - # MR-15: Multiline dialog messages - self.textVAlign = "center" - # MR-15: -- END OF -- Multiline dialog messages - - wndMgr.SetVerticalAlign(self.hWnd, wndMgr.TEXT_VERTICAL_ALIGN_CENTER) - - def SetSecret(self, Value=True): - wndMgr.SetSecret(self.hWnd, Value) - - def SetOutline(self, Value=True): - wndMgr.SetOutline(self.hWnd, Value) - - def SetBaseDirectionAuto(self): - wndMgr.SetBaseDirection(self.hWnd, wndMgr.TEXT_BASEDIR_AUTO) - - def SetBaseDirectionLTR(self): - wndMgr.SetBaseDirection(self.hWnd, wndMgr.TEXT_BASEDIR_LTR) - - def SetBaseDirectionRTL(self): - wndMgr.SetBaseDirection(self.hWnd, wndMgr.TEXT_BASEDIR_RTL) - - def SetFeather(self, value=True): - wndMgr.SetFeather(self.hWnd, value) - - def SetFontName(self, fontName): - # MR-15: Multiline dialog messages - self.fontName = fontName - # MR-15: -- END OF -- Multiline dialog messages - - wndMgr.SetFontName(self.hWnd, fontName) - - def SetDefaultFontName(self): - wndMgr.SetFontName(self.hWnd, localeInfo.UI_DEF_FONT) - - def SetFontColor(self, red, green, blue): - wndMgr.SetFontColor(self.hWnd, red, green, blue) - - def SetPackedFontColor(self, color): - wndMgr.SetFontColor(self.hWnd, color) - - def SetText(self, text): - # MR-15: Multiline dialog messages - for line in self.extraLines: - line.Hide() - - self.extraLines = [] - - if not text: - wndMgr.SetText(self.hWnd, "") - return - - if "\\n" in text or "/n" in text: - parts = text.replace("\\n", "\n").replace("/n", "\n").split("\n") - parts = [p.strip(" ") for p in parts] - - wndMgr.SetText(self.hWnd, parts[0]) - - if len(parts) > 1: - LINE_HEIGHT = 20 - - for i, part in enumerate(parts[1:], 1): - extra = TextLine() - extra.SetParent(self) - extra.SetFontName(self.fontName) - - if self.textHAlign == "center": - extra.SetHorizontalAlignCenter() - elif self.textHAlign == "right": - extra.SetHorizontalAlignRight() - - if self.textVAlign == "center": - extra.SetVerticalAlignCenter() - elif self.textVAlign == "bottom": - extra.SetVerticalAlignBottom() - - extra.SetPosition(0, LINE_HEIGHT * i) - extra.SetText(part) - extra.Show() - self.extraLines.append(extra) - else: - wndMgr.SetText(self.hWnd, text) - - def GetText(self): - text = wndMgr.GetText(self.hWnd) - - for line in self.extraLines: - text += "\n" + wndMgr.GetText(line.hWnd) - - return text - # MR-15: -- END OF -- Multiline dialog messages - - def GetTextSize(self): - return wndMgr.GetTextSize(self.hWnd) - -class EmptyCandidateWindow(Window): - def __init__(self): - Window.__init__(self) - - def __del__(self): - Window.__init__(self) - - def Load(self): - pass - - def SetCandidatePosition(self, x, y, textCount): - pass - - def Clear(self): - pass - - def Append(self, text): - pass - - def Refresh(self): - pass - - def Select(self): - pass - -class EditLine(TextLine): - candidateWindowClassDict = {} - - def __init__(self): - TextLine.__init__(self) - - self.eventReturn = Window.NoneMethod - self.eventEscape = Window.NoneMethod - self.eventTab = None - self.numberMode = False - self.useIME = True - self.secretMode = False - - self.candidateWindowClass = None - self.candidateWindow = None - - self.readingWnd = ReadingWnd() - self.readingWnd.Hide() - - - def __del__(self): - TextLine.__del__(self) - - self.eventReturn = Window.NoneMethod - self.eventEscape = Window.NoneMethod - self.eventTab = None - - def __SetCandidateClass(self, candidateWindowClass): - if self.candidateWindowClass==candidateWindowClass: - return - - self.candidateWindowClass = candidateWindowClass - self.candidateWindow = self.candidateWindowClass() - self.candidateWindow.Load() - self.candidateWindow.Hide() - - def RegisterWindow(self, layer): - self.hWnd = wndMgr.RegisterTextLine(self, layer) - - def SAFE_SetReturnEvent(self, event): - self.eventReturn = __mem_func__(event) - - def SetReturnEvent(self, event): - self.eventReturn = event - - def SetEscapeEvent(self, event): - self.eventEscape = event - - def SetTabEvent(self, event): - self.eventTab = event - - def SetMax(self, max): - self.max = max - wndMgr.SetMax(self.hWnd, self.max) - ime.SetMax(self.max) - self.SetUserMax(self.max) - - def SetUserMax(self, max): - self.userMax = max - ime.SetUserMax(self.userMax) - - def SetNumberMode(self): - self.numberMode = True - - #def AddExceptKey(self, key): - # ime.AddExceptKey(key) - - #def ClearExceptKey(self): - # ime.ClearExceptKey() - - def SetIMEFlag(self, flag): - self.useIME = flag - - def SetSecretMode(self, flag): - self.secretMode = flag - - def SetText(self, text): - wndMgr.SetText(self.hWnd, text) - - if self.IsFocus(): - ime.SetText(text) - - def Enable(self): - wndMgr.ShowCursor(self.hWnd) - - def Disable(self): - wndMgr.HideCursor(self.hWnd) - - def SetEndPosition(self): - ime.MoveEnd() - - def OnSetFocus(self): - Text = self.GetText() - ime.SetText(Text) - ime.SetMax(self.max) - ime.SetUserMax(self.userMax) - ime.SetCursorPosition(-1) - if self.numberMode: - ime.SetNumberMode() - else: - ime.SetStringMode() - ime.SetSecretMode(self.secretMode) - ime.EnableCaptureInput() - if self.useIME: - ime.EnableIME() - else: - ime.DisableIME() - wndMgr.ShowCursor(self.hWnd, True) - - def OnKillFocus(self): - self.SetText(ime.GetText()) - #self.OnIMECloseCandidateList() - self.OnIMECloseReadingWnd() - ime.DisableIME() - ime.DisableCaptureInput() - ime.SetSecretMode(0) - wndMgr.HideCursor(self.hWnd) - - def OnIMEOpenCandidateList(self): - self.candidateWindow.Show() - self.candidateWindow.Clear() - self.candidateWindow.Refresh() - - gx, gy = self.GetGlobalPosition() - self.candidateWindow.SetCandidatePosition(gx, gy, len(self.GetText())) - - return True - - def OnIMECloseCandidateList(self): - self.candidateWindow.Hide() - return True - - def OnIMEOpenReadingWnd(self): - gx, gy = self.GetGlobalPosition() - textlen = len(self.GetText())-2 - reading = ime.GetReading() - readinglen = len(reading) - self.readingWnd.SetReadingPosition( gx + textlen*6-24-readinglen*6, gy ) - self.readingWnd.SetText(reading) - if ime.GetReadingError() == 0: - self.readingWnd.SetTextColor(0xffffffff) - else: - self.readingWnd.SetTextColor(0xffff0000) - self.readingWnd.SetSize(readinglen * 6 + 4, 19) - self.readingWnd.Show() - return True - - def OnIMECloseReadingWnd(self): - self.readingWnd.Hide() - return True - - def OnIMEUpdate(self): - snd.PlaySound("sound/ui/type.wav") - self.SetText(ime.GetText()) - - def OnIMETab(self): - if self.eventTab: - self.eventTab() - return True - - return False - - def OnIMEReturn(self): - snd.PlaySound("sound/ui/click.wav") - self.eventReturn() - - return True - - def OnPressEscapeKey(self): - self.eventEscape() - return True - - def OnKeyDown(self, key): - if app.DIK_F1 == key: - return False - if app.DIK_F2 == key: - return False - if app.DIK_F3 == key: - return False - if app.DIK_F4 == key: - return False - if app.DIK_LALT == key: - return False - if app.DIK_SYSRQ == key: - return False - if app.DIK_LCONTROL == key: - return False - return True - - def OnKeyUp(self, key): - if app.DIK_F1 == key: - return False - if app.DIK_F2 == key: - return False - if app.DIK_F3 == key: - return False - if app.DIK_F4 == key: - return False - if app.DIK_LALT == key: - return False - if app.DIK_SYSRQ == key: - return False - if app.DIK_LCONTROL == key: - return False - - return True - - def OnIMEKeyDown(self, key): - # Left - if app.VK_LEFT == key: - ime.MoveLeft() - return True - # Right - if app.VK_RIGHT == key: - ime.MoveRight() - return True - - # Home - if app.VK_HOME == key: - ime.MoveHome() - return True - # End - if app.VK_END == key: - ime.MoveEnd() - return True - - # Delete - if app.VK_DELETE == key: - ime.Delete() - TextLine.SetText(self, ime.GetText()) - return True - - return True - - #def OnMouseLeftButtonDown(self): - # self.SetFocus() - def OnMouseLeftButtonDown(self): - if False == self.IsIn(): - return False - - self.SetFocus() - PixelPosition = wndMgr.GetCursorPosition(self.hWnd) - ime.SetCursorPosition(PixelPosition) - -class MarkBox(Window): - def __init__(self, layer = "UI"): - Window.__init__(self, layer) - - def __del__(self): - Window.__del__(self) - - def RegisterWindow(self, layer): - self.hWnd = wndMgr.RegisterMarkBox(self, layer) - - def Load(self): - wndMgr.MarkBox_Load(self.hWnd) - - def SetScale(self, scale): - wndMgr.MarkBox_SetScale(self.hWnd, scale) - - def SetIndex(self, guildID): - MarkID = guild.GuildIDToMarkID(guildID) - wndMgr.MarkBox_SetImageFilename(self.hWnd, guild.GetMarkImageFilenameByMarkID(MarkID)) - wndMgr.MarkBox_SetIndex(self.hWnd, guild.GetMarkIndexByMarkID(MarkID)) - - def SetAlpha(self, alpha): - wndMgr.MarkBox_SetDiffuseColor(self.hWnd, 1.0, 1.0, 1.0, alpha) - -class ImageBox(Window): - def __init__(self, layer = "UI"): - Window.__init__(self, layer) - - self.eventDict={} - - def __del__(self): - Window.__del__(self) - - def RegisterWindow(self, layer): - self.hWnd = wndMgr.RegisterImageBox(self, layer) - - def LoadImage(self, imageName): - self.name=imageName - wndMgr.LoadImage(self.hWnd, imageName) - - if len(self.eventDict)!=0: - print(("LOAD IMAGE", self, self.eventDict)) - - def LoadImageFromFile(self, imageName): - self.name=imageName - wndMgr.LoadImageFromFile(self.hWnd, imageName) - - if len(self.eventDict)!=0: - print(("LOAD IMAGE", self, self.eventDict)) - - def SetAlpha(self, alpha): - wndMgr.SetDiffuseColor(self.hWnd, 1.0, 1.0, 1.0, alpha) - - def GetWidth(self): - return wndMgr.GetWidth(self.hWnd) - - def GetHeight(self): - return wndMgr.GetHeight(self.hWnd) - - def OnMouseOverIn(self): - try: - self.eventDict["MOUSE_OVER_IN"]() - except KeyError: - pass - - def OnMouseOverOut(self): - try: - self.eventDict["MOUSE_OVER_OUT"]() - except KeyError: - pass - - def SAFE_SetStringEvent(self, event, func): - self.eventDict[event]=__mem_func__(func) - - -class ExpandedImageBox(ImageBox): - def __init__(self, layer = "UI"): - ImageBox.__init__(self, layer) - - def __del__(self): - ImageBox.__del__(self) - - def RegisterWindow(self, layer): - self.hWnd = wndMgr.RegisterExpandedImageBox(self, layer) - - def SetScale(self, xScale, yScale): - wndMgr.SetScale(self.hWnd, xScale, yScale) - - def SetOrigin(self, x, y): - wndMgr.SetOrigin(self.hWnd, x, y) - - def SetRotation(self, rotation): - wndMgr.SetRotation(self.hWnd, rotation) - - def SetRenderingMode(self, mode): - wndMgr.SetRenderingMode(self.hWnd, mode) - - # [0.0, 1.0] ������ ����ŭ �ۼ�Ʈ�� �׸��� �ʴ´�. - def SetRenderingRect(self, left, top, right, bottom): - wndMgr.SetRenderingRect(self.hWnd, left, top, right, bottom) - - def SetPercentage(self, curValue, maxValue): - if maxValue: - self.SetRenderingRect(0.0, 0.0, -1.0 + float(curValue) / float(maxValue), 0.0) - else: - self.SetRenderingRect(0.0, 0.0, 0.0, 0.0) - - def GetWidth(self): - return wndMgr.GetWindowWidth(self.hWnd) - - def GetHeight(self): - return wndMgr.GetWindowHeight(self.hWnd) - -class AniImageBox(Window): - def __init__(self, layer = "UI"): - Window.__init__(self, layer) - - def __del__(self): - Window.__del__(self) - - def RegisterWindow(self, layer): - self.hWnd = wndMgr.RegisterAniImageBox(self, layer) - - def SetDelay(self, delay): - wndMgr.SetDelay(self.hWnd, delay) - - def AppendImage(self, filename): - wndMgr.AppendImage(self.hWnd, filename) - - def SetPercentage(self, curValue, maxValue): - wndMgr.SetRenderingRect(self.hWnd, 0.0, 0.0, -1.0 + float(curValue) / float(maxValue), 0.0) - - def OnEndFrame(self): - pass - -class Button(Window): - def __init__(self, layer = "UI"): - Window.__init__(self, layer) - - self.eventFunc = None - self.eventArgs = None - - self.ButtonText = None - self.ToolTipText = None - - def __del__(self): - Window.__del__(self) - - self.eventFunc = None - self.eventArgs = None - - def RegisterWindow(self, layer): - self.hWnd = wndMgr.RegisterButton(self, layer) - - def SetUpVisual(self, filename): - wndMgr.SetUpVisual(self.hWnd, filename) - - def SetOverVisual(self, filename): - wndMgr.SetOverVisual(self.hWnd, filename) - - def SetDownVisual(self, filename): - wndMgr.SetDownVisual(self.hWnd, filename) - - def SetDisableVisual(self, filename): - wndMgr.SetDisableVisual(self.hWnd, filename) - - def GetUpVisualFileName(self): - return wndMgr.GetUpVisualFileName(self.hWnd) - - def GetOverVisualFileName(self): - return wndMgr.GetOverVisualFileName(self.hWnd) - - def GetDownVisualFileName(self): - return wndMgr.GetDownVisualFileName(self.hWnd) - - def Flash(self): - wndMgr.Flash(self.hWnd) - - def Enable(self): - wndMgr.Enable(self.hWnd) - - def Disable(self): - wndMgr.Disable(self.hWnd) - - def Down(self): - wndMgr.Down(self.hWnd) - - def SetUp(self): - wndMgr.SetUp(self.hWnd) - - def SAFE_SetEvent(self, func, *args): - self.eventFunc = __mem_func__(func) - self.eventArgs = args - - def SetEvent(self, func, *args): - self.eventFunc = func - self.eventArgs = args - - def SetTextColor(self, color): - if not self.ButtonText: - return - self.ButtonText.SetPackedFontColor(color) - - def SetText(self, text, height = 4): - - if not self.ButtonText: - textLine = TextLine() - textLine.SetParent(self) - textLine.SetPosition(self.GetWidth()/2, self.GetHeight()/2) - textLine.SetVerticalAlignCenter() - textLine.SetHorizontalAlignCenter() - textLine.Show() - self.ButtonText = textLine - - self.ButtonText.SetText(text) - - def SetFormToolTipText(self, type, text, x, y): - if not self.ToolTipText: - toolTip=createToolTipWindowDict[type]() - toolTip.SetParent(self) - toolTip.SetSize(0, 0) - toolTip.SetHorizontalAlignCenter() - toolTip.SetOutline() - toolTip.Hide() - toolTip.SetPosition(x + self.GetWidth()/2, y) - self.ToolTipText=toolTip - - self.ToolTipText.SetText(text) - - def SetToolTipWindow(self, toolTip): - self.ToolTipText=toolTip - self.ToolTipText.SetParentProxy(self) - - def SetToolTipText(self, text, x=0, y = -19): - self.SetFormToolTipText("TEXT", text, x, y) - - def CallEvent(self): - snd.PlaySound("sound/ui/click.wav") - - if self.eventFunc: - self.eventFunc(*self.eventArgs) - - def ShowToolTip(self): - if self.ToolTipText: - self.ToolTipText.Show() - - def HideToolTip(self): - if self.ToolTipText: - self.ToolTipText.Hide() - - def IsDown(self): - return wndMgr.IsDown(self.hWnd) - -class RadioButton(Button): - def __init__(self): - Button.__init__(self) - - def __del__(self): - Button.__del__(self) - - def RegisterWindow(self, layer): - self.hWnd = wndMgr.RegisterRadioButton(self, layer) - -class RadioButtonGroup: - def __init__(self): - self.buttonGroup = [] - self.selectedBtnIdx = -1 - - def __del__(self): - for button, ue, de in self.buttonGroup: - button.__del__() - - def Show(self): - for (button, selectEvent, unselectEvent) in self.buttonGroup: - button.Show() - - def Hide(self): - for (button, selectEvent, unselectEvent) in self.buttonGroup: - button.Hide() - - def SetText(self, idx, text): - if idx >= len(self.buttonGroup): - return - (button, selectEvent, unselectEvent) = self.buttonGroup[idx] - button.SetText(text) - - def OnClick(self, btnIdx): - if btnIdx == self.selectedBtnIdx: - return - (button, selectEvent, unselectEvent) = self.buttonGroup[self.selectedBtnIdx] - if unselectEvent: - unselectEvent() - button.SetUp() - - self.selectedBtnIdx = btnIdx - (button, selectEvent, unselectEvent) = self.buttonGroup[btnIdx] - if selectEvent: - selectEvent() - - button.Down() - - def AddButton(self, button, selectEvent, unselectEvent): - i = len(self.buttonGroup) - button.SetEvent(lambda : self.OnClick(i)) - self.buttonGroup.append([button, selectEvent, unselectEvent]) - button.SetUp() - - def Create(rawButtonGroup): - radioGroup = RadioButtonGroup() - for (button, selectEvent, unselectEvent) in rawButtonGroup: - radioGroup.AddButton(button, selectEvent, unselectEvent) - - radioGroup.OnClick(0) - - return radioGroup - - Create=staticmethod(Create) - -class ToggleButton(Button): - def __init__(self): - Button.__init__(self) - - self.eventUp = None - self.eventDown = None - - def __del__(self): - Button.__del__(self) - - self.eventUp = None - self.eventDown = None - - def SetToggleUpEvent(self, event): - self.eventUp = event - - def SetToggleDownEvent(self, event): - self.eventDown = event - - def RegisterWindow(self, layer): - self.hWnd = wndMgr.RegisterToggleButton(self, layer) - - def OnToggleUp(self): - if self.eventUp: - self.eventUp() - - def OnToggleDown(self): - if self.eventDown: - self.eventDown() - -class DragButton(Button): - def __init__(self): - Button.__init__(self) - self.AddFlag("movable") - - self.callbackEnable = True - self.eventMove = lambda: None - - def __del__(self): - Button.__del__(self) - - self.eventMove = lambda: None - - def RegisterWindow(self, layer): - self.hWnd = wndMgr.RegisterDragButton(self, layer) - - def SetMoveEvent(self, event): - self.eventMove = event - - def SetRestrictMovementArea(self, x, y, width, height): - wndMgr.SetRestrictMovementArea(self.hWnd, x, y, width, height) - - def TurnOnCallBack(self): - self.callbackEnable = True - - def TurnOffCallBack(self): - self.callbackEnable = False - - def OnMove(self): - if self.callbackEnable: - self.eventMove() - -class NumberLine(Window): - - def __init__(self, layer = "UI"): - Window.__init__(self, layer) - - def __del__(self): - Window.__del__(self) - - def RegisterWindow(self, layer): - self.hWnd = wndMgr.RegisterNumberLine(self, layer) - - def SetHorizontalAlignCenter(self): - wndMgr.SetNumberHorizontalAlignCenter(self.hWnd) - - def SetHorizontalAlignRight(self): - wndMgr.SetNumberHorizontalAlignRight(self.hWnd) - - def SetPath(self, path): - wndMgr.SetPath(self.hWnd, path) - - def SetNumber(self, number): - wndMgr.SetNumber(self.hWnd, number) - -################################################################################################### -## PythonScript Element -################################################################################################### - -class Box(Window): - - def RegisterWindow(self, layer): - self.hWnd = wndMgr.RegisterBox(self, layer) - - def SetColor(self, color): - wndMgr.SetColor(self.hWnd, color) - -class Bar(Window): - - def RegisterWindow(self, layer): - self.hWnd = wndMgr.RegisterBar(self, layer) - - def SetColor(self, color): - wndMgr.SetColor(self.hWnd, color) - -class Line(Window): - - def RegisterWindow(self, layer): - self.hWnd = wndMgr.RegisterLine(self, layer) - - def SetColor(self, color): - wndMgr.SetColor(self.hWnd, color) - -class SlotBar(Window): - - def __init__(self): - Window.__init__(self) - - def RegisterWindow(self, layer): - self.hWnd = wndMgr.RegisterBar3D(self, layer) - -## Same with SlotBar -class Bar3D(Window): - - def __init__(self): - Window.__init__(self) - - def RegisterWindow(self, layer): - self.hWnd = wndMgr.RegisterBar3D(self, layer) - - def SetColor(self, left, right, center): - wndMgr.SetColor(self.hWnd, left, right, center) - -class SlotWindow(Window): - - def __init__(self): - Window.__init__(self) - - self.StartIndex = 0 - - self.eventSelectEmptySlot = None - self.eventSelectItemSlot = None - self.eventUnselectEmptySlot = None - self.eventUnselectItemSlot = None - self.eventUseSlot = None - self.eventOverInItem = None - self.eventOverOutItem = None - self.eventPressedSlotButton = None - - def __del__(self): - Window.__del__(self) - - self.eventSelectEmptySlot = None - self.eventSelectItemSlot = None - self.eventUnselectEmptySlot = None - self.eventUnselectItemSlot = None - self.eventUseSlot = None - self.eventOverInItem = None - self.eventOverOutItem = None - self.eventPressedSlotButton = None - - def RegisterWindow(self, layer): - self.hWnd = wndMgr.RegisterSlotWindow(self, layer) - - def SetSlotStyle(self, style): - wndMgr.SetSlotStyle(self.hWnd, style) - - def HasSlot(self, slotIndex): - return wndMgr.HasSlot(self.hWnd, slotIndex) - - def SetSlotBaseImage(self, imageFileName, r, g, b, a): - wndMgr.SetSlotBaseImage(self.hWnd, imageFileName, r, g, b, a) - - def SetCoverButton(self,\ - slotIndex,\ - upName="d:/ymir work/ui/public/slot_cover_button_01.sub",\ - overName="d:/ymir work/ui/public/slot_cover_button_02.sub",\ - downName="d:/ymir work/ui/public/slot_cover_button_03.sub",\ - disableName="d:/ymir work/ui/public/slot_cover_button_04.sub",\ - LeftButtonEnable = False,\ - RightButtonEnable = True): - wndMgr.SetCoverButton(self.hWnd, slotIndex, upName, overName, downName, disableName, LeftButtonEnable, RightButtonEnable) - - def EnableCoverButton(self, slotIndex): - wndMgr.EnableCoverButton(self.hWnd, slotIndex) - - def DisableCoverButton(self, slotIndex): - wndMgr.DisableCoverButton(self.hWnd, slotIndex) - - def SetAlwaysRenderCoverButton(self, slotIndex, bAlwaysRender = TRUE): - wndMgr.SetAlwaysRenderCoverButton(self.hWnd, slotIndex, bAlwaysRender) - - def AppendSlotButton(self, upName, overName, downName): - wndMgr.AppendSlotButton(self.hWnd, upName, overName, downName) - - def ShowSlotButton(self, slotNumber): - wndMgr.ShowSlotButton(self.hWnd, slotNumber) - - def HideAllSlotButton(self): - wndMgr.HideAllSlotButton(self.hWnd) - - def AppendRequirementSignImage(self, filename): - wndMgr.AppendRequirementSignImage(self.hWnd, filename) - - def ShowRequirementSign(self, slotNumber): - wndMgr.ShowRequirementSign(self.hWnd, slotNumber) - - def HideRequirementSign(self, slotNumber): - wndMgr.HideRequirementSign(self.hWnd, slotNumber) - - def ActivateSlot(self, slotNumber): - wndMgr.ActivateSlot(self.hWnd, slotNumber) - - def DeactivateSlot(self, slotNumber): - wndMgr.DeactivateSlot(self.hWnd, slotNumber) - - def ShowSlotBaseImage(self, slotNumber): - wndMgr.ShowSlotBaseImage(self.hWnd, slotNumber) - - def HideSlotBaseImage(self, slotNumber): - wndMgr.HideSlotBaseImage(self.hWnd, slotNumber) - - def SAFE_SetButtonEvent(self, button, state, event): - if "LEFT"==button: - if "EMPTY"==state: - self.eventSelectEmptySlot=__mem_func__(event) - elif "EXIST"==state: - self.eventSelectItemSlot=__mem_func__(event) - elif "ALWAYS"==state: - self.eventSelectEmptySlot=__mem_func__(event) - self.eventSelectItemSlot=__mem_func__(event) - elif "RIGHT"==button: - if "EMPTY"==state: - self.eventUnselectEmptySlot=__mem_func__(event) - elif "EXIST"==state: - self.eventUnselectItemSlot=__mem_func__(event) - elif "ALWAYS"==state: - self.eventUnselectEmptySlot=__mem_func__(event) - self.eventUnselectItemSlot=__mem_func__(event) - - def SetSelectEmptySlotEvent(self, empty): - self.eventSelectEmptySlot = empty - - def SetSelectItemSlotEvent(self, item): - self.eventSelectItemSlot = item - - def SetUnselectEmptySlotEvent(self, empty): - self.eventUnselectEmptySlot = empty - - def SetUnselectItemSlotEvent(self, item): - self.eventUnselectItemSlot = item - - def SetUseSlotEvent(self, use): - self.eventUseSlot = use - - def SetOverInItemEvent(self, event): - self.eventOverInItem = event - - def SetOverOutItemEvent(self, event): - self.eventOverOutItem = event - - def SetPressedSlotButtonEvent(self, event): - self.eventPressedSlotButton = event - - def GetSlotCount(self): - return wndMgr.GetSlotCount(self.hWnd) - - def SetUseMode(self, flag): - "True�϶��� ItemToItem �� �������� �����ش�" - wndMgr.SetUseMode(self.hWnd, flag) - - def SetUsableItem(self, flag): - "True�� ���� ����Ų �������� ItemToItem ���� �����ϴ�" - wndMgr.SetUsableItem(self.hWnd, flag) - - ## Slot - def SetSlotCoolTime(self, slotIndex, coolTime, elapsedTime = 0.0): - wndMgr.SetSlotCoolTime(self.hWnd, slotIndex, coolTime, elapsedTime) - - def StoreSlotCoolTime(self, key, slotIndex, coolTime, elapsedTime = 0.0): - wndMgr.StoreSlotCoolTime(self.hWnd, key, slotIndex, coolTime, elapsedTime) - - def RestoreSlotCoolTime(self, key): - wndMgr.RestoreSlotCoolTime(self.hWnd, key) - - def TransferSlotCoolTime(self, slotIndex1, slotIndex2): - wndMgr.TransferSlotCoolTime(self.hWnd, slotIndex1, slotIndex2) - - def ClearSlotCoolTime(self, slotIndex): - wndMgr.ClearSlotCoolTime(self.hWnd, slotIndex) - - def DisableSlot(self, slotIndex): - wndMgr.DisableSlot(self.hWnd, slotIndex) - - def EnableSlot(self, slotIndex): - wndMgr.EnableSlot(self.hWnd, slotIndex) - - def LockSlot(self, slotIndex): - wndMgr.LockSlot(self.hWnd, slotIndex) - - def UnlockSlot(self, slotIndex): - wndMgr.UnlockSlot(self.hWnd, slotIndex) - - def RefreshSlot(self): - wndMgr.RefreshSlot(self.hWnd) - - def ClearSlot(self, slotNumber): - wndMgr.ClearSlot(self.hWnd, slotNumber) - - def ClearAllSlot(self): - wndMgr.ClearAllSlot(self.hWnd) - - def AppendSlot(self, index, x, y, width, height): - wndMgr.AppendSlot(self.hWnd, index, x, y, width, height) - - def SetSlot(self, slotIndex, itemIndex, width, height, icon, diffuseColor = (1.0, 1.0, 1.0, 1.0)): - wndMgr.SetSlot(self.hWnd, slotIndex, itemIndex, width, height, icon, diffuseColor) - - def SetSlotCount(self, slotNumber, count): - wndMgr.SetSlotCount(self.hWnd, slotNumber, count) - - def SetSlotCountNew(self, slotNumber, grade, count): - wndMgr.SetSlotCountNew(self.hWnd, slotNumber, grade, count) - - def SetItemSlot(self, renderingSlotNumber, ItemIndex, ItemCount = 0, diffuseColor = (1.0, 1.0, 1.0, 1.0)): - if 0 == ItemIndex or None == ItemIndex: - wndMgr.ClearSlot(self.hWnd, renderingSlotNumber) - return - - item.SelectItem(ItemIndex) - itemIcon = item.GetIconImage() - - item.SelectItem(ItemIndex) - (width, height) = item.GetItemSize() - - wndMgr.SetSlot(self.hWnd, renderingSlotNumber, ItemIndex, width, height, itemIcon, diffuseColor) - wndMgr.SetSlotCount(self.hWnd, renderingSlotNumber, ItemCount) - - def SetSkillSlot(self, renderingSlotNumber, skillIndex, skillLevel): - - skillIcon = skill.GetIconImage(skillIndex) - - if 0 == skillIcon: - wndMgr.ClearSlot(self.hWnd, renderingSlotNumber) - return - - wndMgr.SetSlot(self.hWnd, renderingSlotNumber, skillIndex, 1, 1, skillIcon) - wndMgr.SetSlotCount(self.hWnd, renderingSlotNumber, skillLevel) - - def SetSkillSlotNew(self, renderingSlotNumber, skillIndex, skillGrade, skillLevel): - - skillIcon = skill.GetIconImageNew(skillIndex, skillGrade) - - if 0 == skillIcon: - wndMgr.ClearSlot(self.hWnd, renderingSlotNumber) - return - - wndMgr.SetSlot(self.hWnd, renderingSlotNumber, skillIndex, 1, 1, skillIcon) - - def SetEmotionSlot(self, renderingSlotNumber, emotionIndex): - import player - icon = player.GetEmotionIconImage(emotionIndex) - - if 0 == icon: - wndMgr.ClearSlot(self.hWnd, renderingSlotNumber) - return - - wndMgr.SetSlot(self.hWnd, renderingSlotNumber, emotionIndex, 1, 1, icon) - - def SetRenderSlot(self, renderingSlotNumber, diffuseColor = (1.0, 1.0, 1.0, 1.0)): - wndMgr.SetSlot(self.hWnd, renderingSlotNumber, 1, 1, 1, 0, diffuseColor) - wndMgr.SetSlotCount(self.hWnd, renderingSlotNumber, 0) - - ## Event - def OnSelectEmptySlot(self, slotNumber): - if self.eventSelectEmptySlot: - self.eventSelectEmptySlot(slotNumber) - - def OnSelectItemSlot(self, slotNumber): - if self.eventSelectItemSlot: - self.eventSelectItemSlot(slotNumber) - - def OnUnselectEmptySlot(self, slotNumber): - if self.eventUnselectEmptySlot: - self.eventUnselectEmptySlot(slotNumber) - - def OnUnselectItemSlot(self, slotNumber): - if self.eventUnselectItemSlot: - self.eventUnselectItemSlot(slotNumber) - - def OnUseSlot(self, slotNumber): - if self.eventUseSlot: - self.eventUseSlot(slotNumber) - - def OnOverInItem(self, slotNumber): - if self.eventOverInItem: - self.eventOverInItem(slotNumber) - - def OnOverOutItem(self): - if self.eventOverOutItem: - self.eventOverOutItem() - - def OnPressedSlotButton(self, slotNumber): - if self.eventPressedSlotButton: - self.eventPressedSlotButton(slotNumber) - - def GetStartIndex(self): - return 0 - -class GridSlotWindow(SlotWindow): - - def __init__(self): - SlotWindow.__init__(self) - - self.startIndex = 0 - - def __del__(self): - SlotWindow.__del__(self) - - def RegisterWindow(self, layer): - self.hWnd = wndMgr.RegisterGridSlotWindow(self, layer) - - def ArrangeSlot(self, StartIndex, xCount, yCount, xSize, ySize, xBlank, yBlank): - - self.startIndex = StartIndex - - wndMgr.ArrangeSlot(self.hWnd, StartIndex, xCount, yCount, xSize, ySize, xBlank, yBlank) - self.startIndex = StartIndex - - def GetStartIndex(self): - return self.startIndex - -class TitleBar(Window): - - BLOCK_WIDTH = 32 - BLOCK_HEIGHT = 23 - - def __init__(self): - Window.__init__(self) - self.AddFlag("attach") - - def __del__(self): - Window.__del__(self) - - def MakeTitleBar(self, width, color): - - ## ���� Color�� ����ϰ� ���� ���� - - width = max(64, width) - - imgLeft = ImageBox() - imgCenter = ExpandedImageBox() - imgRight = ImageBox() - imgLeft.AddFlag("not_pick") - imgCenter.AddFlag("not_pick") - imgRight.AddFlag("not_pick") - imgLeft.SetParent(self) - imgCenter.SetParent(self) - imgRight.SetParent(self) - - if app.IsRTL(): - imgLeft.LoadImage("locale/ae/ui/pattern/titlebar_left.tga") - imgCenter.LoadImage("locale/ae/ui/pattern/titlebar_center.tga") - imgRight.LoadImage("locale/ae/ui/pattern/titlebar_right.tga") - else: - imgLeft.LoadImage("d:/ymir work/ui/pattern/titlebar_left.tga") - imgCenter.LoadImage("d:/ymir work/ui/pattern/titlebar_center.tga") - imgRight.LoadImage("d:/ymir work/ui/pattern/titlebar_right.tga") - - imgLeft.Show() - imgCenter.Show() - imgRight.Show() - - btnClose = Button() - btnClose.SetParent(self) - btnClose.SetUpVisual("d:/ymir work/ui/public/close_button_01.sub") - btnClose.SetOverVisual("d:/ymir work/ui/public/close_button_02.sub") - btnClose.SetDownVisual("d:/ymir work/ui/public/close_button_03.sub") - btnClose.SetToolTipText(localeInfo.UI_CLOSE, 0, -23) - btnClose.Show() - - self.imgLeft = imgLeft - self.imgCenter = imgCenter - self.imgRight = imgRight - self.btnClose = btnClose - - self.SetWidth(width) - - def SetWidth(self, width): - self.imgCenter.SetRenderingRect(0.0, 0.0, float((width - self.BLOCK_WIDTH*2) - self.BLOCK_WIDTH) / self.BLOCK_WIDTH, 0.0) - self.imgCenter.SetPosition(self.BLOCK_WIDTH, 0) - self.imgRight.SetPosition(width - self.BLOCK_WIDTH, 0) - - if app.IsRTL(): - self.btnClose.SetPosition(3, 3) - else: - self.btnClose.SetPosition(width - self.btnClose.GetWidth() - 3, 3) - - self.SetSize(width, self.BLOCK_HEIGHT) - - def SetCloseEvent(self, event): - self.btnClose.SetEvent(event) - -class HorizontalBar(Window): - - BLOCK_WIDTH = 32 - BLOCK_HEIGHT = 17 - - def __init__(self): - Window.__init__(self) - self.AddFlag("attach") - - def __del__(self): - Window.__del__(self) - - def Create(self, width): - - width = max(96, width) - - imgLeft = ImageBox() - imgLeft.SetParent(self) - imgLeft.AddFlag("not_pick") - imgLeft.LoadImage("d:/ymir work/ui/pattern/horizontalbar_left.tga") - imgLeft.Show() - - imgCenter = ExpandedImageBox() - imgCenter.SetParent(self) - imgCenter.AddFlag("not_pick") - imgCenter.LoadImage("d:/ymir work/ui/pattern/horizontalbar_center.tga") - imgCenter.Show() - - imgRight = ImageBox() - imgRight.SetParent(self) - imgRight.AddFlag("not_pick") - imgRight.LoadImage("d:/ymir work/ui/pattern/horizontalbar_right.tga") - imgRight.Show() - - self.imgLeft = imgLeft - self.imgCenter = imgCenter - self.imgRight = imgRight - self.SetWidth(width) - - def SetWidth(self, width): - self.imgCenter.SetRenderingRect(0.0, 0.0, float((width - self.BLOCK_WIDTH*2) - self.BLOCK_WIDTH) / self.BLOCK_WIDTH, 0.0) - self.imgCenter.SetPosition(self.BLOCK_WIDTH, 0) - self.imgRight.SetPosition(width - self.BLOCK_WIDTH, 0) - self.SetSize(width, self.BLOCK_HEIGHT) - -class Gauge(Window): - - SLOT_WIDTH = 16 - SLOT_HEIGHT = 7 - - GAUGE_TEMPORARY_PLACE = 12 - GAUGE_WIDTH = 16 - - def __init__(self): - Window.__init__(self) - self.width = 0 - def __del__(self): - Window.__del__(self) - - def MakeGauge(self, width, color): - - self.width = max(48, width) - - imgSlotLeft = ImageBox() - imgSlotLeft.SetParent(self) - imgSlotLeft.LoadImage("d:/ymir work/ui/pattern/gauge_slot_left.tga") - imgSlotLeft.Show() - - imgSlotRight = ImageBox() - imgSlotRight.SetParent(self) - imgSlotRight.LoadImage("d:/ymir work/ui/pattern/gauge_slot_right.tga") - imgSlotRight.Show() - imgSlotRight.SetPosition(width - self.SLOT_WIDTH, 0) - - imgSlotCenter = ExpandedImageBox() - imgSlotCenter.SetParent(self) - imgSlotCenter.LoadImage("d:/ymir work/ui/pattern/gauge_slot_center.tga") - imgSlotCenter.Show() - imgSlotCenter.SetRenderingRect(0.0, 0.0, float((width - self.SLOT_WIDTH*2) - self.SLOT_WIDTH) / self.SLOT_WIDTH, 0.0) - imgSlotCenter.SetPosition(self.SLOT_WIDTH, 0) - - imgGauge = ExpandedImageBox() - imgGauge.SetParent(self) - imgGauge.LoadImage("d:/ymir work/ui/pattern/gauge_" + color + ".tga") - imgGauge.Show() - imgGauge.SetRenderingRect(0.0, 0.0, 0.0, 0.0) - imgGauge.SetPosition(self.GAUGE_TEMPORARY_PLACE, 0) - - imgSlotLeft.AddFlag("attach") - imgSlotCenter.AddFlag("attach") - imgSlotRight.AddFlag("attach") - - self.imgLeft = imgSlotLeft - self.imgCenter = imgSlotCenter - self.imgRight = imgSlotRight - self.imgGauge = imgGauge - - self.SetSize(width, self.SLOT_HEIGHT) - - def SetPercentage(self, curValue, maxValue): - - # PERCENTAGE_MAX_VALUE_ZERO_DIVISION_ERROR - if maxValue > 0.0: - percentage = min(1.0, float(curValue)/float(maxValue)) - else: - percentage = 0.0 - # END_OF_PERCENTAGE_MAX_VALUE_ZERO_DIVISION_ERROR - - gaugeSize = -1.0 + float(self.width - self.GAUGE_TEMPORARY_PLACE*2) * percentage / self.GAUGE_WIDTH - self.imgGauge.SetRenderingRect(0.0, 0.0, gaugeSize, 0.0) - -class Board(Window): - - CORNER_WIDTH = 32 - CORNER_HEIGHT = 32 - LINE_WIDTH = 128 - LINE_HEIGHT = 128 - - LT = 0 - LB = 1 - RT = 2 - RB = 3 - L = 0 - R = 1 - T = 2 - B = 3 - - def __init__(self): - Window.__init__(self) - - self.MakeBoard("d:/ymir work/ui/pattern/Board_Corner_", "d:/ymir work/ui/pattern/Board_Line_") - self.MakeBase() - - def MakeBoard(self, cornerPath, linePath): - - CornerFileNames = [ cornerPath+dir+".tga" for dir in ("LeftTop", "LeftBottom", "RightTop", "RightBottom", ) ] - LineFileNames = [ linePath+dir+".tga" for dir in ("Left", "Right", "Top", "Bottom", ) ] - """ - CornerFileNames = ( - "d:/ymir work/ui/pattern/Board_Corner_LeftTop.tga", - "d:/ymir work/ui/pattern/Board_Corner_LeftBottom.tga", - "d:/ymir work/ui/pattern/Board_Corner_RightTop.tga", - "d:/ymir work/ui/pattern/Board_Corner_RightBottom.tga", - ) - LineFileNames = ( - "d:/ymir work/ui/pattern/Board_Line_Left.tga", - "d:/ymir work/ui/pattern/Board_Line_Right.tga", - "d:/ymir work/ui/pattern/Board_Line_Top.tga", - "d:/ymir work/ui/pattern/Board_Line_Bottom.tga", - ) - """ - - self.Corners = [] - for fileName in CornerFileNames: - Corner = ExpandedImageBox() - Corner.AddFlag("not_pick") - Corner.LoadImage(fileName) - Corner.SetParent(self) - Corner.SetPosition(0, 0) - Corner.Show() - self.Corners.append(Corner) - - self.Lines = [] - for fileName in LineFileNames: - Line = ExpandedImageBox() - Line.AddFlag("not_pick") - Line.LoadImage(fileName) - Line.SetParent(self) - Line.SetPosition(0, 0) - Line.Show() - self.Lines.append(Line) - - self.Lines[self.L].SetPosition(0, self.CORNER_HEIGHT) - self.Lines[self.T].SetPosition(self.CORNER_WIDTH, 0) - - def MakeBase(self): - self.Base = ExpandedImageBox() - self.Base.AddFlag("not_pick") - self.Base.LoadImage("d:/ymir work/ui/pattern/Board_Base.tga") - self.Base.SetParent(self) - self.Base.SetPosition(self.CORNER_WIDTH, self.CORNER_HEIGHT) - self.Base.Show() - - def __del__(self): - Window.__del__(self) - - def SetSize(self, width, height): - - width = max(self.CORNER_WIDTH*2, width) - height = max(self.CORNER_HEIGHT*2, height) - Window.SetSize(self, width, height) - - self.Corners[self.LB].SetPosition(0, height - self.CORNER_HEIGHT) - self.Corners[self.RT].SetPosition(width - self.CORNER_WIDTH, 0) - self.Corners[self.RB].SetPosition(width - self.CORNER_WIDTH, height - self.CORNER_HEIGHT) - self.Lines[self.R].SetPosition(width - self.CORNER_WIDTH, self.CORNER_HEIGHT) - self.Lines[self.B].SetPosition(self.CORNER_HEIGHT, height - self.CORNER_HEIGHT) - - verticalShowingPercentage = float((height - self.CORNER_HEIGHT*2) - self.LINE_HEIGHT) / self.LINE_HEIGHT - horizontalShowingPercentage = float((width - self.CORNER_WIDTH*2) - self.LINE_WIDTH) / self.LINE_WIDTH - self.Lines[self.L].SetRenderingRect(0, 0, 0, verticalShowingPercentage) - self.Lines[self.R].SetRenderingRect(0, 0, 0, verticalShowingPercentage) - self.Lines[self.T].SetRenderingRect(0, 0, horizontalShowingPercentage, 0) - self.Lines[self.B].SetRenderingRect(0, 0, horizontalShowingPercentage, 0) - - if self.Base: - self.Base.SetRenderingRect(0, 0, horizontalShowingPercentage, verticalShowingPercentage) - -class BoardWithTitleBar(Board): - def __init__(self): - Board.__init__(self) - - titleBar = TitleBar() - titleBar.SetParent(self) - titleBar.MakeTitleBar(0, "red") - titleBar.SetPosition(8, 7) - titleBar.Show() - - titleName = TextLine() - titleName.SetParent(titleBar) - titleName.SetPosition(0, 4) - titleName.SetWindowHorizontalAlignCenter() - titleName.SetHorizontalAlignCenter() - titleName.Show() - - self.titleBar = titleBar - self.titleName = titleName - - self.SetCloseEvent(self.Hide) - - def __del__(self): - Board.__del__(self) - self.titleBar = None - self.titleName = None - - def SetSize(self, width, height): - self.titleBar.SetWidth(width - 15) - #self.pickRestrictWindow.SetSize(width, height - 30) - Board.SetSize(self, width, height) - self.titleName.UpdateRect() - - def SetTitleColor(self, color): - self.titleName.SetPackedFontColor(color) - - def SetTitleName(self, name): - self.titleName.SetText(name) - - def SetCloseEvent(self, event): - self.titleBar.SetCloseEvent(event) - -class ThinBoard(Window): - - CORNER_WIDTH = 16 - CORNER_HEIGHT = 16 - LINE_WIDTH = 16 - LINE_HEIGHT = 16 - BOARD_COLOR = grp.GenerateColor(0.0, 0.0, 0.0, 0.51) - - LT = 0 - LB = 1 - RT = 2 - RB = 3 - L = 0 - R = 1 - T = 2 - B = 3 - - def __init__(self, layer = "UI"): - Window.__init__(self, layer) - - CornerFileNames = [ "d:/ymir work/ui/pattern/ThinBoard_Corner_"+dir+".tga" for dir in ["LeftTop","LeftBottom","RightTop","RightBottom"] ] - LineFileNames = [ "d:/ymir work/ui/pattern/ThinBoard_Line_"+dir+".tga" for dir in ["Left","Right","Top","Bottom"] ] - - self.Corners = [] - for fileName in CornerFileNames: - Corner = ExpandedImageBox() - Corner.AddFlag("attach") - Corner.AddFlag("not_pick") - Corner.LoadImage(fileName) - Corner.SetParent(self) - Corner.SetPosition(0, 0) - Corner.Show() - self.Corners.append(Corner) - - self.Lines = [] - for fileName in LineFileNames: - Line = ExpandedImageBox() - Line.AddFlag("attach") - Line.AddFlag("not_pick") - Line.LoadImage(fileName) - Line.SetParent(self) - Line.SetPosition(0, 0) - Line.Show() - self.Lines.append(Line) - - Base = Bar() - Base.SetParent(self) - Base.AddFlag("attach") - Base.AddFlag("not_pick") - Base.SetPosition(self.CORNER_WIDTH, self.CORNER_HEIGHT) - Base.SetColor(self.BOARD_COLOR) - Base.Show() - self.Base = Base - - self.Lines[self.L].SetPosition(0, self.CORNER_HEIGHT) - self.Lines[self.T].SetPosition(self.CORNER_WIDTH, 0) - - def __del__(self): - Window.__del__(self) - - def SetSize(self, width, height): - - width = max(self.CORNER_WIDTH*2, width) - height = max(self.CORNER_HEIGHT*2, height) - Window.SetSize(self, width, height) - - self.Corners[self.LB].SetPosition(0, height - self.CORNER_HEIGHT) - self.Corners[self.RT].SetPosition(width - self.CORNER_WIDTH, 0) - self.Corners[self.RB].SetPosition(width - self.CORNER_WIDTH, height - self.CORNER_HEIGHT) - self.Lines[self.R].SetPosition(width - self.CORNER_WIDTH, self.CORNER_HEIGHT) - self.Lines[self.B].SetPosition(self.CORNER_HEIGHT, height - self.CORNER_HEIGHT) - - verticalShowingPercentage = float((height - self.CORNER_HEIGHT*2) - self.LINE_HEIGHT) / self.LINE_HEIGHT - horizontalShowingPercentage = float((width - self.CORNER_WIDTH*2) - self.LINE_WIDTH) / self.LINE_WIDTH - self.Lines[self.L].SetRenderingRect(0, 0, 0, verticalShowingPercentage) - self.Lines[self.R].SetRenderingRect(0, 0, 0, verticalShowingPercentage) - self.Lines[self.T].SetRenderingRect(0, 0, horizontalShowingPercentage, 0) - self.Lines[self.B].SetRenderingRect(0, 0, horizontalShowingPercentage, 0) - self.Base.SetSize(width - self.CORNER_WIDTH*2, height - self.CORNER_HEIGHT*2) - - def ShowInternal(self): - self.Base.Show() - for wnd in self.Lines: - wnd.Show() - for wnd in self.Corners: - wnd.Show() - - def HideInternal(self): - self.Base.Hide() - for wnd in self.Lines: - wnd.Hide() - for wnd in self.Corners: - wnd.Hide() - -class ScrollBar(Window): - - SCROLLBAR_WIDTH = 17 - SCROLLBAR_MIDDLE_HEIGHT = 9 - SCROLLBAR_BUTTON_WIDTH = 17 - SCROLLBAR_BUTTON_HEIGHT = 17 - MIDDLE_BAR_POS = 5 - MIDDLE_BAR_UPPER_PLACE = 3 - MIDDLE_BAR_DOWNER_PLACE = 4 - TEMP_SPACE = MIDDLE_BAR_UPPER_PLACE + MIDDLE_BAR_DOWNER_PLACE - - class MiddleBar(DragButton): - def __init__(self): - DragButton.__init__(self) - self.AddFlag("movable") - #self.AddFlag("restrict_x") - - def MakeImage(self): - top = ImageBox() - top.SetParent(self) - top.LoadImage("d:/ymir work/ui/pattern/ScrollBar_Top.tga") - top.SetPosition(0, 0) - top.AddFlag("not_pick") - top.Show() - bottom = ImageBox() - bottom.SetParent(self) - bottom.LoadImage("d:/ymir work/ui/pattern/ScrollBar_Bottom.tga") - bottom.AddFlag("not_pick") - bottom.Show() - - middle = ExpandedImageBox() - middle.SetParent(self) - middle.LoadImage("d:/ymir work/ui/pattern/ScrollBar_Middle.tga") - middle.SetPosition(0, 4) - middle.AddFlag("not_pick") - middle.Show() - - self.top = top - self.bottom = bottom - self.middle = middle - - def SetSize(self, height): - height = max(12, height) - DragButton.SetSize(self, 10, height) - self.bottom.SetPosition(0, height-4) - - height -= 4*3 - self.middle.SetRenderingRect(0, 0, 0, float(height)/4.0) - - def __init__(self): - Window.__init__(self) - - self.pageSize = 1 - self.curPos = 0.0 - self.eventScroll = lambda *arg: None - self.lockFlag = False - self.scrollStep = 0.20 - - - self.CreateScrollBar() - - def __del__(self): - Window.__del__(self) - - def CreateScrollBar(self): - barSlot = Bar3D() - barSlot.SetParent(self) - barSlot.AddFlag("not_pick") - barSlot.Show() - - middleBar = self.MiddleBar() - middleBar.SetParent(self) - middleBar.SetMoveEvent(__mem_func__(self.OnMove)) - middleBar.Show() - middleBar.MakeImage() - middleBar.SetSize(12) - - upButton = Button() - upButton.SetParent(self) - upButton.SetEvent(__mem_func__(self.OnUp)) - upButton.SetUpVisual("d:/ymir work/ui/public/scrollbar_up_button_01.sub") - upButton.SetOverVisual("d:/ymir work/ui/public/scrollbar_up_button_02.sub") - upButton.SetDownVisual("d:/ymir work/ui/public/scrollbar_up_button_03.sub") - upButton.Show() - - downButton = Button() - downButton.SetParent(self) - downButton.SetEvent(__mem_func__(self.OnDown)) - downButton.SetUpVisual("d:/ymir work/ui/public/scrollbar_down_button_01.sub") - downButton.SetOverVisual("d:/ymir work/ui/public/scrollbar_down_button_02.sub") - downButton.SetDownVisual("d:/ymir work/ui/public/scrollbar_down_button_03.sub") - downButton.Show() - - self.upButton = upButton - self.downButton = downButton - self.middleBar = middleBar - self.barSlot = barSlot - - self.SCROLLBAR_WIDTH = self.upButton.GetWidth() - self.SCROLLBAR_MIDDLE_HEIGHT = self.middleBar.GetHeight() - self.SCROLLBAR_BUTTON_WIDTH = self.upButton.GetWidth() - self.SCROLLBAR_BUTTON_HEIGHT = self.upButton.GetHeight() - - def Destroy(self): - self.middleBar = None - self.upButton = None - self.downButton = None - self.eventScroll = lambda *arg: None - - def SetScrollEvent(self, event): - self.eventScroll = event - - def SetMiddleBarSize(self, pageScale): - realHeight = self.GetHeight() - self.SCROLLBAR_BUTTON_HEIGHT*2 - self.SCROLLBAR_MIDDLE_HEIGHT = int(pageScale * float(realHeight)) - self.middleBar.SetSize(self.SCROLLBAR_MIDDLE_HEIGHT) - self.pageSize = (self.GetHeight() - self.SCROLLBAR_BUTTON_HEIGHT*2) - self.SCROLLBAR_MIDDLE_HEIGHT - (self.TEMP_SPACE) - - def SetScrollBarSize(self, height): - self.pageSize = (height - self.SCROLLBAR_BUTTON_HEIGHT*2) - self.SCROLLBAR_MIDDLE_HEIGHT - (self.TEMP_SPACE) - self.SetSize(self.SCROLLBAR_WIDTH, height) - self.upButton.SetPosition(0, 0) - self.downButton.SetPosition(0, height - self.SCROLLBAR_BUTTON_HEIGHT) - self.middleBar.SetRestrictMovementArea(self.MIDDLE_BAR_POS, self.SCROLLBAR_BUTTON_HEIGHT + self.MIDDLE_BAR_UPPER_PLACE, self.MIDDLE_BAR_POS+2, height - self.SCROLLBAR_BUTTON_HEIGHT*2 - self.TEMP_SPACE) - self.middleBar.SetPosition(self.MIDDLE_BAR_POS, 0) - - self.UpdateBarSlot() - - def UpdateBarSlot(self): - self.barSlot.SetPosition(0, self.SCROLLBAR_BUTTON_HEIGHT) - self.barSlot.SetSize(self.GetWidth() - 2, self.GetHeight() - self.SCROLLBAR_BUTTON_HEIGHT*2 - 2) - - def GetPos(self): - return self.curPos - - def SetPos(self, pos): - pos = max(0.0, pos) - pos = min(1.0, pos) - - newPos = float(self.pageSize) * pos - self.middleBar.SetPosition(self.MIDDLE_BAR_POS, int(newPos) + self.SCROLLBAR_BUTTON_HEIGHT + self.MIDDLE_BAR_UPPER_PLACE) - self.OnMove() - - def SetScrollStep(self, step): - self.scrollStep = step - - def GetScrollStep(self): - return self.scrollStep - - def OnUp(self): - self.SetPos(self.curPos-self.scrollStep) - - def OnDown(self): - self.SetPos(self.curPos+self.scrollStep) - - def OnMove(self): - - if self.lockFlag: - return - - if 0 == self.pageSize: - return - - (xLocal, yLocal) = self.middleBar.GetLocalPosition() - self.curPos = float(yLocal - self.SCROLLBAR_BUTTON_HEIGHT - self.MIDDLE_BAR_UPPER_PLACE) / float(self.pageSize) - - self.eventScroll() - - def OnMouseLeftButtonDown(self): - (xMouseLocalPosition, yMouseLocalPosition) = self.GetMouseLocalPosition() - pickedPos = yMouseLocalPosition - self.SCROLLBAR_BUTTON_HEIGHT - self.SCROLLBAR_MIDDLE_HEIGHT/2 - newPos = float(pickedPos) / float(self.pageSize) - self.SetPos(newPos) - - def LockScroll(self): - self.lockFlag = True - - def UnlockScroll(self): - self.lockFlag = False - -class ThinScrollBar(ScrollBar): - - def CreateScrollBar(self): - middleBar = self.MiddleBar() - middleBar.SetParent(self) - middleBar.SetMoveEvent(__mem_func__(self.OnMove)) - middleBar.Show() - middleBar.SetUpVisual("d:/ymir work/ui/public/scrollbar_thin_middle_button_01.sub") - middleBar.SetOverVisual("d:/ymir work/ui/public/scrollbar_thin_middle_button_02.sub") - middleBar.SetDownVisual("d:/ymir work/ui/public/scrollbar_thin_middle_button_03.sub") - - upButton = Button() - upButton.SetParent(self) - upButton.SetUpVisual("d:/ymir work/ui/public/scrollbar_thin_up_button_01.sub") - upButton.SetOverVisual("d:/ymir work/ui/public/scrollbar_thin_up_button_02.sub") - upButton.SetDownVisual("d:/ymir work/ui/public/scrollbar_thin_up_button_03.sub") - upButton.SetEvent(__mem_func__(self.OnUp)) - upButton.Show() - - downButton = Button() - downButton.SetParent(self) - downButton.SetUpVisual("d:/ymir work/ui/public/scrollbar_thin_down_button_01.sub") - downButton.SetOverVisual("d:/ymir work/ui/public/scrollbar_thin_down_button_02.sub") - downButton.SetDownVisual("d:/ymir work/ui/public/scrollbar_thin_down_button_03.sub") - downButton.SetEvent(__mem_func__(self.OnDown)) - downButton.Show() - - self.middleBar = middleBar - self.upButton = upButton - self.downButton = downButton - - self.SCROLLBAR_WIDTH = self.upButton.GetWidth() - self.SCROLLBAR_MIDDLE_HEIGHT = self.middleBar.GetHeight() - self.SCROLLBAR_BUTTON_WIDTH = self.upButton.GetWidth() - self.SCROLLBAR_BUTTON_HEIGHT = self.upButton.GetHeight() - self.MIDDLE_BAR_POS = 0 - self.MIDDLE_BAR_UPPER_PLACE = 0 - self.MIDDLE_BAR_DOWNER_PLACE = 0 - self.TEMP_SPACE = 0 - - def UpdateBarSlot(self): - pass - -class SmallThinScrollBar(ScrollBar): - - def CreateScrollBar(self): - middleBar = self.MiddleBar() - middleBar.SetParent(self) - middleBar.SetMoveEvent(__mem_func__(self.OnMove)) - middleBar.Show() - middleBar.SetUpVisual("d:/ymir work/ui/public/scrollbar_small_thin_middle_button_01.sub") - middleBar.SetOverVisual("d:/ymir work/ui/public/scrollbar_small_thin_middle_button_01.sub") - middleBar.SetDownVisual("d:/ymir work/ui/public/scrollbar_small_thin_middle_button_01.sub") - - upButton = Button() - upButton.SetParent(self) - upButton.SetUpVisual("d:/ymir work/ui/public/scrollbar_small_thin_up_button_01.sub") - upButton.SetOverVisual("d:/ymir work/ui/public/scrollbar_small_thin_up_button_02.sub") - upButton.SetDownVisual("d:/ymir work/ui/public/scrollbar_small_thin_up_button_03.sub") - upButton.SetEvent(__mem_func__(self.OnUp)) - upButton.Show() - - downButton = Button() - downButton.SetParent(self) - downButton.SetUpVisual("d:/ymir work/ui/public/scrollbar_small_thin_down_button_01.sub") - downButton.SetOverVisual("d:/ymir work/ui/public/scrollbar_small_thin_down_button_02.sub") - downButton.SetDownVisual("d:/ymir work/ui/public/scrollbar_small_thin_down_button_03.sub") - downButton.SetEvent(__mem_func__(self.OnDown)) - downButton.Show() - - self.middleBar = middleBar - self.upButton = upButton - self.downButton = downButton - - self.SCROLLBAR_WIDTH = self.upButton.GetWidth() - self.SCROLLBAR_MIDDLE_HEIGHT = self.middleBar.GetHeight() - self.SCROLLBAR_BUTTON_WIDTH = self.upButton.GetWidth() - self.SCROLLBAR_BUTTON_HEIGHT = self.upButton.GetHeight() - self.MIDDLE_BAR_POS = 0 - self.MIDDLE_BAR_UPPER_PLACE = 0 - self.MIDDLE_BAR_DOWNER_PLACE = 0 - self.TEMP_SPACE = 0 - - def UpdateBarSlot(self): - pass - -class SliderBar(Window): - - def __init__(self): - Window.__init__(self) - - self.curPos = 1.0 - self.pageSize = 1.0 - self.eventChange = None - - self.__CreateBackGroundImage() - self.__CreateCursor() - - def __del__(self): - Window.__del__(self) - - def __CreateBackGroundImage(self): - img = ImageBox() - img.SetParent(self) - img.LoadImage("d:/ymir work/ui/game/windows/sliderbar.sub") - img.Show() - self.backGroundImage = img - - ## - self.SetSize(self.backGroundImage.GetWidth(), self.backGroundImage.GetHeight()) - - def __CreateCursor(self): - cursor = DragButton() - cursor.AddFlag("movable") - cursor.AddFlag("restrict_y") - cursor.SetParent(self) - cursor.SetMoveEvent(__mem_func__(self.__OnMove)) - cursor.SetUpVisual("d:/ymir work/ui/game/windows/sliderbar_cursor.sub") - cursor.SetOverVisual("d:/ymir work/ui/game/windows/sliderbar_cursor.sub") - cursor.SetDownVisual("d:/ymir work/ui/game/windows/sliderbar_cursor.sub") - cursor.Show() - self.cursor = cursor - - ## - self.cursor.SetRestrictMovementArea(0, 0, self.backGroundImage.GetWidth(), 0) - self.pageSize = self.backGroundImage.GetWidth() - self.cursor.GetWidth() - - def __OnMove(self): - (xLocal, yLocal) = self.cursor.GetLocalPosition() - self.curPos = float(xLocal) / float(self.pageSize) - - if self.eventChange: - self.eventChange() - - def SetSliderPos(self, pos): - self.curPos = pos - self.cursor.SetPosition(int(self.pageSize * pos), 0) - - def GetSliderPos(self): - return self.curPos - - def SetEvent(self, event): - self.eventChange = event - - def Enable(self): - self.cursor.Show() - - def Disable(self): - self.cursor.Hide() - -class ListBox(Window): - - TEMPORARY_PLACE = 3 - - def __init__(self, layer = "UI"): - Window.__init__(self, layer) - self.overLine = -1 - self.selectedLine = -1 - self.width = 0 - self.height = 0 - self.stepSize = 17 - self.basePos = 0 - self.showLineCount = 0 - self.itemCenterAlign = True - self.itemList = [] - self.keyDict = {} - self.textDict = {} - self.event = lambda *arg: None - def __del__(self): - Window.__del__(self) - - def SetWidth(self, width): - self.SetSize(width, self.height) - - def SetSize(self, width, height): - Window.SetSize(self, width, height) - self.width = width - self.height = height - - def SetTextCenterAlign(self, flag): - self.itemCenterAlign = flag - - def SetBasePos(self, pos): - self.basePos = pos - self._LocateItem() - - def ClearItem(self): - self.keyDict = {} - self.textDict = {} - self.itemList = [] - self.overLine = -1 - self.selectedLine = -1 - - def InsertItem(self, number, text): - self.keyDict[len(self.itemList)] = number - self.textDict[len(self.itemList)] = text - - textLine = TextLine() - textLine.SetParent(self) - textLine.SetText(text) - textLine.Show() - - if self.itemCenterAlign: - textLine.SetWindowHorizontalAlignCenter() - textLine.SetHorizontalAlignCenter() - - self.itemList.append(textLine) - - self._LocateItem() - - def ChangeItem(self, number, text): - for key, value in list(self.keyDict.items()): - if value == number: - self.textDict[key] = text - - if number < len(self.itemList): - self.itemList[key].SetText(text) - - return - - def LocateItem(self): - self._LocateItem() - - def _LocateItem(self): - - skipCount = self.basePos - yPos = 0 - self.showLineCount = 0 - - for textLine in self.itemList: - textLine.Hide() - - if skipCount > 0: - skipCount -= 1 - continue - - if app.IsRTL(): - w, h = textLine.GetTextSize() - textLine.SetPosition(w+10, yPos + 3) - else: - textLine.SetPosition(0, yPos + 3) - - yPos += self.stepSize - - if yPos <= self.GetHeight(): - self.showLineCount += 1 - textLine.Show() - - def ArrangeItem(self): - self.SetSize(self.width, len(self.itemList) * self.stepSize) - self._LocateItem() - - def GetViewItemCount(self): - return int(self.GetHeight() // self.stepSize) - - def GetItemCount(self): - return len(self.itemList) - - def SetEvent(self, event): - self.event = event - - def SelectItem(self, line): - - if line not in self.keyDict: - return - - if line == self.selectedLine: - return - - self.selectedLine = line - self.event(self.keyDict.get(line, 0), self.textDict.get(line, "None")) - - def GetSelectedItem(self): - return self.keyDict.get(self.selectedLine, 0) - - def OnMouseLeftButtonDown(self): - if self.overLine < 0: - return - - def OnMouseLeftButtonUp(self): - if self.overLine >= 0: - self.SelectItem(self.overLine+self.basePos) - - def OnUpdate(self): - - self.overLine = -1 - - if self.IsIn(): - x, y = self.GetGlobalPosition() - height = self.GetHeight() - xMouse, yMouse = wndMgr.GetMousePosition() - - if yMouse - y < height - 1: - self.overLine = (yMouse - y) // self.stepSize - - if self.overLine < 0: - self.overLine = -1 - if self.overLine >= len(self.itemList): - self.overLine = -1 - - def OnRender(self): - xRender, yRender = self.GetGlobalPosition() - yRender -= self.TEMPORARY_PLACE - widthRender = self.width - heightRender = self.height + self.TEMPORARY_PLACE*2 - - if -1 != self.overLine: - grp.SetColor(HALF_WHITE_COLOR) - grp.RenderBar(xRender + 2, yRender + self.overLine*self.stepSize + 4, self.width - 3, self.stepSize) - - if -1 != self.selectedLine: - if self.selectedLine >= self.basePos: - if self.selectedLine - self.basePos < self.showLineCount: - grp.SetColor(SELECT_COLOR) - grp.RenderBar(xRender + 2, yRender + (self.selectedLine-self.basePos)*self.stepSize + 4, self.width - 3, self.stepSize) - - - -class ListBox2(ListBox): - def __init__(self, *args, **kwargs): - ListBox.__init__(self, *args, **kwargs) - self.rowCount = 10 - self.barWidth = 0 - self.colCount = 0 - - def SetRowCount(self, rowCount): - self.rowCount = rowCount - - def SetSize(self, width, height): - ListBox.SetSize(self, width, height) - self._RefreshForm() - - def ClearItem(self): - ListBox.ClearItem(self) - self._RefreshForm() - - def InsertItem(self, *args, **kwargs): - ListBox.InsertItem(self, *args, **kwargs) - self._RefreshForm() - - def OnUpdate(self): - mpos = wndMgr.GetMousePosition() - self.overLine = self._CalcPointIndex(mpos) - - def OnRender(self): - x, y = self.GetGlobalPosition() - pos = (x + 2, y) - - if -1 != self.overLine: - grp.SetColor(HALF_WHITE_COLOR) - self._RenderBar(pos, self.overLine) - - if -1 != self.selectedLine: - if self.selectedLine >= self.basePos: - if self.selectedLine - self.basePos < self.showLineCount: - grp.SetColor(SELECT_COLOR) - self._RenderBar(pos, self.selectedLine-self.basePos) - - def _CalcPointIndex(self, mpos): - if self.IsIn(): - px, py = mpos - gx, gy = self.GetGlobalPosition() - lx, ly = px - gx, py - gy - - col = lx // self.barWidth - row = ly // self.stepSize - idx = col * self.rowCount + row - if col >= 0 and col < self.colCount: - if row >= 0 and row < self.rowCount: - if idx >= 0 and idx < len(self.itemList): - return idx - - return -1 - - def _CalcRenderPos(self, pos, idx): - x, y = pos - row = idx % self.rowCount - col = idx // self.rowCount - return (x + col * self.barWidth, y + row * self.stepSize) - - def _RenderBar(self, basePos, idx): - x, y = self._CalcRenderPos(basePos, idx) - grp.RenderBar(x, y, self.barWidth - 3, self.stepSize) - - def _LocateItem(self): - pos = (0, self.TEMPORARY_PLACE) - - self.showLineCount = 0 - for textLine in self.itemList: - x, y = self._CalcRenderPos(pos, self.showLineCount) - textLine.SetPosition(x, y) - textLine.Show() - - self.showLineCount += 1 - - def _RefreshForm(self): - if len(self.itemList) % self.rowCount: - self.colCount = len(self.itemList) // self.rowCount + 1 - else: - self.colCount = len(self.itemList) // self.rowCount - - if self.colCount: - self.barWidth = self.width // self.colCount - else: - self.barWidth = self.width - - -class ComboBox(Window): - - class ListBoxWithBoard(ListBox): - - def __init__(self, layer): - ListBox.__init__(self, layer) - - def OnRender(self): - xRender, yRender = self.GetGlobalPosition() - yRender -= self.TEMPORARY_PLACE - widthRender = self.width - heightRender = self.height + self.TEMPORARY_PLACE*2 - grp.SetColor(BACKGROUND_COLOR) - grp.RenderBar(xRender, yRender, widthRender, heightRender) - grp.SetColor(DARK_COLOR) - grp.RenderLine(xRender, yRender, widthRender, 0) - grp.RenderLine(xRender, yRender, 0, heightRender) - grp.SetColor(BRIGHT_COLOR) - grp.RenderLine(xRender, yRender+heightRender, widthRender, 0) - grp.RenderLine(xRender+widthRender, yRender, 0, heightRender) - - ListBox.OnRender(self) - - def __init__(self): - Window.__init__(self) - self.x = 0 - self.y = 0 - self.width = 0 - self.height = 0 - self.isSelected = False - self.isOver = False - self.isListOpened = False - self.event = lambda *arg: None - self.enable = True - - self.textLine = MakeTextLine(self) - self.textLine.SetText(localeInfo.UI_ITEM) - - self.listBox = self.ListBoxWithBoard("TOP_MOST") - self.listBox.SetPickAlways() - self.listBox.SetParent(self) - self.listBox.SetEvent(__mem_func__(self.OnSelectItem)) - self.listBox.Hide() - - def __del__(self): - Window.__del__(self) - - def Destroy(self): - self.textLine = None - self.listBox = None - - def SetPosition(self, x, y): - ix = int(x) - iy = int(y) - Window.SetPosition(self, ix, iy) - self.x = ix - self.y = iy - self.__ArrangeListBox() - - def SetSize(self, width, height): - Window.SetSize(self, width, height) - self.width = width - self.height = height - self.textLine.UpdateRect() - self.__ArrangeListBox() - - def __ArrangeListBox(self): - self.listBox.SetPosition(0, self.height + 5) - self.listBox.SetWidth(self.width) - - def Enable(self): - self.enable = True - - def Disable(self): - self.enable = False - self.textLine.SetText("") - self.CloseListBox() - - def SetEvent(self, event): - self.event = event - - def ClearItem(self): - self.CloseListBox() - self.listBox.ClearItem() - - def InsertItem(self, index, name): - self.listBox.InsertItem(index, name) - self.listBox.ArrangeItem() - - def SetCurrentItem(self, text): - self.textLine.SetText(text) - - def SelectItem(self, key): - self.listBox.SelectItem(key) - - def OnSelectItem(self, index, name): - - self.CloseListBox() - self.event(index) - - def CloseListBox(self): - self.isListOpened = False - self.listBox.Hide() - - def OnMouseLeftButtonDown(self): - - if not self.enable: - return - - self.isSelected = True - - def OnMouseLeftButtonUp(self): - - if not self.enable: - return - - self.isSelected = False - - if self.isListOpened: - self.CloseListBox() - else: - if self.listBox.GetItemCount() > 0: - self.isListOpened = True - self.listBox.Show() - self.__ArrangeListBox() - - def OnUpdate(self): - - if not self.enable: - return - - if self.IsIn(): - self.isOver = True - else: - self.isOver = False - - def OnRender(self): - self.x, self.y = self.GetGlobalPosition() - xRender = self.x - yRender = self.y - widthRender = self.width - heightRender = self.height - grp.SetColor(BACKGROUND_COLOR) - grp.RenderBar(xRender, yRender, widthRender, heightRender) - grp.SetColor(DARK_COLOR) - grp.RenderLine(xRender, yRender, widthRender, 0) - grp.RenderLine(xRender, yRender, 0, heightRender) - grp.SetColor(BRIGHT_COLOR) - grp.RenderLine(xRender, yRender+heightRender, widthRender, 0) - grp.RenderLine(xRender+widthRender, yRender, 0, heightRender) - - if self.isOver: - grp.SetColor(HALF_WHITE_COLOR) - grp.RenderBar(xRender + 2, yRender + 3, self.width - 3, heightRender - 5) - - if self.isSelected: - grp.SetColor(WHITE_COLOR) - grp.RenderBar(xRender + 2, yRender + 3, self.width - 3, heightRender - 5) - -################################################################################################### -## Python Script Loader -################################################################################################### - -class ScriptWindow(Window): - def __init__(self, layer = "UI"): - Window.__init__(self, layer) - self.Children = [] - self.ElementDictionary = {} - def __del__(self): - Window.__del__(self) - - def ClearDictionary(self): - self.Children = [] - self.ElementDictionary = {} - def InsertChild(self, name, child): - self.ElementDictionary[name] = child - - def IsChild(self, name): - return name in self.ElementDictionary - def GetChild(self, name): - return self.ElementDictionary[name] - - def GetChild2(self, name): - return self.ElementDictionary.get(name, None) - - -class PythonScriptLoader(object): - - BODY_KEY_LIST = ( "x", "y", "width", "height" ) - - ##### - - DEFAULT_KEY_LIST = ( "type", "x", "y", ) - WINDOW_KEY_LIST = ( "width", "height", ) - IMAGE_KEY_LIST = ( "image", ) - EXPANDED_IMAGE_KEY_LIST = ( "image", ) - ANI_IMAGE_KEY_LIST = ( "images", ) - SLOT_KEY_LIST = ( "width", "height", "slot", ) - CANDIDATE_LIST_KEY_LIST = ( "item_step", "item_xsize", "item_ysize", ) - GRID_TABLE_KEY_LIST = ( "start_index", "x_count", "y_count", "x_step", "y_step", ) - EDIT_LINE_KEY_LIST = ( "width", "height", "input_limit", ) - COMBO_BOX_KEY_LIST = ( "width", "height", "item", ) - TITLE_BAR_KEY_LIST = ( "width", ) - HORIZONTAL_BAR_KEY_LIST = ( "width", ) - BOARD_KEY_LIST = ( "width", "height", ) - BOARD_WITH_TITLEBAR_KEY_LIST = ( "width", "height", "title", ) - BOX_KEY_LIST = ( "width", "height", ) - BAR_KEY_LIST = ( "width", "height", ) - LINE_KEY_LIST = ( "width", "height", ) - SLOTBAR_KEY_LIST = ( "width", "height", ) - GAUGE_KEY_LIST = ( "width", "color", ) - SCROLLBAR_KEY_LIST = ( "size", ) - LIST_BOX_KEY_LIST = ( "width", "height", ) - - def __init__(self): - self.Clear() - - def Clear(self): - self.ScriptDictionary = { "SCREEN_WIDTH" : wndMgr.GetScreenWidth(), "SCREEN_HEIGHT" : wndMgr.GetScreenHeight() } - self.InsertFunction = 0 - - def LoadScriptFile(self, window, FileName): - import exception - self.Clear() - - print(("===== Load Script File : %s" % (FileName))) - - try: - # chr, player ���� sandbox ������ import�� ������ �ʱ� ������,(���� �ǿ��� ������ �ſ� ŭ.) - # �̸� script dictionary�� �ʿ��� ����� �־���´�. - import chr - import player - import app - self.ScriptDictionary["PLAYER_NAME_MAX_LEN"] = chr.PLAYER_NAME_MAX_LEN - self.ScriptDictionary["DRAGON_SOUL_EQUIPMENT_SLOT_START"] = player.DRAGON_SOUL_EQUIPMENT_SLOT_START - self.ScriptDictionary["LOCALE_PATH"] = app.GetLocalePath() - self.ScriptDictionary["LOCALE_PATH_COMMON"] = app.GetLocalePathCommon() - exec(compile(open(FileName, "rb").read(), FileName, 'exec'), self.ScriptDictionary) - except IOError as err: - import sys - import dbg - dbg.TraceError("Failed to load script file : %s" % (FileName)) - dbg.TraceError("error : %s" % (err)) - exception.Abort("LoadScriptFile1") - except RuntimeError as err: - import sys - import dbg - dbg.TraceError("Failed to load script file : %s" % (FileName)) - dbg.TraceError("error : %s" % (err)) - exception.Abort("LoadScriptFile2") - except: - import sys - import dbg - dbg.TraceError("Failed to load script file : %s" % (FileName)) - exception.Abort("LoadScriptFile!!!!!!!!!!!!!!") - - ##### - - Body = self.ScriptDictionary["window"] - self.CheckKeyList("window", Body, self.BODY_KEY_LIST) - - window.ClearDictionary() - self.InsertFunction = window.InsertChild - - window.SetPosition(int(Body["x"]), int(Body["y"])) - - if app.IsRTL(): - w = wndMgr.GetScreenWidth() - h = wndMgr.GetScreenHeight() - if "width" in Body: - w = int(Body["width"]) - if "height" in Body: - h = int(Body["height"]) - - window.SetSize(w, h) - else: - window.SetSize(int(Body["width"]), int(Body["height"])) - if True == ("style" in Body): - for StyleList in Body["style"]: - window.AddFlag(StyleList) - - self.LoadChildren(window, Body) - - def LoadChildren(self, parent, dicChildren): - if app.IsRTL(): - parent.AddFlag("rtl") - - if True == ("style" in dicChildren): - for style in dicChildren["style"]: - parent.AddFlag(style) - - if False == ("children" in dicChildren): - return False - - Index = 0 - - ChildrenList = dicChildren["children"] - parent.Children = list(range(len(ChildrenList))) - for ElementValue in ChildrenList: - try: - Name = ElementValue["name"] - except KeyError: - Name = ElementValue["name"] = "NONAME" - - try: - Type = ElementValue["type"] - except KeyError: - Type = ElementValue["type"] = "window" - - if False == self.CheckKeyList(Name, ElementValue, self.DEFAULT_KEY_LIST): - del parent.Children[Index] - continue - - if Type == "window": - parent.Children[Index] = ScriptWindow() - parent.Children[Index].SetParent(parent) - self.LoadElementWindow(parent.Children[Index], ElementValue, parent) - - elif Type == "button": - parent.Children[Index] = Button() - parent.Children[Index].SetParent(parent) - self.LoadElementButton(parent.Children[Index], ElementValue, parent) - - elif Type == "radio_button": - parent.Children[Index] = RadioButton() - parent.Children[Index].SetParent(parent) - self.LoadElementButton(parent.Children[Index], ElementValue, parent) - - elif Type == "toggle_button": - parent.Children[Index] = ToggleButton() - parent.Children[Index].SetParent(parent) - self.LoadElementButton(parent.Children[Index], ElementValue, parent) - - elif Type == "mark": - parent.Children[Index] = MarkBox() - parent.Children[Index].SetParent(parent) - self.LoadElementMark(parent.Children[Index], ElementValue, parent) - - elif Type == "image": - parent.Children[Index] = ImageBox() - parent.Children[Index].SetParent(parent) - self.LoadElementImage(parent.Children[Index], ElementValue, parent) - - elif Type == "expanded_image": - parent.Children[Index] = ExpandedImageBox() - parent.Children[Index].SetParent(parent) - self.LoadElementExpandedImage(parent.Children[Index], ElementValue, parent) - - elif Type == "ani_image": - parent.Children[Index] = AniImageBox() - parent.Children[Index].SetParent(parent) - self.LoadElementAniImage(parent.Children[Index], ElementValue, parent) - - elif Type == "slot": - parent.Children[Index] = SlotWindow() - parent.Children[Index].SetParent(parent) - self.LoadElementSlot(parent.Children[Index], ElementValue, parent) - - elif Type == "candidate_list": - parent.Children[Index] = CandidateListBox() - parent.Children[Index].SetParent(parent) - self.LoadElementCandidateList(parent.Children[Index], ElementValue, parent) - - elif Type == "grid_table": - parent.Children[Index] = GridSlotWindow() - parent.Children[Index].SetParent(parent) - self.LoadElementGridTable(parent.Children[Index], ElementValue, parent) - - elif Type == "text": - parent.Children[Index] = TextLine() - parent.Children[Index].SetParent(parent) - self.LoadElementText(parent.Children[Index], ElementValue, parent) - - elif Type == "editline": - parent.Children[Index] = EditLine() - parent.Children[Index].SetParent(parent) - self.LoadElementEditLine(parent.Children[Index], ElementValue, parent) - - elif Type == "titlebar": - parent.Children[Index] = TitleBar() - parent.Children[Index].SetParent(parent) - self.LoadElementTitleBar(parent.Children[Index], ElementValue, parent) - - elif Type == "horizontalbar": - parent.Children[Index] = HorizontalBar() - parent.Children[Index].SetParent(parent) - self.LoadElementHorizontalBar(parent.Children[Index], ElementValue, parent) - - elif Type == "board": - parent.Children[Index] = Board() - parent.Children[Index].SetParent(parent) - self.LoadElementBoard(parent.Children[Index], ElementValue, parent) - - elif Type == "board_with_titlebar": - parent.Children[Index] = BoardWithTitleBar() - parent.Children[Index].SetParent(parent) - self.LoadElementBoardWithTitleBar(parent.Children[Index], ElementValue, parent) - - elif Type == "thinboard": - parent.Children[Index] = ThinBoard() - parent.Children[Index].SetParent(parent) - self.LoadElementThinBoard(parent.Children[Index], ElementValue, parent) - - elif Type == "box": - parent.Children[Index] = Box() - parent.Children[Index].SetParent(parent) - self.LoadElementBox(parent.Children[Index], ElementValue, parent) - - elif Type == "bar": - parent.Children[Index] = Bar() - parent.Children[Index].SetParent(parent) - self.LoadElementBar(parent.Children[Index], ElementValue, parent) - - elif Type == "line": - parent.Children[Index] = Line() - parent.Children[Index].SetParent(parent) - self.LoadElementLine(parent.Children[Index], ElementValue, parent) - - elif Type == "slotbar": - parent.Children[Index] = SlotBar() - parent.Children[Index].SetParent(parent) - self.LoadElementSlotBar(parent.Children[Index], ElementValue, parent) - - elif Type == "gauge": - parent.Children[Index] = Gauge() - parent.Children[Index].SetParent(parent) - self.LoadElementGauge(parent.Children[Index], ElementValue, parent) - - elif Type == "scrollbar": - parent.Children[Index] = ScrollBar() - parent.Children[Index].SetParent(parent) - self.LoadElementScrollBar(parent.Children[Index], ElementValue, parent) - - elif Type == "thin_scrollbar": - parent.Children[Index] = ThinScrollBar() - parent.Children[Index].SetParent(parent) - self.LoadElementScrollBar(parent.Children[Index], ElementValue, parent) - - elif Type == "small_thin_scrollbar": - parent.Children[Index] = SmallThinScrollBar() - parent.Children[Index].SetParent(parent) - self.LoadElementScrollBar(parent.Children[Index], ElementValue, parent) - - elif Type == "sliderbar": - parent.Children[Index] = SliderBar() - parent.Children[Index].SetParent(parent) - self.LoadElementSliderBar(parent.Children[Index], ElementValue, parent) - - elif Type == "listbox": - parent.Children[Index] = ListBox() - parent.Children[Index].SetParent(parent) - self.LoadElementListBox(parent.Children[Index], ElementValue, parent) - - elif Type == "listbox2": - parent.Children[Index] = ListBox2() - parent.Children[Index].SetParent(parent) - self.LoadElementListBox2(parent.Children[Index], ElementValue, parent) - elif Type == "listboxex": - parent.Children[Index] = ListBoxEx() - parent.Children[Index].SetParent(parent) - self.LoadElementListBoxEx(parent.Children[Index], ElementValue, parent) - - else: - Index += 1 - continue - - parent.Children[Index].SetWindowName(Name) - if 0 != self.InsertFunction: - self.InsertFunction(Name, parent.Children[Index]) - - self.LoadChildren(parent.Children[Index], ElementValue) - Index += 1 - - def CheckKeyList(self, name, value, key_list): - - for DataKey in key_list: - if False == (DataKey in value): - print(("Failed to find data key", "[" + name + "/" + DataKey + "]")) - return False - - return True - - def LoadDefaultData(self, window, value, parentWindow): - loc_x = int(value["x"]) - loc_y = int(value["y"]) - if "vertical_align" in value: - if "center" == value["vertical_align"]: - window.SetWindowVerticalAlignCenter() - elif "bottom" == value["vertical_align"]: - window.SetWindowVerticalAlignBottom() - - if parentWindow.IsRTL(): - loc_x = int(value["x"]) + window.GetWidth() - if "horizontal_align" in value: - if "center" == value["horizontal_align"]: - window.SetWindowHorizontalAlignCenter() - loc_x = - int(value["x"]) - elif "right" == value["horizontal_align"]: - window.SetWindowHorizontalAlignLeft() - loc_x = int(value["x"]) - window.GetWidth() - ## loc_x = parentWindow.GetWidth() - int(value["x"]) + window.GetWidth() - else: - window.SetWindowHorizontalAlignRight() - - if "all_align" in value: - window.SetWindowVerticalAlignCenter() - window.SetWindowHorizontalAlignCenter() - loc_x = - int(value["x"]) - else: - if "horizontal_align" in value: - if "center" == value["horizontal_align"]: - window.SetWindowHorizontalAlignCenter() - elif "right" == value["horizontal_align"]: - window.SetWindowHorizontalAlignRight() - - window.SetPosition(loc_x, loc_y) - window.Show() - - ## Window - def LoadElementWindow(self, window, value, parentWindow): - - if False == self.CheckKeyList(value["name"], value, self.WINDOW_KEY_LIST): - return False - - window.SetSize(int(value["width"]), int(value["height"])) - self.LoadDefaultData(window, value, parentWindow) - - return True - - ## Button - def LoadElementButton(self, window, value, parentWindow): - - if "width" in value and "height" in value: - window.SetSize(int(value["width"]), int(value["height"])) - - if True == ("default_image" in value): - window.SetUpVisual(value["default_image"]) - if True == ("over_image" in value): - window.SetOverVisual(value["over_image"]) - if True == ("down_image" in value): - window.SetDownVisual(value["down_image"]) - if True == ("disable_image" in value): - window.SetDisableVisual(value["disable_image"]) - - if True == ("text" in value): - if True == ("text_height" in value): - window.SetText(value["text"], value["text_height"]) - else: - window.SetText(value["text"]) - - if "text_color" in value: - window.SetTextColor(value["text_color"]) - - if True == ("tooltip_text" in value): - if True == ("tooltip_x" in value) and True == ("tooltip_y" in value): - window.SetToolTipText(value["tooltip_text"], int(value["tooltip_x"]), int(value["tooltip_y"])) - else: - window.SetToolTipText(value["tooltip_text"]) - - self.LoadDefaultData(window, value, parentWindow) - - return True - - ## Mark - def LoadElementMark(self, window, value, parentWindow): - - #if False == self.CheckKeyList(value["name"], value, self.MARK_KEY_LIST): - # return False - - self.LoadDefaultData(window, value, parentWindow) - - return True - - ## Image - def LoadElementImage(self, window, value, parentWindow): - - if False == self.CheckKeyList(value["name"], value, self.IMAGE_KEY_LIST): - return False - - window.LoadImage(value["image"]) - self.LoadDefaultData(window, value, parentWindow) - - return True - - ## AniImage - def LoadElementAniImage(self, window, value, parentWindow): - - if False == self.CheckKeyList(value["name"], value, self.ANI_IMAGE_KEY_LIST): - return False - - if True == ("delay" in value): - window.SetDelay(value["delay"]) - - for image in value["images"]: - window.AppendImage(image) - - if "width" in value and "height" in value: - window.SetSize(value["width"], value["height"]) - - self.LoadDefaultData(window, value, parentWindow) - - return True - - ## Expanded Image - def LoadElementExpandedImage(self, window, value, parentWindow): - - if False == self.CheckKeyList(value["name"], value, self.EXPANDED_IMAGE_KEY_LIST): - return False - - window.LoadImage(value["image"]) - - if True == ("x_origin" in value) and True == ("y_origin" in value): - window.SetOrigin(float(value["x_origin"]), float(value["y_origin"])) - - if True == ("x_scale" in value) and True == ("y_scale" in value): - window.SetScale(float(value["x_scale"]), float(value["y_scale"])) - - if True == ("rect" in value): - RenderingRect = value["rect"] - window.SetRenderingRect(RenderingRect[0], RenderingRect[1], RenderingRect[2], RenderingRect[3]) - - if True == ("mode" in value): - mode = value["mode"] - if "MODULATE" == mode: - window.SetRenderingMode(wndMgr.RENDERING_MODE_MODULATE) - - self.LoadDefaultData(window, value, parentWindow) - - return True - - ## Slot - def LoadElementSlot(self, window, value, parentWindow): - - if False == self.CheckKeyList(value["name"], value, self.SLOT_KEY_LIST): - return False - - global_x = int(value["x"]) - global_y = int(value["y"]) - global_width = int(value["width"]) - global_height = int(value["height"]) - - window.SetPosition(global_x, global_y) - window.SetSize(global_width, global_height) - window.Show() - - r = 1.0 - g = 1.0 - b = 1.0 - a = 1.0 - - if True == ("image_r" in value) and \ - True == ("image_g" in value) and \ - True == ("image_b" in value) and \ - True == ("image_a" in value): - r = float(value["image_r"]) - g = float(value["image_g"]) - b = float(value["image_b"]) - a = float(value["image_a"]) - - SLOT_ONE_KEY_LIST = ("index", "x", "y", "width", "height") - - for slot in value["slot"]: - if True == self.CheckKeyList(value["name"] + " - one", slot, SLOT_ONE_KEY_LIST): - wndMgr.AppendSlot(window.hWnd, - int(slot["index"]), - int(slot["x"]), - int(slot["y"]), - int(slot["width"]), - int(slot["height"])) - - if True == ("image" in value): - wndMgr.SetSlotBaseImage(window.hWnd, - value["image"], - r, g, b, a) - - return True - - def LoadElementCandidateList(self, window, value, parentWindow): - if False == self.CheckKeyList(value["name"], value, self.CANDIDATE_LIST_KEY_LIST): - return False - - window.SetPosition(int(value["x"]), int(value["y"])) - window.SetItemSize(int(value["item_xsize"]), int(value["item_ysize"])) - window.SetItemStep(int(value["item_step"])) - window.Show() - - return True - - ## Table - def LoadElementGridTable(self, window, value, parentWindow): - - if False == self.CheckKeyList(value["name"], value, self.GRID_TABLE_KEY_LIST): - return False - - xBlank = 0 - yBlank = 0 - if True == ("x_blank" in value): - xBlank = int(value["x_blank"]) - if True == ("y_blank" in value): - yBlank = int(value["y_blank"]) - - if app.IsRTL(): - pass - else: - window.SetPosition(int(value["x"]), int(value["y"])) - - window.ArrangeSlot( int(value["start_index"]), - int(value["x_count"]), - int(value["y_count"]), - int(value["x_step"]), - int(value["y_step"]), - xBlank, - yBlank) - if True == ("image" in value): - r = 1.0 - g = 1.0 - b = 1.0 - a = 1.0 - if True == ("image_r" in value) and \ - True == ("image_g" in value) and \ - True == ("image_b" in value) and \ - True == ("image_a" in value): - r = float(value["image_r"]) - g = float(value["image_g"]) - b = float(value["image_b"]) - a = float(value["image_a"]) - wndMgr.SetSlotBaseImage(window.hWnd, value["image"], r, g, b, a) - - if True == ("style" in value): - if "select" == value["style"]: - wndMgr.SetSlotStyle(window.hWnd, wndMgr.SLOT_STYLE_SELECT) - - if app.IsRTL(): - self.LoadDefaultData(window, value, parentWindow) - else: - window.Show() - - return True - - ## Text - def LoadElementText(self, window, value, parentWindow): - - if "fontsize" in value: - fontSize = value["fontsize"] - - if "LARGE" == fontSize: - window.SetFontName(localeInfo.UI_DEF_FONT_LARGE) - - elif "fontname" in value: - fontName = value["fontname"] - window.SetFontName(fontName) - - if "text_horizontal_align" in value: - if "left" == value["text_horizontal_align"]: - window.SetHorizontalAlignLeft() - elif "center" == value["text_horizontal_align"]: - window.SetHorizontalAlignCenter() - elif "right" == value["text_horizontal_align"]: - window.SetHorizontalAlignRight() - - if "text_vertical_align" in value: - if "top" == value["text_vertical_align"]: - window.SetVerticalAlignTop() - elif "center" == value["text_vertical_align"]: - window.SetVerticalAlignCenter() - elif "bottom" == value["text_vertical_align"]: - window.SetVerticalAlignBottom() - - if "all_align" in value: - window.SetHorizontalAlignCenter() - window.SetVerticalAlignCenter() - window.SetWindowHorizontalAlignCenter() - window.SetWindowVerticalAlignCenter() - - if "r" in value and "g" in value and "b" in value: - window.SetFontColor(float(value["r"]), float(value["g"]), float(value["b"])) - elif "color" in value: - window.SetPackedFontColor(value["color"]) - else: - window.SetFontColor(0.8549, 0.8549, 0.8549) - - if "outline" in value: - if value["outline"]: - window.SetOutline() - if True == ("text" in value): - window.SetText(value["text"]) - - self.LoadDefaultData(window, value, parentWindow) - - return True - - ## EditLine - def LoadElementEditLine(self, window, value, parentWindow): - - if False == self.CheckKeyList(value["name"], value, self.EDIT_LINE_KEY_LIST): - return False - - - if "secret_flag" in value: - window.SetSecret(value["secret_flag"]) - if "only_number" in value: - if value["only_number"]: - window.SetNumberMode() - if "enable_ime" in value: - window.SetIMEFlag(value["enable_ime"]) - if "limit_width" in value: - window.SetLimitWidth(value["limit_width"]) - if "multi_line" in value: - if value["multi_line"]: - window.SetMultiLine() - - window.SetMax(int(value["input_limit"])) - window.SetSize(int(value["width"]), int(value["height"])) - self.LoadElementText(window, value, parentWindow) - - return True - - ## TitleBar - def LoadElementTitleBar(self, window, value, parentWindow): - - if False == self.CheckKeyList(value["name"], value, self.TITLE_BAR_KEY_LIST): - return False - - window.MakeTitleBar(int(value["width"]), value.get("color", "red")) - self.LoadDefaultData(window, value, parentWindow) - - return True - - ## HorizontalBar - def LoadElementHorizontalBar(self, window, value, parentWindow): - - if False == self.CheckKeyList(value["name"], value, self.HORIZONTAL_BAR_KEY_LIST): - return False - - window.Create(int(value["width"])) - self.LoadDefaultData(window, value, parentWindow) - - return True - - ## Board - def LoadElementBoard(self, window, value, parentWindow): - - if False == self.CheckKeyList(value["name"], value, self.BOARD_KEY_LIST): - return False - - window.SetSize(int(value["width"]), int(value["height"])) - self.LoadDefaultData(window, value, parentWindow) - - return True - - ## Board With TitleBar - def LoadElementBoardWithTitleBar(self, window, value, parentWindow): - - if False == self.CheckKeyList(value["name"], value, self.BOARD_WITH_TITLEBAR_KEY_LIST): - return False - - window.SetSize(int(value["width"]), int(value["height"])) - window.SetTitleName(value["title"]) - self.LoadDefaultData(window, value, parentWindow) - - return True - - ## ThinBoard - def LoadElementThinBoard(self, window, value, parentWindow): - - if False == self.CheckKeyList(value["name"], value, self.BOARD_KEY_LIST): - return False - - window.SetSize(int(value["width"]), int(value["height"])) - self.LoadDefaultData(window, value, parentWindow) - - return True - - ## Box - def LoadElementBox(self, window, value, parentWindow): - - if False == self.CheckKeyList(value["name"], value, self.BOX_KEY_LIST): - return False - - if True == ("color" in value): - window.SetColor(value["color"]) - - window.SetSize(int(value["width"]), int(value["height"])) - self.LoadDefaultData(window, value, parentWindow) - - return True - - ## Bar - def LoadElementBar(self, window, value, parentWindow): - - if False == self.CheckKeyList(value["name"], value, self.BAR_KEY_LIST): - return False - - if True == ("color" in value): - window.SetColor(value["color"]) - - window.SetSize(int(value["width"]), int(value["height"])) - self.LoadDefaultData(window, value, parentWindow) - - return True - - ## Line - def LoadElementLine(self, window, value, parentWindow): - - if False == self.CheckKeyList(value["name"], value, self.LINE_KEY_LIST): - return False - - if True == ("color" in value): - window.SetColor(value["color"]) - - window.SetSize(int(value["width"]), int(value["height"])) - self.LoadDefaultData(window, value, parentWindow) - - return True - - ## Slot - def LoadElementSlotBar(self, window, value, parentWindow): - - if False == self.CheckKeyList(value["name"], value, self.SLOTBAR_KEY_LIST): - return False - - window.SetSize(int(value["width"]), int(value["height"])) - self.LoadDefaultData(window, value, parentWindow) - - return True - - ## Gauge - def LoadElementGauge(self, window, value, parentWindow): - - if False == self.CheckKeyList(value["name"], value, self.GAUGE_KEY_LIST): - return False - - window.MakeGauge(value["width"], value["color"]) - self.LoadDefaultData(window, value, parentWindow) - - return True - - ## ScrollBar - def LoadElementScrollBar(self, window, value, parentWindow): - - if False == self.CheckKeyList(value["name"], value, self.SCROLLBAR_KEY_LIST): - return False - - window.SetScrollBarSize(value["size"]) - self.LoadDefaultData(window, value, parentWindow) - - return True - - ## SliderBar - def LoadElementSliderBar(self, window, value, parentWindow): - - self.LoadDefaultData(window, value, parentWindow) - - return True - - ## ListBox - def LoadElementListBox(self, window, value, parentWindow): - - if False == self.CheckKeyList(value["name"], value, self.LIST_BOX_KEY_LIST): - return False - - if "item_align" in value: - window.SetTextCenterAlign(value["item_align"]) - - window.SetSize(value["width"], value["height"]) - self.LoadDefaultData(window, value, parentWindow) - - return True - - ## ListBox2 - def LoadElementListBox2(self, window, value, parentWindow): - - if False == self.CheckKeyList(value["name"], value, self.LIST_BOX_KEY_LIST): - return False - - window.SetRowCount(value.get("row_count", 10)) - window.SetSize(value["width"], value["height"]) - self.LoadDefaultData(window, value, parentWindow) - - if "item_align" in value: - window.SetTextCenterAlign(value["item_align"]) - - return True - def LoadElementListBoxEx(self, window, value, parentWindow): - - if False == self.CheckKeyList(value["name"], value, self.LIST_BOX_KEY_LIST): - return False - - window.SetSize(value["width"], value["height"]) - self.LoadDefaultData(window, value, parentWindow) - - if "itemsize_x" in value and "itemsize_y" in value: - window.SetItemSize(int(value["itemsize_x"]), int(value["itemsize_y"])) - - if "itemstep" in value: - window.SetItemStep(int(value["itemstep"])) - - if "viewcount" in value: - window.SetViewItemCount(int(value["viewcount"])) - - return True - -class ReadingWnd(Bar): - - def __init__(self): - Bar.__init__(self,"TOP_MOST") - - self.__BuildText() - self.SetSize(80, 19) - self.Show() - - def __del__(self): - Bar.__del__(self) - - def __BuildText(self): - self.text = TextLine() - self.text.SetParent(self) - self.text.SetPosition(4, 3) - self.text.Show() - - def SetText(self, text): - self.text.SetText(text) - - def SetReadingPosition(self, x, y): - xPos = x + 2 - yPos = y - self.GetHeight() - 2 - self.SetPosition(xPos, yPos) - - def SetTextColor(self, color): - self.text.SetPackedFontColor(color) - - -def MakeSlotBar(parent, x, y, width, height): - slotBar = SlotBar() - slotBar.SetParent(parent) - slotBar.SetSize(width, height) - slotBar.SetPosition(x, y) - slotBar.Show() - return slotBar - -def MakeImageBox(parent, name, x, y): - image = ImageBox() - image.SetParent(parent) - image.LoadImage(name) - image.SetPosition(x, y) - image.Show() - return image - -def MakeTextLine(parent): - textLine = TextLine() - textLine.SetParent(parent) - textLine.SetWindowHorizontalAlignCenter() - textLine.SetWindowVerticalAlignCenter() - textLine.SetHorizontalAlignCenter() - textLine.SetVerticalAlignCenter() - textLine.Show() - return textLine - -def MakeButton(parent, x, y, tooltipText, path, up, over, down): - button = Button() - button.SetParent(parent) - button.SetPosition(x, y) - button.SetUpVisual(path + up) - button.SetOverVisual(path + over) - button.SetDownVisual(path + down) - button.SetToolTipText(tooltipText) - button.Show() - return button - -def RenderRoundBox(x, y, width, height, color): - grp.SetColor(color) - grp.RenderLine(x+2, y, width-3, 0) - grp.RenderLine(x+2, y+height, width-3, 0) - grp.RenderLine(x, y+2, 0, height-4) - grp.RenderLine(x+width, y+1, 0, height-3) - grp.RenderLine(x, y+2, 2, -2) - grp.RenderLine(x, y+height-2, 2, 2) - grp.RenderLine(x+width-2, y, 2, 2) - grp.RenderLine(x+width-2, y+height, 2, -2) - -def GenerateColor(r, g, b): - r = float(r) / 255.0 - g = float(g) / 255.0 - b = float(b) / 255.0 - return grp.GenerateColor(r, g, b, 1.0) - -def EnablePaste(flag): - ime.EnablePaste(flag) - -def GetHyperlink(): - return wndMgr.GetHyperlink() - -RegisterToolTipWindow("TEXT", TextLine) diff --git a/tools/root/uiaffectshower.py b/tools/root/uiaffectshower.py deleted file mode 100644 index c02e8bfb..00000000 --- a/tools/root/uiaffectshower.py +++ /dev/null @@ -1,1050 +0,0 @@ -import ui -import localeInfo -import chr -import item -import app -import skill -import player -import uiToolTip -import math -import dbg -import weakref - -# WEDDING -class LovePointImage(ui.ExpandedImageBox): - - FILE_PATH = "d:/ymir work/ui/pattern/LovePoint/" - FILE_DICT = { - 0 : FILE_PATH + "01.dds", - 1 : FILE_PATH + "02.dds", - 2 : FILE_PATH + "02.dds", - 3 : FILE_PATH + "03.dds", - 4 : FILE_PATH + "04.dds", - 5 : FILE_PATH + "05.dds", - } - - def __init__(self): - ui.ExpandedImageBox.__init__(self) - - self.loverName = "" - self.lovePoint = 0 - - self.toolTip = uiToolTip.ToolTip(100) - self.toolTip.HideToolTip() - - def __del__(self): - ui.ExpandedImageBox.__del__(self) - - def SetLoverInfo(self, name, lovePoint): - self.loverName = name - self.lovePoint = lovePoint - self.__Refresh() - - def OnUpdateLovePoint(self, lovePoint): - self.lovePoint = lovePoint - self.__Refresh() - - def __Refresh(self): - self.lovePoint = max(0, self.lovePoint) - self.lovePoint = min(100, self.lovePoint) - - if 0 == self.lovePoint: - loveGrade = 0 - else: - loveGrade = self.lovePoint / 25 + 1 - fileName = self.FILE_DICT.get(loveGrade, self.FILE_PATH+"00.dds") - - try: - self.LoadImage(fileName) - except: - import dbg - dbg.TraceError("LovePointImage.SetLoverInfo(lovePoint=%d) - LoadError %s" % (self.lovePoint, fileName)) - - self.SetScale(0.7, 0.7) - - self.toolTip.ClearToolTip() - self.toolTip.SetTitle(self.loverName) - self.toolTip.AppendTextLine(localeInfo.AFF_LOVE_POINT % (self.lovePoint)) - self.toolTip.ResizeToolTip() - - def OnMouseOverIn(self): - self.toolTip.ShowToolTip() - - def OnMouseOverOut(self): - self.toolTip.HideToolTip() -# END_OF_WEDDING - - -class HorseImage(ui.ExpandedImageBox): - - FILE_PATH = "d:/ymir work/ui/pattern/HorseState/" - - FILE_DICT = { - 00 : FILE_PATH + "00.dds", - 0o1 : FILE_PATH + "00.dds", - 0o2 : FILE_PATH + "00.dds", - 0o3 : FILE_PATH + "00.dds", - 10 : FILE_PATH + "10.dds", - 11 : FILE_PATH + "11.dds", - 12 : FILE_PATH + "12.dds", - 13 : FILE_PATH + "13.dds", - 20 : FILE_PATH + "20.dds", - 21 : FILE_PATH + "21.dds", - 22 : FILE_PATH + "22.dds", - 23 : FILE_PATH + "23.dds", - 30 : FILE_PATH + "30.dds", - 31 : FILE_PATH + "31.dds", - 32 : FILE_PATH + "32.dds", - 33 : FILE_PATH + "33.dds", - } - - def __init__(self): - ui.ExpandedImageBox.__init__(self) - - #self.textLineList = [] - self.toolTip = uiToolTip.ToolTip(100) - self.toolTip.HideToolTip() - - def __GetHorseGrade(self, level): - if 0 == level: - return 0 - - return (level-1)/10 + 1 - - def SetState(self, level, health, battery): - #self.textLineList=[] - self.toolTip.ClearToolTip() - - if level > 0: - try: - grade = self.__GetHorseGrade(level) - self.__AppendText(localeInfo.LEVEL_LIST[int(grade)]) - except IndexError: - print(("HorseImage.SetState(level=%d, health=%d, battery=%d) - Unknown Index" % (level, health, battery))) - return - - try: - healthName = localeInfo.HEALTH_LIST[health] - if len(healthName) > 0: - self.__AppendText(healthName) - except IndexError: - print(("HorseImage.SetState(level=%d, health=%d, battery=%d) - Unknown Index" % (level, health, battery))) - return - - if health > 0: - if battery == 0: - self.__AppendText(localeInfo.NEEFD_REST) - - try: - fileName = self.FILE_DICT[health*10 + battery] - except KeyError: - print(("HorseImage.SetState(level=%d, health=%d, battery=%d) - KeyError" % (level, health, battery))) - - try: - self.LoadImage(fileName) - except: - print(("HorseImage.SetState(level=%d, health=%d, battery=%d) - LoadError %s" % (level, health, battery, fileName))) - - self.SetScale(0.7, 0.7) - - def __AppendText(self, text): - - self.toolTip.AppendTextLine(text) - self.toolTip.ResizeToolTip() - - #x=self.GetWidth()/2 - #textLine = ui.TextLine() - #textLine.SetParent(self) - #textLine.SetSize(0, 0) - #textLine.SetOutline() - #textLine.Hide() - #textLine.SetPosition(x, 40+len(self.textLineList)*16) - #textLine.SetText(text) - #self.textLineList.append(textLine) - - def OnMouseOverIn(self): - #for textLine in self.textLineList: - # textLine.Show() - - self.toolTip.ShowToolTip() - - def OnMouseOverOut(self): - #for textLine in self.textLineList: - # textLine.Hide() - - self.toolTip.HideToolTip() - - -# AUTO_POTION -class AutoPotionImage(ui.ExpandedImageBox): - - FILE_PATH_HP = "d:/ymir work/ui/pattern/auto_hpgauge/" - FILE_PATH_SP = "d:/ymir work/ui/pattern/auto_spgauge/" - - def __init__(self): - ui.ExpandedImageBox.__init__(self) - - self.loverName = "" - self.lovePoint = 0 - self.potionType = player.AUTO_POTION_TYPE_HP - self.filePath = "" - - self.toolTip = uiToolTip.ToolTip(100) - self.toolTip.HideToolTip() - - def __del__(self): - ui.ExpandedImageBox.__del__(self) - - def SetPotionType(self, type): - self.potionType = type - - if player.AUTO_POTION_TYPE_HP == type: - self.filePath = self.FILE_PATH_HP - elif player.AUTO_POTION_TYPE_SP == type: - self.filePath = self.FILE_PATH_SP - - - def OnUpdateAutoPotionImage(self): - self.__Refresh() - - def __Refresh(self): - print("__Refresh") - - isActivated, currentAmount, totalAmount, slotIndex = player.GetAutoPotionInfo(self.potionType) - - amountPercent = (float(currentAmount) / totalAmount) * 100.0 - grade = math.ceil(amountPercent / 20) - - if 5.0 > amountPercent: - grade = 0 - - if 80.0 < amountPercent: - grade = 4 - if 90.0 < amountPercent: - grade = 5 - - fmt = self.filePath + "%.2d.dds" - fileName = fmt % grade - - print((self.potionType, amountPercent, fileName)) - - try: - self.LoadImage(fileName) - except: - import dbg - dbg.TraceError("AutoPotionImage.__Refresh(potionType = %d) - LoadError %s" % (self.potionType, fileName)) - - self.SetScale(0.7, 0.7) - - self.toolTip.ClearToolTip() - - # MR-10: Add toolTip support and real-time countdown for affects - itemName = None - - if slotIndex >= 0: - itemVnum = player.GetItemIndex(slotIndex) - - if itemVnum: - item.SelectItem(itemVnum) - itemName = item.GetItemName() - - if itemName: - self.toolTip.SetTitle(itemName) - elif player.AUTO_POTION_TYPE_HP == self.potionType: - self.toolTip.SetTitle(localeInfo.TOOLTIP_AUTO_POTION_HP) - else: - self.toolTip.SetTitle(localeInfo.TOOLTIP_AUTO_POTION_SP) - - self.toolTip.AppendTextLine(localeInfo.TOOLTIP_AUTO_POTION_REST % (amountPercent)) - self.toolTip.ResizeToolTip() - # MR-10: -- END OF -- Add toolTip support and real-time countdown for affects - - def OnMouseOverIn(self): - self.toolTip.ShowToolTip() - - def OnMouseOverOut(self): - self.toolTip.HideToolTip() -# END_OF_AUTO_POTION - - -class AffectImage(ui.ExpandedImageBox): - - # MR-16: Canonical item vnum for each infinite-duration affect (proto lookup, no inventory) - INFINITE_AFFECT_ITEM_VNUM = { - chr.NEW_AFFECT_NO_DEATH_PENALTY : 71004, - chr.NEW_AFFECT_SKILL_BOOK_BONUS : 71094, - chr.NEW_AFFECT_SKILL_BOOK_NO_DELAY : 71001, - } - # MR-16: -- END OF -- Canonical item vnum for each infinite-duration affect - - def __init__(self): - ui.ExpandedImageBox.__init__(self) - - self.toolTipText = None - # MR-10: Add toolTip support and real-time countdown for affects - self.toolTip = None - self.dsTimeCache = {} - self.isHover = False - # MR-10: -- END OF -- Add toolTip support and real-time countdown for affects - self.isSkillAffect = True - self.description = None - self.endTime = 0 - self.affect = None - self.isClocked = True - self.autoPotionToolTipTitle = None - self.autoPotionToolTipLine = None - - def SetAffect(self, affect): - self.affect = affect - - def GetAffect(self): - return self.affect - - def SetToolTipText(self, text, x = 0, y = -19): - - if not self.toolTipText: - textLine = ui.TextLine() - - textLine.SetParent(self) - textLine.SetSize(0, 0) - textLine.SetOutline() - textLine.Hide() - - self.toolTipText = textLine - - self.toolTipText.SetText(text) - w, h = self.toolTipText.GetTextSize() - self.toolTipText.SetPosition(max(0, x + self.GetWidth()/2 - w/2), y) - - def SetDescription(self, description): - self.description = description - - def SetDuration(self, duration): - self.endTime = 0 - - # MR-10: Add toolTip support and real-time countdown for affects - if duration > 0: - self.endTime = app.GetGlobalTimeStamp() + duration - # MR-10: -- END OF -- Add toolTip support and real-time countdown for affects - - def UpdateAutoPotionDescription(self): - - potionType = 0 - - if self.affect == chr.NEW_AFFECT_AUTO_HP_RECOVERY: - potionType = player.AUTO_POTION_TYPE_HP - else: - potionType = player.AUTO_POTION_TYPE_SP - - isActivated, currentAmount, totalAmount, slotIndex = player.GetAutoPotionInfo(potionType) - - #print "UpdateAutoPotionDescription ", isActivated, currentAmount, totalAmount, slotIndex - - amountPercent = 0.0 - - try: - amountPercent = (float(currentAmount) / totalAmount) * 100.0 - except: - amountPercent = 100.0 - - # MR-10: Add toolTip support and real-time countdown for affects - if not self.isHover: - return - - self.__EnsureToolTip() - - itemName = None - - if slotIndex >= 0: - itemVnum = player.GetItemIndex(slotIndex) - - if itemVnum: - item.SelectItem(itemVnum) - itemName = item.GetItemName() - - if itemName: - title = itemName - elif player.AUTO_POTION_TYPE_HP == potionType: - title = localeInfo.TOOLTIP_AUTO_POTION_HP - else: - title = localeInfo.TOOLTIP_AUTO_POTION_SP - - line = self.description % amountPercent - - if self.autoPotionToolTipTitle == title and self.autoPotionToolTipLine == line: - return - - self.toolTip.ClearToolTip() - self.toolTip.SetTitle(title) - self.toolTip.AppendTextLine(line) - self.toolTip.ResizeToolTip() - self.autoPotionToolTipTitle = title - self.autoPotionToolTipLine = line - # MR-10: -- END OF -- Add toolTip support and real-time countdown for affects - - def SetClock(self, isClocked): - self.isClocked = isClocked - - # MR-10: Add toolTip support and real-time countdown for affects - def UpdateDescription(self): - # MR-12: Fix realtime countdown auto-start - if self.__IsDragonSoulAffect(): - minRemain = self.__GetDragonSoulMinRemainSec() - - if self.isHover: - self.__UpdateDragonSoulDescription(minRemain) - # MR-12: -- END OF -- Fix realtime countdown auto-start - - if self.toolTip: - self.toolTip.ShowToolTip() - return - - if not self.isClocked: - self.__UpdateDescription2() - return - - if not self.description: - return - - if self.__ShouldShowTimedToolTip(): - if self.isHover: - remainSec = max(0, self.endTime - app.GetGlobalTimeStamp()) - self.__UpdateTimedDescription(remainSec) - - if self.toolTip: - self.toolTip.ShowToolTip() - return - - # MR-16: Classic affect duration countdown - if self.__ShouldShowInfiniteToolTip(): - return - # MR-16: -- END OF -- Classic affect duration countdown - - self.SetToolTipText(self.description, 0, 40) - - # Used to suppress the time countdown display (German version) - def __UpdateDescription2(self): - if not self.description: - return - - toolTip = self.description - self.SetToolTipText(toolTip, 0, 40) - - def __EnsureToolTip(self): - if not self.toolTip: - self.toolTip = uiToolTip.ToolTip(100) - self.toolTip.HideToolTip() - - def __IsAutoPotionAffect(self): - return self.affect in (chr.NEW_AFFECT_AUTO_HP_RECOVERY, chr.NEW_AFFECT_AUTO_SP_RECOVERY) - - def __ShouldShowTimedToolTip(self): - return self.isClocked and self.endTime > 0 and not self.__IsAutoPotionAffect() - - # MR-16: Classic affect duration countdown - def __ShouldShowInfiniteToolTip(self): - return (self.isClocked and self.description and self.endTime == 0 - and not self.__IsAutoPotionAffect() and not self.__IsDragonSoulAffect()) - # MR-16: -- END OF -- Classic affect duration countdown - - def __UpdateTimedDescription(self, remainSec): - if not self.description: - return - - self.__EnsureToolTip() - - self.toolTip.ClearToolTip() - self.toolTip.SetTitle(self.description) - self.toolTip.AppendTextLine("(%s : %s)" % (localeInfo.LEFT_TIME, localeInfo.RTSecondToDHMS(remainSec))) - self.toolTip.ResizeToolTip() - - # MR-16: Classic affect duration countdown - def __GetInfiniteAffectItemName(self): - vnum = self.INFINITE_AFFECT_ITEM_VNUM.get(self.affect) - - if not vnum: - return None - - item.SelectItem(vnum) - - return item.GetItemName() - - def __UpdateInfiniteDescription(self): - if not self.description: - return - - self.__EnsureToolTip() - - self.toolTip.ClearToolTip() - - itemName = self.__GetInfiniteAffectItemName() - - if itemName: - self.toolTip.SetTitle(itemName) - - self.toolTip.AppendTextLine(self.description) - self.toolTip.ResizeToolTip() - # MR-16: -- END OF -- Classic affect duration countdown - - def __IsDragonSoulAffect(self): - return self.affect in (chr.NEW_AFFECT_DRAGON_SOUL_DECK1, chr.NEW_AFFECT_DRAGON_SOUL_DECK2) - - def __GetDragonSoulMinRemainSec(self): - deckIndex = 0 if self.affect == chr.NEW_AFFECT_DRAGON_SOUL_DECK1 else 1 - now = app.GetGlobalTimeStamp() - minRemain = None - - for i in range(6): - slotNumber = deckIndex * player.DRAGON_SOUL_EQUIPMENT_FIRST_SIZE + (player.DRAGON_SOUL_EQUIPMENT_SLOT_START + i) - itemVnum = player.GetItemIndex(slotNumber) - - if itemVnum == 0: - continue - - item.SelectItem(itemVnum) - remainSec = None - - for j in range(item.LIMIT_MAX_NUM): - (limitType, limitValue) = item.GetLimit(j) - - if item.LIMIT_REAL_TIME == limitType or item.LIMIT_REAL_TIME_START_FIRST_USE == limitType: - endTime = player.GetItemMetinSocket(player.INVENTORY, slotNumber, 0) - remainSec = endTime - now - break - - if item.LIMIT_TIMER_BASED_ON_WEAR == limitType: - rawRemain = player.GetItemMetinSocket(player.INVENTORY, slotNumber, 0) - cacheKey = (slotNumber, itemVnum) - cache = self.dsTimeCache.get(cacheKey) - - if cache and cache["remainSec"] == rawRemain: - remainSec = cache["endTime"] - now - else: - endTime = now + rawRemain - self.dsTimeCache[cacheKey] = {"remainSec": rawRemain, "endTime": endTime} - remainSec = endTime - now - break - - if remainSec is None or remainSec <= 0: - continue - - if minRemain is None or remainSec < minRemain: - minRemain = remainSec - - return minRemain - - # MR-12: Fix realtime countdown auto-start - def __UpdateDragonSoulDescription(self, minRemain = None): - if not self.description: - return - - if minRemain is None: - minRemain = self.__GetDragonSoulMinRemainSec() - - self.__EnsureToolTip() - self.toolTip.ClearToolTip() - self.toolTip.SetTitle(self.description) - - if minRemain is not None: - self.toolTip.AppendTextLine("(%s : %s)" % (localeInfo.LEFT_TIME, localeInfo.RTSecondToDHMS(minRemain))) - - self.toolTip.ResizeToolTip() - # MR-12: -- END OF -- Fix realtime countdown auto-start - - def SetSkillAffectFlag(self, flag): - self.isSkillAffect = flag - - def IsSkillAffect(self): - return self.isSkillAffect - - def OnMouseOverIn(self): - # MR-10: Add toolTip support and real-time countdown for affects - self.isHover = True - - if self.__IsAutoPotionAffect(): - self.UpdateAutoPotionDescription() - - if self.toolTip: - self.toolTip.ShowToolTip() - return - - if self.__IsDragonSoulAffect(): - self.__UpdateDragonSoulDescription() - - if self.toolTip: - self.toolTip.ShowToolTip() - return - - if self.__ShouldShowTimedToolTip(): - remainSec = max(0, self.endTime - app.GetGlobalTimeStamp()) - self.__UpdateTimedDescription(remainSec) - - if self.toolTip: - self.toolTip.ShowToolTip() - return - - # MR-16: Classic affect duration countdown - if self.__ShouldShowInfiniteToolTip(): - self.__UpdateInfiniteDescription() - - if self.toolTip: - self.toolTip.ShowToolTip() - return - # MR-16: -- END OF -- Classic affect duration countdown - - if self.toolTipText: - self.toolTipText.Show() - - def OnMouseOverOut(self): - self.isHover = False - - if self.toolTip: - self.toolTip.HideToolTip() - - if self.toolTipText: - self.toolTipText.Hide() - # MR-10: -- END OF -- Add toolTip support and real-time countdown for affects - -class AffectShower(ui.Window): - - MALL_DESC_IDX_START = 1000 - IMAGE_STEP = 25 - AFFECT_MAX_NUM = 32 - - INFINITE_AFFECT_DURATION = 0x1FFFFFFF - _liveInstances = weakref.WeakSet() - - # Maps affect key -> (localeInfo attribute name, image path). - # AFFECT_DATA_DICT is built from this by _RebuildLocaleStrings(). - _AFFECT_TEMPLATE = { - chr.AFFECT_POISON : ("SKILL_TOXICDIE", "d:/ymir work/ui/skill/common/affect/poison.sub"), - chr.AFFECT_SLOW : ("SKILL_SLOW", "d:/ymir work/ui/skill/common/affect/slow.sub"), - chr.AFFECT_STUN : ("SKILL_STUN", "d:/ymir work/ui/skill/common/affect/stun.sub"), - chr.AFFECT_ATT_SPEED_POTION : ("SKILL_INC_ATKSPD", "d:/ymir work/ui/skill/common/affect/Increase_Attack_Speed.sub"), - chr.AFFECT_MOV_SPEED_POTION : ("SKILL_INC_MOVSPD", "d:/ymir work/ui/skill/common/affect/Increase_Move_Speed.sub"), - chr.AFFECT_FISH_MIND : ("SKILL_FISHMIND", "d:/ymir work/ui/skill/common/affect/fishmind.sub"), - chr.AFFECT_JEONGWI : ("SKILL_JEONGWI", "d:/ymir work/ui/skill/warrior/jeongwi_03.sub"), - chr.AFFECT_GEOMGYEONG : ("SKILL_GEOMGYEONG", "d:/ymir work/ui/skill/warrior/geomgyeong_03.sub"), - chr.AFFECT_CHEONGEUN : ("SKILL_CHEONGEUN", "d:/ymir work/ui/skill/warrior/cheongeun_03.sub"), - chr.AFFECT_GYEONGGONG : ("SKILL_GYEONGGONG", "d:/ymir work/ui/skill/assassin/gyeonggong_03.sub"), - chr.AFFECT_EUNHYEONG : ("SKILL_EUNHYEONG", "d:/ymir work/ui/skill/assassin/eunhyeong_03.sub"), - chr.AFFECT_GWIGEOM : ("SKILL_GWIGEOM", "d:/ymir work/ui/skill/sura/gwigeom_03.sub"), - chr.AFFECT_GONGPO : ("SKILL_GONGPO", "d:/ymir work/ui/skill/sura/gongpo_03.sub"), - chr.AFFECT_JUMAGAP : ("SKILL_JUMAGAP", "d:/ymir work/ui/skill/sura/jumagap_03.sub"), - chr.AFFECT_HOSIN : ("SKILL_HOSIN", "d:/ymir work/ui/skill/shaman/hosin_03.sub"), - chr.AFFECT_BOHO : ("SKILL_BOHO", "d:/ymir work/ui/skill/shaman/boho_03.sub"), - chr.AFFECT_KWAESOK : ("SKILL_KWAESOK", "d:/ymir work/ui/skill/shaman/kwaesok_03.sub"), - chr.AFFECT_HEUKSIN : ("SKILL_HEUKSIN", "d:/ymir work/ui/skill/sura/heuksin_03.sub"), - chr.AFFECT_MUYEONG : ("SKILL_MUYEONG", "d:/ymir work/ui/skill/sura/muyeong_03.sub"), - chr.AFFECT_GICHEON : ("SKILL_GICHEON", "d:/ymir work/ui/skill/shaman/gicheon_03.sub"), - chr.AFFECT_JEUNGRYEOK : ("SKILL_JEUNGRYEOK", "d:/ymir work/ui/skill/shaman/jeungryeok_03.sub"), - chr.AFFECT_PABEOP : ("SKILL_PABEOP", "d:/ymir work/ui/skill/sura/pabeop_03.sub"), - chr.AFFECT_FALLEN_CHEONGEUN : ("SKILL_CHEONGEUN", "d:/ymir work/ui/skill/warrior/cheongeun_03.sub"), - # MR-16: Added AFFECT_FIRE to Affects Shower - chr.AFFECT_FIRE : ("SKILL_FIRE", "d:/ymir work/ui/skill/sura/hwayeom_03.sub"), - # MR-16: -- END OF -- Added AFFECT_FIRE to Affects Shower - chr.AFFECT_CHINA_FIREWORK : ("SKILL_POWERFUL_STRIKE", "d:/ymir work/ui/skill/common/affect/powerfulstrike.sub"), - chr.NEW_AFFECT_EXP_BONUS : ("TOOLTIP_MALL_EXPBONUS_STATIC", "d:/ymir work/ui/skill/common/affect/exp_bonus.sub"), - chr.NEW_AFFECT_ITEM_BONUS : ("TOOLTIP_MALL_ITEMBONUS_STATIC", "d:/ymir work/ui/skill/common/affect/item_bonus.sub"), - chr.NEW_AFFECT_SAFEBOX : ("TOOLTIP_MALL_SAFEBOX", "d:/ymir work/ui/skill/common/affect/safebox.sub"), - chr.NEW_AFFECT_AUTOLOOT : ("TOOLTIP_MALL_AUTOLOOT", "d:/ymir work/ui/skill/common/affect/autoloot.sub"), - chr.NEW_AFFECT_FISH_MIND : ("TOOLTIP_MALL_FISH_MIND", "d:/ymir work/ui/skill/common/affect/fishmind.sub"), - chr.NEW_AFFECT_MARRIAGE_FAST : ("TOOLTIP_MALL_MARRIAGE_FAST", "d:/ymir work/ui/skill/common/affect/marriage_fast.sub"), - chr.NEW_AFFECT_GOLD_BONUS : ("TOOLTIP_MALL_GOLDBONUS_STATIC", "d:/ymir work/ui/skill/common/affect/gold_bonus.sub"), - chr.NEW_AFFECT_NO_DEATH_PENALTY : ("TOOLTIP_APPLY_NO_DEATH_PENALTY", "d:/ymir work/ui/skill/common/affect/gold_premium.sub"), - chr.NEW_AFFECT_SKILL_BOOK_BONUS : ("TOOLTIP_APPLY_SKILL_BOOK_BONUS", "d:/ymir work/ui/skill/common/affect/gold_premium.sub"), - chr.NEW_AFFECT_SKILL_BOOK_NO_DELAY : ("TOOLTIP_APPLY_SKILL_BOOK_NO_DELAY", "d:/ymir work/ui/skill/common/affect/gold_premium.sub"), - chr.NEW_AFFECT_AUTO_HP_RECOVERY : ("TOOLTIP_AUTO_POTION_REST", "d:/ymir work/ui/pattern/auto_hpgauge/05.dds"), - chr.NEW_AFFECT_AUTO_SP_RECOVERY : ("TOOLTIP_AUTO_POTION_REST", "d:/ymir work/ui/pattern/auto_spgauge/05.dds"), - # Mall point affects - MALL_DESC_IDX_START + player.POINT_MALL_ATTBONUS : ("TOOLTIP_MALL_ATTBONUS_STATIC", "d:/ymir work/ui/skill/common/affect/att_bonus.sub"), - MALL_DESC_IDX_START + player.POINT_MALL_DEFBONUS : ("TOOLTIP_MALL_DEFBONUS_STATIC", "d:/ymir work/ui/skill/common/affect/def_bonus.sub"), - MALL_DESC_IDX_START + player.POINT_MALL_EXPBONUS : ("TOOLTIP_MALL_EXPBONUS", "d:/ymir work/ui/skill/common/affect/exp_bonus.sub"), - MALL_DESC_IDX_START + player.POINT_MALL_ITEMBONUS : ("TOOLTIP_MALL_ITEMBONUS", "d:/ymir work/ui/skill/common/affect/item_bonus.sub"), - MALL_DESC_IDX_START + player.POINT_MALL_GOLDBONUS : ("TOOLTIP_MALL_GOLDBONUS", "d:/ymir work/ui/skill/common/affect/gold_bonus.sub"), - MALL_DESC_IDX_START + player.POINT_CRITICAL_PCT : ("TOOLTIP_APPLY_CRITICAL_PCT", "d:/ymir work/ui/skill/common/affect/critical.sub"), - MALL_DESC_IDX_START + player.POINT_PENETRATE_PCT : ("TOOLTIP_APPLY_PENETRATE_PCT", "d:/ymir work/ui/skill/common/affect/gold_premium.sub"), - MALL_DESC_IDX_START + player.POINT_MAX_HP_PCT : ("TOOLTIP_MAX_HP_PCT", "d:/ymir work/ui/skill/common/affect/gold_premium.sub"), - MALL_DESC_IDX_START + player.POINT_MAX_SP_PCT : ("TOOLTIP_MAX_SP_PCT", "d:/ymir work/ui/skill/common/affect/gold_premium.sub"), - MALL_DESC_IDX_START + player.POINT_PC_BANG_EXP_BONUS : ("TOOLTIP_MALL_EXPBONUS_P_STATIC", "d:/ymir work/ui/skill/common/affect/EXP_Bonus_p_on.sub"), - MALL_DESC_IDX_START + player.POINT_PC_BANG_DROP_BONUS : ("TOOLTIP_MALL_ITEMBONUS_P_STATIC", "d:/ymir work/ui/skill/common/affect/Item_Bonus_p_on.sub"), - # MR-12: Add Mall Attack speed affect - MALL_DESC_IDX_START + player.POINT_ATT_SPEED : ("TOOLTIP_MALL_ATT_SPEED", "d:/ymir work/ui/skill/common/affect/Increase_Attack_Speed.sub"), - # MR-12: -- END OF -- Add Mall Attack speed affect - } - - if app.ENABLE_DRAGON_SOUL_SYSTEM: - _AFFECT_TEMPLATE[chr.NEW_AFFECT_DRAGON_SOUL_DECK1] = ("TOOLTIP_DRAGON_SOUL_DECK1", "d:/ymir work/ui/dragonsoul/buff_ds_sky1.tga") - _AFFECT_TEMPLATE[chr.NEW_AFFECT_DRAGON_SOUL_DECK2] = ("TOOLTIP_DRAGON_SOUL_DECK2", "d:/ymir work/ui/dragonsoul/buff_ds_land1.tga") - - AFFECT_DATA_DICT = {} # populated by _RebuildLocaleStrings() - - @staticmethod - def _RebuildLocaleStrings(): - d = {} - for key, (attrName, path) in AffectShower._AFFECT_TEMPLATE.items(): - d[key] = (getattr(localeInfo, attrName), path) - AffectShower.AFFECT_DATA_DICT = d - for inst in AffectShower._liveInstances: - inst.RefreshLocale() - - def RefreshLocale(self): - for affect, image in list(self.affectImageDict.items()): - if affect not in self.AFFECT_DATA_DICT: - continue - name = self.AFFECT_DATA_DICT[affect][0] - skillIndex = player.AffectIndexToSkillIndex(affect) - if 0 != skillIndex: - name = skill.GetSkillName(skillIndex) - if image.IsSkillAffect(): - image.SetToolTipText(name, 0, 40) - else: - image.SetDescription(name) - image.UpdateDescription() - - def __init__(self): - ui.Window.__init__(self) - AffectShower._liveInstances.add(self) - - self.serverPlayTime = 0 - self.clientPlayTime = 0 - - self.lastUpdateTime = 0 - self.affectImageDict = {} - self.horseImage = None - self.lovePointImage = None - self.autoPotionImageHP = AutoPotionImage() - self.autoPotionImageSP = AutoPotionImage() - # MR-16: Classic affect duration countdown - self.pendingClassicDurations = {} - # MR-16: -- END OF -- Classic affect duration countdown - - self.SetPosition(10, 10) - self.Show() - - def ClearAllAffects(self): - self.horseImage = None - self.lovePointImage = None - self.affectImageDict = {} - # MR-16: Classic affect duration countdown - self.pendingClassicDurations = {} - # MR-16: -- END OF -- Classic affect duration countdown - - self.__ArrangeImageList() - - def ClearAffects(self): ## Clears skill affects on death; MALL (non-skill) affects survive. - self.living_affectImageDict = {} - - for key, image in list(self.affectImageDict.items()): - if not image.IsSkillAffect(): - self.living_affectImageDict[key] = image - - self.affectImageDict = self.living_affectImageDict - # MR-16: Classic affect duration countdown - self.pendingClassicDurations = {} - # MR-16: -- END OF -- Classic affect duration countdown - - self.__ArrangeImageList() - - def BINARY_NEW_AddAffect(self, type, pointIdx, value, duration, affFlag = 0): - print(("BINARY_NEW_AddAffect", type, pointIdx, value, duration, affFlag)) - - if type < 500: - # MR-16: Classic affect duration countdown - # affFlag is the server-side AFF_* enum value (1-based). - # The client's chr.AFFECT_* enum is 0-based, so affBit = affFlag - 1. - # This covers all classic affects without any static mapping. - if 0 < duration <= self.INFINITE_AFFECT_DURATION and affFlag > 0: - affBit = affFlag - 1 - - if affBit in self.AFFECT_DATA_DICT: - if affBit in self.affectImageDict: - # Icon already exists (CHARACTER_UPDATE arrived first) - update directly - self.__ApplyClassicDuration(affBit, duration) - else: - # Icon not yet created - store for when __AppendAffect fires - self.pendingClassicDurations[affBit] = duration - # MR-16: -- END OF -- Classic affect duration countdown - - return - - if type == chr.NEW_AFFECT_MALL: - affect = self.MALL_DESC_IDX_START + pointIdx - else: - affect = type - - if affect in self.affectImageDict: - return - - if affect not in self.AFFECT_DATA_DICT: - return - - ## As an exception, the following affects have their Duration forced to 0. - if affect == chr.NEW_AFFECT_NO_DEATH_PENALTY or\ - affect == chr.NEW_AFFECT_SKILL_BOOK_BONUS or\ - affect == chr.NEW_AFFECT_AUTO_SP_RECOVERY or\ - affect == chr.NEW_AFFECT_AUTO_HP_RECOVERY or\ - affect == chr.NEW_AFFECT_SKILL_BOOK_NO_DELAY: - duration = 0 - - affectData = self.AFFECT_DATA_DICT[affect] - description = affectData[0] - filename = affectData[1] - - if pointIdx == player.POINT_MALL_ITEMBONUS or\ - pointIdx == player.POINT_MALL_GOLDBONUS: - value = 1 + float(value) / 100.0 - - trashValue = 123 - - #if affect == chr.NEW_AFFECT_AUTO_SP_RECOVERY or affect == chr.NEW_AFFECT_AUTO_HP_RECOVERY: - if trashValue == 1: - try: - #image = AutoPotionImage() - #image.SetParent(self) - image = None - - if affect == chr.NEW_AFFECT_AUTO_SP_RECOVERY: - image.SetPotionType(player.AUTO_POTION_TYPE_SP) - image = self.autoPotionImageSP - #self.autoPotionImageSP = image; - else: - image.SetPotionType(player.AUTO_POTION_TYPE_HP) - image = self.autoPotionImageHP - #self.autoPotionImageHP = image; - - image.SetParent(self) - image.Show() - image.OnUpdateAutoPotionImage() - - self.affectImageDict[affect] = image - - self.__ArrangeImageList() - except Exception as e: - print(("except Aff auto potion affect ", e)) - pass - else: - if affect != chr.NEW_AFFECT_AUTO_SP_RECOVERY and affect != chr.NEW_AFFECT_AUTO_HP_RECOVERY: - description = description(float(value)) - - try: - print(("Add affect %s" % affect)) - - image = AffectImage() - - image.SetParent(self) - image.LoadImage(filename) - image.SetDescription(description) - image.SetDuration(duration) - image.SetAffect(affect) - - if affect == chr.NEW_AFFECT_EXP_BONUS_EURO_FREE or\ - affect == chr.NEW_AFFECT_EXP_BONUS_EURO_FREE_UNDER_15 or\ - self.INFINITE_AFFECT_DURATION < duration: - image.SetClock(False) - image.UpdateDescription() - elif affect == chr.NEW_AFFECT_AUTO_SP_RECOVERY or affect == chr.NEW_AFFECT_AUTO_HP_RECOVERY: - image.UpdateAutoPotionDescription() - else: - image.UpdateDescription() - - if affect == chr.NEW_AFFECT_DRAGON_SOUL_DECK1 or affect == chr.NEW_AFFECT_DRAGON_SOUL_DECK2: - image.SetScale(1, 1) - else: - image.SetScale(0.7, 0.7) - - image.SetSkillAffectFlag(False) - image.Show() - self.affectImageDict[affect] = image - self.__ArrangeImageList() - except Exception as e: - print(("except Aff affect ", e)) - pass - - def BINARY_NEW_RemoveAffect(self, type, pointIdx): - if type == chr.NEW_AFFECT_MALL: - affect = self.MALL_DESC_IDX_START + pointIdx - else: - affect = type - - print(("Remove Affect %s %s" % ( type , pointIdx ))) - self.__RemoveAffect(affect) - self.__ArrangeImageList() - - def SetAffect(self, affect): - self.__AppendAffect(affect) - self.__ArrangeImageList() - - def ResetAffect(self, affect): - self.__RemoveAffect(affect) - self.__ArrangeImageList() - - def SetLoverInfo(self, name, lovePoint): - image = LovePointImage() - image.SetParent(self) - image.SetLoverInfo(name, lovePoint) - self.lovePointImage = image - self.__ArrangeImageList() - - def ShowLoverState(self): - if self.lovePointImage: - self.lovePointImage.Show() - self.__ArrangeImageList() - - def HideLoverState(self): - if self.lovePointImage: - self.lovePointImage.Hide() - self.__ArrangeImageList() - - def ClearLoverState(self): - self.lovePointImage = None - self.__ArrangeImageList() - - def OnUpdateLovePoint(self, lovePoint): - if self.lovePointImage: - self.lovePointImage.OnUpdateLovePoint(lovePoint) - - def SetHorseState(self, level, health, battery): - if level == 0: - self.horseImage=None - else: - image = HorseImage() - image.SetParent(self) - image.SetState(level, health, battery) - image.Show() - - self.horseImage = image - - # MR-17: Fix icons not re-arranging after horse state changes - self.__ArrangeImageList() - # MR-17: -- END OF -- Fix icons not re-arranging after horse state changes - - def SetPlayTime(self, playTime): - self.serverPlayTime = playTime - self.clientPlayTime = app.GetTime() - - def __AppendAffect(self, affect): - - if affect in self.affectImageDict: - return - - try: - affectData = self.AFFECT_DATA_DICT[affect] - except KeyError: - return - - name = affectData[0] - filename = affectData[1] - - skillIndex = player.AffectIndexToSkillIndex(affect) - - if 0 != skillIndex: - name = skill.GetSkillName(skillIndex) - - image = AffectImage() - image.SetParent(self) - image.SetSkillAffectFlag(True) - - try: - image.LoadImage(filename) - except: - pass - - image.SetToolTipText(name, 0, 40) - image.SetScale(0.7, 0.7) - image.Show() - self.affectImageDict[affect] = image - - # MR-16: Classic affect duration countdown - # Apply pending duration if AFFECT_ADD arrived before CHARACTER_UPDATE - if affect in self.pendingClassicDurations: - duration = self.pendingClassicDurations.pop(affect) - self.__ApplyClassicDuration(affect, duration) - # MR-16: -- END OF -- Classic affect duration countdown - - # MR-16: Classic affect duration countdown - def __ApplyClassicDuration(self, affBit, duration): - image = self.affectImageDict.get(affBit) - if not image: - return - - affectData = self.AFFECT_DATA_DICT.get(affBit) - if not affectData: - return - - name = affectData[0] - skillIndex = player.AffectIndexToSkillIndex(affBit) - if 0 != skillIndex: - name = skill.GetSkillName(skillIndex) - - image.SetDescription(name) - image.SetDuration(duration) - # MR-16: -- END OF -- Classic affect duration countdown - - def __RemoveAffect(self, affect): - """ - if affect == chr.NEW_AFFECT_AUTO_SP_RECOVERY: - self.autoPotionImageSP.Hide() - - if affect == chr.NEW_AFFECT_AUTO_HP_RECOVERY: - self.autoPotionImageHP.Hide() - """ - - if affect not in self.affectImageDict: - print(("__RemoveAffect %s ( No Affect )" % affect)) - return - - print(("__RemoveAffect %s ( Affect )" % affect)) - del self.affectImageDict[affect] - - self.__ArrangeImageList() - - def __ArrangeImageList(self): - - width = len(self.affectImageDict) * self.IMAGE_STEP - if self.lovePointImage: - width+=self.IMAGE_STEP - if self.horseImage: - width+=self.IMAGE_STEP - - self.SetSize(width, 26) - - xPos = 0 - - if self.lovePointImage: - if self.lovePointImage.IsShow(): - self.lovePointImage.SetPosition(xPos, 0) - xPos += self.IMAGE_STEP - - if self.horseImage: - self.horseImage.SetPosition(xPos, 0) - xPos += self.IMAGE_STEP - - for image in list(self.affectImageDict.values()): - image.SetPosition(xPos, 0) - xPos += self.IMAGE_STEP - - # MR-12: Fix realtime countdown auto-start - def OnUpdate(self): - try: - for image in list(self.affectImageDict.values()): - if image.GetAffect() == chr.NEW_AFFECT_AUTO_HP_RECOVERY or image.GetAffect() == chr.NEW_AFFECT_AUTO_SP_RECOVERY: - image.UpdateAutoPotionDescription() - continue - - # MR-16: Classic affect duration countdown - if not image.IsSkillAffect(): - image.UpdateDescription() - continue - - # Classic (skill) affects also need UpdateDescription when they - # carry a timed duration captured from the AFFECT_ADD packet. - if image.endTime > 0: - image.UpdateDescription() - # MR-16: -- END OF -- Classic affect duration countdown - except Exception as e: - print(("AffectShower::OnUpdate error : ", e)) - # MR-12: -- END OF -- Fix realtime countdown auto-start - -AffectShower._RebuildLocaleStrings() -localeInfo.RegisterReloadCallback(AffectShower._RebuildLocaleStrings) diff --git a/tools/root/uiattachmetin.py b/tools/root/uiattachmetin.py deleted file mode 100644 index 941c63c7..00000000 --- a/tools/root/uiattachmetin.py +++ /dev/null @@ -1,156 +0,0 @@ -import dbg -import app -import player -import item -import net -import snd -import ui -import uiToolTip -import localeInfo - -class AttachMetinDialog(ui.ScriptWindow): - def __init__(self): - ui.ScriptWindow.__init__(self) - self.__LoadScript() - - self.metinItemPos = 0 - self.targetItemPos = 0 - - def __LoadScript(self): - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "uiscript/attachstonedialog.py") - - except: - import exception - exception.Abort("AttachStoneDialog.__LoadScript.LoadObject") - - try: - self.board = self.GetChild("Board") - self.titleBar = self.GetChild("TitleBar") - self.metinImage = self.GetChild("MetinImage") - self.GetChild("AcceptButton").SetEvent(ui.__mem_func__(self.Accept)) - self.GetChild("CancelButton").SetEvent(ui.__mem_func__(self.Close)) - except: - import exception - exception.Abort("AttachStoneDialog.__LoadScript.BindObject") - - oldToolTip = uiToolTip.ItemToolTip() - - oldToolTip.SetParent(self) - oldToolTip.SetPosition(15, 38) - oldToolTip.SetFollow(False) - oldToolTip.Show() - - self.oldToolTip = oldToolTip - - newToolTip = uiToolTip.ItemToolTip() - - newToolTip.SetParent(self) - newToolTip.SetPosition(230 + 20, 38) - newToolTip.SetFollow(False) - newToolTip.Show() - - self.newToolTip = newToolTip - - self.titleBar.SetCloseEvent(ui.__mem_func__(self.Close)) - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def Destroy(self): - self.ClearDictionary() - self.board = 0 - self.titleBar = 0 - self.metinImage = 0 - self.toolTip = 0 - - def CanAttachMetin(self, slot, metin): - if item.METIN_NORMAL == metin: - if player.METIN_SOCKET_TYPE_SILVER == slot or player.METIN_SOCKET_TYPE_GOLD == slot: - return True - - elif item.METIN_GOLD == metin: - if player.METIN_SOCKET_TYPE_GOLD == slot: - return True - - def Open(self, metinItemPos, targetItemPos): - self.metinItemPos = metinItemPos - self.targetItemPos = targetItemPos - - metinIndex = player.GetItemIndex(metinItemPos) - itemIndex = player.GetItemIndex(targetItemPos) - - self.oldToolTip.ClearToolTip() - self.newToolTip.ClearToolTip() - - item.SelectItem(metinIndex) - metinSubType = item.GetItemSubType() - - try: - self.metinImage.LoadImage(item.GetIconImageFileName()) - except: - dbg.TraceError("AttachMetinDialog.Open.LoadImage - Failed to find item data") - - # MR-12: Fix attribute and metin socket order display in tooltip - # Get actual item attributes/bonuses for display - attrSlot = [] - - for i in range(player.ATTRIBUTE_SLOT_MAX_NUM): - attrSlot.append(player.GetItemAttribute(targetItemPos, i)) - - metinSlot = [] - - for i in range(player.METIN_SOCKET_MAX_NUM): - metinSlot.append(player.GetItemMetinSocket(targetItemPos, i)) - - for i in range(player.METIN_SOCKET_MAX_NUM): - slotData = metinSlot[i] - - if self.CanAttachMetin(slotData, metinSubType): - metinSlot[i] = metinIndex - - break - - self.newToolTip.AddItemData(itemIndex, metinSlot, attrSlot) - item.SelectItem(metinIndex) - - metinSlot = [] - - for i in range(player.METIN_SOCKET_MAX_NUM): - metinSlot.append(player.GetItemMetinSocket(targetItemPos, i)) - - self.oldToolTip.ResizeToolTipWidth(self.newToolTip.GetWidth()) - self.oldToolTip.AddItemData(itemIndex, metinSlot, attrSlot) - # MR-12: -- END OF -- Fix attribute and metin socket order display in tooltip - - self.UpdateDialog() - self.SetTop() - self.Show() - - def UpdateDialog(self): - newWidth = 15 + self.oldToolTip.GetWidth() + 45 + self.newToolTip.GetWidth() + 15 - newHeight = self.newToolTip.GetHeight() + 98 - - self.newToolTip.SetPosition(15 + self.oldToolTip.GetWidth() + 45, 38) - - if app.IsRTL(): - self.board.SetPosition(newWidth, 0) - - (x, y) = self.titleBar.GetLocalPosition() - self.titleBar.SetPosition(newWidth - 15, y) - - self.board.SetSize(newWidth, newHeight) - self.titleBar.SetWidth(newWidth-15) - self.SetSize(newWidth, newHeight) - - (x, y) = self.GetLocalPosition() - self.SetPosition(x, y) - - def Accept(self): - net.SendItemUseToItemPacket(self.metinItemPos, self.targetItemPos) - snd.PlaySound("sound/ui/metinstone_insert.wav") - self.Close() - - def Close(self): - self.Hide() diff --git a/tools/root/uiauction.py b/tools/root/uiauction.py deleted file mode 100644 index 41e5b000..00000000 --- a/tools/root/uiauction.py +++ /dev/null @@ -1,149 +0,0 @@ -import ui -class AuctionWindow(ui.ScriptWindow): - - class PageWindow(ui.ScriptWindow): - def __init__(self, parent, filename): - ui.ScriptWindow.__init__(self) - self.SetParent(parent) - self.filename = filename - def GetScriptFileName(self): - return self.filename - - def __init__(self): - ui.ScriptWindow.__init__(self) - self.__LoadWindow() - - self.SelectPage("UNIQUE_AUCTION") - - def __LoadWindow(self): - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "uiscript/auctionwindow.py") - - self.pageName = { - "LIST" : "Trade List", - "REGISTER" : "Register Trade", - "UNIQUE_AUCTION" : "Unique Auction", - } - self.pageWindow = { - "LIST" : self.PageWindow(self, "uiscript/auctionwindow_listpage.py"), - "REGISTER" : self.PageWindow(self, "uiscript/auctionwindow_registerpage.py"), - "UNIQUE_AUCTION" : self.PageWindow(self, "uiscript/auctionwindow_uniqueauctionpage.py"), - } - - self.board = self.GetChild("Board") - self.tabDict = { - "LIST" : self.GetChild("Tab_01"), - "REGISTER" : self.GetChild("Tab_02"), - "UNIQUE_AUCTION" : self.GetChild("Tab_03"), - } - self.tabButtonDict = { - "LIST" : self.GetChild("Tab_Button_01"), - "REGISTER" : self.GetChild("Tab_Button_02"), - "UNIQUE_AUCTION" : self.GetChild("Tab_Button_03"), - } - for page in list(self.pageWindow.values()): - pyScrLoader.LoadScriptFile(page, page.GetScriptFileName()) - for key, button in list(self.tabButtonDict.items()): - button.SetEvent(self.SelectPage, key) - - self.__MakeListPage() - self.__MakeRegisterPage() - self.__MakeUniqueAuctionPage() - - def Destroy(self): - self.ClearDictionary() - - def __MakeListPage(self): - - page = self.pageWindow["LIST"] - - yPos = 27 - - AUCTION_LINE_COUNT = 10 - - for i in range(AUCTION_LINE_COUNT): - - numberSlotImage = ui.MakeImageBox(page, "d:/ymir work/ui/public/Parameter_Slot_00.sub", 11, yPos) - numberSlot = ui.MakeTextLine(numberSlotImage) - page.Children.append(numberSlotImage) - page.Children.append(numberSlot) - - nameSlotImage = ui.MakeImageBox(page, "d:/ymir work/ui/public/Parameter_Slot_04.sub", 55, yPos) - nameSlot = ui.MakeTextLine(nameSlotImage) - page.Children.append(nameSlotImage) - page.Children.append(nameSlot) - - priceSlotImage = ui.MakeImageBox(page, "d:/ymir work/ui/public/Parameter_Slot_05.sub", 175, yPos) - priceSlot = ui.MakeTextLine(priceSlotImage) - page.Children.append(priceSlotImage) - page.Children.append(priceSlot) - - deleteButton = ui.Button() - deleteButton.SetParent(page) - deleteButton.SetPosition(310, yPos) - deleteButton.SetUpVisual("d:/ymir work/ui/public/small_button_01.sub") - deleteButton.SetOverVisual("d:/ymir work/ui/public/small_button_02.sub") - deleteButton.SetDownVisual("d:/ymir work/ui/public/small_button_03.sub") - deleteButton.SetText("Purchase") - deleteButton.Show() - page.Children.append(deleteButton) - - yPos += 20 - - def __MakeRegisterPage(self): - pass - - def __MakeUniqueAuctionPage(self): - - page = self.pageWindow["UNIQUE_AUCTION"] - - LINE_COUNT = 3 - - for i in range(LINE_COUNT): - - yPos = 5 + 99*i - - itemSlotImage = ui.MakeSlotBar(page, 10, yPos, 97, 97) - page.Children.append(itemSlotImage) - - itemName = ui.MakeTextLine(page, False, 117, yPos + 14) - page.Children.append(itemName) - ## Temporary - itemName.SetText("Fairy Hairpin") - ## Temporary - - curPrice = ui.MakeTextLine(page, False, 117, yPos + 31) - page.Children.append(curPrice) - ## Temporary - curPrice.SetText("Current Price: 2,012,341,234 Yang") - ## Temporary - - lastTime = ui.MakeTextLine(page, False, 117, yPos + 48) - page.Children.append(lastTime) - ## Temporary - lastTime.SetText("Time Until Close: 19 min 28 sec") - ## Temporary - - priceSlotImage = ui.MakeImageBox(page, "d:/ymir work/ui/public/Parameter_Slot_05.sub", 117, yPos + 65) - priceSlot = ui.MakeTextLine(priceSlotImage) - page.Children.append(priceSlotImage) - page.Children.append(priceSlot) - ## Temporary - priceSlot.SetText("2,012,341,234 Yang") - ## Temporary - - def SelectPage(self, arg): - for key, btn in list(self.tabButtonDict.items()): - if arg != key: - btn.SetUp() - for key, img in list(self.tabDict.items()): - if arg == key: - img.Show() - else: - img.Hide() - for key, page in list(self.pageWindow.items()): - if arg == key: - page.Show() - else: - page.Hide() - self.board.SetTitleName(self.pageName[arg]) diff --git a/tools/root/uicandidate.py b/tools/root/uicandidate.py deleted file mode 100644 index e7493f18..00000000 --- a/tools/root/uicandidate.py +++ /dev/null @@ -1,152 +0,0 @@ -import ui -import ime -import wndMgr - -class VerticalCandidateBoard(ui.Board): - - CORNER_WIDTH = 3 - CORNER_HEIGHT = 3 - LINE_WIDTH = 16 - LINE_HEIGHT = 16 - - SLOT_WIDTH = 14 - SLOT_HEIGHT = 14 - - def __init__(self): - ui.Window.__init__(self, "CURTAIN") - - self.Base = None - self.BaseBar = None - self.numberList = [] - self.slotList = [] - - def __del__(self): - ui.Board.__del__(self) - - def SetCharacterCount(self, xCount, yCount): - self.SetSize(xCount*14 + 14, yCount*14 + 7) - self.BaseBar.SetSize(xCount*14 + 1, yCount*14 + 1) - - self.numberList = [] - self.slotList = [] - - for y in range(yCount): - - number = ui.ImageBox() - number.SetParent(self.BaseBar) - number.LoadImage("d:/ymir work/ui/pattern/ime/%d.tga" % (y+1)) - number.SetPosition(5 - 10, 8 + y * 14 - 3) - number.Show() - self.numberList.append(number) - - slot = ui.Bar() - slot.SetParent(self.BaseBar) - slot.SetPosition(10 + 1 - 10, 3 + y*14 + 1 - 3) - slot.SetSize(xCount*14 - 1, 13) - slot.SetColor(0xFF302C2A) - slot.Show() - self.slotList.append(slot) - - ################################################################# - - def SetCandidatePosition(self, x, y, textCount): - xPos = x + (textCount - 5) * 6 + 2 - yPos = y - self.GetHeight() - 2 - self.SetPosition(xPos, yPos) - - def Load(self): - self.MakeBoard("d:/ymir work/ui/pattern/ime/corner_", "d:/ymir work/ui/pattern/ime/bar_") - - BaseBar = ui.Bar() - BaseBar.SetParent(self) - BaseBar.SetPosition(10, 3) - BaseBar.SetColor(0xff000000) - BaseBar.Show() - self.BaseBar = BaseBar - - candidateListBox = ui.CandidateListBox(ui.CandidateListBox.VERTICAL_MODE) - candidateListBox.SetParent(self) - candidateListBox.SetPosition(11, 4) - candidateListBox.SetItemSize(16, 14) - candidateListBox.SetItemStep(14) - candidateListBox.Show() - self.candidateListBox = candidateListBox - - def Clear(self): - self.candidateListBox.RemoveAllItems() - - def Append(self, text): - self.candidateListBox.AppendItem(ui.CandidateListBox.Item(text)) - - def Refresh(self): - - maxTextLength = 0 - yCount = ime.GetCandidateCount() - - for i in range(yCount): - text, length = ime.GetCandidate(i) - self.Append(text) - - if length > maxTextLength: - maxTextLength = length - - if maxTextLength > 0: - self.SetCharacterCount(maxTextLength, yCount) - - self.candidateListBox.SelectIndex(ime.GetCandidateSelection()) - -class KORCandidateWindow(ui.ScriptWindow): - - def __init__(self): - ui.Window.__init__(self, "CURTAIN") - self.candidateListBox=None - - def __del__(self): - ui.Window.__del__(self) - - def SetCandidatePosition(self, x, y, textCount): - xPos = x + textCount*6 - 20 - yPos = y + 20 - xPos = min(xPos, wndMgr.GetScreenWidth() - self.GetWidth()) - self.SetPosition(xPos, yPos) - - def Clear(self): - self.candidateListBox.RemoveAllItems() - - def Append(self, text): - self.candidateListBox.AppendItem(ui.CandidateListBox.Item(text)) - - def Refresh(self): - for i in range(9): - text, length = ime.GetCandidate(i) - self.Append(text) - - self.candidateListBox.SelectIndex(ime.GetCandidateSelection()) - - def Select(self, pos): - self.candidateListBox.SelectIndex(pos) - - def Load(self): - self.__LoadScript() - self.__BindObject() - - def __LoadScript(self): - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "UIScript/IMEKOR.py") - except: - import exception - exception.Abort("CandidateWindow.__LoadScript") - - def __BindObject(self): - try: - self.candidateListBox=self.GetChild("CandidateList") - - except: - import exception - exception.Abort("CandidateWindow.__BindObject") - -ui.RegisterCandidateWindowClass(KORCandidateWindow) -ui.RegisterCandidateWindowClass(VerticalCandidateBoard) -ui.RegisterCandidateWindowClass(VerticalCandidateBoard) -ui.RegisterCandidateWindowClass(VerticalCandidateBoard) diff --git a/tools/root/uicharacter.py b/tools/root/uicharacter.py deleted file mode 100644 index 085809b9..00000000 --- a/tools/root/uicharacter.py +++ /dev/null @@ -1,1349 +0,0 @@ -import ui -import uiScriptLocale -import app -import net -import dbg -import snd -import player -import mouseModule -import wndMgr -import skill -import playerSettingModule -import quest -import localeInfo -import uiToolTip -import constInfo -import emotion -import chr - -SHOW_ONLY_ACTIVE_SKILL = False -SHOW_LIMIT_SUPPORT_SKILL_LIST = [] -HIDE_SUPPORT_SKILL_POINT = True - -FACE_IMAGE_DICT = { - playerSettingModule.RACE_WARRIOR_M : "icon/face/warrior_m.tga", - playerSettingModule.RACE_WARRIOR_W : "icon/face/warrior_w.tga", - playerSettingModule.RACE_ASSASSIN_M : "icon/face/assassin_m.tga", - playerSettingModule.RACE_ASSASSIN_W : "icon/face/assassin_w.tga", - playerSettingModule.RACE_SURA_M : "icon/face/sura_m.tga", - playerSettingModule.RACE_SURA_W : "icon/face/sura_w.tga", - playerSettingModule.RACE_SHAMAN_M : "icon/face/shaman_m.tga", - playerSettingModule.RACE_SHAMAN_W : "icon/face/shaman_w.tga", -} -def unsigned32(n): - return n & 0xFFFFFFFF - -class CharacterWindow(ui.ScriptWindow): - - ACTIVE_PAGE_SLOT_COUNT = 8 - SUPPORT_PAGE_SLOT_COUNT = 12 - - PAGE_SLOT_COUNT = 12 - - PAGE_HORSE = 3 - - SKILL_GROUP_NAME_DICT = {} - STAT_DESCRIPTION = {} - STAT_MINUS_DESCRIPTION = "" - - @staticmethod - def _RebuildLocaleStrings(): - CharacterWindow.SKILL_GROUP_NAME_DICT = { - playerSettingModule.JOB_WARRIOR : { 1 : localeInfo.SKILL_GROUP_WARRIOR_1, 2 : localeInfo.SKILL_GROUP_WARRIOR_2, }, - playerSettingModule.JOB_ASSASSIN : { 1 : localeInfo.SKILL_GROUP_ASSASSIN_1, 2 : localeInfo.SKILL_GROUP_ASSASSIN_2, }, - playerSettingModule.JOB_SURA : { 1 : localeInfo.SKILL_GROUP_SURA_1, 2 : localeInfo.SKILL_GROUP_SURA_2, }, - playerSettingModule.JOB_SHAMAN : { 1 : localeInfo.SKILL_GROUP_SHAMAN_1, 2 : localeInfo.SKILL_GROUP_SHAMAN_2, }, - } - CharacterWindow.STAT_DESCRIPTION = { - "HTH" : localeInfo.STAT_TOOLTIP_CON, - "INT" : localeInfo.STAT_TOOLTIP_INT, - "STR" : localeInfo.STAT_TOOLTIP_STR, - "DEX" : localeInfo.STAT_TOOLTIP_DEX, - } - CharacterWindow.STAT_MINUS_DESCRIPTION = localeInfo.STAT_MINUS_DESCRIPTION - - def __init__(self): - ui.ScriptWindow.__init__(self) - self.state = "STATUS" - self.isLoaded = 0 - - self.toolTipSkill = 0 - - self.__Initialize() - self.__LoadWindow() - - self.statusPlusCommandDict={ - "HTH" : "/stat ht", - "INT" : "/stat iq", - "STR" : "/stat st", - "DEX" : "/stat dx", - } - - self.statusMinusCommandDict={ - "HTH-" : "/stat- ht", - "INT-" : "/stat- iq", - "STR-" : "/stat- st", - "DEX-" : "/stat- dx", - } - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def __Initialize(self): - self.refreshToolTip = 0 - self.curSelectedSkillGroup = 0 - self.canUseHorseSkill = -1 - - self.toolTip = None - self.toolTipJob = None - self.toolTipAlignment = None - self.toolTipSkill = None - - self.faceImage = None - self.statusPlusLabel = None - self.statusPlusValue = None - self.activeSlot = None - self.tabDict = None - self.tabButtonDict = None - self.pageDict = None - self.titleBarDict = None - self.statusPlusButtonDict = None - self.statusMinusButtonDict = None - - self.skillPageDict = None - self.questShowingStartIndex = 0 - self.questScrollBar = None - self.questSlot = None - self.questNameList = None - self.questLastTimeList = None - self.questLastCountList = None - self.skillGroupButton = () - - self.activeSlot = None - self.activeSkillPointValue = None - self.supportSkillPointValue = None - self.skillGroupButton1 = None - self.skillGroupButton2 = None - self.skillGroupButton3 = None - - self.activeSkillGroupName = None - - self.guildNameSlot = None - self.guildNameValue = None - self.characterNameSlot = None - self.characterNameValue = None - - self.emotionToolTip = None - self.soloEmotionSlot = None - self.dualEmotionSlot = None - - def Show(self): - self.__LoadWindow() - - ui.ScriptWindow.Show(self) - - def __LoadScript(self, fileName): - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, fileName) - - def __BindObject(self): - self.toolTip = uiToolTip.ToolTip() - self.toolTipJob = uiToolTip.ToolTip() - self.toolTipAlignment = uiToolTip.ToolTip(130) - - self.faceImage = self.GetChild("Face_Image") - - faceSlot=self.GetChild("Face_Slot") - - self.statusPlusLabel = self.GetChild("Status_Plus_Label") - self.statusPlusValue = self.GetChild("Status_Plus_Value") - - self.characterNameSlot = self.GetChild("Character_Name_Slot") - self.characterNameValue = self.GetChild("Character_Name") - self.guildNameSlot = self.GetChild("Guild_Name_Slot") - self.guildNameValue = self.GetChild("Guild_Name") - self.characterNameSlot.SAFE_SetStringEvent("MOUSE_OVER_IN", self.__ShowAlignmentToolTip) - self.characterNameSlot.SAFE_SetStringEvent("MOUSE_OVER_OUT", self.__HideAlignmentToolTip) - - self.activeSlot = self.GetChild("Skill_Active_Slot") - self.activeSkillPointValue = self.GetChild("Active_Skill_Point_Value") - self.supportSkillPointValue = self.GetChild("Support_Skill_Point_Value") - self.skillGroupButton1 = self.GetChild("Skill_Group_Button_1") - self.skillGroupButton2 = self.GetChild("Skill_Group_Button_2") - self.skillGroupButton3 = self.GetChild("Skill_Group_Button_3") - - self.activeSkillGroupName = self.GetChild("Active_Skill_Group_Name") - - self.tabDict = { - "STATUS" : self.GetChild("Tab_01"), - "SKILL" : self.GetChild("Tab_02"), - "EMOTICON" : self.GetChild("Tab_03"), - "QUEST" : self.GetChild("Tab_04"), - } - - self.tabButtonDict = { - "STATUS" : self.GetChild("Tab_Button_01"), - "SKILL" : self.GetChild("Tab_Button_02"), - "EMOTICON" : self.GetChild("Tab_Button_03"), - "QUEST" : self.GetChild("Tab_Button_04") - } - - self.pageDict = { - "STATUS" : self.GetChild("Character_Page"), - "SKILL" : self.GetChild("Skill_Page"), - "EMOTICON" : self.GetChild("Emoticon_Page"), - "QUEST" : self.GetChild("Quest_Page") - } - - self.titleBarDict = { - "STATUS" : self.GetChild("Character_TitleBar"), - "SKILL" : self.GetChild("Skill_TitleBar"), - "EMOTICON" : self.GetChild("Emoticon_TitleBar"), - "QUEST" : self.GetChild("Quest_TitleBar") - } - - self.statusPlusButtonDict = { - "HTH" : self.GetChild("HTH_Plus"), - "INT" : self.GetChild("INT_Plus"), - "STR" : self.GetChild("STR_Plus"), - "DEX" : self.GetChild("DEX_Plus"), - } - - self.statusMinusButtonDict = { - "HTH-" : self.GetChild("HTH_Minus"), - "INT-" : self.GetChild("INT_Minus"), - "STR-" : self.GetChild("STR_Minus"), - "DEX-" : self.GetChild("DEX_Minus"), - } - - self.skillPageDict = { - "ACTIVE" : self.GetChild("Skill_Active_Slot"), - "SUPPORT" : self.GetChild("Skill_ETC_Slot"), - "HORSE" : self.GetChild("Skill_Active_Slot"), - } - - self.skillPageStatDict = { - "SUPPORT" : player.SKILL_SUPPORT, - "ACTIVE" : player.SKILL_ACTIVE, - "HORSE" : player.SKILL_HORSE, - } - - self.skillGroupButton = ( - self.GetChild("Skill_Group_Button_1"), - self.GetChild("Skill_Group_Button_2"), - self.GetChild("Skill_Group_Button_3"), - ) - - global SHOW_ONLY_ACTIVE_SKILL - global HIDE_SUPPORT_SKILL_POINT - - if SHOW_ONLY_ACTIVE_SKILL or HIDE_SUPPORT_SKILL_POINT: - self.GetChild("Support_Skill_Point_Label").Hide() - - self.soloEmotionSlot = self.GetChild("SoloEmotionSlot") - self.dualEmotionSlot = self.GetChild("DualEmotionSlot") - self.__SetEmotionSlot() - - self.questShowingStartIndex = 0 - self.questScrollBar = self.GetChild("Quest_ScrollBar") - self.questScrollBar.SetScrollEvent(ui.__mem_func__(self.OnQuestScroll)) - self.questSlot = self.GetChild("Quest_Slot") - - for i in range(quest.QUEST_MAX_NUM): - self.questSlot.HideSlotBaseImage(i) - self.questSlot.SetCoverButton(i,\ - "d:/ymir work/ui/game/quest/slot_button_01.sub",\ - "d:/ymir work/ui/game/quest/slot_button_02.sub",\ - "d:/ymir work/ui/game/quest/slot_button_03.sub",\ - "d:/ymir work/ui/game/quest/slot_button_03.sub", True) - - self.questNameList = [] - self.questLastTimeList = [] - self.questLastCountList = [] - - for i in range(quest.QUEST_MAX_NUM): - self.questNameList.append(self.GetChild("Quest_Name_0" + str(i))) - self.questLastTimeList.append(self.GetChild("Quest_LastTime_0" + str(i))) - self.questLastCountList.append(self.GetChild("Quest_LastCount_0" + str(i))) - - def __SetSkillSlotEvent(self): - for skillPageValue in list(self.skillPageDict.values()): - skillPageValue.SetSlotStyle(wndMgr.SLOT_STYLE_NONE) - skillPageValue.SetSelectItemSlotEvent(ui.__mem_func__(self.SelectSkill)) - skillPageValue.SetSelectEmptySlotEvent(ui.__mem_func__(self.SelectEmptySlot)) - skillPageValue.SetUnselectItemSlotEvent(ui.__mem_func__(self.ClickSkillSlot)) - skillPageValue.SetUseSlotEvent(ui.__mem_func__(self.ClickSkillSlot)) - skillPageValue.SetOverInItemEvent(ui.__mem_func__(self.OverInItem)) - skillPageValue.SetOverOutItemEvent(ui.__mem_func__(self.OverOutItem)) - skillPageValue.SetPressedSlotButtonEvent(ui.__mem_func__(self.OnPressedSlotButton)) - skillPageValue.AppendSlotButton("d:/ymir work/ui/game/windows/btn_plus_up.sub",\ - "d:/ymir work/ui/game/windows/btn_plus_over.sub",\ - "d:/ymir work/ui/game/windows/btn_plus_down.sub") - - def __SetEmotionSlot(self): - self.emotionToolTip = uiToolTip.ToolTip() - - for slot in (self.soloEmotionSlot, self.dualEmotionSlot): - slot.SetSlotStyle(wndMgr.SLOT_STYLE_NONE) - slot.SetSelectItemSlotEvent(ui.__mem_func__(self.__SelectEmotion)) - slot.SetUnselectItemSlotEvent(ui.__mem_func__(self.__ClickEmotionSlot)) - slot.SetUseSlotEvent(ui.__mem_func__(self.__ClickEmotionSlot)) - slot.SetOverInItemEvent(ui.__mem_func__(self.__OverInEmotion)) - slot.SetOverOutItemEvent(ui.__mem_func__(self.__OverOutEmotion)) - slot.AppendSlotButton("d:/ymir work/ui/game/windows/btn_plus_up.sub",\ - "d:/ymir work/ui/game/windows/btn_plus_over.sub",\ - "d:/ymir work/ui/game/windows/btn_plus_down.sub") - - for slotIdx, datadict in list(emotion.EMOTION_DICT.items()): - emotionIdx = slotIdx - - slot = self.soloEmotionSlot - - if slotIdx > 50: - slot = self.dualEmotionSlot - - slot.SetEmotionSlot(slotIdx, emotionIdx) - slot.SetCoverButton(slotIdx) - - def __SelectEmotion(self, slotIndex): - if not slotIndex in emotion.EMOTION_DICT: - return - - if app.IsPressed(app.DIK_LCONTROL): - player.RequestAddToEmptyLocalQuickSlot(player.SLOT_TYPE_EMOTION, slotIndex) - - return - - mouseModule.mouseController.AttachObject(self, player.SLOT_TYPE_EMOTION, slotIndex, slotIndex) - - def __ClickEmotionSlot(self, slotIndex): - print("click emotion") - - if not slotIndex in emotion.EMOTION_DICT: - return - - print("check acting") - - if player.IsActingEmotion(): - return - - command = emotion.EMOTION_DICT[slotIndex]["command"] - print(("command", command)) - - if slotIndex > 50: - vid = player.GetTargetVID() - - if 0 == vid or vid == player.GetMainCharacterIndex() or chr.IsNPC(vid) or chr.IsEnemy(vid): - import chat - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.EMOTION_CHOOSE_ONE) - return - - command += " " + chr.GetNameByVID(vid) - - print(("send_command", command)) - net.SendChatPacket(command) - - def ActEmotion(self, emotionIndex): - self.__ClickEmotionSlot(emotionIndex) - - def __OverInEmotion(self, slotIndex): - if self.emotionToolTip: - - if not slotIndex in emotion.EMOTION_DICT: - return - - self.emotionToolTip.ClearToolTip() - self.emotionToolTip.SetTitle(emotion.EMOTION_DICT[slotIndex]["name"]) - self.emotionToolTip.AlignHorizonalCenter() - self.emotionToolTip.ShowToolTip() - - def __OverOutEmotion(self): - if self.emotionToolTip: - self.emotionToolTip.HideToolTip() - - def __BindEvent(self): - for i in range(len(self.skillGroupButton)): - self.skillGroupButton[i].SetEvent(lambda arg=i: self.__SelectSkillGroup(arg)) - - self.RefreshQuest() - self.__HideJobToolTip() - - for (tabKey, tabButton) in list(self.tabButtonDict.items()): - tabButton.SetEvent(ui.__mem_func__(self.__OnClickTabButton), tabKey) - - for (statusPlusKey, statusPlusButton) in list(self.statusPlusButtonDict.items()): - statusPlusButton.SAFE_SetEvent(self.__OnClickStatusPlusButton, statusPlusKey) - statusPlusButton.ShowToolTip = lambda arg=statusPlusKey: self.__OverInStatButton(arg) - statusPlusButton.HideToolTip = lambda arg=statusPlusKey: self.__OverOutStatButton() - - for (statusMinusKey, statusMinusButton) in list(self.statusMinusButtonDict.items()): - statusMinusButton.SAFE_SetEvent(self.__OnClickStatusMinusButton, statusMinusKey) - statusMinusButton.ShowToolTip = lambda arg=statusMinusKey: self.__OverInStatMinusButton(arg) - statusMinusButton.HideToolTip = lambda arg=statusMinusKey: self.__OverOutStatMinusButton() - - for titleBarValue in list(self.titleBarDict.values()): - titleBarValue.SetCloseEvent(ui.__mem_func__(self.Hide)) - - self.questSlot.SetSelectItemSlotEvent(ui.__mem_func__(self.__SelectQuest)) - - def __LoadWindow(self): - if self.isLoaded == 1: - return - - self.isLoaded = 1 - - try: - if app.IsRTL(): - self.__LoadScript(uiScriptLocale.LOCALE_UISCRIPT_PATH + "CharacterWindow.py") - else: - self.__LoadScript("UIScript/CharacterWindow.py") - - self.__BindObject() - self.__BindEvent() - except: - import exception - exception.Abort("CharacterWindow.__LoadWindow") - - #self.tabButtonDict["EMOTICON"].Disable() - self.SetState("STATUS") - - def Destroy(self): - self.ClearDictionary() - - self.__Initialize() - - def Close(self): - if 0 != self.toolTipSkill: - self.toolTipSkill.Hide() - - self.Hide() - - def SetSkillToolTip(self, toolTipSkill): - self.toolTipSkill = toolTipSkill - - def __OnClickStatusPlusButton(self, statusKey): - try: - statusPlusCommand=self.statusPlusCommandDict[statusKey] - net.SendChatPacket(statusPlusCommand) - except KeyError as msg: - dbg.TraceError("CharacterWindow.__OnClickStatusPlusButton KeyError: %s", msg) - - def __OnClickStatusMinusButton(self, statusKey): - try: - statusMinusCommand=self.statusMinusCommandDict[statusKey] - net.SendChatPacket(statusMinusCommand) - except KeyError as msg: - dbg.TraceError("CharacterWindow.__OnClickStatusMinusButton KeyError: %s", msg) - - - def __OnClickTabButton(self, stateKey): - self.SetState(stateKey) - - def SetState(self, stateKey): - - self.state = stateKey - - for (tabKey, tabButton) in list(self.tabButtonDict.items()): - if stateKey!=tabKey: - tabButton.SetUp() - - for tabValue in list(self.tabDict.values()): - tabValue.Hide() - - for pageValue in list(self.pageDict.values()): - pageValue.Hide() - - for titleBarValue in list(self.titleBarDict.values()): - titleBarValue.Hide() - - self.titleBarDict[stateKey].Show() - self.tabDict[stateKey].Show() - self.pageDict[stateKey].Show() - - - def GetState(self): - return self.state - - def __GetTotalAtkText(self): - minAtk=player.GetStatus(player.ATT_MIN) - maxAtk=player.GetStatus(player.ATT_MAX) - atkBonus=player.GetStatus(player.ATT_BONUS) - attackerBonus=player.GetStatus(player.ATTACKER_BONUS) - - if minAtk==maxAtk: - return "%d" % (minAtk+atkBonus+attackerBonus) - else: - return "%d-%d" % (minAtk+atkBonus+attackerBonus, maxAtk+atkBonus+attackerBonus) - - def __GetTotalMagAtkText(self): - minMagAtk=player.GetStatus(player.MAG_ATT)+player.GetStatus(player.MIN_MAGIC_WEP) - maxMagAtk=player.GetStatus(player.MAG_ATT)+player.GetStatus(player.MAX_MAGIC_WEP) - - if minMagAtk==maxMagAtk: - return "%d" % (minMagAtk) - else: - return "%d-%d" % (minMagAtk, maxMagAtk) - - def __GetTotalDefText(self): - defValue=player.GetStatus(player.DEF_GRADE) - if constInfo.ADD_DEF_BONUS_ENABLE: - defValue+=player.GetStatus(player.DEF_BONUS) - return "%d" % (defValue) - - def RefreshStatus(self): - if self.isLoaded==0: - return - - try: - self.GetChild("Level_Value").SetText(str(player.GetStatus(player.LEVEL))) - self.GetChild("Exp_Value").SetText(str(unsigned32(player.GetEXP()))) - self.GetChild("RestExp_Value").SetText(str(unsigned32(player.GetStatus(player.NEXT_EXP)) - unsigned32(player.GetStatus(player.EXP)))) - self.GetChild("HP_Value").SetText(str(player.GetStatus(player.HP)) + '/' + str(player.GetStatus(player.MAX_HP))) - self.GetChild("SP_Value").SetText(str(player.GetStatus(player.SP)) + '/' + str(player.GetStatus(player.MAX_SP))) - - self.GetChild("STR_Value").SetText(str(player.GetStatus(player.ST))) - self.GetChild("DEX_Value").SetText(str(player.GetStatus(player.DX))) - self.GetChild("HTH_Value").SetText(str(player.GetStatus(player.HT))) - self.GetChild("INT_Value").SetText(str(player.GetStatus(player.IQ))) - - self.GetChild("ATT_Value").SetText(self.__GetTotalAtkText()) - self.GetChild("DEF_Value").SetText(self.__GetTotalDefText()) - - self.GetChild("MATT_Value").SetText(self.__GetTotalMagAtkText()) - #self.GetChild("MATT_Value").SetText(str(player.GetStatus(player.MAG_ATT))) - - self.GetChild("MDEF_Value").SetText(str(player.GetStatus(player.MAG_DEF))) - self.GetChild("ASPD_Value").SetText(str(player.GetStatus(player.ATT_SPEED))) - self.GetChild("MSPD_Value").SetText(str(player.GetStatus(player.MOVING_SPEED))) - self.GetChild("CSPD_Value").SetText(str(player.GetStatus(player.CASTING_SPEED))) - self.GetChild("ER_Value").SetText(str(player.GetStatus(player.EVADE_RATE))) - - except: - #import exception - #exception.Abort("CharacterWindow.RefreshStatus.BindObject") - ## Prevents game crash - pass - - self.__RefreshStatusPlusButtonList() - self.__RefreshStatusMinusButtonList() - self.RefreshAlignment() - - if self.refreshToolTip: - self.refreshToolTip() - - def __RefreshStatusPlusButtonList(self): - if self.isLoaded==0: - return - - statusPlusPoint=player.GetStatus(player.STAT) - - if statusPlusPoint>0: - self.statusPlusValue.SetText(str(statusPlusPoint)) - self.statusPlusLabel.Show() - self.ShowStatusPlusButtonList() - else: - self.statusPlusValue.SetText(str(0)) - self.statusPlusLabel.Hide() - self.HideStatusPlusButtonList() - - def __RefreshStatusMinusButtonList(self): - if self.isLoaded==0: - return - - statusMinusPoint=self.__GetStatMinusPoint() - - if statusMinusPoint>0: - self.__ShowStatusMinusButtonList() - else: - self.__HideStatusMinusButtonList() - - def RefreshAlignment(self): - point, grade = player.GetAlignmentData() - - import colorInfo - COLOR_DICT = { 0 : colorInfo.TITLE_RGB_GOOD_4, - 1 : colorInfo.TITLE_RGB_GOOD_3, - 2 : colorInfo.TITLE_RGB_GOOD_2, - 3 : colorInfo.TITLE_RGB_GOOD_1, - 4 : colorInfo.TITLE_RGB_NORMAL, - 5 : colorInfo.TITLE_RGB_EVIL_1, - 6 : colorInfo.TITLE_RGB_EVIL_2, - 7 : colorInfo.TITLE_RGB_EVIL_3, - 8 : colorInfo.TITLE_RGB_EVIL_4, } - colorList = COLOR_DICT.get(grade, colorInfo.TITLE_RGB_NORMAL) - gradeColor = ui.GenerateColor(colorList[0], colorList[1], colorList[2]) - - self.toolTipAlignment.ClearToolTip() - self.toolTipAlignment.AutoAppendTextLine(localeInfo.TITLE_NAME_LIST[grade], gradeColor) - self.toolTipAlignment.AutoAppendTextLine(localeInfo.ALIGNMENT_NAME + ": " + str(point)) - self.toolTipAlignment.AlignHorizonalCenter() - - def __ShowStatusMinusButtonList(self): - for (stateMinusKey, statusMinusButton) in list(self.statusMinusButtonDict.items()): - statusMinusButton.Show() - - def __HideStatusMinusButtonList(self): - for (stateMinusKey, statusMinusButton) in list(self.statusMinusButtonDict.items()): - statusMinusButton.Hide() - - def ShowStatusPlusButtonList(self): - for (statePlusKey, statusPlusButton) in list(self.statusPlusButtonDict.items()): - statusPlusButton.Show() - - def HideStatusPlusButtonList(self): - for (statePlusKey, statusPlusButton) in list(self.statusPlusButtonDict.items()): - statusPlusButton.Hide() - - def SelectSkill(self, skillSlotIndex): - mouseController = mouseModule.mouseController - - if False == mouseController.isAttached(): - srcSlotIndex = self.__RealSkillSlotToSourceSlot(skillSlotIndex) - selectedSkillIndex = player.GetSkillIndex(srcSlotIndex) - - if skill.CanUseSkill(selectedSkillIndex): - if app.IsPressed(app.DIK_LCONTROL): - player.RequestAddToEmptyLocalQuickSlot(player.SLOT_TYPE_SKILL, srcSlotIndex) - - return - - mouseController.AttachObject(self, player.SLOT_TYPE_SKILL, srcSlotIndex, selectedSkillIndex) - - else: - mouseController.DeattachObject() - - def SelectEmptySlot(self, SlotIndex): - mouseModule.mouseController.DeattachObject() - - ## ToolTip - def OverInItem(self, slotNumber): - if mouseModule.mouseController.isAttached(): - return - - if 0 == self.toolTipSkill: - return - - srcSlotIndex = self.__RealSkillSlotToSourceSlot(slotNumber) - skillIndex = player.GetSkillIndex(srcSlotIndex) - skillLevel = player.GetSkillLevel(srcSlotIndex) - skillGrade = player.GetSkillGrade(srcSlotIndex) - skillType = skill.GetSkillType(skillIndex) - - ## ACTIVE - if skill.SKILL_TYPE_ACTIVE == skillType: - overInSkillGrade = self.__GetSkillGradeFromSlot(slotNumber) - - if overInSkillGrade == skill.SKILL_GRADE_COUNT-1 and skillGrade == skill.SKILL_GRADE_COUNT: - self.toolTipSkill.SetSkillNew(srcSlotIndex, skillIndex, skillGrade, skillLevel) - elif overInSkillGrade == skillGrade: - self.toolTipSkill.SetSkillNew(srcSlotIndex, skillIndex, overInSkillGrade, skillLevel) - else: - self.toolTipSkill.SetSkillOnlyName(srcSlotIndex, skillIndex, overInSkillGrade) - - else: - self.toolTipSkill.SetSkillNew(srcSlotIndex, skillIndex, skillGrade, skillLevel) - - def OverOutItem(self): - if 0 != self.toolTipSkill: - self.toolTipSkill.HideToolTip() - - ## Quest - def __SelectQuest(self, slotIndex): - questIndex = quest.GetQuestIndex(self.questShowingStartIndex+slotIndex) - - import event - event.QuestButtonClick(-2147483648 + questIndex) - - def RefreshQuest(self): - - if self.isLoaded==0: - return - - questCount = quest.GetQuestCount() - questRange = list(range(quest.QUEST_MAX_NUM)) - - if questCount > quest.QUEST_MAX_NUM: - self.questScrollBar.Show() - else: - self.questScrollBar.Hide() - - for i in questRange[:questCount]: - (questName, questIcon, questCounterName, questCounterValue) = quest.GetQuestData(self.questShowingStartIndex+i) - - self.questNameList[i].SetText(questName) - self.questNameList[i].Show() - self.questLastCountList[i].Show() - self.questLastTimeList[i].Show() - - if len(questCounterName) > 0: - self.questLastCountList[i].SetText("%s : %d" % (questCounterName, questCounterValue)) - else: - self.questLastCountList[i].SetText("") - - ## Icon - self.questSlot.SetSlot(i, i, 1, 1, questIcon) - - for i in questRange[questCount:]: - self.questNameList[i].Hide() - self.questLastTimeList[i].Hide() - self.questLastCountList[i].Hide() - self.questSlot.ClearSlot(i) - self.questSlot.HideSlotBaseImage(i) - - self.__UpdateQuestClock() - - def __UpdateQuestClock(self): - if "QUEST" == self.state: - # QUEST_LIMIT_COUNT_BUG_FIX - for i in range(min(quest.GetQuestCount(), quest.QUEST_MAX_NUM)): - # END_OF_QUEST_LIMIT_COUNT_BUG_FIX - (lastName, lastTime) = quest.GetQuestLastTime(i) - clockText = localeInfo.QUEST_UNLIMITED_TIME - - if len(lastName) > 0: - - if lastTime <= 0: - clockText = localeInfo.QUEST_TIMEOVER - - else: - questLastMinute = lastTime // 60 - questLastSecond = lastTime % 60 - - clockText = lastName + " : " - - if questLastMinute > 0: - clockText += str(questLastMinute) + localeInfo.QUEST_MIN - - if questLastSecond > 0: - clockText += " " - - if questLastSecond > 0: - clockText += str(questLastSecond) + localeInfo.QUEST_SEC - - self.questLastTimeList[i].SetText(clockText) - - def __GetStatMinusPoint(self): - POINT_STAT_RESET_COUNT = 112 - - return player.GetStatus(POINT_STAT_RESET_COUNT) - - def __OverInStatMinusButton(self, stat): - try: - self.__ShowStatToolTip(self.STAT_MINUS_DESCRIPTION[stat] % self.__GetStatMinusPoint()) - except KeyError: - pass - - self.refreshToolTip = lambda arg=stat: self.__OverInStatMinusButton(arg) - - def __OverOutStatMinusButton(self): - self.__HideStatToolTip() - self.refreshToolTip = 0 - - def __OverInStatButton(self, stat): - try: - self.__ShowStatToolTip(self.STAT_DESCRIPTION[stat]) - except KeyError: - pass - - def __OverOutStatButton(self): - self.__HideStatToolTip() - - def __ShowStatToolTip(self, statDesc): - self.toolTip.ClearToolTip() - self.toolTip.AppendTextLine(statDesc) - self.toolTip.Show() - - def __HideStatToolTip(self): - self.toolTip.Hide() - - def OnPressEscapeKey(self): - self.Close() - - return True - - def OnUpdate(self): - self.__UpdateQuestClock() - - ## Skill Process - def __RefreshSkillPage(self, name, slotCount): - global SHOW_LIMIT_SUPPORT_SKILL_LIST - - skillPage = self.skillPageDict[name] - startSlotIndex = skillPage.GetStartIndex() - - if "ACTIVE" == name: - if self.PAGE_HORSE == self.curSelectedSkillGroup: - startSlotIndex += slotCount - - getSkillType = skill.GetSkillType - getSkillIndex = player.GetSkillIndex - getSkillGrade = player.GetSkillGrade - getSkillLevel = player.GetSkillLevel - getSkillLevelUpPoint = skill.GetSkillLevelUpPoint - getSkillMaxLevel = skill.GetSkillMaxLevel - - for i in range(slotCount + 1): - slotIndex = i + startSlotIndex - skillIndex = getSkillIndex(slotIndex) - - for j in range(skill.SKILL_GRADE_COUNT): - skillPage.ClearSlot(self.__GetRealSkillSlot(j, i)) - - if 0 == skillIndex: - continue - - skillGrade = getSkillGrade(slotIndex) - skillLevel = getSkillLevel(slotIndex) - skillType = getSkillType(skillIndex) - - ## Horse riding skill exception handling - if player.SKILL_INDEX_RIDING == skillIndex: - if 1 == skillGrade: - skillLevel += 19 - elif 2 == skillGrade: - skillLevel += 29 - elif 3 == skillGrade: - skillLevel = 40 - - skillPage.SetSkillSlotNew(slotIndex, skillIndex, max(skillLevel - 1, 0), skillLevel) - skillPage.SetSlotCount(slotIndex, skillLevel) - - ## ACTIVE - elif skill.SKILL_TYPE_ACTIVE == skillType: - for j in range(skill.SKILL_GRADE_COUNT): - realSlotIndex = self.__GetRealSkillSlot(j, slotIndex) - - skillPage.SetSkillSlotNew(realSlotIndex, skillIndex, j, skillLevel) - skillPage.SetCoverButton(realSlotIndex) - - if (skillGrade == skill.SKILL_GRADE_COUNT) and j == (skill.SKILL_GRADE_COUNT - 1): - skillPage.SetSlotCountNew(realSlotIndex, skillGrade, skillLevel) - elif (not self.__CanUseSkillNow()) or (skillGrade != j): - skillPage.SetSlotCount(realSlotIndex, 0) - skillPage.DisableCoverButton(realSlotIndex) - - if not player.IsSkillActive(slotIndex): - skillPage.DeactivateSlot(realSlotIndex) - - if player.IsSkillCoolTime(slotIndex) and skillGrade != j: - skillPage.TransferSlotCoolTime(realSlotIndex, self.__GetRealSkillSlot(skillGrade, i)) - else: - self.SkillClearCoolTime(realSlotIndex) - else: - skillPage.SetSlotCountNew(realSlotIndex, skillGrade, skillLevel) - - # Check if this is the active slot - # Grade 3 appears in slot 2, so check both conditions - isActiveSlot = (skillGrade == j) or ((skillGrade == skill.SKILL_GRADE_COUNT) and j == (skill.SKILL_GRADE_COUNT - 1)) - - if player.IsSkillActive(slotIndex) and isActiveSlot: - skillPage.ActivateSlot(realSlotIndex) - else: - skillPage.DeactivateSlot(realSlotIndex) - else: - if not SHOW_LIMIT_SUPPORT_SKILL_LIST or skillIndex in SHOW_LIMIT_SUPPORT_SKILL_LIST: - realSlotIndex = self.__GetETCSkillRealSlotIndex(slotIndex) - - skillPage.SetSkillSlot(realSlotIndex, skillIndex, skillLevel) - skillPage.SetSlotCountNew(realSlotIndex, skillGrade, skillLevel) - - if skill.CanUseSkill(skillIndex): - skillPage.SetCoverButton(realSlotIndex) - - # Clear storage for horse skills at level 0 BEFORE restore runs - if skillType == skill.SKILL_TYPE_HORSE and skillLevel == 0: - player.ResetHorseSkillCoolTime(skillIndex, realSlotIndex) - skillPage.SetSlotCoolTime(realSlotIndex, 0) - - if player.IsSkillActive(slotIndex): - skillPage.ActivateSlot(realSlotIndex) - else: - skillPage.DeactivateSlot(realSlotIndex) - - skillPage.RefreshSlot() - - self.__RestoreSlotCoolTime(skillPage) - - def __RestoreSlotCoolTime(self, skillPage): - restoreType = skill.SKILL_TYPE_NONE - - if self.PAGE_HORSE == self.curSelectedSkillGroup: - restoreType = skill.SKILL_TYPE_HORSE - else: - restoreType = skill.SKILL_TYPE_ACTIVE - - skillPage.RestoreSlotCoolTime(restoreType) - - def __ClearHorseSkillQuickSlots(self): - HORSE_SKILL_SET = (137, 138, 139, 140) - - quick_slot_per_page = 8 # two quick_slot windows * 4 slots - quick_page_count = 4 # matches QUICKPAGE_NUMBER_FILENAME - current_page = player.GetQuickPage() - - for page in range(quick_page_count): - player.SetQuickPage(page) - - for local_slot in range(quick_slot_per_page): - slotType, position = player.GetLocalQuickSlot(local_slot) - - if slotType != player.SLOT_TYPE_SKILL: - continue - - skillIndex = player.GetSkillIndex(position) - - if skillIndex in HORSE_SKILL_SET: - player.RequestDeleteGlobalQuickSlot(page * quick_slot_per_page + local_slot) - - player.SetQuickPage(current_page) - - def RefreshSkill(self): - if self.isLoaded == 0: - return - - if self.__IsChangedHorseRidingSkillLevel(): - if not self.__CanUseHorseSkill(): - if self.curSelectedSkillGroup == self.PAGE_HORSE: - self.__SelectSkillGroup(0) # fall back to first active tab - - self.__ClearHorseSkillQuickSlots() # remove horse skills from taskbar - - self.RefreshCharacter() - - return - - global SHOW_ONLY_ACTIVE_SKILL - - if SHOW_ONLY_ACTIVE_SKILL: - self.__RefreshSkillPage("ACTIVE", self.ACTIVE_PAGE_SLOT_COUNT) - else: - self.__RefreshSkillPage("ACTIVE", self.ACTIVE_PAGE_SLOT_COUNT) - self.__RefreshSkillPage("SUPPORT", self.SUPPORT_PAGE_SLOT_COUNT) - - self.RefreshSkillPlusButtonList() - - def CanShowPlusButton(self, skillIndex, skillLevel, curStatPoint): - - ## Check if skill exists - if 0 == skillIndex: - return False - - ## Check if skill can be leveled up - if not skill.CanLevelUpSkill(skillIndex, skillLevel): - return False - - return True - - def __RefreshSkillPlusButton(self, name): - global HIDE_SUPPORT_SKILL_POINT - - if HIDE_SUPPORT_SKILL_POINT and "SUPPORT" == name: - return - - slotWindow = self.skillPageDict[name] - slotWindow.HideAllSlotButton() - - slotStatType = self.skillPageStatDict[name] - - if 0 == slotStatType: - return - - statPoint = player.GetStatus(slotStatType) - startSlotIndex = slotWindow.GetStartIndex() - - if "HORSE" == name: - startSlotIndex += self.ACTIVE_PAGE_SLOT_COUNT - - if statPoint > 0: - for i in range(self.PAGE_SLOT_COUNT): - slotIndex = i + startSlotIndex - skillIndex = player.GetSkillIndex(slotIndex) - skillGrade = player.GetSkillGrade(slotIndex) - skillLevel = player.GetSkillLevel(slotIndex) - - if skillIndex == 0: - continue - if skillGrade != 0: - continue - - if name == "HORSE": - if player.GetStatus(player.LEVEL) >= skill.GetSkillLevelLimit(skillIndex): - if skillLevel < 20: - slotWindow.ShowSlotButton(self.__GetETCSkillRealSlotIndex(slotIndex)) - - else: - if "SUPPORT" == name: - if not SHOW_LIMIT_SUPPORT_SKILL_LIST or skillIndex in SHOW_LIMIT_SUPPORT_SKILL_LIST: - if self.CanShowPlusButton(skillIndex, skillLevel, statPoint): - slotWindow.ShowSlotButton(slotIndex) - else: - if self.CanShowPlusButton(skillIndex, skillLevel, statPoint): - slotWindow.ShowSlotButton(slotIndex) - - - def RefreshSkillPlusButtonList(self): - if self.isLoaded==0: - return - - self.RefreshSkillPlusPointLabel() - - if not self.__CanUseSkillNow(): - return - - try: - if self.PAGE_HORSE == self.curSelectedSkillGroup: - self.__RefreshSkillPlusButton("HORSE") - else: - self.__RefreshSkillPlusButton("ACTIVE") - - self.__RefreshSkillPlusButton("SUPPORT") - - except: - import exception - - exception.Abort("CharacterWindow.RefreshSkillPlusButtonList.BindObject") - - def RefreshSkillPlusPointLabel(self): - if self.isLoaded==0: - return - - if self.PAGE_HORSE == self.curSelectedSkillGroup: - activeStatPoint = player.GetStatus(player.SKILL_HORSE) - self.activeSkillPointValue.SetText(str(activeStatPoint)) - - else: - activeStatPoint = player.GetStatus(player.SKILL_ACTIVE) - self.activeSkillPointValue.SetText(str(activeStatPoint)) - - supportStatPoint = max(0, player.GetStatus(player.SKILL_SUPPORT)) - self.supportSkillPointValue.SetText(str(supportStatPoint)) - - ## Skill Level Up Button - def OnPressedSlotButton(self, slotNumber): - srcSlotIndex = self.__RealSkillSlotToSourceSlot(slotNumber) - - skillIndex = player.GetSkillIndex(srcSlotIndex) - curLevel = player.GetSkillLevel(srcSlotIndex) - maxLevel = skill.GetSkillMaxLevel(skillIndex) - - net.SendChatPacket("/skillup " + str(skillIndex)) - - ## Use Skill - def ClickSkillSlot(self, slotIndex): - - srcSlotIndex = self.__RealSkillSlotToSourceSlot(slotIndex) - skillIndex = player.GetSkillIndex(srcSlotIndex) - skillType = skill.GetSkillType(skillIndex) - - if not self.__CanUseSkillNow(): - if skill.SKILL_TYPE_ACTIVE == skillType: - return - - for slotWindow in list(self.skillPageDict.values()): - if slotWindow.HasSlot(slotIndex): - if skill.CanUseSkill(skillIndex): - player.ClickSkillSlot(srcSlotIndex) - return - - mouseModule.mouseController.DeattachObject() - - ## FIXME: When using a skill, find and update the slot by slot number. - ## Very inefficient. The structure itself needs improvement. - def OnUseSkill(self, slotIndex, coolTime): - skillIndex = player.GetSkillIndex(slotIndex) - skillType = skill.GetSkillType(skillIndex) - - ## ACTIVE - if skill.SKILL_TYPE_ACTIVE == skillType: - skillGrade = player.GetSkillGrade(slotIndex) - slotIndex = self.__GetRealSkillSlot(skillGrade, slotIndex) - ## ETC - else: - slotIndex = self.__GetETCSkillRealSlotIndex(slotIndex) - - for slotWindow in list(self.skillPageDict.values()): - if slotWindow.HasSlot(slotIndex): - slotWindow.StoreSlotCoolTime(skillType, slotIndex, coolTime) - self.__RestoreSlotCoolTime(slotWindow) - - return - - def OnActivateSkill(self, slotIndex): - skillIndex = player.GetSkillIndex(slotIndex) - skillType = skill.GetSkillType(skillIndex) - - ## ACTIVE - if skill.SKILL_TYPE_ACTIVE == skillType: - skillGrade = player.GetSkillGrade(slotIndex) - slotIndex = self.__GetRealSkillSlot(skillGrade, slotIndex) - ## ETC - else: - slotIndex = self.__GetETCSkillRealSlotIndex(slotIndex) - - for slotWindow in list(self.skillPageDict.values()): - if slotWindow.HasSlot(slotIndex): - slotWindow.ActivateSlot(slotIndex) - - return - - def OnDeactivateSkill(self, slotIndex): - skillIndex = player.GetSkillIndex(slotIndex) - skillType = skill.GetSkillType(skillIndex) - - ## ACTIVE - if skill.SKILL_TYPE_ACTIVE == skillType: - skillGrade = player.GetSkillGrade(slotIndex) - slotIndex = self.__GetRealSkillSlot(skillGrade, slotIndex) - ## ETC - else: - slotIndex = self.__GetETCSkillRealSlotIndex(slotIndex) - - for slotWindow in list(self.skillPageDict.values()): - if slotWindow.HasSlot(slotIndex): - slotWindow.DeactivateSlot(slotIndex) - - return - - def __ShowJobToolTip(self): - self.toolTipJob.ShowToolTip() - - def SkillClearCoolTime(self, slotIndex): - skillIndex = player.GetSkillIndex(slotIndex) - - if skillIndex < 1: - return - - skillType = skill.GetSkillType(skillIndex) - - ## ACTIVE - # Map to the correct visual slot based on skill type - if skill.SKILL_TYPE_ACTIVE == skillType: - slotIndex = self.__GetRealSkillSlot(player.GetSkillGrade(slotIndex), slotIndex) - else: - slotIndex = self.__GetETCSkillRealSlotIndex(slotIndex) - - for slotWindow in list(self.skillPageDict.values()): - if slotWindow.HasSlot(slotIndex): - slotWindow.SetSlotCoolTime(slotIndex, 0) - - def __HideJobToolTip(self): - self.toolTipJob.HideToolTip() - - def __SetJobText(self, mainJob, subJob): - if player.GetStatus(player.LEVEL)<5: - subJob=0 - - def __ShowAlignmentToolTip(self): - self.toolTipAlignment.ShowToolTip() - - def __HideAlignmentToolTip(self): - self.toolTipAlignment.HideToolTip() - - def RefreshCharacter(self): - - if self.isLoaded==0: - return - - ## Name - try: - characterName = player.GetName() - guildName = player.GetGuildName() - self.characterNameValue.SetText(characterName) - self.guildNameValue.SetText(guildName) - if not guildName: - if app.IsRTL(): - self.characterNameSlot.SetPosition(190, 34) - else: - self.characterNameSlot.SetPosition(109, 34) - - self.guildNameSlot.Hide() - else: - self.characterNameSlot.SetPosition(153, 34) - self.guildNameSlot.Show() - except: - import exception - exception.Abort("CharacterWindow.RefreshCharacter.BindObject") - - race = net.GetMainActorRace() - group = net.GetMainActorSkillGroup() - empire = net.GetMainActorEmpire() - - ## Job Text - job = chr.RaceToJob(race) - self.__SetJobText(job, group) - - ## FaceImage - try: - faceImageName = FACE_IMAGE_DICT[race] - - try: - self.faceImage.LoadImage(faceImageName) - except: - print(("CharacterWindow.RefreshCharacter(race=%d, faceImageName=%s)" % (race, faceImageName))) - self.faceImage.Hide() - - except KeyError: - self.faceImage.Hide() - - ## GroupName - self.__SetSkillGroupName(race, group) - - self.__SetSkillSlotData(race, group, empire) - - ## Skill - if 0 == group: - self.__SelectSkillGroup(0) - else: - if self.__CanUseHorseSkill(): - self.__SelectSkillGroup(0) - - def __SetSkillGroupName(self, race, group): - job = chr.RaceToJob(race) - - if job not in self.SKILL_GROUP_NAME_DICT: - return - - nameList = self.SKILL_GROUP_NAME_DICT[job] - - if 0 == group: - self.skillGroupButton1.SetText(nameList[1]) - self.skillGroupButton2.SetText(nameList[2]) - - if self.__CanUseHorseSkill(): - self.skillGroupButton3.SetText(localeInfo.SKILL_GROUP_HORSE) - self.skillGroupButton3.Show() - self.skillGroupButton3.SetPosition(95, 2) - else: - self.skillGroupButton3.Hide() - - self.skillGroupButton1.Show() - self.skillGroupButton2.Show() - self.activeSkillGroupName.Hide() - else: - if self.__CanUseHorseSkill(): - self.activeSkillGroupName.Hide() - self.skillGroupButton1.SetText(nameList.get(group, "Noname")) - self.skillGroupButton3.SetText(localeInfo.SKILL_GROUP_HORSE) - self.skillGroupButton1.Show() - self.skillGroupButton2.Hide() - self.skillGroupButton3.Show() - self.skillGroupButton3.SetPosition(50, 2) - else: - self.activeSkillGroupName.SetText(nameList.get(group, "Noname")) - self.activeSkillGroupName.Show() - self.skillGroupButton1.Hide() - self.skillGroupButton2.Hide() - self.skillGroupButton3.Hide() - - def __SetSkillSlotData(self, race, group, empire=0): - ## SkillIndex - playerSettingModule.RegisterSkill(race, group, empire) - - ## Event - self.__SetSkillSlotEvent() - - ## Refresh - self.RefreshSkill() - - def __SelectSkillGroup(self, pageIndex, xxx_todo_changeme = list(range(3))): - (PAGE_SKILL_1, PAGE_SKILL_2, PAGE_SKILL_HORSE) = xxx_todo_changeme - for pageButton in self.skillGroupButton: - pageButton.SetUp() - - self.skillGroupButton[pageIndex].Down() - - if pageIndex in (PAGE_SKILL_1, PAGE_SKILL_2): - skillGroupIndex = net.GetMainActorSkillGroup() - - if bool(skillGroupIndex): - (tmpCurSkillGroup, tmpSkillGroup) = (skillGroupIndex - 1, skillGroupIndex) - else: - (tmpCurSkillGroup, tmpSkillGroup) = (pageIndex, pageIndex + 1) - - self.curSelectedSkillGroup = tmpCurSkillGroup - self.__SetSkillSlotData(net.GetMainActorRace(), tmpSkillGroup, net.GetMainActorEmpire()) - elif pageIndex == PAGE_SKILL_HORSE and self.__CanUseHorseSkill(): - self.curSelectedSkillGroup = self.PAGE_HORSE - - self.RefreshSkill() - - def __CanUseSkillNow(self): - if 0 == net.GetMainActorSkillGroup(): - return False - - return True - - def __CanUseHorseSkill(self): - slotIndex = player.GetSkillSlotIndex(player.SKILL_INDEX_RIDING) - - if not slotIndex: - return False - - grade = player.GetSkillGrade(slotIndex) - level = player.GetSkillLevel(slotIndex) - - if level < 0: - level *= -1 - - # Map to UI-displayed riding level (matches __RefreshSkillPage logic) - # grade 1: base 1..20 shown as 20..39 (offset +19) - # grade 2: base 1..10 shown as 30..39 (offset +29) - # grade 3: shown as 40 - effective = 0 - - if grade >= 3: - effective = 40 - elif grade == 2: - effective = level + 29 - elif grade == 1: - effective = level + 19 - else: - effective = level - - # Require displayed riding level >= 21 to enable the horse page - return effective >= 21 - - def __IsChangedHorseRidingSkillLevel(self): - ret = False - - if -1 == self.canUseHorseSkill: - self.canUseHorseSkill = self.__CanUseHorseSkill() - - if self.canUseHorseSkill != self.__CanUseHorseSkill(): - ret = True - - self.canUseHorseSkill = self.__CanUseHorseSkill() - return ret - - def __GetRealSkillSlot(self, skillGrade, skillSlot): - return skillSlot + min(skill.SKILL_GRADE_COUNT-1, skillGrade)*skill.SKILL_GRADE_STEP_COUNT - - def __GetETCSkillRealSlotIndex(self, skillSlot): - if skillSlot > 100: - return skillSlot - return skillSlot % self.ACTIVE_PAGE_SLOT_COUNT - - def __RealSkillSlotToSourceSlot(self, realSkillSlot): - if realSkillSlot > 100: - return realSkillSlot - if self.PAGE_HORSE == self.curSelectedSkillGroup: - return realSkillSlot + self.ACTIVE_PAGE_SLOT_COUNT - return realSkillSlot % skill.SKILL_GRADE_STEP_COUNT - - def __GetSkillGradeFromSlot(self, skillSlot): - return int(skillSlot // skill.SKILL_GRADE_STEP_COUNT) - - def SelectSkillGroup(self, index): - self.__SelectSkillGroup(index) - - def OnQuestScroll(self): - questCount = quest.GetQuestCount() - scrollLineCount = max(0, questCount - quest.QUEST_MAX_NUM) - startIndex = int(scrollLineCount * self.questScrollBar.GetPos()) - - if startIndex != self.questShowingStartIndex: - self.questShowingStartIndex = startIndex - self.RefreshQuest() - -CharacterWindow._RebuildLocaleStrings() -localeInfo.RegisterReloadCallback(CharacterWindow._RebuildLocaleStrings) diff --git a/tools/root/uichat.py b/tools/root/uichat.py deleted file mode 100644 index f0fb39e0..00000000 --- a/tools/root/uichat.py +++ /dev/null @@ -1,1173 +0,0 @@ -import ui -import grp -import chat -import wndMgr -import net -import app -import ime -import localeInfo -import colorInfo -import constInfo -import systemSetting - -ENABLE_CHAT_COMMAND = True -ENABLE_LAST_SENTENCE_STACK = True -ENABLE_INSULT_CHECK = True - -chatInputSetList = [] -def InsertChatInputSetWindow(wnd): - global chatInputSetList - chatInputSetList.append(wnd) -def RefreshChatMode(): - global chatInputSetList - list([wnd.OnRefreshChatMode() for wnd in chatInputSetList]) -def DestroyChatInputSetWindow(): - global chatInputSetList - chatInputSetList = [] - -## ChatModeButton -class ChatModeButton(ui.Window): - - OUTLINE_COLOR = grp.GenerateColor(1.0, 1.0, 1.0, 1.0) - OVER_COLOR = grp.GenerateColor(1.0, 1.0, 1.0, 0.3) - BUTTON_STATE_UP = 0 - BUTTON_STATE_OVER = 1 - BUTTON_STATE_DOWN = 2 - - def __init__(self): - ui.Window.__init__(self) - self.state = self.BUTTON_STATE_UP - self.buttonText = None - self.event = None - self.SetWindowName("ChatModeButton") - - net.EnableChatInsultFilter(ENABLE_INSULT_CHECK) - - def __del__(self): - ui.Window.__del__(self) - - def SAFE_SetEvent(self, event): - self.event=ui.__mem_func__(event) - - def SetText(self, text): - if None == self.buttonText: - textLine = ui.TextLine() - textLine.SetParent(self) - textLine.SetWindowHorizontalAlignCenter() - textLine.SetWindowVerticalAlignCenter() - textLine.SetVerticalAlignCenter() - textLine.SetHorizontalAlignCenter() - textLine.SetPackedFontColor(self.OUTLINE_COLOR) - textLine.Show() - self.buttonText = textLine - - self.buttonText.SetText(text) - - def SetSize(self, width, height): - self.width = width - self.height = height - ui.Window.SetSize(self, width, height) - - def OnMouseOverIn(self): - self.state = self.BUTTON_STATE_OVER - - def OnMouseOverOut(self): - self.state = self.BUTTON_STATE_UP - - def OnMouseLeftButtonDown(self): - self.state = self.BUTTON_STATE_DOWN - - def OnMouseLeftButtonUp(self): - self.state = self.BUTTON_STATE_UP - if self.IsIn(): - self.state = self.BUTTON_STATE_OVER - - if None != self.event: - self.event() - - def OnRender(self): - (x, y) = self.GetGlobalPosition() - - grp.SetColor(self.OUTLINE_COLOR) - grp.RenderRoundBox(x, y, self.width, self.height) - - if self.state >= self.BUTTON_STATE_OVER: - grp.RenderRoundBox(x+1, y, self.width-2, self.height) - grp.RenderRoundBox(x, y+1, self.width, self.height-2) - - if self.BUTTON_STATE_DOWN == self.state: - grp.SetColor(self.OVER_COLOR) - grp.RenderBar(x+1, y+1, self.width-2, self.height-2) - -## ChatLine -class ChatLine(ui.EditLine): - - CHAT_MODE_NAME = {} - - @staticmethod - def _RebuildLocaleStrings(): - ChatLine.CHAT_MODE_NAME = { - chat.CHAT_TYPE_TALKING : localeInfo.CHAT_NORMAL, - chat.CHAT_TYPE_PARTY : localeInfo.CHAT_PARTY, - chat.CHAT_TYPE_GUILD : localeInfo.CHAT_GUILD, - chat.CHAT_TYPE_SHOUT : localeInfo.CHAT_SHOUT, - } - - def __init__(self): - ui.EditLine.__init__(self) - self.SetWindowName("Chat Line") - self.lastShoutTime = 0 - self.eventEscape = lambda *arg: None - self.eventReturn = lambda *arg: None - self.eventTab = None - self.chatMode = chat.CHAT_TYPE_TALKING - - self.overTextLine = ui.TextLine() - self.overTextLine.SetParent(self) - self.overTextLine.SetPosition(-1, 0) - self.overTextLine.SetFontColor(1.0, 1.0, 0.0) - self.overTextLine.SetOutline() - self.overTextLine.Hide() - - self.lastSentenceStack = [] - self.lastSentencePos = 0 - - def SetChatMode(self, mode): - self.chatMode = mode - - def GetChatMode(self): - return self.chatMode - - def ChangeChatMode(self): - if chat.CHAT_TYPE_TALKING == self.GetChatMode(): - self.SetChatMode(chat.CHAT_TYPE_PARTY) - self.SetText("#") - self.SetEndPosition() - - elif chat.CHAT_TYPE_PARTY == self.GetChatMode(): - self.SetChatMode(chat.CHAT_TYPE_GUILD) - self.SetText("%") - self.SetEndPosition() - - elif chat.CHAT_TYPE_GUILD == self.GetChatMode(): - self.SetChatMode(chat.CHAT_TYPE_SHOUT) - self.SetText("!") - self.SetEndPosition() - - elif chat.CHAT_TYPE_SHOUT == self.GetChatMode(): - self.SetChatMode(chat.CHAT_TYPE_TALKING) - self.SetText("") - - self.__CheckChatMark() - - def GetCurrentChatModeName(self): - try: - return self.CHAT_MODE_NAME[self.chatMode] - except: - import exception - exception.Abort("ChatLine.GetCurrentChatModeName") - - def SAFE_SetEscapeEvent(self, event): - self.eventReturn = ui.__mem_func__(event) - - def SAFE_SetReturnEvent(self, event): - self.eventEscape = ui.__mem_func__(event) - - def SAFE_SetTabEvent(self, event): - self.eventTab = ui.__mem_func__(event) - - def SetTabEvent(self, event): - self.eventTab = event - - def OpenChat(self): - self.SetFocus() - self.__ResetChat() - - def __ClearChat(self): - self.SetText("") - self.lastSentencePos = 0 - - def __ResetChat(self): - if chat.CHAT_TYPE_PARTY == self.GetChatMode(): - self.SetText("#") - self.SetEndPosition() - elif chat.CHAT_TYPE_GUILD == self.GetChatMode(): - self.SetText("%") - self.SetEndPosition() - elif chat.CHAT_TYPE_SHOUT == self.GetChatMode(): - self.SetText("!") - self.SetEndPosition() - else: - self.__ClearChat() - - self.__CheckChatMark() - - - def __SendChatPacket(self, text, type): - if net.IsChatInsultIn(text): - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.CHAT_INSULT_STRING) - else: - net.SendChatPacket(text, type) - - def __SendPartyChatPacket(self, text): - - if 1 == len(text): - self.RunCloseEvent() - return - - self.__SendChatPacket(text[1:], chat.CHAT_TYPE_PARTY) - self.__ResetChat() - - def __SendGuildChatPacket(self, text): - - if 1 == len(text): - self.RunCloseEvent() - return - - self.__SendChatPacket(text[1:], chat.CHAT_TYPE_GUILD) - self.__ResetChat() - - def __SendShoutChatPacket(self, text): - - if 1 == len(text): - self.RunCloseEvent() - return - - if app.GetTime() < self.lastShoutTime + 15: - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.CHAT_SHOUT_LIMIT) - self.__ResetChat() - return - - self.__SendChatPacket(text[1:], chat.CHAT_TYPE_SHOUT) - self.__ResetChat() - - self.lastShoutTime = app.GetTime() - - def __SendTalkingChatPacket(self, text): - self.__SendChatPacket(text, chat.CHAT_TYPE_TALKING) - self.__ResetChat() - - def OnIMETab(self): - return False - - def OnIMEUpdate(self): - ui.EditLine.OnIMEUpdate(self) - self.__CheckChatMark() - - def __CheckChatMark(self): - - self.overTextLine.Hide() - - text = self.GetText() - if len(text) > 0: - if '#' == text[0]: - self.overTextLine.SetText("#") - self.overTextLine.Show() - elif '%' == text[0]: - self.overTextLine.SetText("%") - self.overTextLine.Show() - elif '!' == text[0]: - self.overTextLine.SetText("!") - self.overTextLine.Show() - - def OnIMEKeyDown(self, key): - # LAST_SENTENCE_STACK - if app.VK_UP == key: - self.__PrevLastSentenceStack() - return True - - if app.VK_DOWN == key: - self.__NextLastSentenceStack() - return True - # END_OF_LAST_SENTENCE_STACK - - ui.EditLine.OnIMEKeyDown(self, key) - - # LAST_SENTENCE_STACK - def __PrevLastSentenceStack(self): - global ENABLE_LAST_SENTENCE_STACK - if not ENABLE_LAST_SENTENCE_STACK: - return - - if self.lastSentenceStack and self.lastSentencePos < len(self.lastSentenceStack): - self.lastSentencePos += 1 - lastSentence = self.lastSentenceStack[-self.lastSentencePos] - self.SetText(lastSentence) - self.SetEndPosition() - - def __NextLastSentenceStack(self): - global ENABLE_LAST_SENTENCE_STACK - if not ENABLE_LAST_SENTENCE_STACK: - return - - if self.lastSentenceStack and self.lastSentencePos > 1: - self.lastSentencePos -= 1 - lastSentence = self.lastSentenceStack[-self.lastSentencePos] - self.SetText(lastSentence) - self.SetEndPosition() - - def __PushLastSentenceStack(self, text): - global ENABLE_LAST_SENTENCE_STACK - if not ENABLE_LAST_SENTENCE_STACK: - return - - if len(text) <= 0: - return - - LAST_SENTENCE_STACK_SIZE = 32 - if len(self.lastSentenceStack) > LAST_SENTENCE_STACK_SIZE: - self.lastSentenceStack.pop(0) - - self.lastSentenceStack.append(text) - # END_OF_LAST_SENTENCE_STACK - - def OnIMEReturn(self): - text = self.GetText() - textLen=len(text) - - # LAST_SENTENCE_STACK - self.__PushLastSentenceStack(text) - # END_OF_LAST_SENTENCE_STACK - - textSpaceCount=text.count(' ') - - if (textLen > 0) and (textLen != textSpaceCount): - if '#' == text[0]: - self.__SendPartyChatPacket(text) - elif '%' == text[0]: - self.__SendGuildChatPacket(text) - elif '!' == text[0]: - self.__SendShoutChatPacket(text) - else: - self.__SendTalkingChatPacket(text) - else: - self.__ClearChat() - self.eventReturn() - - return True - - def OnPressEscapeKey(self): - self.__ClearChat() - self.eventEscape() - return True - - def RunCloseEvent(self): - self.eventEscape() - - def BindInterface(self, interface): - self.interface = interface - - def OnMouseLeftButtonDown(self): - hyperlink = ui.GetHyperlink() - if hyperlink: - if app.IsPressed(app.DIK_LALT): - link = chat.GetLinkFromHyperlink(hyperlink) - ime.PasteString(link) - else: - self.interface.MakeHyperlinkTooltip(hyperlink) - else: - ui.EditLine.OnMouseLeftButtonDown(self) - -class ChatInputSet(ui.Window): - - CHAT_OUTLINE_COLOR = grp.GenerateColor(1.0, 1.0, 1.0, 1.0) - - def __init__(self): - ui.Window.__init__(self) - self.SetWindowName("ChatInputSet") - - InsertChatInputSetWindow(self) - self.__Create() - - def __del__(self): - ui.Window.__del__(self) - - def __Create(self): - chatModeButton = ChatModeButton() - chatModeButton.SetParent(self) - chatModeButton.SetSize(40, 17) - chatModeButton.SetText(localeInfo.CHAT_NORMAL) - chatModeButton.SetPosition(7, 2) - chatModeButton.SAFE_SetEvent(self.OnChangeChatMode) - self.chatModeButton = chatModeButton - - chatLine = ChatLine() - chatLine.SetParent(self) - chatLine.SetMax(512) - chatLine.SetUserMax(76) - chatLine.SetText("") - # Keep cursor on right in RTL UI, left in LTR UI - if app.IsRTL(): - chatLine.SetBaseDirectionRTL() - else: - chatLine.SetBaseDirectionLTR() - chatLine.SAFE_SetTabEvent(self.OnChangeChatMode) - chatLine.x = 0 - chatLine.y = 0 - chatLine.width = 0 - chatLine.height = 0 - self.chatLine = chatLine - - btnSend = ui.Button() - btnSend.SetParent(self) - btnSend.SetUpVisual("d:/ymir work/ui/game/taskbar/Send_Chat_Button_01.sub") - btnSend.SetOverVisual("d:/ymir work/ui/game/taskbar/Send_Chat_Button_02.sub") - btnSend.SetDownVisual("d:/ymir work/ui/game/taskbar/Send_Chat_Button_03.sub") - btnSend.SetToolTipText(localeInfo.CHAT_SEND_CHAT) - btnSend.SAFE_SetEvent(self.chatLine.OnIMEReturn) - self.btnSend = btnSend - - def Destroy(self): - self.chatModeButton = None - self.chatLine = None - self.btnSend = None - - def Open(self): - self.chatLine.Show() - self.chatLine.SetPosition(57, 5) - self.chatLine.SetFocus() - self.chatLine.OpenChat() - - self.chatModeButton.SetPosition(7, 2) - self.chatModeButton.Show() - - self.btnSend.Show() - self.Show() - - self.RefreshPosition() - return True - - def Close(self): - self.chatLine.KillFocus() - self.chatLine.Hide() - self.chatModeButton.Hide() - self.btnSend.Hide() - self.Hide() - return True - - def SetEscapeEvent(self, event): - self.chatLine.SetEscapeEvent(event) - - def SetReturnEvent(self, event): - self.chatLine.SetReturnEvent(event) - - def OnChangeChatMode(self): - RefreshChatMode() - - def OnRefreshChatMode(self): - self.chatLine.ChangeChatMode() - self.chatModeButton.SetText(self.chatLine.GetCurrentChatModeName()) - - def SetChatFocus(self): - self.chatLine.SetFocus() - - def KillChatFocus(self): - self.chatLine.KillFocus() - - def SetChatMax(self, max): - self.chatLine.SetUserMax(max) - - def RefreshPosition(self): - if app.IsRTL(): - self.chatLine.SetSize(self.GetWidth() - 93, 18) - else: - self.chatLine.SetSize(self.GetWidth() - 93, 13) - - self.btnSend.SetPosition(self.GetWidth() - 25, 2) - - (self.chatLine.x, self.chatLine.y, self.chatLine.width, self.chatLine.height) = self.chatLine.GetRect() - - def BindInterface(self, interface): - self.chatLine.BindInterface(interface) - - def OnRender(self): - (x, y, width, height) = self.chatLine.GetRect() - ui.RenderRoundBox(x-4, y-3, width+7, height+4, self.CHAT_OUTLINE_COLOR) - -## ChatWindow -class ChatWindow(ui.Window): - - BOARD_START_COLOR = grp.GenerateColor(0.0, 0.0, 0.0, 0.0) - BOARD_END_COLOR = grp.GenerateColor(0.0, 0.0, 0.0, 0.8) - BOARD_MIDDLE_COLOR = grp.GenerateColor(0.0, 0.0, 0.0, 0.5) - CHAT_OUTLINE_COLOR = grp.GenerateColor(1.0, 1.0, 1.0, 1.0) - - EDIT_LINE_HEIGHT = 25 - CHAT_WINDOW_WIDTH = 600 - - class ChatBackBoard(ui.Window): - def __init__(self): - ui.Window.__init__(self) - def __del__(self): - ui.Window.__del__(self) - - class ChatButton(ui.DragButton): - - def __init__(self): - ui.DragButton.__init__(self) - self.AddFlag("float") - self.AddFlag("movable") - self.AddFlag("restrict_x") - self.topFlag = False - self.SetWindowName("ChatWindow:ChatButton") - - - def __del__(self): - ui.DragButton.__del__(self) - - def SetOwner(self, owner): - self.owner = owner - - def OnMouseOverIn(self): - app.SetCursor(app.VSIZE) - - def OnMouseOverOut(self): - app.SetCursor(app.NORMAL) - - def OnTop(self): - if True == self.topFlag: - return - - self.topFlag = True - self.owner.SetTop() - self.topFlag = False - - def __init__(self): - ui.Window.__init__(self) - self.AddFlag("float") - - self.SetWindowName("ChatWindow") - self.__RegisterChatColorDict() - - self.boardState = chat.BOARD_STATE_VIEW - self.chatID = chat.CreateChatSet(chat.CHAT_SET_CHAT_WINDOW) - chat.SetBoardState(self.chatID, chat.BOARD_STATE_VIEW) - - self.xBar = 0 - self.yBar = 0 - self.widthBar = 0 - self.heightBar = 0 - self.curHeightBar = 0 - self.visibleLineCount = 0 - self.scrollBarPos = 1.0 - self.scrollLock = False - - chatInputSet = ChatInputSet() - chatInputSet.SetParent(self) - chatInputSet.SetEscapeEvent(ui.__mem_func__(self.CloseChat)) - chatInputSet.SetReturnEvent(ui.__mem_func__(self.CloseChat)) - chatInputSet.SetSize(550, 25) - self.chatInputSet = chatInputSet - - btnSendWhisper = ui.Button() - btnSendWhisper.SetParent(self) - btnSendWhisper.SetUpVisual("d:/ymir work/ui/game/taskbar/Send_Whisper_Button_01.sub") - btnSendWhisper.SetOverVisual("d:/ymir work/ui/game/taskbar/Send_Whisper_Button_02.sub") - btnSendWhisper.SetDownVisual("d:/ymir work/ui/game/taskbar/Send_Whisper_Button_03.sub") - btnSendWhisper.SetToolTipText(localeInfo.CHAT_SEND_MEMO) - btnSendWhisper.Hide() - self.btnSendWhisper = btnSendWhisper - - btnChatLog = ui.Button() - btnChatLog.SetParent(self) - btnChatLog.SetUpVisual("d:/ymir work/ui/game/taskbar/Open_Chat_Log_Button_01.sub") - btnChatLog.SetOverVisual("d:/ymir work/ui/game/taskbar/Open_Chat_Log_Button_02.sub") - btnChatLog.SetDownVisual("d:/ymir work/ui/game/taskbar/Open_Chat_Log_Button_03.sub") - btnChatLog.SetToolTipText(localeInfo.CHAT_LOG) - btnChatLog.Hide() - self.btnChatLog = btnChatLog - - btnChatSizing = self.ChatButton() - btnChatSizing.SetOwner(self) - btnChatSizing.SetMoveEvent(ui.__mem_func__(self.Refresh)) - btnChatSizing.Hide() - self.btnChatSizing = btnChatSizing - - imgChatBarLeft = ui.ImageBox() - imgChatBarLeft.SetParent(self.btnChatSizing) - imgChatBarLeft.AddFlag("not_pick") - imgChatBarLeft.LoadImage("d:/ymir work/ui/pattern/chat_bar_left.tga") - imgChatBarLeft.Show() - self.imgChatBarLeft = imgChatBarLeft - imgChatBarRight = ui.ImageBox() - imgChatBarRight.SetParent(self.btnChatSizing) - imgChatBarRight.AddFlag("not_pick") - imgChatBarRight.LoadImage("d:/ymir work/ui/pattern/chat_bar_right.tga") - imgChatBarRight.Show() - self.imgChatBarRight = imgChatBarRight - imgChatBarMiddle = ui.ExpandedImageBox() - imgChatBarMiddle.SetParent(self.btnChatSizing) - imgChatBarMiddle.AddFlag("not_pick") - imgChatBarMiddle.LoadImage("d:/ymir work/ui/pattern/chat_bar_middle.tga") - imgChatBarMiddle.Show() - self.imgChatBarMiddle = imgChatBarMiddle - - scrollBar = ui.ScrollBar() - scrollBar.AddFlag("float") - scrollBar.SetScrollEvent(ui.__mem_func__(self.OnScroll)) - self.scrollBar = scrollBar - - self.Refresh() - self.chatInputSet.RefreshPosition() # RTL 시 위치를 제대로 잡으려면 위치 갱신이 필요하다 - - def __del__(self): - ui.Window.__del__(self) - - def __RegisterChatColorDict(self): - CHAT_COLOR_DICT = { - chat.CHAT_TYPE_TALKING : colorInfo.CHAT_RGB_TALK, - chat.CHAT_TYPE_INFO : colorInfo.CHAT_RGB_INFO, - chat.CHAT_TYPE_NOTICE : colorInfo.CHAT_RGB_NOTICE, - chat.CHAT_TYPE_PARTY : colorInfo.CHAT_RGB_PARTY, - chat.CHAT_TYPE_GUILD : colorInfo.CHAT_RGB_GUILD, - chat.CHAT_TYPE_COMMAND : colorInfo.CHAT_RGB_COMMAND, - chat.CHAT_TYPE_SHOUT : colorInfo.CHAT_RGB_SHOUT, - chat.CHAT_TYPE_WHISPER : colorInfo.CHAT_RGB_WHISPER, - } - - for colorItem in list(CHAT_COLOR_DICT.items()): - type=colorItem[0] - rgb=colorItem[1] - chat.SetChatColor(type, rgb[0], rgb[1], rgb[2]) - - def Destroy(self): - self.chatInputSet.Destroy() - self.chatInputSet = None - - self.btnSendWhisper = 0 - self.btnChatLog = 0 - self.btnChatSizing = 0 - - ################ - ## Open & Close - def OpenChat(self): - self.SetSize(self.CHAT_WINDOW_WIDTH, 25) - chat.SetBoardState(self.chatID, chat.BOARD_STATE_EDIT) - self.boardState = chat.BOARD_STATE_EDIT - - (x, y, width, height) = self.GetRect() - (btnX, btnY) = self.btnChatSizing.GetGlobalPosition() - - if app.IsRTL(): - chat.SetAlign(self.chatID, 1) - chat.SetPosition(self.chatID, x + width - 10, y) - else: - chat.SetAlign(self.chatID, 0) - chat.SetPosition(self.chatID, x + 10, y) - - chat.SetHeight(self.chatID, y - btnY - self.EDIT_LINE_HEIGHT + 100) - - if self.IsShow(): - self.btnChatSizing.Show() - - self.Refresh() - - self.btnSendWhisper.SetPosition(self.GetWidth() - 50, 2) - self.btnSendWhisper.Show() - - self.btnChatLog.SetPosition(self.GetWidth() - 25, 2) - self.btnChatLog.Show() - - self.chatInputSet.Open() - self.chatInputSet.SetTop() - self.SetTop() - - def CloseChat(self): - chat.SetBoardState(self.chatID, chat.BOARD_STATE_VIEW) - self.boardState = chat.BOARD_STATE_VIEW - - (x, y, width, height) = self.GetRect() - - if app.IsRTL(): - chat.SetAlign(self.chatID, 1) - chat.SetPosition(self.chatID, x + width - 10, y + self.EDIT_LINE_HEIGHT) - else: - chat.SetAlign(self.chatID, 0) - chat.SetPosition(self.chatID, x + 10, y + self.EDIT_LINE_HEIGHT) - - self.SetSize(self.CHAT_WINDOW_WIDTH, 0) - - self.chatInputSet.Close() - self.btnSendWhisper.Hide() - self.btnChatLog.Hide() - self.btnChatSizing.Hide() - - self.Refresh() - - def SetSendWhisperEvent(self, event): - self.btnSendWhisper.SetEvent(event) - - def SetOpenChatLogEvent(self, event): - self.btnChatLog.SetEvent(event) - - def IsEditMode(self): - if chat.BOARD_STATE_EDIT == self.boardState: - return True - - return False - - def __RefreshSizingBar(self): - (x, y, width, height) = self.GetRect() - gxChat, gyChat = self.btnChatSizing.GetGlobalPosition() - self.btnChatSizing.SetPosition(x, gyChat) - self.btnChatSizing.SetSize(width, 22) - self.imgChatBarLeft.SetPosition(0, 0) - self.imgChatBarRight.SetPosition(width - 64, 0) - self.imgChatBarMiddle.SetPosition(64, 0) - self.imgChatBarMiddle.SetRenderingRect(0.0, 0.0, float(width - 128) / 64.0 - 1.0, 0.0) - - def SetPosition(self, x, y): - ui.Window.SetPosition(self, x, y) - self.__RefreshSizingBar() - - def SetSize(self, width, height): - ui.Window.SetSize(self, width, height) - self.__RefreshSizingBar() - - def SetHeight(self, height): - gxChat, gyChat = self.btnChatSizing.GetGlobalPosition() - self.btnChatSizing.SetPosition(gxChat, wndMgr.GetScreenHeight() - height) - - ########### - ## Refresh - def Refresh(self): - if self.boardState == chat.BOARD_STATE_EDIT: - self.RefreshBoardEditState() - elif self.boardState == chat.BOARD_STATE_VIEW: - self.RefreshBoardViewState() - - def RefreshBoardEditState(self): - - (x, y, width, height) = self.GetRect() - (btnX, btnY) = self.btnChatSizing.GetGlobalPosition() - - self.xBar = x - self.yBar = btnY - self.widthBar = width - self.heightBar = y - btnY + self.EDIT_LINE_HEIGHT - self.curHeightBar = self.heightBar - - if app.IsRTL(): - chat.SetAlign(self.chatID, 1) - chat.SetPosition(self.chatID, x + width - 10, y) - else: - chat.SetAlign(self.chatID, 0) - chat.SetPosition(self.chatID, x + 10, y) - - chat.SetHeight(self.chatID, y - btnY - self.EDIT_LINE_HEIGHT) - chat.ArrangeShowingChat(self.chatID) - - if btnY > y: - self.btnChatSizing.SetPosition(btnX, y) - self.heightBar = self.EDIT_LINE_HEIGHT - - def RefreshBoardViewState(self): - (x, y, width, height) = self.GetRect() - (btnX, btnY) = self.btnChatSizing.GetGlobalPosition() - textAreaHeight = self.visibleLineCount * chat.GetLineStep(self.chatID) - - if app.IsRTL(): - chat.SetAlign(self.chatID, 1) - chat.SetPosition(self.chatID, x + width - 10, y + self.EDIT_LINE_HEIGHT) - else: - chat.SetAlign(self.chatID, 0) - chat.SetPosition(self.chatID, x + 10, y + self.EDIT_LINE_HEIGHT) - - chat.SetHeight(self.chatID, y - btnY - self.EDIT_LINE_HEIGHT + 100) - - if self.boardState == chat.BOARD_STATE_EDIT: - textAreaHeight += 45 - elif self.visibleLineCount != 0: - textAreaHeight += 10 + 10 - - self.xBar = x - self.yBar = y + self.EDIT_LINE_HEIGHT - textAreaHeight - self.widthBar = width - self.heightBar = textAreaHeight - - self.scrollBar.Hide() - - ########## - ## Render - def OnUpdate(self): - if self.boardState == chat.BOARD_STATE_EDIT: - chat.Update(self.chatID) - elif self.boardState == chat.BOARD_STATE_VIEW: - if systemSetting.IsViewChat(): - chat.Update(self.chatID) - - def OnRender(self): - if chat.GetVisibleLineCount(self.chatID) != self.visibleLineCount: - self.visibleLineCount = chat.GetVisibleLineCount(self.chatID) - self.Refresh() - - if self.curHeightBar != self.heightBar: - self.curHeightBar += (self.heightBar - self.curHeightBar) // 10 - - if self.boardState == chat.BOARD_STATE_EDIT: - grp.SetColor(self.BOARD_MIDDLE_COLOR) - grp.RenderBar(self.xBar, self.yBar + (self.heightBar - self.curHeightBar) + 10, self.widthBar, self.curHeightBar) - chat.Render(self.chatID) - elif self.boardState == chat.BOARD_STATE_VIEW: - if systemSetting.IsViewChat(): - grp.RenderGradationBar(self.xBar, self.yBar + (self.heightBar - self.curHeightBar), self.widthBar, self.curHeightBar, self.BOARD_START_COLOR, self.BOARD_END_COLOR) - chat.Render(self.chatID) - - ########## - ## Event - def OnTop(self): - self.btnChatSizing.SetTop() - self.scrollBar.SetTop() - - def OnScroll(self): - if not self.scrollLock: - self.scrollBarPos = self.scrollBar.GetPos() - - lineCount = chat.GetLineCount(self.chatID) - visibleLineCount = chat.GetVisibleLineCount(self.chatID) - endLine = visibleLineCount + int(float(lineCount - visibleLineCount) * self.scrollBarPos) - - chat.SetEndPos(self.chatID, self.scrollBarPos) - - def OnChangeChatMode(self): - self.chatInputSet.OnChangeChatMode() - - def SetChatFocus(self): - self.chatInputSet.SetChatFocus() - - def BindInterface(self, interface): - self.chatInputSet.BindInterface(interface) - -## ChatLogWindow -class ChatLogWindow(ui.Window): - - BLOCK_WIDTH = 32 - CHAT_MODE_NAME = ( localeInfo.CHAT_NORMAL, localeInfo.CHAT_PARTY, localeInfo.CHAT_GUILD, localeInfo.CHAT_SHOUT, localeInfo.CHAT_INFORMATION, localeInfo.CHAT_NOTICE, ) - CHAT_MODE_INDEX = ( chat.CHAT_TYPE_TALKING, - chat.CHAT_TYPE_PARTY, - chat.CHAT_TYPE_GUILD, - chat.CHAT_TYPE_SHOUT, - chat.CHAT_TYPE_INFO, - chat.CHAT_TYPE_NOTICE, ) - - CHAT_LOG_WINDOW_MINIMUM_WIDTH = 450 - CHAT_LOG_WINDOW_MINIMUM_HEIGHT = 120 - - class ResizeButton(ui.DragButton): - - def __init__(self): - ui.DragButton.__init__(self) - - def __del__(self): - ui.DragButton.__del__(self) - - def OnMouseOverIn(self): - app.SetCursor(app.HVSIZE) - - def OnMouseOverOut(self): - app.SetCursor(app.NORMAL) - - def __init__(self): - - self.allChatMode = True - self.chatInputSet = None - - ui.Window.__init__(self) - self.AddFlag("float") - self.AddFlag("movable") - - self.SetWindowName("ChatLogWindow") - - self.__CreateChatInputSet() - self.__CreateWindow() - self.__CreateButton() - self.__CreateScrollBar() - - self.chatID = chat.CreateChatSet(chat.CHAT_SET_LOG_WINDOW) - chat.SetBoardState(self.chatID, chat.BOARD_STATE_LOG) - for i in self.CHAT_MODE_INDEX: - chat.EnableChatMode(self.chatID, i) - - self.SetPosition(20, 20) - self.SetSize(self.CHAT_LOG_WINDOW_MINIMUM_WIDTH, self.CHAT_LOG_WINDOW_MINIMUM_HEIGHT) - self.btnSizing.SetPosition(self.CHAT_LOG_WINDOW_MINIMUM_WIDTH-self.btnSizing.GetWidth(), self.CHAT_LOG_WINDOW_MINIMUM_HEIGHT-self.btnSizing.GetHeight()+2) - - self.OnResize() - - def __CreateChatInputSet(self): - chatInputSet = ChatInputSet() - chatInputSet.SetParent(self) - chatInputSet.SetEscapeEvent(ui.__mem_func__(self.Close)) - chatInputSet.SetWindowVerticalAlignBottom() - chatInputSet.Open() - self.chatInputSet = chatInputSet - - def __CreateWindow(self): - imgLeft = ui.ImageBox() - imgLeft.AddFlag("not_pick") - imgLeft.SetParent(self) - - imgCenter = ui.ExpandedImageBox() - imgCenter.AddFlag("not_pick") - imgCenter.SetParent(self) - - imgRight = ui.ImageBox() - imgRight.AddFlag("not_pick") - imgRight.SetParent(self) - - if app.IsRTL(): - imgLeft.LoadImage("locale/ae/ui/pattern/titlebar_left.tga") - imgCenter.LoadImage("locale/ae/ui/pattern/titlebar_center.tga") - imgRight.LoadImage("locale/ae/ui/pattern/titlebar_right.tga") - else: - imgLeft.LoadImage("d:/ymir work/ui/pattern/chatlogwindow_titlebar_left.tga") - imgCenter.LoadImage("d:/ymir work/ui/pattern/chatlogwindow_titlebar_middle.tga") - imgRight.LoadImage("d:/ymir work/ui/pattern/chatlogwindow_titlebar_right.tga") - - imgLeft.Show() - imgCenter.Show() - imgRight.Show() - - btnClose = ui.Button() - btnClose.SetParent(self) - btnClose.SetUpVisual("d:/ymir work/ui/public/close_button_01.sub") - btnClose.SetOverVisual("d:/ymir work/ui/public/close_button_02.sub") - btnClose.SetDownVisual("d:/ymir work/ui/public/close_button_03.sub") - btnClose.SetToolTipText(localeInfo.UI_CLOSE, 0, -23) - btnClose.SetEvent(ui.__mem_func__(self.Close)) - btnClose.Show() - - btnSizing = self.ResizeButton() - btnSizing.SetParent(self) - btnSizing.SetMoveEvent(ui.__mem_func__(self.OnResize)) - btnSizing.SetSize(16, 16) - btnSizing.Show() - - titleName = ui.TextLine() - titleName.SetParent(self) - - if app.IsRTL(): - titleName.SetPosition(self.GetWidth()-20, 6) - else: - titleName.SetPosition(20, 6) - - titleName.SetText(localeInfo.CHAT_LOG_TITLE) - titleName.Show() - - self.imgLeft = imgLeft - self.imgCenter = imgCenter - self.imgRight = imgRight - self.btnClose = btnClose - self.btnSizing = btnSizing - self.titleName = titleName - - def __CreateButton(self): - if app.IsRTL(): - bx = 20 - else: - bx = 13 - - btnAll = ui.RadioButton() - btnAll.SetParent(self) - btnAll.SetPosition(bx, 24) - btnAll.SetUpVisual("d:/ymir work/ui/public/xsmall_button_01.sub") - btnAll.SetOverVisual("d:/ymir work/ui/public/xsmall_button_02.sub") - btnAll.SetDownVisual("d:/ymir work/ui/public/xsmall_button_03.sub") - btnAll.SetText(localeInfo.CHAT_ALL) - btnAll.SetEvent(ui.__mem_func__(self.ToggleAllChatMode)) - btnAll.Down() - btnAll.Show() - self.btnAll = btnAll - - x = bx + 48 - i = 0 - self.modeButtonList = [] - for name in self.CHAT_MODE_NAME: - btn = ui.ToggleButton() - btn.SetParent(self) - btn.SetPosition(x, 24) - btn.SetUpVisual("d:/ymir work/ui/public/xsmall_button_01.sub") - btn.SetOverVisual("d:/ymir work/ui/public/xsmall_button_02.sub") - btn.SetDownVisual("d:/ymir work/ui/public/xsmall_button_03.sub") - btn.SetText(name) - btn.Show() - - mode = self.CHAT_MODE_INDEX[i] - btn.SetToggleUpEvent(lambda arg=mode: self.ToggleChatMode(arg)) - btn.SetToggleDownEvent(lambda arg=mode: self.ToggleChatMode(arg)) - self.modeButtonList.append(btn) - - x += 48 - i += 1 - - def __CreateScrollBar(self): - scrollBar = ui.SmallThinScrollBar() - scrollBar.SetParent(self) - scrollBar.Show() - scrollBar.SetScrollEvent(ui.__mem_func__(self.OnScroll)) - self.scrollBar = scrollBar - self.scrollBarPos = 1.0 - - def __del__(self): - ui.Window.__del__(self) - - def Destroy(self): - self.imgLeft = None - self.imgCenter = None - self.imgRight = None - self.btnClose = None - self.btnSizing = None - self.modeButtonList = [] - self.scrollBar = None - self.chatInputSet = None - - def ToggleAllChatMode(self): - if self.allChatMode: - return - - self.allChatMode = True - - for i in self.CHAT_MODE_INDEX: - chat.EnableChatMode(self.chatID, i) - for btn in self.modeButtonList: - btn.SetUp() - - def ToggleChatMode(self, mode): - if self.allChatMode: - self.allChatMode = False - for i in self.CHAT_MODE_INDEX: - chat.DisableChatMode(self.chatID, i) - chat.EnableChatMode(self.chatID, mode) - self.btnAll.SetUp() - - else: - chat.ToggleChatMode(self.chatID, mode) - - def SetSize(self, width, height): - self.imgCenter.SetRenderingRect(0.0, 0.0, float((width - self.BLOCK_WIDTH*2) - self.BLOCK_WIDTH) / self.BLOCK_WIDTH, 0.0) - self.imgCenter.SetPosition(self.BLOCK_WIDTH, 0) - self.imgRight.SetPosition(width - self.BLOCK_WIDTH, 0) - - if app.IsRTL(): - self.titleName.SetPosition(self.GetWidth()-20, 3) - self.btnClose.SetPosition(3, 3) - self.scrollBar.SetPosition(1, 45) - else: - self.btnClose.SetPosition(width - self.btnClose.GetWidth() - 5, 5) - self.scrollBar.SetPosition(width - 15, 45) - - self.scrollBar.SetScrollBarSize(height - 45 - 12) - self.scrollBar.SetPos(self.scrollBarPos) - ui.Window.SetSize(self, width, height) - - def Open(self): - self.OnResize() - self.chatInputSet.SetChatFocus() - self.Show() - - def Close(self): - if self.chatInputSet: - self.chatInputSet.KillChatFocus() - self.Hide() - - def OnResize(self): - x, y = self.btnSizing.GetLocalPosition() - width = self.btnSizing.GetWidth() - height = self.btnSizing.GetHeight() - - if x < self.CHAT_LOG_WINDOW_MINIMUM_WIDTH - width: - self.btnSizing.SetPosition(self.CHAT_LOG_WINDOW_MINIMUM_WIDTH - width, y) - return - if y < self.CHAT_LOG_WINDOW_MINIMUM_HEIGHT - height: - self.btnSizing.SetPosition(x, self.CHAT_LOG_WINDOW_MINIMUM_HEIGHT - height) - return - - self.scrollBar.LockScroll() - self.SetSize(x + width, y + height) - self.scrollBar.UnlockScroll() - - if app.IsRTL(): - self.chatInputSet.SetPosition(20, 25) - else: - self.chatInputSet.SetPosition(0, 25) - - self.chatInputSet.SetSize(self.GetWidth() - 20, 20) - self.chatInputSet.RefreshPosition() - self.chatInputSet.SetChatMax(self.GetWidth() // 8) - - def OnScroll(self): - self.scrollBarPos = self.scrollBar.GetPos() - - lineCount = chat.GetLineCount(self.chatID) - visibleLineCount = chat.GetVisibleLineCount(self.chatID) - endLine = visibleLineCount + int(float(lineCount - visibleLineCount) * self.scrollBarPos) - - chat.SetEndPos(self.chatID, self.scrollBarPos) - - def OnRender(self): - (x, y, width, height) = self.GetRect() - - if app.IsRTL(): - grp.SetColor(0x77000000) - grp.RenderBar(x+2, y+45, 13, height-45) - - grp.SetColor(0x77000000) - grp.RenderBar(x, y, width, height) - grp.SetColor(0x77000000) - grp.RenderBox(x, y, width-2, height) - grp.SetColor(0x77000000) - grp.RenderBox(x+1, y+1, width-2, height) - - grp.SetColor(0xff989898) - grp.RenderLine(x+width-13, y+height-1, 11, -11) - grp.RenderLine(x+width-9, y+height-1, 7, -7) - grp.RenderLine(x+width-5, y+height-1, 3, -3) - else: - grp.SetColor(0x77000000) - grp.RenderBar(x+width-15, y+45, 13, height-45) - - grp.SetColor(0x77000000) - grp.RenderBar(x, y, width, height) - grp.SetColor(0x77000000) - grp.RenderBox(x, y, width-2, height) - grp.SetColor(0x77000000) - grp.RenderBox(x+1, y+1, width-2, height) - - grp.SetColor(0xff989898) - grp.RenderLine(x+width-13, y+height-1, 11, -11) - grp.RenderLine(x+width-9, y+height-1, 7, -7) - grp.RenderLine(x+width-5, y+height-1, 3, -3) - - ##### - - chat.ArrangeShowingChat(self.chatID) - - if app.IsRTL(): - chat.SetAlign(self.chatID, 1) - chat.SetPosition(self.chatID, x + width - 10, y + height - 25) - else: - chat.SetAlign(self.chatID, 0) - chat.SetPosition(self.chatID, x + 10, y + height - 25) - - chat.SetHeight(self.chatID, height - 45 - 25) - chat.Update(self.chatID) - chat.Render(self.chatID) - - def OnPressEscapeKey(self): - self.Close() - return True - - def BindInterface(self, interface): - self.interface = interface - - def OnMouseLeftButtonDown(self): - hyperlink = ui.GetHyperlink() - if hyperlink: - if app.IsPressed(app.DIK_LALT): - link = chat.GetLinkFromHyperlink(hyperlink) - ime.PasteString(link) - else: - self.interface.MakeHyperlinkTooltip(hyperlink) - -ChatLine._RebuildLocaleStrings() -localeInfo.RegisterReloadCallback(ChatLine._RebuildLocaleStrings) diff --git a/tools/root/uicommon.py b/tools/root/uicommon.py deleted file mode 100644 index b700ace6..00000000 --- a/tools/root/uicommon.py +++ /dev/null @@ -1,472 +0,0 @@ -import ui -import localeInfo -import app -import ime -import uiScriptLocale - -class PopupDialog(ui.ScriptWindow): - - def __init__(self): - ui.ScriptWindow.__init__(self) - self.__LoadDialog() - self.acceptEvent = lambda *arg: None - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def __LoadDialog(self): - try: - PythonScriptLoader = ui.PythonScriptLoader() - PythonScriptLoader.LoadScriptFile(self, "UIScript/PopupDialog.py") - - self.board = self.GetChild("board") - self.message = self.GetChild("message") - self.accceptButton = self.GetChild("accept") - self.accceptButton.SetEvent(ui.__mem_func__(self.Close)) - - except: - import exception - exception.Abort("PopupDialog.LoadDialog.BindObject") - - def Open(self): - self.SetCenterPosition() - self.SetTop() - self.Show() - - def Close(self): - self.Hide() - self.acceptEvent() - - def Destroy(self): - self.Close() - self.ClearDictionary() - - def SetWidth(self, width): - height = self.GetHeight() - self.SetSize(width, height) - self.board.SetSize(width, height) - self.SetCenterPosition() - self.UpdateRect() - - def SetText(self, text): - self.message.SetText(text) - - def SetAcceptEvent(self, event): - self.acceptEvent = event - - def SetButtonName(self, name): - self.accceptButton.SetText(name) - - def OnPressEscapeKey(self): - self.Close() - return True - - def OnIMEReturn(self): - self.Close() - return True - -class InputDialog(ui.ScriptWindow): - - def __init__(self): - ui.ScriptWindow.__init__(self) - - self.__CreateDialog() - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def __CreateDialog(self): - - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "uiscript/inputdialog.py") - - getObject = self.GetChild - self.board = getObject("Board") - self.acceptButton = getObject("AcceptButton") - self.cancelButton = getObject("CancelButton") - self.inputSlot = getObject("InputSlot") - self.inputValue = getObject("InputValue") - - def Open(self): - self.inputValue.SetFocus() - self.SetCenterPosition() - self.SetTop() - self.Show() - - def Close(self): - self.ClearDictionary() - self.board = None - self.acceptButton = None - self.cancelButton = None - self.inputSlot = None - self.inputValue = None - self.Hide() - - def SetTitle(self, name): - self.board.SetTitleName(name) - - def SetNumberMode(self): - self.inputValue.SetNumberMode() - - def SetSecretMode(self): - self.inputValue.SetSecret() - - def SetFocus(self): - self.inputValue.SetFocus() - - def SetMaxLength(self, length): - width = length * 6 + 10 - self.SetBoardWidth(max(width + 50, 160)) - self.SetSlotWidth(width) - self.inputValue.SetMax(length) - - def SetSlotWidth(self, width): - self.inputSlot.SetSize(width, self.inputSlot.GetHeight()) - self.inputValue.SetSize(width, self.inputValue.GetHeight()) - if self.IsRTL(): - self.inputValue.SetPosition(self.inputValue.GetWidth(), 0) - - def SetBoardWidth(self, width): - self.SetSize(max(width + 50, 160), self.GetHeight()) - self.board.SetSize(max(width + 50, 160), self.GetHeight()) - if self.IsRTL(): - self.board.SetPosition(self.board.GetWidth(), 0) - self.UpdateRect() - - def SetAcceptEvent(self, event): - self.acceptButton.SetEvent(event) - self.inputValue.OnIMEReturn = event - - def SetCancelEvent(self, event): - self.board.SetCloseEvent(event) - self.cancelButton.SetEvent(event) - self.inputValue.OnPressEscapeKey = event - - def GetText(self): - return self.inputValue.GetText() - -class InputDialogWithDescription(InputDialog): - - def __init__(self): - ui.ScriptWindow.__init__(self) - - self.__CreateDialog() - - def __del__(self): - InputDialog.__del__(self) - - def __CreateDialog(self): - - pyScrLoader = ui.PythonScriptLoader() - if app.IsRTL() : - pyScrLoader.LoadScriptFile(self, uiScriptLocale.LOCALE_UISCRIPT_PATH + "inputdialogwithdescription.py") - else: - pyScrLoader.LoadScriptFile(self, "uiscript/inputdialogwithdescription.py") - - try: - getObject = self.GetChild - self.board = getObject("Board") - self.acceptButton = getObject("AcceptButton") - self.cancelButton = getObject("CancelButton") - self.inputSlot = getObject("InputSlot") - self.inputValue = getObject("InputValue") - self.description = getObject("Description") - - except: - import exception - exception.Abort("InputDialogWithDescription.LoadBoardDialog.BindObject") - - def SetDescription(self, text): - self.description.SetText(text) - -class InputDialogWithDescription2(InputDialog): - - def __init__(self): - ui.ScriptWindow.__init__(self) - - self.__CreateDialog() - - def __del__(self): - InputDialog.__del__(self) - - def __CreateDialog(self): - - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "uiscript/inputdialogwithdescription2.py") - - try: - getObject = self.GetChild - self.board = getObject("Board") - self.acceptButton = getObject("AcceptButton") - self.cancelButton = getObject("CancelButton") - self.inputSlot = getObject("InputSlot") - self.inputValue = getObject("InputValue") - self.description1 = getObject("Description1") - self.description2 = getObject("Description2") - - except: - import exception - exception.Abort("InputDialogWithDescription.LoadBoardDialog.BindObject") - - def SetDescription1(self, text): - self.description1.SetText(text) - - def SetDescription2(self, text): - self.description2.SetText(text) - -class QuestionDialog(ui.ScriptWindow): - # MR-15: Multiline dialog messages - BASE_HEIGHT = 105 - BASE_WIDTH = 340 - BUTTON_Y = 63 - LINE_HEIGHT = 12 - # MR-15: -- END OF -- Multiline dialog messages - - def __init__(self): - ui.ScriptWindow.__init__(self) - self.__CreateDialog() - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def __CreateDialog(self): - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "uiscript/questiondialog.py") - - self.board = self.GetChild("board") - self.textLine = self.GetChild("message") - self.acceptButton = self.GetChild("accept") - self.cancelButton = self.GetChild("cancel") - - def Open(self): - self.SetCenterPosition() - self.SetTop() - self.Show() - - def Close(self): - self.Hide() - - def SetWidth(self, width): - height = self.GetHeight() - self.SetSize(width, height) - self.board.SetSize(width, height) - self.SetCenterPosition() - self.UpdateRect() - - def SAFE_SetAcceptEvent(self, event): - self.acceptButton.SAFE_SetEvent(event) - - def SAFE_SetCancelEvent(self, event): - self.cancelButton.SAFE_SetEvent(event) - - def SetAcceptEvent(self, event): - self.acceptButton.SetEvent(event) - - def SetCancelEvent(self, event): - self.cancelButton.SetEvent(event) - - def SetText(self, text): - self.textLine.SetText(text) - # MR-15: Multiline dialog messages - self.__UpdateLayout() - # MR-15: -- END OF -- Multiline dialog messages - - def SetAcceptText(self, text): - self.acceptButton.SetText(text) - - def SetCancelText(self, text): - self.cancelButton.SetText(text) - - # MR-15: Multiline dialog messages - def __UpdateLayout(self): - extraH = len(self.textLine.extraLines) * self.LINE_HEIGHT - newH = self.BASE_HEIGHT + extraH + 10 - btnY = self.BUTTON_Y + extraH + 10 - - self.SetSize(self.BASE_WIDTH, newH) - self.board.SetSize(self.BASE_WIDTH, newH) - self.acceptButton.SetPosition(-40, btnY) - self.cancelButton.SetPosition(+40, btnY) - self.SetCenterPosition() - self.UpdateRect() - # MR-15: -- END OF -- Multiline dialog messages - - def OnPressEscapeKey(self): - self.Close() - return True - -class QuestionDialog2(QuestionDialog): - # MR-15: Multiline dialog messages - BASE_HEIGHT = 105 - BUTTON_Y = 68 - LINE_HEIGHT = 12 - # MR-15: -- END OF -- Multiline dialog messages - - def __init__(self): - QuestionDialog.__init__(self) - self.__CreateDialog() - - def __del__(self): - QuestionDialog.__del__(self) - - def __CreateDialog(self): - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "uiscript/questiondialog2.py") - - self.board = self.GetChild("board") - self.textLine1 = self.GetChild("message1") - self.textLine2 = self.GetChild("message2") - self.acceptButton = self.GetChild("accept") - self.cancelButton = self.GetChild("cancel") - - # MR-15: Multiline dialog messages - def SetText1(self, text): - self.textLine1.SetText(text) - self.__UpdateLayout() - - def SetText2(self, text): - self.textLine2.SetText(text) - self.__UpdateLayout() - - def __UpdateLayout(self): - # Shift textLine2 down by the number of extra lines in textLine1 - offset = len(self.textLine1.extraLines) * self.LINE_HEIGHT + 2 - - try: - x2, y2 = self.textLine2.GetLocalPosition() - self.textLine2.SetPosition(x2, y2 + offset) - except: - pass - - extraH = (len(self.textLine1.extraLines) + len(self.textLine2.extraLines)) * self.LINE_HEIGHT - newH = self.BASE_HEIGHT + extraH + 10 - btnY = self.BUTTON_Y + extraH + 10 - - self.SetSize(280, newH) - self.board.SetSize(280, newH) - self.acceptButton.SetPosition(-40, btnY) - self.cancelButton.SetPosition(+40, btnY) - self.SetCenterPosition() - self.UpdateRect() - # MR-15: -- END OF -- Multiline dialog messages - -class QuestionDialogWithTimeLimit(QuestionDialog2): - - def __init__(self): - ui.ScriptWindow.__init__(self) - - self.__CreateDialog() - self.endTime = 0 - - def __del__(self): - QuestionDialog2.__del__(self) - - def __CreateDialog(self): - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "uiscript/questiondialog2.py") - - self.board = self.GetChild("board") - self.textLine1 = self.GetChild("message1") - self.textLine2 = self.GetChild("message2") - self.acceptButton = self.GetChild("accept") - self.cancelButton = self.GetChild("cancel") - - def Open(self, msg, timeout): - self.SetCenterPosition() - self.SetTop() - self.Show() - - self.SetText1(msg) - self.endTime = app.GetTime() + timeout - - def OnUpdate(self): - leftTime = max(0, self.endTime - app.GetTime()) - self.SetText2(localeInfo.UI_LEFT_TIME % (leftTime)) - -class MoneyInputDialog(ui.ScriptWindow): - - def __init__(self): - ui.ScriptWindow.__init__(self) - - self.moneyHeaderText = localeInfo.MONEY_INPUT_DIALOG_SELLPRICE - self.__CreateDialog() - self.SetMaxLength(9) - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def __CreateDialog(self): - - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "uiscript/moneyinputdialog.py") - - getObject = self.GetChild - self.board = self.GetChild("board") - self.acceptButton = getObject("AcceptButton") - self.cancelButton = getObject("CancelButton") - self.inputValue = getObject("InputValue") - self.inputValue.SetNumberMode() - self.inputValue.OnIMEUpdate = ui.__mem_func__(self.__OnValueUpdate) - self.moneyText = getObject("MoneyValue") - - def Open(self): - self.inputValue.SetText("") - self.inputValue.SetFocus() - self.__OnValueUpdate() - self.SetCenterPosition() - self.SetTop() - self.Show() - - def Close(self): - self.ClearDictionary() - self.board = None - self.acceptButton = None - self.cancelButton = None - self.inputValue = None - self.Hide() - - def SetTitle(self, name): - self.board.SetTitleName(name) - - def SetFocus(self): - self.inputValue.SetFocus() - - def SetMaxLength(self, length): - length = min(9, length) - self.inputValue.SetMax(length) - - def SetMoneyHeaderText(self, text): - self.moneyHeaderText = text - - def SetAcceptEvent(self, event): - self.acceptButton.SetEvent(event) - self.inputValue.OnIMEReturn = event - - def SetCancelEvent(self, event): - self.board.SetCloseEvent(event) - self.cancelButton.SetEvent(event) - self.inputValue.OnPressEscapeKey = event - - def SetValue(self, value): - value=str(value) - self.inputValue.SetText(value) - self.__OnValueUpdate() - ime.SetCursorPosition(len(value)) - - - def GetText(self): - return self.inputValue.GetText() - - def __OnValueUpdate(self): - ui.EditLine.OnIMEUpdate(self.inputValue) - - text = self.inputValue.GetText() - - money = 0 - if text and text.isdigit(): - try: - money = int(text) - except ValueError: - money = 199999999 - - self.moneyText.SetText(self.moneyHeaderText + localeInfo.NumberToMoneyString(money)) diff --git a/tools/root/uicube.py b/tools/root/uicube.py deleted file mode 100644 index c42c3572..00000000 --- a/tools/root/uicube.py +++ /dev/null @@ -1,601 +0,0 @@ -import ui -import app -import net -import mouseModule -import player -import snd -import localeInfo -import item -import grp -import uiScriptLocale -import uiToolTip - -class CubeResultWindow(ui.ScriptWindow): - def __init__(self): - ui.ScriptWindow.__init__(self) - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def LoadWindow(self): - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "UIScript/CubeResultWindow.py") - except: - import exception - exception.Abort("CubeResultWindow.LoadDialog.LoadScript") - - try: - GetObject=self.GetChild - self.titleBar = GetObject("TitleBar") - self.btnClose = GetObject("CloseButton") - self.cubeSlot = GetObject("CubeSlot") - - except: - import exception - exception.Abort("CubeWindow.LoadDialog.BindObject") - - self.cubeSlot.SetOverInItemEvent(ui.__mem_func__(self.__OnOverInItem)) - self.cubeSlot.SetOverOutItemEvent(ui.__mem_func__(self.__OnOverOutItem)) - self.titleBar.SetCloseEvent(ui.__mem_func__(self.__OnCloseButtonClick)) - self.btnClose.SetEvent(ui.__mem_func__(self.__OnCloseButtonClick)) - self.itemVnum = 0 - - def Destroy(self): - self.ClearDictionary() - self.titleBar = None - self.btnClose = None - self.cubeSlot = None - self.tooltipItem = None - self.itemVnum = 0 - - def SetItemToolTip(self, tooltipItem): - self.tooltipItem = tooltipItem - - def SetCubeResultItem(self, itemVnum, count): - self.itemVnum = itemVnum - - if 0 == count: - count = 1 - - self.cubeSlot.SetItemSlot(0, itemVnum, count) - - def Open(self): - self.Show() - - def Close(self): - self.Hide() - - def __OnCloseButtonClick(self): - self.Close() - - def __OnOverInItem(self, slotIndex): - if self.tooltipItem: - if 0 != self.itemVnum: - self.tooltipItem.SetItemToolTip(self.itemVnum) - - def __OnOverOutItem(self): - if self.tooltipItem: - self.tooltipItem.HideToolTip() - - def OnPressEscapeKey(self): - if 0 != self.eventClose: - self.eventClose() - return True - - -class CubeWindow(ui.ScriptWindow): - - def __init__(self): - ui.ScriptWindow.__init__(self) - self.xShopStart = 0 - self.yShopStart = 0 - self.isUsable = False - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def LoadWindow(self): - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "UIScript/CubeWindow.py") - - except: - import exception - exception.Abort("CubeWindow.LoadDialog.LoadScript") - - try: - GetObject=self.GetChild - if app.IsRTL(): - self.board = GetObject("board") - self.board.SetScale(-1.0, 1.0) - self.board.SetRenderingRect(-1.0, 0.0, 1.0, 0.0) - - self.titleBar = GetObject("TitleBar") - self.btnAccept = GetObject("AcceptButton") - self.btnCancel = GetObject("CancelButton") - self.cubeSlot = GetObject("CubeSlot") - self.needMoney = GetObject("NeedMoney") - self.contentScrollbar = GetObject("contentScrollbar") - self.resultSlots = [GetObject("result1"), GetObject("result2"), GetObject("result3")] - self.materialSlots = [ - [GetObject("material11"), GetObject("material12"), GetObject("material13"), GetObject("material14"), GetObject("material15")], - [GetObject("material21"), GetObject("material22"), GetObject("material23"), GetObject("material24"), GetObject("material25")], - [GetObject("material31"), GetObject("material32"), GetObject("material33"), GetObject("material34"), GetObject("material35")], - ] - - - row = 0 - for materialRow in self.materialSlots: - j = 0 - for material in materialRow: - material.SetOverInItemEvent(lambda trash = 0, rowIndex = row, col = j: self.__OverInMaterialSlot(trash, rowIndex, col)) - material.SetSelectItemSlotEvent(lambda trash = 0, rowIndex = row, col = j: self.__OnSelectMaterialSlot(trash, rowIndex, col)) - material.SetOverOutItemEvent(lambda : self.__OverOutMaterialSlot()) - j = j + 1 - row = row + 1 - - row = 0 - for resultSlot in self.resultSlots: - resultSlot.SetOverInItemEvent(lambda trash = 0, rowIndex = row: self.__OverInCubeResultSlot(trash, rowIndex)) - resultSlot.SetOverOutItemEvent(lambda : self.__OverOutMaterialSlot()) - row = row + 1 - - - - except: - import exception - exception.Abort("CubeWindow.LoadDialog.BindObject") - - self.contentScrollbar.SetScrollStep(0.15) - self.contentScrollbar.SetScrollEvent(ui.__mem_func__(self.OnScrollResultList)) - self.cubeSlot.SetSelectEmptySlotEvent(ui.__mem_func__(self.__OnSelectEmptySlot)) - self.cubeSlot.SetSelectItemSlotEvent(ui.__mem_func__(self.__OnSelectItemSlot)) - self.cubeSlot.SetOverInItemEvent(ui.__mem_func__(self.__OnOverInItem)) - self.cubeSlot.SetOverOutItemEvent(ui.__mem_func__(self.__OnOverOutItem)) - - self.titleBar.SetCloseEvent(ui.__mem_func__(self.__OnCloseButtonClick)) - self.btnCancel.SetEvent(ui.__mem_func__(self.__OnCloseButtonClick)) - self.btnAccept.SetEvent(ui.__mem_func__(self.__OnAcceptButtonClick)) - - self.cubeItemInfo = {} - self.cubeResultInfos = [] - self.cubeMaterialInfos = {} - - self.tooltipItem = None - - self.firstSlotIndex = 0 - self.RESULT_SLOT_COUNT = len(self.resultSlots) - self.SLOT_SIZEX = 32 - self.SLOT_SIZEY = 32 - self.CUBE_SLOT_COUNTX = 8 - self.CUBE_SLOT_COUNTY = 3 - - def SetItemToolTip(self, itemTooltip): - self.tooltipItem = itemTooltip - - def GetResultCount(self): - return len(self.cubeResultInfos) - - def OnScrollResultList(self): - count = self.GetResultCount() - scrollLineCount = max(0, count - self.RESULT_SLOT_COUNT) - startIndex = int(scrollLineCount * self.contentScrollbar.GetPos()) - - if startIndex != self.firstSlotIndex: - self.firstSlotIndex = startIndex - self.Refresh() - - def AddCubeResultItem(self, itemVnum, count): - self.cubeResultInfos.append((itemVnum, count)) - #self.Refresh() - - def AddMaterialInfo(self, itemIndex, orderIndex, itemVnum, itemCount): - if itemIndex not in self.cubeMaterialInfos: - self.cubeMaterialInfos[itemIndex] = [[], [], [], [], []] - - self.cubeMaterialInfos[itemIndex][orderIndex].append((itemVnum, itemCount)) - #print "AddMaterialInfo", itemIndex, orderIndex, itemVnum, itemCount, self.cubeMaterialInfos - - def ClearCubeResultItem(self): - self.cubeResultInfos = [] - self.Refresh() - - def Destroy(self): - self.ClearDictionary() - - self.titleBar = None - self.btnAccept = None - self.btnCancel = None - self.cubeSlot = None - self.tooltipItem = None - self.needMoney = None - - def __OverOutMaterialSlot(self): - self.tooltipItem.SetCannotUseItemForceSetDisableColor(True) - self.tooltipItem.HideToolTip() - - def __OverInCubeResultSlot(self, trash, resultIndex): - self.tooltipItem.ClearToolTip() - self.tooltipItem.SetCannotUseItemForceSetDisableColor(True) - - metinSlot = [] - for i in range(player.METIN_SOCKET_MAX_NUM): - metinSlot.append(0) - attrSlot = [] - for i in range(player.ATTRIBUTE_SLOT_MAX_NUM): - attrSlot.append((0, 0)) - - #print "resultIndex, firstSlotIndex", resultIndex, self.firstSlotIndex - - resultIndex = resultIndex + self.firstSlotIndex - itemVnum, itemCount = self.cubeResultInfos[resultIndex] - - self.tooltipItem.AddItemData(itemVnum, metinSlot, attrSlot) - - - # Click material to find and register item from inventory. - def __OnSelectMaterialSlot(self, trash, resultIndex, materialIndex): - resultIndex = resultIndex + self.firstSlotIndex - if resultIndex not in self.cubeMaterialInfos: - return - - materialInfo = self.cubeMaterialInfos[resultIndex] - materialCount = len(materialInfo[materialIndex]) - - if 0 == materialCount: - return - - for itemVnum, itemCount in materialInfo[materialIndex]: - bAddedNow = False # Was item added by this click? - item.SelectItem(itemVnum) - itemSizeX, itemSizeY = item.GetItemSize() - - # Do you have enough materials for crafting? - if player.GetItemCountByVnum(itemVnum) >= itemCount: - for i in range(player.INVENTORY_SLOT_COUNT): - vnum = player.GetItemIndex(i) - count= player.GetItemCount(i) - - if vnum == itemVnum and count >= itemCount: - # Check if same item already registered, add if not - bAlreadyExists = False - for slotPos, invenPos in list(self.cubeItemInfo.items()): - if invenPos == i: - bAlreadyExists = True - - if True == bAlreadyExists: - continue #continue inventory iterating - - #print "Cube Status : ", self.cubeItemInfo - - # If entered here, item not registered in cube, so add to empty cube slot - bCanAddSlot = False - for slotPos in range(self.cubeSlot.GetSlotCount()): - # Is this cube slot empty? - if not slotPos in self.cubeItemInfo: - upperColumnItemSizeY = -1 - currentSlotLine = int(slotPos / self.CUBE_SLOT_COUNTX) - cubeColumn = int(slotPos % self.CUBE_SLOT_COUNTX) - - - # If 3-slot item registered in cube, skip this column entirely - if cubeColumn in self.cubeItemInfo: - columnVNUM = player.GetItemIndex(self.cubeItemInfo[cubeColumn]) - item.SelectItem(columnVNUM) - columnItemSizeX, columnItemSizeY = item.GetItemSize() - - if 3 == columnItemSizeY: - continue #continue cube slot iterating - - if 0 < currentSlotLine and slotPos - self.CUBE_SLOT_COUNTX in self.cubeItemInfo: - upperColumnVNUM = player.GetItemIndex(self.cubeItemInfo[slotPos - self.CUBE_SLOT_COUNTX]) - item.SelectItem(upperColumnVNUM) - columnItemSizeX, upperColumnItemSizeY = item.GetItemSize() - - # 1-slot items must have 1-slot item directly above - if 1 == itemSizeY: - if 0 == currentSlotLine: - bCanAddSlot = True - elif 1 == currentSlotLine and 1 == upperColumnItemSizeY: - bCanAddSlot = True - elif 2 == currentSlotLine: - bCanAddSlot = True - # 2-slot items must have empty spaces above and below - elif 2 == itemSizeY: - if 0 == currentSlotLine and not cubeColumn + self.CUBE_SLOT_COUNTX in self.cubeItemInfo: - bCanAddSlot = True - elif 1 == currentSlotLine and 1 == upperColumnItemSizeY and not cubeColumn + (self.CUBE_SLOT_COUNTX * 2) in self.cubeItemInfo: - bCanAddSlot = True - # 3-slot items require entire column to be empty - else: - if not cubeColumn in self.cubeItemInfo and not cubeColumn + self.CUBE_SLOT_COUNTX in self.cubeItemInfo and not cubeColumn + (self.CUBE_SLOT_COUNTX * 2) in self.cubeItemInfo: - bCanAddSlot = True - - if True == bCanAddSlot: - self.cubeItemInfo[slotPos] = i - self.cubeSlot.SetItemSlot(slotPos, vnum, count) - net.SendChatPacket("/cube add %d %d" % (slotPos, i)) - - bAddedNow = True - - if True == bAddedNow: - break #break cube slot iterating - - if True == bAddedNow: - break #break inventory iterating - - if True == bAddedNow: - break #break material iterating - - - - def __OverInMaterialSlot(self, trash, resultIndex, col): - self.tooltipItem.ClearToolTip() - self.tooltipItem.SetCannotUseItemForceSetDisableColor(False) - - resultIndex = resultIndex + self.firstSlotIndex - - if resultIndex not in self.cubeMaterialInfos: - return - - i = 0 - materialInfo = self.cubeMaterialInfos[resultIndex] - materialCount = len(materialInfo[col]) - - for itemVnum, count in materialInfo[col]: - item.SelectItem(itemVnum) - if player.GetItemCountByVnum(itemVnum) >= count: - self.tooltipItem.AppendTextLine("%s" % (item.GetItemName()), grp.GenerateColor(0.5411, 0.7254, 0.5568, 1.0)).SetFeather() - else: - self.tooltipItem.AppendTextLine("%s" % (item.GetItemName()), grp.GenerateColor(0.9, 0.4745, 0.4627, 1.0)).SetFeather() - - if i < materialCount - 1: - self.tooltipItem.AppendTextLine(uiScriptLocale.CUBE_REQUIRE_MATERIAL_OR) - - i = i + 1 - - self.tooltipItem.Show() - - - def Open(self): - self.cubeItemInfo = {} - self.cubeResultInfos = [] - self.cubeMaterialInfos = {} - - self.Refresh() - self.Show() - - self.isUsable = True - (self.xShopStart, self.yShopStart, z) = player.GetMainCharacterPosition() - - def UpdateInfo(self, gold, itemVnum, count): - if self.needMoney: - self.needMoney.SetText(localeInfo.NumberToMoneyString(gold)) - - self.Refresh() - - def OnPressEscapeKey(self): - self.__OnCloseButtonClick() - return True - - def Close(self): - if self.tooltipItem: - self.tooltipItem.HideToolTip() - - self.Hide() - self.cubeItemInfo = {} - self.cubeMaterialInfos = {} - self.cubeResultInfos = {} - self.firstSlotIndex = 0 - self.contentScrollbar.SetPos(0) - - if self.needMoney: - self.needMoney.SetText("0") - - def Clear(self): - self.Refresh() - - def Refresh(self): - for slotPos in range(self.cubeSlot.GetSlotCount()): - - if not slotPos in self.cubeItemInfo: - self.cubeSlot.ClearSlot(slotPos) - continue - - invenPos = self.cubeItemInfo[slotPos] - itemCount = player.GetItemCount(invenPos) - if itemCount > 0: - self.cubeSlot.SetItemSlot(slotPos, player.GetItemIndex(invenPos), itemCount) - else: - del self.cubeItemInfo[slotPos] - self.cubeSlot.ClearSlot(slotPos) - - i = 0 - for itemVnum, count in self.cubeResultInfos[self.firstSlotIndex:]: - currentSlot = self.resultSlots[i] - - item.SelectItem(itemVnum) - - currentSlot.SetItemSlot(0, itemVnum, count) - currentSlot.Show() - - # Center Align - item.SelectItem(itemVnum) - sizeX, sizeY = item.GetItemSize() - localX, localY = currentSlot.GetLocalPosition() - - currentSlot.SetSize(self.SLOT_SIZEX, self.SLOT_SIZEY * sizeY) - - adjustLocalY = 0 - if sizeY < 3: - adjustLocalY = int(32 / sizeY) - - currentSlot.SetPosition(localX, 0 + adjustLocalY) - - i = i + 1 - if 3 <= i: - break - - #print "self.cubeMaterialInfos : ", self.cubeMaterialInfos - if self.firstSlotIndex in self.cubeMaterialInfos: - for i in range(self.RESULT_SLOT_COUNT): - materialList = self.cubeMaterialInfos[self.firstSlotIndex + i] - #print "Refresh ::: ", materialList - j = 0 - for materialInfo in materialList: - if 0 < len(materialInfo): - currentSlot = self.materialSlots[i][j] - itemVnum, itemCount = materialInfo[0] - currentSlot.SetItemSlot(0, itemVnum, itemCount) - j = j + 1 - - # Center Align - item.SelectItem(itemVnum) - sizeX, sizeY = item.GetItemSize() - localX, localY = currentSlot.GetLocalPosition() - - currentSlot.SetSize(self.SLOT_SIZEX, self.SLOT_SIZEY * sizeY) - - adjustLocalY = 0 - if sizeY < 3: - adjustLocalY = int(32 / sizeY) - - currentSlot.SetPosition(localX, 0 + adjustLocalY) - - for k in range(5): - if k >= j: - self.materialSlots[i][k].ClearSlot(0) - - if self.RESULT_SLOT_COUNT <= i: - break - - self.cubeSlot.RefreshSlot() - - def __OnCloseButtonClick(self): - if self.isUsable: - self.isUsable = False - - print("Close cube") - net.SendChatPacket("/cube close") - - self.Close() - - def __OnAcceptButtonClick(self): - if len(self.cubeItemInfo) == 0: - "Empty cube" - return - - print("Start cube crafting") - #for invenPos in self.cubeItemInfo.values(): - # net.SendChatPacket("/cube add " + str(invenPos)) - net.SendChatPacket("/cube make") - - def __OnSelectEmptySlot(self, selectedSlotPos): - - isAttached = mouseModule.mouseController.isAttached() - if isAttached: - attachedSlotType = mouseModule.mouseController.GetAttachedType() - attachedSlotPos = mouseModule.mouseController.GetAttachedSlotNumber() - mouseModule.mouseController.DeattachObject() - - if player.SLOT_TYPE_INVENTORY != attachedSlotType: - return - - for slotPos, invenPos in list(self.cubeItemInfo.items()): - if invenPos == attachedSlotPos: - del self.cubeItemInfo[slotPos] - - self.cubeItemInfo[selectedSlotPos] = attachedSlotPos - net.SendChatPacket("/cube add %d %d" % (selectedSlotPos, attachedSlotPos)) - - self.Refresh() - - def __OnSelectItemSlot(self, selectedSlotPos): - - isAttached = mouseModule.mouseController.isAttached() - if isAttached: - snd.PlaySound("sound/ui/loginfail.wav") - mouseModule.mouseController.DeattachObject() - - else: - if not selectedSlotPos in self.cubeItemInfo: - return - - snd.PlaySound("sound/ui/drop.wav") - - net.SendChatPacket("/cube del %d " % selectedSlotPos) - del self.cubeItemInfo[selectedSlotPos] - - self.Refresh() - - def __OnOverInItem(self, slotIndex): - if self.tooltipItem: - if slotIndex in self.cubeItemInfo: - self.tooltipItem.SetInventoryItem(self.cubeItemInfo[slotIndex]) - - def __OnOverOutItem(self): - if self.tooltipItem: - self.tooltipItem.HideToolTip() - - def OnUpdate(self): - USE_SHOP_LIMIT_RANGE = 1000 - - (x, y, z) = player.GetMainCharacterPosition() - if abs(x - self.xShopStart) > USE_SHOP_LIMIT_RANGE or abs(y - self.yShopStart) > USE_SHOP_LIMIT_RANGE: - self.__OnCloseButtonClick() - -if __name__ == "__main__": - - import app - import wndMgr - import systemSetting - import mouseModule - import grp - import ui - import uiToolTip - import localeInfo - - app.SetMouseHandler(mouseModule.mouseController) - app.SetHairColorEnable(True) - wndMgr.SetMouseHandler(mouseModule.mouseController) - wndMgr.SetScreenSize(systemSetting.GetWidth(), systemSetting.GetHeight()) - app.Create(localeInfo.APP_TITLE, systemSetting.GetWidth(), systemSetting.GetHeight(), 1) - mouseModule.mouseController.Create() - - class TestGame(ui.Window): - def __init__(self): - ui.Window.__init__(self) - - localeInfo.LoadLocaleData() - - self.tooltipItem = uiToolTip.ItemToolTip() - self.tooltipItem.Hide() - - self.cubeWindow = CubeWindow() - self.cubeWindow.LoadWindow() - self.cubeWindow.SetItemToolTip(self.tooltipItem) - self.cubeWindow.Open() - - self.cubeResultWindow = CubeResultWindow() - self.cubeResultWindow.LoadWindow() - self.cubeResultWindow.SetItemToolTip(self.tooltipItem) - self.cubeResultWindow.SetCubeResultItem(27001, 1) - self.cubeResultWindow.Open() - - def __del__(self): - ui.Window.__del__(self) - - def OnUpdate(self): - app.UpdateGame() - - def OnRender(self): - app.RenderGame() - grp.PopState() - grp.SetInterfaceRenderState() - - game = TestGame() - game.SetSize(systemSetting.GetWidth(), systemSetting.GetHeight()) - game.Show() - - app.Loop() diff --git a/tools/root/uidragonsoul.py b/tools/root/uidragonsoul.py deleted file mode 100644 index f355d3c8..00000000 --- a/tools/root/uidragonsoul.py +++ /dev/null @@ -1,1534 +0,0 @@ -import ui -import player -import mouseModule -import net -import app -import snd -import item -import chat -import grp -import uiScriptLocale -import uiRefine -import uiAttachMetin -import uiPickMoney -import uiCommon -import uiPrivateShopBuilder -import localeInfo -import constInfo -import ime -import uiInventory -import sys -ITEM_FLAG_APPLICABLE = 1 << 14 - -# Dragon soul Vnum comments -# If ITEM VNUM from 100,000s digit is represented as FEDCBA -# FE: Dragon soul type D: Grade -# C: Step B: Strength -# A: Reserved numbers - -class DragonSoulWindow(ui.ScriptWindow): - KIND_TAP_TITLES = [uiScriptLocale.DRAGONSOUL_TAP_TITLE_1, uiScriptLocale.DRAGONSOUL_TAP_TITLE_2, - uiScriptLocale.DRAGONSOUL_TAP_TITLE_3, uiScriptLocale.DRAGONSOUL_TAP_TITLE_4, uiScriptLocale.DRAGONSOUL_TAP_TITLE_5, uiScriptLocale.DRAGONSOUL_TAP_TITLE_6] - def __init__(self): - ui.ScriptWindow.__init__(self) - self.questionDialog = None - self.tooltipItem = None - self.sellingSlotNumber = -1 - self.isLoaded = 0 - self.isActivated = False - self.DSKindIndex = 0 - self.tabDict = None - self.tabButtonDict = None - self.deckPageIndex = 0 - self.inventoryPageIndex = 0 - self.SetWindowName("DragonSoulWindow") - self.__LoadWindow() - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def Show(self): - self.__LoadWindow() - - ui.ScriptWindow.Show(self) - def __LoadWindow(self): - if self.isLoaded == 1: - return - self.isLoaded = 1 - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "UIScript/dragonsoulwindow.py") - - except: - import exception - exception.Abort("dragonsoulwindow.LoadWindow.LoadObject") - try: - if app.IsRTL(): - self.board = self.GetChild("Equipment_Base") - self.board.SetScale(-1.0, 1.0) - self.board.SetRenderingRect(-1.0, 0.0, 1.0, 0.0) - self.board = self.GetChild("Tab_01") - self.board.SetScale(-1.0, 1.0) - self.board.SetRenderingRect(-1.0, 0.0, 1.0, 0.0) - self.board = self.GetChild("Tab_02") - self.board.SetScale(-1.0, 1.0) - self.board.SetRenderingRect(-1.0, 0.0, 1.0, 0.0) - self.board = self.GetChild("Tab_03") - self.board.SetScale(-1.0, 1.0) - self.board.SetRenderingRect(-1.0, 0.0, 1.0, 0.0) - self.board = self.GetChild("Tab_04") - self.board.SetScale(-1.0, 1.0) - self.board.SetRenderingRect(-1.0, 0.0, 1.0, 0.0) - self.board = self.GetChild("Tab_05") - self.board.SetScale(-1.0, 1.0) - self.board.SetRenderingRect(-1.0, 0.0, 1.0, 0.0) - self.board = self.GetChild("Tab_06") - self.board.SetScale(-1.0, 1.0) - self.board.SetRenderingRect(-1.0, 0.0, 1.0, 0.0) - - wndItem = self.GetChild("ItemSlot") - wndEquip = self.GetChild("EquipmentSlot") - self.activateButton = self.GetChild("activate") - self.deckTab = [] - self.deckTab.append(self.GetChild("deck1")) - self.deckTab.append(self.GetChild("deck2")) - self.GetChild("TitleBar").SetCloseEvent(ui.__mem_func__(self.Close)) - self.inventoryTab = [] - self.inventoryTab.append(self.GetChild("Inventory_Tab_01")) - self.inventoryTab.append(self.GetChild("Inventory_Tab_02")) - self.inventoryTab.append(self.GetChild("Inventory_Tab_03")) - self.inventoryTab.append(self.GetChild("Inventory_Tab_04")) - self.inventoryTab.append(self.GetChild("Inventory_Tab_05")) - self.tabDict = { - 0 : self.GetChild("Tab_01"), - 1 : self.GetChild("Tab_02"), - 2 : self.GetChild("Tab_03"), - 3 : self.GetChild("Tab_04"), - 4 : self.GetChild("Tab_05"), - 5 : self.GetChild("Tab_06"), - } - self.tabButtonDict = { - 0 : self.GetChild("Tab_Button_01"), - 1 : self.GetChild("Tab_Button_02"), - 2 : self.GetChild("Tab_Button_03"), - 3 : self.GetChild("Tab_Button_04"), - 4 : self.GetChild("Tab_Button_05"), - 5 : self.GetChild("Tab_Button_06"), - } - self.tabText = self.GetChild("tab_text_area") - except: - import exception - exception.Abort("InventoryWindow.LoadWindow.BindObject") - ## DragonSoul Kind Tap - for (tabKey, tabButton) in list(self.tabButtonDict.items()): - tabButton.SetEvent(ui.__mem_func__(self.SetDSKindIndex), tabKey) - ## Item - wndItem.SetOverInItemEvent(ui.__mem_func__(self.OverInItem)) - wndItem.SetOverOutItemEvent(ui.__mem_func__(self.OverOutItem)) - wndItem.SetSelectItemSlotEvent(ui.__mem_func__(self.SelectItemSlot)) - wndItem.SetSelectEmptySlotEvent(ui.__mem_func__(self.SelectEmptySlot)) - wndItem.SetUnselectItemSlotEvent(ui.__mem_func__(self.UseItemSlot)) - wndItem.SetUseSlotEvent(ui.__mem_func__(self.UseItemSlot)) - - ## Equipment - wndEquip.SetSelectEmptySlotEvent(ui.__mem_func__(self.SelectEmptyEquipSlot)) - wndEquip.SetSelectItemSlotEvent(ui.__mem_func__(self.SelectEquipItemSlot)) - wndEquip.SetUnselectItemSlotEvent(ui.__mem_func__(self.UseEquipItemSlot)) - wndEquip.SetUseSlotEvent(ui.__mem_func__(self.UseEquipItemSlot)) - wndEquip.SetOverInItemEvent(ui.__mem_func__(self.OverInEquipItem)) - wndEquip.SetOverOutItemEvent(ui.__mem_func__(self.OverOutEquipItem)) - - ## Deck - self.deckTab[0].SetToggleDownEvent(lambda arg=0: self.SetDeckPage(arg)) - self.deckTab[1].SetToggleDownEvent(lambda arg=1: self.SetDeckPage(arg)) - self.deckTab[0].SetToggleUpEvent(lambda arg=0: self.__DeckButtonDown(arg)) - self.deckTab[1].SetToggleUpEvent(lambda arg=1: self.__DeckButtonDown(arg)) - self.deckTab[0].Down() - ## Grade button - self.inventoryTab[0].SetEvent(lambda arg=0: self.SetInventoryPage(arg)) - self.inventoryTab[1].SetEvent(lambda arg=1: self.SetInventoryPage(arg)) - self.inventoryTab[2].SetEvent(lambda arg=2: self.SetInventoryPage(arg)) - self.inventoryTab[3].SetEvent(lambda arg=3: self.SetInventoryPage(arg)) - self.inventoryTab[4].SetEvent(lambda arg=4: self.SetInventoryPage(arg)) - self.inventoryTab[0].Down() - ## Etc - self.wndItem = wndItem - self.wndEquip = wndEquip - - self.dlgQuestion = uiCommon.QuestionDialog2() - self.dlgQuestion.Close() - - self.activateButton.SetToggleDownEvent(ui.__mem_func__(self.ActivateButtonClick)) - self.activateButton.SetToggleUpEvent(ui.__mem_func__(self.ActivateButtonClick)) - self.wndPopupDialog = uiCommon.PopupDialog() - - ## - self.listHighlightedSlot = [] - - ## Refresh - self.SetInventoryPage(0) - self.RefreshItemSlot() - self.RefreshEquipSlotWindow() - self.RefreshBagSlotWindow() - self.SetDSKindIndex(0) - self.activateButton.Enable() - self.deckTab[self.deckPageIndex].Down() - self.activateButton.SetUp() - - def Destroy(self): - self.ClearDictionary() - self.tooltipItem = None - self.wndItem = 0 - self.wndEquip = 0 - self.activateButton = 0 - self.questionDialog = None - self.mallButton = None - self.inventoryTab = [] - self.deckTab = [] - self.equipmentTab = [] - self.tabDict = None - self.tabButtonDict = None - - def Close(self): - if None != self.tooltipItem: - self.tooltipItem.HideToolTip() - - self.Hide() - - def __DeckButtonDown(self, deck): - self.deckTab[deck].Down() - - def SetInventoryPage(self, page): - if self.inventoryPageIndex != page: - self.__HighlightSlot_ClearCurrentPage() - - self.inventoryPageIndex = page - - self.inventoryTab[(page + 1) % 5].SetUp() - self.inventoryTab[(page + 2) % 5].SetUp() - self.inventoryTab[(page + 3) % 5].SetUp() - self.inventoryTab[(page + 4) % 5].SetUp() - - self.RefreshBagSlotWindow() - - def SetItemToolTip(self, tooltipItem): - self.tooltipItem = tooltipItem - - if tooltipItem: - tooltipItem.SetDragonSoulWindow(self) - - # MR-11: Fix Dragon stones timer auto-start - if self.isActivated: - self.__WarmDragonSoulTimeCache() - # MR-11: -- END OF -- Fix Dragon stones timer auto-start - - def RefreshItemSlot(self): - self.RefreshBagSlotWindow() - self.RefreshEquipSlotWindow() - - def RefreshEquipSlotWindow(self): - for i in range(6): - slotNumber = self.__InventoryLocalSlotPosToGlobalSlotPos(player.INVENTORY, player.DRAGON_SOUL_EQUIPMENT_SLOT_START + i) - itemVnum = player.GetItemIndex(slotNumber) - self.wndEquip.SetItemSlot(player.DRAGON_SOUL_EQUIPMENT_SLOT_START + i, itemVnum, 0) - self.wndEquip.EnableSlot(player.DRAGON_SOUL_EQUIPMENT_SLOT_START + i) - - if itemVnum != 0: - item.SelectItem(itemVnum) - for j in range(item.LIMIT_MAX_NUM): - (limitType, limitValue) = item.GetLimit(j) - - # Initialize to arbitrary positive number since we check if remain_time <= 0 below - remain_time = 999 - # Currently only these three timers exist - if item.LIMIT_REAL_TIME == limitType: - remain_time = player.GetItemMetinSocket(player.INVENTORY, slotNumber, 0) - app.GetGlobalTimeStamp() - elif item.LIMIT_REAL_TIME_START_FIRST_USE == limitType: - remain_time = player.GetItemMetinSocket(player.INVENTORY, slotNumber, 0) - app.GetGlobalTimeStamp() - elif item.LIMIT_TIMER_BASED_ON_WEAR == limitType: - remain_time = player.GetItemMetinSocket(player.INVENTORY, slotNumber, 0) - - if remain_time <= 0: - self.wndEquip.DisableSlot(player.DRAGON_SOUL_EQUIPMENT_SLOT_START + i) - break - - self.wndEquip.RefreshSlot() - - # MR-17: Improve slot activation for active Dragon Soul deck - if self.isActivated: - self.ActivateEquipSlotWindow(self.deckPageIndex) - # MR-17: -- END OF -- Improve slot activation for active Dragon Soul deck - - # MR-17: Improve slot activation for active Dragon Soul deck - def ActivateEquipSlotWindow(self, deck): - for i in range(6): - slotNumber = player.DRAGON_SOUL_EQUIPMENT_SLOT_START + deck * player.DRAGON_SOUL_EQUIPMENT_FIRST_SIZE + i - itemVnum = player.GetItemIndex(slotNumber) - - if itemVnum == 0: - continue - - item.SelectItem(itemVnum) - remain_time = 999 - - for j in range(item.LIMIT_MAX_NUM): - (limitType, limitValue) = item.GetLimit(j) - if item.LIMIT_REAL_TIME == limitType: - remain_time = player.GetItemMetinSocket(player.INVENTORY, slotNumber, 0) - app.GetGlobalTimeStamp() - elif item.LIMIT_REAL_TIME_START_FIRST_USE == limitType: - remain_time = player.GetItemMetinSocket(player.INVENTORY, slotNumber, 0) - app.GetGlobalTimeStamp() - elif item.LIMIT_TIMER_BASED_ON_WEAR == limitType: - remain_time = player.GetItemMetinSocket(player.INVENTORY, slotNumber, 0) - if remain_time <= 0: - break - - if remain_time > 0: - self.wndEquip.ActivateSlot(player.DRAGON_SOUL_EQUIPMENT_SLOT_START + i) - # MR-17: -- END OF -- Improve slot activation for active Dragon Soul deck - - def DeactivateEquipSlotWindow(self): - for i in range(12): - self.wndEquip.DeactivateSlot(player.DRAGON_SOUL_EQUIPMENT_SLOT_START + i) - - def RefreshStatus(self): - self.RefreshItemSlot() - - def __InventoryLocalSlotPosToGlobalSlotPos(self, window_type, local_slot_pos): - if player.INVENTORY == window_type: - return self.deckPageIndex * player.DRAGON_SOUL_EQUIPMENT_FIRST_SIZE + local_slot_pos - - return (self.DSKindIndex * 5 * player.DRAGON_SOUL_PAGE_SIZE) + self.inventoryPageIndex * player.DRAGON_SOUL_PAGE_SIZE + local_slot_pos - - def RefreshBagSlotWindow(self): - getItemVNum=player.GetItemIndex - getItemCount=player.GetItemCount - setItemVnum=self.wndItem.SetItemSlot - for i in range(player.DRAGON_SOUL_PAGE_SIZE): - self.wndItem.EnableSlot(i) - #<- dragon soul kind - slotNumber = self.__InventoryLocalSlotPosToGlobalSlotPos(player.DRAGON_SOUL_INVENTORY, i) - - itemCount = getItemCount(player.DRAGON_SOUL_INVENTORY, slotNumber) - if 0 == itemCount: - self.wndItem.ClearSlot(i) - continue - elif 1 == itemCount: - itemCount = 0 - itemVnum = getItemVNum(player.DRAGON_SOUL_INVENTORY, slotNumber) - - setItemVnum(i, itemVnum, itemCount) - - if itemVnum != 0: - item.SelectItem(itemVnum) - for j in range(item.LIMIT_MAX_NUM): - (limitType, limitValue) = item.GetLimit(j) - - # Initialize to arbitrary positive number since we check if remain_time < 0 below - remain_time = 999 - if item.LIMIT_REAL_TIME == limitType: - remain_time = player.GetItemMetinSocket(player.DRAGON_SOUL_INVENTORY, slotNumber, 0) - elif item.LIMIT_REAL_TIME_START_FIRST_USE == limitType: - remain_time = player.GetItemMetinSocket(player.DRAGON_SOUL_INVENTORY, slotNumber, 0) - elif item.LIMIT_TIMER_BASED_ON_WEAR == limitType: - remain_time = player.GetItemMetinSocket(player.DRAGON_SOUL_INVENTORY, slotNumber, 0) - - if remain_time <= 0: - self.wndItem.DisableSlot(i) - break - - self.__HighlightSlot_RefreshCurrentPage() - self.wndItem.RefreshSlot() - - def ShowToolTip(self, window_type, slotIndex): - if None != self.tooltipItem: - if player.INVENTORY == window_type: - self.tooltipItem.SetInventoryItem(slotIndex) - else: - self.tooltipItem.SetInventoryItem(slotIndex, player.DRAGON_SOUL_INVENTORY) - - def OnPressEscapeKey(self): - self.Close() - return True - - def OnTop(self): - if None != self.tooltipItem: - self.tooltipItem.SetTop() - - # Item slot related functions - def OverOutItem(self): - self.wndItem.SetUsableItem(False) - if None != self.tooltipItem: - self.tooltipItem.HideToolTip() - - def OverInItem(self, overSlotPos): - self.wndItem.DeactivateSlot(overSlotPos) - overSlotPos = self.__InventoryLocalSlotPosToGlobalSlotPos(player.DRAGON_SOUL_INVENTORY, overSlotPos) - try: - self.listHighlightedSlot.remove(overSlotPos) - except: - pass - - self.wndItem.SetUsableItem(False) - self.ShowToolTip(player.DRAGON_SOUL_INVENTORY, overSlotPos) - - def __UseItem(self, slotIndex): - ItemVNum = player.GetItemIndex(player.DRAGON_SOUL_INVENTORY, slotIndex) - if 0 == player.GetItemMetinSocket(player.DRAGON_SOUL_INVENTORY, slotIndex, 0): - self.wndPopupDialog.SetText(localeInfo.DRAGON_SOUL_EXPIRED) - self.wndPopupDialog.Open() - return - - self.__EquipItem(slotIndex) - - def __EquipItem(self, slotIndex): - ItemVNum = player.GetItemIndex(player.DRAGON_SOUL_INVENTORY, slotIndex) - item.SelectItem(ItemVNum) - subType = item.GetItemSubType() - equipSlotPos = player.DRAGON_SOUL_EQUIPMENT_SLOT_START + self.deckPageIndex * player.DRAGON_SOUL_EQUIPMENT_FIRST_SIZE + subType - srcItemPos = (player.DRAGON_SOUL_INVENTORY, slotIndex) - dstItemPos = (player.INVENTORY, equipSlotPos) - self.__OpenQuestionDialog(True, srcItemPos, dstItemPos) - - def SelectItemSlot(self, itemSlotIndex): - if constInfo.GET_ITEM_QUESTION_DIALOG_STATUS() == 1: - return - - itemSlotIndex = self.__InventoryLocalSlotPosToGlobalSlotPos(player.DRAGON_SOUL_INVENTORY, itemSlotIndex) - - if mouseModule.mouseController.isAttached(): - attachedSlotType = mouseModule.mouseController.GetAttachedType() - attachedSlotPos = mouseModule.mouseController.GetAttachedSlotNumber() - attachedItemVID = mouseModule.mouseController.GetAttachedItemIndex() - - attachedInvenType = player.SlotTypeToInvenType(attachedSlotType) - if player.RESERVED_WINDOW != attachedInvenType: - net.SendItemUseToItemPacket(attachedInvenType, attachedSlotPos, player.DRAGON_SOUL_INVENTORY, itemSlotIndex) - - mouseModule.mouseController.DeattachObject() - - else: - # # Added to be sold in shop - ## 20140220 - curCursorNum = app.GetCursor() - - if app.SELL == curCursorNum: - self.__SellItem(itemSlotIndex) - elif app.BUY == curCursorNum: - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.SHOP_BUY_INFO) - elif app.IsPressed(app.DIK_LALT): - link = player.GetItemLink(player.DRAGON_SOUL_INVENTORY, itemSlotIndex) - ime.PasteString(link) - else: - selectedItemVNum = player.GetItemIndex(player.DRAGON_SOUL_INVENTORY, itemSlotIndex) - itemCount = player.GetItemCount(player.DRAGON_SOUL_INVENTORY, itemSlotIndex) - mouseModule.mouseController.AttachObject(self, player.SLOT_TYPE_DRAGON_SOUL_INVENTORY, itemSlotIndex, selectedItemVNum, itemCount) - self.wndItem.SetUseMode(False) - snd.PlaySound("sound/ui/pick.wav") - - ## Sell to shop - ## Added 2014.02.20 - def __SellItem(self, itemSlotPos): - if not player.IsDSEquipmentSlot(player.DRAGON_SOUL_INVENTORY, itemSlotPos): - self.sellingSlotNumber = itemSlotPos - itemIndex = player.GetItemIndex(player.DRAGON_SOUL_INVENTORY, itemSlotPos) - itemCount = player.GetItemCount(player.DRAGON_SOUL_INVENTORY, itemSlotPos) - - item.SelectItem(itemIndex) - - if item.IsAntiFlag(item.ANTIFLAG_SELL): - popup = uiCommon.PopupDialog() - popup.SetText(localeInfo.SHOP_CANNOT_SELL_ITEM) - popup.SetAcceptEvent(self.__OnClosePopupDialog) - popup.Open() - self.popup = popup - return - - itemPrice = item.GetISellItemPrice() - - if item.Is1GoldItem(): - itemPrice = itemCount // itemPrice // 5 - else: - itemPrice = itemPrice * itemCount // 5 - - item.GetItemName(itemIndex) - itemName = item.GetItemName() - - self.questionDialog = uiCommon.QuestionDialog() - self.questionDialog.SetText(localeInfo.DO_YOU_SELL_ITEM(itemName, itemCount, itemPrice)) - self.questionDialog.SetAcceptEvent(ui.__mem_func__(self.SellItem)) - self.questionDialog.SetCancelEvent(ui.__mem_func__(self.OnCloseQuestionDialog)) - self.questionDialog.Open() - self.questionDialog.count = itemCount - - ## Sell to shop - def SellItem(self): - - net.SendShopSellPacketNew(self.sellingSlotNumber, self.questionDialog.count, player.DRAGON_SOUL_INVENTORY) - snd.PlaySound("sound/ui/money.wav") - self.OnCloseQuestionDialog() - - ## Sell to shop - def OnCloseQuestionDialog(self): - if self.questionDialog: - self.questionDialog.Close() - - self.questionDialog = None - - ## Sell to shop - def __OnClosePopupDialog(self): - self.pop = None - - def SelectEmptySlot(self, selectedSlotPos): - if constInfo.GET_ITEM_QUESTION_DIALOG_STATUS() == 1: - return - - selectedSlotPos = self.__InventoryLocalSlotPosToGlobalSlotPos(player.DRAGON_SOUL_INVENTORY, selectedSlotPos) - if mouseModule.mouseController.isAttached(): - - attachedSlotType = mouseModule.mouseController.GetAttachedType() - attachedSlotPos = mouseModule.mouseController.GetAttachedSlotNumber() - attachedItemCount = mouseModule.mouseController.GetAttachedItemCount() - attachedItemIndex = mouseModule.mouseController.GetAttachedItemIndex() - - attachedInvenType = player.SlotTypeToInvenType(attachedSlotType) - if player.SLOT_TYPE_PRIVATE_SHOP == attachedSlotType: - mouseModule.mouseController.RunCallBack("INVENTORY") - - elif player.SLOT_TYPE_SHOP == attachedSlotType: - net.SendShopBuyPacket(attachedSlotPos) - - elif player.SLOT_TYPE_SAFEBOX == attachedSlotType: - if player.ITEM_MONEY == attachedItemIndex: - net.SendSafeboxWithdrawMoneyPacket(mouseModule.mouseController.GetAttachedItemCount()) - snd.PlaySound("sound/ui/money.wav") - - else: - net.SendSafeboxCheckoutPacket(attachedSlotPos, player.DRAGON_SOUL_INVENTORY, selectedSlotPos) - - elif player.SLOT_TYPE_MALL == attachedSlotType: - net.SendMallCheckoutPacket(attachedSlotPos, player.DRAGON_SOUL_INVENTORY, selectedSlotPos) - - elif player.RESERVED_WINDOW != attachedInvenType: - if player.IsDSEquipmentSlot(attachedInvenType, attachedSlotPos): - srcItemPos = (attachedInvenType, attachedSlotPos) - dstItemPos = (player.DRAGON_SOUL_INVENTORY, selectedSlotPos) - self.__OpenQuestionDialog(False, srcItemPos, dstItemPos) - else: - itemCount = player.GetItemCount(attachedInvenType, attachedSlotPos) - attachedCount = mouseModule.mouseController.GetAttachedItemCount() - - self.__SendMoveItemPacket(attachedInvenType, attachedSlotPos, player.DRAGON_SOUL_INVENTORY, selectedSlotPos, attachedCount) - - mouseModule.mouseController.DeattachObject() - - def UseItemSlot(self, slotIndex): - if constInfo.GET_ITEM_QUESTION_DIALOG_STATUS(): - return - slotIndex = self.__InventoryLocalSlotPosToGlobalSlotPos(player.DRAGON_SOUL_INVENTORY, slotIndex) - try: - # If dragon soul refine window is open, right-click automatically puts item into refine window - if self.wndDragonSoulRefine.IsShow(): - if uiPrivateShopBuilder.IsBuildingPrivateShop(): - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.MOVE_ITEM_FAILURE_PRIVATE_SHOP) - return - self.wndDragonSoulRefine.AutoSetItem((player.DRAGON_SOUL_INVENTORY, slotIndex), 1) - return - except: - pass - - self.__UseItem(slotIndex) - - mouseModule.mouseController.DeattachObject() - self.OverOutItem() - - def __SendMoveItemPacket(self, srcSlotWindow, srcSlotPos, dstSlotWindow, dstSlotPos, srcItemCount): - if uiPrivateShopBuilder.IsBuildingPrivateShop(): - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.MOVE_ITEM_FAILURE_PRIVATE_SHOP) - return - - net.SendItemMovePacket(srcSlotWindow , srcSlotPos, dstSlotWindow, dstSlotPos, srcItemCount) - - # Equipment slot related functions - def OverOutEquipItem(self): - self.OverOutItem() - - def OverInEquipItem(self, overSlotPos): - overSlotPos = self.__InventoryLocalSlotPosToGlobalSlotPos(player.INVENTORY, overSlotPos) - self.wndItem.SetUsableItem(False) - self.ShowToolTip(player.INVENTORY, overSlotPos) - - def UseEquipItemSlot(self, slotIndex): - if constInfo.GET_ITEM_QUESTION_DIALOG_STATUS(): - return - - slotIndex = self.__InventoryLocalSlotPosToGlobalSlotPos(player.INVENTORY, slotIndex) - - self.__UseEquipItem(slotIndex) - mouseModule.mouseController.DeattachObject() - self.OverOutEquipItem() - - def __UseEquipItem(self, slotIndex): - if uiPrivateShopBuilder.IsBuildingPrivateShop(): - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.USE_ITEM_FAILURE_PRIVATE_SHOP) - return - - self.__OpenQuestionDialog(False, (player.INVENTORY, slotIndex), (1, 1)) - - - def SelectEquipItemSlot(self, itemSlotIndex): - - ## Check for sell/buy mouse button and return - curCursorNum = app.GetCursor() - if app.SELL == curCursorNum: - return - elif app.BUY == curCursorNum: - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.SHOP_BUY_INFO) - return - - if constInfo.GET_ITEM_QUESTION_DIALOG_STATUS() == 1: - return - - itemSlotIndex = self.__InventoryLocalSlotPosToGlobalSlotPos(player.INVENTORY, itemSlotIndex) - - if mouseModule.mouseController.isAttached(): - attachedSlotType = mouseModule.mouseController.GetAttachedType() - attachedSlotPos = mouseModule.mouseController.GetAttachedSlotNumber() - - # Case of dragging item onto itself - if player.SLOT_TYPE_INVENTORY == attachedSlotType and itemSlotIndex == attachedSlotPos: - return - - attachedItemVID = mouseModule.mouseController.GetAttachedItemIndex() - - attachedInvenType = player.SlotTypeToInvenType(attachedSlotType) - if player.RESERVED_WINDOW != attachedInvenType: - net.SendItemUseToItemPacket(attachedInvenType, attachedSlotPos, player.INVENTORY, itemSlotIndex) - - mouseModule.mouseController.DeattachObject() - else: - selectedItemVNum = player.GetItemIndex(player.INVENTORY, itemSlotIndex) - itemCount = player.GetItemCount(player.INVENTORY, itemSlotIndex) - - mouseModule.mouseController.AttachObject(self, player.SLOT_TYPE_INVENTORY, itemSlotIndex, selectedItemVNum, itemCount) - self.wndItem.SetUseMode(False) - snd.PlaySound("sound/ui/pick.wav") - - def SelectEmptyEquipSlot(self, selectedSlot): - if constInfo.GET_ITEM_QUESTION_DIALOG_STATUS() == 1: - return - - selectedSlotPos = self.__InventoryLocalSlotPosToGlobalSlotPos(player.INVENTORY, selectedSlot) - - if mouseModule.mouseController.isAttached(): - attachedSlotType = mouseModule.mouseController.GetAttachedType() - attachedSlotPos = mouseModule.mouseController.GetAttachedSlotNumber() - attachedItemCount = mouseModule.mouseController.GetAttachedItemCount() - attachedItemIndex = mouseModule.mouseController.GetAttachedItemIndex() - - if player.SLOT_TYPE_DRAGON_SOUL_INVENTORY == attachedSlotType: - if 0 == player.GetItemMetinSocket(player.DRAGON_SOUL_INVENTORY, attachedSlotPos, 0): - self.wndPopupDialog.SetText(localeInfo.DRAGON_SOUL_EXPIRED) - self.wndPopupDialog.Open() - - return - - item.SelectItem(attachedItemIndex) - subType = item.GetItemSubType() - - if subType != (selectedSlot - player.DRAGON_SOUL_EQUIPMENT_SLOT_START): - self.wndPopupDialog.SetText(localeInfo.DRAGON_SOUL_UNMATCHED_SLOT) - self.wndPopupDialog.Open() - else: - srcItemPos = (player.DRAGON_SOUL_INVENTORY, attachedSlotPos) - dstItemPos = (player.INVENTORY, selectedSlotPos) - self.__OpenQuestionDialog(True, srcItemPos, dstItemPos) - - mouseModule.mouseController.DeattachObject() - # Equipment slot related functions end - - # Warning dialog related - def __OpenQuestionDialog(self, Equip, srcItemPos, dstItemPos): - self.srcItemPos = srcItemPos - self.dstItemPos = dstItemPos - - self.dlgQuestion.SetAcceptEvent(ui.__mem_func__(self.__Accept)) - self.dlgQuestion.SetCancelEvent(ui.__mem_func__(self.__Cancel)) - - if Equip: - self.dlgQuestion.SetText1(localeInfo.DRAGON_SOUL_EQUIP_WARNING1) - self.dlgQuestion.SetText2(localeInfo.DRAGON_SOUL_EQUIP_WARNING2) - else: - self.dlgQuestion.SetText1(localeInfo.DRAGON_SOUL_UNEQUIP_WARNING1) - self.dlgQuestion.SetText2(localeInfo.DRAGON_SOUL_UNEQUIP_WARNING2) - - self.dlgQuestion.Open() - - def __Accept(self): - if (-1, -1) == self.dstItemPos: - net.SendItemUsePacket(*self.srcItemPos) - else: - self.__SendMoveItemPacket(*(self.srcItemPos + self.dstItemPos + (0,))) - - self.dlgQuestion.Close() - - def __Cancel(self): - self.srcItemPos = (0, 0) - self.dstItemPos = (0, 0) - - self.dlgQuestion.Close() - - # Warning dialog related end - - def SetDSKindIndex(self, kindIndex): - if self.DSKindIndex != kindIndex: - self.__HighlightSlot_ClearCurrentPage() - - self.DSKindIndex = kindIndex - - for (tabKey, tabButton) in list(self.tabButtonDict.items()): - if kindIndex!=tabKey: - tabButton.SetUp() - - for tabValue in list(self.tabDict.values()): - tabValue.Hide() - - self.tabDict[kindIndex].Show() - self.tabText.SetText(DragonSoulWindow.KIND_TAP_TITLES[kindIndex]) - - self.RefreshBagSlotWindow() - - def SetDeckPage(self, page): - if page == self.deckPageIndex: - return - - if self.isActivated: - self.DeactivateDragonSoul() - net.SendChatPacket("/dragon_soul deactivate") - - self.deckPageIndex = page - - self.deckTab[page].Down() - self.deckTab[(page + 1) % 2].SetUp() - - self.RefreshEquipSlotWindow() - - # Dragon soul activation related - def ActivateDragonSoulByExtern(self, deck): - self.isActivated = True - self.activateButton.Down() - self.deckPageIndex = deck - - self.deckTab[deck].Down() - self.deckTab[(deck + 1) % 2].SetUp() - - self.RefreshEquipSlotWindow() - self.ActivateEquipSlotWindow(deck) - if self.interface: - self.interface.UseDSSButtonEffect(self.isActivated) - self.__WarmDragonSoulTimeCache(deck) - - def DeactivateDragonSoul(self): - self.isActivated = False - self.activateButton.SetUp() - self.DeactivateEquipSlotWindow() - if self.interface: - self.interface.UseDSSButtonEffect(self.isActivated) - - if self.tooltipItem: - self.tooltipItem.ClearDragonSoulTimeCache() - - # MR-3: Keyboard-enabled deck toggling - def ActivateButtonClick(self, deckIndex = None): - # If deckIndex is not specified, use the current deckPageIndex - if deckIndex is None: - deckIndex = self.deckPageIndex - - # MR-17: Improve slot activation for active Dragon Soul deck - was_activated = self.isActivated - # MR-17: -- END OF -- Improve slot activation for active Dragon Soul deck - - if not self.isActivated or self.deckPageIndex != deckIndex: - # MR-12: Improve keyboard shortcut functionality for deck toggling - if self.deckPageIndex != deckIndex: - self.deckPageIndex = deckIndex - self.deckTab[deckIndex].Down() - self.deckTab[(deckIndex + 1) % 2].SetUp() - self.RefreshEquipSlotWindow() - - # Now validate the deck we switched to - if self.__CanActivateDeck(deckIndex): - net.SendChatPacket("/dragon_soul activate " + str(deckIndex)) - - self.isActivated = True - - self.activateButton.Down() - self.__WarmDragonSoulTimeCache(deckIndex) - else: - self.isActivated = False - - self.activateButton.SetUp() - - # MR-17: Improve slot activation for active Dragon Soul deck - if was_activated: - net.SendChatPacket("/dragon_soul deactivate") - - if self.tooltipItem: - self.tooltipItem.ClearDragonSoulTimeCache() - # MR-17: -- END OF -- Improve slot activation for active Dragon Soul deck - # MR-12: -- END OF -- Improve keyboard shortcut functionality for deck toggling - else: - net.SendChatPacket("/dragon_soul deactivate") - self.isActivated = False - self.activateButton.SetUp() - - # Clear the tooltip cache when deactivating - if self.tooltipItem: - self.tooltipItem.ClearDragonSoulTimeCache() - # MR-3: -- END OF -- Keyboard-enabled deck toggling - - # MR-12: Fix activation of decks with expired dragon souls - def __CanActivateDeck(self, deckIndex = None): - # If deckIndex not specified, check the current deck page - if deckIndex is None: - deckIndex = self.deckPageIndex - - canActiveNum = 0 - - for i in range(6): - # Calculate the slot number for the specified deck - equipSlotPos = player.DRAGON_SOUL_EQUIPMENT_SLOT_START + deckIndex * player.DRAGON_SOUL_EQUIPMENT_FIRST_SIZE + i - slotNumber = equipSlotPos - itemVnum = player.GetItemIndex(player.INVENTORY, slotNumber) - # MR-12: -- END OF -- Fix activation of decks with expired dragon souls - - if itemVnum != 0: - item.SelectItem(itemVnum) - - isNoLimit = True - - for i in range(item.LIMIT_MAX_NUM): - (limitType, limitValue) = item.GetLimit(i) - - # LIMIT_TIMER_BASED_ON_WEAR stores remaining time in socket0 - # LIMIT_REAL_TIME makes item disappear when time expires, so no need to check - # LIMIT_REAL_TIME_START_FIRST_USE not properly defined on server, leave as is - if item.LIMIT_TIMER_BASED_ON_WEAR == limitType: - isNoLimit = False - remain_time = player.GetItemMetinSocket(player.INVENTORY, slotNumber, 0) - - if 0 != remain_time: - canActiveNum += 1 - break - - # Dragon soul can be activated if it has no timer - if isNoLimit: - canActiveNum += 1 - - return canActiveNum > 0 - - # MR-11: Fix Dragon stones timer auto-start - def __WarmDragonSoulTimeCache(self, deckIndex = None): - if not self.tooltipItem: - return - - if not self.isActivated: - return - - if deckIndex is None: - deckIndex = self.deckPageIndex - - deckStart = deckIndex * player.DRAGON_SOUL_EQUIPMENT_FIRST_SIZE - deckStart += player.DRAGON_SOUL_EQUIPMENT_SLOT_START - slotNumbers = [deckStart + i for i in range(6)] - - self.tooltipItem.WarmDragonSoulTimeCache(slotNumbers) - # MR-11: -- END OF -- Fix Dragon stones timer auto-start - - # Activation related end - - # Slot highlight related - def __HighlightSlot_ClearCurrentPage(self): - for i in range(self.wndItem.GetSlotCount()): - slotNumber = self.__InventoryLocalSlotPosToGlobalSlotPos(player.DRAGON_SOUL_INVENTORY, i) - if slotNumber in self.listHighlightedSlot: - self.wndItem.DeactivateSlot(i) - self.listHighlightedSlot.remove(slotNumber) - - def __HighlightSlot_RefreshCurrentPage(self): - for i in range(self.wndItem.GetSlotCount()): - slotNumber = self.__InventoryLocalSlotPosToGlobalSlotPos(player.DRAGON_SOUL_INVENTORY, i) - if slotNumber in self.listHighlightedSlot: - self.wndItem.ActivateSlot(i) - - def HighlightSlot(self, slot): - if not slot in self.listHighlightedSlot: - self.listHighlightedSlot.append (slot) - # Slot highlight related end - - def BindInterfaceClass(self, interface): - from _weakref import proxy - self.interface = proxy(interface) - - def SetDragonSoulRefineWindow(self, wndDragonSoulRefine): - if app.ENABLE_DRAGON_SOUL_SYSTEM: - from _weakref import proxy - self.wndDragonSoulRefine = proxy(wndDragonSoulRefine) - -## Exception raised when refining is not possible -#class DragonSoulRefineException(Exception): - #pass - -class DragonSoulRefineWindow(ui.ScriptWindow): - REFINE_TYPE_GRADE, REFINE_TYPE_STEP, REFINE_TYPE_STRENGTH = list(range(3)) - DS_SUB_HEADER_DIC = { - REFINE_TYPE_GRADE : player.DS_SUB_HEADER_DO_UPGRADE, - REFINE_TYPE_STEP : player.DS_SUB_HEADER_DO_IMPROVEMENT, - REFINE_TYPE_STRENGTH : player.DS_SUB_HEADER_DO_REFINE - } - REFINE_STONE_SLOT, DRAGON_SOUL_SLOT = list(range(2)) - - INVALID_DRAGON_SOUL_INFO = -1 - - def __init__(self): - ui.ScriptWindow.__init__(self) - self.tooltipItem = None - self.sellingSlotNumber = -1 - self.isLoaded = 0 - self.refineChoiceButtonDict = None - self.doRefineButton = None - self.wndMoney = None - self.SetWindowName("DragonSoulRefineWindow") - self.__LoadWindow() - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def Show(self): - self.__LoadWindow() - ui.ScriptWindow.Show(self) - - def __LoadWindow(self): - if self.isLoaded == 1: - return - self.isLoaded = 1 - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "UIScript/dragonsoulrefinewindow.py") - - except: - import exception - exception.Abort("dragonsoulrefinewindow.LoadWindow.LoadObject") - try: - if app.IsRTL(): - self.board = self.GetChild("DragonSoulRefineWindowBaseImage") - self.board.SetScale(-1.0, 1.0) - self.board.SetRenderingRect(-1.0, 0.0, 1.0, 0.0) - - wndRefineSlot = self.GetChild("RefineSlot") - wndResultSlot = self.GetChild("ResultSlot") - self.GetChild("TitleBar").SetCloseEvent(ui.__mem_func__(self.Close)) - self.refineChoiceButtonDict = { - self.REFINE_TYPE_GRADE : self.GetChild("GradeButton"), - self.REFINE_TYPE_STEP: self.GetChild("StepButton"), - self.REFINE_TYPE_STRENGTH : self.GetChild("StrengthButton"), - } - self.doRefineButton = self.GetChild("DoRefineButton") - self.wndMoney = self.GetChild("Money_Slot") - - except: - import exception - exception.Abort("DragonSoulRefineWindow.LoadWindow.BindObject") - - - ## Item Slots - wndRefineSlot.SetOverInItemEvent(ui.__mem_func__(self.__OverInRefineItem)) - wndRefineSlot.SetOverOutItemEvent(ui.__mem_func__(self.__OverOutItem)) - wndRefineSlot.SetSelectEmptySlotEvent(ui.__mem_func__(self.__SelectRefineEmptySlot)) - wndRefineSlot.SetSelectItemSlotEvent(ui.__mem_func__(self.__SelectRefineItemSlot)) - wndRefineSlot.SetUseSlotEvent(ui.__mem_func__(self.__SelectRefineItemSlot)) - wndRefineSlot.SetUnselectItemSlotEvent(ui.__mem_func__(self.__SelectRefineItemSlot)) - - wndResultSlot.SetOverInItemEvent(ui.__mem_func__(self.__OverInResultItem)) - wndResultSlot.SetOverOutItemEvent(ui.__mem_func__(self.__OverOutItem)) - self.wndRefineSlot = wndRefineSlot - self.wndResultSlot = wndResultSlot - - ## Button - self.refineChoiceButtonDict[self.REFINE_TYPE_GRADE].SetToggleDownEvent(self.__ToggleDownGradeButton) - self.refineChoiceButtonDict[self.REFINE_TYPE_STEP].SetToggleDownEvent(self.__ToggleDownStepButton) - self.refineChoiceButtonDict[self.REFINE_TYPE_STRENGTH].SetToggleDownEvent(self.__ToggleDownStrengthButton) - self.refineChoiceButtonDict[self.REFINE_TYPE_GRADE].SetToggleUpEvent(lambda : self.__ToggleUpButton(self.REFINE_TYPE_GRADE)) - self.refineChoiceButtonDict[self.REFINE_TYPE_STEP].SetToggleUpEvent(lambda : self.__ToggleUpButton(self.REFINE_TYPE_STEP)) - self.refineChoiceButtonDict[self.REFINE_TYPE_STRENGTH].SetToggleUpEvent(lambda : self.__ToggleUpButton(self.REFINE_TYPE_STRENGTH)) - self.doRefineButton.SetEvent(self.__PressDoRefineButton) - - ## Dialog - self.wndPopupDialog = uiCommon.PopupDialog() - - self.currentRefineType = self.REFINE_TYPE_GRADE - self.refineItemInfo = {} - self.resultItemInfo = {} - self.currentRecipe = {} - - self.wndMoney.SetText(localeInfo.NumberToMoneyString(0)) - self.refineChoiceButtonDict[self.REFINE_TYPE_GRADE].Down() - - self.__Initialize() - - def Destroy(self): - self.ClearDictionary() - self.tooltipItem = None - self.wndItem = 0 - self.wndEquip = 0 - self.activateButton = 0 - self.questionDialog = None - self.mallButton = None - self.inventoryTab = [] - self.deckTab = [] - self.equipmentTab = [] - self.tabDict = None - self.tabButtonDict = None - - def Close(self): - if None != self.tooltipItem: - self.tooltipItem.HideToolTip() - - self.__FlushRefineItemSlot() - player.SendDragonSoulRefine(player.DRAGON_SOUL_REFINE_CLOSE) - self.Hide() - - def Show(self): - self.currentRefineType = self.REFINE_TYPE_GRADE - self.wndMoney.SetText(localeInfo.NumberToMoneyString(0)) - self.refineChoiceButtonDict[self.REFINE_TYPE_GRADE].Down() - self.refineChoiceButtonDict[self.REFINE_TYPE_STEP].SetUp() - self.refineChoiceButtonDict[self.REFINE_TYPE_STRENGTH].SetUp() - - self.Refresh() - - ui.ScriptWindow.Show(self) - - def SetItemToolTip(self, tooltipItem): - self.tooltipItem = tooltipItem - - # Initialize all refine window variables except button pressed state - def __Initialize(self): - self.currentRecipe = {} - self.refineItemInfo = {} - self.resultItemInfo = {} - - if self.REFINE_TYPE_STRENGTH == self.currentRefineType: - self.refineSlotLockStartIndex = 2 - else: - self.refineSlotLockStartIndex = 1 - - for i in range(self.refineSlotLockStartIndex): - self.wndRefineSlot.HideSlotBaseImage(i) - - self.wndMoney.SetText(localeInfo.NumberToMoneyString(0)) - - def __FlushRefineItemSlot(self): - ## Item slot settings - # Restore original inventory item count - for invenType, invenPos, itemCount in list(self.refineItemInfo.values()): - remainCount = player.GetItemCount(invenType, invenPos) - player.SetItemCount(invenType, invenPos, remainCount + itemCount) - self.__Initialize() - - def __ToggleUpButton(self, idx): - #if self.REFINE_TYPE_GRADE == self.currentRefineType: - self.refineChoiceButtonDict[idx].Down() - - def __ToggleDownGradeButton(self): - if self.REFINE_TYPE_GRADE == self.currentRefineType: - return - self.refineChoiceButtonDict[self.currentRefineType].SetUp() - self.currentRefineType = self.REFINE_TYPE_GRADE - self.__FlushRefineItemSlot() - self.Refresh() - - def __ToggleDownStepButton(self): - if self.REFINE_TYPE_STEP == self.currentRefineType: - return - self.refineChoiceButtonDict[self.currentRefineType].SetUp() - self.currentRefineType = self.REFINE_TYPE_STEP - self.__FlushRefineItemSlot() - self.Refresh() - - def __ToggleDownStrengthButton(self): - if self.REFINE_TYPE_STRENGTH == self.currentRefineType: - return - self.refineChoiceButtonDict[self.currentRefineType].SetUp() - self.currentRefineType = self.REFINE_TYPE_STRENGTH - self.__FlushRefineItemSlot() - self.Refresh() - - def __PopUp(self, message): - self.wndPopupDialog.SetText(message) - self.wndPopupDialog.Open() - - def __SetItem(self, inven, dstSlotIndex, itemCount): - invenType, invenPos = inven - - if dstSlotIndex >= self.refineSlotLockStartIndex: - return False - - itemVnum = player.GetItemIndex(invenType, invenPos) - maxCount = player.GetItemCount(invenType, invenPos) - - if itemCount > maxCount: - raise Exception("Invalid attachedItemCount(%d). (base pos (%d, %d), base itemCount(%d))" % (itemCount, invenType, invenPos, maxCount)) - #return False - - # For strength refining, force slot 0 for refine stone and slot 1 for dragon soul - if DragonSoulRefineWindow.REFINE_TYPE_STRENGTH == self.currentRefineType: - if self.__IsDragonSoul(itemVnum): - dstSlotIndex = 1 - else: - dstSlotIndex = 0 - - # Must be empty slot - if dstSlotIndex in self.refineItemInfo: - return False - - # Check if item can be placed in refine window - if False == self.__CheckCanRefine(itemVnum): - return False - - # Decrease original slot item count by dragged amount - player.SetItemCount(invenType, invenPos, maxCount - itemCount) - self.refineItemInfo[dstSlotIndex] = (invenType, invenPos, itemCount) - self.Refresh() - - return True - - # Check if item can be refined - # Dragon soul refining doesn't start with a predetermined recipe - # The refine recipe is determined by the first dragon soul placed in the refine window - # So __CanRefineGrade, __CanRefineStep, __CanRefineStrength functions also - # set the refine recipe if there isn't one (if it's the first item placed) - def __CheckCanRefine(self, vnum): - if self.REFINE_TYPE_GRADE == self.currentRefineType: - return self.__CanRefineGrade(vnum) - - elif self.REFINE_TYPE_STEP == self.currentRefineType: - return self.__CanRefineStep(vnum) - - elif self.REFINE_TYPE_STRENGTH == self.currentRefineType: - return self.__CanRefineStrength(vnum) - - else: - return False - - def __CanRefineGrade (self, vnum): - ds_info = self.__GetDragonSoulTypeInfo(vnum) - - if DragonSoulRefineWindow.INVALID_DRAGON_SOUL_INFO == ds_info: - self.__PopUp(localeInfo.DRAGON_SOUL_IS_NOT_DRAGON_SOUL) - return False - - if self.currentRecipe: - ds_type, grade, step, strength = ds_info - cur_refine_ds_type, cur_refine_grade, cur_refine_step, cur_refine_strength = self.currentRecipe["ds_info"] - if not (cur_refine_ds_type == ds_type and cur_refine_grade == grade): - self.__PopUp(localeInfo.DRAGON_SOUL_INVALID_DRAGON_SOUL) - return False - # When placing first item in refine window, there's no material information - # Dragon soul refining doesn't start with a recipe - what to refine and - # what materials are needed (recipe) is determined by the first item placed - # If no recipe exists, assume it's the first item and set recipe based on vnum - else: - self.currentRecipe = self.__GetRefineGradeRecipe(vnum) - - if self.currentRecipe: - self.refineSlotLockStartIndex = self.currentRecipe["need_count"] - self.wndMoney.SetText(localeInfo.NumberToMoneyString(self.currentRecipe["fee"])) - return True - else: - # If recipe setup fails, item cannot be placed - self.__PopUp(localeInfo.DRAGON_SOUL_CANNOT_REFINE) - return False - - def __CanRefineStep (self, vnum): - ds_info = self.__GetDragonSoulTypeInfo(vnum) - - if DragonSoulRefineWindow.INVALID_DRAGON_SOUL_INFO == ds_info: - self.__PopUp(localeInfo.DRAGON_SOUL_IS_NOT_DRAGON_SOUL) - return False - - if self.currentRecipe: - ds_type, grade, step, strength = ds_info - cur_refine_ds_type, cur_refine_grade, cur_refine_step, cur_refine_strength = self.currentRecipe["ds_info"] - if not (cur_refine_ds_type == ds_type and cur_refine_grade == grade and cur_refine_step == step): - self.__PopUp(localeInfo.DRAGON_SOUL_INVALID_DRAGON_SOUL) - return False - # When placing first item in refine window, there's no material information - # Dragon soul refining doesn't start with a recipe - what to refine and - # what materials are needed (recipe) is determined by the first item placed - # If no recipe exists, assume it's the first item and set recipe based on vnum - else: - self.currentRecipe = self.__GetRefineStepRecipe(vnum) - - if self.currentRecipe: - self.refineSlotLockStartIndex = self.currentRecipe["need_count"] - self.wndMoney.SetText(localeInfo.NumberToMoneyString(self.currentRecipe["fee"])) - return True - - else: - # If recipe setup fails, item cannot be placed - self.__PopUp(localeInfo.DRAGON_SOUL_CANNOT_REFINE) - return False - - def __CanRefineStrength (self, vnum): - # For dragon souls, check if strength refining is no longer possible - if self.__IsDragonSoul(vnum): - ds_type, grade, step, strength = self.__GetDragonSoulTypeInfo(vnum) - - import dragon_soul_refine_settings - if strength >= dragon_soul_refine_settings.dragon_soul_refine_info[ds_type]["strength_max_table"][grade][step]: - self.__PopUp(localeInfo.DRAGON_SOUL_CANNOT_REFINE_MORE) - return False - - else: - return True - - # For strength refining, refine_recipe depends on refine stone type, not dragon soul type - # So if it's not a dragon soul: - # If recipe already exists, refine stone is in window, so return False - # If no recipe, check if it's a refine stone and set recipe - else: - if self.currentRecipe: - self.__PopUp(localeInfo.DRAGON_SOUL_IS_NOT_DRAGON_SOUL) - return False - else: - refineRecipe = self.__GetRefineStrengthInfo(vnum) - if refineRecipe: - self.currentRecipe = refineRecipe - self.wndMoney.SetText(localeInfo.NumberToMoneyString(self.currentRecipe["fee"])) - return True - else: - # Cannot set recipe - self.__PopUp(localeInfo.DRAGON_SOUL_NOT_DRAGON_SOUL_REFINE_STONE) - return False - - def __GetRefineGradeRecipe (self, vnum): - ds_type, grade, step, strength = self.__GetDragonSoulTypeInfo(vnum) - try: - import dragon_soul_refine_settings - - return { - "ds_info" : (ds_type, grade, step, strength), - "need_count" : dragon_soul_refine_settings.dragon_soul_refine_info[ds_type]["grade_need_count"][grade], - "fee" : dragon_soul_refine_settings.dragon_soul_refine_info[ds_type]["grade_fee"][grade] - } - except: - return None - - def __GetRefineStepRecipe (self, vnum): - ds_type, grade, step, strength = self.__GetDragonSoulTypeInfo(vnum) - try: - import dragon_soul_refine_settings - - return { - "ds_info" : (ds_type, grade, step, strength), - "need_count" : dragon_soul_refine_settings.dragon_soul_refine_info[ds_type]["step_need_count"][step], - "fee" : dragon_soul_refine_settings.dragon_soul_refine_info[ds_type]["step_fee"][step] - } - except: - return None - - # For strength refining, refineInfo depends on the refine stone - def __GetRefineStrengthInfo (self, itemVnum): - try: - # Where to put this... - # Must be a refine stone - item.SelectItem(itemVnum) - if not (item.ITEM_TYPE_MATERIAL == item.GetItemType() \ - and (item.MATERIAL_DS_REFINE_NORMAL <= item.GetItemSubType() and item.GetItemSubType() <= item.MATERIAL_DS_REFINE_HOLLY)): - return None - - import dragon_soul_refine_settings - return { "fee" : dragon_soul_refine_settings.strength_fee[item.GetItemSubType()] } - except: - return None - - def __IsDragonSoul(self, vnum): - item.SelectItem(vnum) - return item.GetItemType() == item.ITEM_TYPE_DS - - # Dragon soul Vnum comments - # If ITEM VNUM from 100,000s digit is represented as FEDCBA - # FE: Dragon soul type D: Grade - # C: Step B: Strength - # A: Reserved numbers - def __GetDragonSoulTypeInfo(self, vnum): - if not self.__IsDragonSoul(vnum): - return DragonSoulRefineWindow.INVALID_DRAGON_SOUL_INFO - ds_type = vnum // 10000 - grade = vnum % 10000 //1000 - step = vnum % 1000 // 100 - strength = vnum % 100 // 10 - - return (ds_type, grade, step, strength) - - def __MakeDragonSoulVnum(self, ds_type, grade, step, strength): - return ds_type * 10000 + grade * 1000 + step * 100 + strength * 10 - - ## Empty slot selection event - def __SelectRefineEmptySlot(self, selectedSlotPos): - try: - if constInfo.GET_ITEM_QUESTION_DIALOG_STATUS() == 1: - return - - if selectedSlotPos >= self.refineSlotLockStartIndex: - return - - if mouseModule.mouseController.isAttached(): - attachedSlotType = mouseModule.mouseController.GetAttachedType() - attachedSlotPos = mouseModule.mouseController.GetAttachedSlotNumber() - attachedItemCount = mouseModule.mouseController.GetAttachedItemCount() - attachedItemIndex = mouseModule.mouseController.GetAttachedItemIndex() - mouseModule.mouseController.DeattachObject() - - if uiPrivateShopBuilder.IsBuildingPrivateShop(): - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.MOVE_ITEM_FAILURE_PRIVATE_SHOP) - return - - attachedInvenType = player.SlotTypeToInvenType(attachedSlotType) - - if player.INVENTORY == attachedInvenType and player.IsEquipmentSlot(attachedSlotPos): - return - - if player.INVENTORY != attachedInvenType and player.DRAGON_SOUL_INVENTORY != attachedInvenType: - return - - if True == self.__SetItem((attachedInvenType, attachedSlotPos), selectedSlotPos, attachedItemCount): - self.Refresh() - - except Exception as e: - import dbg - dbg.TraceError("Exception : __SelectRefineEmptySlot, %s" % e) - - # Remove from slot by clicking - def __SelectRefineItemSlot(self, selectedSlotPos): - if constInfo.GET_ITEM_QUESTION_DIALOG_STATUS() == 1: - return - - try: - if not selectedSlotPos in self.refineItemInfo: - # Place new item in refine window - if mouseModule.mouseController.isAttached(): - attachedSlotType = mouseModule.mouseController.GetAttachedType() - attachedSlotPos = mouseModule.mouseController.GetAttachedSlotNumber() - attachedItemCount = mouseModule.mouseController.GetAttachedItemCount() - attachedItemIndex = mouseModule.mouseController.GetAttachedItemIndex() - mouseModule.mouseController.DeattachObject() - - if uiPrivateShopBuilder.IsBuildingPrivateShop(): - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.MOVE_ITEM_FAILURE_PRIVATE_SHOP) - return - - attachedInvenType = player.SlotTypeToInvenType(attachedSlotType) - - if player.INVENTORY == attachedInvenType and player.IsEquipmentSlot(attachedSlotPos): - return - - if player.INVENTORY != attachedInvenType and player.DRAGON_SOUL_INVENTORY != attachedInvenType: - return - - self.AutoSetItem((attachedInvenType, attachedSlotPos), 1) - return - elif mouseModule.mouseController.isAttached(): - return - - attachedInvenType, attachedSlotPos, attachedItemCount = self.refineItemInfo[selectedSlotPos] - selectedItemVnum = player.GetItemIndex(attachedInvenType, attachedSlotPos) - - # Remove from refine window and restore original inventory item count - invenType, invenPos, itemCount = self.refineItemInfo[selectedSlotPos] - remainCount = player.GetItemCount(invenType, invenPos) - player.SetItemCount(invenType, invenPos, remainCount + itemCount) - del self.refineItemInfo[selectedSlotPos] - - # If refine window is empty, initialize - if not self.refineItemInfo: - self.__Initialize() - else: - item.SelectItem(selectedItemVnum) - # If removed item was refine stone, reset refine recipe - if (item.ITEM_TYPE_MATERIAL == item.GetItemType() \ - and (item.MATERIAL_DS_REFINE_NORMAL <= item.GetItemSubType() and item.GetItemSubType() <= item.MATERIAL_DS_REFINE_HOLLY)): - self.currentRecipe = {} - self.wndMoney.SetText(localeInfo.NumberToMoneyString(0)) - # If it was a dragon soul: - # For non-strength refining, don't reset recipe since other dragon souls remain in window - # For strength refining, no special handling needed since recipe depends on refine stone - else: - pass - - except Exception as e: - import dbg - dbg.TraceError("Exception : __SelectRefineItemSlot, %s" % e) - - self.Refresh() - - def __OverInRefineItem(self, slotIndex): - if not self.tooltipItem: - return - if slotIndex in self.refineItemInfo: - inven_type, inven_pos, item_count = self.refineItemInfo[slotIndex] - self.tooltipItem.SetInventoryItem(inven_pos, inven_type) - else: - self.tooltipItem.HideToolTip() - - def __OverInResultItem(self, slotIndex): - if not self.tooltipItem: - return - if slotIndex in self.resultItemInfo: - inven_type, inven_pos, item_count = self.resultItemInfo[slotIndex] - self.tooltipItem.SetInventoryItem(inven_pos, inven_type) - else: - self.tooltipItem.HideToolTip() - - def __OverOutItem(self): - if self.tooltipItem: - self.tooltipItem.HideToolTip() - - def __PressDoRefineButton(self): - for i in range(self.refineSlotLockStartIndex): - if not i in self.refineItemInfo: - self.wndPopupDialog.SetText(localeInfo.DRAGON_SOUL_NOT_ENOUGH_MATERIAL) - self.wndPopupDialog.Open() - - return - - player.SendDragonSoulRefine(DragonSoulRefineWindow.DS_SUB_HEADER_DIC[self.currentRefineType], self.refineItemInfo) - - def OnPressEscapeKey(self): - self.Close() - return True - - def Refresh(self): - self.__RefreshRefineItemSlot() - self.__ClearResultItemSlot() - - def __RefreshRefineItemSlot(self): - try: - for slotPos in range(self.wndRefineSlot.GetSlotCount()): - self.wndRefineSlot.ClearSlot(slotPos) - if slotPos < self.refineSlotLockStartIndex: - # Check self.refineItemInfo[slotPos] information - # (check if item actually exists) - # Exists -> Set item icon to slot - # Doesn't exist -> Remove from refine window since there's no item - if slotPos in self.refineItemInfo: - invenType, invenPos, itemCount = self.refineItemInfo[slotPos] - itemVnum = player.GetItemIndex(invenType, invenPos) - - # if itemVnum: - if itemVnum: - self.wndRefineSlot.SetItemSlot(slotPos, player.GetItemIndex(invenType, invenPos), itemCount) - else: - del self.refineItemInfo[slotPos] - - # Set reference icon with alpha 0.5 for empty slot - if not slotPos in self.refineItemInfo: - try: - reference_vnum = 0 - # For strength refining: - # Slot 0 for refine stone, slot 1 for dragon soul - if DragonSoulRefineWindow.REFINE_TYPE_STRENGTH == self.currentRefineType: - if DragonSoulRefineWindow.REFINE_STONE_SLOT == slotPos: - reference_vnum = 100300 - else: - reference_vnum = self.__MakeDragonSoulVnum(*self.currentRecipe["ds_info"]) - if 0 != reference_vnum: - item.SelectItem(reference_vnum) - itemIcon = item.GetIconImage() - (width, height) = item.GetItemSize() - self.wndRefineSlot.SetSlot(slotPos, 0, width, height, itemIcon, (1.0, 1.0, 1.0, 0.5)) - # Don't show number in bottom right of slot, looks bad - self.wndRefineSlot.SetSlotCount(slotPos, 0) - except: - pass - # Slots smaller than refineSlotLockStartIndex shouldn't show closed image - self.wndRefineSlot.HideSlotBaseImage(slotPos) - # slotPos >= self.refineSlotLockStartIndex: - else: - # Normally this if statement shouldn't execute - # (since we prevented items from being placed in slots >= refineSlotLockStartIndex) - # But handle just in case of error - if slotPos in self.refineItemInfo: - invenType, invenPos, itemCount = self.refineItemInfo[slotPos] - remainCount = player.GetItemCount(invenType, invenPos) - player.SetItemCount(invenType, invenPos, remainCount + itemCount) - del self.refineItemInfo[slotPos] - # Slots >= refineSlotLockStartIndex should show closed image - self.wndRefineSlot.ShowSlotBaseImage(slotPos) - - # If there are no items in refine window, initialize - # Need to check here since we did "del self.refineItemInfo[slotPos]" above - if not self.refineItemInfo: - self.__Initialize() - - self.wndRefineSlot.RefreshSlot() - except Exception as e: - import dbg - dbg.TraceError("Exception : __RefreshRefineItemSlot, %s" % e) - - def __GetEmptySlot(self, itemVnum = 0): - # For STRENGTH refining, dragon soul slot and refine stone slot are separate - # so we need to know the vnum - if DragonSoulRefineWindow.REFINE_TYPE_STRENGTH == self.currentRefineType: - if 0 == itemVnum: - return -1 - - if self.__IsDragonSoul(itemVnum): - if not DragonSoulRefineWindow.DRAGON_SOUL_SLOT in self.refineItemInfo: - return DragonSoulRefineWindow.DRAGON_SOUL_SLOT - else: - if not DragonSoulRefineWindow.REFINE_STONE_SLOT in self.refineItemInfo: - return DragonSoulRefineWindow.REFINE_STONE_SLOT - else: - for slotPos in range(self.wndRefineSlot.GetSlotCount()): - if not slotPos in self.refineItemInfo: - return slotPos - - return -1 - - def AutoSetItem(self, inven, itemCount): - invenType, invenPos = inven - itemVnum = player.GetItemIndex(invenType, invenPos) - emptySlot = self.__GetEmptySlot(itemVnum) - if -1 == emptySlot: - return - - self.__SetItem((invenType, invenPos), emptySlot, itemCount) - - def __ClearResultItemSlot(self): - self.wndResultSlot.ClearSlot(0) - self.resultItemInfo = {} - - def RefineSucceed(self, inven_type, inven_pos): - self.__Initialize() - self.Refresh() - - itemCount = player.GetItemCount(inven_type, inven_pos) - if itemCount > 0: - self.resultItemInfo[0] = (inven_type, inven_pos, itemCount) - self.wndResultSlot.SetItemSlot(0, player.GetItemIndex(inven_type, inven_pos), itemCount) - - def RefineFail(self, reason, inven_type, inven_pos): - if net.DS_SUB_HEADER_REFINE_FAIL == reason: - self.__Initialize() - self.Refresh() - itemCount = player.GetItemCount(inven_type, inven_pos) - if itemCount > 0: - self.resultItemInfo[0] = (inven_type, inven_pos, itemCount) - self.wndResultSlot.SetItemSlot(0, player.GetItemIndex(inven_type, inven_pos), itemCount) - else: - self.Refresh() - - def SetInventoryWindows(self, wndInventory, wndDragonSoul): - self.wndInventory = wndInventory - self.wndDragonSoul = wndDragonSoul diff --git a/tools/root/uiequipmentdialog.py b/tools/root/uiequipmentdialog.py deleted file mode 100644 index 856cc1d5..00000000 --- a/tools/root/uiequipmentdialog.py +++ /dev/null @@ -1,124 +0,0 @@ -import ui -import chr -import player - -class EquipmentDialog(ui.ScriptWindow): - - def __init__(self): - print("NEW EQUIPMENT DIALOG ----------------------------------------------------------------------------") - ui.ScriptWindow.__init__(self) - self.__LoadDialog() - - self.vid = None - self.eventClose = None - self.itemDataDict = {} - self.tooltipItem = None - - def __del__(self): - print("---------------------------------------------------------------------------- DELETE EQUIPMENT DIALOG ") - ui.ScriptWindow.__del__(self) - - def __LoadDialog(self): - try: - PythonScriptLoader = ui.PythonScriptLoader() - PythonScriptLoader.LoadScriptFile(self, "UIScript/EquipmentDialog.py") - - getObject = self.GetChild - self.board = getObject("Board") - self.slotWindow = getObject("EquipmentSlot") - - except: - import exception - exception.Abort("EquipmentDialog.LoadDialog.BindObject") - - self.board.SetCloseEvent(ui.__mem_func__(self.Close)) - self.slotWindow.SetOverInItemEvent(ui.__mem_func__(self.OverInItem)) - self.slotWindow.SetOverOutItemEvent(ui.__mem_func__(self.OverOutItem)) - - def Open(self, vid): - - self.vid = vid - self.itemDataDict = {} - - name = chr.GetNameByVID(vid) - self.board.SetTitleName(name) - - self.SetCenterPosition() - self.SetTop() - self.Show() - - def Close(self): - self.itemDataDict = {} - self.tooltipItem = None - self.Hide() - - if self.eventClose: - self.eventClose(self.vid) - - def Destroy(self): - self.eventClose = None - - self.Close() - self.ClearDictionary() - - self.board = None - self.slotWindow = None - - def SetEquipmentDialogItem(self, slotIndex, vnum, count): - if count <= 1: - count = 0 - self.slotWindow.SetItemSlot(slotIndex, vnum, count) - - emptySocketList = [] - emptyAttrList = [] - for i in range(player.METIN_SOCKET_MAX_NUM): - emptySocketList.append(0) - for i in range(player.ATTRIBUTE_SLOT_MAX_NUM): - emptyAttrList.append((0, 0)) - self.itemDataDict[slotIndex] = (vnum, count, emptySocketList, emptyAttrList) - - def SetEquipmentDialogSocket(self, slotIndex, socketIndex, value): - if not slotIndex in self.itemDataDict: - return - if socketIndex < 0 or socketIndex > player.METIN_SOCKET_MAX_NUM: - return - self.itemDataDict[slotIndex][2][socketIndex] = value - - def SetEquipmentDialogAttr(self, slotIndex, attrIndex, type, value): - if not slotIndex in self.itemDataDict: - return - if attrIndex < 0 or attrIndex > player.ATTRIBUTE_SLOT_MAX_NUM: - return - self.itemDataDict[slotIndex][3][attrIndex] = (type, value) - - def SetItemToolTip(self, tooltipItem): - self.tooltipItem = tooltipItem - - def SetCloseEvent(self, event): - self.eventClose = event - - def OverInItem(self, slotIndex): - - if None == self.tooltipItem: - return - - if not slotIndex in self.itemDataDict: - return - - itemVnum = self.itemDataDict[slotIndex][0] - if 0 == itemVnum: - return - - self.tooltipItem.ClearToolTip() - metinSlot = self.itemDataDict[slotIndex][2] - attrSlot = self.itemDataDict[slotIndex][3] - self.tooltipItem.AddItemData(itemVnum, metinSlot, attrSlot) - self.tooltipItem.ShowToolTip() - - def OverOutItem(self): - if None != self.tooltipItem: - self.tooltipItem.HideToolTip() - - def OnPressEscapeKey(self): - self.Close() - return True diff --git a/tools/root/uiex.py b/tools/root/uiex.py deleted file mode 100644 index 1ca247a1..00000000 --- a/tools/root/uiex.py +++ /dev/null @@ -1,75 +0,0 @@ -import app -import wndMgr -import systemSetting -import mouseModule -import ui - -class Window(ui.Window): - def __init__(self, skinFileName = ""): - ui.Window.__init__(self, "UI") - - self.children = [] - self.childDict = {} - - self.__LoadSkin(skinFileName) - - self.Show() - - def __del__(self): - ui.Window.__del__(self) - - def ClearDictionary(self): - self.children = [] - self.childDict = {} - - def InsertChild(self, name, child): - self.childDict[name] = child - - def IsChild(self, name): - return name in self.childDict - - def GetChild(self, name): - return self.childDict[name] - - def __LoadSkin(self, fileName): - loader = ui.PythonScriptLoader() - loader.LoadScriptFile(self, fileName) - - -#wndMgr.SetOutlineFlag(True) - -class App: - def __init__(self, title = "METIN2 UI TEST"): - app.SetMouseHandler(mouseModule.mouseController) - app.SetHairColorEnable(True) - wndMgr.SetMouseHandler(mouseModule.mouseController) - - width = systemSetting.GetWidth() - height = systemSetting.GetHeight() - wndMgr.SetScreenSize(width, height) - app.Create(title, width, height, 1) - mouseModule.mouseController.Create() - - self.OnInit() - - def MainLoop(self): - app.Loop() - - def OnInit(self): - pass - - -if __name__ == "__main__": - class TestWindow(Window): - def __init__(self, skinFileName): - Window.__init__(self, skinFileName) - - def __del__(self): - Window.__del__(self) - - class TestApp(App): - def OnInit(self): - self.test = TestWindow("locale/ymir_ui/matrixwindow.py") - pass - - TestApp().MainLoop() diff --git a/tools/root/uiexchange.py b/tools/root/uiexchange.py deleted file mode 100644 index 90dce3e1..00000000 --- a/tools/root/uiexchange.py +++ /dev/null @@ -1,232 +0,0 @@ -import player -import exchange -import net -import localeInfo -import chat -import item - -import ui -import mouseModule -import uiPickMoney -import wndMgr -import constInfo - -################################################################################################### -## Exchange -class ExchangeDialog(ui.ScriptWindow): - - def __init__(self): - ui.ScriptWindow.__init__(self) - self.TitleName = 0 - self.tooltipItem = 0 - self.xStart = 0 - self.yStart = 0 - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def LoadDialog(self): - PythonScriptLoader = ui.PythonScriptLoader() - PythonScriptLoader.LoadScriptFile(self, "UIScript/exchangedialog.py") - - ## Owner - self.OwnerSlot = self.GetChild("Owner_Slot") - self.OwnerSlot.SetSelectEmptySlotEvent(ui.__mem_func__(self.SelectOwnerEmptySlot)) - self.OwnerSlot.SetSelectItemSlotEvent(ui.__mem_func__(self.SelectOwnerItemSlot)) - self.OwnerSlot.SetOverInItemEvent(ui.__mem_func__(self.OverInOwnerItem)) - self.OwnerSlot.SetOverOutItemEvent(ui.__mem_func__(self.OverOutItem)) - self.OwnerMoney = self.GetChild("Owner_Money_Value") - self.OwnerAcceptLight = self.GetChild("Owner_Accept_Light") - self.OwnerAcceptLight.Disable() - self.OwnerMoneyButton = self.GetChild("Owner_Money") - self.OwnerMoneyButton.SetEvent(ui.__mem_func__(self.OpenPickMoneyDialog)) - - ## Target - self.TargetSlot = self.GetChild("Target_Slot") - self.TargetSlot.SetOverInItemEvent(ui.__mem_func__(self.OverInTargetItem)) - self.TargetSlot.SetOverOutItemEvent(ui.__mem_func__(self.OverOutItem)) - self.TargetMoney = self.GetChild("Target_Money_Value") - self.TargetAcceptLight = self.GetChild("Target_Accept_Light") - self.TargetAcceptLight.Disable() - - ## PickMoneyDialog - dlgPickMoney = uiPickMoney.PickMoneyDialog() - dlgPickMoney.LoadDialog() - dlgPickMoney.SetAcceptEvent(ui.__mem_func__(self.OnPickMoney)) - dlgPickMoney.SetTitleName(localeInfo.EXCHANGE_MONEY) - dlgPickMoney.SetMax(7) - dlgPickMoney.Hide() - self.dlgPickMoney = dlgPickMoney - - ## Button - self.AcceptButton = self.GetChild("Owner_Accept_Button") - self.AcceptButton.SetToggleDownEvent(ui.__mem_func__(self.AcceptExchange)) - - self.TitleName = self.GetChild("TitleName") - self.GetChild("TitleBar").SetCloseEvent(net.SendExchangeExitPacket) - - def Destroy(self): - print("---------------------------------------------------------------------------- DESTROY EXCHANGE") - self.ClearDictionary() - self.dlgPickMoney.Destroy() - self.dlgPickMoney = 0 - self.OwnerSlot = 0 - self.OwnerMoney = 0 - self.OwnerAcceptLight = 0 - self.OwnerMoneyButton = 0 - self.TargetSlot = 0 - self.TargetMoney = 0 - self.TargetAcceptLight = 0 - self.TitleName = 0 - self.AcceptButton = 0 - self.tooltipItem = 0 - - def OpenDialog(self): - self.TitleName.SetText(localeInfo.EXCHANGE_TITLE % (exchange.GetNameFromTarget())) - self.AcceptButton.Enable() - self.AcceptButton.SetUp() - self.Show() - - (self.xStart, self.yStart, z) = player.GetMainCharacterPosition() - - def CloseDialog(self): - wndMgr.OnceIgnoreMouseLeftButtonUpEvent() - - if 0 != self.tooltipItem: - self.tooltipItem.HideToolTip() - - self.dlgPickMoney.Close() - self.Hide() - - def SetItemToolTip(self, tooltipItem): - self.tooltipItem = tooltipItem - - def OpenPickMoneyDialog(self): - - if exchange.GetElkFromSelf() > 0: - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.EXCHANGE_CANT_EDIT_MONEY) - return - - self.dlgPickMoney.Open(player.GetElk()) - - def OnPickMoney(self, money): - net.SendExchangeElkAddPacket(money) - - def AcceptExchange(self): - net.SendExchangeAcceptPacket() - self.AcceptButton.Disable() - - def SelectOwnerEmptySlot(self, SlotIndex): - - if False == mouseModule.mouseController.isAttached(): - return - - if mouseModule.mouseController.IsAttachedMoney(): - net.SendExchangeElkAddPacket(mouseModule.mouseController.GetAttachedMoneyAmount()) - else: - attachedSlotType = mouseModule.mouseController.GetAttachedType() - if (player.SLOT_TYPE_INVENTORY == attachedSlotType - or player.SLOT_TYPE_DRAGON_SOUL_INVENTORY == attachedSlotType): - - attachedInvenType = player.SlotTypeToInvenType(attachedSlotType) - SrcSlotNumber = mouseModule.mouseController.GetAttachedSlotNumber() - DstSlotNumber = SlotIndex - - itemID = player.GetItemIndex(attachedInvenType, SrcSlotNumber) - - # MR-3: Auto-deactivate auto potions before moving out - if attachedSlotType == player.SLOT_TYPE_INVENTORY: - itemVnum = player.GetItemIndex(attachedInvenType, SrcSlotNumber) - - if constInfo.IS_AUTO_POTION(itemVnum): - metinSocket = [player.GetItemMetinSocket(attachedInvenType, SrcSlotNumber, j) for j in range(player.METIN_SOCKET_MAX_NUM)] - isActivated = (0 != int(metinSocket[0])) - - if isActivated: - net.SendItemUsePacket(SrcSlotNumber) - # MR-3: -- END OF -- Auto-deactivate auto potions before moving out - item.SelectItem(itemID) - - if item.IsAntiFlag(item.ANTIFLAG_GIVE): - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.EXCHANGE_CANNOT_GIVE) - mouseModule.mouseController.DeattachObject() - return - - net.SendExchangeItemAddPacket(attachedInvenType, SrcSlotNumber, DstSlotNumber) - - mouseModule.mouseController.DeattachObject() - - def SelectOwnerItemSlot(self, SlotIndex): - - if player.ITEM_MONEY == mouseModule.mouseController.GetAttachedItemIndex(): - - money = mouseModule.mouseController.GetAttachedItemCount() - net.SendExchangeElkAddPacket(money) - - def RefreshOwnerSlot(self): - for i in range(exchange.EXCHANGE_ITEM_MAX_NUM): - itemIndex = exchange.GetItemVnumFromSelf(i) - itemCount = exchange.GetItemCountFromSelf(i) - if 1 == itemCount: - itemCount = 0 - self.OwnerSlot.SetItemSlot(i, itemIndex, itemCount) - self.OwnerSlot.RefreshSlot() - - def RefreshTargetSlot(self): - for i in range(exchange.EXCHANGE_ITEM_MAX_NUM): - itemIndex = exchange.GetItemVnumFromTarget(i) - itemCount = exchange.GetItemCountFromTarget(i) - if 1 == itemCount: - itemCount = 0 - self.TargetSlot.SetItemSlot(i, itemIndex, itemCount) - self.TargetSlot.RefreshSlot() - - def Refresh(self): - - self.RefreshOwnerSlot() - self.RefreshTargetSlot() - - # self.OwnerMoney.SetText(str(exchange.GetElkFromSelf())) - # self.TargetMoney.SetText(str(exchange.GetElkFromTarget())) - - self.OwnerMoney.SetText(str(('.'.join([ i-3<0 and str(exchange.GetElkFromSelf())[:i] or str(exchange.GetElkFromSelf())[i-3:i] for i in range(len(str(exchange.GetElkFromSelf()))%3, len(str(exchange.GetElkFromSelf()))+1, 3) if i ])))) - self.TargetMoney.SetText(str(('.'.join([ i-3<0 and str(exchange.GetElkFromTarget())[:i] or str(exchange.GetElkFromTarget())[i-3:i] for i in range(len(str(exchange.GetElkFromTarget()))%3, len(str(exchange.GetElkFromTarget()))+1, 3) if i ])))) - - if True == exchange.GetAcceptFromSelf(): - self.OwnerAcceptLight.Down() - else: - self.AcceptButton.Enable() - self.AcceptButton.SetUp() - self.OwnerAcceptLight.SetUp() - - if True == exchange.GetAcceptFromTarget(): - self.TargetAcceptLight.Down() - else: - self.TargetAcceptLight.SetUp() - - def OverInOwnerItem(self, slotIndex): - - if 0 != self.tooltipItem: - self.tooltipItem.SetExchangeOwnerItem(slotIndex) - - def OverInTargetItem(self, slotIndex): - - if 0 != self.tooltipItem: - self.tooltipItem.SetExchangeTargetItem(slotIndex) - - def OverOutItem(self): - - if 0 != self.tooltipItem: - self.tooltipItem.HideToolTip() - - def OnTop(self): - self.tooltipItem.SetTop() - - def OnUpdate(self): - - USE_EXCHANGE_LIMIT_RANGE = 1000 - - (x, y, z) = player.GetMainCharacterPosition() - if abs(x - self.xStart) > USE_EXCHANGE_LIMIT_RANGE or abs(y - self.yStart) > USE_EXCHANGE_LIMIT_RANGE: - (self.xStart, self.yStart, z) = player.GetMainCharacterPosition() - net.SendExchangeExitPacket() diff --git a/tools/root/uigamebutton.py b/tools/root/uigamebutton.py deleted file mode 100644 index 605c4760..00000000 --- a/tools/root/uigamebutton.py +++ /dev/null @@ -1,107 +0,0 @@ -import app -import ui -import player -import net - -class GameButtonWindow(ui.ScriptWindow): - def __init__(self): - ui.ScriptWindow.__init__(self) - self.__LoadWindow("UIScript/gamewindow.py") - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def __LoadWindow(self, filename): - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, filename) - except Exception as msg: - import dbg - dbg.TraceError("GameButtonWindow.LoadScript - %s" % (msg)) - app.Abort() - return False - - try: - self.gameButtonDict={ - "STATUS" : self.GetChild("StatusPlusButton"), - "SKILL" : self.GetChild("SkillPlusButton"), - "QUEST" : self.GetChild("QuestButton"), - "HELP" : self.GetChild("HelpButton"), - "BUILD" : self.GetChild("BuildGuildBuilding"), - "EXIT_OBSERVER" : self.GetChild("ExitObserver"), - } - - self.gameButtonDict["EXIT_OBSERVER"].SetEvent(ui.__mem_func__(self.__OnClickExitObserver)) - - except Exception as msg: - import dbg - dbg.TraceError("GameButtonWindow.LoadScript - %s" % (msg)) - app.Abort() - return False - - self.__HideAllGameButton() - self.SetObserverMode(player.IsObserverMode()) - return True - - def Destroy(self): - for key in self.gameButtonDict: - self.gameButtonDict[key].SetEvent(0) - - self.gameButtonDict={} - - def SetButtonEvent(self, name, event): - try: - self.gameButtonDict[name].SetEvent(event) - except Exception as msg: - print(("GameButtonWindow.LoadScript - %s" % (msg))) - app.Abort() - return - - def ShowBuildButton(self): - self.gameButtonDict["BUILD"].Show() - - def HideBuildButton(self): - self.gameButtonDict["BUILD"].Hide() - - def CheckGameButton(self): - - if not self.IsShow(): - return - - statusPlusButton=self.gameButtonDict["STATUS"] - skillPlusButton=self.gameButtonDict["SKILL"] - helpButton=self.gameButtonDict["HELP"] - - if player.GetStatus(player.STAT) > 0: - statusPlusButton.Show() - else: - statusPlusButton.Hide() - - if self.__IsSkillStat(): - skillPlusButton.Show() - else: - skillPlusButton.Hide() - - if 0 == player.GetPlayTime(): - helpButton.Show() - else: - helpButton.Hide() - - def __IsSkillStat(self): - if player.GetStatus(player.SKILL_ACTIVE) > 0: - return True - - return False - - def __OnClickExitObserver(self): - net.SendChatPacket("/observer_exit") - - def __HideAllGameButton(self): - for btn in list(self.gameButtonDict.values()): - btn.Hide() - - def SetObserverMode(self, isEnable): - if isEnable: - self.gameButtonDict["EXIT_OBSERVER"].Show() - else: - self.gameButtonDict["EXIT_OBSERVER"].Hide() diff --git a/tools/root/uigameoption.py b/tools/root/uigameoption.py deleted file mode 100644 index 56919877..00000000 --- a/tools/root/uigameoption.py +++ /dev/null @@ -1,370 +0,0 @@ -import ui -import snd -import systemSetting -import net -import chat -import app -import localeInfo -import constInfo -import chrmgr -import player -import uiPrivateShopBuilder # 占쏙옙占쏙옙호 -import interfaceModule # 占쏙옙占쏙옙호 - -blockMode = 0 -viewChatMode = 0 - -class OptionDialog(ui.ScriptWindow): - - def __init__(self): - ui.ScriptWindow.__init__(self) - self.__Initialize() - self.__Load() - self.RefreshViewChat() - self.RefreshAlwaysShowName() - self.RefreshShowDamage() - self.RefreshShowSalesText() - - def __del__(self): - ui.ScriptWindow.__del__(self) - print(" -------------------------------------- DELETE GAME OPTION DIALOG") - - def __Initialize(self): - self.titleBar = 0 - self.nameColorModeButtonList = [] - self.viewTargetBoardButtonList = [] - self.pvpModeButtonDict = {} - self.blockButtonList = [] - self.viewChatButtonList = [] - self.alwaysShowNameButtonList = [] - self.showDamageButtonList = [] - self.showsalesTextButtonList = [] - - def Destroy(self): - self.ClearDictionary() - - self.__Initialize() - print(" -------------------------------------- DESTROY GAME OPTION DIALOG") - - def __Load_LoadScript(self, fileName): - try: - pyScriptLoader = ui.PythonScriptLoader() - pyScriptLoader.LoadScriptFile(self, fileName) - except: - import exception - exception.Abort("OptionDialog.__Load_LoadScript") - - def __Load_BindObject(self): - try: - GetObject = self.GetChild - self.titleBar = GetObject("titlebar") - self.nameColorModeButtonList.append(GetObject("name_color_normal")) - self.nameColorModeButtonList.append(GetObject("name_color_empire")) - self.viewTargetBoardButtonList.append(GetObject("target_board_no_view")) - self.viewTargetBoardButtonList.append(GetObject("target_board_view")) - self.pvpModeButtonDict[player.PK_MODE_PEACE] = GetObject("pvp_peace") - self.pvpModeButtonDict[player.PK_MODE_REVENGE] = GetObject("pvp_revenge") - self.pvpModeButtonDict[player.PK_MODE_GUILD] = GetObject("pvp_guild") - self.pvpModeButtonDict[player.PK_MODE_FREE] = GetObject("pvp_free") - self.blockButtonList.append(GetObject("block_exchange_button")) - self.blockButtonList.append(GetObject("block_party_button")) - self.blockButtonList.append(GetObject("block_guild_button")) - self.blockButtonList.append(GetObject("block_whisper_button")) - self.blockButtonList.append(GetObject("block_friend_button")) - self.blockButtonList.append(GetObject("block_party_request_button")) - self.viewChatButtonList.append(GetObject("view_chat_on_button")) - self.viewChatButtonList.append(GetObject("view_chat_off_button")) - self.alwaysShowNameButtonList.append(GetObject("always_show_name_on_button")) - self.alwaysShowNameButtonList.append(GetObject("always_show_name_off_button")) - self.showDamageButtonList.append(GetObject("show_damage_on_button")) - self.showDamageButtonList.append(GetObject("show_damage_off_button")) - self.showsalesTextButtonList.append(GetObject("salestext_on_button")) - self.showsalesTextButtonList.append(GetObject("salestext_off_button")) - - except: - import exception - exception.Abort("OptionDialog.__Load_BindObject") - - def __Load(self): - self.__Load_LoadScript("uiscript/gameoptiondialog.py") - - self.__Load_BindObject() - - self.SetCenterPosition() - - self.titleBar.SetCloseEvent(ui.__mem_func__(self.Close)) - - self.nameColorModeButtonList[0].SAFE_SetEvent(self.__OnClickNameColorModeNormalButton) - self.nameColorModeButtonList[1].SAFE_SetEvent(self.__OnClickNameColorModeEmpireButton) - - self.viewTargetBoardButtonList[0].SAFE_SetEvent(self.__OnClickTargetBoardViewButton) - self.viewTargetBoardButtonList[1].SAFE_SetEvent(self.__OnClickTargetBoardNoViewButton) - - self.pvpModeButtonDict[player.PK_MODE_PEACE].SAFE_SetEvent(self.__OnClickPvPModePeaceButton) - self.pvpModeButtonDict[player.PK_MODE_REVENGE].SAFE_SetEvent(self.__OnClickPvPModeRevengeButton) - self.pvpModeButtonDict[player.PK_MODE_GUILD].SAFE_SetEvent(self.__OnClickPvPModeGuildButton) - self.pvpModeButtonDict[player.PK_MODE_FREE].SAFE_SetEvent(self.__OnClickPvPModeFreeButton) - - self.blockButtonList[0].SetToggleUpEvent(self.__OnClickBlockExchangeButton) - self.blockButtonList[1].SetToggleUpEvent(self.__OnClickBlockPartyButton) - self.blockButtonList[2].SetToggleUpEvent(self.__OnClickBlockGuildButton) - self.blockButtonList[3].SetToggleUpEvent(self.__OnClickBlockWhisperButton) - self.blockButtonList[4].SetToggleUpEvent(self.__OnClickBlockFriendButton) - self.blockButtonList[5].SetToggleUpEvent(self.__OnClickBlockPartyRequest) - - self.blockButtonList[0].SetToggleDownEvent(self.__OnClickBlockExchangeButton) - self.blockButtonList[1].SetToggleDownEvent(self.__OnClickBlockPartyButton) - self.blockButtonList[2].SetToggleDownEvent(self.__OnClickBlockGuildButton) - self.blockButtonList[3].SetToggleDownEvent(self.__OnClickBlockWhisperButton) - self.blockButtonList[4].SetToggleDownEvent(self.__OnClickBlockFriendButton) - self.blockButtonList[5].SetToggleDownEvent(self.__OnClickBlockPartyRequest) - - self.viewChatButtonList[0].SAFE_SetEvent(self.__OnClickViewChatOnButton) - self.viewChatButtonList[1].SAFE_SetEvent(self.__OnClickViewChatOffButton) - - self.alwaysShowNameButtonList[0].SAFE_SetEvent(self.__OnClickAlwaysShowNameOnButton) - self.alwaysShowNameButtonList[1].SAFE_SetEvent(self.__OnClickAlwaysShowNameOffButton) - - self.showDamageButtonList[0].SAFE_SetEvent(self.__OnClickShowDamageOnButton) - self.showDamageButtonList[1].SAFE_SetEvent(self.__OnClickShowDamageOffButton) - - self.showsalesTextButtonList[0].SAFE_SetEvent(self.__OnClickSalesTextOnButton) - self.showsalesTextButtonList[1].SAFE_SetEvent(self.__OnClickSalesTextOffButton) - - self.__ClickRadioButton(self.nameColorModeButtonList, constInfo.GET_CHRNAME_COLOR_INDEX()) - self.__ClickRadioButton(self.viewTargetBoardButtonList, constInfo.GET_VIEW_OTHER_EMPIRE_PLAYER_TARGET_BOARD()) - self.__SetPeacePKMode() - - def __ClickRadioButton(self, buttonList, buttonIndex): - try: - selButton=buttonList[buttonIndex] - except IndexError: - return - - for eachButton in buttonList: - eachButton.SetUp() - - selButton.Down() - - def __SetNameColorMode(self, index): - constInfo.SET_CHRNAME_COLOR_INDEX(index) - self.__ClickRadioButton(self.nameColorModeButtonList, index) - - def __SetTargetBoardViewMode(self, flag): - constInfo.SET_VIEW_OTHER_EMPIRE_PLAYER_TARGET_BOARD(flag) - self.__ClickRadioButton(self.viewTargetBoardButtonList, flag) - - def __OnClickNameColorModeNormalButton(self): - self.__SetNameColorMode(0) - - def __OnClickNameColorModeEmpireButton(self): - self.__SetNameColorMode(1) - - def __OnClickTargetBoardViewButton(self): - self.__SetTargetBoardViewMode(0) - - def __OnClickTargetBoardNoViewButton(self): - self.__SetTargetBoardViewMode(1) - - def __OnClickCameraModeShortButton(self): - self.__SetCameraMode(0) - - def __OnClickCameraModeLongButton(self): - self.__SetCameraMode(1) - - def __OnClickFogModeLevel0Button(self): - self.__SetFogLevel(0) - - def __OnClickFogModeLevel1Button(self): - self.__SetFogLevel(1) - - def __OnClickFogModeLevel2Button(self): - self.__SetFogLevel(2) - - def __OnClickBlockExchangeButton(self): - self.RefreshBlock() - global blockMode - net.SendChatPacket("/setblockmode " + str(blockMode ^ player.BLOCK_EXCHANGE)) - def __OnClickBlockPartyButton(self): - self.RefreshBlock() - global blockMode - net.SendChatPacket("/setblockmode " + str(blockMode ^ player.BLOCK_PARTY)) - def __OnClickBlockGuildButton(self): - self.RefreshBlock() - global blockMode - net.SendChatPacket("/setblockmode " + str(blockMode ^ player.BLOCK_GUILD)) - def __OnClickBlockWhisperButton(self): - self.RefreshBlock() - global blockMode - net.SendChatPacket("/setblockmode " + str(blockMode ^ player.BLOCK_WHISPER)) - def __OnClickBlockFriendButton(self): - self.RefreshBlock() - global blockMode - net.SendChatPacket("/setblockmode " + str(blockMode ^ player.BLOCK_FRIEND)) - def __OnClickBlockPartyRequest(self): - self.RefreshBlock() - global blockMode - net.SendChatPacket("/setblockmode " + str(blockMode ^ player.BLOCK_PARTY_REQUEST)) - - def __OnClickViewChatOnButton(self): - global viewChatMode - viewChatMode = 1 - systemSetting.SetViewChatFlag(viewChatMode) - self.RefreshViewChat() - def __OnClickViewChatOffButton(self): - global viewChatMode - viewChatMode = 0 - systemSetting.SetViewChatFlag(viewChatMode) - self.RefreshViewChat() - - def __OnClickAlwaysShowNameOnButton(self): - systemSetting.SetAlwaysShowNameFlag(True) - self.RefreshAlwaysShowName() - - def __OnClickAlwaysShowNameOffButton(self): - systemSetting.SetAlwaysShowNameFlag(False) - self.RefreshAlwaysShowName() - - def __OnClickShowDamageOnButton(self): - systemSetting.SetShowDamageFlag(True) - self.RefreshShowDamage() - - def __OnClickShowDamageOffButton(self): - systemSetting.SetShowDamageFlag(False) - self.RefreshShowDamage() - - def __OnClickSalesTextOnButton(self): - systemSetting.SetShowSalesTextFlag(True) - self.RefreshShowSalesText() - uiPrivateShopBuilder.UpdateADBoard() - - def __OnClickSalesTextOffButton(self): - systemSetting.SetShowSalesTextFlag(False) - self.RefreshShowSalesText() - - def __CheckPvPProtectedLevelPlayer(self): - if player.GetStatus(player.LEVEL) self.TEXT_LIMIT: - limitText = grpText.GetSplitingTextLine(text, self.TEXT_LIMIT-3, 0) - self.slotSimpleText.SetText(limitText + "...") - self.bar.SetSize(self.len * 6 + 5, 17) - - else: - self.slotSimpleText.SetText(text) - - self.slotFullText.SetText(text) - self.slotFullText.SetPosition(2, 0) - self.slotFullText.Hide() - - def OnMouseOverIn(self): - if self.len > self.TEXT_LIMIT: - self.bar.Show() - self.slotFullText.Show() - - def OnMouseOverOut(self): - if self.len > self.TEXT_LIMIT: - self.bar.Hide() - self.slotFullText.Hide() - -class GuildWindow(ui.ScriptWindow): - - JOB_NAME = {} - - @staticmethod - def _RebuildLocaleStrings(): - GuildWindow.JOB_NAME = { - 0 : localeInfo.JOB_WARRIOR, - 1 : localeInfo.JOB_ASSASSIN, - 2 : localeInfo.JOB_SURA, - 3 : localeInfo.JOB_SHAMAN, - } - - GUILD_SKILL_PASSIVE_SLOT = 0 - GUILD_SKILL_ACTIVE_SLOT = 1 - GUILD_SKILL_AFFECT_SLOT = 2 - - GRADE_SLOT_NAME = 0 - GRADE_ADD_MEMBER_AUTHORITY = 1 - GRADE_REMOVE_MEMBER_AUTHORITY = 2 - GRADE_NOTICE_AUTHORITY = 3 - GRADE_SKILL_AUTHORITY = 4 - - MEMBER_LINE_COUNT = 13 - - class PageWindow(ui.ScriptWindow): - def __init__(self, parent, filename): - ui.ScriptWindow.__init__(self) - self.SetParent(parent) - self.filename = filename - def GetScriptFileName(self): - return self.filename - - def __init__(self): - ui.ScriptWindow.__init__(self) - self.isLoaded=0 - - self.__Initialize() - - def __del__(self): - ui.ScriptWindow.__del__(self) - print(" ==================================== DESTROIED GUILD WINDOW") - - def __Initialize(self): - - self.board = None - self.pageName = None - self.tabDict = None - self.tabButtonDict = None - self.pickDialog = None - self.questionDialog = None - self.offerDialog = None - self.popupDialog = None - self.moneyDialog = None - self.changeGradeNameDialog = None - self.popup = None - - self.popupMessage = None - self.commentSlot = None - - self.pageWindow = None - self.tooltipSkill = None - - self.memberLinePos = 0 - - self.enemyGuildNameList = [] - - def Open(self): - self.Show() - self.SetTop() - - guildID = net.GetGuildID() - self.largeMarkBox.SetIndex(guildID) - self.largeMarkBox.SetScale(3) - - def Close(self): - self.__CloseAllGuildMemberPageGradeComboBox() - self.offerDialog.Close() - self.popupDialog.Hide() - self.changeGradeNameDialog.Hide() - self.tooltipSkill.Hide() - self.Hide() - - self.pickDialog = None - self.questionDialog = None - self.popup = None - - def Destroy(self): - self.ClearDictionary() - - if self.offerDialog: - self.offerDialog.Destroy() - - if self.popupDialog: - self.popupDialog.ClearDictionary() - - if self.changeGradeNameDialog: - self.changeGradeNameDialog.ClearDictionary() - - if self.pageWindow: - for window in list(self.pageWindow.values()): - window.ClearDictionary() - - self.__Initialize() - - def Show(self): - if self.isLoaded==0: - self.isLoaded=1 - - self.__LoadWindow() - - self.RefreshGuildInfoPage() - self.RefreshGuildBoardPage() - self.RefreshGuildMemberPage() - self.RefreshGuildSkillPage() - self.RefreshGuildGradePage() - - ui.ScriptWindow.Show(self) - - def __LoadWindow(self): - global DISABLE_GUILD_SKILL - try: - pyScrLoader = ui.PythonScriptLoader() - - if app.IsRTL() : - pyScrLoader.LoadScriptFile(self, uiScriptLocale.LOCALE_UISCRIPT_PATH + "guildwindow.py") - else: - pyScrLoader.LoadScriptFile(self, "uiscript/guildwindow.py") - - self.popupDialog = ui.ScriptWindow() - pyScrLoader.LoadScriptFile(self.popupDialog, "UIScript/PopupDialog.py") - - self.changeGradeNameDialog = ChangeGradeNameDialog() - pyScrLoader.LoadScriptFile(self.changeGradeNameDialog, "uiscript/changegradenamedialog.py") - - if app.IsRTL(): - self.pageWindow = { - "GUILD_INFO" : self.PageWindow(self, "uiscript/guildwindow_guildinfopage_eu.py"), - "BOARD" : self.PageWindow(self, "uiscript/guildwindow_boardpage.py"), - "MEMBER" : self.PageWindow(self, "uiscript/guildwindow_memberpage.py"), - "BASE_INFO" : self.PageWindow(self, "uiscript/guildwindow_baseinfopage.py"), - "SKILL" : self.PageWindow(self, uiScriptLocale.LOCALE_UISCRIPT_PATH + "guildwindow_guildskillpage.py"), - "GRADE" : self.PageWindow(self, "uiscript/guildwindow_gradepage.py"), - } - else: - self.pageWindow = { - "GUILD_INFO" : self.PageWindow(self, "uiscript/guildwindow_guildinfopage.py"), - "BOARD" : self.PageWindow(self, "uiscript/guildwindow_boardpage.py"), - "MEMBER" : self.PageWindow(self, "uiscript/guildwindow_memberpage.py"), - "BASE_INFO" : self.PageWindow(self, "uiscript/guildwindow_baseinfopage.py"), - "SKILL" : self.PageWindow(self, "uiscript/guildwindow_guildskillpage.py"), - "GRADE" : self.PageWindow(self, "uiscript/guildwindow_gradepage.py"), - } - - for window in list(self.pageWindow.values()): - pyScrLoader.LoadScriptFile(window, window.GetScriptFileName()) - - except: - import exception - exception.Abort("GuildWindow.__LoadWindow.LoadScript") - - try: - getObject = self.GetChild - - self.board = getObject("Board") - self.pageName = { - "GUILD_INFO" : localeInfo.GUILD_TILE_INFO, - "BOARD" : localeInfo.GUILD_TILE_BOARD, - "MEMBER" : localeInfo.GUILD_TILE_MEMBER, - "BASE_INFO" : localeInfo.GUILD_TILE_BASEINFO, - "SKILL" : localeInfo.GUILD_TILE_SKILL, - "GRADE" : localeInfo.GUILD_TILE_GRADE, - } - - self.tabDict = { - "GUILD_INFO" : getObject("Tab_01"), - "BOARD" : getObject("Tab_02"), - "MEMBER" : getObject("Tab_03"), - "BASE_INFO" : getObject("Tab_04"), - "SKILL" : getObject("Tab_05"), - "GRADE" : getObject("Tab_06"), - } - self.tabButtonDict = { - "GUILD_INFO" : getObject("Tab_Button_01"), - "BOARD" : getObject("Tab_Button_02"), - "MEMBER" : getObject("Tab_Button_03"), - "BASE_INFO" : getObject("Tab_Button_04"), - "SKILL" : getObject("Tab_Button_05"), - "GRADE" : getObject("Tab_Button_06"), - } - - ## QuestionDialog - self.popupMessage = self.popupDialog.GetChild("message") - self.popupDialog.GetChild("accept").SetEvent(ui.__mem_func__(self.popupDialog.Hide)) - - ## ChangeGradeName - self.changeGradeNameDialog.GetChild("AcceptButton").SetEvent(ui.__mem_func__(self.OnChangeGradeName)) - self.changeGradeNameDialog.GetChild("CancelButton").SetEvent(ui.__mem_func__(self.changeGradeNameDialog.Hide)) - self.changeGradeNameDialog.GetChild("Board").SetCloseEvent(ui.__mem_func__(self.changeGradeNameDialog.Hide)) - self.changeGradeNameDialog.gradeNameSlot = self.changeGradeNameDialog.GetChild("GradeNameValue") - self.changeGradeNameDialog.gradeNameSlot.OnIMEReturn = ui.__mem_func__(self.OnChangeGradeName) - self.changeGradeNameDialog.gradeNameSlot.OnPressEscapeKey = ui.__mem_func__(self.changeGradeNameDialog.Close) - - ## Comment - self.commentSlot = self.pageWindow["BOARD"].GetChild("CommentValue") - self.commentSlot.OnIMEReturn = ui.__mem_func__(self.OnPostComment) - #self.commentSlot.OnKeyDown = ui.__mem_func__(self.OnKeyDownInBoardPage) - self.commentSlot.OnKeyDown = lambda key, argSelf=self: argSelf.OnKeyDownInBoardPage(key) - - ## RefreshButton - self.pageWindow["BOARD"].GetChild("RefreshButton").SetEvent(ui.__mem_func__(self.OnRefreshComments)) - - ## ScrollBar - scrollBar = self.pageWindow["MEMBER"].GetChild("ScrollBar") - scrollBar.SetScrollEvent(ui.__mem_func__(self.OnScrollMemberLine)) - self.pageWindow["MEMBER"].scrollBar = scrollBar - - except: - import exception - exception.Abort("GuildWindow.__LoadWindow.BindObject") - - self.__MakeInfoPage() - self.__MakeBoardPage() - self.__MakeMemberPage() - self.__MakeBaseInfoPage() - self.__MakeSkillPage() - self.__MakeGradePage() - - for page in list(self.pageWindow.values()): - page.UpdateRect() - - for key, btn in list(self.tabButtonDict.items()): - btn.SetEvent(self.SelectPage, key) - - self.tabButtonDict["BASE_INFO"].Disable() - - if DISABLE_GUILD_SKILL: - self.tabButtonDict["SKILL"].Disable() - - self.board.SetCloseEvent(ui.__mem_func__(self.Close)) - self.board.SetTitleColor(0xffffffff) - self.SelectPage("GUILD_INFO") - - self.offerDialog = uiPickMoney.PickMoneyDialog() - self.offerDialog.LoadDialog() - self.offerDialog.SetMax(9) - self.offerDialog.SetTitleName(localeInfo.GUILD_OFFER_EXP) - self.offerDialog.SetAcceptEvent(ui.__mem_func__(self.OnOffer)) - - def __MakeInfoPage(self): - page = self.pageWindow["GUILD_INFO"] - - try: - page.nameSlot = page.GetChild("GuildNameValue") - page.masterNameSlot = page.GetChild("GuildMasterNameValue") - page.guildLevelSlot = page.GetChild("GuildLevelValue") - page.curExpSlot = page.GetChild("CurrentExperienceValue") - page.lastExpSlot = page.GetChild("LastExperienceValue") - page.memberCountSlot = page.GetChild("GuildMemberCountValue") - page.levelAverageSlot = page.GetChild("GuildMemberLevelAverageValue") - page.uploadMarkButton = page.GetChild("UploadGuildMarkButton") - page.uploadSymbolButton = page.GetChild("UploadGuildSymbolButton") - page.declareWarButton = page.GetChild("DeclareWarButton") - - try: - page.guildMoneySlot = page.GetChild("GuildMoneyValue") - except KeyError: - page.guildMoneySlot = None - - try: - page.GetChild("DepositButton").SetEvent(ui.__mem_func__(self.__OnClickDepositButton)) - page.GetChild("WithdrawButton").SetEvent(ui.__mem_func__(self.__OnClickWithdrawButton)) - except KeyError: - pass - - page.uploadMarkButton.SetEvent(ui.__mem_func__(self.__OnClickSelectGuildMarkButton)) - page.uploadSymbolButton.SetEvent(ui.__mem_func__(self.__OnClickSelectGuildSymbolButton)) - page.declareWarButton.SetEvent(ui.__mem_func__(self.__OnClickDeclareWarButton)) - page.GetChild("OfferButton").SetEvent(ui.__mem_func__(self.__OnClickOfferButton)) - page.GetChild("EnemyGuildCancel1").Hide() - page.GetChild("EnemyGuildCancel2").Hide() - page.GetChild("EnemyGuildCancel3").Hide() - page.GetChild("EnemyGuildCancel4").Hide() - page.GetChild("EnemyGuildCancel5").Hide() - page.GetChild("EnemyGuildCancel6").Hide() - - self.enemyGuildNameList.append(page.GetChild("EnemyGuildName1")) - self.enemyGuildNameList.append(page.GetChild("EnemyGuildName2")) - self.enemyGuildNameList.append(page.GetChild("EnemyGuildName3")) - self.enemyGuildNameList.append(page.GetChild("EnemyGuildName4")) - self.enemyGuildNameList.append(page.GetChild("EnemyGuildName5")) - self.enemyGuildNameList.append(page.GetChild("EnemyGuildName6")) - - self.largeMarkBox = page.GetChild("LargeGuildMark") - except: - import exception - exception.Abort("GuildWindow.__MakeInfoPage") - - self.largeMarkBox.AddFlag("not_pick") - - self.markSelectDialog=uiUploadMark.MarkSelectDialog() - self.markSelectDialog.SAFE_SetSelectEvent(self.__OnSelectMark) - - self.symbolSelectDialog=uiUploadMark.SymbolSelectDialog() - self.symbolSelectDialog.SAFE_SetSelectEvent(self.__OnSelectSymbol) - - - def __MakeBoardPage(self): - - i = 0 - lineStep = 20 - page = self.pageWindow["BOARD"] - - page.boardDict = {} - - for i in range(12): - - yPos = 25 + i * lineStep - - ## NoticeMark - noticeMarkImage = ui.MakeImageBox(page, "d:/ymir work/ui/game/guild/notice_mark.sub", 5, yPos+3) - noticeMarkImage.Hide() - page.Children.append(noticeMarkImage) - - ## Name - ## 13.12.02 Arabic modification - if app.IsRTL(): - nameSlotImage = ui.MakeImageBox(page, "d:/ymir work/ui/public/Parameter_Slot_03.sub", 255, yPos) - else: - nameSlotImage = ui.MakeImageBox(page, "d:/ymir work/ui/public/Parameter_Slot_03.sub", 15, yPos) - nameSlot = ui.MakeTextLine(nameSlotImage) - page.Children.append(nameSlotImage) - page.Children.append(nameSlot) - - ## Delete Button - if app.IsRTL(): - deleteButton = ui.MakeButton(page, 3, yPos + 3, localeInfo.GUILD_DELETE, "d:/ymir work/ui/public/", "close_button_01.sub", "close_button_02.sub", "close_button_03.sub") - else: - deleteButton = ui.MakeButton(page, 340, yPos + 3, localeInfo.GUILD_DELETE, "d:/ymir work/ui/public/", "close_button_01.sub", "close_button_02.sub", "close_button_03.sub") - deleteButton.SetEvent(ui.__mem_func__(self.OnDeleteComment), i) - page.Children.append(deleteButton) - - ## Comment - ## 13.12.02 Arabic modification - commentSlot = CommentSlot() - commentSlot.SetParent(page) - if app.IsRTL(): - commentSlot.SetPosition(25, yPos) - else: - commentSlot.SetPosition(114, yPos) - commentSlot.Show() - page.Children.append(commentSlot) - - boardSlotList = [] - boardSlotList.append(noticeMarkImage) - boardSlotList.append(nameSlot) - boardSlotList.append(commentSlot) - page.boardDict[i] = boardSlotList - - ## PostComment - Have to make this here for that fit tooltip's position. - ## 13.12.02 Arabic modification - if app.IsRTL(): - postCommentButton = ui.MakeButton(page, 3, 273, localeInfo.GUILD_COMMENT, "d:/ymir work/ui/game/taskbar/", "Send_Chat_Button_01.sub", "Send_Chat_Button_02.sub", "Send_Chat_Button_03.sub") - else: - postCommentButton = ui.MakeButton(page, 337, 273, localeInfo.GUILD_COMMENT, "d:/ymir work/ui/game/taskbar/", "Send_Chat_Button_01.sub", "Send_Chat_Button_02.sub", "Send_Chat_Button_03.sub") - postCommentButton.SetEvent(ui.__mem_func__(self.OnPostComment)) - page.Children.append(postCommentButton) - - def __MakeMemberPage(self): - - page = self.pageWindow["MEMBER"] - - lineStep = 20 - page.memberDict = {} - - for i in range(self.MEMBER_LINE_COUNT): - - inverseLineIndex = self.MEMBER_LINE_COUNT - i - 1 - yPos = 28 + inverseLineIndex*lineStep - ## 13.12.02 Arabic modification - ## Name - if app.IsRTL(): - nameSlotImage = ui.MakeImageBox(page, "d:/ymir work/ui/public/Parameter_Slot_100x18.sub", 255, yPos) - else: - nameSlotImage = ui.MakeImageBox(page, "d:/ymir work/ui/public/Parameter_Slot_03.sub", 10, yPos) - nameSlot = ui.MakeTextLine(nameSlotImage) - page.Children.append(nameSlotImage) - page.Children.append(nameSlot) - - ## Grade - gradeSlot = ui.ComboBox() - gradeSlot.SetParent(page) - if app.IsRTL(): - gradeSlot.SetPosition(192, yPos-1) - else: - gradeSlot.SetPosition(101, yPos-1) - gradeSlot.SetSize(61, 18) - gradeSlot.SetEvent(lambda gradeNumber, lineIndex=inverseLineIndex, argSelf=proxy(self): argSelf.OnChangeMemberGrade(lineIndex, gradeNumber)) - gradeSlot.Show() - page.Children.append(gradeSlot) - - ## Job - if app.IsRTL(): - jobSlotImage = ui.MakeImageBox(page, "d:/ymir work/ui/public/Parameter_Slot_00.sub", 145, yPos) - else: - jobSlotImage = ui.MakeImageBox(page, "d:/ymir work/ui/public/Parameter_Slot_00.sub", 170, yPos) - jobSlot = ui.MakeTextLine(jobSlotImage) - page.Children.append(jobSlotImage) - page.Children.append(jobSlot) - - ## Level - if app.IsRTL(): - levelSlotImage = ui.MakeImageBox(page, "d:/ymir work/ui/public/Parameter_Slot_00.sub", 106, yPos) - else: - levelSlotImage = ui.MakeImageBox(page, "d:/ymir work/ui/public/Parameter_Slot_00.sub", 210, yPos) - levelSlot = ui.MakeTextLine(levelSlotImage) - page.Children.append(levelSlotImage) - page.Children.append(levelSlot) - - ## Offer - if app.IsRTL(): - offerSlotImage = ui.MakeImageBox(page, "d:/ymir work/ui/public/Parameter_Slot_00.sub", 66, yPos) - else: - offerSlotImage = ui.MakeImageBox(page, "d:/ymir work/ui/public/Parameter_Slot_00.sub", 250, yPos) - offerSlot = ui.MakeTextLine(offerSlotImage) - page.Children.append(offerSlotImage) - page.Children.append(offerSlot) - - ## General Enable - event = lambda argSelf=proxy(self), argIndex=inverseLineIndex: argSelf.OnEnableGeneral(*(argIndex,)) - if app.IsRTL(): - generalEnableCheckBox = CheckBox(page, 22, yPos, event, "d:/ymir work/ui/public/Parameter_Slot_00.sub") - else: - generalEnableCheckBox = CheckBox(page, 297, yPos, event, "d:/ymir work/ui/public/Parameter_Slot_00.sub") - page.Children.append(generalEnableCheckBox) - - memberSlotList = [] - memberSlotList.append(nameSlot) - memberSlotList.append(gradeSlot) - memberSlotList.append(jobSlot) - memberSlotList.append(levelSlot) - memberSlotList.append(offerSlot) - memberSlotList.append(generalEnableCheckBox) - page.memberDict[inverseLineIndex] = memberSlotList - - def __MakeBaseInfoPage(self): - - page = self.pageWindow["BASE_INFO"] - - page.buildingDataDict = {} - - lineStep = 20 - GUILD_BUILDING_MAX_NUM = 7 - - yPos = 95 + 35 - - for i in range(GUILD_BUILDING_MAX_NUM): - - nameSlotImage = ui.MakeSlotBar(page, 15, yPos, 78, 17) - nameSlot = ui.MakeTextLine(nameSlotImage) - page.Children.append(nameSlotImage) - page.Children.append(nameSlot) - nameSlot.SetText(localeInfo.GUILD_BUILDING_NAME) - - gradeSlotImage = ui.MakeSlotBar(page, 99, yPos, 26, 17) - gradeSlot = ui.MakeTextLine(gradeSlotImage) - page.Children.append(gradeSlotImage) - page.Children.append(gradeSlot) - gradeSlot.SetText(localeInfo.GUILD_BUILDING_GRADE) - - RESOURCE_MAX_NUM = 6 - for j in range(RESOURCE_MAX_NUM): - resourceSlotImage = ui.MakeSlotBar(page, 131 + 29*j, yPos, 26, 17) - resourceSlot = ui.MakeTextLine(resourceSlotImage) - page.Children.append(resourceSlotImage) - page.Children.append(resourceSlot) - resourceSlot.SetText(localeInfo.GUILD_GEM) - - event = lambda *arg: None - powerSlot = CheckBox(page, 308, yPos, event, "d:/ymir work/ui/public/Parameter_Slot_00.sub") - page.Children.append(powerSlot) - - yPos += lineStep - - def __MakeSkillPage(self): - - page = self.pageWindow["SKILL"] - - page.skillPoint = page.GetChild("Skill_Plus_Value") - page.passiveSlot = page.GetChild("Passive_Skill_Slot_Table") - page.activeSlot = page.GetChild("Active_Skill_Slot_Table") - page.affectSlot = page.GetChild("Affect_Slot_Table") - page.gpGauge = page.GetChild("Dragon_God_Power_Gauge") - page.gpValue = page.GetChild("Dragon_God_Power_Value") - page.btnHealGSP = page.GetChild("Heal_GSP_Button") - - page.activeSlot.SetSlotStyle(wndMgr.SLOT_STYLE_NONE) - page.activeSlot.SetOverInItemEvent(lambda slotNumber, type=self.GUILD_SKILL_ACTIVE_SLOT: self.OverInItem(slotNumber, type)) - page.activeSlot.SetOverOutItemEvent(ui.__mem_func__(self.OverOutItem)) - page.activeSlot.SetSelectItemSlotEvent(lambda slotNumber, type=self.GUILD_SKILL_ACTIVE_SLOT: self.OnPickUpGuildSkill(slotNumber, type)) - page.activeSlot.SetUnselectItemSlotEvent(lambda slotNumber, type=self.GUILD_SKILL_ACTIVE_SLOT: self.OnUseGuildSkill(slotNumber, type)) - page.activeSlot.SetPressedSlotButtonEvent(lambda slotNumber, type=self.GUILD_SKILL_ACTIVE_SLOT: self.OnUpGuildSkill(slotNumber, type)) - page.activeSlot.AppendSlotButton("d:/ymir work/ui/game/windows/btn_plus_up.sub",\ - "d:/ymir work/ui/game/windows/btn_plus_over.sub",\ - "d:/ymir work/ui/game/windows/btn_plus_down.sub") - page.passiveSlot.SetSlotStyle(wndMgr.SLOT_STYLE_NONE) - page.passiveSlot.SetOverInItemEvent(lambda slotNumber, type=self.GUILD_SKILL_PASSIVE_SLOT: self.OverInItem(slotNumber, type)) - page.passiveSlot.SetOverOutItemEvent(ui.__mem_func__(self.OverOutItem)) - page.passiveSlot.SetPressedSlotButtonEvent(lambda slotNumber, type=self.GUILD_SKILL_PASSIVE_SLOT: self.OnUpGuildSkill(slotNumber, type)) - page.passiveSlot.AppendSlotButton("d:/ymir work/ui/game/windows/btn_plus_up.sub",\ - "d:/ymir work/ui/game/windows/btn_plus_over.sub",\ - "d:/ymir work/ui/game/windows/btn_plus_down.sub") - page.affectSlot.SetSlotStyle(wndMgr.SLOT_STYLE_NONE) - page.affectSlot.SetOverInItemEvent(lambda slotNumber, type=self.GUILD_SKILL_AFFECT_SLOT: self.OverInItem(slotNumber, type)) - page.affectSlot.SetOverOutItemEvent(ui.__mem_func__(self.OverOutItem)) - page.btnHealGSP.SetEvent(ui.__mem_func__(self.__OnOpenHealGSPBoard)) - - ## Passive - """ - for i in range(len(playerSettingModule.PASSIVE_GUILD_SKILL_INDEX_LIST)): - - slotIndex = page.passiveSlot.GetStartIndex()+i - skillIndex = playerSettingModule.PASSIVE_GUILD_SKILL_INDEX_LIST[i] - - page.passiveSlot.SetSkillSlot(slotIndex, skillIndex, 0) - page.passiveSlot.RefreshSlot() - guild.SetSkillIndex(slotIndex, i) - """ - - ## Active - for i in range(len(playerSettingModule.ACTIVE_GUILD_SKILL_INDEX_LIST)): - - slotIndex = page.activeSlot.GetStartIndex()+i - skillIndex = playerSettingModule.ACTIVE_GUILD_SKILL_INDEX_LIST[i] - - page.activeSlot.SetSkillSlot(slotIndex, skillIndex, 0) - page.activeSlot.SetCoverButton(slotIndex) - page.activeSlot.RefreshSlot() - guild.SetSkillIndex(slotIndex, len(playerSettingModule.PASSIVE_GUILD_SKILL_INDEX_LIST)+i) - - def __MakeGradePage(self): - - lineStep = 18 - page = self.pageWindow["GRADE"] - - page.gradeDict = {} - - for i in range(15): - - yPos = 22 + i*lineStep - index = i+1 - ## 13.12.02 Arabic modification - ## GradeNumber - if app.IsRTL(): - gradeNumberSlotImage = ui.MakeImageBox(page, "d:/ymir work/ui/public/Parameter_Slot_00.sub", 310, yPos) - else: - gradeNumberSlotImage = ui.MakeImageBox(page, "d:/ymir work/ui/public/Parameter_Slot_00.sub", 14, yPos) - gradeNumberSlot = ui.MakeTextLine(gradeNumberSlotImage) - gradeNumberSlot.SetText(str(i+1)) - page.Children.append(gradeNumberSlotImage) - page.Children.append(gradeNumberSlot) - - ## GradeName - if app.IsRTL(): - gradeNameSlot = EditableTextSlot(page, 242, yPos) - else: - gradeNameSlot = EditableTextSlot(page, 58, yPos) - gradeNameSlot.SetEvent(ui.__mem_func__(self.OnOpenChangeGradeName), index) - page.Children.append(gradeNameSlot) - - ## Invite Authority - event = lambda argSelf=proxy(self), argIndex=index, argAuthority=1<<0: argSelf.OnCheckAuthority(*(argIndex,argAuthority)) - if app.IsRTL(): - inviteAuthorityCheckBox = CheckBox(page, 185, yPos, event) - else: - inviteAuthorityCheckBox = CheckBox(page, 124, yPos, event) - page.Children.append(inviteAuthorityCheckBox) - - ## DriveOut Authority - event = lambda argSelf=proxy(self), argIndex=index, argAuthority=1<<1: argSelf.OnCheckAuthority(*(argIndex,argAuthority)) - if app.IsRTL(): - driveoutAuthorityCheckBox = CheckBox(page, 128, yPos, event) - else: - driveoutAuthorityCheckBox = CheckBox(page, 181, yPos, event) - page.Children.append(driveoutAuthorityCheckBox) - - ## Notice Authority - event = lambda argSelf=proxy(self), argIndex=index, argAuthority=1<<2: argSelf.OnCheckAuthority(*(argIndex,argAuthority)) - if app.IsRTL(): - noticeAuthorityCheckBox = CheckBox(page, 71, yPos, event) - else: - noticeAuthorityCheckBox = CheckBox(page, 238, yPos, event) - page.Children.append(noticeAuthorityCheckBox) - - ## Skill Authority - event = lambda argSelf=proxy(self), argIndex=index, argAuthority=1<<3: argSelf.OnCheckAuthority(*(argIndex,argAuthority)) - if app.IsRTL(): - skillAuthorityCheckBox = CheckBox(page, 14, yPos, event) - else: - skillAuthorityCheckBox = CheckBox(page, 295, yPos, event) - page.Children.append(skillAuthorityCheckBox) - - gradeSlotList = [] - gradeSlotList.append(gradeNameSlot) - gradeSlotList.append(inviteAuthorityCheckBox) - gradeSlotList.append(driveoutAuthorityCheckBox) - gradeSlotList.append(noticeAuthorityCheckBox) - gradeSlotList.append(skillAuthorityCheckBox) - page.gradeDict[index] = gradeSlotList - - masterSlotList = page.gradeDict[1] - for slot in masterSlotList: - slot.Disable() - - def CanOpen(self): - return guild.IsGuildEnable() - - def Open(self): - self.Show() - self.SetTop() - - guildID = net.GetGuildID() - self.largeMarkBox.SetIndex(guildID) - self.largeMarkBox.SetScale(3) - ## 13.12.02 Arabic modification - - if app.IsRTL(): - self.largeMarkBox.SetPosition(self.largeMarkBox.GetWidth()+32,1) - - def Close(self): - self.__CloseAllGuildMemberPageGradeComboBox() - self.offerDialog.Close() - self.popupDialog.Hide() - self.changeGradeNameDialog.Hide() - self.Hide() - - if self.tooltipSkill: - self.tooltipSkill.Hide() - - self.pickDialog = None - self.questionDialog = None - self.moneyDialog = None - - def Destroy(self): - self.ClearDictionary() - self.board = None - self.pageName = None - self.tabDict = None - self.tabButtonDict = None - self.pickDialog = None - self.questionDialog = None - self.markSelectDialog = None - self.symbolSelectDialog = None - - if self.offerDialog: - self.offerDialog.Destroy() - self.offerDialog = None - - if self.popupDialog: - self.popupDialog.ClearDictionary() - self.popupDialog = None - - if self.changeGradeNameDialog: - self.changeGradeNameDialog.ClearDictionary() - self.changeGradeNameDialog = None - - self.popupMessage = None - self.commentSlot = None - - if self.pageWindow: - for window in list(self.pageWindow.values()): - window.ClearDictionary() - - self.pageWindow = None - self.tooltipSkill = None - self.moneyDialog = None - - self.enemyGuildNameList = [] - - def DeleteGuild(self): - self.RefreshGuildInfoPage() - self.RefreshGuildBoardPage() - self.RefreshGuildMemberPage() - self.RefreshGuildSkillPage() - self.RefreshGuildGradePage() - self.Hide() - - def SetSkillToolTip(self, tooltipSkill): - self.tooltipSkill = tooltipSkill - - def SelectPage(self, arg): - - if "BOARD" == arg: - self.OnRefreshComments() - - for key, btn in list(self.tabButtonDict.items()): - if arg != key: - btn.SetUp() - for key, img in list(self.tabDict.items()): - if arg == key: - img.Show() - else: - img.Hide() - for key, page in list(self.pageWindow.items()): - if arg == key: - page.Show() - else: - page.Hide() - self.board.SetTitleName(self.pageName[arg]) - self.__CloseAllGuildMemberPageGradeComboBox() - - def __CloseAllGuildMemberPageGradeComboBox(self): - - page = self.pageWindow["MEMBER"] - for key, slotList in list(page.memberDict.items()): - slotList[1].CloseListBox() - - def RefreshGuildInfoPage(self): - - if self.isLoaded==0: - return - - global DISABLE_DECLARE_WAR - - page = self.pageWindow["GUILD_INFO"] - - page.nameSlot.SetText(guild.GetGuildName()) - page.masterNameSlot.SetText(guild.GetGuildMasterName()) - page.guildLevelSlot.SetText(str(guild.GetGuildLevel())) - - if page.guildMoneySlot: - page.guildMoneySlot.SetText(str(guild.GetGuildMoney())) - - curExp, lastExp = guild.GetGuildExperience() - curExp *= 100 - lastExp *= 100 - - page.curExpSlot.SetText(str(curExp)) - page.lastExpSlot.SetText(str(lastExp)) - - curMemberCount, maxMemberCount = guild.GetGuildMemberCount() - - if maxMemberCount == 0xffff: - page.memberCountSlot.SetText("%d / %s " % (curMemberCount, localeInfo.GUILD_MEMBER_COUNT_INFINITY)) - else: - page.memberCountSlot.SetText("%d / %d" % (curMemberCount, maxMemberCount)) - - page.levelAverageSlot.SetText(str(guild.GetGuildMemberLevelAverage())) - - ## Only guild master can see guild mark and guild war request buttons - mainCharacterName = player.GetMainCharacterName() - masterName = guild.GetGuildMasterName() - - if mainCharacterName == masterName: - page.uploadMarkButton.Show() - - if DISABLE_DECLARE_WAR: - page.declareWarButton.Hide() - else: - page.declareWarButton.Show() - - if guild.HasGuildLand(): - page.uploadSymbolButton.Show() - else: - page.uploadSymbolButton.Hide() - else: - page.uploadMarkButton.Hide() - page.declareWarButton.Hide() - page.uploadSymbolButton.Hide() - - ## Update guild war information on refresh - for i in range(guild.ENEMY_GUILD_SLOT_MAX_COUNT): - name = guild.GetEnemyGuildName(i) - nameTextLine = self.enemyGuildNameList[i] - if name: - nameTextLine.SetText(name) - else: - nameTextLine.SetText(localeInfo.GUILD_INFO_ENEMY_GUILD_EMPTY) - - def __GetGuildBoardCommentData(self, index): - commentID, chrName, comment = guild.GetGuildBoardCommentData(index) - if 0==commentID: - if ""==chrName: - chrName=localeInfo.UI_NONAME - if ""==comment: - comment=localeInfo.UI_NOCONTENTS - - return commentID, chrName, comment - - def RefreshGuildBoardPage(self): - - if self.isLoaded==0: - return - - page = self.pageWindow["BOARD"] - - self.BOARD_LINE_MAX_NUM = 12 - lineIndex = 0 - - commentCount = guild.GetGuildBoardCommentCount() - for i in range(commentCount): - - commentID, chrName, comment = self.__GetGuildBoardCommentData(i) - - if not comment: - continue - - slotList = page.boardDict[lineIndex] - - if "!" == comment[0]: - slotList[0].Show() - slotList[1].SetText(chrName) - slotList[2].SetText(comment[1:]) - - else: - slotList[0].Hide() - slotList[1].SetText(chrName) - slotList[2].SetText(comment) - - lineIndex += 1 - - for i in range(self.BOARD_LINE_MAX_NUM - lineIndex): - slotList = page.boardDict[lineIndex+i] - slotList[0].Hide() - slotList[1].SetText("") - slotList[2].SetText("") - - def RefreshGuildMemberPage(self): - - if self.isLoaded==0: - return - - page = self.pageWindow["MEMBER"] - - ## ScrollBar - count = guild.GetMemberCount() - if count > self.MEMBER_LINE_COUNT: - page.scrollBar.SetMiddleBarSize(float(self.MEMBER_LINE_COUNT) / float(count)) - page.scrollBar.Show() - else: - page.scrollBar.Hide() - self.RefreshGuildMemberPageGradeComboBox() - self.RefreshGuildMemberPageMemberList() - - def RefreshGuildMemberPageMemberList(self): - - if self.isLoaded==0: - return - - page = self.pageWindow["MEMBER"] - - for line, slotList in list(page.memberDict.items()): - - gradeComboBox = slotList[1] - gradeComboBox.Disable() - - if not guild.IsMember(line): - slotList[0].SetText("") - slotList[2].SetText("") - slotList[3].SetText("") - slotList[4].SetText("") - slotList[5].SetCheck(False) - continue - - pid, name, grade, race, level, offer, general = self.GetMemberData(line) - if pid < 0: - continue - - job = chr.RaceToJob(race) - - guildExperienceSummary = guild.GetGuildExperienceSummary() - - offerPercentage = 0 - if guildExperienceSummary > 0: - offerPercentage = int(float(offer) / float(guildExperienceSummary) * 100.0) - - slotList[0].SetText(name) - slotList[2].SetText(self.JOB_NAME.get(job, "?")) - slotList[3].SetText(str(level)) - slotList[4].SetText(str(offerPercentage) + "%") - slotList[5].SetCheck(general) - gradeComboBox.SetCurrentItem(guild.GetGradeName(grade)) - if 1 != grade: - gradeComboBox.Enable() - - def RefreshGuildMemberPageGradeComboBox(self): - - if self.isLoaded==0: - return - - page = self.pageWindow["MEMBER"] - - self.CAN_CHANGE_GRADE_COUNT = 15 - 1 - for key, slotList in list(page.memberDict.items()): - - gradeComboBox = slotList[1] - gradeComboBox.Disable() - - if not guild.IsMember(key): - continue - - pid, name, grade, job, level, offer, general = self.GetMemberData(key) - if pid < 0: - continue - - gradeComboBox.ClearItem() - for i in range(self.CAN_CHANGE_GRADE_COUNT): - gradeComboBox.InsertItem(i+2, guild.GetGradeName(i+2)) - gradeComboBox.SetCurrentItem(guild.GetGradeName(grade)) - if 1 != grade: - gradeComboBox.Enable() - - def RefreshGuildSkillPage(self): - - if self.isLoaded==0: - return - - page = self.pageWindow["SKILL"] - - curPoint, maxPoint = guild.GetDragonPowerPoint() - maxPoint = max(maxPoint, 1) - page.gpValue.SetText(str(curPoint) + " / " + str(maxPoint)) - - percentage = (float(curPoint) / float(maxPoint) * 100) * (float(173) / float(95)) - page.gpGauge.SetPercentage(int(percentage), 100) - - skillPoint = guild.GetGuildSkillPoint() - page.skillPoint.SetText(str(skillPoint)) - - page.passiveSlot.HideAllSlotButton() - page.activeSlot.HideAllSlotButton() - - ## Passive - """ - for i in xrange(len(playerSettingModule.PASSIVE_GUILD_SKILL_INDEX_LIST)): - - slotIndex = page.passiveSlot.GetStartIndex()+i - skillIndex = playerSettingModule.PASSIVE_GUILD_SKILL_INDEX_LIST[i] - skillLevel = guild.GetSkillLevel(slotIndex) - skillMaxLevel = skill.GetSkillMaxLevel(skillIndex) - - page.passiveSlot.SetSlotCount(slotIndex, skillLevel) - if skillPoint > 0: - if skillLevel < skillMaxLevel: - page.passiveSlot.ShowSlotButton(slotIndex) - """ - - ## Active - for i in range(len(playerSettingModule.ACTIVE_GUILD_SKILL_INDEX_LIST)): - - slotIndex = page.activeSlot.GetStartIndex()+i - skillIndex = playerSettingModule.ACTIVE_GUILD_SKILL_INDEX_LIST[i] - skillLevel = guild.GetSkillLevel(slotIndex) - skillMaxLevel = skill.GetSkillMaxLevel(skillIndex) - - page.activeSlot.SetSlotCount(slotIndex, skillLevel) - - if skillLevel <= 0: - page.activeSlot.DisableCoverButton(slotIndex) - else: - page.activeSlot.EnableCoverButton(slotIndex) - - if skillPoint > 0: - if skillLevel < skillMaxLevel: - page.activeSlot.ShowSlotButton(slotIndex) - - def RefreshGuildGradePage(self): - - if self.isLoaded==0: - return - - page = self.pageWindow["GRADE"] - - for key, slotList in list(page.gradeDict.items()): - name, authority = guild.GetGradeData(int(key)) - - slotList[self.GRADE_SLOT_NAME].SetText(name) - slotList[self.GRADE_ADD_MEMBER_AUTHORITY].SetCheck(authority & guild.AUTH_ADD_MEMBER) - slotList[self.GRADE_REMOVE_MEMBER_AUTHORITY].SetCheck(authority & guild.AUTH_REMOVE_MEMBER) - slotList[self.GRADE_NOTICE_AUTHORITY].SetCheck(authority & guild.AUTH_NOTICE) - slotList[self.GRADE_SKILL_AUTHORITY].SetCheck(authority & guild.AUTH_SKILL) - - ## GuildInfo - - def __PopupMessage(self, msg): - self.popupMessage.SetText(msg) - self.popupDialog.SetTop() - self.popupDialog.Show() - - def __OnClickSelectGuildMarkButton(self): - if guild.GetGuildLevel() < int(localeInfo.GUILD_MARK_MIN_LEVEL): - self.__PopupMessage(localeInfo.GUILD_MARK_NOT_ENOUGH_LEVEL) - elif not guild.MainPlayerHasAuthority(guild.AUTH_NOTICE): - self.__PopupMessage(localeInfo.GUILD_NO_NOTICE_PERMISSION) - else: - self.markSelectDialog.Open() - - def __OnClickSelectGuildSymbolButton(self): - if guild.MainPlayerHasAuthority(guild.AUTH_NOTICE): - self.symbolSelectDialog.Open() - else: - self.__PopupMessage(localeInfo.GUILD_NO_NOTICE_PERMISSION) - - def __OnClickDeclareWarButton(self): - inputDialog = DeclareGuildWarDialog() - inputDialog.Open() - self.inputDialog = inputDialog - - def __OnSelectMark(self, markFileName): - ret = net.UploadMark("upload/"+markFileName) - - # MARK_BUG_FIX - if net.ERROR_MARK_UPLOAD_NEED_RECONNECT == ret: - self.__PopupMessage(localeInfo.UPLOAD_MARK_UPLOAD_NEED_RECONNECT); - - return ret - # END_OF_MARK_BUG_FIX - - def __OnSelectSymbol(self, symbolFileName): - net.UploadSymbol("upload/"+symbolFileName) - - def __OnClickOfferButton(self): - - curEXP = unsigned32(player.GetStatus(player.EXP)) - - if curEXP <= 100: - self.__PopupMessage(localeInfo.GUILD_SHORT_EXP); - return - - self.offerDialog.Open(curEXP, 100) - - def __OnClickDepositButton(self): - moneyDialog = uiPickMoney.PickMoneyDialog() - moneyDialog.LoadDialog() - moneyDialog.SetMax(6) - moneyDialog.SetTitleName(localeInfo.GUILD_DEPOSIT) - moneyDialog.SetAcceptEvent(ui.__mem_func__(self.OnDeposit)) - moneyDialog.Open(player.GetMoney()) - self.moneyDialog = moneyDialog - - def __OnClickWithdrawButton(self): - moneyDialog = uiPickMoney.PickMoneyDialog() - moneyDialog.LoadDialog() - moneyDialog.SetMax(6) - moneyDialog.SetTitleName(localeInfo.GUILD_WITHDRAW) - moneyDialog.SetAcceptEvent(ui.__mem_func__(self.OnWithdraw)) - moneyDialog.Open(guild.GetGuildMoney()) - self.moneyDialog = moneyDialog - - def __OnBlock(self): - popup = uiCommon.PopupDialog() - popup.SetText(localeInfo.NOT_YET_SUPPORT) - popup.SetAcceptEvent(self.__OnClosePopupDialog) - popup.Open() - self.popup = popup - - def __OnClosePopupDialog(self): - self.popup = None - - def OnDeposit(self, money): - net.SendGuildDepositMoneyPacket(money) - - def OnWithdraw(self, money): - net.SendGuildWithdrawMoneyPacket(money) - - def OnOffer(self, exp): - net.SendGuildOfferPacket(exp) - - ## Board - def OnPostComment(self): - - text = self.commentSlot.GetText() - if not text: - return False - - net.SendGuildPostCommentPacket(text[:50]) - self.commentSlot.SetText("") - return True - - def OnDeleteComment(self, index): - - commentID, chrName, comment = self.__GetGuildBoardCommentData(index) - net.SendGuildDeleteCommentPacket(commentID) - - def OnRefreshComments(self): - net.SendGuildRefreshCommentsPacket(0) - - def OnKeyDownInBoardPage(self, key): - if key == 63: - self.OnRefreshComments() - return True - - ## Member - ## OnEnableGeneral - def OnChangeMemberGrade(self, lineIndex, gradeNumber): - PID = guild.MemberIndexToPID(lineIndex + self.memberLinePos) - net.SendGuildChangeMemberGradePacket(PID, gradeNumber) - - def OnEnableGeneral(self, lineIndex): - if not guild.IsMember(lineIndex): - return - - pid, name, grade, job, level, offer, general = self.GetMemberData(lineIndex) - if pid < 0: - return - - net.SendGuildChangeMemberGeneralPacket(pid, 1 - general) - - ## Grade - def OnOpenChangeGradeName(self, arg): - self.changeGradeNameDialog.SetGradeNumber(arg) - self.changeGradeNameDialog.Open() - - def OnChangeGradeName(self): - self.changeGradeNameDialog.Hide() - gradeNumber = self.changeGradeNameDialog.GetGradeNumber() - gradeName = self.changeGradeNameDialog.GetGradeName() - - if len(gradeName) == 0: - gradeName = localeInfo.GUILD_DEFAULT_GRADE - - net.SendGuildChangeGradeNamePacket(gradeNumber, gradeName) - return True - - def OnCheckAuthority(self, argIndex, argAuthority): - name, authority = guild.GetGradeData(argIndex) - net.SendGuildChangeGradeAuthorityPacket(argIndex, authority ^ argAuthority) - - def OnScrollMemberLine(self): - scrollBar = self.pageWindow["MEMBER"].scrollBar - pos = scrollBar.GetPos() - - count = guild.GetMemberCount() - newLinePos = int(float(count - self.MEMBER_LINE_COUNT) * pos) - - if newLinePos != self.memberLinePos: - self.memberLinePos = newLinePos - self.RefreshGuildMemberPageMemberList() - self.__CloseAllGuildMemberPageGradeComboBox() - - def GetMemberData(self, localPos): - return guild.GetMemberData(localPos + self.memberLinePos) - - ## Guild Skill - def __OnOpenHealGSPBoard(self): - - curPoint, maxPoint = guild.GetDragonPowerPoint() - - if maxPoint - curPoint <= 0: - self.__PopupMessage(localeInfo.GUILD_CANNOT_HEAL_GSP_ANYMORE) - return - - pickDialog = uiPickMoney.PickMoneyDialog() - pickDialog.LoadDialog() - pickDialog.SetMax(9) - pickDialog.SetTitleName(localeInfo.GUILD_HEAL_GSP) - pickDialog.SetAcceptEvent(ui.__mem_func__(self.__OnOpenHealGSPQuestionDialog)) - pickDialog.Open(maxPoint - curPoint, 1) - self.pickDialog = pickDialog - - def __OnOpenHealGSPQuestionDialog(self, healGSP): - - money = healGSP * constInfo.GUILD_MONEY_PER_GSP - - questionDialog = uiCommon.QuestionDialog() - questionDialog.SetText(localeInfo.GUILD_DO_YOU_HEAL_GSP % (money, healGSP)) - questionDialog.SetAcceptEvent(ui.__mem_func__(self.__OnHealGSP)) - questionDialog.SetCancelEvent(ui.__mem_func__(self.__OnCloseQuestionDialog)) - questionDialog.SetWidth(400) - questionDialog.Open() - questionDialog.healGSP = healGSP - self.questionDialog = questionDialog - - def __OnHealGSP(self): - net.SendGuildChargeGSPPacket(self.questionDialog.healGSP) - self.__OnCloseQuestionDialog() - - def __OnCloseQuestionDialog(self): - if self.questionDialog: - self.questionDialog.Close() - self.questionDialog = None - - def OnPickUpGuildSkill(self, skillSlotIndex, type): - - mouseController = mouseModule.mouseController - - if False == mouseController.isAttached(): - - skillIndex = player.GetSkillIndex(skillSlotIndex) - skillLevel = guild.GetSkillLevel(skillSlotIndex) - - if skill.CanUseSkill(skillIndex) and skillLevel > 0: - - if app.IsPressed(app.DIK_LCONTROL): - - player.RequestAddToEmptyLocalQuickSlot(player.SLOT_TYPE_SKILL, skillSlotIndex) - return - - mouseController.AttachObject(self, player.SLOT_TYPE_SKILL, skillSlotIndex, skillIndex) - - else: - mouseController.DeattachObject() - - def OnUseGuildSkill(self, slotNumber, type): - skillIndex = player.GetSkillIndex(slotNumber) - skillLevel = guild.GetSkillLevel(slotNumber) - - if skillLevel <= 0: - return - - player.UseGuildSkill(slotNumber) - - def OnUpGuildSkill(self, slotNumber, type): - skillIndex = player.GetSkillIndex(slotNumber) - net.SendChatPacket("/gskillup " + str(skillIndex)) - - def OnUseSkill(self, slotNumber, coolTime): - - if self.isLoaded==0: - return - - page = self.pageWindow["SKILL"] - - if page.activeSlot.HasSlot(slotNumber): - page.activeSlot.SetSlotCoolTime(slotNumber, coolTime) - - def OnStartGuildWar(self, guildSelf, guildOpp): - - if self.isLoaded==0: - return - - if guild.GetGuildID() != guildSelf: - return - - guildName = guild.GetGuildName(guildOpp) - for guildNameTextLine in self.enemyGuildNameList: - if localeInfo.GUILD_INFO_ENEMY_GUILD_EMPTY == guildNameTextLine.GetText(): - guildNameTextLine.SetText(guildName) - return - - def OnEndGuildWar(self, guildSelf, guildOpp): - - if self.isLoaded==0: - return - - if guild.GetGuildID() != guildSelf: - return - - guildName = guild.GetGuildName(guildOpp) - for guildNameTextLine in self.enemyGuildNameList: - if guildName == guildNameTextLine.GetText(): - guildNameTextLine.SetText(localeInfo.GUILD_INFO_ENEMY_GUILD_EMPTY) - return - - ## ToolTip - def OverInItem(self, slotNumber, type): - - if mouseModule.mouseController.isAttached(): - return - - if None != self.tooltipSkill: - skillIndex = player.GetSkillIndex(slotNumber) - skillLevel = guild.GetSkillLevel(slotNumber) - - self.tooltipSkill.SetSkill(skillIndex, skillLevel) - - def OverOutItem(self): - if None != self.tooltipSkill: - self.tooltipSkill.HideToolTip() - - def OnPressEscapeKey(self): - self.Close() - return True - - -class BuildGuildBuildingWindow(ui.ScriptWindow): - - GUILD_CATEGORY_LIST = ( - ("HEADQUARTER", localeInfo.GUILD_HEADQUARTER), - ("FACILITY", localeInfo.GUILD_FACILITY), - ("OBJECT", localeInfo.GUILD_OBJECT), - ) - - MODE_VIEW = 0 - MODE_POSITIONING = 1 - MODE_PREVIEW = 2 - - BUILDING_ALPHA = 0.55 - - ENABLE_COLOR = grp.GenerateColor(0.7607, 0.7607, 0.7607, 1.0) - DISABLE_COLOR = grp.GenerateColor(0.9, 0.4745, 0.4627, 1.0) - - START_INSTANCE_INDEX = 123450 - #WALL_SET_INSTANCE = 14105 - - def __init__(self): - ui.ScriptWindow.__init__(self) - self.__LoadWindow() - - self.closeEvent = None - self.popup = None - self.mode = self.MODE_VIEW - self.race = 0 - self.type = None - self.x = 0 - self.y = 0 - self.z = 0 - self.rot_x = 0 - self.rot_y = 0 - self.rot_z = 0 - self.rot_x_limit = 0 - self.rot_y_limit = 0 - self.rot_z_limit = 0 - self.needMoney = 0 - self.needStoneCount = 0 - self.needLogCount = 0 - self.needPlywoodCount = 0 - - #self.index = 0 - self.indexList = [] - self.raceList = [] - self.posList = [] - self.rotList = [] - - index = 0 - for category in self.GUILD_CATEGORY_LIST: - self.categoryList.InsertItem(index, category[1]) - index += 1 - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def __LoadWindow(self): - - try: - pyScrLoader = ui.PythonScriptLoader() - if app.IsRTL(): - pyScrLoader.LoadScriptFile(self, uiScriptLocale.LOCALE_UISCRIPT_PATH + "buildguildbuildingwindow.py") - else: - pyScrLoader.LoadScriptFile(self, "uiscript/buildguildbuildingwindow.py") - except: - import exception - exception.Abort("DeclareGuildWarWindow.__CreateDialog - LoadScript") - - try: - getObject = self.GetChild - self.board = getObject("Board") - self.categoryList = getObject("CategoryList") - self.buildingList = getObject("BuildingList") - self.listScrollBar = getObject("ListScrollBar") - self.positionButton = getObject("PositionButton") - self.previewButton = getObject("PreviewButton") - self.posValueX = getObject("BuildingPositionXValue") - self.posValueY = getObject("BuildingPositionYValue") - self.ctrlRotationX = getObject("BuildingRotationX") - self.ctrlRotationY = getObject("BuildingRotationY") - self.ctrlRotationZ = getObject("BuildingRotationZ") - self.buildingPriceValue = getObject("BuildingPriceValue") - self.buildingMaterialStoneValue = getObject("BuildingMaterialStoneValue") - self.buildingMaterialLogValue = getObject("BuildingMaterialLogValue") - self.buildingMaterialPlywoodValue = getObject("BuildingMaterialPlywoodValue") - - self.positionButton.SetEvent(ui.__mem_func__(self.__OnSelectPositioningMode)) - self.previewButton.SetToggleDownEvent(ui.__mem_func__(self.__OnEnterPreviewMode)) - self.previewButton.SetToggleUpEvent(ui.__mem_func__(self.__OnLeavePreviewMode)) - self.ctrlRotationX.SetEvent(ui.__mem_func__(self.__OnChangeRotation)) - self.ctrlRotationY.SetEvent(ui.__mem_func__(self.__OnChangeRotation)) - self.ctrlRotationZ.SetEvent(ui.__mem_func__(self.__OnChangeRotation)) - self.listScrollBar.SetScrollEvent(ui.__mem_func__(self.__OnScrollBuildingList)) - - getObject("CategoryList").SetEvent(ui.__mem_func__(self.__OnSelectCategory)) - getObject("BuildingList").SetEvent(ui.__mem_func__(self.__OnSelectBuilding)) - getObject("AcceptButton").SetEvent(ui.__mem_func__(self.Build)) - getObject("CancelButton").SetEvent(ui.__mem_func__(self.Close)) - self.board.SetCloseEvent(ui.__mem_func__(self.Close)) - - except: - import exception - exception.Abort("BuildGuildBuildingWindow.__LoadWindow - BindObject") - - def __CreateWallBlock(self, race, x, y, rot=0.0 ): - idx = self.START_INSTANCE_INDEX + len(self.indexList) - self.indexList.append(idx) - self.raceList.append(race) - self.posList.append((x, y)) - self.rotList.append(rot) - chr.CreateInstance(idx) - chr.SelectInstance(idx) - chr.SetVirtualID(idx) - chr.SetInstanceType(chr.INSTANCE_TYPE_OBJECT) - - chr.SetRace(race) - chr.SetArmor(0) - chr.Refresh() - chr.SetLoopMotion(chr.MOTION_WAIT) - chr.SetBlendRenderMode(idx, self.BUILDING_ALPHA) - chr.SetRotationAll(0.0, 0.0, rot) - - self.ctrlRotationX.SetSliderPos(0.5) - self.ctrlRotationY.SetSliderPos(0.5) - self.ctrlRotationZ.SetSliderPos(0.5) - - def __GetObjectSize(self, race): - idx = self.START_INSTANCE_INDEX + 1000 - chr.CreateInstance(idx) - chr.SelectInstance(idx) - chr.SetVirtualID(idx) - chr.SetInstanceType(chr.INSTANCE_TYPE_OBJECT) - - chr.SetRace(race) - chr.SetArmor(0) - chr.Refresh() - chr.SetLoopMotion(chr.MOTION_WAIT) - sx, sy, ex, ey = chr.GetBoundBoxOnlyXY(idx) - chr.DeleteInstance(idx) - return sx, sy, ex, ey - - def __GetBuildInPosition(self): - - zList = [] - zList.append( background.GetHeight(self.x+self.sxPos, self.y+self.syPos) ) - zList.append( background.GetHeight(self.x+self.sxPos, self.y+self.eyPos) ) - zList.append( background.GetHeight(self.x+self.exPos, self.y+self.syPos) ) - zList.append( background.GetHeight(self.x+self.exPos, self.y+self.eyPos) ) - zList.append( background.GetHeight(self.x+(self.exPos+self.sxPos)/2, self.y+(self.eyPos+self.syPos)/2) ) - zList.sort() - return zList[3] - - def __CreateBuildInInstance(self,race): - - self.__DeleteInstance() - - object_base = race - race%10 - - door_minX, door_minY, door_maxX, door_maxY = self.__GetObjectSize(object_base+4) - corner_minX, corner_minY, corner_maxX, corner_maxY = self.__GetObjectSize(object_base+1) - line_minX, line_minY, line_maxX, line_maxY = self.__GetObjectSize(object_base+2) - line_width = line_maxX - line_minX - line_width_half = line_width / 2 - - X_SIZE_STEP = 2 * 2 ## Must increase only in units of 2 - Y_SIZE_STEP = 8 - sxPos = door_maxX - corner_minX + (line_width_half*X_SIZE_STEP) - exPos = -sxPos - syPos = 0 - eyPos = -(corner_maxY*2 + line_width*Y_SIZE_STEP) - - self.sxPos = sxPos - self.syPos = syPos - self.exPos = exPos - self.eyPos = eyPos - - z = self.__GetBuildInPosition() - - ## Door - self.__CreateWallBlock(object_base+4, 0.0, syPos) - - ## Corner - self.__CreateWallBlock(object_base+1, sxPos, syPos) - self.__CreateWallBlock(object_base+1, exPos, syPos, 270.0) - self.__CreateWallBlock(object_base+1, sxPos, eyPos, 90.0) - self.__CreateWallBlock(object_base+1, exPos, eyPos,180.0 ) - - ## Line - lineBlock = object_base+2 - line_startX = -door_maxX - line_minX - (line_width_half*X_SIZE_STEP) - self.__CreateWallBlock(lineBlock, line_startX, eyPos) - self.__CreateWallBlock(lineBlock, line_startX+line_width*1, eyPos) - self.__CreateWallBlock(lineBlock, line_startX+line_width*2, eyPos) - self.__CreateWallBlock(lineBlock, line_startX+line_width*3, eyPos) - for i in range(X_SIZE_STEP): - self.__CreateWallBlock(lineBlock, line_startX+line_width*(3+i+1), eyPos) - for i in range(X_SIZE_STEP/2): - self.__CreateWallBlock(lineBlock, door_minX - line_maxX - line_width*i, syPos) - self.__CreateWallBlock(lineBlock, door_maxX - line_minX + line_width*i, syPos) - for i in range(Y_SIZE_STEP): - self.__CreateWallBlock(lineBlock, sxPos, line_minX + corner_minX - line_width*i, 90.0) - self.__CreateWallBlock(lineBlock, exPos, line_minX + corner_minX - line_width*i, 90.0) - - self.SetBuildingPosition(int(self.x), int(self.y), self.__GetBuildInPosition()) - - def __DeleteInstance(self): - if not self.indexList: - return - - for index in self.indexList: - chr.DeleteInstance(index) - - self.indexList = [] - self.raceList = [] - self.posList = [] - self.rotList = [] - - def __CreateInstance(self, race): - - self.__DeleteInstance() - - self.race = race - - idx = self.START_INSTANCE_INDEX - self.indexList.append(idx) - self.posList.append((0, 0)) - self.rotList.append(0) - - chr.CreateInstance(idx) - chr.SelectInstance(idx) - chr.SetVirtualID(idx) - chr.SetInstanceType(chr.INSTANCE_TYPE_OBJECT) - - chr.SetRace(race) - chr.SetArmor(0) - chr.Refresh() - chr.SetLoopMotion(chr.MOTION_WAIT) - chr.SetBlendRenderMode(idx, self.BUILDING_ALPHA) - - self.SetBuildingPosition(int(self.x), int(self.y), 0) - self.ctrlRotationX.SetSliderPos(0.5) - self.ctrlRotationY.SetSliderPos(0.5) - self.ctrlRotationZ.SetSliderPos(0.5) - - def Build(self): - - if not self.__IsEnoughMoney(): - self.__PopupDialog(localeInfo.GUILD_NOT_ENOUGH_MONEY) - return - if not self.__IsEnoughMaterialStone(): - self.__PopupDialog(localeInfo.GUILD_NOT_ENOUGH_MATERIAL) - return - if not self.__IsEnoughMaterialLog(): - self.__PopupDialog(localeInfo.GUILD_NOT_ENOUGH_MATERIAL) - return - if not self.__IsEnoughMaterialPlywood(): - self.__PopupDialog(localeInfo.GUILD_NOT_ENOUGH_MATERIAL) - return - - ## /build c vnum x y x_rot y_rot z_rot - ## /build d vnum - if "BUILDIN" == self.type: - for i in range(len(self.raceList)): - race = self.raceList[i] - xPos, yPos = self.posList[i] - rot = self.rotList[i] - net.SendChatPacket("/build c %d %d %d %d %d %d" % (race, int(self.x+xPos), int(self.y+yPos), self.rot_x, self.rot_y, rot)) - else: - net.SendChatPacket("/build c %d %d %d %d %d %d" % (self.race, int(self.x), int(self.y), self.rot_x, self.rot_y, self.rot_z)) - - self.Close() - - def Open(self): - x, y, z = player.GetMainCharacterPosition() - app.SetCameraSetting(int(x), int(-y), int(z), 3000, 0, 30) - - background.VisibleGuildArea() - - self.x = x - self.y = y - self.z = z - self.categoryList.SelectItem(0) - self.buildingList.SelectItem(0) - self.SetTop() - self.Show() - self.__DisablePCBlocker() - - import debugInfo - if debugInfo.IsDebugMode(): - self.categoryList.SelectItem(2) - self.buildingList.SelectItem(0) - - def Close(self): - - self.__DeleteInstance() - - background.DisableGuildArea() - - self.Hide() - self.__OnClosePopupDialog() - self.__EnablePCBlocker() - self.__UnlockCameraMoving() - if self.closeEvent: - self.closeEvent() - - def Destory(self): - self.Close() - - self.ClearDictionary() - self.board = None - self.categoryList = None - self.buildingList = None - self.listScrollBar = None - self.positionButton = None - self.previewButton = None - self.posValueX = None - self.posValueY = None - self.ctrlRotationX = None - self.ctrlRotationY = None - self.ctrlRotationZ = None - self.buildingPriceValue = None - self.buildingMaterialStoneValue = None - self.buildingMaterialLogValue = None - self.buildingMaterialPlywoodValue = None - self.closeEvent = None - - def SetCloseEvent(self, event): - self.closeEvent = event - - def __PopupDialog(self, text): - popup = uiCommon.PopupDialog() - popup.SetText(text) - popup.SetAcceptEvent(self.__OnClosePopupDialog) - popup.Open() - self.popup = popup - - def __OnClosePopupDialog(self): - self.popup = None - - def __EnablePCBlocker(self): - ## Enable PC Blocker processing (becomes transparent) - chr.SetInstanceType(chr.INSTANCE_TYPE_BUILDING) - - for idx in self.indexList: - chr.SetBlendRenderMode(idx, 1.0) - - def __DisablePCBlocker(self): - ## Disable PC Blocker processing (stays opaque) - chr.SetInstanceType(chr.INSTANCE_TYPE_OBJECT) - - for idx in self.indexList: - chr.SetBlendRenderMode(idx, self.BUILDING_ALPHA) - - def __OnSelectPositioningMode(self): - if self.MODE_PREVIEW == self.mode: - self.positionButton.SetUp() - return - - self.mode = self.MODE_POSITIONING - self.Hide() - - def __OnEnterPreviewMode(self): - - if self.MODE_POSITIONING == self.mode: - self.previewButton.SetUp() - return - - self.mode = self.MODE_PREVIEW - self.positionButton.SetUp() - self.__UnlockCameraMoving() - self.__EnablePCBlocker() - - def __OnLeavePreviewMode(self): - self.__RestoreViewMode() - - def __RestoreViewMode(self): - self.__DisablePCBlocker() - self.__LockCameraMoving() - self.mode = self.MODE_VIEW - self.positionButton.SetUp() - self.previewButton.SetUp() - - def __IsEnoughMoney(self): - - if app.IsEnableTestServerFlag(): - return True - - curMoney = player.GetMoney() - if curMoney < self.needMoney: - return False - return True - - def __IsEnoughMaterialStone(self): - - if app.IsEnableTestServerFlag(): - return True - - curStoneCount = player.GetItemCountByVnum(MATERIAL_STONE_ID) - if curStoneCount < self.needStoneCount: - return False - return True - - def __IsEnoughMaterialLog(self): - - if app.IsEnableTestServerFlag(): - return True - - curLogCount = player.GetItemCountByVnum(MATERIAL_LOG_ID) - if curLogCount < self.needLogCount: - return False - return True - - def __IsEnoughMaterialPlywood(self): - - if app.IsEnableTestServerFlag(): - return True - - curPlywoodCount = player.GetItemCountByVnum(MATERIAL_PLYWOOD_ID) - if curPlywoodCount < self.needPlywoodCount: - return False - return True - - def __OnSelectCategory(self): - self.listScrollBar.SetPos(0.0) - self.__RefreshItem() - - def __SetBuildingData(self, data): - self.buildingPriceValue.SetText(NumberToMoneyString(int(data["PRICE"]))) - - self.needMoney = int(data["PRICE"]) - - materialList = data["MATERIAL"] - self.needStoneCount = int(materialList[MATERIAL_STONE_INDEX]) - self.needLogCount = int(materialList[MATERIAL_LOG_INDEX]) - self.needPlywoodCount = int(materialList[MATERIAL_PLYWOOD_INDEX]) - - self.buildingMaterialStoneValue.SetText(materialList[MATERIAL_STONE_INDEX] + localeInfo.THING_COUNT) - self.buildingMaterialLogValue.SetText(materialList[MATERIAL_LOG_INDEX] + localeInfo.THING_COUNT) - self.buildingMaterialPlywoodValue.SetText(materialList[MATERIAL_PLYWOOD_INDEX] + localeInfo.THING_COUNT) - - if self.__IsEnoughMoney(): - self.buildingPriceValue.SetPackedFontColor(self.ENABLE_COLOR) - else: - self.buildingPriceValue.SetPackedFontColor(self.DISABLE_COLOR) - - if self.__IsEnoughMaterialStone(): - self.buildingMaterialStoneValue.SetPackedFontColor(self.ENABLE_COLOR) - else: - self.buildingMaterialStoneValue.SetPackedFontColor(self.DISABLE_COLOR) - - if self.__IsEnoughMaterialLog(): - self.buildingMaterialLogValue.SetPackedFontColor(self.ENABLE_COLOR) - else: - self.buildingMaterialLogValue.SetPackedFontColor(self.DISABLE_COLOR) - - if self.__IsEnoughMaterialPlywood(): - self.buildingMaterialPlywoodValue.SetPackedFontColor(self.ENABLE_COLOR) - else: - self.buildingMaterialPlywoodValue.SetPackedFontColor(self.DISABLE_COLOR) - - self.rot_x_limit = data["X_ROT_LIMIT"] - self.rot_y_limit = data["Y_ROT_LIMIT"] - self.rot_z_limit = data["Z_ROT_LIMIT"] - self.ctrlRotationX.Enable() - self.ctrlRotationY.Enable() - self.ctrlRotationZ.Enable() - if 0 == self.rot_x_limit: - self.ctrlRotationX.Disable() - if 0 == self.rot_y_limit: - self.ctrlRotationY.Disable() - if 0 == self.rot_z_limit: - self.ctrlRotationZ.Disable() - - def __OnSelectBuilding(self): - buildingIndex = self.buildingList.GetSelectedItem() - if buildingIndex >= len(BUILDING_DATA_LIST): - return - - categoryIndex = self.categoryList.GetSelectedItem() - if categoryIndex >= len(self.GUILD_CATEGORY_LIST): - return - selectedType = self.GUILD_CATEGORY_LIST[categoryIndex][0] - - index = 0 - for data in BUILDING_DATA_LIST: - type = data["TYPE"] - vnum = data["VNUM"] - if selectedType != type: - continue - - if index == buildingIndex: - self.type = type - if "BUILDIN" == self.type: - self.__CreateBuildInInstance(vnum) - else: - self.__CreateInstance(vnum) - - self.__SetBuildingData(data) - - index += 1 - - def __OnScrollBuildingList(self): - viewItemCount = self.buildingList.GetViewItemCount() - itemCount = self.buildingList.GetItemCount() - pos = self.listScrollBar.GetPos() * (itemCount-viewItemCount) - self.buildingList.SetBasePos(int(pos)) - - def __OnChangeRotation(self): - self.rot_x = self.ctrlRotationX.GetSliderPos() * self.rot_x_limit - self.rot_x_limit/2 - self.rot_y = self.ctrlRotationY.GetSliderPos() * self.rot_y_limit - self.rot_y_limit/2 - self.rot_z = (self.ctrlRotationZ.GetSliderPos() * 360 + 180) % 360 - if "BUILDIN" == self.type: - chr.SetRotationAll(self.rot_x, self.rot_y, self.rot_z) - else: - chr.SetRotationAll(self.rot_x, self.rot_y, self.rot_z) - - def __LockCameraMoving(self): - app.SetCameraSetting(int(self.x), int(-self.y), int(self.z), 3000, 0, 30) - - def __UnlockCameraMoving(self): - app.SetDefaultCamera() - - def __RefreshItem(self): - - self.buildingList.ClearItem() - - categoryIndex = self.categoryList.GetSelectedItem() - if categoryIndex >= len(self.GUILD_CATEGORY_LIST): - return - selectedType = self.GUILD_CATEGORY_LIST[categoryIndex][0] - - index = 0 - for data in BUILDING_DATA_LIST: - if selectedType != data["TYPE"]: - continue - - if data["SHOW"]: - self.buildingList.InsertItem(index, data["LOCAL_NAME"]) - - index += 1 - - self.buildingList.SelectItem(0) - - if self.buildingList.GetItemCount() < self.buildingList.GetViewItemCount(): - self.buildingList.SetSize(120, self.buildingList.GetHeight()) - self.buildingList.LocateItem() - self.listScrollBar.Hide() - else: - self.buildingList.SetSize(105, self.buildingList.GetHeight()) - self.buildingList.LocateItem() - self.listScrollBar.Show() - - def SettleCurrentPosition(self): - guildID = miniMap.GetGuildAreaID(self.x, self.y) - - import debugInfo - if debugInfo.IsDebugMode(): - guildID = player.GetGuildID() - - if guildID != player.GetGuildID(): - return - - self.__RestoreViewMode() - self.__LockCameraMoving() - self.Show() - - def SetBuildingPosition(self, x, y, z): - self.x = x - self.y = y - self.posValueX.SetText(str(int(x))) - self.posValueY.SetText(str(int(y))) - - for i in range(len(self.indexList)): - idx = self.indexList[i] - xPos, yPos = self.posList[i] - - chr.SelectInstance(idx) - if 0 != z: - self.z = z - chr.SetPixelPosition(int(x+xPos), int(y+yPos), int(z)) - else: - chr.SetPixelPosition(int(x+xPos), int(y+yPos)) - - def IsPositioningMode(self): - if self.MODE_POSITIONING == self.mode: - return True - return False - - def IsPreviewMode(self): - if self.MODE_PREVIEW == self.mode: - return True - return False - - def OnPressEscapeKey(self): - self.Close() - return True - -""" -- Protocol - -On game entry: - RecvLandPacket: - CPythonMiniMap::RegisterGuildArea - -During game movement: - PythonPlayer::Update() - CPythonPlayer::__Update_NotifyGuildAreaEvent() - game.py.BINARY_Guild_EnterGuildArea - uigameButton.GameButtonWindow.ShowBuildButton() - game.py.BINARY_Guild_ExitGuildArea - uigameButton.GameButtonWindow.HideBuildButton() - -BuildButton: -!No guild master check -!Build button exists even if building present - -!Building temporary VID may be confused with server-sent VID -!Building VNUM converted using BuildGuildBuildingWindow.BUILDING_VNUM_LIST - -!To build: /build c(reate) -!To destroy: /build d(estroy) -!Rotation unit is degree - - interfaceModule.interface.__OnClickBuildButton: - interfaceModule.interface.BUILD_OpenWindow: - -AcceptButton: - BuildGuildBuildingWindow.Build: - net.SendChatPacket("/build c vnum x y x_rot y_rot z_rot") - -PreviewButton: - __OnPreviewMode: - __RestoreViewMode: - -Destroy building: - uiTarget.TargetBoard.__OnDestroyBuilding - net.SendChatPacket("/build d vid") -""" - -if __name__ == "__main__": - - import app - import wndMgr - import systemSetting - import mouseModule - import grp - import ui - - #wndMgr.SetOutlineFlag(True) - - app.SetMouseHandler(mouseModule.mouseController) - app.SetHairColorEnable(True) - wndMgr.SetMouseHandler(mouseModule.mouseController) - wndMgr.SetScreenSize(systemSetting.GetWidth(), systemSetting.GetHeight()) - app.Create("METIN2 CLOSED BETA", systemSetting.GetWidth(), systemSetting.GetHeight(), 1) - mouseModule.mouseController.Create() - - import chrmgr - chrmgr.CreateRace(0) - chrmgr.SelectRace(0) - chrmgr.SetPathName("d:/ymir Work/pc/warrior/") - chrmgr.LoadRaceData("warrior.msm") - chrmgr.SetPathName("d:/ymir work/pc/warrior/general/") - chrmgr.RegisterMotionMode(chr.MOTION_MODE_GENERAL) - chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_WAIT, "wait.msa") - chrmgr.RegisterMotionData(chr.MOTION_MODE_GENERAL, chr.MOTION_RUN, "run.msa") - - def LoadGuildBuildingList(filename): - handle = app.OpenTextFile(filename) - count = app.GetTextFileLineCount(handle) - for i in range(count): - line = app.GetTextFileLine(handle, i) - tokens = line.split("\t") - - TOKEN_VNUM = 0 - TOKEN_TYPE = 1 - TOKEN_NAME = 2 - TOKEN_LOCAL_NAME = 3 - NO_USE_TOKEN_SIZE_1 = 4 - NO_USE_TOKEN_SIZE_2 = 5 - NO_USE_TOKEN_SIZE_3 = 6 - NO_USE_TOKEN_SIZE_4 = 7 - TOKEN_X_ROT_LIMIT = 8 - TOKEN_Y_ROT_LIMIT = 9 - TOKEN_Z_ROT_LIMIT = 10 - TOKEN_PRICE = 11 - TOKEN_MATERIAL = 12 - TOKEN_NPC = 13 - TOKEN_GROUP = 14 - TOKEN_DEPEND_GROUP = 15 - TOKEN_ENABLE_FLAG = 16 - LIMIT_TOKEN_COUNT = 17 - - if not tokens[TOKEN_VNUM].isdigit(): - continue - - if not int(tokens[TOKEN_ENABLE_FLAG]): - continue - - if len(tokens) < LIMIT_TOKEN_COUNT: - import dbg - dbg.TraceError("Strange token count [%d/%d] [%s]" % (len(tokens), LIMIT_TOKEN_COUNT, line)) - continue - - ENABLE_FLAG_TYPE_NOT_USE = False - ENABLE_FLAG_TYPE_USE = True - ENABLE_FLAG_TYPE_USE_BUT_HIDE = 2 - - if ENABLE_FLAG_TYPE_NOT_USE == int(tokens[TOKEN_ENABLE_FLAG]): - continue - - vnum = int(tokens[TOKEN_VNUM]) - type = tokens[TOKEN_TYPE] - name = tokens[TOKEN_NAME] - localName = tokens[TOKEN_LOCAL_NAME] - xRotLimit = int(tokens[TOKEN_X_ROT_LIMIT]) - yRotLimit = int(tokens[TOKEN_Y_ROT_LIMIT]) - zRotLimit = int(tokens[TOKEN_Z_ROT_LIMIT]) - price = tokens[TOKEN_PRICE] - material = tokens[TOKEN_MATERIAL] - - folderName = "" - - if "HEADQUARTER" == type: - folderName = "headquarter" - elif "FACILITY" == type: - folderName = "facility" - elif "OBJECT" == type: - folderName = "object" - ##"BuildIn" Is made by exist instance. - - materialList = ["0", "0", "0"] - - if material[0] == "\"": - material = material[1:] - - if material[-1] == "\"": - material = material[:-1] - - for one in material.split("/"): - data = one.split(",") - - if 2 != len(data): - continue - - itemID = int(data[0]) - count = data[1] - - if itemID == MATERIAL_STONE_ID: - materialList[MATERIAL_STONE_INDEX] = count - elif itemID == MATERIAL_LOG_ID: - materialList[MATERIAL_LOG_INDEX] = count - elif itemID == MATERIAL_PLYWOOD_ID: - materialList[MATERIAL_PLYWOOD_INDEX] = count - - import chrmgr - chrmgr.RegisterRaceSrcName(name, folderName) - chrmgr.RegisterRaceName(vnum, name) - - appendingData = { "VNUM":vnum, - "TYPE":type, - "NAME":name, - "LOCAL_NAME":localName, - "X_ROT_LIMIT":xRotLimit, - "Y_ROT_LIMIT":yRotLimit, - "Z_ROT_LIMIT":zRotLimit, - "PRICE":price, - "MATERIAL":materialList, - "SHOW" : True } - - if ENABLE_FLAG_TYPE_USE_BUT_HIDE == int(tokens[TOKEN_ENABLE_FLAG]): - appendingData["SHOW"] = False - - BUILDING_DATA_LIST.append(appendingData) - - app.CloseTextFile(handle) - - LoadGuildBuildingList(app.GetLocalePath() + "/GuildBuildingList.txt") - - class TestGame(ui.Window): - def __init__(self): - ui.Window.__init__(self) - - x = 30000 - y = 40000 - - self.wndGuildBuilding = None - self.onClickKeyDict = {} - self.onClickKeyDict[app.DIK_SPACE] = lambda: self.OpenBuildGuildBuildingWindow() - - background.Initialize() - background.LoadMap("metin2_map_a1", x, y, 0) - background.SetShadowLevel(background.SHADOW_ALL) - - self.MakeCharacter(1, 0, x, y) - player.SetMainCharacterIndex(1) - chr.SelectInstance(1) - - def __del__(self): - ui.Window.__del__(self) - - def MakeCharacter(self, index, race, x, y): - chr.CreateInstance(index) - chr.SelectInstance(index) - chr.SetVirtualID(index) - chr.SetInstanceType(chr.INSTANCE_TYPE_PLAYER) - - chr.SetRace(race) - chr.SetArmor(0) - chr.SetHair(0) - chr.Refresh() - chr.SetMotionMode(chr.MOTION_MODE_GENERAL) - chr.SetLoopMotion(chr.MOTION_WAIT) - - chr.SetPixelPosition(x, y) - chr.SetDirection(chr.DIR_NORTH) - - def OpenBuildGuildBuildingWindow(self): - self.wndGuildBuilding = BuildGuildBuildingWindow() - self.wndGuildBuilding.Open() - self.wndGuildBuilding.SetParent(self) - self.wndGuildBuilding.SetTop() - - def OnKeyUp(self, key): - if key in self.onClickKeyDict: - self.onClickKeyDict[key]() - return True - - def OnMouseLeftButtonDown(self): - if self.wndGuildBuilding: - if self.wndGuildBuilding.IsPositioningMode(): - self.wndGuildBuilding.SettleCurrentPosition() - return - - player.SetMouseState(player.MBT_LEFT, player.MBS_PRESS); - return True - - def OnMouseLeftButtonUp(self): - if self.wndGuildBuilding: - return - - player.SetMouseState(player.MBT_LEFT, player.MBS_CLICK) - return True - - def OnMouseRightButtonDown(self): - player.SetMouseState(player.MBT_RIGHT, player.MBS_PRESS); - return True - - def OnMouseRightButtonUp(self): - player.SetMouseState(player.MBT_RIGHT, player.MBS_CLICK); - return True - - def OnMouseMiddleButtonDown(self): - player.SetMouseMiddleButtonState(player.MBS_PRESS) - - def OnMouseMiddleButtonUp(self): - player.SetMouseMiddleButtonState(player.MBS_CLICK) - - def OnUpdate(self): - app.UpdateGame() - - if self.wndGuildBuilding: - if self.wndGuildBuilding.IsPositioningMode(): - x, y, z = background.GetPickingPoint() - self.wndGuildBuilding.SetBuildingPosition(x, y, z) - - def OnRender(self): - app.RenderGame() - grp.PopState() - grp.SetInterfaceRenderState() - - game = TestGame() - game.SetSize(systemSetting.GetWidth(), systemSetting.GetHeight()) - game.Show() - - wndGuildBuilding = BuildGuildBuildingWindow() - wndGuildBuilding.Open() - wndGuildBuilding.SetTop() - - app.Loop() - - """ - - Protocol - -On game entry: - RecvLandPacket: - CPythonMiniMap::RegisterGuildArea - -During game movement: - PythonPlayer::Update() - CPythonPlayer::__Update_NotifyGuildAreaEvent() - game.py.BINARY_Guild_EnterGuildArea - uigameButton.GameButtonWindow.ShowBuildButton() - game.py.BINARY_Guild_ExitGuildArea - uigameButton.GameButtonWindow.HideBuildButton() - -BuildButton: -!No guild master check -!Build button exists even if building present - -!Building temporary VID may be confused with server-sent VID -!Building VNUM converted using BuildGuildBuildingWindow.BUILDING_VNUM_LIST - -!To build: /build c(reate) -!To destroy: /build d(estroy) -!Rotation unit is degree - - interfaceModule.interface.__OnClickBuildButton: - interfaceModule.interface.BUILD_OpenWindow: - -AcceptButton: - BuildGuildBuildingWindow.Build: - net.SendChatPacket("/build c vnum x y x_rot y_rot z_rot") - - x_rot, y_rot stored in AffectContainer - -PreviewButton: - __OnPreviewMode: - __RestoreViewMode: - -Destroy building: - uiTarget.TargetBoard.__OnDestroyBuilding - net.SendChatPacket("/build d vid") - """ - -GuildWindow._RebuildLocaleStrings() -localeInfo.RegisterReloadCallback(GuildWindow._RebuildLocaleStrings) diff --git a/tools/root/uihelp.py b/tools/root/uihelp.py deleted file mode 100644 index ca4c5040..00000000 --- a/tools/root/uihelp.py +++ /dev/null @@ -1,136 +0,0 @@ -import app -import ui -import localeInfo -import uiScriptLocale - -ENABLE_HELP_MULTIPAGE = 0 - -class HelpWindow(ui.ScriptWindow): - def __init__(self): - ui.ScriptWindow.__init__(self, "TOP_MOST") - self.eventClose = 0 - def __del__(self): - ui.ScriptWindow.__del__(self) - - def LoadDialog(self): - if ENABLE_HELP_MULTIPAGE: - self.LoadDialogMultiPage() - else: - self.LoadDialogSinglePage() - - def LoadDialogSinglePage(self): - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "UIScript/HelpWindow.py") - except: - import exception - exception.Abort("HelpWindow.LoadDialogSinglePage.LoadScript") - - try: - GetObject=self.GetChild - self.btnClose = GetObject("close_button") - except: - import exception - exception.Abort("DialogWindow.LoadDialogSinglePage.BindObject") - - - def LoadDialogMultiPage(self): - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "UIScript/HelpWindow2.py") - except: - import exception - exception.Abort("HelpWindow.LoadDialogMultiPage.LoadScript") - - try: - GetObject=self.GetChild - self.btnClose = GetObject("close_button") - self.pages = {} - self.btnPages = {} - self.pages[0] = GetObject("page_1") - self.pages[1] = GetObject("page_2") - self.btnPages[0] = GetObject("page_1_button") - self.btnPages[1] = GetObject("page_2_button") - self.btnPages[0].SAFE_SetEvent(self.__OnClickPage1) - self.btnPages[1].SAFE_SetEvent(self.__OnClickPage2) - - self.__SelectPage(0) - - except: - import exception - exception.Abort("DialogWindow.LoadDialogMultiPage.BindObject") - - def __OnClickPage1(self): - self.__SelectPage(0) - - def __OnClickPage2(self): - self.__SelectPage(1) - - def Destroy(self): - self.eventClose = 0 - self.closeButton = 0 - self.pages = {} - self.btnPages = {} - - def SetCloseEvent(self, event): - self.eventClose = event - self.btnClose.SetEvent(event) - - def Open(self): - self.Lock() - self.Show() - - def Close(self): - self.Unlock() - self.Hide() - - def OnKeyDown(self, key): - if app.DIK_H == key and 0 != self.eventClose: - self.eventClose() - - return True - - def OnIMEReturn(self): - return True - - def OnPressEscapeKey(self): - if 0 != self.eventClose: - self.eventClose() - return True - - def OnPressExitKey(self): - if 0 != self.eventClose: - self.eventClose() - return True - - def __SelectPage(self, pageIndex): - for page in list(self.pages.values()): - page.Hide() - for btn in list(self.btnPages.values()): - btn.SetUp() - - self.pages[pageIndex].Show() - self.btnPages[pageIndex].Down() - -if __name__ == "__main__": - - import app - import wndMgr - import systemSetting - import mouseModule - import grp - import ui - - app.SetMouseHandler(mouseModule.mouseController) - app.SetHairColorEnable(True) - wndMgr.SetMouseHandler(mouseModule.mouseController) - wndMgr.SetScreenSize(systemSetting.GetWidth(), systemSetting.GetHeight()) - app.Create(localeInfo.APP_TITLE, systemSetting.GetWidth(), systemSetting.GetHeight(), 1) - mouseModule.mouseController.Create() - - wnd = HelpWindow() - wnd.LoadDialog() - wnd.Open() - app.Loop() - wnd = None - diff --git a/tools/root/uiinventory.py b/tools/root/uiinventory.py deleted file mode 100644 index deb20a39..00000000 --- a/tools/root/uiinventory.py +++ /dev/null @@ -1,1263 +0,0 @@ -import ui -import player -import mouseModule -import net -import app -import snd -import item -import player -import chat -import grp -import uiScriptLocale -import uiRefine -import uiAttachMetin -import uiPickMoney -import uiCommon -import uiPrivateShopBuilder # Prevent ItemMove while private shop is open -import localeInfo -import constInfo -import ime -import wndMgr - -ITEM_FLAG_APPLICABLE = 1 << 14 - -class CostumeWindow(ui.ScriptWindow): - - def __init__(self, wndInventory): - import exception - - if not app.ENABLE_COSTUME_SYSTEM: - exception.Abort("What do you do?") - return - - if not wndInventory: - exception.Abort("wndInventory parameter must be set to InventoryWindow") - return - - ui.ScriptWindow.__init__(self) - - self.isLoaded = 0 - self.wndInventory = wndInventory - - self.__LoadWindow() - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def Show(self): - self.__LoadWindow() - self.RefreshCostumeSlot() - - ui.ScriptWindow.Show(self) - - def Close(self): - self.Hide() - - def __LoadWindow(self): - if self.isLoaded == 1: - return - - self.isLoaded = 1 - - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "UIScript/CostumeWindow.py") - except: - import exception - exception.Abort("CostumeWindow.LoadWindow.LoadObject") - - try: - wndEquip = self.GetChild("CostumeSlot") - self.GetChild("TitleBar").SetCloseEvent(ui.__mem_func__(self.Close)) - - except: - import exception - exception.Abort("CostumeWindow.LoadWindow.BindObject") - - ## Equipment - wndEquip.SetOverInItemEvent(ui.__mem_func__(self.wndInventory.OverInItem)) - wndEquip.SetOverOutItemEvent(ui.__mem_func__(self.wndInventory.OverOutItem)) - wndEquip.SetUnselectItemSlotEvent(ui.__mem_func__(self.wndInventory.UseItemSlot)) - wndEquip.SetUseSlotEvent(ui.__mem_func__(self.wndInventory.UseItemSlot)) - wndEquip.SetSelectEmptySlotEvent(ui.__mem_func__(self.wndInventory.SelectEmptySlot)) - wndEquip.SetSelectItemSlotEvent(ui.__mem_func__(self.wndInventory.SelectItemSlot)) - - self.wndEquip = wndEquip - - def RefreshCostumeSlot(self): - getItemVNum=player.GetItemIndex - - for i in range(item.COSTUME_SLOT_COUNT): - slotNumber = item.COSTUME_SLOT_START + i - self.wndEquip.SetItemSlot(slotNumber, getItemVNum(slotNumber), 0) - - self.wndEquip.RefreshSlot() - -class BeltInventoryWindow(ui.ScriptWindow): - - def __init__(self, wndInventory): - import exception - - if not app.ENABLE_NEW_EQUIPMENT_SYSTEM: - exception.Abort("What do you do?") - return - - if not wndInventory: - exception.Abort("wndInventory parameter must be set to InventoryWindow") - return - - ui.ScriptWindow.__init__(self) - - self.AddFlag("float") - - self.isLoaded = 0 - self.wndInventory = wndInventory - - self.wndBeltInventoryLayer = None - self.wndBeltInventorySlot = None - self.expandBtn = None - self.minBtn = None - - self.__LoadWindow() - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def Show(self, openBeltSlot = False): - self.__LoadWindow() - self.RefreshSlot() - - ui.ScriptWindow.Show(self) - - if openBeltSlot: - self.OpenInventory() - else: - self.CloseInventory() - - def Close(self): - self.Hide() - - def IsOpeningInventory(self): - return self.wndBeltInventoryLayer.IsShow() - - def OpenInventory(self): - self.wndBeltInventoryLayer.Show() - self.expandBtn.Hide() - - if app.IsRTL() == 0: - self.AdjustPositionAndSize() - - def CloseInventory(self): - self.wndBeltInventoryLayer.Hide() - self.expandBtn.Show() - - if app.IsRTL() == 0: - self.AdjustPositionAndSize() - - ## Calculate and return BASE position based on current inventory position. Hard-coded numbers are unavoidable. - def GetBasePosition(self): - x, y = self.wndInventory.GetGlobalPosition() - return x - 148, y + 241 - - def AdjustPositionAndSize(self): - bx, by = self.GetBasePosition() - - if self.IsOpeningInventory(): - self.SetPosition(bx, by) - self.SetSize(self.ORIGINAL_WIDTH, self.GetHeight()) - - else: - self.SetPosition(bx + 138, by) - self.SetSize(10, self.GetHeight()) - - def __LoadWindow(self): - if self.isLoaded == 1: - return - - self.isLoaded = 1 - - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "UIScript/BeltInventoryWindow.py") - except: - import exception - exception.Abort("CostumeWindow.LoadWindow.LoadObject") - - try: - self.ORIGINAL_WIDTH = self.GetWidth() - wndBeltInventorySlot = self.GetChild("BeltInventorySlot") - self.wndBeltInventoryLayer = self.GetChild("BeltInventoryLayer") - self.expandBtn = self.GetChild("ExpandBtn") - self.minBtn = self.GetChild("MinimizeBtn") - - self.expandBtn.SetEvent(ui.__mem_func__(self.OpenInventory)) - self.minBtn.SetEvent(ui.__mem_func__(self.CloseInventory)) - - if app.IsRTL() : - self.expandBtn.SetPosition(self.expandBtn.GetWidth() - 2, 15) - self.wndBeltInventoryLayer.SetPosition(self.wndBeltInventoryLayer.GetWidth() - 5, 0) - self.minBtn.SetPosition(self.minBtn.GetWidth() + 3, 15) - - for i in range(item.BELT_INVENTORY_SLOT_COUNT): - slotNumber = item.BELT_INVENTORY_SLOT_START + i - wndBeltInventorySlot.SetCoverButton(slotNumber, "d:/ymir work/ui/game/quest/slot_button_01.sub",\ - "d:/ymir work/ui/game/quest/slot_button_01.sub",\ - "d:/ymir work/ui/game/quest/slot_button_01.sub",\ - "d:/ymir work/ui/game/belt_inventory/slot_disabled.tga", False, False) - - except: - import exception - exception.Abort("CostumeWindow.LoadWindow.BindObject") - - ## Equipment - wndBeltInventorySlot.SetOverInItemEvent(ui.__mem_func__(self.wndInventory.OverInItem)) - wndBeltInventorySlot.SetOverOutItemEvent(ui.__mem_func__(self.wndInventory.OverOutItem)) - wndBeltInventorySlot.SetUnselectItemSlotEvent(ui.__mem_func__(self.wndInventory.UseItemSlot)) - wndBeltInventorySlot.SetUseSlotEvent(ui.__mem_func__(self.wndInventory.UseItemSlot)) - wndBeltInventorySlot.SetSelectEmptySlotEvent(ui.__mem_func__(self.wndInventory.SelectEmptySlot)) - wndBeltInventorySlot.SetSelectItemSlotEvent(ui.__mem_func__(self.wndInventory.SelectItemSlot)) - - self.wndBeltInventorySlot = wndBeltInventorySlot - - def RefreshSlot(self): - getItemVNum=player.GetItemIndex - - for i in range(item.BELT_INVENTORY_SLOT_COUNT): - slotNumber = item.BELT_INVENTORY_SLOT_START + i - self.wndBeltInventorySlot.SetItemSlot(slotNumber, getItemVNum(slotNumber), player.GetItemCount(slotNumber)) - self.wndBeltInventorySlot.SetAlwaysRenderCoverButton(slotNumber, True) - - avail = "0" - - if player.IsAvailableBeltInventoryCell(slotNumber): - self.wndBeltInventorySlot.EnableCoverButton(slotNumber) - else: - self.wndBeltInventorySlot.DisableCoverButton(slotNumber) - - self.wndBeltInventorySlot.RefreshSlot() - - -class InventoryWindow(ui.ScriptWindow): - - USE_TYPE_TUPLE = ("USE_CLEAN_SOCKET", "USE_CHANGE_ATTRIBUTE", "USE_ADD_ATTRIBUTE", "USE_ADD_ATTRIBUTE2", "USE_ADD_ACCESSORY_SOCKET", "USE_PUT_INTO_ACCESSORY_SOCKET", "USE_PUT_INTO_BELT_SOCKET", "USE_PUT_INTO_RING_SOCKET") - - questionDialog = None - tooltipItem = None - wndCostume = None - wndBelt = None - dlgPickMoney = None - - sellingSlotNumber = -1 - isLoaded = 0 - isOpenedCostumeWindowWhenClosingInventory = 0 # Whether costume window was open when closing inventory - isOpenedBeltWindowWhenClosingInventory = 0 # Whether belt inventory was open when closing inventory - - def __init__(self): - ui.ScriptWindow.__init__(self) - - self.isOpenedBeltWindowWhenClosingInventory = 0 # Whether belt inventory was open when closing inventory - - self.__LoadWindow() - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def Show(self): - self.__LoadWindow() - - ui.ScriptWindow.Show(self) - - # If costume window was open when closing inventory, open it again when opening inventory. - if self.isOpenedCostumeWindowWhenClosingInventory and self.wndCostume: - self.wndCostume.Show() - - # If belt inventory was open when closing inventory, open it again. - if self.wndBelt: - self.wndBelt.Show(self.isOpenedBeltWindowWhenClosingInventory) - - def BindInterfaceClass(self, interface): - self.interface = interface - - def __LoadWindow(self): - if self.isLoaded == 1: - return - - self.isLoaded = 1 - - try: - pyScrLoader = ui.PythonScriptLoader() - - if app.IsRTL(): - pyScrLoader.LoadScriptFile(self, uiScriptLocale.LOCALE_UISCRIPT_PATH + "InventoryWindow.py") - else: - pyScrLoader.LoadScriptFile(self, "UIScript/InventoryWindow.py") - except: - import exception - exception.Abort("InventoryWindow.LoadWindow.LoadObject") - - try: - wndItem = self.GetChild("ItemSlot") - wndEquip = self.GetChild("EquipmentSlot") - self.GetChild("TitleBar").SetCloseEvent(ui.__mem_func__(self.Close)) - self.wndMoney = self.GetChild("Money") - self.wndMoneySlot = self.GetChild("Money_Slot") - self.mallButton = self.GetChild2("MallButton") - self.DSSButton = self.GetChild2("DSSButton") - self.costumeButton = self.GetChild2("CostumeButton") - - self.inventoryTab = [] - self.inventoryTab.append(self.GetChild("Inventory_Tab_01")) - self.inventoryTab.append(self.GetChild("Inventory_Tab_02")) - - self.equipmentTab = [] - self.equipmentTab.append(self.GetChild("Equipment_Tab_01")) - self.equipmentTab.append(self.GetChild("Equipment_Tab_02")) - - if self.costumeButton and not app.ENABLE_COSTUME_SYSTEM: - self.costumeButton.Hide() - self.costumeButton.Destroy() - self.costumeButton = 0 - - # Belt Inventory Window - self.wndBelt = None - - if app.ENABLE_NEW_EQUIPMENT_SYSTEM: - self.wndBelt = BeltInventoryWindow(self) - - except: - import exception - exception.Abort("InventoryWindow.LoadWindow.BindObject") - - ## Item - wndItem.SetSelectEmptySlotEvent(ui.__mem_func__(self.SelectEmptySlot)) - wndItem.SetSelectItemSlotEvent(ui.__mem_func__(self.SelectItemSlot)) - wndItem.SetUnselectItemSlotEvent(ui.__mem_func__(self.UseItemSlot)) - wndItem.SetUseSlotEvent(ui.__mem_func__(self.UseItemSlot)) - wndItem.SetOverInItemEvent(ui.__mem_func__(self.OverInItem)) - wndItem.SetOverOutItemEvent(ui.__mem_func__(self.OverOutItem)) - - ## Equipment - wndEquip.SetSelectEmptySlotEvent(ui.__mem_func__(self.SelectEmptySlot)) - wndEquip.SetSelectItemSlotEvent(ui.__mem_func__(self.SelectItemSlot)) - wndEquip.SetUnselectItemSlotEvent(ui.__mem_func__(self.UseItemSlot)) - wndEquip.SetUseSlotEvent(ui.__mem_func__(self.UseItemSlot)) - wndEquip.SetOverInItemEvent(ui.__mem_func__(self.OverInItem)) - wndEquip.SetOverOutItemEvent(ui.__mem_func__(self.OverOutItem)) - - ## PickMoneyDialog - dlgPickMoney = uiPickMoney.PickMoneyDialog() - dlgPickMoney.LoadDialog() - dlgPickMoney.Hide() - - ## RefineDialog - self.refineDialog = uiRefine.RefineDialog() - self.refineDialog.Hide() - - ## AttachMetinDialog - self.attachMetinDialog = uiAttachMetin.AttachMetinDialog() - self.attachMetinDialog.Hide() - - ## MoneySlot - self.wndMoneySlot.SetEvent(ui.__mem_func__(self.OpenPickMoneyDialog)) - - self.inventoryTab[0].SetEvent(lambda arg=0: self.SetInventoryPage(arg)) - self.inventoryTab[1].SetEvent(lambda arg=1: self.SetInventoryPage(arg)) - self.inventoryTab[0].Down() - - self.equipmentTab[0].SetEvent(lambda arg=0: self.SetEquipmentPage(arg)) - self.equipmentTab[1].SetEvent(lambda arg=1: self.SetEquipmentPage(arg)) - self.equipmentTab[0].Down() - self.equipmentTab[0].Hide() - self.equipmentTab[1].Hide() - - self.wndItem = wndItem - self.wndEquip = wndEquip - self.dlgPickMoney = dlgPickMoney - - # MallButton - if self.mallButton: - self.mallButton.SetEvent(ui.__mem_func__(self.ClickMallButton)) - - if self.DSSButton: - self.DSSButton.SetEvent(ui.__mem_func__(self.ClickDSSButton)) - - # Costume Button - if self.costumeButton: - self.costumeButton.SetEvent(ui.__mem_func__(self.ClickCostumeButton)) - - self.wndCostume = None - - ##### - - ## Refresh - self.SetInventoryPage(0) - self.SetEquipmentPage(0) - self.RefreshItemSlot() - self.RefreshStatus() - - def Destroy(self): - self.ClearDictionary() - - self.dlgPickMoney.Destroy() - self.dlgPickMoney = 0 - - self.refineDialog.Destroy() - self.refineDialog = 0 - - self.attachMetinDialog.Destroy() - self.attachMetinDialog = 0 - - self.tooltipItem = None - self.wndItem = 0 - self.wndEquip = 0 - self.dlgPickMoney = 0 - self.wndMoney = 0 - self.wndMoneySlot = 0 - self.questionDialog = None - self.mallButton = None - self.DSSButton = None - self.DSSButtonEffect = None - self.interface = None - - if self.wndCostume: - self.wndCostume.Destroy() - self.wndCostume = 0 - - if self.wndBelt: - self.wndBelt.Destroy() - self.wndBelt = None - - self.inventoryTab = [] - self.equipmentTab = [] - - def Hide(self): - if constInfo.GET_ITEM_QUESTION_DIALOG_STATUS(): - self.OnCloseQuestionDialog() - return - if None != self.tooltipItem: - self.tooltipItem.HideToolTip() - - if self.wndCostume: - self.isOpenedCostumeWindowWhenClosingInventory = self.wndCostume.IsShow() # Was costume window open when inventory was closed? - self.wndCostume.Close() - - if self.wndBelt: - self.isOpenedBeltWindowWhenClosingInventory = self.wndBelt.IsOpeningInventory() # Was belt inventory open when inventory was closed? - print(("Is Opening Belt Inven?? ", self.isOpenedBeltWindowWhenClosingInventory)) - self.wndBelt.Close() - - if self.dlgPickMoney: - self.dlgPickMoney.Close() - - wndMgr.Hide(self.hWnd) - - - def Close(self): - self.Hide() - - def SetInventoryPage(self, page): - self.inventoryPageIndex = page - self.inventoryTab[1-page].SetUp() - self.RefreshBagSlotWindow() - - def SetEquipmentPage(self, page): - self.equipmentPageIndex = page - self.equipmentTab[1-page].SetUp() - self.RefreshEquipSlotWindow() - - def ClickMallButton(self): - print("click_mall_button") - net.SendChatPacket("/click_mall") - - # DSSButton - def ClickDSSButton(self): - print("click_dss_button") - self.interface.ToggleDragonSoulWindow() - - def UseDSSButtonEffect(self, enable): - if self.DSSButton: - DSSButtonEffect = ui.SlotWindow() - DSSButtonEffect.AddFlag("attach") - DSSButtonEffect.SetParent(self.DSSButton) - DSSButtonEffect.SetPosition(3.2, 0) - - DSSButtonEffect.AppendSlot(0, 0, 0, 32, 32) - DSSButtonEffect.SetRenderSlot(0) - DSSButtonEffect.RefreshSlot() - - if enable == True: - DSSButtonEffect.ActivateSlot(0) - DSSButtonEffect.Show() - else: - DSSButtonEffect.DeactivateSlot(0) - DSSButtonEffect.Hide() - self.DSSButtonEffect = DSSButtonEffect - - def ClickCostumeButton(self): - print("Click Costume Button") - if self.wndCostume: - if self.wndCostume.IsShow(): - self.wndCostume.Hide() - else: - self.wndCostume.Show() - else: - self.wndCostume = CostumeWindow(self) - self.wndCostume.Show() - - def OpenPickMoneyDialog(self): - - if mouseModule.mouseController.isAttached(): - - attachedSlotPos = mouseModule.mouseController.GetAttachedSlotNumber() - if player.SLOT_TYPE_SAFEBOX == mouseModule.mouseController.GetAttachedType(): - - if player.ITEM_MONEY == mouseModule.mouseController.GetAttachedItemIndex(): - net.SendSafeboxWithdrawMoneyPacket(mouseModule.mouseController.GetAttachedItemCount()) - snd.PlaySound("sound/ui/money.wav") - - mouseModule.mouseController.DeattachObject() - - else: - curMoney = player.GetElk() - - if curMoney <= 0: - return - - self.dlgPickMoney.SetTitleName(localeInfo.PICK_MONEY_TITLE) - self.dlgPickMoney.SetAcceptEvent(ui.__mem_func__(self.OnPickMoney)) - self.dlgPickMoney.Open(curMoney) - self.dlgPickMoney.SetMax(7) # Fixed inventory 990000 limit bug - - def OnPickMoney(self, money): - mouseModule.mouseController.AttachMoney(self, player.SLOT_TYPE_INVENTORY, money) - - def OnPickItem(self, count): - itemSlotIndex = self.dlgPickMoney.itemGlobalSlotIndex - selectedItemVNum = player.GetItemIndex(itemSlotIndex) - mouseModule.mouseController.AttachObject(self, player.SLOT_TYPE_INVENTORY, itemSlotIndex, selectedItemVNum, count) - - def __InventoryLocalSlotPosToGlobalSlotPos(self, local): - if player.IsEquipmentSlot(local) or player.IsCostumeSlot(local) or (app.ENABLE_NEW_EQUIPMENT_SYSTEM and player.IsBeltInventorySlot(local)): - return local - - return self.inventoryPageIndex*player.INVENTORY_PAGE_SIZE + local - - def RefreshBagSlotWindow(self): - getItemVNum=player.GetItemIndex - getItemCount=player.GetItemCount - setItemVNum=self.wndItem.SetItemSlot - - for i in range(player.INVENTORY_PAGE_SIZE): - slotNumber = self.__InventoryLocalSlotPosToGlobalSlotPos(i) - - itemCount = getItemCount(slotNumber) - # If itemCount == 0, clear the slot. - if 0 == itemCount: - self.wndItem.ClearSlot(i) - continue - elif 1 == itemCount: - itemCount = 0 - - itemVnum = getItemVNum(slotNumber) - setItemVNum(i, itemVnum, itemCount) - - ## Auto-potion special handling (HP: #72723~#72726, SP: #72727~#72730) - Display activation/deactivation in slot even though it's an item - [hyo] - if constInfo.IS_AUTO_POTION(itemVnum): - # metinSocket - [0]: Activation status, [1]: Amount used, [2]: Maximum capacity - metinSocket = [player.GetItemMetinSocket(slotNumber, j) for j in range(player.METIN_SOCKET_MAX_NUM)] - - if slotNumber >= player.INVENTORY_PAGE_SIZE * self.inventoryPageIndex: - slotNumber -= player.INVENTORY_PAGE_SIZE * self.inventoryPageIndex - - isActivated = 0 != metinSocket[0] - - if isActivated: - self.wndItem.ActivateSlot(slotNumber) - potionType = 0 - if constInfo.IS_AUTO_POTION_HP(itemVnum): - potionType = player.AUTO_POTION_TYPE_HP - elif constInfo.IS_AUTO_POTION_SP(itemVnum): - potionType = player.AUTO_POTION_TYPE_SP - - usedAmount = int(metinSocket[1]) - totalAmount = int(metinSocket[2]) - player.SetAutoPotionInfo(potionType, isActivated, (totalAmount - usedAmount), totalAmount, self.__InventoryLocalSlotPosToGlobalSlotPos(i)) - - else: - self.wndItem.DeactivateSlot(slotNumber) - - self.wndItem.RefreshSlot() - - if self.wndBelt: - self.wndBelt.RefreshSlot() - - def RefreshEquipSlotWindow(self): - getItemVNum=player.GetItemIndex - getItemCount=player.GetItemCount - setItemVNum=self.wndEquip.SetItemSlot - for i in range(player.EQUIPMENT_PAGE_COUNT): - slotNumber = player.EQUIPMENT_SLOT_START + i - itemCount = getItemCount(slotNumber) - if itemCount <= 1: - itemCount = 0 - setItemVNum(slotNumber, getItemVNum(slotNumber), itemCount) - - if app.ENABLE_NEW_EQUIPMENT_SYSTEM: - for i in range(player.NEW_EQUIPMENT_SLOT_COUNT): - slotNumber = player.NEW_EQUIPMENT_SLOT_START + i - itemCount = getItemCount(slotNumber) - if itemCount <= 1: - itemCount = 0 - setItemVNum(slotNumber, getItemVNum(slotNumber), itemCount) - print(("ENABLE_NEW_EQUIPMENT_SYSTEM", slotNumber, itemCount, getItemVNum(slotNumber))) - - - - self.wndEquip.RefreshSlot() - - if self.wndCostume: - self.wndCostume.RefreshCostumeSlot() - - def RefreshItemSlot(self): - self.RefreshBagSlotWindow() - self.RefreshEquipSlotWindow() - - def RefreshStatus(self): - money = player.GetElk() - self.wndMoney.SetText(localeInfo.NumberToMoneyString(money)) - - def SetItemToolTip(self, tooltipItem): - self.tooltipItem = tooltipItem - - def SellItem(self): - if self.sellingSlotitemIndex == player.GetItemIndex(self.sellingSlotNumber): - if self.sellingSlotitemCount == player.GetItemCount(self.sellingSlotNumber): - ## Added type argument to enable selling dragon soul stones - net.SendShopSellPacketNew(self.sellingSlotNumber, self.questionDialog.count, player.INVENTORY) - snd.PlaySound("sound/ui/money.wav") - self.OnCloseQuestionDialog() - - def OnDetachMetinFromItem(self): - if None == self.questionDialog: - return - - #net.SendItemUseToItemPacket(self.questionDialog.sourcePos, self.questionDialog.targetPos) - self.__SendUseItemToItemPacket(self.questionDialog.sourcePos, self.questionDialog.targetPos) - self.OnCloseQuestionDialog() - - def OnCloseQuestionDialog(self): - if not self.questionDialog: - return - - self.questionDialog.Close() - self.questionDialog = None - constInfo.SET_ITEM_QUESTION_DIALOG_STATUS(0) - - ## Slot Event - def SelectEmptySlot(self, selectedSlotPos): - if constInfo.GET_ITEM_QUESTION_DIALOG_STATUS() == 1: - return - - selectedSlotPos = self.__InventoryLocalSlotPosToGlobalSlotPos(selectedSlotPos) - - if mouseModule.mouseController.isAttached(): - - attachedSlotType = mouseModule.mouseController.GetAttachedType() - attachedSlotPos = mouseModule.mouseController.GetAttachedSlotNumber() - attachedItemCount = mouseModule.mouseController.GetAttachedItemCount() - attachedItemIndex = mouseModule.mouseController.GetAttachedItemIndex() - - if player.SLOT_TYPE_INVENTORY == attachedSlotType: - itemCount = player.GetItemCount(attachedSlotPos) - attachedCount = mouseModule.mouseController.GetAttachedItemCount() - self.__SendMoveItemPacket(attachedSlotPos, selectedSlotPos, attachedCount) - - if item.IsRefineScroll(attachedItemIndex): - self.wndItem.SetUseMode(False) - - elif player.SLOT_TYPE_PRIVATE_SHOP == attachedSlotType: - mouseModule.mouseController.RunCallBack("INVENTORY") - - elif player.SLOT_TYPE_SHOP == attachedSlotType: - net.SendShopBuyPacket(attachedSlotPos) - - elif player.SLOT_TYPE_SAFEBOX == attachedSlotType: - - if player.ITEM_MONEY == attachedItemIndex: - net.SendSafeboxWithdrawMoneyPacket(mouseModule.mouseController.GetAttachedItemCount()) - snd.PlaySound("sound/ui/money.wav") - - else: - net.SendSafeboxCheckoutPacket(attachedSlotPos, selectedSlotPos) - - elif player.SLOT_TYPE_MALL == attachedSlotType: - net.SendMallCheckoutPacket(attachedSlotPos, selectedSlotPos) - - mouseModule.mouseController.DeattachObject() - - def SelectItemSlot(self, itemSlotIndex): - if constInfo.GET_ITEM_QUESTION_DIALOG_STATUS() == 1: - return - - itemSlotIndex = self.__InventoryLocalSlotPosToGlobalSlotPos(itemSlotIndex) - - if mouseModule.mouseController.isAttached(): - attachedSlotType = mouseModule.mouseController.GetAttachedType() - attachedSlotPos = mouseModule.mouseController.GetAttachedSlotNumber() - attachedItemVID = mouseModule.mouseController.GetAttachedItemIndex() - - if player.SLOT_TYPE_INVENTORY == attachedSlotType: - self.__DropSrcItemToDestItemInInventory(attachedItemVID, attachedSlotPos, itemSlotIndex) - - mouseModule.mouseController.DeattachObject() - - else: - - curCursorNum = app.GetCursor() - if app.SELL == curCursorNum: - self.__SellItem(itemSlotIndex) - - elif app.BUY == curCursorNum: - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.SHOP_BUY_INFO) - - elif app.IsPressed(app.DIK_LALT): - link = player.GetItemLink(itemSlotIndex) - ime.PasteString(link) - - elif app.IsPressed(app.DIK_LSHIFT): - itemCount = player.GetItemCount(itemSlotIndex) - - if itemCount > 1: - self.dlgPickMoney.SetTitleName(localeInfo.PICK_ITEM_TITLE) - self.dlgPickMoney.SetAcceptEvent(ui.__mem_func__(self.OnPickItem)) - self.dlgPickMoney.Open(itemCount) - self.dlgPickMoney.itemGlobalSlotIndex = itemSlotIndex - #else: - #selectedItemVNum = player.GetItemIndex(itemSlotIndex) - #mouseModule.mouseController.AttachObject(self, player.SLOT_TYPE_INVENTORY, itemSlotIndex, selectedItemVNum) - - elif app.IsPressed(app.DIK_LCONTROL): - itemIndex = player.GetItemIndex(itemSlotIndex) - - if True == item.CanAddToQuickSlotItem(itemIndex): - player.RequestAddToEmptyLocalQuickSlot(player.SLOT_TYPE_INVENTORY, itemSlotIndex) - else: - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.QUICKSLOT_REGISTER_DISABLE_ITEM) - - else: - selectedItemVNum = player.GetItemIndex(itemSlotIndex) - itemCount = player.GetItemCount(itemSlotIndex) - mouseModule.mouseController.AttachObject(self, player.SLOT_TYPE_INVENTORY, itemSlotIndex, selectedItemVNum, itemCount) - - if self.__IsUsableItemToItem(selectedItemVNum, itemSlotIndex): - self.wndItem.SetUseMode(True) - else: - self.wndItem.SetUseMode(False) - - snd.PlaySound("sound/ui/pick.wav") - - def __DropSrcItemToDestItemInInventory(self, srcItemVID, srcItemSlotPos, dstItemSlotPos): - if srcItemSlotPos == dstItemSlotPos: - return - - elif item.IsRefineScroll(srcItemVID): - self.RefineItem(srcItemSlotPos, dstItemSlotPos) - self.wndItem.SetUseMode(False) - - elif item.IsMetin(srcItemVID): - self.AttachMetinToItem(srcItemSlotPos, dstItemSlotPos) - - elif item.IsDetachScroll(srcItemVID): - self.DetachMetinFromItem(srcItemSlotPos, dstItemSlotPos) - - elif item.IsKey(srcItemVID): - self.__SendUseItemToItemPacket(srcItemSlotPos, dstItemSlotPos) - - elif (player.GetItemFlags(srcItemSlotPos) & ITEM_FLAG_APPLICABLE) == ITEM_FLAG_APPLICABLE: - self.__SendUseItemToItemPacket(srcItemSlotPos, dstItemSlotPos) - - elif item.GetUseType(srcItemVID) in self.USE_TYPE_TUPLE: - self.__SendUseItemToItemPacket(srcItemSlotPos, dstItemSlotPos) - - else: - #snd.PlaySound("sound/ui/drop.wav") - - ## If destination is an equipment slot, use item to equip it - [levites] - if player.IsEquipmentSlot(dstItemSlotPos): - - ## Only when holding equipment item - if item.IsEquipmentVID(srcItemVID): - self.__UseItem(srcItemSlotPos) - - else: - self.__SendMoveItemPacket(srcItemSlotPos, dstItemSlotPos, 0) - #net.SendItemMovePacket(srcItemSlotPos, dstItemSlotPos, 0) - - def __SellItem(self, itemSlotPos): - if not player.IsEquipmentSlot(itemSlotPos): - self.sellingSlotNumber = itemSlotPos - itemIndex = player.GetItemIndex(itemSlotPos) - itemCount = player.GetItemCount(itemSlotPos) - - - self.sellingSlotitemIndex = itemIndex - self.sellingSlotitemCount = itemCount - - item.SelectItem(itemIndex) - ## Added anti-flag check that was missing - ## 20140220 - if item.IsAntiFlag(item.ANTIFLAG_SELL): - popup = uiCommon.PopupDialog() - popup.SetText(localeInfo.SHOP_CANNOT_SELL_ITEM) - popup.SetAcceptEvent(self.__OnClosePopupDialog) - popup.Open() - self.popup = popup - return - - itemPrice = item.GetISellItemPrice() - - if item.Is1GoldItem(): - itemPrice = itemCount // itemPrice // 5 - else: - itemPrice = itemPrice * itemCount // 5 - - item.GetItemName(itemIndex) - itemName = item.GetItemName() - - self.questionDialog = uiCommon.QuestionDialog() - self.questionDialog.SetText(localeInfo.DO_YOU_SELL_ITEM(itemName, itemCount, itemPrice)) - self.questionDialog.SetAcceptEvent(ui.__mem_func__(self.SellItem)) - self.questionDialog.SetCancelEvent(ui.__mem_func__(self.OnCloseQuestionDialog)) - self.questionDialog.Open() - self.questionDialog.count = itemCount - - constInfo.SET_ITEM_QUESTION_DIALOG_STATUS(1) - - def __OnClosePopupDialog(self): - self.pop = None - - def RefineItem(self, scrollSlotPos, targetSlotPos): - - scrollIndex = player.GetItemIndex(scrollSlotPos) - targetIndex = player.GetItemIndex(targetSlotPos) - - if player.REFINE_OK != player.CanRefine(scrollIndex, targetSlotPos): - return - - ########################################################### - self.__SendUseItemToItemPacket(scrollSlotPos, targetSlotPos) - #net.SendItemUseToItemPacket(scrollSlotPos, targetSlotPos) - return - ########################################################### - - ########################################################### - #net.SendRequestRefineInfoPacket(targetSlotPos) - #return - ########################################################### - - result = player.CanRefine(scrollIndex, targetSlotPos) - - if player.REFINE_ALREADY_MAX_SOCKET_COUNT == result: - #snd.PlaySound("sound/ui/jaeryun_fail.wav") - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.REFINE_FAILURE_NO_MORE_SOCKET) - - elif player.REFINE_NEED_MORE_GOOD_SCROLL == result: - #snd.PlaySound("sound/ui/jaeryun_fail.wav") - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.REFINE_FAILURE_NEED_BETTER_SCROLL) - - elif player.REFINE_CANT_MAKE_SOCKET_ITEM == result: - #snd.PlaySound("sound/ui/jaeryun_fail.wav") - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.REFINE_FAILURE_SOCKET_DISABLE_ITEM) - - elif player.REFINE_NOT_NEXT_GRADE_ITEM == result: - #snd.PlaySound("sound/ui/jaeryun_fail.wav") - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.REFINE_FAILURE_UPGRADE_DISABLE_ITEM) - - elif player.REFINE_CANT_REFINE_METIN_TO_EQUIPMENT == result: - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.REFINE_FAILURE_EQUIP_ITEM) - - if player.REFINE_OK != result: - return - - self.refineDialog.Open(scrollSlotPos, targetSlotPos) - - def DetachMetinFromItem(self, scrollSlotPos, targetSlotPos): - scrollIndex = player.GetItemIndex(scrollSlotPos) - targetIndex = player.GetItemIndex(targetSlotPos) - - if not player.CanDetach(scrollIndex, targetSlotPos): - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.REFINE_FAILURE_METIN_INSEPARABLE_ITEM) - return - - self.questionDialog = uiCommon.QuestionDialog() - self.questionDialog.SetText(localeInfo.REFINE_DO_YOU_SEPARATE_METIN) - self.questionDialog.SetAcceptEvent(ui.__mem_func__(self.OnDetachMetinFromItem)) - self.questionDialog.SetCancelEvent(ui.__mem_func__(self.OnCloseQuestionDialog)) - self.questionDialog.Open() - self.questionDialog.sourcePos = scrollSlotPos - self.questionDialog.targetPos = targetSlotPos - - def AttachMetinToItem(self, metinSlotPos, targetSlotPos): - metinIndex = player.GetItemIndex(metinSlotPos) - targetIndex = player.GetItemIndex(targetSlotPos) - - item.SelectItem(metinIndex) - itemName = item.GetItemName() - - result = player.CanAttachMetin(metinIndex, targetSlotPos) - - if player.ATTACH_METIN_NOT_MATCHABLE_ITEM == result: - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.REFINE_FAILURE_CAN_NOT_ATTACH(itemName)) - - if player.ATTACH_METIN_NO_MATCHABLE_SOCKET == result: - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.REFINE_FAILURE_NO_SOCKET(itemName)) - - elif player.ATTACH_METIN_NOT_EXIST_GOLD_SOCKET == result: - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.REFINE_FAILURE_NO_GOLD_SOCKET(itemName)) - - elif player.ATTACH_METIN_CANT_ATTACH_TO_EQUIPMENT == result: - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.REFINE_FAILURE_EQUIP_ITEM) - - if player.ATTACH_METIN_OK != result: - return - - self.attachMetinDialog.Open(metinSlotPos, targetSlotPos) - - - - def OverOutItem(self): - self.wndItem.SetUsableItem(False) - if None != self.tooltipItem: - self.tooltipItem.HideToolTip() - - def OverInItem(self, overSlotPos): - overSlotPos = self.__InventoryLocalSlotPosToGlobalSlotPos(overSlotPos) - self.wndItem.SetUsableItem(False) - - if mouseModule.mouseController.isAttached(): - attachedItemType = mouseModule.mouseController.GetAttachedType() - if player.SLOT_TYPE_INVENTORY == attachedItemType: - - attachedSlotPos = mouseModule.mouseController.GetAttachedSlotNumber() - attachedItemVNum = mouseModule.mouseController.GetAttachedItemIndex() - - if self.__CanUseSrcItemToDstItem(attachedItemVNum, attachedSlotPos, overSlotPos): - self.wndItem.SetUsableItem(True) - self.ShowToolTip(overSlotPos) - return - - self.ShowToolTip(overSlotPos) - - - def __IsUsableItemToItem(self, srcItemVNum, srcSlotPos): - "Can this item be used on other items?" - - if item.IsRefineScroll(srcItemVNum): - return True - elif item.IsMetin(srcItemVNum): - return True - elif item.IsDetachScroll(srcItemVNum): - return True - elif item.IsKey(srcItemVNum): - return True - elif (player.GetItemFlags(srcSlotPos) & ITEM_FLAG_APPLICABLE) == ITEM_FLAG_APPLICABLE: - return True - else: - if item.GetUseType(srcItemVNum) in self.USE_TYPE_TUPLE: - return True - - return False - - def __CanUseSrcItemToDstItem(self, srcItemVNum, srcSlotPos, dstSlotPos): - "Can this item be used on the target item?" - - if srcSlotPos == dstSlotPos: - return False - - if item.IsRefineScroll(srcItemVNum): - if player.REFINE_OK == player.CanRefine(srcItemVNum, dstSlotPos): - return True - elif item.IsMetin(srcItemVNum): - if player.ATTACH_METIN_OK == player.CanAttachMetin(srcItemVNum, dstSlotPos): - return True - elif item.IsDetachScroll(srcItemVNum): - if player.DETACH_METIN_OK == player.CanDetach(srcItemVNum, dstSlotPos): - return True - elif item.IsKey(srcItemVNum): - if player.CanUnlock(srcItemVNum, dstSlotPos): - return True - - elif (player.GetItemFlags(srcSlotPos) & ITEM_FLAG_APPLICABLE) == ITEM_FLAG_APPLICABLE: - return True - - else: - useType=item.GetUseType(srcItemVNum) - - if "USE_CLEAN_SOCKET" == useType: - if self.__CanCleanBrokenMetinStone(dstSlotPos): - return True - elif "USE_CHANGE_ATTRIBUTE" == useType: - if self.__CanChangeItemAttrList(dstSlotPos): - return True - elif "USE_ADD_ATTRIBUTE" == useType: - if self.__CanAddItemAttr(dstSlotPos): - return True - elif "USE_ADD_ATTRIBUTE2" == useType: - if self.__CanAddItemAttr(dstSlotPos): - return True - elif "USE_ADD_ACCESSORY_SOCKET" == useType: - # MR-10: Add belt support for accessory sockets - if self.__CanAddAccessorySocket(dstSlotPos) or self.__CanAddBeltSocket(dstSlotPos): - return True - # MR-10: -- END OF -- Add belt support for accessory sockets - elif "USE_PUT_INTO_ACCESSORY_SOCKET" == useType: - if self.__CanPutAccessorySocket(dstSlotPos, srcItemVNum): - return True - elif "USE_PUT_INTO_BELT_SOCKET" == useType: - # MR-10: Add belt support for accessory sockets - if self.__CanPutBeltSocket(dstSlotPos, srcItemVNum): - return True - # MR-10: -- END OF -- Add belt support for accessory sockets - - return False - - def __CanCleanBrokenMetinStone(self, dstSlotPos): - dstItemVNum = player.GetItemIndex(dstSlotPos) - if dstItemVNum == 0: - return False - - item.SelectItem(dstItemVNum) - - if item.ITEM_TYPE_WEAPON != item.GetItemType(): - return False - - for i in range(player.METIN_SOCKET_MAX_NUM): - if player.GetItemMetinSocket(dstSlotPos, i) == constInfo.ERROR_METIN_STONE: - return True - - return False - - def __CanChangeItemAttrList(self, dstSlotPos): - dstItemVNum = player.GetItemIndex(dstSlotPos) - if dstItemVNum == 0: - return False - - item.SelectItem(dstItemVNum) - - if not item.GetItemType() in (item.ITEM_TYPE_WEAPON, item.ITEM_TYPE_ARMOR): - return False - - for i in range(player.METIN_SOCKET_MAX_NUM): - if player.GetItemAttribute(dstSlotPos, i) != 0: - return True - - return False - - # MR-10: Add belt support for accessory sockets - def __CanPutBeltSocket(self, dstSlotPos, mtrlVnum): - dstItemVNum = player.GetItemIndex(dstSlotPos) - - if dstItemVNum == 0: - return False - - item.SelectItem(dstItemVNum) - - if item.ITEM_TYPE_BELT != item.GetItemType(): - return False - - if mtrlVnum != constInfo.GET_BELT_MATERIAL_VNUM(dstItemVNum): - return False - - curCount = player.GetItemMetinSocket(dstSlotPos, 0) - maxCount = player.GetItemMetinSocket(dstSlotPos, 1) - - if maxCount <= 0: - return False - - if curCount >= maxCount: - return False - - return True - # MR-10: -- END OF -- Add belt support for accessory sockets - - def __CanPutAccessorySocket(self, dstSlotPos, mtrlVnum): - dstItemVNum = player.GetItemIndex(dstSlotPos) - if dstItemVNum == 0: - return False - - item.SelectItem(dstItemVNum) - - if item.GetItemType() != item.ITEM_TYPE_ARMOR: - return False - - if not item.GetItemSubType() in (item.ARMOR_WRIST, item.ARMOR_NECK, item.ARMOR_EAR): - return False - - curCount = player.GetItemMetinSocket(dstSlotPos, 0) - maxCount = player.GetItemMetinSocket(dstSlotPos, 1) - - if mtrlVnum != constInfo.GET_ACCESSORY_MATERIAL_VNUM(dstItemVNum, item.GetItemSubType()): - return False - - if curCount>=maxCount: - return False - - return True - - def __CanAddAccessorySocket(self, dstSlotPos): - dstItemVNum = player.GetItemIndex(dstSlotPos) - if dstItemVNum == 0: - return False - - item.SelectItem(dstItemVNum) - - if item.GetItemType() != item.ITEM_TYPE_ARMOR: - return False - - if not item.GetItemSubType() in (item.ARMOR_WRIST, item.ARMOR_NECK, item.ARMOR_EAR): - return False - - curCount = player.GetItemMetinSocket(dstSlotPos, 0) - maxCount = player.GetItemMetinSocket(dstSlotPos, 1) - - ACCESSORY_SOCKET_MAX_SIZE = 3 - if maxCount >= ACCESSORY_SOCKET_MAX_SIZE: - return False - - return True - - # MR-10: Add belt support for accessory sockets - def __CanAddBeltSocket(self, dstSlotPos): - dstItemVNum = player.GetItemIndex(dstSlotPos) - - if dstItemVNum == 0: - return False - - item.SelectItem(dstItemVNum) - - if item.ITEM_TYPE_BELT != item.GetItemType(): - return False - - curCount = player.GetItemMetinSocket(dstSlotPos, 0) - maxCount = player.GetItemMetinSocket(dstSlotPos, 1) - - ACCESSORY_SOCKET_MAX_SIZE = 3 - - if maxCount >= ACCESSORY_SOCKET_MAX_SIZE: - return False - - return True - # MR-10: -- END OF -- Add belt support for accessory sockets - - def __CanAddItemAttr(self, dstSlotPos): - dstItemVNum = player.GetItemIndex(dstSlotPos) - if dstItemVNum == 0: - return False - - item.SelectItem(dstItemVNum) - - if not item.GetItemType() in (item.ITEM_TYPE_WEAPON, item.ITEM_TYPE_ARMOR): - return False - - attrCount = 0 - for i in range(player.METIN_SOCKET_MAX_NUM): - if player.GetItemAttribute(dstSlotPos, i) != 0: - attrCount += 1 - - if attrCount<4: - return True - - return False - - def ShowToolTip(self, slotIndex): - if None != self.tooltipItem: - self.tooltipItem.SetInventoryItem(slotIndex) - - def OnTop(self): - if None != self.tooltipItem: - self.tooltipItem.SetTop() - - if self.wndBelt: - self.wndBelt.SetTop() - - def OnPressEscapeKey(self): - self.Close() - return True - - def UseItemSlot(self, slotIndex): - curCursorNum = app.GetCursor() - if app.SELL == curCursorNum: - return - - if constInfo.GET_ITEM_QUESTION_DIALOG_STATUS(): - return - - slotIndex = self.__InventoryLocalSlotPosToGlobalSlotPos(slotIndex) - - if app.ENABLE_DRAGON_SOUL_SYSTEM: - if self.wndDragonSoulRefine.IsShow(): - self.wndDragonSoulRefine.AutoSetItem((player.INVENTORY, slotIndex), 1) - return - - self.__UseItem(slotIndex) - mouseModule.mouseController.DeattachObject() - self.OverOutItem() - - def __UseItem(self, slotIndex): - ItemVNum = player.GetItemIndex(slotIndex) - item.SelectItem(ItemVNum) - if item.IsFlag(item.ITEM_FLAG_CONFIRM_WHEN_USE): - self.questionDialog = uiCommon.QuestionDialog() - self.questionDialog.SetText(localeInfo.INVENTORY_REALLY_USE_ITEM) - self.questionDialog.SetAcceptEvent(ui.__mem_func__(self.__UseItemQuestionDialog_OnAccept)) - self.questionDialog.SetCancelEvent(ui.__mem_func__(self.__UseItemQuestionDialog_OnCancel)) - self.questionDialog.Open() - self.questionDialog.slotIndex = slotIndex - - constInfo.SET_ITEM_QUESTION_DIALOG_STATUS(1) - - else: - self.__SendUseItemPacket(slotIndex) - #net.SendItemUsePacket(slotIndex) - - def __UseItemQuestionDialog_OnCancel(self): - self.OnCloseQuestionDialog() - - def __UseItemQuestionDialog_OnAccept(self): - self.__SendUseItemPacket(self.questionDialog.slotIndex) - self.OnCloseQuestionDialog() - - def __SendUseItemToItemPacket(self, srcSlotPos, dstSlotPos): - # Prevent item usage while private shop is open - if uiPrivateShopBuilder.IsBuildingPrivateShop(): - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.USE_ITEM_FAILURE_PRIVATE_SHOP) - return - - net.SendItemUseToItemPacket(srcSlotPos, dstSlotPos) - - def __SendUseItemPacket(self, slotPos): - # Prevent item usage while private shop is open - if uiPrivateShopBuilder.IsBuildingPrivateShop(): - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.USE_ITEM_FAILURE_PRIVATE_SHOP) - return - - net.SendItemUsePacket(slotPos) - - def __SendMoveItemPacket(self, srcSlotPos, dstSlotPos, srcItemCount): - # Prevent item movement while private shop is open - if uiPrivateShopBuilder.IsBuildingPrivateShop(): - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.MOVE_ITEM_FAILURE_PRIVATE_SHOP) - return - - net.SendItemMovePacket(srcSlotPos, dstSlotPos, srcItemCount) - - def SetDragonSoulRefineWindow(self, wndDragonSoulRefine): - if app.ENABLE_DRAGON_SOUL_SYSTEM: - self.wndDragonSoulRefine = wndDragonSoulRefine - - def OnMoveWindow(self, x, y): -# print "Inventory Global Pos : ", self.GetGlobalPosition() - if self.wndBelt: -# print "Belt Global Pos : ", self.wndBelt.GetGlobalPosition() - self.wndBelt.AdjustPositionAndSize() - diff --git a/tools/root/uilocalerefresh.py b/tools/root/uilocalerefresh.py deleted file mode 100644 index 9dc97ae8..00000000 --- a/tools/root/uilocalerefresh.py +++ /dev/null @@ -1,64 +0,0 @@ -""" -Generic UI Locale Refresh System -Provides RefreshByMapping and RebuildDictionary for hot-reload support. -""" - -import dbg - -def RefreshByMapping(elementMap): - """ - Refresh UI elements using a mapping dictionary. - - Args: - elementMap: Dict of {element_instance: "LOCALE_KEY_NAME"} - - Returns: - Number of elements successfully refreshed - """ - import uiScriptLocale - import localeInfo - - refreshCount = 0 - for element, localeKey in list(elementMap.items()): - try: - # Try uiScriptLocale first, then localeInfo - if hasattr(uiScriptLocale, localeKey): - text = getattr(uiScriptLocale, localeKey) - elif hasattr(localeInfo, localeKey): - text = getattr(localeInfo, localeKey) - else: - dbg.TraceError("LocaleRefresh: key not found: %s" % localeKey) - continue - - if hasattr(element, 'SetText'): - element.SetText(text) - refreshCount += 1 - except Exception as e: - dbg.TraceError("LocaleRefresh: failed for key %s: %s" % (localeKey, str(e))) - - return refreshCount - -def RebuildDictionary(template, localeModule="localeInfo"): - """ - Rebuild a dictionary with fresh locale strings. - - Args: - template: Dict of {key: "LOCALE_CONSTANT_NAME"} - localeModule: "localeInfo" or "uiScriptLocale" - - Returns: - New dictionary with resolved locale values - """ - import localeInfo - import uiScriptLocale - - module = localeInfo if localeModule == "localeInfo" else uiScriptLocale - newDict = {} - - for key, localeKey in list(template.items()): - if hasattr(module, localeKey): - newDict[key] = getattr(module, localeKey) - else: - dbg.TraceError("LocaleRefresh: key not found: %s" % localeKey) - - return newDict diff --git a/tools/root/uilocaleselector.py b/tools/root/uilocaleselector.py deleted file mode 100644 index 0c822a15..00000000 --- a/tools/root/uilocaleselector.py +++ /dev/null @@ -1,192 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Locale Selector UI Component -============================= - -A reusable UI component for selecting and changing the client language. -Can be added to any window (login, game settings, etc.). - -Usage: - from uilocaleselector import LocaleSelector - - # In your window class: - self.localeSelector = LocaleSelector() - self.localeSelector.Create(self) - self.localeSelector.SetLocaleChangedEvent(ui.__mem_func__(self.__OnLocaleChanged)) - - # Implement the callback: - def __OnLocaleChanged(self, newLocaleCode): - # Handle UI recreation here - pass -""" - -import ui -import uiCommon -import localeInfo -import wndMgr - - -# Available locales configuration -AVAILABLE_LOCALES = [ - {"code": "ae", "name": "Arabic", "flag": "ae"}, - {"code": "br", "name": "Português Brasileiro", "flag": "br"}, - {"code": "en", "name": "English", "flag": "en"}, - {"code": "cz", "name": "Čeština", "flag": "cz"}, - {"code": "de", "name": "Deutsch", "flag": "de"}, - {"code": "dk", "name": "Dansk", "flag": "dk"}, - {"code": "es", "name": "Español", "flag": "es"}, - {"code": "fr", "name": "Français", "flag": "fr"}, - {"code": "gr", "name": "Ελληνικά", "flag": "gr"}, - {"code": "hu", "name": "Magyar", "flag": "hu"}, - {"code": "it", "name": "Italiano", "flag": "it"}, - {"code": "nl", "name": "Nederlands", "flag": "nl"}, - {"code": "pl", "name": "Polski", "flag": "pl"}, - {"code": "pt", "name": "Português", "flag": "pt"}, - {"code": "ro", "name": "Română", "flag": "ro"}, - {"code": "ru", "name": "Русский", "flag": "ru"}, - {"code": "tr", "name": "Türkçe", "flag": "tr"}, -] - -# Flag image path template -FLAG_IMAGE_PATH = "d:/ymir work/ui/intro/login/server_flag_%s.sub" - - -class LocaleSelector(ui.Window): - """ - UI component for selecting and changing client language. - - Features: - - Displays flag buttons for all available locales - - Shows confirmation dialog before changing - - Triggers callback when locale is confirmed - - Self-contained and reusable - """ - - def __init__(self): - ui.Window.__init__(self) - self.background = None - self.flagButtons = [] - self.confirmDialog = None - self.selectedLocaleCode = None - self.eventLocaleChanged = None - - def __del__(self): - ui.Window.__del__(self) - - def Destroy(self): - """Clean up resources when destroying the selector.""" - self.eventLocaleChanged = None - self.selectedLocaleCode = None - - if self.confirmDialog: - self.confirmDialog.Close() - self.confirmDialog = None - - for btn in self.flagButtons: - btn.SetEvent(None) - btn.Hide() - self.flagButtons = [] - - if self.background: - self.background.Hide() - self.background = None - - def Create(self, parent): - """ - Create and display the locale selector UI. - - Args: - parent: The parent window to attach to - """ - self.SetParent(parent) - self.SetSize(wndMgr.GetScreenWidth(), 35) - self.SetPosition(0, 20) - - # Create background board - self.background = ui.ThinBoard() - self.background.SetParent(self) - self.background.SetSize(wndMgr.GetScreenWidth(), 35) - self.background.SetPosition(0, 0) - self.background.Show() - - # Create flag buttons - self._CreateFlagButtons() - - self.Show() - - def _CreateFlagButtons(self): - """Create flag buttons for all available locales.""" - localeCount = len(AVAILABLE_LOCALES) - if localeCount == 0: - return - - buttonSpacing = wndMgr.GetScreenWidth() / localeCount - xPosition = 0 - - for locale in AVAILABLE_LOCALES: - flagPath = FLAG_IMAGE_PATH % locale["flag"] - - button = ui.Button() - button.SetParent(self.background) - button.SetPosition(xPosition + 15, 10) - button.SetUpVisual(flagPath) - button.SetOverVisual(flagPath) - button.SetDownVisual(flagPath) - button.SetToolTipText(locale["name"]) - button.SetEvent(ui.__mem_func__(self._OnClickFlag), locale["code"]) - button.Show() - - self.flagButtons.append(button) - xPosition += buttonSpacing - - def _OnClickFlag(self, localeCode): - """ - Handle flag button click - show confirmation dialog. - - Args: - localeCode: The locale code that was clicked - """ - self.selectedLocaleCode = localeCode - - # Get locale name for display - localeName = "Unknown" - for locale in AVAILABLE_LOCALES: - if locale["code"] == localeCode: - localeName = locale["name"] - break - - # Show confirmation dialog - if not self.confirmDialog: - self.confirmDialog = uiCommon.QuestionDialog() - - self.confirmDialog.SetText(localeInfo.LOCALE_CHANGE_CONFIRM % localeName) - self.confirmDialog.SetAcceptEvent(ui.__mem_func__(self._OnConfirmLocaleChange)) - self.confirmDialog.SetCancelEvent(ui.__mem_func__(self._OnCancelLocaleChange)) - self.confirmDialog.Open() - - def _OnConfirmLocaleChange(self): - """User confirmed locale change - trigger the callback.""" - if self.confirmDialog: - self.confirmDialog.Close() - - if not self.selectedLocaleCode: - return - - # Notify parent window to handle the locale change - if self.eventLocaleChanged: - self.eventLocaleChanged(self.selectedLocaleCode) - - def _OnCancelLocaleChange(self): - """User cancelled locale change.""" - if self.confirmDialog: - self.confirmDialog.Close() - self.selectedLocaleCode = None - - def SetLocaleChangedEvent(self, event): - """ - Set callback function to be called when locale is confirmed. - - Args: - event: Callback function(localeCode) to handle locale change - """ - self.eventLocaleChanged = event diff --git a/tools/root/uimapnameshower.py b/tools/root/uimapnameshower.py deleted file mode 100644 index 5b9d15d3..00000000 --- a/tools/root/uimapnameshower.py +++ /dev/null @@ -1,211 +0,0 @@ -import app -import ui -import uiScriptLocale -import localeInfo - -LOCALE_PATH = uiScriptLocale.MAPNAME_PATH - -# Static map name -> image suffix mapping (locale-independent) -_MAP_NAME_SUFFIXES = { - "metin2_map_a1": "a1.tga", - "map_a2": "a2.tga", - "metin2_map_a3": "a3.tga", - "metin2_map_b1": "b1.tga", - "map_b2": "b2.tga", - "metin2_map_b3": "b3.tga", - "metin2_map_c1": "c1.tga", - "map_c2": "c2.tga", - "metin2_map_c3": "c3.tga", - "map_n_snowm_01": "snow1.tga", - "metin2_map_deviltower1": "devil1_title.tga", - "metin2_map_n_flame_01": "frame1.tga", - "metin2_map_n_desert_01": "desert1.tga", - "metin2_map_milgyo": "milgyo.tga", - "metin2_map_monkeydungeon": "monkey1.tga", - "metin2_map_monkeydungeon_02": "monkey2.tga", - "metin2_map_monkeydungeon_03": "monkey3.tga", - "metin2_map_guild_01": "guild1.tga", - "metin2_map_guild_02": "guild2.tga", - "metin2_map_guild_03": "guild3.tga", - "metin2_map_trent": "trent.tga", - "metin2_map_trent02": "trent02.tga", - "season2/map_n_snowm_02": "snow2.tga", - "season2/metin2_map_a2_1": "a2_2.tga", - "season2/metin2_map_n_desert_02": "desert2.tga", - "season2/metin2_map_n_flame_02": "frame2.tga", - "season2/metin2_map_milgyo_a": "milgyo2.TGA", - "season2/metin2_map_trent_a": "trent_a.tga", - "season2/metin2_map_trent02_a": "trent02_a.tga", - "season2/metin2_map_skipia_dungeon_01": "skipia.tga", - "season2/metin2_map_skipia_dungeon_02": "skipia.tga", - "metin2_map_devilsCatacomb": "devil_basement.tga", - "metin2_guild_village_01": "a4.tga", - "metin2_guild_village_02": "b4.tga", - "metin2_guild_village_03": "c4.tga", - "metin2_map_BayBlackSand": "bay.tga", - "metin2_map_Mt_Thunder": "thunder.tga", - "metin2_map_dawnmistwood": "dawn.tga", - "Metin2_map_CapeDragonHead": "cape.tga", - "metin2_map_spiderdungeon": "spider1.tga", - "metin2_map_spiderdungeon_02": "spider1.tga", - "metin2_map_spiderdungeon_03": "spider1.tga", -} - -def _RebuildLocaleStrings(): - global LOCALE_PATH - LOCALE_PATH = uiScriptLocale.MAPNAME_PATH - -localeInfo.RegisterReloadCallback(_RebuildLocaleStrings) - -class MapNameShower(ui.ExpandedImageBox): - - STATE_HIDE = 0 - STATE_FADE_IN = 1 - STATE_SHOW = 2 - STATE_FADE_OUT = 3 - - def __init__(self): - ui.ExpandedImageBox.__init__(self, "TOP_MOST") - self.AddFlag("not_pick") - self.__Initialize() - - def __del__(self): - ui.ExpandedImageBox.__del__(self) - - def __Initialize(self): - self.floorImage = None - self.objectiveImage = None - self.fadeStartTime = 0 - self.state = self.STATE_HIDE - self.curAlpha = 0.0 - self.SetAlpha(0.0) - self.SetWindowHorizontalAlignCenter() - self.SetPosition(0, 80) - self.Hide() - - def __GetDevilTowerFloor(self, x, y): - if x > 10000 and y > 58000 and x < 25000 and y < 72000: - return 1 - elif x > 10000 and y > 35000 and x < 25000 and y < 50000: - return 2 - elif x > 10000 and y > 10000 and x < 25000 and y < 25000: - return 3 - elif x > 35000 and y > 61000 and x < 43500 and y < 70500: - return 4 - elif x > 35000 and y > 38000 and x < 43500 and y < 48000: - return 5 - elif x > 14000 and y > 14000 and x < 43500 and y < 24500: - return 6 - elif x > 56000 and y > 60000 and x < 68000 and y < 73000: - return 7 - elif x > 56000 and y > 38000 and x < 68000 and y < 49000: - return 8 - elif x > 56000 and y > 13000 and x < 68000 and y < 23000: - return 9 - return 0 - - def __GetDevilBase(self, x, y): - if x > 3000 and y > 4500 and x < 45000 and y < 45000: - return 1 - elif x > 54000 and y > 3900 and x < 100000 and y < 46200: - return 2 - elif x > 104800 and y > 3500 and x < 145500 and y < 45800: - return 3 - elif x > 3100 and y > 54100 and x < 56400 and y < 105800: - return 4 - elif x > 65000 and y > 54000 and x < 105000 and y < 95500: - return 5 - elif x > 117500 and y > 57600 and x < 142000 and y < 81000: - return 6 - elif x > 5000 and y > 104900 and x < 15000 and y < 122000: - return 7 - return 0 - - def ShowMapName(self, mapName, x, y): - if mapName not in _MAP_NAME_SUFFIXES: - print((" [ERROR] - There is no map name image", mapName)) - return - - try: - self.LoadImage(LOCALE_PATH + _MAP_NAME_SUFFIXES[mapName]) - except RuntimeError: - return - - self.__Initialize() - - if mapName == "metin2_map_deviltower1": - self.SetPosition(-60, 80) - - self.floorImage = ui.ExpandedImageBox() - self.floorImage.AddFlag("not_pick") - self.floorImage.SetWindowHorizontalAlignCenter() - self.floorImage.SetPosition(100, 80) - self.floorImage.SetAlpha(0.0) - self.floorImage.Show() - - try: - floor = self.__GetDevilTowerFloor(x, y) - print((x, y, floor)) - self.floorImage.LoadImage(LOCALE_PATH+"devil1_%df.tga" % floor) - except RuntimeError: - self.SetPosition(0, 80) - self.floorImage.Hide() - self.floorImage = None - - if mapName == "metin2_map_devilsCatacomb": - self.SetPosition(-75, 80) - - self.floorImage = ui.ExpandedImageBox() - self.floorImage.AddFlag("not_pick") - self.floorImage.SetWindowHorizontalAlignCenter() - self.floorImage.SetPosition(100, 80) - self.floorImage.SetAlpha(0.0) - self.floorImage.Show() - - try: - floor = self.__GetDevilBase(x, y) - print((x, y, floor)) - self.floorImage.LoadImage(LOCALE_PATH+"devil1_%df.tga" % floor) - except RuntimeError: - self.SetPosition(0, 80) - self.floorImage.Hide() - self.floorImage = None - - self.state = self.STATE_FADE_IN - self.fadeStartTime = app.GetTime() + 1.0 - self.Show() - - def Update(self): - - self.SetAlpha(self.curAlpha) - if self.floorImage: - self.floorImage.SetAlpha(self.curAlpha) - - if self.objectiveImage: - self.objectiveImage.SetAlpha(self.curAlpha) - - if self.STATE_FADE_IN == self.state: - if app.GetTime() > self.fadeStartTime: - self.curAlpha += 0.05 - - if self.curAlpha > 0.9: - self.state = self.STATE_SHOW - self.fadeStartTime = app.GetTime() + 5.0 - - elif self.STATE_SHOW == self.state: - if app.GetTime() > self.fadeStartTime: - self.state = self.STATE_FADE_OUT - - elif self.STATE_FADE_OUT == self.state: - self.curAlpha -= 0.05 - - if self.curAlpha < 0.0001: - self.Hide() - if self.floorImage: - self.floorImage.Hide() - self.floorImage = None - - if self.objectiveImage: - self.objectiveImage.Hide() - self.objectiveImage = None - return diff --git a/tools/root/uimessenger.py b/tools/root/uimessenger.py deleted file mode 100644 index 9dbbc2d8..00000000 --- a/tools/root/uimessenger.py +++ /dev/null @@ -1,739 +0,0 @@ -import app -import ui -import grp -import net -import guild -import messenger -import localeInfo -import constInfo -import uiToolTip -import uiCommon -from _weakref import proxy - -FRIEND = 0 -GUILD = 1 - -class MessengerItem(ui.Window): - - def __init__(self, getParentEvent): - ui.Window.__init__(self) - - self.SetParent(getParentEvent()) - self.AddFlag("float") - - self.name = "" - self.image = ui.ImageBox() - self.image.AddFlag("not_pick") - self.image.SetParent(self) - self.image.Show() - self.text = ui.TextLine() - self.text.SetParent(self) - self.text.SetPosition(20, 2) - self.text.Show() - - self.lovePoint = -1 - self.lovePointToolTip = None - - self.isSelected = False - - self.getParentEvent = getParentEvent - - def SetName(self, name): - self.name = name - if name: - self.text.SetText(name) - self.SetSize(20 + 6*len(name) + 4, 16) - - if app.IsRTL(): - self.text.SetPosition(20 + 6*len(name) + 4, 2) - - def SetLovePoint(self, lovePoint): - self.lovePoint = lovePoint - - def Select(self): - self.isSelected = True - - def UnSelect(self): - self.isSelected = False - - def GetName(self): - return self.name - - def GetStepWidth(self): - return 0 - - # Whisper - def CanWhisper(self): - return False - - def IsOnline(self): - return False - - def OnWhisper(self): - pass - - # Remove - def CanRemove(self): - return False - - def OnRemove(self): - return False - - # Warp - def CanWarp(self): - return False - - def OnWarp(self): - pass - - def OnMouseOverIn(self): - if -1 != self.lovePoint: - if not self.lovePointToolTip: - self.lovePointToolTip = uiToolTip.ToolTip(100) - self.lovePointToolTip.SetTitle(self.name) - self.lovePointToolTip.AppendTextLine(localeInfo.AFF_LOVE_POINT % (self.lovePoint)) - self.lovePointToolTip.ResizeToolTip() - self.lovePointToolTip.ShowToolTip() - - def OnMouseOverOut(self): - if self.lovePointToolTip: - self.lovePointToolTip.HideToolTip() - - def OnMouseLeftButtonDown(self): - self.getParentEvent().OnSelectItem(self) - - def OnMouseLeftButtonDoubleClick(self): - self.getParentEvent().OnDoubleClickItem(self) - - def OnRender(self): - if self.isSelected: - x, y = self.GetGlobalPosition() - - grp.SetColor(grp.GenerateColor(0.0, 0.0, 0.7, 0.7)) - grp.RenderBar(x + 16, y, self.GetWidth() - 16, self.GetHeight()) - -class MessengerMemberItem(MessengerItem): - - STATE_OFFLINE = 0 - STATE_ONLINE = 1 - - IMAGE_FILE_NAME = { "ONLINE" : "d:/ymir work/ui/game/windows/messenger_list_online.sub", - "OFFLINE" : "d:/ymir work/ui/game/windows/messenger_list_offline.sub", } - - def __init__(self, getParentEvent): - MessengerItem.__init__(self, getParentEvent) - self.key = None - self.state = self.STATE_OFFLINE - self.Offline() - - @property - def RemoveMessage(self): - return localeInfo.MESSENGER_DO_YOU_DELETE - - def GetStepWidth(self): - return 15 - - def SetKey(self, key): - self.key = key - - def IsSameKey(self, key): - return self.key == key - - def IsOnline(self): - if self.STATE_ONLINE == self.state: - return True - - return False - - def Online(self): - self.image.LoadImage(self.IMAGE_FILE_NAME["ONLINE"]) - self.state = self.STATE_ONLINE - - def Offline(self): - self.image.LoadImage(self.IMAGE_FILE_NAME["OFFLINE"]) - self.state = self.STATE_OFFLINE - - def CanWhisper(self): - if self.IsOnline(): - return True - - return False - - def OnWhisper(self): - if self.IsOnline(): - self.getParentEvent().whisperButtonEvent(self.GetName()) - - def Select(self): - MessengerItem.Select(self) - -class MessengerGroupItem(MessengerItem): - - IMAGE_FILE_NAME = { "OPEN" : "d:/ymir work/ui/game/windows/messenger_list_open.sub", - "CLOSE" : "d:/ymir work/ui/game/windows/messenger_list_close.sub", } - - def __init__(self, getParentEvent): - self.isOpen = False - self.memberList = [] - - MessengerItem.__init__(self, getParentEvent) - - def AppendMember(self, member, key, name): - member.SetKey(key) - member.SetName(name) - self.memberList.append(member) - return member - - def RemoveMember(self, item): - for i in range(len(self.memberList)): - if item == self.memberList[i]: - del self.memberList[i] - return - - def ClearMember(self): - self.memberList = [] - - def FindMember(self, key): - return next((m for m in self.memberList if m.IsSameKey(key)), None) - - def GetLoginMemberList(self): - return list(filter(MessengerMemberItem.IsOnline, self.memberList)) - - def GetLogoutMemberList(self): - return [arg for arg in self.memberList if not arg.IsOnline()] - - def IsOpen(self): - return self.isOpen - - def Open(self): - self.image.LoadImage(self.IMAGE_FILE_NAME["OPEN"]) - self.isOpen = True - - def Close(self): - self.image.LoadImage(self.IMAGE_FILE_NAME["CLOSE"]) - self.isOpen = False - - list(map(ui.Window.Hide, self.memberList)) - - def Select(self): - - if self.IsOpen(): - self.Close() - else: - self.Open() - - MessengerItem.Select(self) - self.getParentEvent().OnRefreshList() - -class MessengerFriendItem(MessengerMemberItem): - - def __init__(self, getParentEvent): - MessengerMemberItem.__init__(self, getParentEvent) - - def CanRemove(self): - return True - - def OnRemove(self): - messenger.RemoveFriend(self.key) - net.SendMessengerRemovePacket(self.key, self.name) - return True - -class MessengerGuildItem(MessengerMemberItem): - - def __init__(self, getParentEvent): - MessengerMemberItem.__init__(self, getParentEvent) - - def CanWarp(self): - if not self.IsOnline(): - return False - return True - - def OnWarp(self): - net.SendGuildUseSkillPacket(155, self.key) - - @property - def RemoveMessage(self): - return localeInfo.GUILD_REMOVE_MEMBER_QUESTION - - def CanRemove(self): - for i in range(guild.ENEMY_GUILD_SLOT_MAX_COUNT): - if guild.GetEnemyGuildName(i) != "": - return False - - if guild.MainPlayerHasAuthority(guild.AUTH_REMOVE_MEMBER): - guildMasterName = guild.GetGuildMasterName() - isTargetGuildMaster = guildMasterName == self.name - if guild.IsMemberByName(self.name) and not isTargetGuildMaster: - return True - - return False - - def OnRemove(self): - net.SendGuildRemoveMemberPacket(self.key) - return True - -class MessengerFriendGroup(MessengerGroupItem): - - def __init__(self, getParentEvent): - MessengerGroupItem.__init__(self, getParentEvent) - self.SetName(localeInfo.MESSENGER_FRIEND) - - def AppendMember(self, key, name): - item = MessengerFriendItem(self.getParentEvent) - return MessengerGroupItem.AppendMember(self, item, key, name) - -class MessengerGuildGroup(MessengerGroupItem): - - def __init__(self, getParentEvent): - MessengerGroupItem.__init__(self, getParentEvent) - self.SetName(localeInfo.MESSENGER_GUILD) - self.AddFlag("float") - - def AppendMember(self, key, name): - item = MessengerGuildItem(self.getParentEvent) - return MessengerGroupItem.AppendMember(self, item, key, name) - -class MessengerFamilyGroup(MessengerGroupItem): - - def __init__(self, getParentEvent): - MessengerGroupItem.__init__(self, getParentEvent) - self.SetName(localeInfo.MESSENGER_FAMILY) - self.AddFlag("float") - - self.lover = None - - def AppendMember(self, key, name): - item = MessengerGuildItem(self.getParentEvent) - self.lover = item - return MessengerGroupItem.AppendMember(self, item, key, name) - - def GetLover(self): - return self.lover - -################################################################################################### -################################################################################################### -################################################################################################### - -class MessengerWindow(ui.ScriptWindow): - - START_POSITION = 40 - - class ResizeButton(ui.DragButton): - - def OnMouseOverIn(self): - app.SetCursor(app.VSIZE) - - def OnMouseOverOut(self): - app.SetCursor(app.NORMAL) - - def __init__(self): - ui.ScriptWindow.__init__(self) - messenger.SetMessengerHandler(self) - - self.board = None - self.groupList = [] - self.showingItemList = [] - self.selectedItem = None - self.whisperButtonEvent = lambda *arg: None - self.familyGroup = None - - self.guildButtonEvent = None - - self.showingPageSize = 0 - self.startLine = 0 - self.isLoaded = 0 - - self.__AddGroup() - messenger.RefreshGuildMember() - - def InitializeHandler(self): - """Load UI and register packet handlers without showing window""" - if self.isLoaded == 0: - self.isLoaded = 1 - self.__LoadWindow() - self.OnRefreshList() - self.OnResizeDialog() - - def Show(self): - if self.isLoaded==0: - self.isLoaded=1 - - self.__LoadWindow() - self.OnRefreshList() - self.OnResizeDialog() - - ui.ScriptWindow.Show(self) - - def __LoadWindow(self): - - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "UIScript/MessengerWindow.py") - - try: - self.board = self.GetChild("board") - self.scrollBar = self.GetChild("ScrollBar") - self.whisperButton = self.GetChild("WhisperButton") - self.removeButton = self.GetChild("RemoveButton") - self.addFriendButton = self.GetChild("AddFriendButton") - self.guildButton = self.GetChild("GuildButton") - except: - import exception - exception.Abort("MessengerWindow.__LoadWindow.__Bind") - - self.board.SetCloseEvent(ui.__mem_func__(self.Close)) - self.scrollBar.SetScrollEvent(ui.__mem_func__(self.OnScroll)) - self.whisperButton.SetEvent(ui.__mem_func__(self.OnPressWhisperButton)) - self.removeButton.SetEvent(ui.__mem_func__(self.OnPressRemoveButton)) - self.addFriendButton.SetEvent(ui.__mem_func__(self.OnPressAddFriendButton)) - self.guildButton.SetEvent(ui.__mem_func__(self.OnPressGuildButton)) - - self.whisperButton.Disable() - self.removeButton.Disable() - - resizeButton = self.ResizeButton() - resizeButton.AddFlag("restrict_x") - resizeButton.SetParent(self) - resizeButton.SetSize(self.GetWidth(), 10) - resizeButton.SetWindowVerticalAlignBottom() - resizeButton.SetPosition(0, 0) - resizeButton.Show() - self.resizeButton = resizeButton - self.resizeButton.SetMoveEvent(ui.__mem_func__(self.OnResizeDialog)) - self.resizeButton.SetPosition(0, 300) - - for list in self.groupList: - list.SetTop() - - def __del__(self): - messenger.SetMessengerHandler(None) - ui.ScriptWindow.__del__(self) - - def Destroy(self): - self.board = None - self.scrollBar = None - self.resizeButton = None - self.friendNameBoard = None - self.questionDialog = None - self.popupDialog = None - self.inputDialog = None - self.familyGroup = None - - self.whisperButton = None - self.removeButton = None - - def OnCloseQuestionDialog(self): - self.questionDialog.Close() - self.questionDialog = None - return True - - def Close(self): - self.questionDialog = None - self.Hide() - - def SetSize(self, width, height): - ui.ScriptWindow.SetSize(self, width, height) - if self.board: - self.board.SetSize(width, height) - - def OnResizeDialog(self): - x, y = self.resizeButton.GetLocalPosition() - if y < 140: - self.resizeButton.SetPosition(x, 140) - return - self.SetSize(self.GetWidth(), y + self.resizeButton.GetHeight()) - - self.showingPageSize = y - (self.START_POSITION + 26) - self.scrollBar.SetScrollBarSize(self.showingPageSize) - - self.__LocateMember() - - self.resizeButton.TurnOffCallBack() - self.UpdateRect() - self.resizeButton.TurnOnCallBack() - - def __LocateMember(self): - - if self.isLoaded==0: - return - - if self.showingPageSize / 20 >= len(self.showingItemList): - self.scrollBar.Hide() - self.startLine = 0 - else: - if self.showingItemList: - self.scrollBar.SetMiddleBarSize(float(self.showingPageSize / 20) / float(len(self.showingItemList))) - self.scrollBar.Show() - - ##### - - yPos = self.START_POSITION - heightLimit = self.GetHeight() - (self.START_POSITION + 13) - - list(map(ui.Window.Hide, self.showingItemList)) - - for item in self.showingItemList[self.startLine:]: - item.SetPosition(20 + item.GetStepWidth(), yPos) - item.SetTop() - item.Show() - - yPos += 20 - - if yPos > heightLimit: - break - - def __AddGroup(self): - member = MessengerFriendGroup(ui.__mem_func__(self.GetSelf)) - member.Open() - member.Show() - self.groupList.append(member) - - member = MessengerGuildGroup(ui.__mem_func__(self.GetSelf)) - member.Open() - member.Show() - self.groupList.append(member) - - def __AddFamilyGroup(self): - member = MessengerFamilyGroup(ui.__mem_func__(self.GetSelf)) - member.Open() - member.Show() - - self.familyGroup = member - - def ClearGuildMember(self): - self.groupList[GUILD].ClearMember() - - def SetWhisperButtonEvent(self, event): - self.whisperButtonEvent=event - - def SetGuildButtonEvent(self, event): - self.guildButtonEvent=event - - def OnPressGuildButton(self): - self.guildButtonEvent() - - def OnPressAddFriendButton(self): - friendNameBoard = uiCommon.InputDialog() - friendNameBoard.SetTitle(localeInfo.MESSENGER_ADD_FRIEND) - friendNameBoard.SetAcceptEvent(ui.__mem_func__(self.OnAddFriend)) - friendNameBoard.SetCancelEvent(ui.__mem_func__(self.OnCancelAddFriend)) - friendNameBoard.Open() - self.friendNameBoard = friendNameBoard - - def OnAddFriend(self): - text = self.friendNameBoard.GetText() - if text: - net.SendMessengerAddByNamePacket(text) - self.friendNameBoard.Close() - self.friendNameBoard = None - return True - - def OnCancelAddFriend(self): - self.friendNameBoard.Close() - self.friendNameBoard = None - return True - - def OnPressWhisperButton(self): - if self.selectedItem: - self.selectedItem.OnWhisper() - - def OnPressRemoveButton(self): - if self.selectedItem: - if self.selectedItem.CanRemove(): - self.questionDialog = uiCommon.QuestionDialog() - self.questionDialog.SetText(self.selectedItem.RemoveMessage) - self.questionDialog.SetAcceptEvent(ui.__mem_func__(self.OnRemove)) - self.questionDialog.SetCancelEvent(ui.__mem_func__(self.OnCloseQuestionDialog)) - self.questionDialog.Open() - - def OnRemove(self): - if self.selectedItem: - if self.selectedItem.CanRemove(): - list(map(lambda arg, argDeletingItem=self.selectedItem: arg.RemoveMember(argDeletingItem), self.groupList)) - self.selectedItem.OnRemove() - self.selectedItem.UnSelect() - self.selectedItem = None - - self.whisperButton.Disable() - self.removeButton.Disable() - self.OnRefreshList() - - self.OnCloseQuestionDialog() - - def OnScroll(self): - scrollLineCount = len(self.showingItemList) - (self.showingPageSize / 20) - startLine = int(scrollLineCount * self.scrollBar.GetPos()) - - if startLine != self.startLine: - self.startLine = startLine - self.__LocateMember() - - def OnPressEscapeKey(self): - self.Close() - return True - - ## CallBack - def OnSelectItem(self, item): - - if self.selectedItem: - if item != self.selectedItem: - self.selectedItem.UnSelect() - - self.selectedItem = item - - if self.selectedItem: - self.selectedItem.Select() - - if self.selectedItem.CanWhisper(): - self.whisperButton.Enable() - else: - self.whisperButton.Disable() - - if self.selectedItem.CanRemove(): - self.removeButton.Enable() - else: - self.removeButton.Disable() - - def OnDoubleClickItem(self, item): - - if not self.selectedItem: - return - - if self.selectedItem.IsOnline(): - self.OnPressWhisperButton() - - def GetSelf(self): - return self - - def OnRefreshList(self): - self.showingItemList = [] - - if self.familyGroup: - self.showingItemList.append(self.familyGroup) - if self.familyGroup.GetLover(): - self.showingItemList.append(self.familyGroup.GetLover()) - - for group in self.groupList: - - self.showingItemList.append(group) - - if group.IsOpen(): - - loginMemberList = group.GetLoginMemberList() - logoutMemberList = group.GetLogoutMemberList() - - if loginMemberList or logoutMemberList: - for member in loginMemberList: - self.showingItemList.append(member) - for member in logoutMemberList: - self.showingItemList.append(member) - - else: - item = MessengerItem(ui.__mem_func__(self.GetSelf)) - item.SetName(localeInfo.MESSENGER_EMPTY_LIST) - self.showingItemList.append(item) - - self.__LocateMember() - - def RefreshMessenger(self): - self.OnRefreshList() - - ## EventHandler - def __AddList(self, groupIndex, key, name): - group = self.groupList[groupIndex] - member = group.FindMember(key) - if not member: - member = group.AppendMember(key, name) - self.OnSelectItem(None) - return member - - def OnRemoveList(self, groupIndex, key): - group = self.groupList[groupIndex] - - member = group.FindMember(key) - - if not member: - return - - if self.selectedItem is member or member.IsSameKey(key): - member.UnSelect() - self.selectedItem = None - - # Optional: also disable buttons to mirror local delete flow - self.whisperButton.Disable() - self.removeButton.Disable() - - member.Hide() - group.RemoveMember(member) - - self.OnRefreshList() - - def OnRemoveAllList(self, groupIndex): - group = self.groupList[groupIndex] - group.ClearMember() - self.OnRefreshList() - - def OnLogin(self, groupIndex, key, name=None): - if not name: - name = key - group = self.groupList[groupIndex] - member = self.__AddList(groupIndex, key, name) - member.SetName(name) - member.Online() - self.OnRefreshList() - - def OnLogout(self, groupIndex, key, name=None): - group = self.groupList[groupIndex] - member = self.__AddList(groupIndex, key, name) - if not name: - name = key - member.SetName(name) - member.Offline() - self.OnRefreshList() - - def OnAddLover(self, name, lovePoint): - if not self.familyGroup: - self.__AddFamilyGroup() - - member = self.familyGroup.AppendMember(0, name) - - member.SetName(name) - member.SetLovePoint(lovePoint) - member.Offline() - self.OnRefreshList() - - def OnUpdateLovePoint(self, lovePoint): - if not self.familyGroup: - return - - lover = self.familyGroup.GetLover() - if not lover: - return - - lover.SetLovePoint(lovePoint) - - def OnLoginLover(self): - if not self.familyGroup: - return - - lover = self.familyGroup.GetLover() - if not lover: - return - - lover.Online() - - def OnLogoutLover(self): - if not self.familyGroup: - return - - lover = self.familyGroup.GetLover() - if not lover: - return - - lover.Offline() - - def ClearLoverInfo(self): - if not self.familyGroup: - return - - self.familyGroup.ClearMember() - self.familyGroup = None - self.OnRefreshList() diff --git a/tools/root/uiminimap.py b/tools/root/uiminimap.py deleted file mode 100644 index b6c5a2c9..00000000 --- a/tools/root/uiminimap.py +++ /dev/null @@ -1,487 +0,0 @@ -import ui -import uiScriptLocale -import wndMgr -import player -import miniMap -import localeInfo -import net -import app -import colorInfo -import constInfo -import background - -class MapTextToolTip(ui.Window): - def __init__(self): - ui.Window.__init__(self) - - textLine = ui.TextLine() - textLine.SetParent(self) - textLine.SetHorizontalAlignCenter() - textLine.SetOutline() - textLine.SetHorizontalAlignRight() - textLine.Show() - self.textLine = textLine - - def __del__(self): - ui.Window.__del__(self) - - def SetText(self, text): - self.textLine.SetText(text) - - def SetTooltipPosition(self, PosX, PosY): - if app.IsRTL(): - w, h = self.textLine.GetTextSize() - self.textLine.SetPosition(PosX - w - 5, PosY) - else: - self.textLine.SetPosition(PosX - 5, PosY) - - def SetTextColor(self, TextColor): - self.textLine.SetPackedFontColor(TextColor) - - def GetTextSize(self): - return self.textLine.GetTextSize() - -class AtlasWindow(ui.ScriptWindow): - - class AtlasRenderer(ui.Window): - def __init__(self): - ui.Window.__init__(self) - self.AddFlag("not_pick") - - def OnUpdate(self): - miniMap.UpdateAtlas() - - def OnRender(self): - (x, y) = self.GetGlobalPosition() - fx = float(x) - fy = float(y) - miniMap.RenderAtlas(fx, fy) - - def HideAtlas(self): - miniMap.HideAtlas() - - def ShowAtlas(self): - miniMap.ShowAtlas() - - def __init__(self): - self.tooltipInfo = MapTextToolTip() - self.tooltipInfo.Hide() - self.infoGuildMark = ui.MarkBox() - self.infoGuildMark.Hide() - self.AtlasMainWindow = None - self.mapName = "" - self.board = 0 - - ui.ScriptWindow.__init__(self) - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def SetMapName(self, mapName): - self.board.SetTitleName(localeInfo.MINIMAP_ZONE_NAME_DICT[mapName]) - - def LoadWindow(self): - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "UIScript/AtlasWindow.py") - except: - import exception - exception.Abort("AtlasWindow.LoadWindow.LoadScript") - - try: - self.board = self.GetChild("board") - - except: - import exception - exception.Abort("AtlasWindow.LoadWindow.BindObject") - - self.AtlasMainWindow = self.AtlasRenderer() - self.board.SetCloseEvent(self.Hide) - self.AtlasMainWindow.SetParent(self.board) - self.AtlasMainWindow.SetPosition(7, 30) - self.tooltipInfo.SetParent(self.board) - self.infoGuildMark.SetParent(self.board) - self.SetPosition(wndMgr.GetScreenWidth() - 136 - 256 - 10, 0) - self.Hide() - - miniMap.RegisterAtlasWindow(self) - - def Destroy(self): - miniMap.UnregisterAtlasWindow() - self.ClearDictionary() - self.AtlasMainWindow = None - self.tooltipAtlasClose = 0 - self.tooltipInfo = None - self.infoGuildMark = None - self.board = None - - def OnUpdate(self): - - if not self.tooltipInfo: - return - - if not self.infoGuildMark: - return - - self.infoGuildMark.Hide() - self.tooltipInfo.Hide() - - if False == self.board.IsIn(): - return - - (mouseX, mouseY) = wndMgr.GetMousePosition() - (bFind, sName, iPosX, iPosY, dwTextColor, dwGuildID) = miniMap.GetAtlasInfo(mouseX, mouseY) - - if False == bFind: - return - - if "empty_guild_area" == sName: - sName = localeInfo.GUILD_EMPTY_AREA - - if app.IsRTL() and sName[-1].isalnum(): - self.tooltipInfo.SetText("(%s)%d, %d" % (sName, iPosX, iPosY)) - else: - self.tooltipInfo.SetText("%s(%d, %d)" % (sName, iPosX, iPosY)) - - (x, y) = self.GetGlobalPosition() - self.tooltipInfo.SetTooltipPosition(mouseX - x, mouseY - y) - self.tooltipInfo.SetTextColor(dwTextColor) - self.tooltipInfo.Show() - self.tooltipInfo.SetTop() - - if 0 != dwGuildID: - textWidth, textHeight = self.tooltipInfo.GetTextSize() - self.infoGuildMark.SetIndex(dwGuildID) - self.infoGuildMark.SetPosition(mouseX - x - textWidth - 18 - 5, mouseY - y) - self.infoGuildMark.Show() - - def Hide(self): - if self.AtlasMainWindow: - self.AtlasMainWindow.HideAtlas() - self.AtlasMainWindow.Hide() - ui.ScriptWindow.Hide(self) - - def Show(self): - if self.AtlasMainWindow: - (bGet, iSizeX, iSizeY) = miniMap.GetAtlasSize() - if bGet: - self.SetSize(iSizeX + 15, iSizeY + 38) - - if app.IsRTL(): - self.board.SetPosition(iSizeX+15, 0) - - self.board.SetSize(iSizeX + 15, iSizeY + 38) - #self.AtlasMainWindow.SetSize(iSizeX, iSizeY) - self.AtlasMainWindow.ShowAtlas() - self.AtlasMainWindow.Show() - ui.ScriptWindow.Show(self) - - def SetCenterPositionAdjust(self, x, y): - self.SetPosition((wndMgr.GetScreenWidth() - self.GetWidth()) // 2 + x, (wndMgr.GetScreenHeight() - self.GetHeight()) // 2 + y) - - def OnPressEscapeKey(self): - self.Hide() - return True - -def __RegisterMiniMapColor(type, rgb): - miniMap.RegisterColor(type, rgb[0], rgb[1], rgb[2]) - -class MiniMap(ui.ScriptWindow): - - CANNOT_SEE_INFO_MAP_DICT = { - "metin2_map_monkeydungeon" : False, - "metin2_map_monkeydungeon_02" : False, - "metin2_map_monkeydungeon_03" : False, - "metin2_map_devilsCatacomb" : False, - } - - def __init__(self): - ui.ScriptWindow.__init__(self) - - self.__Initialize() - - miniMap.Create() - miniMap.SetScale(2.0) - - self.AtlasWindow = AtlasWindow() - self.AtlasWindow.LoadWindow() - self.AtlasWindow.Hide() - - self.tooltipMiniMapOpen = MapTextToolTip() - self.tooltipMiniMapOpen.SetText(localeInfo.MINIMAP) - self.tooltipMiniMapOpen.Show() - self.tooltipMiniMapClose = MapTextToolTip() - self.tooltipMiniMapClose.SetText(localeInfo.UI_CLOSE) - self.tooltipMiniMapClose.Show() - self.tooltipScaleUp = MapTextToolTip() - self.tooltipScaleUp.SetText(localeInfo.MINIMAP_INC_SCALE) - self.tooltipScaleUp.Show() - self.tooltipScaleDown = MapTextToolTip() - self.tooltipScaleDown.SetText(localeInfo.MINIMAP_DEC_SCALE) - self.tooltipScaleDown.Show() - self.tooltipAtlasOpen = MapTextToolTip() - self.tooltipAtlasOpen.SetText(localeInfo.MINIMAP_SHOW_AREAMAP) - self.tooltipAtlasOpen.Show() - self.tooltipInfo = MapTextToolTip() - self.tooltipInfo.Show() - - if miniMap.IsAtlas(): - self.tooltipAtlasOpen.SetText(localeInfo.MINIMAP_SHOW_AREAMAP) - else: - self.tooltipAtlasOpen.SetText(localeInfo.MINIMAP_CAN_NOT_SHOW_AREAMAP) - - self.tooltipInfo = MapTextToolTip() - self.tooltipInfo.Show() - - self.mapName = "" - - self.isLoaded = 0 - self.canSeeInfo = True - - # AUTOBAN - self.imprisonmentDuration = 0 - self.imprisonmentEndTime = 0 - self.imprisonmentEndTimeText = "" - # END_OF_AUTOBAN - - def __del__(self): - miniMap.Destroy() - ui.ScriptWindow.__del__(self) - - def __Initialize(self): - self.positionInfo = 0 - self.observerCount = 0 - - self.OpenWindow = 0 - self.CloseWindow = 0 - self.ScaleUpButton = 0 - self.ScaleDownButton = 0 - self.MiniMapHideButton = 0 - self.MiniMapShowButton = 0 - self.AtlasShowButton = 0 - - self.tooltipMiniMapOpen = 0 - self.tooltipMiniMapClose = 0 - self.tooltipScaleUp = 0 - self.tooltipScaleDown = 0 - self.tooltipAtlasOpen = 0 - self.tooltipInfo = None - self.serverInfo = None - - def SetMapName(self, mapName): - self.mapName=mapName - self.AtlasWindow.SetMapName(mapName) - - if mapName in self.CANNOT_SEE_INFO_MAP_DICT: - self.canSeeInfo = False - self.HideMiniMap() - self.tooltipMiniMapOpen.SetText(localeInfo.MINIMAP_CANNOT_SEE) - else: - self.canSeeInfo = True - self.ShowMiniMap() - self.tooltipMiniMapOpen.SetText(localeInfo.MINIMAP) - - # AUTOBAN - def SetImprisonmentDuration(self, duration): - self.imprisonmentDuration = duration - self.imprisonmentEndTime = app.GetGlobalTimeStamp() + duration - - self.__UpdateImprisonmentDurationText() - - def __UpdateImprisonmentDurationText(self): - restTime = max(self.imprisonmentEndTime - app.GetGlobalTimeStamp(), 0) - - imprisonmentEndTimeText = localeInfo.SecondToDHM(restTime) - if imprisonmentEndTimeText != self.imprisonmentEndTimeText: - self.imprisonmentEndTimeText = imprisonmentEndTimeText - self.serverInfo.SetText("%s: %s" % (uiScriptLocale.AUTOBAN_QUIZ_REST_TIME, self.imprisonmentEndTimeText)) - # END_OF_AUTOBAN - - def Show(self): - self.__LoadWindow() - - ui.ScriptWindow.Show(self) - - def __LoadWindow(self): - if self.isLoaded == 1: - return - - self.isLoaded = 1 - - try: - pyScrLoader = ui.PythonScriptLoader() - if app.IsRTL(): - pyScrLoader.LoadScriptFile(self, uiScriptLocale.LOCALE_UISCRIPT_PATH + "Minimap.py") - else: - pyScrLoader.LoadScriptFile(self, "UIScript/MiniMap.py") - except: - import exception - exception.Abort("MiniMap.LoadWindow.LoadScript") - - try: - self.OpenWindow = self.GetChild("OpenWindow") - self.MiniMapWindow = self.GetChild("MiniMapWindow") - self.ScaleUpButton = self.GetChild("ScaleUpButton") - self.ScaleDownButton = self.GetChild("ScaleDownButton") - self.MiniMapHideButton = self.GetChild("MiniMapHideButton") - self.AtlasShowButton = self.GetChild("AtlasShowButton") - self.CloseWindow = self.GetChild("CloseWindow") - self.MiniMapShowButton = self.GetChild("MiniMapShowButton") - self.positionInfo = self.GetChild("PositionInfo") - self.observerCount = self.GetChild("ObserverCount") - self.serverInfo = self.GetChild("ServerInfo") - except: - import exception - exception.Abort("MiniMap.LoadWindow.Bind") - - if constInfo.MINIMAP_POSITIONINFO_ENABLE==0: - self.positionInfo.Hide() - - self.serverInfo.SetText(net.GetServerInfo()) - self.ScaleUpButton.SetEvent(ui.__mem_func__(self.ScaleUp)) - self.ScaleDownButton.SetEvent(ui.__mem_func__(self.ScaleDown)) - self.MiniMapHideButton.SetEvent(ui.__mem_func__(self.HideMiniMap)) - self.MiniMapShowButton.SetEvent(ui.__mem_func__(self.ShowMiniMap)) - - if miniMap.IsAtlas(): - self.AtlasShowButton.SetEvent(ui.__mem_func__(self.ShowAtlas)) - - (ButtonPosX, ButtonPosY) = self.MiniMapShowButton.GetGlobalPosition() - self.tooltipMiniMapOpen.SetTooltipPosition(ButtonPosX, ButtonPosY) - - (ButtonPosX, ButtonPosY) = self.MiniMapHideButton.GetGlobalPosition() - self.tooltipMiniMapClose.SetTooltipPosition(ButtonPosX, ButtonPosY) - - (ButtonPosX, ButtonPosY) = self.ScaleUpButton.GetGlobalPosition() - self.tooltipScaleUp.SetTooltipPosition(ButtonPosX, ButtonPosY) - - (ButtonPosX, ButtonPosY) = self.ScaleDownButton.GetGlobalPosition() - self.tooltipScaleDown.SetTooltipPosition(ButtonPosX, ButtonPosY) - - (ButtonPosX, ButtonPosY) = self.AtlasShowButton.GetGlobalPosition() - self.tooltipAtlasOpen.SetTooltipPosition(ButtonPosX, ButtonPosY) - - self.ShowMiniMap() - - def Destroy(self): - self.HideMiniMap() - - self.AtlasWindow.Destroy() - self.AtlasWindow = None - - self.ClearDictionary() - - self.__Initialize() - - def UpdateObserverCount(self, observerCount): - if observerCount>0: - self.observerCount.Show() - elif observerCount<=0: - self.observerCount.Hide() - - self.observerCount.SetText(localeInfo.MINIMAP_OBSERVER_COUNT % observerCount) - - def OnUpdate(self): - (x, y, z) = player.GetMainCharacterPosition() - miniMap.Update(x, y) - - self.positionInfo.SetText("(%.0f, %.0f)" % (x // 100, y // 100)) - - if self.tooltipInfo: - if True == self.MiniMapWindow.IsIn(): - (mouseX, mouseY) = wndMgr.GetMousePosition() - (bFind, sName, iPosX, iPosY, dwTextColor) = miniMap.GetInfo(mouseX, mouseY) - - if bFind == 0: - self.tooltipInfo.Hide() - elif not self.canSeeInfo: - self.tooltipInfo.SetText("%s (%s)" % (sName, localeInfo.UI_POS_UNKNOWN)) - self.tooltipInfo.SetTooltipPosition(mouseX - 5, mouseY) - self.tooltipInfo.SetTextColor(dwTextColor) - self.tooltipInfo.Show() - else: - if app.IsRTL() and sName[-1].isalnum(): - self.tooltipInfo.SetText("(%s) %d, %d" % (sName, iPosX, iPosY)) - else: - self.tooltipInfo.SetText("%s (%d, %d)" % (sName, iPosX, iPosY)) - - self.tooltipInfo.SetTooltipPosition(mouseX - 5, mouseY) - self.tooltipInfo.SetTextColor(dwTextColor) - self.tooltipInfo.Show() - else: - self.tooltipInfo.Hide() - - # AUTOBAN - if self.imprisonmentDuration: - self.__UpdateImprisonmentDurationText() - # END_OF_AUTOBAN - - if True == self.MiniMapShowButton.IsIn(): - self.tooltipMiniMapOpen.Show() - else: - self.tooltipMiniMapOpen.Hide() - - if True == self.MiniMapHideButton.IsIn(): - self.tooltipMiniMapClose.Show() - else: - self.tooltipMiniMapClose.Hide() - - if True == self.ScaleUpButton.IsIn(): - self.tooltipScaleUp.Show() - else: - self.tooltipScaleUp.Hide() - - if True == self.ScaleDownButton.IsIn(): - self.tooltipScaleDown.Show() - else: - self.tooltipScaleDown.Hide() - - if True == self.AtlasShowButton.IsIn(): - self.tooltipAtlasOpen.Show() - else: - self.tooltipAtlasOpen.Hide() - - def OnRender(self): - (x, y) = self.GetGlobalPosition() - fx = float(x) - fy = float(y) - miniMap.Render(fx + 4.0, fy + 5.0) - - def Close(self): - self.HideMiniMap() - - def HideMiniMap(self): - miniMap.Hide() - self.OpenWindow.Hide() - self.CloseWindow.Show() - - def ShowMiniMap(self): - if not self.canSeeInfo: - return - - miniMap.Show() - self.OpenWindow.Show() - self.CloseWindow.Hide() - - def isShowMiniMap(self): - return miniMap.isShow() - - def ScaleUp(self): - miniMap.ScaleUp() - - def ScaleDown(self): - miniMap.ScaleDown() - - def ShowAtlas(self): - if not miniMap.IsAtlas(): - return - if not self.AtlasWindow.IsShow(): - self.AtlasWindow.Show() - - def ToggleAtlasWindow(self): - if not miniMap.IsAtlas(): - return - if self.AtlasWindow.IsShow(): - self.AtlasWindow.Hide() - else: - self.AtlasWindow.Show() diff --git a/tools/root/uioption.py b/tools/root/uioption.py deleted file mode 100644 index c9749bb5..00000000 --- a/tools/root/uioption.py +++ /dev/null @@ -1,325 +0,0 @@ -import ui -import snd -import systemSetting -import net -import chat -import app -import localeInfo -import constInfo -import chrmgr -import player - -blockMode = 0 - -class OptionDialog(ui.ScriptWindow): - - def __init__(self): - ui.ScriptWindow.__init__(self) - self.__Initialize() - self.__LoadDialog() - - def __del__(self): - ui.ScriptWindow.__del__(self) - print(" -------------------------------------- DELETE OPTION DIALOG") - - def __Initialize(self): - self.titleBar = 0 - self.ctrlMusicVolume = 0 - self.ctrlSoundVolume = 0 - self.nameColorModeButtonList = [] - self.viewTargetBoardButtonList = [] - self.cameraModeButtonList = [] - self.pvpModeButtonDict = {} - self.fogModeButtonList = [] - self.blockButtonList = [] - - def Destroy(self): - self.ClearDictionary() - - self.__Initialize() - print(" -------------------------------------- DESTROY OPTION DIALOG") - - def __LoadDialog(self): - try: - pyScriptLoader = ui.PythonScriptLoader() - pyScriptLoader.LoadScriptFile(self, "uiscript/optiondialog.py") - except: - import exception - exception.Abort("OptionDialog.__LoadDialog.LoadObject") - - try: - GetObject = self.GetChild - self.titleBar = GetObject("titlebar") - self.ctrlMusicVolume = GetObject("music_volume_controller") - self.ctrlSoundVolume = GetObject("sound_volume_controller") - self.nameColorModeButtonList.append(GetObject("name_color_normal")) - self.nameColorModeButtonList.append(GetObject("name_color_empire")) - self.viewTargetBoardButtonList.append(GetObject("target_board_no_view")) - self.viewTargetBoardButtonList.append(GetObject("target_board_view")) - self.cameraModeButtonList.append(GetObject("camera_short")) - self.cameraModeButtonList.append(GetObject("camera_long")) - self.fogModeButtonList.append(GetObject("fog_level0")) - self.fogModeButtonList.append(GetObject("fog_level1")) - self.fogModeButtonList.append(GetObject("fog_level2")) - self.pvpModeButtonDict[player.PK_MODE_PEACE] = GetObject("pvp_peace") - self.pvpModeButtonDict[player.PK_MODE_REVENGE] = GetObject("pvp_revenge") - self.pvpModeButtonDict[player.PK_MODE_GUILD] = GetObject("pvp_guild") - self.pvpModeButtonDict[player.PK_MODE_FREE] = GetObject("pvp_free") - self.blockButtonList.append(GetObject("block_exchange_button")) - self.blockButtonList.append(GetObject("block_party_button")) - self.blockButtonList.append(GetObject("block_guild_button")) - self.blockButtonList.append(GetObject("block_whisper_button")) - self.blockButtonList.append(GetObject("block_friend_button")) - except: - import exception - exception.Abort("OptionDialog.__LoadDialog.BindObject") - - self.SetCenterPosition() - self.ctrlMusicVolume.SetSliderPos(float(systemSetting.GetMusicVolume())) - self.ctrlSoundVolume.SetSliderPos(float(systemSetting.GetSoundVolume())) - - self.titleBar.SetCloseEvent(ui.__mem_func__(self.Close)) - self.ctrlMusicVolume.SetEvent(ui.__mem_func__(self.OnChangeMusicVolume)) - self.ctrlSoundVolume.SetEvent(ui.__mem_func__(self.OnChangeSoundVolume)) - - self.nameColorModeButtonList[0].SAFE_SetEvent(self.__OnClickNameColorModeNormalButton) - self.nameColorModeButtonList[1].SAFE_SetEvent(self.__OnClickNameColorModeEmpireButton) - - self.viewTargetBoardButtonList[0].SAFE_SetEvent(self.__OnClickTargetBoardViewButton) - self.viewTargetBoardButtonList[1].SAFE_SetEvent(self.__OnClickTargetBoardNoViewButton) - - self.cameraModeButtonList[0].SAFE_SetEvent(self.__OnClickCameraModeShortButton) - self.cameraModeButtonList[1].SAFE_SetEvent(self.__OnClickCameraModeLongButton) - - self.pvpModeButtonDict[player.PK_MODE_PEACE].SAFE_SetEvent(self.__OnClickPvPModePeaceButton) - self.pvpModeButtonDict[player.PK_MODE_REVENGE].SAFE_SetEvent(self.__OnClickPvPModeRevengeButton) - self.pvpModeButtonDict[player.PK_MODE_GUILD].SAFE_SetEvent(self.__OnClickPvPModeGuildButton) - self.pvpModeButtonDict[player.PK_MODE_FREE].SAFE_SetEvent(self.__OnClickPvPModeFreeButton) - - self.fogModeButtonList[0].SAFE_SetEvent(self.__OnClickFogModeLevel0Button) - self.fogModeButtonList[1].SAFE_SetEvent(self.__OnClickFogModeLevel1Button) - self.fogModeButtonList[2].SAFE_SetEvent(self.__OnClickFogModeLevel2Button) - - self.blockButtonList[0].SetToggleUpEvent(self.__OnClickBlockExchangeButton) - self.blockButtonList[1].SetToggleUpEvent(self.__OnClickBlockPartyButton) - self.blockButtonList[2].SetToggleUpEvent(self.__OnClickBlockGuildButton) - self.blockButtonList[3].SetToggleUpEvent(self.__OnClickBlockWhisperButton) - self.blockButtonList[4].SetToggleUpEvent(self.__OnClickBlockFriendButton) - self.blockButtonList[0].SetToggleDownEvent(self.__OnClickBlockExchangeButton) - self.blockButtonList[1].SetToggleDownEvent(self.__OnClickBlockPartyButton) - self.blockButtonList[2].SetToggleDownEvent(self.__OnClickBlockGuildButton) - self.blockButtonList[3].SetToggleDownEvent(self.__OnClickBlockWhisperButton) - self.blockButtonList[4].SetToggleDownEvent(self.__OnClickBlockFriendButton) - - self.__ClickRadioButton(self.fogModeButtonList, constInfo.GET_FOG_LEVEL_INDEX()) - self.__ClickRadioButton(self.cameraModeButtonList, constInfo.GET_CAMERA_MAX_DISTANCE_INDEX()) - self.__ClickRadioButton(self.nameColorModeButtonList, constInfo.GET_CHRNAME_COLOR_INDEX()) - self.__ClickRadioButton(self.viewTargetBoardButtonList, constInfo.GET_VIEW_OTHER_EMPIRE_PLAYER_TARGET_BOARD()) - self.__SetPeacePKMode() - - def __ClickRadioButton(self, buttonList, buttonIndex): - try: - selButton=buttonList[buttonIndex] - except IndexError: - return - - for eachButton in buttonList: - eachButton.SetUp() - - selButton.Down() - - def __SetNameColorMode(self, index): - constInfo.SET_CHRNAME_COLOR_INDEX(index) - self.__ClickRadioButton(self.nameColorModeButtonList, index) - - def __SetTargetBoardViewMode(self, flag): - constInfo.SET_VIEW_OTHER_EMPIRE_PLAYER_TARGET_BOARD(flag) - self.__ClickRadioButton(self.viewTargetBoardButtonList, flag) - - def __SetCameraMode(self, index): - constInfo.SET_CAMERA_MAX_DISTANCE_INDEX(index) - self.__ClickRadioButton(self.cameraModeButtonList, index) - - def __SetFogLevel(self, index): - constInfo.SET_FOG_LEVEL_INDEX(index) - self.__ClickRadioButton(self.fogModeButtonList, index) - - def __OnClickNameColorModeNormalButton(self): - self.__SetNameColorMode(0) - - def __OnClickNameColorModeEmpireButton(self): - self.__SetNameColorMode(1) - - def __OnClickTargetBoardViewButton(self): - self.__SetTargetBoardViewMode(0) - - def __OnClickTargetBoardNoViewButton(self): - self.__SetTargetBoardViewMode(1) - - def __OnClickCameraModeShortButton(self): - self.__SetCameraMode(0) - - def __OnClickCameraModeLongButton(self): - self.__SetCameraMode(1) - - def __OnClickFogModeLevel0Button(self): - self.__SetFogLevel(0) - - def __OnClickFogModeLevel1Button(self): - self.__SetFogLevel(1) - - def __OnClickFogModeLevel2Button(self): - self.__SetFogLevel(2) - - def __OnClickBlockExchangeButton(self): - self.RefreshBlock() - global blockMode - net.SendChatPacket("/setblockmode " + str(blockMode ^ player.BLOCK_EXCHANGE)) - def __OnClickBlockPartyButton(self): - self.RefreshBlock() - global blockMode - net.SendChatPacket("/setblockmode " + str(blockMode ^ player.BLOCK_PARTY)) - def __OnClickBlockGuildButton(self): - self.RefreshBlock() - global blockMode - net.SendChatPacket("/setblockmode " + str(blockMode ^ player.BLOCK_GUILD)) - def __OnClickBlockWhisperButton(self): - self.RefreshBlock() - global blockMode - net.SendChatPacket("/setblockmode " + str(blockMode ^ player.BLOCK_WHISPER)) - def __OnClickBlockFriendButton(self): - self.RefreshBlock() - global blockMode - net.SendChatPacket("/setblockmode " + str(blockMode ^ player.BLOCK_FRIEND)) - - def __CheckPvPProtectedLevelPlayer(self): - if player.GetStatus(player.LEVEL)= 10: - self.__AppendStateButton(xPos, y, player.PARTY_STATE_ATTACKER) - xPos += 23 - - ## Attacker - if skillLevel >= 20: - self.__AppendStateButton(xPos, y, player.PARTY_STATE_BERSERKER) - xPos += 23 - - ## Tanker - if skillLevel >= 20: - self.__AppendStateButton(xPos, y, player.PARTY_STATE_TANKER) - xPos += 23 - - ## Buffer - if skillLevel >= 25: - self.__AppendStateButton(xPos, y, player.PARTY_STATE_BUFFER) - xPos += 23 - - ## Skill Master - if skillLevel >= 35: - self.__AppendStateButton(xPos, y, player.PARTY_STATE_SKILL_MASTER) - xPos += 23 - - ## Defender - if skillLevel >= 40: - self.__AppendStateButton(xPos, y, player.PARTY_STATE_DEFENDER) - xPos += 23 - - ## Warp - #if skillLevel >= 35: - # if self.stateButtonDict.has_key(self.MEMBER_BUTTON_WARP): - # button = self.stateButtonDict[self.MEMBER_BUTTON_WARP] - # button.SetPosition(xPos, y) - # button.Show() - # xPos += 23 - - ## Expel - if self.MEMBER_BUTTON_EXPEL in self.stateButtonDict: - button = self.stateButtonDict[self.MEMBER_BUTTON_EXPEL] - button.SetPosition(xPos, y) - button.Show() - xPos += 23 - - def __HideStateButton(self): - self.isShowStateButton = False - for button in list(self.stateButtonDict.values()): - button.Hide() - - def __GetAffectNumber(self, img): - for i in range(self.partyAffectImageList): - if img == self.partyAffectImageList[i]: - return i - - return -1 - - def SetCharacterName(self, name): - self.nameTextLine.SetText(name) - - def GetCharacterName(self): - return self.nameTextLine.GetText() - - def SetCharacterPID(self, pid): - self.pid = pid - - def SetCharacterVID(self, vid): - self.vid = vid - - def GetCharacterPID(self): - return self.pid - - def GetCharacterVID(self): - return self.vid - - def SetCharacterHP(self, hpPercentage): - hpPercentage = max(0, hpPercentage) - self.gauge.SetPercentage(hpPercentage, 100) - - def SetCharacterState(self, state): - - if self.state == state: - return - - self.state = state - self.stateButton.Show() - - name = self.MEMBER_BUTTON_IMAGE_FILE_NAME_DICT[self.MEMBER_BUTTON_NORMAL] - if state in self.MEMBER_BUTTON_IMAGE_FILE_NAME_DICT: - name = self.MEMBER_BUTTON_IMAGE_FILE_NAME_DICT[state] - - self.stateButton.SetUpVisual(self.MEMBER_BUTTON_PATH + name + "_01.sub") - self.stateButton.SetOverVisual(self.MEMBER_BUTTON_PATH + name + "_02.sub") - self.stateButton.SetDownVisual(self.MEMBER_BUTTON_PATH + name + "_03.sub") - - def SetAffect(self, affectSlotIndex, affectValue): - - if affectSlotIndex >= len(self.partyAffectImageList): - return - - if affectValue > 0: - self.partyAffectImageList[affectSlotIndex].Show() - else: - self.partyAffectImageList[affectSlotIndex].Hide() - - self.affectValueDict[affectSlotIndex] = affectValue - - def Link(self): - self.nameTextLine.SetPackedFontColor(self.LINK_COLOR) - self.gauge.Show() - - def Unlink(self): - self.vid = None - self.nameTextLine.SetPackedFontColor(self.UNLINK_COLOR) - self.gauge.Hide() - self.__HideAllAffects() - - def OnSelectState(self, state): - - self.__HideStateButton() - if state <= 0: - net.SendPartySetStatePacket(self.pid, self.state, False) - - else: - - if self.state <= 0: - net.SendPartySetStatePacket(self.pid, state, True) - - else: - net.SendPartySetStatePacket(self.pid, self.state, False) - net.SendPartySetStatePacket(self.pid, state, True) - - def OnWarp(self): - self.__HideStateButton() - - if self.vid: - net.SendPartyUseSkillPacket(self.PARTY_SKILL_WARP, self.vid) - - def OnExpel(self): - self.__HideStateButton() - - if not self.pid: - return - net.SendPartyRemovePacket(self.pid) - - def OnMouseLeftButtonDown(self): - - if self.vid: - player.SetTarget(self.vid) - player.OpenCharacterMenu(self.vid) - - if mouseModule.mouseController.isAttached(): - attachedSlotPos = mouseModule.mouseController.GetAttachedSlotNumber() - net.SendExchangeStartPacket(self.vid) - net.SendExchangeItemAddPacket(attachedSlotPos, 0) - mouseModule.mouseController.DeattachObject() - return - - if player.IsPartyLeader(player.GetMainCharacterIndex()): - if player.PARTY_STATE_LEADER != self.state: - - if self.isShowStateButton: - self.__HideStateButton() - - else: - self.__ShowStateButton() - - def OnMouseLeftButtonUp(self): - - if self.vid: - player.SetTarget(self.vid) - player.OpenCharacterMenu(self.vid) - - if mouseModule.mouseController.isAttached(): - attachedSlotPos = mouseModule.mouseController.GetAttachedSlotNumber() - net.SendExchangeStartPacket(self.vid) - net.SendExchangeItemAddPacket(attachedSlotPos, 0) - mouseModule.mouseController.DeattachObject() - - def OnMouseRightButtonDown(self): - self.OnMouseLeftButtonDown() - - def OnAffectOverIn(self, index): - - if index not in self.AFFECT_STRING_DICT: - return - if index not in self.affectValueDict: - return - - (x, y) = self.GetGlobalPosition() - - self.affectToolTip.ClearToolTip() - self.affectToolTip.SetTitle(self.AFFECT_STRING_DICT[index](self.affectValueDict[index])) - self.affectToolTip.SetToolTipPosition(x + index*12, y + 11) - self.affectToolTip.ShowToolTip() - - def OnAffectOverOut(self, index): - self.affectToolTip.HideToolTip() - -class PartyMenu(ui.ThinBoard): - - # Locale-independent button identifiers (never use translated strings as dict keys) - BTN_HEAL_ALL = 0 - BTN_BREAK_UP = 1 - BTN_LEAVE = 2 - - def __init__(self): - ui.ThinBoard.__init__(self) - self.buttonDict = {} - self.distributionMode = 0 - self.isLeader = False - self.showingButtonList = [] - self.modeButtonList = {} - self.__CreateButtons() - self.__CreateModeButtons() - def __del__(self): - ui.ThinBoard.__del__(self) - - def Destroy(self): - self.buttonDict = {} - self.showingButtonList = [] - self.modeButtonList = {} - - def __CreateModeButtons(self): - - self.modeTitle = ui.MakeTextLine(self) - self.modeTitle.SetText(localeInfo.PARTY_EXP_DISTRIBUTION_MODE) - - self.modeButtonList = {} - - level = ui.RadioButton() - level.SetParent(self) - level.SetWindowHorizontalAlignCenter() - level.SetEvent(ui.__mem_func__(self.OnClickEXPLevel)) - level.SetUpVisual("d:/ymir work/ui/public/large_button_01.sub") - level.SetOverVisual("d:/ymir work/ui/public/large_button_02.sub") - level.SetDownVisual("d:/ymir work/ui/public/large_button_03.sub") - level.SetText(localeInfo.PARTY_EXP_DISTRIBUTION_MODE_LEVEL) - level.SetToolTipText(localeInfo.PARTY_EXP_DISTRIBUTION_MODE_LEVEL_TOOLTIP, 70) - level.Show() - self.modeButtonList[player.PARTY_EXP_NON_DISTRIBUTION] = level - - parity = ui.RadioButton() - parity.SetParent(self) - parity.SetWindowHorizontalAlignCenter() - parity.SetEvent(ui.__mem_func__(self.OnClickEXPDistributeParity)) - parity.SetUpVisual("d:/ymir work/ui/public/large_button_01.sub") - parity.SetOverVisual("d:/ymir work/ui/public/large_button_02.sub") - parity.SetDownVisual("d:/ymir work/ui/public/large_button_03.sub") - parity.SetText(localeInfo.PARTY_EXP_DISTRIBUTION_MODE_PARITY) - parity.SetToolTipText(localeInfo.PARTY_EXP_DISTRIBUTION_MODE_PARITY_TOOLTIP, 70) - parity.Show() - self.modeButtonList[player.PARTY_EXP_DISTRIBUTION_PARITY] = parity - - self.ChangePartyParameter(self.distributionMode) - - def __CreateButtons(self): - buttonConfig = ( - (self.BTN_HEAL_ALL, "PARTY_HEAL_ALL_MEMBER", - "d:/ymir work/ui/game/windows/Party_Skill_Heal", - ui.__mem_func__(self.OnPartyUseSkill)), - (self.BTN_BREAK_UP, "PARTY_BREAK_UP", - "d:/ymir work/ui/game/windows/Party_Disband", - net.SendPartyExitPacket), - (self.BTN_LEAVE, "PARTY_LEAVE", - "d:/ymir work/ui/game/windows/Party_Exit", - net.SendPartyExitPacket), - ) - - for btnId, localeAttr, imgBase, event in buttonConfig: - button = ui.Button() - button.SetParent(self) - button.SetWindowHorizontalAlignCenter() - button.SetToolTipText(getattr(localeInfo, localeAttr)) - button.SetUpVisual(imgBase + "_01.sub") - button.SetOverVisual(imgBase + "_02.sub") - button.SetDownVisual(imgBase + "_03.sub") - button.SetEvent(event) - self.buttonDict[btnId] = button - - def __ClearShowingButtons(self): - self.showingButtonList = [] - - def __ArrangeButtons(self): - - STEP_SIZE = 37 - - showingButtonCount = len(self.showingButtonList) - xPos = (showingButtonCount-1) * (-STEP_SIZE/2) - for button in self.showingButtonList: - button.SetPosition(xPos, 15) - button.Show() - xPos += 37 - - yPos = 85 - for button in list(self.modeButtonList.values()): - button.SetPosition(0, yPos) - yPos += 25 - - self.UpdateRect() - - def __ShowButton(self, name): - if name not in self.buttonDict: - return - - self.showingButtonList.append(self.buttonDict[name]) - self.__ArrangeButtons() - - def __HideButton(self, name): - if name not in self.buttonDict: - return - - searchingButton = self.buttonDict[name] - searchingButton.Hide() - for btn in self.showingButtonList: - if btn == searchingButton: - self.showingButtonList.remove(btn) - - self.__ArrangeButtons() - - def ShowLeaderButton(self): - self.isLeader = True - self.__ClearShowingButtons() - self.__ShowButton(self.BTN_BREAK_UP) - - def ShowMemberButton(self): - self.isLeader = False - self.__ClearShowingButtons() - self.__ShowButton(self.BTN_LEAVE) - - def OnPartyUseSkill(self): - net.SendPartyUseSkillPacket(PartyMemberInfoBoard.PARTY_SKILL_HEAL, 0) - self.__HideButton(self.BTN_HEAL_ALL) - - def PartyHealReady(self): - self.__ShowButton(self.BTN_HEAL_ALL) - - def __UpAllModeButtons(self): - for button in list(self.modeButtonList.values()): - button.SetUp() - - def __SetModeButton(self, mode): - self.__UpAllModeButtons() - self.modeButtonList[mode].Down() - self.distributionMode = mode - - def OnClickEXPLevel(self): - self.__SetModeButton(self.distributionMode) - if self.isLeader: - net.SendPartyParameterPacket(player.PARTY_EXP_NON_DISTRIBUTION) - - def OnClickEXPDistributeParity(self): - self.__SetModeButton(self.distributionMode) - if self.isLeader: - net.SendPartyParameterPacket(player.PARTY_EXP_DISTRIBUTION_PARITY) - - def ChangePartyParameter(self, distributionMode): - try: - self.__SetModeButton(distributionMode) - except: - pass - -class PartyWindow(ui.Window): - - def __init__(self): - ui.Window.__init__(self) - - self.SetPosition(10, 52) - self.partyMemberInfoBoardList = [] - - self.__CreatePartyMenuButton() - self.__CreatePartyMenu() - - def __del__(self): - ui.Window.__del__(self) - - print(" =============================== DESTROIED PartyWindow") - - def Destroy(self): - self.DestroyPartyMemberInfoBoard() - self.partyMenu.Destroy() - self.partyMenuButton = None - self.partyMenu = None - - def DestroyPartyMemberInfoBoard(self): - for board in self.partyMemberInfoBoardList: - board.Destroy() - - self.partyMemberInfoBoardList = [] - - def __CreatePartyMenuButton(self): - partyMenuButton = ui.Button() - partyMenuButton.SetParent(self) - partyMenuButton.SetWindowHorizontalAlignCenter() - partyMenuButton.SetWindowVerticalAlignBottom() - partyMenuButton.SetPosition(0, 20) - partyMenuButton.SetUpVisual("d:/ymir work/ui/game/windows/Party_Menu_Open_01.sub") - partyMenuButton.SetOverVisual("d:/ymir work/ui/game/windows/Party_Menu_Open_02.sub") - partyMenuButton.SetDownVisual("d:/ymir work/ui/game/windows/Party_Menu_Open_03.sub") - partyMenuButton.SetEvent(ui.__mem_func__(self.OnTogglePartyMenu)) - partyMenuButton.Show() - self.partyMenuButton = partyMenuButton - - def __CreatePartyMenu(self): - partyMenu = PartyMenu() - partyMenu.SetSize(106, 70 + 70) - partyMenu.Hide() - self.partyMenu = partyMenu - - def AddPartyMember(self, pid, name): - - board = self.__FindPartyMemberInfoBoardByPID(pid) - - if None == board: - - board = PartyMemberInfoBoard() - board.SetParent(self) - board.SetCharacterPID(pid) - - self.partyMemberInfoBoardList.append(board) - self.__ArrangePartyMemberInfoBoard() - self.UpdateRect() - - if not name: - name = localeInfo.PARTY_MEMBER_OFFLINE - - board.SetCharacterName(name) - board.Unlink() - - self.Show() - - def RemovePartyMember(self, pid): - - board = self.__FindPartyMemberInfoBoardByPID(pid) - - if None == board: - return - - vid = board.GetCharacterVID() - - if None != vid and player.IsMainCharacterIndex(vid): - - self.ExitParty() - player.ExitParty() - - else: - - board.Destroy() - player.RemovePartyMember(pid) - self.partyMemberInfoBoardList.remove(board) - self.__ArrangePartyMemberInfoBoard() - self.UpdateRect() - - def UpdatePartyMemberInfo(self, pid): - - board = self.__FindPartyMemberInfoBoardByPID(pid) - - if None == board: - return - - state = player.GetPartyMemberState(pid) - hpPercentage = player.GetPartyMemberHPPercentage(pid) - affectsList = player.GetPartyMemberAffects(pid) - - board.SetCharacterState(state) - board.SetCharacterHP(hpPercentage) - for i in range(len(affectsList)): - board.SetAffect(i, affectsList[i]) - - vid = board.GetCharacterVID() - if None != vid: - if player.IsMainCharacterIndex(vid): - if player.PARTY_STATE_LEADER == player.GetPartyMemberState(pid): - self.partyMenu.ShowLeaderButton() - else: - self.partyMenu.ShowMemberButton() - - def LinkPartyMember(self, pid, vid): - - board = self.__FindPartyMemberInfoBoardByPID(pid) - - if None == board: - return - - board.Link() - board.SetCharacterVID(vid) - - def UnlinkPartyMember(self, pid): - - board = self.__FindPartyMemberInfoBoardByPID(pid) - - if None == board: - return - - board.Unlink() - - def UnlinkAllPartyMember(self): - for board in self.partyMemberInfoBoardList: - board.Unlink() - - def ExitParty(self): - self.partyMenu.Hide() - self.DestroyPartyMemberInfoBoard() - self.Hide() - - def __ArrangePartyMemberInfoBoard(self): - - count = 0 - newHeight = 20 - - for board in self.partyMemberInfoBoardList: - board.SetPosition(0, count * (board.GetHeight() + 2)) - count += 1 - newHeight += board.GetHeight() + 2 - - self.SetSize(PartyMemberInfoBoard.BOARD_WIDTH, newHeight) - - (x, y) = self.GetGlobalPosition() - self.partyMenu.SetPosition(10, y + newHeight + 2) - - def __FindPartyMemberInfoBoardByVID(self, vid): - for board in self.partyMemberInfoBoardList: - if vid == board.GetCharacterVID(): - return board - - return None - - def __FindPartyMemberInfoBoardByPID(self, pid): - for board in self.partyMemberInfoBoardList: - if pid == board.GetCharacterPID(): - return board - - return None - - def PartyHealReady(self): - self.partyMenu.PartyHealReady() - - def ChangePartyParameter(self, distributionMode): - self.partyMenu.ChangePartyParameter(distributionMode) - - def OnTogglePartyMenu(self): - if self.partyMenu.IsShow(): - self.partyMenuButton.SetUpVisual("d:/ymir work/ui/game/windows/Party_Menu_Open_01.sub") - self.partyMenuButton.SetOverVisual("d:/ymir work/ui/game/windows/Party_Menu_Open_02.sub") - self.partyMenuButton.SetDownVisual("d:/ymir work/ui/game/windows/Party_Menu_Open_03.sub") - self.partyMenu.Hide() - else: - self.partyMenuButton.SetUpVisual("d:/ymir work/ui/game/windows/Party_Menu_Close_01.sub") - self.partyMenuButton.SetOverVisual("d:/ymir work/ui/game/windows/Party_Menu_Close_02.sub") - self.partyMenuButton.SetDownVisual("d:/ymir work/ui/game/windows/Party_Menu_Close_03.sub") - self.partyMenu.Show() - -PartyMemberInfoBoard._RebuildLocaleStrings() -localeInfo.RegisterReloadCallback(PartyMemberInfoBoard._RebuildLocaleStrings) diff --git a/tools/root/uiphasecurtain.py b/tools/root/uiphasecurtain.py deleted file mode 100644 index d3e62546..00000000 --- a/tools/root/uiphasecurtain.py +++ /dev/null @@ -1,72 +0,0 @@ -import grp -import ui -import wndMgr -import app - -class PhaseCurtain(ui.Bar): - - def __init__(self): - print("NEW CURTAIN ----------------------------------------------------------------------------") - ui.Bar.__init__(self, "CURTAIN") - self.speed = 0.1 - self.curAlpha = 0.0 - self.event = 0 - self.args = -1 - self.FadeInFlag = False - self.SetWindowName("PhaseCurtain") - self.AddFlag("float") - - def __del__(self): - print("---------------------------------------------------------------------------- DELETE CURTAIN") - ui.Bar.__del__(self) - - def SAFE_FadeOut(self, event, args = -1): - self.FadeOut(ui.__mem_func__(event), args) - - def FadeOut(self, event, args = -1): - self.curAlpha = 0.0 - self.SetAlpha(self.curAlpha) - #self.SetTop() - self.Show() - self.event = event - self.args = args - - def FadeIn(self): - self.event = 0 - self.FadeInFlag = True - - def SetAlpha(self, alpha): - self.SetSize(wndMgr.GetScreenWidth(), wndMgr.GetScreenHeight()) - - color = grp.GenerateColor(0.0, 0.0, 0.0, alpha) - self.SetColor(color) - - def OnUpdate(self): - - if 0 != self.event: - - self.curAlpha += self.speed - if self.curAlpha >= 1.0: - self.curAlpha = 1.0 - - # Use only this timer when event fade out was added - event=self.event - self.event = 0 - - #print "Fade out complete event executed" - - if -1 != self.args: - event(self.args) - else: - event() - - elif True == self.FadeInFlag: - - self.curAlpha -= self.speed - if self.curAlpha <= 0.0: - self.curAlpha = 0.0 - self.eventFadeIn = 0 - self.FadeInFlag = False - self.Hide() - - self.SetAlpha(self.curAlpha) diff --git a/tools/root/uipickmoney.py b/tools/root/uipickmoney.py deleted file mode 100644 index d2d97bdb..00000000 --- a/tools/root/uipickmoney.py +++ /dev/null @@ -1,104 +0,0 @@ -import wndMgr -import ui -import ime -import app - -class PickMoneyDialog(ui.ScriptWindow): - def __init__(self): - ui.ScriptWindow.__init__(self) - - self.unitValue = 1 - self.maxValue = 0 - self.eventAccept = 0 - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def LoadDialog(self): - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "UIScript/PickMoneyDialog.py") - except: - import exception - exception.Abort("MoneyDialog.LoadDialog.LoadScript") - - try: - self.board = self.GetChild("board") - self.maxValueTextLine = self.GetChild("max_value") - self.pickValueEditLine = self.GetChild("money_value") - self.acceptButton = self.GetChild("accept_button") - self.cancelButton = self.GetChild("cancel_button") - except: - import exception - exception.Abort("MoneyDialog.LoadDialog.BindObject") - - self.pickValueEditLine.SetReturnEvent(ui.__mem_func__(self.OnAccept)) - self.pickValueEditLine.SetEscapeEvent(ui.__mem_func__(self.Close)) - self.acceptButton.SetEvent(ui.__mem_func__(self.OnAccept)) - self.cancelButton.SetEvent(ui.__mem_func__(self.Close)) - self.board.SetCloseEvent(ui.__mem_func__(self.Close)) - - def Destroy(self): - self.ClearDictionary() - self.eventAccept = 0 - self.maxValue = 0 - self.pickValueEditLine = 0 - self.acceptButton = 0 - self.cancelButton = 0 - self.board = None - - def SetTitleName(self, text): - self.board.SetTitleName(text) - - def SetAcceptEvent(self, event): - self.eventAccept = event - - def SetMax(self, max): - self.pickValueEditLine.SetMax(max) - - def Open(self, maxValue, unitValue = 1): - width = self.GetWidth() - (mouseX, mouseY) = wndMgr.GetMousePosition() - - if mouseX + width/2 > wndMgr.GetScreenWidth(): - xPos = wndMgr.GetScreenWidth() - width - elif mouseX - width/2 < 0: - xPos = 0 - else: - xPos = mouseX - width/2 - - self.SetPosition(xPos, mouseY - self.GetHeight() - 20) - - if app.IsRTL(): - self.maxValueTextLine.SetText("/" + str(maxValue)) - else: - self.maxValueTextLine.SetText(" / " + str(maxValue)) - - self.pickValueEditLine.SetText(str(unitValue)) - self.pickValueEditLine.SetFocus() - - ime.SetCursorPosition(1) - - self.unitValue = unitValue - self.maxValue = maxValue - self.Show() - self.SetTop() - - def Close(self): - self.pickValueEditLine.KillFocus() - self.Hide() - - def OnAccept(self): - - text = self.pickValueEditLine.GetText() - - if len(text) > 0 and text.isdigit(): - - money = int(text) - money = min(money, self.maxValue) - - if money > 0: - if self.eventAccept: - self.eventAccept(money) - - self.Close() diff --git a/tools/root/uiplayergauge.py b/tools/root/uiplayergauge.py deleted file mode 100644 index 2e73bda2..00000000 --- a/tools/root/uiplayergauge.py +++ /dev/null @@ -1,59 +0,0 @@ -import ui -import player -import chr -import textTail - -class PlayerGauge(ui.Gauge): - def __init__(self, parent): - ui.Gauge.__init__(self) - self.SetParent(parent) - self.AddFlag("not_pick") - self.MakeGauge(100, "red") - - self.curHP = 0 - self.maxHP = 0 - - self.showAlways = False - - def __del__(self): - ui.Gauge.__del__(self) - - def Hide(self): - self.SetPosition(-100, -100) - ui.Gauge.Hide(self) - - def OnUpdate(self): - playerIndex = player.GetMainCharacterIndex() - - (x, y, z)=textTail.GetPosition(playerIndex) - - isChat = textTail.IsChat(playerIndex) - ui.Gauge.SetPosition(self, int(x - self.GetWidth() // 2), int(y + 5) + isChat * 17) - - def RefreshGauge(self): - - self.curHP = player.GetStatus(player.HP) - self.maxHP = player.GetStatus(player.MAX_HP) - self.SetPercentage(self.curHP, self.maxHP) - - if self.showAlways: - self.Show() - - else: - - if self.IsShow(): - if self.curHP > self.maxHP // 2: - self.Hide() - - else: - if self.curHP < self.maxHP // 2: - self.OnUpdate() - self.Show() - - def EnableShowAlways(self): - self.showAlways = True - self.RefreshGauge() - - def DisableShowAlways(self): - self.showAlways = False - self.RefreshGauge() diff --git a/tools/root/uipointreset.py b/tools/root/uipointreset.py deleted file mode 100644 index bc31ad68..00000000 --- a/tools/root/uipointreset.py +++ /dev/null @@ -1,74 +0,0 @@ -import net - -import ui -import networkModule - -################################################################################################### -## PointReset -class PointResetDialog(ui.ScriptWindow): - - def __init__(self): - ui.ScriptWindow.__init__(self) - self.ConfirmDialog = ui.ScriptWindow() - - def LoadDialog(self): - try: - PythonScriptLoader = ui.PythonScriptLoader() - PythonScriptLoader.LoadScriptFile(self, "uiscript/questiondialog2.py") - PythonScriptLoader.LoadScriptFile(self.ConfirmDialog, "uiscript/questiondialog2.py") - except: - import exception - exception.Abort("PointResetDialog.LoadDialog.LoadObject") - - try: - GetObject = self.ConfirmDialog.GetChild - self.ConfirmText = GetObject("message1") - self.ConfirmText2 = GetObject("message2") - self.ConfirmAcceptButton = GetObject("accept") - self.ConfirmCancelButton = GetObject("cancel") - except: - import exception - exception.Abort("PointResetDialog.LoadWindow.BindObject") - - self.GetChild("message1").SetText("스탯/스킬 포인트를 초기화해주겠네.") - self.GetChild("message2").SetText("가격은 500원이야. 어때, 초기화할텐가?") - self.GetChild("accept").SetEvent(ui.__mem_func__(self.OpenConfirmDialog)) - self.GetChild("cancel").SetEvent(ui.__mem_func__(self.Close)) - - ## Confirm Dialog - self.ConfirmText.SetText("현재 레벨의 경험치가 모두 없어진다네.") - self.ConfirmText.SetFontColor(1.0, 0.3, 0.3) - self.ConfirmText2.SetText("정말 초기화하고 싶은가?") - self.ConfirmAcceptButton.SetEvent(ui.__mem_func__(self.ResetPoint)) - self.ConfirmCancelButton.SetEvent(ui.__mem_func__(self.Close)) - - def Destroy(self): - self.ClearDictionary() - self.ConfirmDialog.ClearDictionary() - self.ConfirmAcceptButton.SetEvent(0) - self.ConfirmCancelButton.SetEvent(0) - - self.ConfirmDialog = 0 - self.ConfirmText = 0 - self.ConfirmAcceptButton = 0 - self.ConfirmCancelButton = 0 - - def OpenDialog(self): - self.Show() - - def OpenConfirmDialog(self): - self.ConfirmDialog.Show() - self.ConfirmDialog.SetTop() - - def ResetPoint(self): - net.SendChatPacket("/pointreset") - self.Close() - - def Close(self): - self.ConfirmDialog.Hide() - self.Hide() - return True - - def OnPressEscapeKey(self): - self.Close() - return True diff --git a/tools/root/uiprivateshopbuilder.py b/tools/root/uiprivateshopbuilder.py deleted file mode 100644 index 60569d25..00000000 --- a/tools/root/uiprivateshopbuilder.py +++ /dev/null @@ -1,347 +0,0 @@ -import ui -import snd -import shop -import mouseModule -import player -import chr -import net -import uiCommon -import localeInfo -import chat -import item -import systemSetting -import player - -g_isBuildingPrivateShop = False - -g_itemPriceDict={} - -g_privateShopAdvertisementBoardDict={} - -def Clear(): - global g_itemPriceDict - global g_isBuildingPrivateShop - g_itemPriceDict={} - g_isBuildingPrivateShop = False - -def IsPrivateShopItemPriceList(): - global g_itemPriceDict - if g_itemPriceDict: - return True - else: - return False - -def IsBuildingPrivateShop(): - global g_isBuildingPrivateShop - if player.IsOpenPrivateShop() or g_isBuildingPrivateShop: - return True - else: - return False - -def SetPrivateShopItemPrice(itemVNum, itemPrice): - global g_itemPriceDict - g_itemPriceDict[int(itemVNum)]=itemPrice - -def GetPrivateShopItemPrice(itemVNum): - try: - global g_itemPriceDict - return g_itemPriceDict[itemVNum] - except KeyError: - return 0 - -def UpdateADBoard(): - for key in list(g_privateShopAdvertisementBoardDict.keys()): - g_privateShopAdvertisementBoardDict[key].Show() - -def DeleteADBoard(vid): - if vid not in g_privateShopAdvertisementBoardDict: - return - - del g_privateShopAdvertisementBoardDict[vid] - - -class PrivateShopAdvertisementBoard(ui.ThinBoard): - def __init__(self): - ui.ThinBoard.__init__(self, "UI_BOTTOM") - self.vid = None - self.__MakeTextLine() - - def __del__(self): - ui.ThinBoard.__del__(self) - - def __MakeTextLine(self): - self.textLine = ui.TextLine() - self.textLine.SetParent(self) - self.textLine.SetWindowHorizontalAlignCenter() - self.textLine.SetWindowVerticalAlignCenter() - self.textLine.SetHorizontalAlignCenter() - self.textLine.SetVerticalAlignCenter() - self.textLine.Show() - - def Open(self, vid, text): - self.vid = vid - - self.textLine.SetText(text) - self.textLine.UpdateRect() - self.SetSize(len(text)*6 + 10*2, 20) - self.Show() - - g_privateShopAdvertisementBoardDict[vid] = self - - def OnMouseLeftButtonUp(self): - if not self.vid: - return - net.SendOnClickPacket(self.vid) - - return True - - def OnUpdate(self): - if not self.vid: - return - - if systemSetting.IsShowSalesText(): - self.Show() - x, y = chr.GetProjectPosition(self.vid, 220) - self.SetPosition(x - self.GetWidth()/2, y - self.GetHeight()/2) - - else: - for key in list(g_privateShopAdvertisementBoardDict.keys()): - if player.GetMainCharacterIndex() == key: # When the private shop is visible and closed, the player's own shop ID changes. - g_privateShopAdvertisementBoardDict[key].Show() - x, y = chr.GetProjectPosition(player.GetMainCharacterIndex(), 220) - g_privateShopAdvertisementBoardDict[key].SetPosition(x - self.GetWidth()/2, y - self.GetHeight()/2) - else: - g_privateShopAdvertisementBoardDict[key].Hide() - -class PrivateShopBuilder(ui.ScriptWindow): - - def __init__(self): - #print "NEW MAKE_PRIVATE_SHOP_WINDOW ----------------------------------------------------------------" - ui.ScriptWindow.__init__(self) - - self.__LoadWindow() - self.itemStock = {} - self.tooltipItem = None - self.priceInputBoard = None - self.title = "" - - def __del__(self): - #print "------------------------------------------------------------- DELETE MAKE_PRIVATE_SHOP_WINDOW" - ui.ScriptWindow.__del__(self) - - def __LoadWindow(self): - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "UIScript/PrivateShopBuilder.py") - except: - import exception - exception.Abort("PrivateShopBuilderWindow.LoadWindow.LoadObject") - - try: - GetObject = self.GetChild - self.nameLine = GetObject("NameLine") - self.itemSlot = GetObject("ItemSlot") - self.btnOk = GetObject("OkButton") - self.btnClose = GetObject("CloseButton") - self.titleBar = GetObject("TitleBar") - except: - import exception - exception.Abort("PrivateShopBuilderWindow.LoadWindow.BindObject") - - self.btnOk.SetEvent(ui.__mem_func__(self.OnOk)) - self.btnClose.SetEvent(ui.__mem_func__(self.OnClose)) - self.titleBar.SetCloseEvent(ui.__mem_func__(self.OnClose)) - - self.itemSlot.SetSelectEmptySlotEvent(ui.__mem_func__(self.OnSelectEmptySlot)) - self.itemSlot.SetSelectItemSlotEvent(ui.__mem_func__(self.OnSelectItemSlot)) - self.itemSlot.SetOverInItemEvent(ui.__mem_func__(self.OnOverInItem)) - self.itemSlot.SetOverOutItemEvent(ui.__mem_func__(self.OnOverOutItem)) - - def Destroy(self): - self.ClearDictionary() - - self.nameLine = None - self.itemSlot = None - self.btnOk = None - self.btnClose = None - self.titleBar = None - self.priceInputBoard = None - - def Open(self, title): - - self.title = title - - if len(title) > 25: - title = title[:22] + "..." - - self.itemStock = {} - shop.ClearPrivateShopStock() - self.nameLine.SetText(title) - self.SetCenterPosition() - self.Refresh() - self.Show() - - global g_isBuildingPrivateShop - g_isBuildingPrivateShop = True - - def Close(self): - global g_isBuildingPrivateShop - g_isBuildingPrivateShop = False - - self.title = "" - self.itemStock = {} - shop.ClearPrivateShopStock() - self.Hide() - - def SetItemToolTip(self, tooltipItem): - self.tooltipItem = tooltipItem - - def Refresh(self): - getitemVNum=player.GetItemIndex - getItemCount=player.GetItemCount - setitemVNum=self.itemSlot.SetItemSlot - delItem=self.itemSlot.ClearSlot - - for i in range(shop.SHOP_SLOT_COUNT): - - if i not in self.itemStock: - delItem(i) - continue - - pos = self.itemStock[i] - - itemCount = getItemCount(*pos) - if itemCount <= 1: - itemCount = 0 - setitemVNum(i, getitemVNum(*pos), itemCount) - - self.itemSlot.RefreshSlot() - - def OnSelectEmptySlot(self, selectedSlotPos): - - isAttached = mouseModule.mouseController.isAttached() - if isAttached: - attachedSlotType = mouseModule.mouseController.GetAttachedType() - attachedSlotPos = mouseModule.mouseController.GetAttachedSlotNumber() - mouseModule.mouseController.DeattachObject() - - if player.SLOT_TYPE_INVENTORY != attachedSlotType and player.SLOT_TYPE_DRAGON_SOUL_INVENTORY != attachedSlotType: - return - attachedInvenType = player.SlotTypeToInvenType(attachedSlotType) - - itemVNum = player.GetItemIndex(attachedInvenType, attachedSlotPos) - item.SelectItem(itemVNum) - - if item.IsAntiFlag(item.ANTIFLAG_GIVE) or item.IsAntiFlag(item.ANTIFLAG_MYSHOP): - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.PRIVATE_SHOP_CANNOT_SELL_ITEM) - return - - priceInputBoard = uiCommon.MoneyInputDialog() - priceInputBoard.SetTitle(localeInfo.PRIVATE_SHOP_INPUT_PRICE_DIALOG_TITLE) - priceInputBoard.SetAcceptEvent(ui.__mem_func__(self.AcceptInputPrice)) - priceInputBoard.SetCancelEvent(ui.__mem_func__(self.CancelInputPrice)) - priceInputBoard.Open() - - itemPrice=GetPrivateShopItemPrice(itemVNum) - - if itemPrice>0: - priceInputBoard.SetValue(itemPrice) - - self.priceInputBoard = priceInputBoard - self.priceInputBoard.itemVNum = itemVNum - self.priceInputBoard.sourceWindowType = attachedInvenType - self.priceInputBoard.sourceSlotPos = attachedSlotPos - self.priceInputBoard.targetSlotPos = selectedSlotPos - - def OnSelectItemSlot(self, selectedSlotPos): - - isAttached = mouseModule.mouseController.isAttached() - if isAttached: - snd.PlaySound("sound/ui/loginfail.wav") - mouseModule.mouseController.DeattachObject() - - else: - if not selectedSlotPos in self.itemStock: - return - - invenType, invenPos = self.itemStock[selectedSlotPos] - shop.DelPrivateShopItemStock(invenType, invenPos) - snd.PlaySound("sound/ui/drop.wav") - - del self.itemStock[selectedSlotPos] - - self.Refresh() - - def AcceptInputPrice(self): - - if not self.priceInputBoard: - return True - - text = self.priceInputBoard.GetText() - - if not text: - return True - - if not text.isdigit(): - return True - - if int(text) <= 0: - return True - - attachedInvenType = self.priceInputBoard.sourceWindowType - sourceSlotPos = self.priceInputBoard.sourceSlotPos - targetSlotPos = self.priceInputBoard.targetSlotPos - - for privatePos, (itemWindowType, itemSlotIndex) in list(self.itemStock.items()): - if itemWindowType == attachedInvenType and itemSlotIndex == sourceSlotPos: - shop.DelPrivateShopItemStock(itemWindowType, itemSlotIndex) - del self.itemStock[privatePos] - - price = int(self.priceInputBoard.GetText()) - - if IsPrivateShopItemPriceList(): - SetPrivateShopItemPrice(self.priceInputBoard.itemVNum, price) - - shop.AddPrivateShopItemStock(attachedInvenType, sourceSlotPos, targetSlotPos, price) - self.itemStock[targetSlotPos] = (attachedInvenType, sourceSlotPos) - snd.PlaySound("sound/ui/drop.wav") - - self.Refresh() - - ##### - - self.priceInputBoard = None - return True - - def CancelInputPrice(self): - self.priceInputBoard = None - return True - - def OnOk(self): - - if not self.title: - return - - if 0 == len(self.itemStock): - return - - shop.BuildPrivateShop(self.title) - self.Close() - - def OnClose(self): - self.Close() - - def OnPressEscapeKey(self): - self.Close() - return True - - def OnOverInItem(self, slotIndex): - - if self.tooltipItem: - if slotIndex in self.itemStock: - self.tooltipItem.SetPrivateShopBuilderItem(*self.itemStock[slotIndex] + (slotIndex,)) - - def OnOverOutItem(self): - - if self.tooltipItem: - self.tooltipItem.HideToolTip() diff --git a/tools/root/uiquest.py b/tools/root/uiquest.py deleted file mode 100644 index 88f6ede6..00000000 --- a/tools/root/uiquest.py +++ /dev/null @@ -1,926 +0,0 @@ -import ui -import dbg -import app -import grp -import grpImage -import event -import time -import wndMgr -import net -import sys - -QUEST_BOARD_IMAGE_DIR = 'd:/ymir work/ui/game/questboard/' - -cur_questpage_number = 1 -entire_questbutton_number = 0 -entire_questpage_number = 1 - - -# TOOLTIP_IMAGE_BOX -class ToolTipImageBox(ui.ImageBox): - def __init__(self): - ui.ImageBox.__init__(self) - self.DestroyToolTip() - def __del__(self): - ui.ImageBox.__del__(self) - - def CreateToolTip(self, parent, title, desc, x, y): - import uiToolTip - self.toolTip = uiToolTip.ToolTip() - self.toolTip.SetWindowHorizontalAlignCenter() - self.toolTip.SetFollow(False) - self.toolTip.SetTitle(title) - self.toolTip.SetPosition(x, y) - - desc = desc.replace("|", "/") - for line in desc.split("/"): - self.toolTip.AutoAppendTextLine(line) - - self.toolTip.ResizeToolTip() - self.toolTip.Hide() - - def DestroyToolTip(self): - self.toolTip = None - - def OnMouseOverIn(self): - if self.toolTip: - self.toolTip.SetTop() - self.toolTip.Show() - - def OnMouseOverOut(self): - if self.toolTip: - self.toolTip.Hide() -# END_OF_TOOLTIP_IMAGE_BOX - -class QuestCurtain(ui.Window): - CURTAIN_TIME = 0.25 - CURTAIN_SPEED = 200 - BarHeight = 60 - OnDoneEventList = [] - def __init__(self,layer="TOP_MOST"): - ui.Window.__init__(self,layer) - self.TopBar = ui.Bar("TOP_MOST") - self.BottomBar = ui.Bar("TOP_MOST") - - self.TopBar.Show() - self.BottomBar.Show() - - self.TopBar.SetColor(0xff000000) - self.BottomBar.SetColor(0xff000000) - - self.TopBar.SetPosition(0,-self.BarHeight) - self.TopBar.SetSize(wndMgr.GetScreenWidth(),self.BarHeight) - - self.BottomBar.SetPosition(0,wndMgr.GetScreenHeight()) - self.BottomBar.SetSize(wndMgr.GetScreenWidth(),self.BarHeight) - - self.CurtainMode = 0 - - self.lastclock = time.perf_counter() - - def Close(self): - self.CurtainMode = 0 - self.TopBar.SetPosition(0, -self.BarHeight-1) - self.BottomBar.SetPosition(0, wndMgr.GetScreenHeight()+1) - for OnDoneEvent in QuestCurtain.OnDoneEventList: - OnDoneEvent(*(self,)) - QuestCurtain.OnDoneEventList = [] - - def OnUpdate(self): - dt = time.perf_counter() - self.lastclock - if self.CurtainMode>0: - self.TopBar.SetPosition(0, int(self.TopBar.GetGlobalPosition()[1]+dt*self.CURTAIN_SPEED)) - self.BottomBar.SetPosition(0, int(self.BottomBar.GetGlobalPosition()[1]-dt*self.CURTAIN_SPEED)) - if self.TopBar.GetGlobalPosition()[1]>0: - self.TopBar.SetPosition(0,0) - self.BottomBar.SetPosition(0,wndMgr.GetScreenHeight()-self.BarHeight) - self.CurtainMode = 0 - - elif self.CurtainMode<0: - self.TopBar.SetPosition(0, int(self.TopBar.GetGlobalPosition()[1]-dt*self.CURTAIN_SPEED)) - self.BottomBar.SetPosition(0, int(self.BottomBar.GetGlobalPosition()[1]+dt*self.CURTAIN_SPEED)) - if self.TopBar.GetGlobalPosition()[1]<-self.BarHeight: - self.TopBar.SetPosition(0,-self.BarHeight-1) - self.BottomBar.SetPosition(0,wndMgr.GetScreenHeight()+1) - self.Close() - - self.lastclock = time.perf_counter() - -class EventCurtain(ui.Bar): - - COLOR_WHITE = 0.0 - COLOR_BLACK = 1.0 - - DEFAULT_FADE_SPEED = 0.035 - - STATE_WAIT = 0 - STATE_OUT = 1 - STATE_IN = 2 - - def __init__(self, index): - print("NEW EVENT CURTAIN ----------------------------------------------------------------------------") - ui.Bar.__init__(self, "CURTAIN") - self.SetWindowName("EventCurtain") - self.AddFlag("float") - self.SetSize(wndMgr.GetScreenWidth(), wndMgr.GetScreenHeight()) - self.Hide() - - self.fadeColor = 1.0 - self.curAlpha = 0.0 - self.FadeInFlag = False - self.state = self.STATE_WAIT - self.speed = 1.0 - self.eventIndex = index - - def __del__(self): - print("---------------------------------------------------------------------------- DELETE EVENT CURTAIN") - ui.Bar.__del__(self) - - def SetAlpha(self, alpha): - color = grp.GenerateColor(self.fadeColor, self.fadeColor, self.fadeColor, alpha) - self.SetColor(color) - - def FadeOut(self, speed): - self.curAlpha = 0.0 - self.__StartFade(self.STATE_OUT, 0.0, speed) - - def FadeIn(self, speed): - self.curAlpha = 1.0 - self.__StartFade(self.STATE_IN, 0.0, speed) - - def WhiteOut(self, speed): - self.curAlpha = 0.0 - self.__StartFade(self.STATE_OUT, 1.0, speed) - - def WhiteIn(self, speed): - self.curAlpha = 1.0 - self.__StartFade(self.STATE_IN, 1.0, speed) - - def __StartFade(self, state, color, speed): - self.state = state - self.fadeColor = color - self.Show() - - self.speed = self.DEFAULT_FADE_SPEED - if 0 != speed: - self.speed = speed - - def __EndFade(self): - event.EndEventProcess(self.eventIndex) - - def OnUpdate(self): - - if self.STATE_OUT == self.state: - - self.curAlpha += self.speed - - if self.curAlpha >= 1.0: - - self.state = self.STATE_WAIT - self.curAlpha = 1.0 - self.__EndFade() - - elif self.STATE_IN == self.state: - - self.curAlpha -= self.speed - - if self.curAlpha <= 0.0: - - self.state = self.STATE_WAIT - self.curAlpha = 0.0 - self.__EndFade() - self.Hide() - - self.SetAlpha(self.curAlpha) - -class BarButton(ui.Button): - ColorUp = 0x40999999 - ColorDown = 0x40aaaacc - ColorOver = 0x40ddddff - - UP=0 - DOWN=1 - OVER=2 - - def __init__(self, layer = "UI", - aColorUp = ColorUp, - aColorDown = ColorDown, - aColorOver = ColorOver): - ui.Button.__init__(self,layer) - self.state = self.UP - self.colortable = aColorUp, aColorDown, aColorOver - - def OnRender(self): - x,y = self.GetGlobalPosition() - grp.SetColor(self.colortable[self.state]) - grp.RenderBar(x,y,self.GetWidth(),self.GetHeight()) - - def CallEvent(self): - self.state = self.UP - ui.Button.CallEvent(self) - - def DownEvent(self): - self.state = self.DOWN - - def ShowToolTip(self): - self.state = self.OVER - - def HideToolTip(self): - self.state = self.UP - -class DescriptionWindow(ui.Window): - def __init__(self,idx): - ui.Window.__init__(self, "TOP_MOST") - self.descIndex = idx - def __del__(self): - ui.Window.__del__(self) - def OnRender(self): - event.RenderEventSet(self.descIndex) - -class QuestDialog(ui.ScriptWindow): - - TITLE_STATE_NONE = 0 - TITLE_STATE_APPEAR = 1 - TITLE_STATE_SHOW = 2 - TITLE_STATE_DISAPPEAR = 3 - - SKIN_NONE = 0 - SKIN_CINEMA = 5 - - QUEST_BUTTON_MAX_NUM = 8 - - def __init__(self,skin,idx): - - ui.ScriptWindow.__init__(self) - self.SetWindowName("quest dialog") - - self.focusIndex = 0 - - self.board = None - self.sx = 0 - self.sy = 0 - - self.skin = skin - if skin == 3: - event.SetRestrictedCount(idx,36) - else: - event.SetRestrictedCount(idx,60) - - QuestCurtain.BarHeight = (wndMgr.GetScreenHeight()-wndMgr.GetScreenWidth() * 9 // 16) // 2 - - if QuestCurtain.BarHeight<0: - QuestCurtain.BarHeight = 50 - if not ('QuestCurtain' in QuestDialog.__dict__): - QuestDialog.QuestCurtain = QuestCurtain() - QuestDialog.QuestCurtain.Show() - - QuestDialog.QuestCurtain.CurtainMode = 1 - self.nextCurtainMode = 0 - if self.skin: - QuestDialog.QuestCurtain.CurtainMode = 1 - self.nextCurtainMode = 0 - self.LoadDialog(self.skin) - else: - QuestDialog.QuestCurtain.CurtainMode = -1 - self.nextCurtainMode = -1 - - self.descIndex = idx - self.descWindow = DescriptionWindow(idx) - self.descWindow.Show() - self.eventCurtain = EventCurtain(idx) - event.SetEventHandler(idx, self) - - self.OnCloseEvent = None - self.btnAnswer = None - self.btnNext = None - self.imgLeft = None - self.imgTop = None - self.imgBackground = None - self.imgTitle = None - self.titleState = self.TITLE_STATE_NONE - self.titleShowTime = 0 - self.images = [] - self.prevbutton = None - self.nextbutton = None - - # QUEST_INPUT - self.needInputString = False - self.editSlot = None - self.editLine = None - # END_OF_QUEST_INPUT - - # QUEST_CANCEL - Track if dialog was cancelled - self.bCancelled = False - # END_OF_QUEST_CANCEL - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def LoadDialog(self, skin): - try: - PythonScriptLoader = ui.PythonScriptLoader() - PythonScriptLoader.LoadScriptFile(self, "uiscript/questdialog.py") - except RuntimeError: - dbg.TraceError("QuestDialog.LoadDialog") - - try: - self.board = self.GetChild('board') - except RuntimeError: - dbg.TraceError("QuestDialog.BindObject") - - self.SetCenterPosition() - if self.SKIN_CINEMA == skin: - self.board.Hide() - - # QUEST_CANCEL - def OnCancel(self): - self.bCancelled = True - self.nextCurtainMode = -1 - self.CloseSelf() - # END_OF_QUEST_CANCEL - - def CloseSelf(self): - if self.bCancelled: - net.SendQuestCancelPacket() - self.bCancelled = False - - QuestDialog.QuestCurtain.CurtainMode = self.nextCurtainMode - self.btnNext = None - self.descWindow = None - self.btnAnswer = None - self.Destroy() - if self.descIndex: - event.ClearEventSet(self.descIndex) - self.descIndex = None - - self.focusIndex = 0 - - def Destroy(self): - self.ClearDictionary() - if self.OnCloseEvent: - self.OnCloseEvent() - self.OnCloseEvent = None - - # QUEST_INPUT - if self.needInputString: - if self.editLine: - text = self.editLine.GetText() - net.SendQuestInputStringPacket(text) - # END_OF_QUEST_INPUT - - self.imgTitle = None - self.images = None - self.eventCurtain = None - self.board = None - - def OnUpdate(self): - if self.skin == self.SKIN_CINEMA: - event.UpdateEventSet(self.descIndex, 50, -(wndMgr.GetScreenHeight() - 44)) - - # AUTO_RESIZE_BOARD - elif self.skin == 3: - if self.board: - event.UpdateEventSet(self.descIndex, self.board.GetGlobalPosition()[0]+20+self.sx, -self.board.GetGlobalPosition()[1]-20-self.sy) - event.SetEventSetWidth(self.descIndex, self.board.GetWidth()-40) - elif self.skin: - if self.board: - event.UpdateEventSet(self.descIndex, self.board.GetGlobalPosition()[0]+20, -self.board.GetGlobalPosition()[1]-20) - event.SetEventSetWidth(self.descIndex, self.board.GetWidth()-40) - # END_OF_AUTO_RESIZE_BOARD - else: - event.UpdateEventSet(self.descIndex, 0, 0) - - if self.TITLE_STATE_NONE != self.titleState: - - curTime = app.GetTime() - elapsedTime = app.GetTime() - self.titleShowTime - - if self.TITLE_STATE_APPEAR == self.titleState: - self.imgTitle.SetAlpha(elapsedTime*2) - if elapsedTime > 0.5: - self.titleState = self.TITLE_STATE_SHOW - self.titleShowTime = curTime - - elif self.TITLE_STATE_SHOW == self.titleState: - if elapsedTime > 1.0: - self.titleState = self.TITLE_STATE_DISAPPEAR - self.titleShowTime = curTime - - elif self.TITLE_STATE_DISAPPEAR == self.titleState: - self.imgTitle.SetAlpha(1.0 - elapsedTime*2) - if elapsedTime > 0.5: - self.titleState = self.TITLE_STATE_NONE - self.titleShowTime = curTime - - ## Set Variables - - def AddOnCloseEvent(self, f): - if self.OnCloseEvent: - old = self.OnCloseEvent - - def combined(*args, **kwargs): - err = None - try: - old(*args, **kwargs) - except Exception as e: - err = e - f(*args, **kwargs) - if err: - raise err - - self.OnCloseEvent = combined - else: - self.OnCloseEvent = f - - def AddOnDoneEvent(self,f): - QuestCurtain.OnDoneEventList.append(f) - - def SetOnCloseEvent(self,f): - self.OnCloseEvent = f - - def SetEventSetPosition(self, x, y): - self.sx = x - self.sy = y - - def AdjustEventSetPosition(self, x, y): - self.sx += x - self.sy += y - - ## Event - # QUEST_CANCEL - def MakeNextButton(self, button_type): - if self.SKIN_NONE == self.skin: - return - - yPos = event.GetEventSetLocalYPosition(self.descIndex) - - b = BarButton() - b.SetParent(self.board) - - b.SetSize(100,26) - b.SetPosition(self.sx+self.board.GetWidth()//2-50,self.sy+yPos) - - self.nextButtonType = button_type; - - import localeInfo - if event.BUTTON_TYPE_CANCEL == button_type: - b.SetEvent(lambda s=self:(setattr(s, 'bCancelled', True) or None) or event.SelectAnswer(s.descIndex, 254) or s.OnCancel()) - b.SetText(localeInfo.UI_CANCEL) - elif event.BUTTON_TYPE_DONE == button_type: - b.SetEvent(lambda s=self:s.CloseSelf()) - b.SetText(localeInfo.UI_OK) - elif event.BUTTON_TYPE_NEXT == button_type: - b.SetEvent(lambda s=self:event.SelectAnswer(s.descIndex, 254) or s.CloseSelf()) - b.SetText(localeInfo.UI_NEXT) - b.Show() - b.SetTextColor(0xffffffff) - self.btnNext = b - - # END_OF_QUEST_CANCEL - - def MakeQuestion(self, n): # n is the total number of quest buttons including the final "Close" button - global entire_questbutton_number - global entire_questpage_number - global cur_questpage_number - entire_questpage_number = ((n-2)//7)+1 - entire_questbutton_number = n - - if not self.board: - return - - self.btnAnswer = [self.MakeEachButton(i) for i in range (n)] - - import localeInfo - self.prevbutton = self.MakeNextPrevPageButton() - self.prevbutton.SetPosition(self.sx+self.board.GetWidth()//2-164, self.board.GetHeight()//2-16) - self.prevbutton.SetText(localeInfo.UI_PREVPAGE) - self.prevbutton.SetEvent(self.PrevQuestPageEvent, 1, n) - - self.nextbutton = self.MakeNextPrevPageButton() - self.nextbutton.SetPosition(self.sx+self.board.GetWidth()//2+112, self.board.GetHeight()//2-16) - self.nextbutton.SetText(localeInfo.UI_NEXTPAGE) - self.nextbutton.SetEvent(self.NextQuestPageEvent, 1, n) - - if cur_questpage_number != 1: - cur_questpage_number = 1 - - def MakeEachButton(self, i): - if self.skin == 3: - button = BarButton("TOP_MOST",0x50000000, 0x50404040, 0x50606060) - button.SetParent(self.board) - button.SetSize(106,26) - button.SetPosition(self.sx + self.board.GetWidth()//2+((i*2)-1)*56-56, self.sy+(event.GetLineCount(self.descIndex))*16+20+5) - button.SetText("a") - button.SetTextColor(0xff000000) - else: - i = i % 8 - button = BarButton("TOP_MOST") - button.SetParent(self.board) - button.SetSize(200,26) - button.SetPosition(self.sx + self.board.GetWidth()//2-100,self.sy+(event.GetLineCount(self.descIndex)+i*2)*16+20+5) - button.SetText("a") - button.SetTextColor(0xffffffff) - return button - - def MakeNextPrevPageButton(self): - button = BarButton("TOP_MOST") - button.SetParent(self.board) - button.SetSize(52,26) - button.SetText("a") - button.SetTextColor(0xffffffff) - return button - - def RefreshQuestPage(self, n): - global cur_questpage_number - global entire_questpage_number - num = 0 - Showing_button_inx = (cur_questpage_number-1)* self.QUEST_BUTTON_MAX_NUM - - while num < n: - if num >= Showing_button_inx and num < Showing_button_inx + self.QUEST_BUTTON_MAX_NUM: - self.btnAnswer[num].Show() - else: - self.btnAnswer[num].Hide() - num = num + 1 - - if cur_questpage_number == 1: - self.prevbutton.Hide() - self.nextbutton.Show() - elif cur_questpage_number == entire_questpage_number: - self.prevbutton.Show() - self.nextbutton.Hide() - else: - self.prevbutton.Show() - self.nextbutton.Show() - - def NextQuestPageEvent(self, one, n): - global cur_questpage_number - cur_questpage_number = cur_questpage_number + one - self.RefreshQuestPage(n) - - def PrevQuestPageEvent(self, one, n): - global cur_questpage_number - cur_questpage_number = cur_questpage_number - one - self.RefreshQuestPage(n) - - def ClickAnswerEvent(self, ai): - event.SelectAnswer(self.descIndex, ai) - self.nextbutton = None - self.prevbutton = None - self.CloseSelf() - - def AppendQuestion(self, name, idx): # idx starts from 0. See PythonEventManager.cpp line 881 - if not self.btnAnswer: - return - - self.btnAnswer[idx].SetText(name) - x, y= self.btnAnswer[idx].GetGlobalPosition() - - self.btnAnswer[idx].SetEvent(self.ClickAnswerEvent, idx) - - global entire_questbutton_number - - Showing_button_idx = (cur_questpage_number-1)* self.QUEST_BUTTON_MAX_NUM - - if Showing_button_idx <= idx and idx < Showing_button_idx + self.QUEST_BUTTON_MAX_NUM: - self.btnAnswer[idx].Show() - else: - self.btnAnswer[idx].Hide() - if entire_questbutton_number >= self.QUEST_BUTTON_MAX_NUM: - self.nextbutton.Show() - - def FadeOut(self, speed): - self.eventCurtain.FadeOut(speed) - - def FadeIn(self, speed): - self.eventCurtain.FadeIn(speed) - - def WhiteOut(self, speed): - self.eventCurtain.WhiteOut(speed) - - def WhiteIn(self, speed): - self.eventCurtain.WhiteIn(speed) - - def DoneEvent(self): - self.nextCurtainMode = -1 - if self.SKIN_NONE == self.skin or self.SKIN_CINEMA == self.skin: - self.CloseSelf() - - def __GetQuestImageFileName(self, filename): - if len(filename) > 1: - if filename[1]!=':': - filename = QUEST_BOARD_IMAGE_DIR+filename - - return filename - - # QUEST_INPUT - def OnKeyDown(self, key): - if self.btnAnswer == None: - ## Handle cases with only unidirectional buttons like 'Next' or 'OK' without choice options - if None != self.btnNext: - if app.DIK_RETURN == key: - self.OnPressEscapeKey() - - if app.DIK_UP == key or app.DIK_DOWN == key: - self.btnNext.ShowToolTip() - - return True - - focusIndex = self.focusIndex; - lastFocusIndex = focusIndex; - - #print "QuestDialog key down - focus, last : ", focusIndex, lastFocusIndex - - answerCount = len(self.btnAnswer) - - if app.DIK_DOWN == key: - focusIndex += 1 - - if app.DIK_UP == key: - focusIndex -= 1 - - if focusIndex < 0: - focusIndex = answerCount - 1 - - if focusIndex >= answerCount: - focusIndex = 0 - - self.focusIndex = focusIndex; - - focusBtn = self.btnAnswer[focusIndex] - lastFocusBtn = self.btnAnswer[lastFocusIndex] - - if focusIndex != lastFocusIndex: - focusBtn.ShowToolTip() - lastFocusBtn.HideToolTip() - - if app.DIK_RETURN == key: - focusBtn.CallEvent() - - return True - - def OnPressEscapeKey(self): - - # When ESC key is pressed, have the same effect as clicking the "Next" button. - if None != self.btnNext: - ## ESC button when all quest text has been displayed - if event.BUTTON_TYPE_CANCEL == self.nextButtonType: - self.bCancelled = True - event.SelectAnswer(self.descIndex, 254) - self.CloseSelf() - ## When no action is being performed - elif event.BUTTON_TYPE_DONE == self.nextButtonType: - self.CloseSelf() - ## When trying to press Enter or move to next screen - elif event.BUTTON_TYPE_NEXT == self.nextButtonType: - event.SelectAnswer(self.descIndex, 254) - self.CloseSelf() - else: - ## When dialog is closed midway or ESC button appears - event.SelectAnswer(self.descIndex, entire_questbutton_number -1 ) - self.nextbutton = None - self.prevbutton = None - self.OnCancel() - return True - - def OnIMEReturn(self): - if self.needInputString: - self.CloseSelf() - return True - - def OnIMEUpdate(self): - if not self.needInputString: - return - - if not self.editLine: - return - - self.editLine.OnIMEUpdate() - - def OnInput(self): - - self.needInputString = True - - event.AddEventSetLocalYPosition(self.descIndex, 5+10) - yPos = event.GetEventSetLocalYPosition(self.descIndex) - - self.editSlot = ui.SlotBar() - self.editSlot.SetSize(200, 18) - self.editSlot.SetPosition(0, yPos) - self.editSlot.SetParent(self.board) - self.editSlot.SetWindowHorizontalAlignCenter() - self.editSlot.Show() - - self.editLine = ui.EditLine() - self.editLine.SetParent(self.editSlot) - self.editLine.SetPosition(3, 3) - self.editLine.SetSize(200, 17) - self.editLine.SetMax(30) - self.editLine.SetFocus() - self.editLine.Show() - - event.AddEventSetLocalYPosition(self.descIndex, 25+10) - - self.MakeNextButton(event.BUTTON_TYPE_DONE) - - self.editLine.UpdateRect() - self.editSlot.UpdateRect() - self.board.UpdateRect() - # END_OF_QUEST_INPUT - - def OnImage(self, x, y, filename, desc=""): - filename = self.__GetQuestImageFileName(filename) - - # IMAGE_EXCEPTION_BUG_FIX - try: - img = ui.MakeImageBox(self.board, filename, x, y) - self.images.append(img) - except RuntimeError: - pass - # END_OF_IMAGE_EXCEPTION_BUG_FIX - - # QUEST_IMAGE - def OnInsertItemIcon(self, type, idx, title, desc, index=0, total=1): - if "item" != type: - return - - import item - item.SelectItem(idx) - filename = item.GetIconImageFileName() - - underTitle = title - - if not title and not desc: - title = item.GetItemName() - desc = item.GetItemDescription() - - tempDesc = desc - desc = "" - - import grpText - lineCount = grpText.GetSplitingTextLineCount(tempDesc, 25) - for i in range(lineCount): - desc += grpText.GetSplitingTextLine(tempDesc, 25, i) + "/" - - desc = desc[:-1] - - self.OnInsertImage(filename, underTitle, title, desc, index, total) - - def OnInsertImage(self, filename, underTitle, title, desc, index=0, total=1): - - if index == 0: - event.AddEventSetLocalYPosition(self.descIndex, 24) - - y = event.GetEventSetLocalYPosition(self.descIndex) - xBoard, yBoard = self.board.GetGlobalPosition() - - try: - img = ToolTipImageBox() - img.SetParent(self.board) - img.LoadImage(filename) - pos_x = (self.board.GetWidth() * (index + 1) // (total + 1)) - (img.GetWidth() // 2) - img.SetPosition(pos_x, y) - #img.SetWindowHorizontalAlignCenter() - img.DestroyToolTip() - if title and desc: - img.CreateToolTip(self.board, title, desc, 0, yBoard + y + img.GetHeight()) - img.Show() - self.images.append(img) - except RuntimeError: - pass - - event.AddEventSetLocalYPosition(self.descIndex, img.GetHeight() - 20) - - if underTitle: - event.AddEventSetLocalYPosition(self.descIndex, 3) - event.InsertTextInline(self.descIndex, underTitle, (self.board.GetWidth() * (index + 1) // (total + 1))) - if index != total - 1: - event.AddEventSetLocalYPosition(self.descIndex, -( 3 + 16 )) - else: - if index == total - 1: - event.AddEventSetLocalYPosition(self.descIndex, 4) - - if index != total - 1: - event.AddEventSetLocalYPosition(self.descIndex, -(img.GetHeight() - 20)) - - - # END_OF_QUEST_IMAGE - - def OnSize(self, width, height): - self.board.SetSize(width, height) - - def OnTitleImage(self, filename): - img = ui.ImageBox("TOP_MOST") - - try: - img.SetWindowHorizontalAlignCenter() - img.LoadImage(filename) - img.SetPosition(0, wndMgr.GetScreenHeight() - (75//2) - (32//2)) - img.SetAlpha(0.0) - img.Show() - except RuntimeError: - dbg.TraceError("QuestDialog.OnTitleImage(%s)" % filename) - img.Hide() - - self.imgTitle = img - self.titleState = self.TITLE_STATE_APPEAR - self.titleShowTime = app.GetTime() - - def OnLeftImage(self, imgfile): - imgfile = self.__GetQuestImageFileName(imgfile) - if not self.imgLeft: - self.imgLeft = ui.ExpandedImageBox("TOP_MOST") - self.imgLeft.SetParent(self) - self.imgLeft.SetPosition(0,0) - bd = self.board - bx, by = bd.GetLocalPosition() - bd.SetPosition(160,by) - if self.imgTop: - tx, ty = self.imgTop.GetLocalPosition() - self.imgTop.SetPosition(160,ty) - - try: - self.imgLeft.LoadImage(imgfile) - self.imgLeft.SetSize(400,450) - self.imgLeft.SetOrigin(self.imgLeft.GetWidth()//2,self.imgLeft.GetHeight()//2) - self.imgLeft.Show() - except RuntimeError: - import dbg - dbg.TraceError("QuestDialog.OnLeftImage(%s)" % imgfile) - self.imgLeft.Hide() - - def OnTopImage(self, imgfile): - imgfile = self.__GetQuestImageFileName(imgfile) - - bd = self.board - bx, by = bd.GetLocalPosition() - if not self.imgTop: - self.imgTop = ui.ExpandedImageBox("TOP_MOST") - self.imgTop.SetParent(self) - bd.SetPosition(bx,190) - self.imgTop.SetPosition(bx,10) - - try: - self.imgTop.LoadImage(imgfile) - h = self.imgTop.GetHeight() - if h>170: - # need adjust board size - bd.SetPosition(bx,20+h) - bd.SetSize(350,420-h) - self.imgTop.SetSize(350,h) - else: - self.imgTop.SetSize(350,170) - bd.SetPosition(bx,190) - bd.SetSize(350,250) - self.imgTop.SetOrigin(self.imgTop.GetWidth()//2,self.imgTop.GetHeight()//2) - self.imgTop.Show() - except RuntimeError: - dbg.TraceError("QuestDialog.OnTopImage(%s)" % imgfile) - self.imgTop.Hide() - - def OnBackgroundImage(self, imgfile): - imgfile = self.__GetQuestImageFileName(imgfile) - c = self.board - w = c.GetWidth() - h = c.GetHeight() - px, py = c.GetLocalPosition() - moved = 0 - if not self.imgBackground: - self.imgBackground = ui.ExpandedImageBox("TOP_MOST") - self.imgBackground.SetParent(c) - self.imgBackground.SetPosition(0,0) - self.imgBackground.LoadImage(imgfile) - iw = self.imgBackground.GetWidth() - ih = self.imgBackground.GetHeight() - if self.skin==3: - iw = 256 - ih = 333 - self.imgBackground.SetSize(iw,ih) - if w < iw: - px -= (iw-w)//2 - c.SetPosition(px,py) - w = iw - if h < ih: - py -= (ih-h)//2 - c.SetPosition(px,py) - h = ih - if self.skin == 3: - w=256 - h = 333 - self.sx = 0 - self.sy = 100 - - c.SetSize(w,h) - c.HideInternal() - - c.SetWindowHorizontalAlignCenter() - c.SetWindowVerticalAlignCenter() - - c.SetPosition(0,0) - if self.skin==3: - c.SetPosition(-190,0) - - self.imgBackground.SetWindowHorizontalAlignCenter() - self.imgBackground.SetWindowVerticalAlignCenter() - self.imgBackground.SetPosition(0,0) - self.imgBackground.Show() diff --git a/tools/root/uirefine.py b/tools/root/uirefine.py deleted file mode 100644 index 804acd75..00000000 --- a/tools/root/uirefine.py +++ /dev/null @@ -1,449 +0,0 @@ -import app -import net -import player -import item -import ui -import uiToolTip -import mouseModule -import localeInfo -import uiCommon -import constInfo - -class RefineDialog(ui.ScriptWindow): - makeSocketSuccessPercentage = ( 100, 33, 20, 15, 10, 5, 0 ) - upgradeStoneSuccessPercentage = ( 30, 29, 28, 27, 26, 25, 24, 23, 22 ) - upgradeArmorSuccessPercentage = ( 99, 66, 33, 33, 33, 33, 33, 33, 33 ) - upgradeAccessorySuccessPercentage = ( 99, 88, 77, 66, 33, 33, 33, 33, 33 ) - upgradeSuccessPercentage = ( 99, 66, 33, 33, 33, 33, 33, 33, 33 ) - - def __init__(self): - ui.ScriptWindow.__init__(self) - self.__LoadScript() - - self.scrollItemPos = 0 - self.targetItemPos = 0 - - def __LoadScript(self): - - self.__LoadQuestionDialog() - - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "uiscript/refinedialog.py") - - except: - import exception - exception.Abort("RefineDialog.__LoadScript.LoadObject") - - try: - self.board = self.GetChild("Board") - self.titleBar = self.GetChild("TitleBar") - self.successPercentage = self.GetChild("SuccessPercentage") - self.GetChild("AcceptButton").SetEvent(self.OpenQuestionDialog) - self.GetChild("CancelButton").SetEvent(self.Close) - except: - import exception - exception.Abort("RefineDialog.__LoadScript.BindObject") - - self.successPercentage.Hide() - - toolTip = uiToolTip.ItemToolTip() - toolTip.SetParent(self) - toolTip.SetPosition(15, 38) - toolTip.SetFollow(False) - toolTip.Show() - self.toolTip = toolTip - - self.titleBar.SetCloseEvent(ui.__mem_func__(self.Close)) - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def __LoadQuestionDialog(self): - self.dlgQuestion = ui.ScriptWindow() - - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self.dlgQuestion, "uiscript/questiondialog2.py") - except: - import exception - exception.Abort("RefineDialog.__LoadQuestionDialog.LoadScript") - - try: - GetObject=self.dlgQuestion.GetChild - GetObject("message1").SetText(localeInfo.REFINE_DESTROY_WARNING) - GetObject("message2").SetText(localeInfo.REFINE_WARNING2) - GetObject("accept").SetEvent(ui.__mem_func__(self.Accept)) - GetObject("cancel").SetEvent(ui.__mem_func__(self.dlgQuestion.Hide)) - except: - import exception - exception.Abort("SelectCharacterWindow.__LoadQuestionDialog.BindObject") - - def Destroy(self): - self.ClearDictionary() - self.board = 0 - self.successPercentage = 0 - self.titleBar = 0 - self.toolTip = 0 - self.dlgQuestion = 0 - - def GetRefineSuccessPercentage(self, scrollSlotIndex, itemSlotIndex): - if -1 != scrollSlotIndex: - if player.IsRefineGradeScroll(scrollSlotIndex): - curGrade = player.GetItemGrade(itemSlotIndex) - itemIndex = player.GetItemIndex(itemSlotIndex) - - item.SelectItem(itemIndex) - - itemType = item.GetItemType() - itemSubType = item.GetItemSubType() - - if item.ITEM_TYPE_METIN == itemType: - if curGrade >= len(self.upgradeStoneSuccessPercentage): - return 0 - return self.upgradeStoneSuccessPercentage[curGrade] - elif item.ITEM_TYPE_ARMOR == itemType: - if item.ARMOR_BODY == itemSubType: - if curGrade >= len(self.upgradeArmorSuccessPercentage): - return 0 - return self.upgradeArmorSuccessPercentage[curGrade] - else: - if curGrade >= len(self.upgradeAccessorySuccessPercentage): - return 0 - return self.upgradeAccessorySuccessPercentage[curGrade] - else: - if curGrade >= len(self.upgradeSuccessPercentage): - return 0 - - return self.upgradeSuccessPercentage[curGrade] - - for i in range(player.METIN_SOCKET_MAX_NUM+1): - if 0 == player.GetItemMetinSocket(itemSlotIndex, i): - break - - return self.makeSocketSuccessPercentage[i] - - def Open(self, scrollItemPos, targetItemPos): - self.scrollItemPos = scrollItemPos - self.targetItemPos = targetItemPos - - percentage = self.GetRefineSuccessPercentage(scrollItemPos, targetItemPos) - - if 0 == percentage: - return - - self.successPercentage.SetText(localeInfo.REFINE_SUCCESS_PROBALITY % (percentage)) - - itemIndex = player.GetItemIndex(targetItemPos) - self.toolTip.ClearToolTip() - metinSlot = [] - - for i in range(player.METIN_SOCKET_MAX_NUM): - metinSlot.append(player.GetItemMetinSocket(targetItemPos, i)) - - self.toolTip.AddItemData(itemIndex, metinSlot) - - self.UpdateDialog() - self.SetTop() - self.Show() - - def UpdateDialog(self): - newWidth = self.toolTip.GetWidth() + 30 - # MR-15: Adjust button padding for refine window - newHeight = self.toolTip.GetHeight() + 108 - # MR-15: -- END OF -- Adjust button padding for refine window - - self.board.SetSize(newWidth, newHeight) - # MR-15: Adjust button padding for refine window - self.titleBar.SetWidth(newWidth - 15) - # MR-15: -- END OF -- Adjust button padding for refine window - self.SetSize(newWidth, newHeight) - - (x, y) = self.GetLocalPosition() - - self.SetPosition(x, y) - - def OpenQuestionDialog(self): - percentage = self.GetRefineSuccessPercentage(-1, self.targetItemPos) - - if 100 == percentage: - self.Accept() - - return - - self.dlgQuestion.SetTop() - self.dlgQuestion.Show() - - def Accept(self): - net.SendItemUseToItemPacket(self.scrollItemPos, self.targetItemPos) - self.Close() - - def Close(self): - self.dlgQuestion.Hide() - self.Hide() - - def OnPressEscapeKey(self): - self.Close() - return True - -class RefineDialogNew(ui.ScriptWindow): - - def __init__(self): - ui.ScriptWindow.__init__(self) - self.__Initialize() - self.isLoaded = False - - def __Initialize(self): - self.dlgQuestion = None - self.children = [] - self.vnum = 0 - self.targetItemPos = 0 - self.dialogHeight = 0 - self.cost = 0 - self.percentage = 0 - self.type = 0 - - def __LoadScript(self): - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "uiscript/refinedialog.py") - except: - import exception - exception.Abort("RefineDialog.__LoadScript.LoadObject") - - try: - self.board = self.GetChild("Board") - self.titleBar = self.GetChild("TitleBar") - self.probText = self.GetChild("SuccessPercentage") - self.costText = self.GetChild("Cost") - self.successPercentage = self.GetChild("SuccessPercentage") - self.GetChild("AcceptButton").SetEvent(self.OpenQuestionDialog) - self.GetChild("CancelButton").SetEvent(self.CancelRefine) - except: - import exception - exception.Abort("RefineDialog.__LoadScript.BindObject") - - self.successPercentage.Hide() - - toolTip = uiToolTip.ItemToolTip() - toolTip.SetParent(self) - toolTip.SetFollow(False) - toolTip.SetPosition(15, 38) - toolTip.Show() - self.toolTip = toolTip - - self.slotList = [] - - for i in range(3): - slot = self.__MakeSlot() - - slot.SetParent(toolTip) - slot.SetWindowVerticalAlignCenter() - self.slotList.append(slot) - - itemImage = self.__MakeItemImage() - itemImage.SetParent(toolTip) - itemImage.SetWindowVerticalAlignCenter() - itemImage.SetPosition(-35, 0) - self.itemImage = itemImage - - self.titleBar.SetCloseEvent(ui.__mem_func__(self.CancelRefine)) - self.isLoaded = True - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def __MakeSlot(self): - slot = ui.ImageBox() - - slot.LoadImage("d:/ymir work/ui/public/slot_base.sub") - slot.Show() - self.children.append(slot) - - return slot - - def __MakeItemImage(self): - itemImage = ui.ImageBox() - - itemImage.Show() - self.children.append(itemImage) - - return itemImage - - def __MakeThinBoard(self): - thinBoard = ui.ThinBoard() - - thinBoard.SetParent(self) - thinBoard.Show() - self.children.append(thinBoard) - - return thinBoard - - def Destroy(self): - self.ClearDictionary() - - self.dlgQuestion = None - self.board = 0 - self.probText = 0 - self.costText = 0 - self.titleBar = 0 - self.toolTip = 0 - self.successPercentage = None - self.slotList = [] - self.children = [] - - def Open(self, targetItemPos, nextGradeItemVnum, cost, prob, type): - if False == self.isLoaded: - self.__LoadScript() - - self.__Initialize() - - self.targetItemPos = targetItemPos - self.vnum = nextGradeItemVnum - self.cost = cost - self.percentage = prob - self.type = type - - self.probText.SetText(localeInfo.REFINE_SUCCESS_PROBALITY % (self.percentage)) - self.costText.SetText(localeInfo.REFINE_COST % (self.cost)) - - self.toolTip.ClearToolTip() - metinSlot = [] - - for i in range(player.METIN_SOCKET_MAX_NUM): - metinSlot.append(player.GetItemMetinSocket(targetItemPos, i)) - - attrSlot = [] - - for i in range(player.ATTRIBUTE_SLOT_MAX_NUM): - attrSlot.append(player.GetItemAttribute(targetItemPos, i)) - - self.toolTip.AddRefineItemData(nextGradeItemVnum, metinSlot, attrSlot) - - item.SelectItem(nextGradeItemVnum) - self.itemImage.LoadImage(item.GetIconImageFileName()) - xSlotCount, ySlotCount = item.GetItemSize() - - for slot in self.slotList: - slot.Hide() - - for i in range(min(3, ySlotCount)): - self.slotList[i].SetPosition(-35, i * 32 - (ySlotCount - 1) * 16) - self.slotList[i].Show() - - self.dialogHeight = self.toolTip.GetHeight() + 46 - self.UpdateDialog() - - self.SetTop() - self.Show() - - def Close(self): - # MR-15: Multiline dialog messages - if self.dlgQuestion: - self.dlgQuestion.Hide() - # MR-15: -- END OF -- Multiline dialog messages - - self.dlgQuestion = None - self.Hide() - - def AppendMaterial(self, vnum, count): - slot = self.__MakeSlot() - - slot.SetParent(self) - slot.SetPosition(15, self.dialogHeight) - - itemImage = self.__MakeItemImage() - - itemImage.SetParent(slot) - item.SelectItem(vnum) - itemImage.LoadImage(item.GetIconImageFileName()) - - thinBoard = self.__MakeThinBoard() - - thinBoard.SetPosition(50, self.dialogHeight) - thinBoard.SetSize(self.toolTip.GetWidth(), 20) - - textLine = ui.TextLine() - - textLine.SetParent(thinBoard) - textLine.SetFontName(localeInfo.UI_DEF_FONT) - textLine.SetPackedFontColor(0xffdddddd) - textLine.SetText("%s x %02d" % (item.GetItemName(), count)) - textLine.SetOutline() - textLine.SetFeather(False) - textLine.SetWindowVerticalAlignCenter() - textLine.SetVerticalAlignCenter() - - if app.IsRTL(): - (x,y) = textLine.GetTextSize() - textLine.SetPosition(x, 0) - else: - textLine.SetPosition(15, 0) - - textLine.Show() - self.children.append(textLine) - - self.dialogHeight += 34 - self.UpdateDialog() - - def UpdateDialog(self): - newWidth = self.toolTip.GetWidth() + 60 - # MR-15: Adjust button padding for refine window - newHeight = self.dialogHeight + 79 - # MR-15: -- END OF -- Adjust button padding for refine window - - newHeight -= 8 - - if app.IsRTL(): - self.board.SetPosition(newWidth, 0) - - (x, y) = self.titleBar.GetLocalPosition() - self.titleBar.SetPosition(newWidth - 15, y) - - self.board.SetSize(newWidth, newHeight) - self.toolTip.SetPosition(15 + 35, 38) - self.titleBar.SetWidth(newWidth - 15) - self.SetSize(newWidth, newHeight) - - (x, y) = self.GetLocalPosition() - self.SetPosition(x, y) - - def OpenQuestionDialog(self): - - if 100 == self.percentage: - self.Accept() - return - - if 5 == self.type: ## ������ �ູ�� - self.Accept() - return - - dlgQuestion = uiCommon.QuestionDialog2() - dlgQuestion.SetText2(localeInfo.REFINE_WARNING2) - dlgQuestion.SetAcceptEvent(ui.__mem_func__(self.Accept)) - dlgQuestion.SetCancelEvent(ui.__mem_func__(dlgQuestion.Close)) - - if 3 == self.type: ## ��ö - dlgQuestion.SetText1(localeInfo.REFINE_DESTROY_WARNING_WITH_BONUS_PERCENT_1) - # MR-15: Update refining messages - dlgQuestion.SetText2(localeInfo.REFINE_POPUP_NO_DOWNGRADE_MESSAGE) - # MR-15: -- END OF -- Update refining messages - elif 2 == self.type: ## �ູ�� - dlgQuestion.SetText1(localeInfo.REFINE_DOWN_GRADE_WARNING) - else: - dlgQuestion.SetText1(localeInfo.REFINE_DESTROY_WARNING) - - dlgQuestion.Open() - self.dlgQuestion = dlgQuestion - - def Accept(self): - net.SendRefinePacket(self.targetItemPos, self.type) - self.Close() - - def CancelRefine(self): - net.SendRefinePacket(255, 255) - self.Close() - - def OnPressEscapeKey(self): - self.CancelRefine() - return True diff --git a/tools/root/uirestart.py b/tools/root/uirestart.py deleted file mode 100644 index 23730df1..00000000 --- a/tools/root/uirestart.py +++ /dev/null @@ -1,65 +0,0 @@ -import dbg -import app -import net - -import ui - -################################################################################################### -## Restart -class RestartDialog(ui.ScriptWindow): - - def __init__(self): - ui.ScriptWindow.__init__(self) - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def LoadDialog(self): - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "uiscript/restartdialog.py") - except Exception as msg: - import sys - (type, msg, tb)=sys.exc_info() - dbg.TraceError("RestartDialog.LoadDialog - %s:%s" % (type, msg)) - app.Abort() - return 0 - - try: - self.restartHereButton=self.GetChild("restart_here_button") - self.restartTownButton=self.GetChild("restart_town_button") - except: - import sys - (type, msg, tb)=sys.exc_info() - dbg.TraceError("RestartDialog.LoadDialog - %s:%s" % (type, msg)) - app.Abort() - return 0 - - self.restartHereButton.SetEvent(ui.__mem_func__(self.RestartHere)) - self.restartTownButton.SetEvent(ui.__mem_func__(self.RestartTown)) - - return 1 - - def Destroy(self): - self.restartHereButton=0 - self.restartTownButton=0 - self.ClearDictionary() - - def OpenDialog(self): - self.Show() - - def Close(self): - self.Hide() - return True - - def RestartHere(self): - net.SendChatPacket("/restart_here") - - def RestartTown(self): - net.SendChatPacket("/restart_town") - - def OnPressExitKey(self): - return True - - def OnPressEscapeKey(self): - return True diff --git a/tools/root/uisafebox.py b/tools/root/uisafebox.py deleted file mode 100644 index 1c608a00..00000000 --- a/tools/root/uisafebox.py +++ /dev/null @@ -1,710 +0,0 @@ -import ui -import mouseModule -import player -import net -import snd -import safebox -import chat -import app -import localeInfo -import uiScriptLocale - -class PasswordDialog(ui.ScriptWindow): - def __init__(self): - ui.ScriptWindow.__init__(self) - self.__LoadDialog() - - self.sendMessage = "/safebox_password " - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def __LoadDialog(self): - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "uiscript/passworddialog.py") - except: - import exception - exception.Abort("PasswordDialog.__LoadDialog.LoadObject") - - try: - self.passwordValue = self.GetChild("password_value") - self.acceptButton = self.GetChild("accept_button") - self.cancelButton = self.GetChild("cancel_button") - self.titleName = self.GetChild("TitleName") - self.GetChild("titlebar").SetCloseEvent(ui.__mem_func__(self.CloseDialog)) - except: - import exception - exception.Abort("PasswordDialog.__LoadDialog.BindObject") - - self.passwordValue.OnIMEReturn = self.OnAccept - self.passwordValue.OnPressEscapeKey = self.OnCancel - self.acceptButton.SetEvent(ui.__mem_func__(self.OnAccept)) - self.cancelButton.SetEvent(ui.__mem_func__(self.OnCancel)) - # MR-17: Set secret mode for password input - self.passwordValue.SetSecretMode(1) - # MR-17: -- END OF -- Set secret mode for password input - - def Destroy(self): - self.ClearDictionary() - self.passwordValue = None - self.acceptButton = None - self.cancelButton = None - self.titleName = None - - def SetTitle(self, title): - self.titleName.SetText(title) - - def SetSendMessage(self, msg): - self.sendMessage = msg - - def ShowDialog(self): - self.passwordValue.SetText("") - self.passwordValue.SetFocus() - self.SetCenterPosition() - self.Show() - - def CloseDialog(self): - self.passwordValue.KillFocus() - self.Hide() - - def OnAccept(self): - net.SendChatPacket(self.sendMessage + self.passwordValue.GetText()) - self.CloseDialog() - return True - - def OnCancel(self): - self.CloseDialog() - return True - -class ChangePasswordDialog(ui.ScriptWindow): - def __init__(self): - ui.ScriptWindow.__init__(self) - self.__LoadDialog() - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def __LoadDialog(self): - self.dlgMessage = ui.ScriptWindow() - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self.dlgMessage, "uiscript/popupdialog.py") - self.dlgMessage.GetChild("message").SetText(localeInfo.SAFEBOX_WRONG_PASSWORD) - self.dlgMessage.GetChild("accept").SetEvent(ui.__mem_func__(self.OnCloseMessageDialog)) - except: - import exception - exception.Abort("SafeboxWindow.__LoadDialog.LoadObject") - - def LoadDialog(self): - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "uiscript/changepassworddialog.py") - - except: - import exception - exception.Abort("ChangePasswordDialog.LoadDialog.LoadObject") - - try: - self.GetChild("accept_button").SetEvent(ui.__mem_func__(self.OnAccept)) - self.GetChild("cancel_button").SetEvent(ui.__mem_func__(self.OnCancel)) - self.GetChild("titlebar").SetCloseEvent(ui.__mem_func__(self.OnCancel)) - oldPassword = self.GetChild("old_password_value") - newPassword = self.GetChild("new_password_value") - newPasswordCheck = self.GetChild("new_password_check_value") - except: - import exception - exception.Abort("ChangePasswordDialog.LoadDialog.BindObject") - - oldPassword.SetTabEvent(lambda arg=1: self.OnNextFocus(arg)) - newPassword.SetTabEvent(lambda arg=2: self.OnNextFocus(arg)) - newPasswordCheck.SetTabEvent(lambda arg=3: self.OnNextFocus(arg)) - oldPassword.SetReturnEvent(lambda arg=1: self.OnNextFocus(arg)) - newPassword.SetReturnEvent(lambda arg=2: self.OnNextFocus(arg)) - newPasswordCheck.SetReturnEvent(ui.__mem_func__(self.OnAccept)) - oldPassword.OnPressEscapeKey = self.OnCancel - newPassword.OnPressEscapeKey = self.OnCancel - newPasswordCheck.OnPressEscapeKey = self.OnCancel - - # MR-17: Set secret mode for password input - oldPassword.SetSecretMode(1) - newPassword.SetSecretMode(1) - newPasswordCheck.SetSecretMode(1) - # MR-17: -- END OF -- Set secret mode for password input - - self.oldPassword = oldPassword - self.newPassword = newPassword - self.newPasswordCheck = newPasswordCheck - - def OnNextFocus(self, arg): - if 1 == arg: - self.oldPassword.KillFocus() - self.newPassword.SetFocus() - elif 2 == arg: - self.newPassword.KillFocus() - self.newPasswordCheck.SetFocus() - elif 3 == arg: - self.newPasswordCheck.KillFocus() - self.oldPassword.SetFocus() - - def Destroy(self): - self.ClearDictionary() - self.dlgMessage.ClearDictionary() - self.oldPassword = None - self.newPassword = None - self.newPasswordCheck = None - - def Open(self): - self.oldPassword.SetText("") - self.newPassword.SetText("") - self.newPasswordCheck.SetText("") - self.oldPassword.SetFocus() - self.SetCenterPosition() - self.SetTop() - self.Show() - - def Close(self): - self.oldPassword.SetText("") - self.newPassword.SetText("") - self.newPasswordCheck.SetText("") - self.oldPassword.KillFocus() - self.newPassword.KillFocus() - self.newPasswordCheck.KillFocus() - self.Hide() - - def OnAccept(self): - oldPasswordText = self.oldPassword.GetText() - newPasswordText = self.newPassword.GetText() - newPasswordCheckText = self.newPasswordCheck.GetText() - if newPasswordText != newPasswordCheckText: - self.dlgMessage.SetCenterPosition() - self.dlgMessage.SetTop() - self.dlgMessage.Show() - return True - net.SendChatPacket("/safebox_change_password %s %s" % (oldPasswordText, newPasswordText)) - self.Close() - return True - - def OnCancel(self): - self.Close() - return True - - def OnCloseMessageDialog(self): - self.newPassword.SetText("") - self.newPasswordCheck.SetText("") - self.newPassword.SetFocus() - self.dlgMessage.Hide() - -class SafeboxWindow(ui.ScriptWindow): - - BOX_WIDTH = 176 - - def __init__(self): - ui.ScriptWindow.__init__(self) - self.tooltipItem = None - self.sellingSlotNumber = -1 - self.pageButtonList = [] - self.curPageIndex = 0 - self.isLoaded = 0 - self.xSafeBoxStart = 0 - self.ySafeBoxStart = 0 - - self.__LoadWindow() - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def Show(self): - self.__LoadWindow() - - ui.ScriptWindow.Show(self) - - def Destroy(self): - self.ClearDictionary() - - self.dlgPickMoney.Destroy() - self.dlgPickMoney = None - self.dlgChangePassword.Destroy() - self.dlgChangePassword = None - - self.tooltipItem = None - self.wndMoneySlot = None - self.wndMoney = None - self.wndBoard = None - self.wndItem = None - - self.pageButtonList = [] - - def __LoadWindow(self): - if self.isLoaded == 1: - return - - self.isLoaded = 1 - - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "UIScript/SafeboxWindow.py") - - from _weakref import proxy - - ## Item - wndItem = ui.GridSlotWindow() - wndItem.SetParent(self) - wndItem.SetPosition(8, 35) - wndItem.SetSelectEmptySlotEvent(ui.__mem_func__(self.SelectEmptySlot)) - wndItem.SetSelectItemSlotEvent(ui.__mem_func__(self.SelectItemSlot)) - wndItem.SetUnselectItemSlotEvent(ui.__mem_func__(self.UseItemSlot)) - wndItem.SetUseSlotEvent(ui.__mem_func__(self.UseItemSlot)) - wndItem.SetOverInItemEvent(ui.__mem_func__(self.OverInItem)) - wndItem.SetOverOutItemEvent(ui.__mem_func__(self.OverOutItem)) - wndItem.Show() - - ## PickMoneyDialog - import uiPickMoney - dlgPickMoney = uiPickMoney.PickMoneyDialog() - dlgPickMoney.LoadDialog() - dlgPickMoney.SetAcceptEvent(ui.__mem_func__(self.OnPickMoney)) - dlgPickMoney.Hide() - - ## ChangePasswrod - dlgChangePassword = ChangePasswordDialog() - dlgChangePassword.LoadDialog() - dlgChangePassword.Hide() - - ## Close Button - self.GetChild("TitleBar").SetCloseEvent(ui.__mem_func__(self.Close)) - self.GetChild("ChangePasswordButton").SetEvent(ui.__mem_func__(self.OnChangePassword)) - self.GetChild("ExitButton").SetEvent(ui.__mem_func__(self.Close)) - - self.wndItem = wndItem - self.dlgPickMoney = dlgPickMoney - self.dlgChangePassword = dlgChangePassword - self.wndBoard = self.GetChild("board") - #self.wndMoney = self.GetChild("Money") - #self.wndMoneySlot = self.GetChild("Money_Slot") - #self.wndMoneySlot.SetEvent(ui.__mem_func__(self.OpenPickMoneyDialog)) - - ## Initialize - self.SetTableSize(3) - self.RefreshSafeboxMoney() - - def OpenPickMoneyDialog(self): - - if mouseModule.mouseController.isAttached(): - - attachedSlotPos = mouseModule.mouseController.GetAttachedSlotNumber() - if player.SLOT_TYPE_INVENTORY == mouseModule.mouseController.GetAttachedType(): - - if player.ITEM_MONEY == mouseModule.mouseController.GetAttachedItemIndex(): - net.SendSafeboxSaveMoneyPacket(mouseModule.mouseController.GetAttachedItemCount()) - snd.PlaySound("sound/ui/money.wav") - - mouseModule.mouseController.DeattachObject() - - else: - curMoney = safebox.GetMoney() - - if curMoney <= 0: - return - - self.dlgPickMoney.Open(curMoney) - - def ShowWindow(self, size): - - (self.xSafeBoxStart, self.ySafeBoxStart, z) = player.GetMainCharacterPosition() - - self.SetTableSize(size) - self.Show() - - def __MakePageButton(self, pageCount): - - self.curPageIndex = 0 - self.pageButtonList = [] - - text = "I" - pos = -int(float(pageCount-1) / 2 * 52) - - for i in range(pageCount): - button = ui.RadioButton() - - button.SetParent(self) - button.SetUpVisual("d:/ymir work/ui/game/windows/tab_button_middle_01.sub") - button.SetOverVisual("d:/ymir work/ui/game/windows/tab_button_middle_02.sub") - button.SetDownVisual("d:/ymir work/ui/game/windows/tab_button_middle_03.sub") - button.SetWindowHorizontalAlignCenter() - button.SetWindowVerticalAlignBottom() - button.SetPosition(pos, 85) - button.SetText(text) - button.SetEvent(lambda arg=i: self.SelectPage(arg)) - button.Show() - - self.pageButtonList.append(button) - - pos += 52 - text += "I" - - self.pageButtonList[0].Down() - - def SelectPage(self, index): - - self.curPageIndex = index - - for btn in self.pageButtonList: - btn.SetUp() - - self.pageButtonList[index].Down() - self.RefreshSafebox() - - def __LocalPosToGlobalPos(self, local): - return self.curPageIndex * safebox.SAFEBOX_PAGE_SIZE + local - - def SetTableSize(self, size): - - pageCount = max(1, size // safebox.SAFEBOX_SLOT_Y_COUNT) - pageCount = min(3, pageCount) - size = safebox.SAFEBOX_SLOT_Y_COUNT - - self.__MakePageButton(pageCount) - - self.wndItem.ArrangeSlot(0, safebox.SAFEBOX_SLOT_X_COUNT, size, 32, 32, 0, 0) - self.wndItem.RefreshSlot() - self.wndItem.SetSlotBaseImage("d:/ymir work/ui/public/Slot_Base.sub", 1.0, 1.0, 1.0, 1.0) - - wnd_height = 130 + 32 * size - - self.wndBoard.SetSize(self.BOX_WIDTH, wnd_height) - self.SetSize(self.BOX_WIDTH, wnd_height) - self.UpdateRect() - - def RefreshSafebox(self): - getItemID=safebox.GetItemID - getItemCount=safebox.GetItemCount - setItemID=self.wndItem.SetItemSlot - - for i in range(safebox.SAFEBOX_PAGE_SIZE): - slotIndex = self.__LocalPosToGlobalPos(i) - itemCount = getItemCount(slotIndex) - if itemCount <= 1: - itemCount = 0 - setItemID(i, getItemID(slotIndex), itemCount) - - self.wndItem.RefreshSlot() - - def RefreshSafeboxMoney(self): - pass - #self.wndMoney.SetText(str(safebox.GetMoney())) - - def SetItemToolTip(self, tooltip): - self.tooltipItem = tooltip - - def Close(self): - net.SendChatPacket("/safebox_close") - - def CommandCloseSafebox(self): - if self.tooltipItem: - self.tooltipItem.HideToolTip() - - self.dlgPickMoney.Close() - self.dlgChangePassword.Close() - self.Hide() - - ## Slot Event - def SelectEmptySlot(self, selectedSlotPos): - import constInfo - - selectedSlotPos = self.__LocalPosToGlobalPos(selectedSlotPos) - - if mouseModule.mouseController.isAttached(): - attachedSlotType = mouseModule.mouseController.GetAttachedType() - attachedSlotPos = mouseModule.mouseController.GetAttachedSlotNumber() - - # MR-3: Auto-deactivate auto potions before moving out - # Deactivate inventory slot if it's an active auto potion before moving out - if attachedSlotType == player.SLOT_TYPE_INVENTORY: - itemVnum = player.GetItemIndex(attachedSlotPos) - - if constInfo.IS_AUTO_POTION(itemVnum): - metinSocket = [player.GetItemMetinSocket(attachedSlotPos, j) for j in range(player.METIN_SOCKET_MAX_NUM)] - isActivated = (0 != int(metinSocket[0])) - - if isActivated: - net.SendItemUsePacket(attachedSlotPos) - # MR-3: -- END OF -- Auto-deactivate auto potions before moving out - - if player.SLOT_TYPE_SAFEBOX == attachedSlotType: - net.SendSafeboxItemMovePacket(attachedSlotPos, selectedSlotPos, 0) - #snd.PlaySound("sound/ui/drop.wav") - else: - attachedInvenType = player.SlotTypeToInvenType(attachedSlotType) - - if player.RESERVED_WINDOW == attachedInvenType: - return - - if player.ITEM_MONEY == mouseModule.mouseController.GetAttachedItemIndex(): - net.SendSafeboxSaveMoneyPacket(mouseModule.mouseController.GetAttachedItemCount()) - snd.PlaySound("sound/ui/money.wav") - else: - net.SendSafeboxCheckinPacket(attachedInvenType, attachedSlotPos, selectedSlotPos) - #snd.PlaySound("sound/ui/drop.wav") - - mouseModule.mouseController.DeattachObject() - - def SelectItemSlot(self, selectedSlotPos): - selectedSlotPos = self.__LocalPosToGlobalPos(selectedSlotPos) - - if mouseModule.mouseController.isAttached(): - attachedSlotType = mouseModule.mouseController.GetAttachedType() - - if player.SLOT_TYPE_INVENTORY == attachedSlotType: - - if player.ITEM_MONEY == mouseModule.mouseController.GetAttachedItemIndex(): - net.SendSafeboxSaveMoneyPacket(mouseModule.mouseController.GetAttachedItemCount()) - snd.PlaySound("sound/ui/money.wav") - - else: - attachedSlotPos = mouseModule.mouseController.GetAttachedSlotNumber() - #net.SendSafeboxCheckinPacket(attachedSlotPos, selectedSlotPos) - #snd.PlaySound("sound/ui/drop.wav") - - mouseModule.mouseController.DeattachObject() - - else: - - curCursorNum = app.GetCursor() - - if app.SELL == curCursorNum: - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.SAFEBOX_SELL_DISABLE_SAFEITEM) - - elif app.BUY == curCursorNum: - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.SHOP_BUY_INFO) - - else: - selectedItemID = safebox.GetItemID(selectedSlotPos) - mouseModule.mouseController.AttachObject(self, player.SLOT_TYPE_SAFEBOX, selectedSlotPos, selectedItemID) - snd.PlaySound("sound/ui/pick.wav") - - def UseItemSlot(self, slotIndex): - mouseModule.mouseController.DeattachObject() - - def __ShowToolTip(self, slotIndex): - if self.tooltipItem: - self.tooltipItem.SetSafeBoxItem(slotIndex) - - def OverInItem(self, slotIndex): - slotIndex = self.__LocalPosToGlobalPos(slotIndex) - self.wndItem.SetUsableItem(False) - self.__ShowToolTip(slotIndex) - - def OverOutItem(self): - self.wndItem.SetUsableItem(False) - if self.tooltipItem: - self.tooltipItem.HideToolTip() - - def OnPickMoney(self, money): - mouseModule.mouseController.AttachMoney(self, player.SLOT_TYPE_SAFEBOX, money) - - def OnChangePassword(self): - self.dlgChangePassword.Open() - - def OnPressEscapeKey(self): - self.Close() - return True - - def OnUpdate(self): - - USE_SAFEBOX_LIMIT_RANGE = 1000 - - (x, y, z) = player.GetMainCharacterPosition() - if abs(x - self.xSafeBoxStart) > USE_SAFEBOX_LIMIT_RANGE or abs(y - self.ySafeBoxStart) > USE_SAFEBOX_LIMIT_RANGE: - self.Close() - -class MallWindow(ui.ScriptWindow): - - BOX_WIDTH = 176 - - def __init__(self): - ui.ScriptWindow.__init__(self) - self.tooltipItem = None - self.sellingSlotNumber = -1 - self.pageButtonList = [] - self.curPageIndex = 0 - self.isLoaded = 0 - self.xSafeBoxStart = 0 - self.ySafeBoxStart = 0 - - self.__LoadWindow() - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def Show(self): - self.__LoadWindow() - - ui.ScriptWindow.Show(self) - - def Destroy(self): - self.ClearDictionary() - - self.tooltipItem = None - self.wndBoard = None - self.wndItem = None - - self.pageButtonList = [] - - def __LoadWindow(self): - if self.isLoaded == 1: - return - - self.isLoaded = 1 - - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "UIScript/MallWindow.py") - - from _weakref import proxy - - ## Item - wndItem = ui.GridSlotWindow() - wndItem.SetParent(self) - wndItem.SetPosition(8, 35) - wndItem.SetSelectEmptySlotEvent(ui.__mem_func__(self.SelectEmptySlot)) - wndItem.SetSelectItemSlotEvent(ui.__mem_func__(self.SelectItemSlot)) - wndItem.SetUnselectItemSlotEvent(ui.__mem_func__(self.UseItemSlot)) - wndItem.SetUseSlotEvent(ui.__mem_func__(self.UseItemSlot)) - wndItem.SetOverInItemEvent(ui.__mem_func__(self.OverInItem)) - wndItem.SetOverOutItemEvent(ui.__mem_func__(self.OverOutItem)) - wndItem.Show() - - ## Close Button - self.GetChild("TitleBar").SetCloseEvent(ui.__mem_func__(self.Close)) - self.GetChild("ExitButton").SetEvent(ui.__mem_func__(self.Close)) - - self.wndItem = wndItem - self.wndBoard = self.GetChild("board") - - ## Initialize - self.SetTableSize(3) - - def ShowWindow(self, size): - - (self.xSafeBoxStart, self.ySafeBoxStart, z) = player.GetMainCharacterPosition() - - self.SetTableSize(size) - self.Show() - - def SetTableSize(self, size): - - pageCount = max(1, size // safebox.SAFEBOX_SLOT_Y_COUNT) - pageCount = min(3, pageCount) - size = safebox.SAFEBOX_SLOT_Y_COUNT - - self.wndItem.ArrangeSlot(0, safebox.SAFEBOX_SLOT_X_COUNT, size, 32, 32, 0, 0) - self.wndItem.RefreshSlot() - self.wndItem.SetSlotBaseImage("d:/ymir work/ui/public/Slot_Base.sub", 1.0, 1.0, 1.0, 1.0) - - self.wndBoard.SetSize(self.BOX_WIDTH, 82 + 32 * size) - self.SetSize(self.BOX_WIDTH, 85 + 32 * size) - self.UpdateRect() - - def RefreshMall(self): - getItemID = safebox.GetMallItemID - getItemCount = safebox.GetMallItemCount - setItemID = self.wndItem.SetItemSlot - - for i in range(safebox.GetMallSize()): - itemID = getItemID(i) - itemCount = getItemCount(i) - - if itemCount <= 1: - itemCount = 0 - - setItemID(i, itemID, itemCount) - - self.wndItem.RefreshSlot() - - def SetItemToolTip(self, tooltip): - self.tooltipItem = tooltip - - def Close(self): - net.SendChatPacket("/mall_close") - - def CommandCloseMall(self): - if self.tooltipItem: - self.tooltipItem.HideToolTip() - - self.Hide() - - ## Slot Event - def SelectEmptySlot(self, selectedSlotPos): - - if mouseModule.mouseController.isAttached(): - - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.MALL_CANNOT_INSERT) - mouseModule.mouseController.DeattachObject() - - def SelectItemSlot(self, selectedSlotPos): - - if mouseModule.mouseController.isAttached(): - - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.MALL_CANNOT_INSERT) - mouseModule.mouseController.DeattachObject() - - else: - - curCursorNum = app.GetCursor() - selectedItemID = safebox.GetMallItemID(selectedSlotPos) - mouseModule.mouseController.AttachObject(self, player.SLOT_TYPE_MALL, selectedSlotPos, selectedItemID) - snd.PlaySound("sound/ui/pick.wav") - - def UseItemSlot(self, slotIndex): - mouseModule.mouseController.DeattachObject() - - def __ShowToolTip(self, slotIndex): - if self.tooltipItem: - self.tooltipItem.SetMallItem(slotIndex) - - def OverInItem(self, slotIndex): - self.__ShowToolTip(slotIndex) - - def OverOutItem(self): - self.wndItem.SetUsableItem(False) - if self.tooltipItem: - self.tooltipItem.HideToolTip() - - def OnPressEscapeKey(self): - self.Close() - return True - - def OnUpdate(self): - - USE_SAFEBOX_LIMIT_RANGE = 1000 - - (x, y, z) = player.GetMainCharacterPosition() - if abs(x - self.xSafeBoxStart) > USE_SAFEBOX_LIMIT_RANGE or abs(y - self.ySafeBoxStart) > USE_SAFEBOX_LIMIT_RANGE: - self.Close() - - -if __name__ == "__main__": - - import app - import wndMgr - import systemSetting - import mouseModule - import grp - import ui - import chr - import background - import player - - #wndMgr.SetOutlineFlag(True) - - app.SetMouseHandler(mouseModule.mouseController) - app.SetHairColorEnable(True) - wndMgr.SetMouseHandler(mouseModule.mouseController) - wndMgr.SetScreenSize(systemSetting.GetWidth(), systemSetting.GetHeight()) - app.Create("METIN2 CLOSED BETA", systemSetting.GetWidth(), systemSetting.GetHeight(), 1) - mouseModule.mouseController.Create() - - - wnd = SafeboxWindow() - wnd.ShowWindow(1) - - app.Loop() diff --git a/tools/root/uiscriptlocale.py b/tools/root/uiscriptlocale.py deleted file mode 100644 index 542dda1b..00000000 --- a/tools/root/uiscriptlocale.py +++ /dev/null @@ -1,103 +0,0 @@ -import app - -AUTOBAN_QUIZ_ANSWER = "ANSWER" -AUTOBAN_QUIZ_REFRESH = "REFRESH" -AUTOBAN_QUIZ_REST_TIME = "REST_TIME" - -OPTION_SHADOW = "SHADOW" - -#CUBE_TITLE = "Cube Window" - -def LoadLocaleFile(srcFileName, localeDict): - localeDict["CUBE_INFO_TITLE"] = "Recipe" - localeDict["CUBE_REQUIRE_MATERIAL"] = "Requirements" - localeDict["CUBE_REQUIRE_MATERIAL_OR"] = "or" - - try: - lines = pack_open(srcFileName, "r").readlines() - except IOError: - import dbg - dbg.LogBox("LoadUIScriptLocaleError(%(srcFileName)s)" % locals()) - app.Abort() - - for line in lines: - tokens = line[:-1].split("\t") - - if len(tokens) >= 2: - localeDict[tokens[0]] = tokens[1] - else: - print((len(tokens), lines.index(line), line)) - -name = app.GetLocalePath() -LOCALE_UISCRIPT_PATH = "%s/ui/" % (name) -LOGIN_PATH = "%s/ui/login/" % (name) -EMPIRE_PATH = "%s/ui/empire/" % (name) -GUILD_PATH = "%s/ui/guild/" % (name) -SELECT_PATH = "%s/ui/select/" % (name) -WINDOWS_PATH = "%s/ui/windows/" % (name) -MAPNAME_PATH = "%s/ui/mapname/" % (name) - -JOBDESC_WARRIOR_PATH = "%s/jobdesc_warrior.txt" % (name) -JOBDESC_ASSASSIN_PATH = "%s/jobdesc_assassin.txt" % (name) -JOBDESC_SURA_PATH = "%s/jobdesc_sura.txt" % (name) -JOBDESC_SHAMAN_PATH = "%s/jobdesc_shaman.txt" % (name) - -EMPIREDESC_A = "%s/empiredesc_a.txt" % (name) -EMPIREDESC_B = "%s/empiredesc_b.txt" % (name) -EMPIREDESC_C = "%s/empiredesc_c.txt" % (name) - -LOCALE_INTERFACE_FILE_NAME = "%s/locale_interface.txt" % (name) -LoadLocaleFile(LOCALE_INTERFACE_FILE_NAME, globals()) - -def LoadLocaleData(): - """ - Reload all UI locale strings from locale_interface.txt - - Called by app.ReloadLocale() when the user changes language. - Updates all locale-dependent paths and reloads locale_interface.txt. - - This is the LAST Python module reloaded by the C++ reload chain, - so it fires localeInfo.FireReloadCallbacks() at the end to notify - all modules that both localeInfo and uiScriptLocale are fully loaded. - - Returns: - True on success, False on failure - """ - try: - # Update all locale-dependent paths - global name, LOCALE_UISCRIPT_PATH, LOGIN_PATH, EMPIRE_PATH, GUILD_PATH, SELECT_PATH, WINDOWS_PATH, MAPNAME_PATH - global JOBDESC_WARRIOR_PATH, JOBDESC_ASSASSIN_PATH, JOBDESC_SURA_PATH, JOBDESC_SHAMAN_PATH - global EMPIREDESC_A, EMPIREDESC_B, EMPIREDESC_C, LOCALE_INTERFACE_FILE_NAME - - name = app.GetLocalePath() - LOCALE_UISCRIPT_PATH = "%s/ui/" % (name) - LOGIN_PATH = "%s/ui/login/" % (name) - EMPIRE_PATH = "%s/ui/empire/" % (name) - GUILD_PATH = "%s/ui/guild/" % (name) - SELECT_PATH = "%s/ui/select/" % (name) - WINDOWS_PATH = "%s/ui/windows/" % (name) - MAPNAME_PATH = "%s/ui/mapname/" % (name) - - JOBDESC_WARRIOR_PATH = "%s/jobdesc_warrior.txt" % (name) - JOBDESC_ASSASSIN_PATH = "%s/jobdesc_assassin.txt" % (name) - JOBDESC_SURA_PATH = "%s/jobdesc_sura.txt" % (name) - JOBDESC_SHAMAN_PATH = "%s/jobdesc_shaman.txt" % (name) - - EMPIREDESC_A = "%s/empiredesc_a.txt" % (name) - EMPIREDESC_B = "%s/empiredesc_b.txt" % (name) - EMPIREDESC_C = "%s/empiredesc_c.txt" % (name) - - LOCALE_INTERFACE_FILE_NAME = "%s/locale_interface.txt" % (name) - - # Reload locale_interface.txt - this updates all UI strings - LoadLocaleFile(LOCALE_INTERFACE_FILE_NAME, globals()) - - # Fire reload callbacks now that BOTH modules are fully loaded - import localeInfo - localeInfo.FireReloadCallbacks() - - return True - except Exception as e: - import dbg - dbg.TraceError("uiScriptLocale.LoadLocaleData failed: %s" % str(e)) - return False \ No newline at end of file diff --git a/tools/root/uiselectitem.py b/tools/root/uiselectitem.py deleted file mode 100644 index 55896738..00000000 --- a/tools/root/uiselectitem.py +++ /dev/null @@ -1,139 +0,0 @@ -import ui -import player -import item -import wndMgr -import net - -class SelectItemWindow(ui.ScriptWindow): - - def __init__(self): - ui.ScriptWindow.__init__(self) - - self.tooltipItem = None - self.inventorySlotPosDict = {} - - self.LoadWindow() - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def LoadWindow(self): - try: - PythonScriptLoader = ui.PythonScriptLoader() - PythonScriptLoader.LoadScriptFile(self, "UIScript/selectitemwindow.py") - except: - import exception - exception.Abort("ItemSelectWindow.LoadDialog.LoadObject") - - try: - GetObject = self.GetChild - self.board = GetObject("board") - self.titleBar = GetObject("TitleBar") - self.itemSlot = GetObject("ItemSlot") - self.btnExit = GetObject("ExitButton") - except: - import exception - exception.Abort("ItemSelectWindow.LoadDialog.BindObject") - - self.titleBar.SetCloseEvent(ui.__mem_func__(self.Close)) - self.btnExit.SetEvent(ui.__mem_func__(self.Close)) - self.itemSlot.SetSlotStyle(wndMgr.SLOT_STYLE_NONE) - self.itemSlot.SAFE_SetButtonEvent("LEFT", "EXIST", self.SelectItemSlot) - self.itemSlot.SetOverInItemEvent(ui.__mem_func__(self.OverInItem)) - self.itemSlot.SetOverOutItemEvent(ui.__mem_func__(self.OverOutItem)) - - def Open(self): - self.RefreshSlot() - self.Show() - - def Close(self): - wndMgr.OnceIgnoreMouseLeftButtonUpEvent() - net.SendSelectItemPacket(0) - self.Hide() - - def SetItemToolTip(self, tooltipItem): - self.tooltipItem = tooltipItem - - def SelectItemSlot(self, slotPos): - wndMgr.OnceIgnoreMouseLeftButtonUpEvent() - inventorySlotPos = self.inventorySlotPosDict[slotPos] - net.SendSelectItemPacket(inventorySlotPos) - self.Hide() - - def SetTableSize(self, size): - - SLOT_X_COUNT = 5 - self.itemSlot.ArrangeSlot(0, SLOT_X_COUNT, size, 32, 32, 0, 0) - self.itemSlot.RefreshSlot() - self.itemSlot.SetSlotBaseImage("d:/ymir work/ui/public/Slot_Base.sub", 1.0, 1.0, 1.0, 1.0) - - self.board.SetSize(self.board.GetWidth(), 76 + 32*size) - self.SetSize(self.board.GetWidth(), 76 + 32*size) - self.UpdateRect() - - def RefreshSlot(self): - - slotPos = 0 - self.inventorySlotPosDict = {} - - getItemVNum=player.GetItemIndex - getItemCount=player.GetItemCount - setItemVNum=self.itemSlot.SetItemSlot - - for i in range(player.INVENTORY_PAGE_SIZE*2): - slotNumber = i - - itemVNum = getItemVNum(slotNumber) - - if 0 == itemVNum: - continue - - if not item.IsMetin(itemVNum): - continue - - itemGrade = player.GetItemGrade(slotNumber) - - if itemGrade > 2: - continue - - self.inventorySlotPosDict[slotPos] = i - - slotPos += 1 - - if slotPos > 54: - break - - itemCount = len(self.inventorySlotPosDict) - - if itemCount < 15: - self.SetTableSize(3) - - else: - lineCount = 3 - lineCount += (itemCount - 15) // 5 - - if itemCount % 5: - lineCount += 1 - - self.SetTableSize(lineCount) - - for selectWndPos, inventoryPos in list(self.inventorySlotPosDict.items()): - itemVNum = getItemVNum(inventoryPos) - itemCount = getItemCount(inventoryPos) - - if itemCount <= 1: - itemCount = 0 - - setItemVNum(selectWndPos, itemVNum, itemCount) - - self.itemSlot.RefreshSlot() - - def OverOutItem(self): - if None != self.tooltipItem: - self.tooltipItem.HideToolTip() - - def OverInItem(self, slotIndex): - if None != self.tooltipItem: - inventorySlotPos = self.inventorySlotPosDict[slotIndex] - self.tooltipItem.SetInventoryItem(inventorySlotPos) - diff --git a/tools/root/uiselectmusic.py b/tools/root/uiselectmusic.py deleted file mode 100644 index 26bd5e32..00000000 --- a/tools/root/uiselectmusic.py +++ /dev/null @@ -1,213 +0,0 @@ -import app -import ui -import localeInfo -import uiScriptLocale - -FILE_NAME_LEN = 20 -DEFAULT_THEMA = "" - -def _RebuildLocaleStrings(): - global DEFAULT_THEMA - DEFAULT_THEMA = localeInfo.MUSIC_METIN2_DEFAULT_THEMA - -_RebuildLocaleStrings() -localeInfo.RegisterReloadCallback(_RebuildLocaleStrings) - -class Item(ui.ListBoxEx.Item): - def __init__(self, fileName): - ui.ListBoxEx.Item.__init__(self) - self.canLoad=0 - self.text=fileName - self.textLine=self.__CreateTextLine(fileName[:FILE_NAME_LEN]) - - def __del__(self): - ui.ListBoxEx.Item.__del__(self) - - def GetText(self): - return self.text - - def SetSize(self, width, height): - ui.ListBoxEx.Item.SetSize(self, 6*len(self.textLine.GetText()) + 4, height) - - def __CreateTextLine(self, fileName): - textLine=ui.TextLine() - textLine.SetParent(self) - - if app.IsRTL(): - textLine.SetPosition(6*len(fileName) + 6, 0) - else: - textLine.SetPosition(0, 0) - - textLine.SetText(fileName) - textLine.Show() - return textLine - -class PopupDialog(ui.ScriptWindow): - def __init__(self, parent): - print("NEW POPUP WINDOW ----------------------------------------------------------------------------") - ui.ScriptWindow.__init__(self) - - self.__Load() - self.__Bind() - - def __del__(self): - ui.ScriptWindow.__del__(self) - print("---------------------------------------------------------------------------- DELETE POPUP WINDOW") - - def __Load(self): - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "UIScript/PopupDialog.py") - except: - import exception - exception.Abort("PopupDialog.__Load") - - def __Bind(self): - try: - self.textLine=self.GetChild("message") - self.okButton=self.GetChild("accept") - except: - import exception - exception.Abort("PopupDialog.__Bind") - - self.okButton.SAFE_SetEvent(self.__OnOK) - - def Open(self, msg): - self.textLine.SetText(msg) - self.SetCenterPosition() - self.Show() - self.SetTop() - - def __OnOK(self): - self.Hide() - -class FileListDialog(ui.ScriptWindow): - def __init__(self): - print("NEW LIST DIALOG ----------------------------------------------------------------------------") - ui.ScriptWindow.__init__(self) - - self.isLoaded=0 - self.selectEvent=None - self.fileListBox=None - - def __del__(self): - ui.ScriptWindow.__del__(self) - print("---------------------------------------------------------------------------- DELETE LIST DIALOG") - - def Show(self): - if self.isLoaded==0: - self.isLoaded=1 - - self.__Load() - - ui.ScriptWindow.Show(self) - - def Open(self): - self.Show() - - self.SetCenterPosition() - self.SetTop() - - if self.fileListBox.IsEmpty(): - self.__PopupMessage(localeInfo.MUSIC_EMPTY_MUSIC_LIST) - - def Close(self): - self.popupDialog.Hide() - self.Hide() - - def OnPressEscapeKey(self): - self.Close() - return True - - def SAFE_SetSelectEvent(self, event): - self.selectEvent=ui.__mem_func__(event) - - def __CreateFileListBox(self): - fileListBox=ui.ListBoxEx() - fileListBox.SetParent(self) - - if app.IsRTL(): - fileListBox.SetPosition( self.GetWidth() - fileListBox.GetWidth() - 10, 50) - else: - fileListBox.SetPosition(15, 50) - - fileListBox.Show() - return fileListBox - - def __Load(self): - self.popupDialog=PopupDialog(self) - - if app.IsRTL(): - self.__Load_LoadScript(uiScriptLocale.LOCALE_UISCRIPT_PATH + "MusicListWindow.py") - else: - self.__Load_LoadScript("UIScript/MusicListWindow.py") - - self.__Load_BindObject() - - self.refreshButton.SAFE_SetEvent(self.__OnRefresh) - self.cancelButton.SAFE_SetEvent(self.__OnCancel) - self.okButton.SAFE_SetEvent(self.__OnOK) - self.board.SetCloseEvent(ui.__mem_func__(self.__OnCancel)) - self.UpdateRect() - - self.__RefreshFileList() - - def __Load_LoadScript(self, fileName): - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, fileName) - except: - import exception - exception.Abort("MusicListBox.__Load") - - def __Load_BindObject(self): - try: - self.fileListBox=self.__CreateFileListBox() - self.fileListBox.SetScrollBar(self.GetChild("ScrollBar")) - - self.board=self.GetChild("board") - self.okButton=self.GetChild("ok") - self.cancelButton=self.GetChild("cancel") - self.refreshButton=self.GetChild("refresh") - - self.popupText = self.popupDialog.GetChild("message") - - except: - import exception - exception.Abort("MusicListBox.__Bind") - - def __PopupMessage(self, msg): - self.popupDialog.Open(msg) - - def __OnOK(self): - selItem=self.fileListBox.GetSelectedItem() - if selItem: - if self.selectEvent: - self.selectEvent(selItem.GetText()) - self.Hide() - else: - self.__PopupMessage(localeInfo.MUSIC_NOT_SELECT_MUSIC) - - def __OnCancel(self): - self.Hide() - - def __OnRefresh(self): - self.__RefreshFileList() - - def __RefreshFileList(self): - self.__ClearFileList() - self.__AppendFile(DEFAULT_THEMA) - self.__AppendFileList("mp3") - - def __ClearFileList(self): - self.fileListBox.RemoveAllItems() - - def __AppendFileList(self, filter): - fileNameList=app.GetFileList("BGM/*."+filter) - for fileName in fileNameList: - self.__AppendFile(fileName) - - def __AppendFile(self, fileName): - self.fileListBox.AppendItem(Item(fileName)) - - diff --git a/tools/root/uishop.py b/tools/root/uishop.py deleted file mode 100644 index 361b73fa..00000000 --- a/tools/root/uishop.py +++ /dev/null @@ -1,495 +0,0 @@ -import net -import player -import item -import snd -import shop -import net -import wndMgr -import app -import chat - -import ui -import uiCommon -import mouseModule -import localeInfo -import constInfo - -################################################################################################### -## Shop -class ShopDialog(ui.ScriptWindow): - - def __init__(self): - ui.ScriptWindow.__init__(self) - self.tooltipItem = 0 - self.xShopStart = 0 - self.yShopStart = 0 - self.questionDialog = None - self.popup = None - self.itemBuyQuestionDialog = None - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def __GetRealIndex(self, i): - return self.tabIdx * shop.SHOP_SLOT_COUNT + i - - def Refresh(self): - getItemID=shop.GetItemID - getItemCount=shop.GetItemCount - setItemID=self.itemSlotWindow.SetItemSlot - for i in range(shop.SHOP_SLOT_COUNT): - idx = self.__GetRealIndex(i) - itemCount = getItemCount(idx) - if itemCount <= 1: - itemCount = 0 - setItemID(i, getItemID(idx), itemCount) - - wndMgr.RefreshSlot(self.itemSlotWindow.GetWindowHandle()) - - def SetItemData(self, pos, itemID, itemCount, itemPrice): - shop.SetItemData(pos, itemID, itemCount, itemPrice) - - def LoadDialog(self): - try: - PythonScriptLoader = ui.PythonScriptLoader() - PythonScriptLoader.LoadScriptFile(self, "UIScript/shopdialog.py") - except: - import exception - exception.Abort("ShopDialog.LoadDialog.LoadObject") - - smallTab1 = None - smallTab2 = None - smallTab3 = None - middleTab1 = None - middleTab2 = None - - try: - GetObject = self.GetChild - self.itemSlotWindow = GetObject("ItemSlot") - self.btnBuy = GetObject("BuyButton") - self.btnSell = GetObject("SellButton") - self.btnClose = GetObject("CloseButton") - self.titleBar = GetObject("TitleBar") - middleTab1 = GetObject("MiddleTab1") - middleTab2 = GetObject("MiddleTab2") - smallTab1 = GetObject("SmallTab1") - smallTab2 = GetObject("SmallTab2") - smallTab3 = GetObject("SmallTab3") - except: - import exception - exception.Abort("ShopDialog.LoadDialog.BindObject") - - self.itemSlotWindow.SetSlotStyle(wndMgr.SLOT_STYLE_NONE) - self.itemSlotWindow.SAFE_SetButtonEvent("LEFT", "EMPTY", self.SelectEmptySlot) - self.itemSlotWindow.SAFE_SetButtonEvent("LEFT", "EXIST", self.SelectItemSlot) - self.itemSlotWindow.SAFE_SetButtonEvent("RIGHT", "EXIST", self.UnselectItemSlot) - - self.itemSlotWindow.SetOverInItemEvent(ui.__mem_func__(self.OverInItem)) - self.itemSlotWindow.SetOverOutItemEvent(ui.__mem_func__(self.OverOutItem)) - - self.btnBuy.SetToggleUpEvent(ui.__mem_func__(self.CancelShopping)) - self.btnBuy.SetToggleDownEvent(ui.__mem_func__(self.OnBuy)) - - self.btnSell.SetToggleUpEvent(ui.__mem_func__(self.CancelShopping)) - self.btnSell.SetToggleDownEvent(ui.__mem_func__(self.OnSell)) - - self.btnClose.SetEvent(ui.__mem_func__(self.AskClosePrivateShop)) - - self.titleBar.SetCloseEvent(ui.__mem_func__(self.Close)) - - self.smallRadioButtonGroup = ui.RadioButtonGroup.Create([[smallTab1, lambda : self.OnClickTabButton(0), None], [smallTab2, lambda : self.OnClickTabButton(1), None], [smallTab3, lambda : self.OnClickTabButton(2), None]]) - self.middleRadioButtonGroup = ui.RadioButtonGroup.Create([[middleTab1, lambda : self.OnClickTabButton(0), None], [middleTab2, lambda : self.OnClickTabButton(1), None]]) - - self.__HideMiddleTabs() - self.__HideSmallTabs() - - self.tabIdx = 0 - self.coinType = shop.SHOP_COIN_TYPE_GOLD - - self.Refresh() - - def __ShowBuySellButton(self): - self.btnBuy.Show() - self.btnSell.Show() - - def __ShowMiddleTabs(self): - self.middleRadioButtonGroup.Show() - - def __ShowSmallTabs(self): - self.smallRadioButtonGroup.Show() - - def __HideBuySellButton(self): - self.btnBuy.Hide() - self.btnSell.Hide() - - def __HideMiddleTabs(self): - self.middleRadioButtonGroup.Hide() - - def __HideSmallTabs(self): - self.smallRadioButtonGroup.Hide() - - def __SetTabNames(self): - if shop.GetTabCount() == 2: - self.middleRadioButtonGroup.SetText(0, shop.GetTabName(0)) - self.middleRadioButtonGroup.SetText(1, shop.GetTabName(1)) - elif shop.GetTabCount() == 3: - self.smallRadioButtonGroup.SetText(0, shop.GetTabName(0)) - self.smallRadioButtonGroup.SetText(1, shop.GetTabName(1)) - self.smallRadioButtonGroup.SetText(2, shop.GetTabName(2)) - - - def Destroy(self): - self.Close() - self.ClearDictionary() - - self.tooltipItem = 0 - self.itemSlotWindow = 0 - self.btnBuy = 0 - self.btnSell = 0 - self.btnClose = 0 - self.titleBar = 0 - self.questionDialog = None - self.popup = None - - def Open(self, vid): - - isPrivateShop = False - isMainPlayerPrivateShop = False - - import chr - if chr.IsNPC(vid): - isPrivateShop = False - else: - isPrivateShop = True - - if player.IsMainCharacterIndex(vid): - - isMainPlayerPrivateShop = True - - self.btnBuy.Hide() - self.btnSell.Hide() - self.btnClose.Show() - - else: - - isMainPlayerPrivateShop = False - - self.btnBuy.Show() - self.btnSell.Show() - self.btnClose.Hide() - - shop.Open(isPrivateShop, isMainPlayerPrivateShop) - - self.tabIdx = 0 - - if isPrivateShop: - self.__HideMiddleTabs() - self.__HideSmallTabs() - else: - if shop.GetTabCount() == 1: - self.__ShowBuySellButton() - self.__HideMiddleTabs() - self.__HideSmallTabs() - elif shop.GetTabCount() == 2: - self.__HideBuySellButton() - self.__ShowMiddleTabs() - self.__HideSmallTabs() - self.__SetTabNames() - self.middleRadioButtonGroup.OnClick(0) - elif shop.GetTabCount() == 3: - self.__HideBuySellButton() - self.__HideMiddleTabs() - self.__ShowSmallTabs() - self.__SetTabNames() - self.middleRadioButtonGroup.OnClick(1) - - self.Refresh() - self.SetTop() - - self.Show() - - (self.xShopStart, self.yShopStart, z) = player.GetMainCharacterPosition() - - def Close(self): - if self.itemBuyQuestionDialog: - self.itemBuyQuestionDialog.Close() - self.itemBuyQuestionDialog = None - constInfo.SET_ITEM_QUESTION_DIALOG_STATUS(0) - if self.questionDialog: - self.OnCloseQuestionDialog() - shop.Close() - net.SendShopEndPacket() - self.CancelShopping() - self.tooltipItem.HideToolTip() - self.Hide() - - def GetIndexFromSlotPos(self, slotPos): - return self.tabIdx * shop.SHOP_SLOT_COUNT + slotPos - - def OnClickTabButton(self, idx): - self.tabIdx = idx - self.Refresh() - - def AskClosePrivateShop(self): - questionDialog = uiCommon.QuestionDialog() - questionDialog.SetText(localeInfo.PRIVATE_SHOP_CLOSE_QUESTION) - questionDialog.SetAcceptEvent(ui.__mem_func__(self.OnClosePrivateShop)) - questionDialog.SetCancelEvent(ui.__mem_func__(self.OnCloseQuestionDialog)) - questionDialog.Open() - self.questionDialog = questionDialog - - constInfo.SET_ITEM_QUESTION_DIALOG_STATUS(1) - - return True - - def OnClosePrivateShop(self): - net.SendChatPacket("/close_shop") - self.OnCloseQuestionDialog() - return True - - def OnPressEscapeKey(self): - self.Close() - return True - - def OnPressExitKey(self): - self.Close() - return True - - def OnBuy(self): - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.SHOP_BUY_INFO) - app.SetCursor(app.BUY) - self.btnSell.SetUp() - - def OnSell(self): - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.SHOP_SELL_INFO) - app.SetCursor(app.SELL) - self.btnBuy.SetUp() - - def CancelShopping(self): - self.btnBuy.SetUp() - self.btnSell.SetUp() - app.SetCursor(app.NORMAL) - - def __OnClosePopupDialog(self): - self.pop = None - constInfo.SET_ITEM_QUESTION_DIALOG_STATUS(0) - - ## 용혼석 팔리는 기능 추가. - def SellAttachedItem(self): - - if shop.IsPrivateShop(): - mouseModule.mouseController.DeattachObject() - return - - attachedSlotType = mouseModule.mouseController.GetAttachedType() - attachedSlotPos = mouseModule.mouseController.GetAttachedSlotNumber() - attachedCount = mouseModule.mouseController.GetAttachedItemCount() - attachedItemIndex = mouseModule.mouseController.GetAttachedItemIndex() - - # if player.SLOT_TYPE_INVENTORY == attachedSlotType or player.SLOT_TYPE_DRAGON_SOUL_INVENTORY == attachedSlotType: - if player.SLOT_TYPE_INVENTORY == attachedSlotType: - itemIndex = player.GetItemIndex(attachedSlotPos) - item.SelectItem(itemIndex) - - if item.IsAntiFlag(item.ANTIFLAG_SELL): - popup = uiCommon.PopupDialog() - popup.SetText(localeInfo.SHOP_CANNOT_SELL_ITEM) - popup.SetAcceptEvent(self.__OnClosePopupDialog) - popup.Open() - self.popup = popup - return - - itemtype = player.INVENTORY - - if player.SLOT_TYPE_DRAGON_SOUL_INVENTORY == attachedSlotType: - itemtype = player.DRAGON_SOUL_INVENTORY - - # if player.IsValuableItem(itemtype, attachedSlotPos): - if player.IsValuableItem(attachedSlotPos): - - itemPrice = item.GetISellItemPrice() - - if item.Is1GoldItem(): - itemPrice = attachedCount // itemPrice // 5 - else: - itemPrice = itemPrice * max(1, attachedCount) // 5 - - itemName = item.GetItemName() - - questionDialog = uiCommon.QuestionDialog() - questionDialog.SetText(localeInfo.DO_YOU_SELL_ITEM(itemName, attachedCount, itemPrice)) - - questionDialog.SetAcceptEvent(lambda arg1=attachedSlotPos, arg2=attachedCount, arg3 = itemtype: self.OnSellItem(arg1, arg2, arg3)) - questionDialog.SetCancelEvent(ui.__mem_func__(self.OnCloseQuestionDialog)) - questionDialog.Open() - self.questionDialog = questionDialog - - constInfo.SET_ITEM_QUESTION_DIALOG_STATUS(1) - - else: - self.OnSellItem(attachedSlotPos, attachedCount, itemtype) - - else: - snd.PlaySound("sound/ui/loginfail.wav") - - mouseModule.mouseController.DeattachObject() - - def OnSellItem(self, slotPos, count, itemtype): - net.SendShopSellPacketNew(slotPos, count, itemtype) - snd.PlaySound("sound/ui/money.wav") - self.OnCloseQuestionDialog() - - def OnCloseQuestionDialog(self): - if not self.questionDialog: - return - - self.questionDialog.Close() - self.questionDialog = None - constInfo.SET_ITEM_QUESTION_DIALOG_STATUS(0) - - def SelectEmptySlot(self, selectedSlotPos): - - isAttached = mouseModule.mouseController.isAttached() - if isAttached: - self.SellAttachedItem() - - def UnselectItemSlot(self, selectedSlotPos): - if constInfo.GET_ITEM_QUESTION_DIALOG_STATUS() == 1: - return - if shop.IsPrivateShop(): - self.AskBuyItem(selectedSlotPos) - else: - net.SendShopBuyPacket(self.__GetRealIndex(selectedSlotPos)) - - def SelectItemSlot(self, selectedSlotPos): - if constInfo.GET_ITEM_QUESTION_DIALOG_STATUS() == 1: - return - - isAttached = mouseModule.mouseController.isAttached() - selectedSlotPos = self.__GetRealIndex(selectedSlotPos) - if isAttached: - self.SellAttachedItem() - - else: - - if True == shop.IsMainPlayerPrivateShop(): - return - - curCursorNum = app.GetCursor() - if app.BUY == curCursorNum: - self.AskBuyItem(selectedSlotPos) - - elif app.SELL == curCursorNum: - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.SHOP_SELL_INFO) - - else: - selectedItemID = shop.GetItemID(selectedSlotPos) - itemCount = shop.GetItemCount(selectedSlotPos) - - type = player.SLOT_TYPE_SHOP - if shop.IsPrivateShop(): - type = player.SLOT_TYPE_PRIVATE_SHOP - - mouseModule.mouseController.AttachObject(self, type, selectedSlotPos, selectedItemID, itemCount) - mouseModule.mouseController.SetCallBack("INVENTORY", ui.__mem_func__(self.DropToInventory)) - snd.PlaySound("sound/ui/pick.wav") - - def DropToInventory(self): - attachedSlotPos = mouseModule.mouseController.GetAttachedSlotNumber() - self.AskBuyItem(attachedSlotPos) - - def AskBuyItem(self, slotPos): - slotPos = self.__GetRealIndex(slotPos) - - itemIndex = shop.GetItemID(slotPos) - itemPrice = shop.GetItemPrice(slotPos) - itemCount = shop.GetItemCount(slotPos) - - item.SelectItem(itemIndex) - itemName = item.GetItemName() - - itemBuyQuestionDialog = uiCommon.QuestionDialog() - itemBuyQuestionDialog.SetText(localeInfo.DO_YOU_BUY_ITEM(itemName, itemCount, localeInfo.NumberToMoneyString(itemPrice))) - itemBuyQuestionDialog.SetAcceptEvent(lambda arg=True: self.AnswerBuyItem(arg)) - itemBuyQuestionDialog.SetCancelEvent(lambda arg=False: self.AnswerBuyItem(arg)) - itemBuyQuestionDialog.Open() - itemBuyQuestionDialog.pos = slotPos - self.itemBuyQuestionDialog = itemBuyQuestionDialog - - constInfo.SET_ITEM_QUESTION_DIALOG_STATUS(1) - - def AnswerBuyItem(self, flag): - - if flag: - pos = self.itemBuyQuestionDialog.pos - net.SendShopBuyPacket(pos) - - self.itemBuyQuestionDialog.Close() - self.itemBuyQuestionDialog = None - - constInfo.SET_ITEM_QUESTION_DIALOG_STATUS(0) - - def SetItemToolTip(self, tooltipItem): - self.tooltipItem = tooltipItem - - def OverInItem(self, slotIndex): - slotIndex = self.__GetRealIndex(slotIndex) - if mouseModule.mouseController.isAttached(): - return - - if 0 != self.tooltipItem: - if shop.SHOP_COIN_TYPE_GOLD == shop.GetTabCoinType(self.tabIdx): - self.tooltipItem.SetShopItem(slotIndex) - else: - self.tooltipItem.SetShopItemBySecondaryCoin(slotIndex) - def OverOutItem(self): - if 0 != self.tooltipItem: - self.tooltipItem.HideToolTip() - - def OnUpdate(self): - - USE_SHOP_LIMIT_RANGE = 1000 - - (x, y, z) = player.GetMainCharacterPosition() - if abs(x - self.xShopStart) > USE_SHOP_LIMIT_RANGE or abs(y - self.yShopStart) > USE_SHOP_LIMIT_RANGE: - self.Close() - - -class MallPageDialog(ui.ScriptWindow): - def __init__(self): - ui.ScriptWindow.__init__(self) - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def Destroy(self): - self.ClearDictionary() - - def Open(self): - scriptLoader = ui.PythonScriptLoader() - scriptLoader.LoadScriptFile(self, "uiscript/mallpagedialog.py") - - self.GetChild("titlebar").SetCloseEvent(ui.__mem_func__(self.Close)) - - (x, y)=self.GetGlobalPosition() - x+=10 - y+=30 - - MALL_PAGE_WIDTH = 600 - MALL_PAGE_HEIGHT = 480 - - app.ShowWebPage( - "http://metin2.co.kr/08_mall/game_mall/login_fail.htm", - (x, y, x+MALL_PAGE_WIDTH, y+MALL_PAGE_HEIGHT)) - - self.Lock() - self.Show() - - def Close(self): - app.HideWebPage() - self.Unlock() - self.Hide() - - def OnPressEscapeKey(self): - self.Close() - return True diff --git a/tools/root/uisystem.py b/tools/root/uisystem.py deleted file mode 100644 index 2fc1b99e..00000000 --- a/tools/root/uisystem.py +++ /dev/null @@ -1,179 +0,0 @@ -import net -import app -import ui -import uiOption - -import uiSystemOption -import uiGameOption -import uiScriptLocale -import networkModule -import constInfo -import localeInfo - -SYSTEM_MENU_FOR_PORTAL = False - -################################################################################################### -## System -class SystemDialog(ui.ScriptWindow): - - def __init__(self): - ui.ScriptWindow.__init__(self) - self.__Initialize() - - def __Initialize(self): - self.eventOpenHelpWindow = None - self.systemOptionDlg = None - self.gameOptionDlg = None - - - def LoadDialog(self): - if SYSTEM_MENU_FOR_PORTAL: - self.__LoadSystemMenu_ForPortal() - else: - self.__LoadSystemMenu_Default() - - def __LoadSystemMenu_Default(self): - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "uiscript/systemdialog.py") - - self.GetChild("system_option_button").SAFE_SetEvent(self.__ClickSystemOptionButton) - self.GetChild("game_option_button").SAFE_SetEvent(self.__ClickGameOptionButton) - self.GetChild("change_button").SAFE_SetEvent(self.__ClickChangeCharacterButton) - self.GetChild("logout_button").SAFE_SetEvent(self.__ClickLogOutButton) - self.GetChild("exit_button").SAFE_SetEvent(self.__ClickExitButton) - self.GetChild("help_button").SAFE_SetEvent(self.__ClickHelpButton) - self.GetChild("cancel_button").SAFE_SetEvent(self.Close) - self.GetChild("mall_button").SAFE_SetEvent(self.__ClickInGameShopButton) - - def __LoadSystemMenu_ForPortal(self): - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "uiscript/systemdialog_forportal.py") - - self.GetChild("system_option_button").SAFE_SetEvent(self.__ClickSystemOptionButton) - self.GetChild("game_option_button").SAFE_SetEvent(self.__ClickGameOptionButton) - self.GetChild("change_button").SAFE_SetEvent(self.__ClickChangeCharacterButton) - self.GetChild("exit_button").SAFE_SetEvent(self.__ClickExitButton) - self.GetChild("help_button").SAFE_SetEvent(self.__ClickHelpButton) - self.GetChild("cancel_button").SAFE_SetEvent(self.Close) - - - def Destroy(self): - self.ClearDictionary() - - if self.gameOptionDlg: - self.gameOptionDlg.Destroy() - - if self.systemOptionDlg: - self.systemOptionDlg.Destroy() - - self.__Initialize() - - def SetOpenHelpWindowEvent(self, event): - self.eventOpenHelpWindow = event - - def OpenDialog(self): - self.Show() - - def __ClickChangeCharacterButton(self): - self.Close() - - net.ExitGame() - - def __OnClosePopupDialog(self): - self.popup = None - - def __ClickLogOutButton(self): - if SYSTEM_MENU_FOR_PORTAL: - if app.loggined: - self.Close() - net.ExitApplication() - else: - self.Close() - net.LogOutGame() - else: - self.Close() - net.LogOutGame() - - - def __ClickExitButton(self): - self.Close() - net.ExitApplication() - - def __ClickSystemOptionButton(self): - self.Close() - - if not self.systemOptionDlg: - self.systemOptionDlg = uiSystemOption.OptionDialog() - - self.systemOptionDlg.Show() - - def __ClickGameOptionButton(self): - self.Close() - - if not self.gameOptionDlg: - self.gameOptionDlg = uiGameOption.OptionDialog() - - self.gameOptionDlg.Show() - - - def __ClickHelpButton(self): - self.Close() - - if None != self.eventOpenHelpWindow: - self.eventOpenHelpWindow() - - def __ClickInGameShopButton(self): - self.Close() - net.SendChatPacket("/in_game_mall") - - def Close(self): - self.Hide() - return True - - def OnBlockMode(self, mode): - uiGameOption.blockMode = mode - if self.gameOptionDlg: - self.gameOptionDlg.OnBlockMode(mode) - #self.optionDialog.OnBlockMode(mode) - - def OnChangePKMode(self): - if self.gameOptionDlg: - self.gameOptionDlg.OnChangePKMode() - #self.optionDialog.OnChangePKMode() - - def OnPressExitKey(self): - self.Close() - return True - - def OnPressEscapeKey(self): - self.Close() - return True - -if __name__ == "__main__": - - import app - import wndMgr - import systemSetting - import mouseModule - import grp - import ui - import chr - import background - import player - - #wndMgr.SetOutlineFlag(True) - - app.SetMouseHandler(mouseModule.mouseController) - app.SetHairColorEnable(True) - wndMgr.SetMouseHandler(mouseModule.mouseController) - wndMgr.SetScreenSize(systemSetting.GetWidth(), systemSetting.GetHeight()) - app.Create("METIN2 CLOSED BETA", systemSetting.GetWidth(), systemSetting.GetHeight(), 1) - mouseModule.mouseController.Create() - - - wnd = SystemDialog() - wnd.LoadDialog() - wnd.Show() - - app.Loop() - diff --git a/tools/root/uisystemoption.py b/tools/root/uisystemoption.py deleted file mode 100644 index 8050ba3a..00000000 --- a/tools/root/uisystemoption.py +++ /dev/null @@ -1,256 +0,0 @@ -import dbg -import ui -import snd -import systemSetting -import net -import chat -import app -import localeInfo -import constInfo -import chrmgr -import player -import musicInfo - -import uiSelectMusic -import background - -MUSIC_FILENAME_MAX_LEN = 25 - -blockMode = 0 - -class OptionDialog(ui.ScriptWindow): - - def __init__(self): - ui.ScriptWindow.__init__(self) - self.__Initialize() - self.__Load() - - def __del__(self): - ui.ScriptWindow.__del__(self) - print(" -------------------------------------- DELETE SYSTEM OPTION DIALOG") - - def __Initialize(self): - self.tilingMode = 0 - self.titleBar = 0 - self.changeMusicButton = 0 - self.selectMusicFile = 0 - self.ctrlMusicVolume = 0 - self.ctrlSoundVolume = 0 - self.musicListDlg = 0 - self.tilingApplyButton = 0 - self.cameraModeButtonList = [] - self.fogModeButtonList = [] - self.tilingModeButtonList = [] - self.ctrlShadowQuality = 0 - - def Destroy(self): - self.ClearDictionary() - - self.__Initialize() - print(" -------------------------------------- DESTROY SYSTEM OPTION DIALOG") - - def __Load_LoadScript(self, fileName): - try: - pyScriptLoader = ui.PythonScriptLoader() - pyScriptLoader.LoadScriptFile(self, fileName) - except: - import exception - exception.Abort("System.OptionDialog.__Load_LoadScript") - - def __Load_BindObject(self): - try: - GetObject = self.GetChild - self.titleBar = GetObject("titlebar") - self.selectMusicFile = GetObject("bgm_file") - self.changeMusicButton = GetObject("bgm_button") - self.ctrlMusicVolume = GetObject("music_volume_controller") - self.ctrlSoundVolume = GetObject("sound_volume_controller") - self.cameraModeButtonList.append(GetObject("camera_short")) - self.cameraModeButtonList.append(GetObject("camera_long")) - self.fogModeButtonList.append(GetObject("fog_level0")) - self.fogModeButtonList.append(GetObject("fog_level1")) - self.fogModeButtonList.append(GetObject("fog_level2")) - self.tilingModeButtonList.append(GetObject("tiling_cpu")) - self.tilingModeButtonList.append(GetObject("tiling_gpu")) - self.tilingApplyButton=GetObject("tiling_apply") - #self.ctrlShadowQuality = GetObject("shadow_bar") - except: - import exception - exception.Abort("OptionDialog.__Load_BindObject") - - def __Load(self): - self.__Load_LoadScript("uiscript/systemoptiondialog.py") - self.__Load_BindObject() - - self.SetCenterPosition() - - self.titleBar.SetCloseEvent(ui.__mem_func__(self.Close)) - - self.ctrlMusicVolume.SetSliderPos(float(systemSetting.GetMusicVolume())) - self.ctrlMusicVolume.SetEvent(ui.__mem_func__(self.OnChangeMusicVolume)) - - self.ctrlSoundVolume.SetSliderPos(float(systemSetting.GetSoundVolume())) - self.ctrlSoundVolume.SetEvent(ui.__mem_func__(self.OnChangeSoundVolume)) - -# self.ctrlShadowQuality.SetSliderPos(float(systemSetting.GetShadowLevel()) / 5.0) -# self.ctrlShadowQuality.SetEvent(ui.__mem_func__(self.OnChangeShadowQuality)) - - self.changeMusicButton.SAFE_SetEvent(self.__OnClickChangeMusicButton) - - self.cameraModeButtonList[0].SAFE_SetEvent(self.__OnClickCameraModeShortButton) - self.cameraModeButtonList[1].SAFE_SetEvent(self.__OnClickCameraModeLongButton) - - self.fogModeButtonList[0].SAFE_SetEvent(self.__OnClickFogModeLevel0Button) - self.fogModeButtonList[1].SAFE_SetEvent(self.__OnClickFogModeLevel1Button) - self.fogModeButtonList[2].SAFE_SetEvent(self.__OnClickFogModeLevel2Button) - - self.tilingModeButtonList[0].SAFE_SetEvent(self.__OnClickTilingModeCPUButton) - self.tilingModeButtonList[1].SAFE_SetEvent(self.__OnClickTilingModeGPUButton) - - self.tilingApplyButton.SAFE_SetEvent(self.__OnClickTilingApplyButton) - - self.__SetCurTilingMode() - - # MR-14: Fog update by Alaric - self.__ClickRadioButton(self.fogModeButtonList, systemSetting.GetFogLevel()) - # MR-14: -- END OF -- Fog update by Alaric - self.__ClickRadioButton(self.cameraModeButtonList, constInfo.GET_CAMERA_MAX_DISTANCE_INDEX()) - - if musicInfo.fieldMusic==musicInfo.METIN2THEMA: - self.selectMusicFile.SetText(uiSelectMusic.DEFAULT_THEMA) - else: - self.selectMusicFile.SetText(musicInfo.fieldMusic[:MUSIC_FILENAME_MAX_LEN]) - - def __OnClickTilingModeCPUButton(self): - self.__NotifyChatLine(localeInfo.SYSTEM_OPTION_CPU_TILING_1) - self.__NotifyChatLine(localeInfo.SYSTEM_OPTION_CPU_TILING_2) - self.__NotifyChatLine(localeInfo.SYSTEM_OPTION_CPU_TILING_3) - self.__SetTilingMode(0) - - def __OnClickTilingModeGPUButton(self): - self.__NotifyChatLine(localeInfo.SYSTEM_OPTION_GPU_TILING_1) - self.__NotifyChatLine(localeInfo.SYSTEM_OPTION_GPU_TILING_2) - self.__NotifyChatLine(localeInfo.SYSTEM_OPTION_GPU_TILING_3) - self.__SetTilingMode(1) - - def __OnClickTilingApplyButton(self): - self.__NotifyChatLine(localeInfo.SYSTEM_OPTION_TILING_EXIT) - if 0==self.tilingMode: - background.EnableSoftwareTiling(1) - else: - background.EnableSoftwareTiling(0) - - net.ExitGame() - - def __OnClickChangeMusicButton(self): - if not self.musicListDlg: - - self.musicListDlg=uiSelectMusic.FileListDialog() - self.musicListDlg.SAFE_SetSelectEvent(self.__OnChangeMusic) - - self.musicListDlg.Open() - - - def __ClickRadioButton(self, buttonList, buttonIndex): - try: - selButton=buttonList[buttonIndex] - except IndexError: - return - - for eachButton in buttonList: - eachButton.SetUp() - - selButton.Down() - - - def __SetTilingMode(self, index): - self.__ClickRadioButton(self.tilingModeButtonList, index) - self.tilingMode=index - - def __SetCameraMode(self, index): - constInfo.SET_CAMERA_MAX_DISTANCE_INDEX(index) - self.__ClickRadioButton(self.cameraModeButtonList, index) - - def __SetFogLevel(self, index): - # MR-14: Fog update by Alaric - # constInfo.SET_FOG_LEVEL_INDEX(index) - systemSetting.SetFogLevel(index) - # MR-14: -- END OF -- Fog update by Alaric - - self.__ClickRadioButton(self.fogModeButtonList, index) - - def __OnClickCameraModeShortButton(self): - self.__SetCameraMode(0) - - def __OnClickCameraModeLongButton(self): - self.__SetCameraMode(1) - - def __OnClickFogModeLevel0Button(self): - self.__SetFogLevel(0) - - def __OnClickFogModeLevel1Button(self): - self.__SetFogLevel(1) - - def __OnClickFogModeLevel2Button(self): - self.__SetFogLevel(2) - - def __OnChangeMusic(self, fileName): - self.selectMusicFile.SetText(fileName[:MUSIC_FILENAME_MAX_LEN]) - - if musicInfo.fieldMusic != "": - snd.FadeOutMusic("BGM/" + musicInfo.fieldMusic) - - if fileName==uiSelectMusic.DEFAULT_THEMA: - musicInfo.fieldMusic=musicInfo.METIN2THEMA - else: - musicInfo.fieldMusic=fileName - - musicInfo.SaveLastPlayFieldMusic() - - if musicInfo.fieldMusic != "": - snd.FadeInMusic("BGM/" + musicInfo.fieldMusic) - - def OnChangeMusicVolume(self): - pos = self.ctrlMusicVolume.GetSliderPos() - snd.SetMusicVolume(pos) - systemSetting.SetMusicVolume(pos) - - def OnChangeSoundVolume(self): - pos = self.ctrlSoundVolume.GetSliderPos() - snd.SetSoundVolume(pos) - systemSetting.SetSoundVolume(pos) - - def OnChangeShadowQuality(self): - pos = self.ctrlShadowQuality.GetSliderPos() - systemSetting.SetShadowLevel(int(pos / 0.2)) - - def OnCloseInputDialog(self): - self.inputDialog.Close() - self.inputDialog = None - return True - - def OnCloseQuestionDialog(self): - self.questionDialog.Close() - self.questionDialog = None - return True - - def OnPressEscapeKey(self): - self.Close() - return True - - def Show(self): - ui.ScriptWindow.Show(self) - - def Close(self): - self.__SetCurTilingMode() - self.Hide() - - def __SetCurTilingMode(self): - if background.IsSoftwareTiling(): - self.__SetTilingMode(0) - else: - self.__SetTilingMode(1) - - def __NotifyChatLine(self, text): - chat.AppendChat(chat.CHAT_TYPE_INFO, text) - diff --git a/tools/root/uitarget.py b/tools/root/uitarget.py deleted file mode 100644 index ec6dcf11..00000000 --- a/tools/root/uitarget.py +++ /dev/null @@ -1,542 +0,0 @@ -import app -import ui -import player -import net -import wndMgr -import messenger -import guild -import chr -import nonplayer -import localeInfo -import constInfo -import uiCommon - -class TargetBoard(ui.ThinBoard): - - # Locale-independent button identifiers (never use translated strings as dict keys) - BTN_WHISPER = 0 - BTN_EXCHANGE = 1 - BTN_FIGHT = 2 - BTN_ACCEPT_FIGHT = 3 - BTN_AVENGE = 4 - BTN_FRIEND = 5 - BTN_INVITE_PARTY = 6 - BTN_LEAVE_PARTY = 7 - BTN_EXCLUDE = 8 - BTN_INVITE_GUILD = 9 - BTN_REMOVE_GUILD = 10 - BTN_DISMOUNT = 11 - BTN_EXIT_OBSERVER = 12 - BTN_VIEW_EQUIPMENT = 13 - BTN_REQUEST_ENTER_PARTY = 14 - BTN_BUILDING_DESTROY = 15 - BTN_EMOTION_ALLOW = 16 - BTN_VOTE_BLOCK_CHAT = 17 - - # (buttonId, localeInfo attribute name) — text resolved at __init__ time - BUTTON_CONFIG = ( - (BTN_WHISPER, "TARGET_BUTTON_WHISPER"), - (BTN_EXCHANGE, "TARGET_BUTTON_EXCHANGE"), - (BTN_FIGHT, "TARGET_BUTTON_FIGHT"), - (BTN_ACCEPT_FIGHT, "TARGET_BUTTON_ACCEPT_FIGHT"), - (BTN_AVENGE, "TARGET_BUTTON_AVENGE"), - (BTN_FRIEND, "TARGET_BUTTON_FRIEND"), - (BTN_INVITE_PARTY, "TARGET_BUTTON_INVITE_PARTY"), - (BTN_LEAVE_PARTY, "TARGET_BUTTON_LEAVE_PARTY"), - (BTN_EXCLUDE, "TARGET_BUTTON_EXCLUDE"), - (BTN_INVITE_GUILD, "TARGET_BUTTON_INVITE_GUILD"), - (BTN_REMOVE_GUILD, "TARGET_BUTTON_REMOVE_GUILD"), - (BTN_DISMOUNT, "TARGET_BUTTON_DISMOUNT"), - (BTN_EXIT_OBSERVER, "TARGET_BUTTON_EXIT_OBSERVER"), - (BTN_VIEW_EQUIPMENT, "TARGET_BUTTON_VIEW_EQUIPMENT"), - (BTN_REQUEST_ENTER_PARTY, "TARGET_BUTTON_REQUEST_ENTER_PARTY"), - (BTN_BUILDING_DESTROY, "TARGET_BUTTON_BUILDING_DESTROY"), - (BTN_EMOTION_ALLOW, "TARGET_BUTTON_EMOTION_ALLOW"), - (BTN_VOTE_BLOCK_CHAT, "VOTE_BLOCK_CHAT"), - ) - - GRADE_NAME = {} - EXCHANGE_LIMIT_RANGE = 3000 - - @staticmethod - def _RebuildLocaleStrings(): - TargetBoard.GRADE_NAME = { - nonplayer.PAWN : localeInfo.TARGET_LEVEL_PAWN, - nonplayer.S_PAWN : localeInfo.TARGET_LEVEL_S_PAWN, - nonplayer.KNIGHT : localeInfo.TARGET_LEVEL_KNIGHT, - nonplayer.S_KNIGHT : localeInfo.TARGET_LEVEL_S_KNIGHT, - nonplayer.BOSS : localeInfo.TARGET_LEVEL_BOSS, - nonplayer.KING : localeInfo.TARGET_LEVEL_KING, - } - - def __init__(self): - ui.ThinBoard.__init__(self) - - name = ui.TextLine() - name.SetParent(self) - name.SetDefaultFontName() - name.SetOutline() - name.Show() - - hpGauge = ui.Gauge() - hpGauge.SetParent(self) - hpGauge.MakeGauge(130, "red") - hpGauge.Hide() - - closeButton = ui.Button() - closeButton.SetParent(self) - closeButton.SetUpVisual("d:/ymir work/ui/public/close_button_01.sub") - closeButton.SetOverVisual("d:/ymir work/ui/public/close_button_02.sub") - closeButton.SetDownVisual("d:/ymir work/ui/public/close_button_03.sub") - closeButton.SetPosition(30, 13) - - if app.IsRTL(): - hpGauge.SetPosition(55, 17) - hpGauge.SetWindowHorizontalAlignLeft() - closeButton.SetWindowHorizontalAlignLeft() - else: - hpGauge.SetPosition(175, 17) - hpGauge.SetWindowHorizontalAlignRight() - closeButton.SetWindowHorizontalAlignRight() - - closeButton.SetEvent(ui.__mem_func__(self.OnPressedCloseButton)) - closeButton.Show() - - self.buttonDict = {} - self.showingButtonList = [] - - for btnId, localeAttr in self.BUTTON_CONFIG: - button = ui.Button() - button.SetParent(self) - - if app.IsRTL(): - button.SetUpVisual("d:/ymir work/ui/public/Small_Button_01.sub") - button.SetOverVisual("d:/ymir work/ui/public/Small_Button_02.sub") - button.SetDownVisual("d:/ymir work/ui/public/Small_Button_03.sub") - else: - button.SetUpVisual("d:/ymir work/ui/public/small_thin_button_01.sub") - button.SetOverVisual("d:/ymir work/ui/public/small_thin_button_02.sub") - button.SetDownVisual("d:/ymir work/ui/public/small_thin_button_03.sub") - - button.SetWindowHorizontalAlignCenter() - button.SetText(getattr(localeInfo, localeAttr, localeAttr)) - button.Hide() - self.buttonDict[btnId] = button - self.showingButtonList.append(button) - - self.buttonDict[self.BTN_WHISPER].SetEvent(ui.__mem_func__(self.OnWhisper)) - self.buttonDict[self.BTN_EXCHANGE].SetEvent(ui.__mem_func__(self.OnExchange)) - self.buttonDict[self.BTN_FIGHT].SetEvent(ui.__mem_func__(self.OnPVP)) - self.buttonDict[self.BTN_ACCEPT_FIGHT].SetEvent(ui.__mem_func__(self.OnPVP)) - self.buttonDict[self.BTN_AVENGE].SetEvent(ui.__mem_func__(self.OnPVP)) - self.buttonDict[self.BTN_FRIEND].SetEvent(ui.__mem_func__(self.OnAppendToMessenger)) - self.buttonDict[self.BTN_INVITE_PARTY].SetEvent(ui.__mem_func__(self.OnPartyInvite)) - self.buttonDict[self.BTN_LEAVE_PARTY].SetEvent(ui.__mem_func__(self.OnPartyExit)) - self.buttonDict[self.BTN_EXCLUDE].SetEvent(ui.__mem_func__(self.OnPartyRemove)) - - self.buttonDict[self.BTN_INVITE_GUILD].SAFE_SetEvent(self.__OnGuildAddMember) - self.buttonDict[self.BTN_REMOVE_GUILD].SAFE_SetEvent(self.__OnGuildRemoveMember) - self.buttonDict[self.BTN_DISMOUNT].SAFE_SetEvent(self.__OnDismount) - self.buttonDict[self.BTN_EXIT_OBSERVER].SAFE_SetEvent(self.__OnExitObserver) - self.buttonDict[self.BTN_VIEW_EQUIPMENT].SAFE_SetEvent(self.__OnViewEquipment) - self.buttonDict[self.BTN_REQUEST_ENTER_PARTY].SAFE_SetEvent(self.__OnRequestParty) - self.buttonDict[self.BTN_BUILDING_DESTROY].SAFE_SetEvent(self.__OnDestroyBuilding) - self.buttonDict[self.BTN_EMOTION_ALLOW].SAFE_SetEvent(self.__OnEmotionAllow) - - self.buttonDict[self.BTN_VOTE_BLOCK_CHAT].SetEvent(ui.__mem_func__(self.__OnVoteBlockChat)) - - self.name = name - self.hpGauge = hpGauge - self.closeButton = closeButton - self.nameString = 0 - self.nameLength = 0 - self.vid = 0 - self.eventWhisper = None - self.isShowButton = False - - self.__Initialize() - self.ResetTargetBoard() - - def __del__(self): - ui.ThinBoard.__del__(self) - - print("===================================================== DESTROYED TARGET BOARD") - - def __Initialize(self): - self.nameString = "" - self.nameLength = 0 - self.vid = 0 - self.isShowButton = False - - def Destroy(self): - self.eventWhisper = None - self.closeButton = None - self.showingButtonList = None - self.buttonDict = None - self.name = None - self.hpGauge = None - self.__Initialize() - - def OnPressedCloseButton(self): - player.ClearTarget() - self.Close() - - def Close(self): - self.__Initialize() - self.Hide() - - def Open(self, vid, name): - if vid: - if not constInfo.GET_VIEW_OTHER_EMPIRE_PLAYER_TARGET_BOARD(): - if not player.IsSameEmpire(vid): - self.Hide() - return - - if vid != self.GetTargetVID(): - self.ResetTargetBoard() - self.SetTargetVID(vid) - self.SetTargetName(name) - - if player.IsMainCharacterIndex(vid): - self.__ShowMainCharacterMenu() - elif chr.INSTANCE_TYPE_BUILDING == chr.GetInstanceType(self.vid): - self.Hide() - else: - self.RefreshButton() - self.Show() - else: - self.HideAllButton() - self.__ShowButton(self.BTN_WHISPER) - self.__ShowButton(self.BTN_VOTE_BLOCK_CHAT) - self.__ArrangeButtonPosition() - self.SetTargetName(name) - self.Show() - - def Refresh(self): - if self.IsShow(): - if self.IsShowButton(): - self.RefreshButton() - - def RefreshByVID(self, vid): - if vid == self.GetTargetVID(): - self.Refresh() - - def RefreshByName(self, name): - if name == self.GetTargetName(): - self.Refresh() - - def __ShowMainCharacterMenu(self): - canShow=0 - - self.HideAllButton() - - if player.IsMountingHorse(): - self.__ShowButton(self.BTN_DISMOUNT) - canShow=1 - - if player.IsObserverMode(): - self.__ShowButton(self.BTN_EXIT_OBSERVER) - canShow=1 - - if canShow: - self.__ArrangeButtonPosition() - self.Show() - else: - self.Hide() - - def __ShowNameOnlyMenu(self): - self.HideAllButton() - - def SetWhisperEvent(self, event): - self.eventWhisper = event - - def UpdatePosition(self): - self.SetPosition(wndMgr.GetScreenWidth() // 2 - self.GetWidth() // 2, 10) - - def ResetTargetBoard(self): - - for btn in list(self.buttonDict.values()): - btn.Hide() - - self.__Initialize() - - self.name.SetPosition(0, 13) - self.name.SetHorizontalAlignCenter() - self.name.SetWindowHorizontalAlignCenter() - self.hpGauge.Hide() - self.SetSize(250, 40) - - def SetTargetVID(self, vid): - self.vid = vid - - def SetEnemyVID(self, vid): - self.SetTargetVID(vid) - - name = chr.GetNameByVID(vid) - level = nonplayer.GetLevelByVID(vid) - grade = nonplayer.GetGradeByVID(vid) - - nameFront = "" - if -1 != level: - nameFront += "Lv." + str(level) + " " - if grade in self.GRADE_NAME: - nameFront += "(" + self.GRADE_NAME[grade] + ") " - - self.SetTargetName(nameFront + name) - - def GetTargetVID(self): - return self.vid - - def GetTargetName(self): - return self.nameString - - def SetTargetName(self, name): - self.nameString = name - self.nameLength = len(name) - self.name.SetText(name) - - def SetHP(self, hpPercentage): - if not self.hpGauge.IsShow(): - - self.SetSize(200 + 7 * self.nameLength, self.GetHeight()) - - if app.IsRTL(): - self.name.SetPosition( self.GetWidth()-23, 13) - else: - self.name.SetPosition(23, 13) - - self.name.SetWindowHorizontalAlignLeft() - self.name.SetHorizontalAlignLeft() - self.hpGauge.Show() - self.UpdatePosition() - - self.hpGauge.SetPercentage(hpPercentage, 100) - - def ShowDefaultButton(self): - - self.isShowButton = True - self.showingButtonList.append(self.buttonDict[self.BTN_WHISPER]) - self.showingButtonList.append(self.buttonDict[self.BTN_EXCHANGE]) - self.showingButtonList.append(self.buttonDict[self.BTN_FIGHT]) - self.showingButtonList.append(self.buttonDict[self.BTN_EMOTION_ALLOW]) - for button in self.showingButtonList: - button.Show() - - def HideAllButton(self): - self.isShowButton = False - for button in self.showingButtonList: - button.Hide() - self.showingButtonList = [] - - def __ShowButton(self, name): - - if name not in self.buttonDict: - return - - self.buttonDict[name].Show() - self.showingButtonList.append(self.buttonDict[name]) - - def __HideButton(self, name): - - if name not in self.buttonDict: - return - - button = self.buttonDict[name] - button.Hide() - - for btnInList in self.showingButtonList: - if btnInList == button: - self.showingButtonList.remove(button) - break - - def OnWhisper(self): - if None != self.eventWhisper: - self.eventWhisper(self.nameString) - - def OnExchange(self): - net.SendExchangeStartPacket(self.vid) - - def OnPVP(self): - net.SendChatPacket("/pvp %d" % (self.vid)) - - def OnAppendToMessenger(self): - net.SendMessengerAddByVIDPacket(self.vid) - - def OnPartyInvite(self): - net.SendPartyInvitePacket(self.vid) - - def OnPartyExit(self): - net.SendPartyExitPacket() - - def OnPartyRemove(self): - net.SendPartyRemovePacket(self.vid) - - def __OnGuildAddMember(self): - net.SendGuildAddMemberPacket(self.vid) - - def __OnGuildRemoveMember(self): - self.questionDialog = uiCommon.QuestionDialog() - self.questionDialog.SetText(localeInfo.GUILD_REMOVE_MEMBER_QUESTION) - self.questionDialog.SetAcceptEvent(ui.__mem_func__(self.__OnGuildRemoveMemberAccept)) - self.questionDialog.SetCancelEvent(ui.__mem_func__(self.__OnGuildRemoveMemberClose)) - self.questionDialog.Open() - - def __OnGuildRemoveMemberAccept(self): - net.SendGuildRemoveMemberPacket(self.nameString) - self.__OnGuildRemoveMemberClose() - - def __OnGuildRemoveMemberClose(self): - self.questionDialog.Close() - self.questionDialog = None - return True - - def __OnDismount(self): - net.SendChatPacket("/unmount") - - def __OnExitObserver(self): - net.SendChatPacket("/observer_exit") - - def __OnViewEquipment(self): - net.SendChatPacket("/view_equip " + str(self.vid)) - - def __OnRequestParty(self): - net.SendChatPacket("/party_request " + str(self.vid)) - - def __OnDestroyBuilding(self): - net.SendChatPacket("/build d %d" % (self.vid)) - - def __OnEmotionAllow(self): - net.SendChatPacket("/emotion_allow %d" % (self.vid)) - - def __OnVoteBlockChat(self): - cmd = "/vote_block_chat %s" % (self.nameString) - net.SendChatPacket(cmd) - - def OnPressEscapeKey(self): - self.OnPressedCloseButton() - return True - - def IsShowButton(self): - return self.isShowButton - - def RefreshButton(self): - self.HideAllButton() - - if chr.INSTANCE_TYPE_BUILDING == chr.GetInstanceType(self.vid): - #self.__ShowButton(self.BTN_BUILDING_DESTROY) - #self.__ArrangeButtonPosition() - return - - if player.IsPVPInstance(self.vid) or player.IsObserverMode(): - # PVP_INFO_SIZE_BUG_FIX - self.SetSize(200 + 7 * self.nameLength, 40) - self.UpdatePosition() - # END_OF_PVP_INFO_SIZE_BUG_FIX - return - - self.ShowDefaultButton() - - def isGuildMaster(name): - guildMasterName = guild.GetGuildMasterName() - return guildMasterName == name - - def isGuildMember(name, vid): - return guild.IsMemberByName(name) and chr.GetGuildID(vid) != 0 - - def isNotGuildMember(name, vid): - return not guild.IsMemberByName(name) and chr.GetGuildID(vid) == 0 - - guildAuthorityButtons = { - guild.AUTH_ADD_MEMBER: { - "btn": self.BTN_INVITE_GUILD, - "condition": lambda: isNotGuildMember(self.nameString, self.vid), - }, - guild.AUTH_REMOVE_MEMBER: { - "btn": self.BTN_REMOVE_GUILD, - "condition": lambda: isGuildMember(self.nameString, self.vid) and not isGuildMaster(self.nameString), - }, - } - - for guildAuthority, guildButton in guildAuthorityButtons.items(): - hasAuthority = guild.MainPlayerHasAuthority(guildAuthority) - satisfiesCondition = guildButton["condition"]() - if hasAuthority and satisfiesCondition: - self.__ShowButton(guildButton["btn"]) - - if not messenger.IsFriendByName(self.nameString): - self.__ShowButton(self.BTN_FRIEND) - - if player.IsPartyMember(self.vid): - - self.__HideButton(self.BTN_FIGHT) - - if player.IsPartyLeader(self.vid): - self.__ShowButton(self.BTN_LEAVE_PARTY) - elif player.IsPartyLeader(player.GetMainCharacterIndex()): - self.__ShowButton(self.BTN_EXCLUDE) - - else: - if player.IsPartyMember(player.GetMainCharacterIndex()): - if player.IsPartyLeader(player.GetMainCharacterIndex()): - self.__ShowButton(self.BTN_INVITE_PARTY) - else: - if chr.IsPartyMember(self.vid): - self.__ShowButton(self.BTN_REQUEST_ENTER_PARTY) - else: - self.__ShowButton(self.BTN_INVITE_PARTY) - - if player.IsRevengeInstance(self.vid): - self.__HideButton(self.BTN_FIGHT) - self.__ShowButton(self.BTN_AVENGE) - elif player.IsChallengeInstance(self.vid): - self.__HideButton(self.BTN_FIGHT) - self.__ShowButton(self.BTN_ACCEPT_FIGHT) - elif player.IsCantFightInstance(self.vid): - self.__HideButton(self.BTN_FIGHT) - - if not player.IsSameEmpire(self.vid): - self.__HideButton(self.BTN_INVITE_PARTY) - self.__HideButton(self.BTN_FRIEND) - self.__HideButton(self.BTN_FIGHT) - - distance = player.GetCharacterDistance(self.vid) - if distance > self.EXCHANGE_LIMIT_RANGE: - self.__HideButton(self.BTN_EXCHANGE) - self.__ArrangeButtonPosition() - - self.__ArrangeButtonPosition() - - def __ArrangeButtonPosition(self): - showingButtonCount = len(self.showingButtonList) - - pos = -(showingButtonCount // 2) * 68 - - if 0 == showingButtonCount % 2: - pos += 34 - - for button in self.showingButtonList: - button.SetPosition(pos, 33) - pos += 68 - - self.SetSize(max(150, showingButtonCount * 75), 65) - self.UpdatePosition() - - def OnUpdate(self): - if self.isShowButton: - - exchangeButton = self.buttonDict[self.BTN_EXCHANGE] - distance = player.GetCharacterDistance(self.vid) - - if distance < 0: - return - - if exchangeButton.IsShow(): - if distance > self.EXCHANGE_LIMIT_RANGE: - self.RefreshButton() - - else: - if distance < self.EXCHANGE_LIMIT_RANGE: - self.RefreshButton() - -TargetBoard._RebuildLocaleStrings() -localeInfo.RegisterReloadCallback(TargetBoard._RebuildLocaleStrings) diff --git a/tools/root/uitaskbar.py b/tools/root/uitaskbar.py deleted file mode 100644 index ae9bc523..00000000 --- a/tools/root/uitaskbar.py +++ /dev/null @@ -1,1186 +0,0 @@ -import ui -import net -import item -import skill -import localeInfo -import wndMgr -import player -import constInfo -import mouseModule -import uiScriptLocale -import app - -MOUSE_SETTINGS = [0, 0] - -def InitMouseButtonSettings(left, right): - global MOUSE_SETTINGS - MOUSE_SETTINGS = [left, right] - -def SetMouseButtonSetting(dir, event): - global MOUSE_SETTINGS - MOUSE_SETTINGS[dir] = event - -def GetMouseButtonSettings(): - global MOUSE_SETTINGS - return MOUSE_SETTINGS - -def SaveMouseButtonSettings(): - global MOUSE_SETTINGS - with open("config/mouse.cfg", "w") as f: - f.write("%s\t%s" % tuple(MOUSE_SETTINGS)) - -def LoadMouseButtonSettings(): - global MOUSE_SETTINGS - with open("config/mouse.cfg", "r") as f: - tokens = f.read().split() - - if len(tokens) != 2: - raise RuntimeError("MOUSE_SETTINGS_FILE_ERROR") - - MOUSE_SETTINGS[0] = int(tokens[0]) - MOUSE_SETTINGS[1] = int(tokens[1]) - -def unsigned32(n): - return n & 0xFFFFFFFF - -#-------------------Giftbox Begin------------------------------ - -class GiftBox(ui.ScriptWindow): - class TextToolTip(ui.Window): - def __init__(self): - ui.Window.__init__(self, "TOP_MOST") - self.SetWindowName("GiftBox") - textLine = ui.TextLine() - textLine.SetParent(self) - textLine.SetHorizontalAlignCenter() - textLine.SetOutline() - textLine.Show() - self.textLine = textLine - - def __del__(self): - ui.Window.__del__(self) - - def SetText(self, text): - self.textLine.SetText(text) - - def OnRender(self): - (mouseX, mouseY) = wndMgr.GetMousePosition() - self.textLine.SetPosition(mouseX, mouseY - 15) - - def __init__(self): - #print "NEW TASKBAR ----------------------------------------------------------------------------" - ui.ScriptWindow.__init__(self) - self.tooltipGift = self.TextToolTip() - self.tooltipGift.Show() - - def __del__(self): - #print "---------------------------------------------------------------------------- DELETE TASKBAR" - ui.ScriptWindow.__del__(self) - - def LoadWindow(self): - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "UIScript/giftbox.py") - - except: - import exception - exception.Abort("GiftBox.LoadWindow.LoadObject") - - self.giftBoxIcon = self.GetChild("GiftBox_Icon") - self.giftBoxToolTip = self.GetChild("GiftBox_ToolTip") - - def Destroy(self): - self.giftBoxIcon = 0 - self.giftBoxToolTip = 0 - -#-------------------Giftbox End------------------------------ - -class EnergyBar(ui.ScriptWindow): - class TextToolTip(ui.Window): - def __init__(self): - ui.Window.__init__(self, "TOP_MOST") - self.SetWindowName("EnergyBar") - textLine = ui.TextLine() - textLine.SetParent(self) - textLine.SetHorizontalAlignCenter() - textLine.SetOutline() - textLine.Show() - self.textLine = textLine - - def __del__(self): - ui.Window.__del__(self) - - def SetText(self, text): - self.textLine.SetText(text) - - def OnRender(self): - (mouseX, mouseY) = wndMgr.GetMousePosition() - self.textLine.SetPosition(mouseX, mouseY - 15) - - def __init__(self): - #print "NEW TASKBAR ----------------------------------------------------------------------------" - ui.ScriptWindow.__init__(self) - self.tooltipEnergy = self.TextToolTip() - self.tooltipEnergy.Show() - - def __del__(self): - #print "---------------------------------------------------------------------------- DELETE TASKBAR" - ui.ScriptWindow.__del__(self) - - def LoadWindow(self): - try: - pyScrLoader = ui.PythonScriptLoader() - - if app.IsRTL(): - pyScrLoader.LoadScriptFile(self, uiScriptLocale.LOCALE_UISCRIPT_PATH + "EnergyBar.py") - else: - pyScrLoader.LoadScriptFile(self, "UIScript/EnergyBar.py") - - except: - import exception - exception.Abort("EnergyBar.LoadWindow.LoadObject") - - self.energyEmpty = self.GetChild("EnergyGauge_Empty") - self.energyHungry = self.GetChild("EnergyGauge_Hungry") - self.energyFull = self.GetChild("EnergyGauge_Full") - - self.energyGaugeBoard = self.GetChild("EnergyGauge_Board") - self.energyGaugeToolTip = self.GetChild("EnergyGauge_ToolTip") - - - def Destroy(self): - self.energyEmpty = None - self.energyHungry = None - self.energyFull = None - self.energyGaugeBoard = 0 - self.energyGaugeToolTip = 0 - self.tooltipEnergy = 0 - - ## Gauge - def RefreshStatus(self): - pointEnergy = player.GetStatus (player.ENERGY) - leftTimeEnergy = player.GetStatus (player.ENERGY_END_TIME) - app.GetGlobalTimeStamp() - # Energy pill duration = 2 hours. - self.SetEnergy (pointEnergy, leftTimeEnergy, 7200) - - def SetEnergy (self, point, leftTime, maxTime): - leftTime = max (leftTime, 0) - maxTime = max (maxTime, 0) - - self.energyEmpty.Hide() - self.energyHungry.Hide() - self.energyFull.Hide() - - if leftTime == 0: - self.energyEmpty.Show() - elif ((leftTime * 100) // maxTime) < 15: - self.energyHungry.Show() - else: - self.energyFull.Show() - - self.tooltipEnergy.SetText("%s" % (localeInfo.TOOLTIP_ENERGY(point))) - - def OnUpdate(self): - if True == self.energyGaugeToolTip.IsIn(): - self.RefreshStatus() - self.tooltipEnergy.Show() - else: - self.tooltipEnergy.Hide() - -class ExpandedTaskBar(ui.ScriptWindow): - BUTTON_DRAGON_SOUL = 0 - def __init__(self): - ui.Window.__init__(self) - self.SetWindowName("ExpandedTaskBar") - - def LoadWindow(self): - try: - pyScrLoader = ui.PythonScriptLoader() - - if app.IsRTL(): - pyScrLoader.LoadScriptFile(self, uiScriptLocale.LOCALE_UISCRIPT_PATH + "ExpandedTaskBar.py") - else: - pyScrLoader.LoadScriptFile(self, "UIScript/ExpandedTaskBar.py") - - except: - import exception - exception.Abort("ExpandedTaskBar.LoadWindow.LoadObject") - - self.expandedTaskBarBoard = self.GetChild("ExpanedTaskBar_Board") - - self.toggleButtonDict = {} - self.toggleButtonDict[ExpandedTaskBar.BUTTON_DRAGON_SOUL] = self.GetChild("DragonSoulButton") - self.toggleButtonDict[ExpandedTaskBar.BUTTON_DRAGON_SOUL].SetParent(self) - - def SetTop(self): - super(ExpandedTaskBar, self).SetTop() - for button in list(self.toggleButtonDict.values()): - button.SetTop() - - def Show(self): - ui.ScriptWindow.Show(self) - - def Close(self): - self.Hide() - - def SetToolTipText(self, eButton, text): - self.toggleButtonDict[eButton].SetToolTipText(text) - - def SetToggleButtonEvent(self, eButton, kEventFunc): - self.toggleButtonDict[eButton].SetEvent(kEventFunc) - - def OnPressEscapeKey(self): - self.Close() - return True - -class TaskBar(ui.ScriptWindow): - - BUTTON_CHARACTER = 0 - BUTTON_INVENTORY = 1 - BUTTON_MESSENGER = 2 - BUTTON_SYSTEM = 3 - BUTTON_CHAT = 4 - BUTTON_EXPAND = 4 - IS_EXPANDED = False - - MOUSE_BUTTON_LEFT = 0 - MOUSE_BUTTON_RIGHT = 1 - NONE = 255 - - EVENT_MOVE = 0 - EVENT_ATTACK = 1 - EVENT_MOVE_AND_ATTACK = 2 - EVENT_CAMERA = 3 - EVENT_SKILL = 4 - EVENT_AUTO = 5 - - GAUGE_WIDTH = 95 - GAUGE_HEIGHT = 13 - - QUICKPAGE_NUMBER_FILENAME = [ - "d:/ymir work/ui/game/taskbar/1.sub", - "d:/ymir work/ui/game/taskbar/2.sub", - "d:/ymir work/ui/game/taskbar/3.sub", - "d:/ymir work/ui/game/taskbar/4.sub", - ] - - #gift icon show and hide - def ShowGift(self): - self.wndGiftBox.Show() - - def HideGift(self): - self.wndGiftBox.Hide() - - class TextToolTip(ui.Window): - def __init__(self): - ui.Window.__init__(self, "TOP_MOST") - - textLine = ui.TextLine() - textLine.SetParent(self) - textLine.SetHorizontalAlignCenter() - textLine.SetOutline() - textLine.Show() - self.textLine = textLine - - def __del__(self): - ui.Window.__del__(self) - - def SetText(self, text): - self.textLine.SetText(text) - - def OnRender(self): - (mouseX, mouseY) = wndMgr.GetMousePosition() - self.textLine.SetPosition(mouseX, mouseY - 15) - - class SkillButton(ui.SlotWindow): - - def __init__(self): - ui.SlotWindow.__init__(self) - - self.event = 0 - self.arg = 0 - - self.slotIndex = 0 - self.skillIndex = 0 - - slotIndex = 0 - wndMgr.SetSlotBaseImage(self.hWnd, "d:/ymir work/ui/public/slot_base.sub", 1.0, 1.0, 1.0, 1.0) - wndMgr.AppendSlot(self.hWnd, slotIndex, 0, 0, 32, 32) - self.SetCoverButton(slotIndex, "d:/ymir work/ui/public/slot_cover_button_01.sub",\ - "d:/ymir work/ui/public/slot_cover_button_02.sub",\ - "d:/ymir work/ui/public/slot_cover_button_03.sub",\ - "d:/ymir work/ui/public/slot_cover_button_04.sub", True, False) - self.SetSize(32, 32) - - def __del__(self): - ui.SlotWindow.__del__(self) - - def Destroy(self): - if 0 != self.tooltipSkill: - self.tooltipSkill.HideToolTip() - - def RefreshSkill(self): - if 0 != self.slotIndex: - self.SetSkill(self.slotIndex) - - def SetSkillToolTip(self, tooltip): - self.tooltipSkill = tooltip - - def SetSkill(self, skillSlotNumber): - slotNumber = 0 - skillIndex = player.GetSkillIndex(skillSlotNumber) - skillGrade = player.GetSkillGrade(skillSlotNumber) - skillLevel = player.GetSkillLevel(skillSlotNumber) - skillType = skill.GetSkillType(skillIndex) - - self.skillIndex = skillIndex - if 0 == self.skillIndex: - self.ClearSlot(slotNumber) - return - - self.slotIndex = skillSlotNumber - - self.SetSkillSlotNew(slotNumber, skillIndex, skillGrade, skillLevel) - self.SetSlotCountNew(slotNumber, skillGrade, skillLevel) - - ## NOTE: Check cooltime - if player.IsSkillCoolTime(skillSlotNumber): - (coolTime, elapsedTime) = player.GetSkillCoolTime(skillSlotNumber) - self.SetSlotCoolTime(slotNumber, coolTime, elapsedTime) - - ## NOTE: If activated, update icon as well - if player.IsSkillActive(skillSlotNumber): - self.ActivateSlot(slotNumber) - - def SetSkillEvent(self, event, arg=0): - self.event = event - self.arg = arg - - def GetSkillIndex(self): - return self.skillIndex - - def GetSlotIndex(self): - return self.slotIndex - - def Activate(self, coolTime): - self.SetSlotCoolTime(0, coolTime) - - if skill.IsToggleSkill(self.skillIndex): - self.ActivateSlot(0) - - def Deactivate(self): - if skill.IsToggleSkill(self.skillIndex): - self.DeactivateSlot(0) - - def OnOverInItem(self, dummy): - self.tooltipSkill.SetSkill(self.skillIndex) - - def OnOverOutItem(self): - self.tooltipSkill.HideToolTip() - - def OnSelectItemSlot(self, dummy): - if 0 != self.event: - if 0 != self.arg: - self.event(self.arg) - else: - self.event() - - def __init__(self): - #print "NEW TASKBAR ----------------------------------------------------------------------------" - - ui.ScriptWindow.__init__(self, "TOP_MOST") - - self.quickPageNumImageBox = None - self.tooltipItem = 0 - self.tooltipSkill = 0 - self.mouseModeButtonList = [ ui.ScriptWindow("TOP_MOST"), ui.ScriptWindow("TOP_MOST") ] - - self.tooltipHP = self.TextToolTip() - self.tooltipHP.Show() - self.tooltipSP = self.TextToolTip() - self.tooltipSP.Show() - self.tooltipST = self.TextToolTip() - self.tooltipST.Show() - self.tooltipEXP = self.TextToolTip() - self.tooltipEXP.Show() - - self.skillCategoryNameList = [ "ACTIVE_1", "ACTIVE_2", "ACTIVE_3" ] - self.skillPageStartSlotIndexDict = { - "ACTIVE_1" : 1, - "ACTIVE_2" : 21, - "ACTIVE_3" : 41, - } - - self.selectSkillButtonList = [] - - self.lastUpdateQuickSlot = 0 - self.SetWindowName("TaskBar") - - def __del__(self): - #print "---------------------------------------------------------------------------- DELETE TASKBAR" - ui.ScriptWindow.__del__(self) - - def LoadWindow(self): - try: - pyScrLoader = ui.PythonScriptLoader() - - if app.IsRTL(): - pyScrLoader.LoadScriptFile(self, uiScriptLocale.LOCALE_UISCRIPT_PATH + "TaskBar.py") - else: - pyScrLoader.LoadScriptFile(self, "UIScript/TaskBar.py") - - pyScrLoader.LoadScriptFile(self.mouseModeButtonList[self.MOUSE_BUTTON_LEFT], "UIScript/MouseButtonWindow.py") - pyScrLoader.LoadScriptFile(self.mouseModeButtonList[self.MOUSE_BUTTON_RIGHT], "UIScript/RightMouseButtonWindow.py") - except: - import exception - exception.Abort("TaskBar.LoadWindow.LoadObject") - - self.quickslot = [] - self.quickslot.append(self.GetChild("quick_slot_1")) - self.quickslot.append(self.GetChild("quick_slot_2")) - for slot in self.quickslot: - slot.SetSlotStyle(wndMgr.SLOT_STYLE_NONE) - slot.SetSelectEmptySlotEvent(ui.__mem_func__(self.SelectEmptyQuickSlot)) - slot.SetSelectItemSlotEvent(ui.__mem_func__(self.SelectItemQuickSlot)) - slot.SetUnselectItemSlotEvent(ui.__mem_func__(self.UnselectItemQuickSlot)) - slot.SetOverInItemEvent(ui.__mem_func__(self.OverInItem)) - slot.SetOverOutItemEvent(ui.__mem_func__(self.OverOutItem)) - - toggleButtonDict = {} - toggleButtonDict[TaskBar.BUTTON_CHARACTER]=self.GetChild("CharacterButton") - toggleButtonDict[TaskBar.BUTTON_INVENTORY]=self.GetChild("InventoryButton") - toggleButtonDict[TaskBar.BUTTON_MESSENGER]=self.GetChild("MessengerButton") - toggleButtonDict[TaskBar.BUTTON_SYSTEM]=self.GetChild("SystemButton") - - # Either ChatButton or ExpandButton must exist. - try: - toggleButtonDict[TaskBar.BUTTON_CHAT]=self.GetChild("ChatButton") - except: - toggleButtonDict[TaskBar.BUTTON_EXPAND]=self.GetChild("ExpandButton") - TaskBar.IS_EXPANDED = True - - if app.IsRTL(): - systemButton = toggleButtonDict[TaskBar.BUTTON_SYSTEM] - - if systemButton.ToolTipText: - tx, ty = systemButton.ToolTipText.GetLocalPosition() - tw = systemButton.ToolTipText.GetWidth() - systemButton.ToolTipText.SetPosition(-tw // 2, ty) - - expGauge = [] - - expGauge.append(self.GetChild("EXPGauge_01")) - expGauge.append(self.GetChild("EXPGauge_02")) - expGauge.append(self.GetChild("EXPGauge_03")) - expGauge.append(self.GetChild("EXPGauge_04")) - - for exp in expGauge: - exp.SetSize(0, 0) - - self.quickPageNumImageBox=self.GetChild("QuickPageNumber") - - self.GetChild("QuickPageUpButton").SetEvent(ui.__mem_func__(self.__OnClickQuickPageUpButton)) - self.GetChild("QuickPageDownButton").SetEvent(ui.__mem_func__(self.__OnClickQuickPageDownButton)) - - mouseLeftButtonModeButton = self.GetChild("LeftMouseButton") - mouseRightButtonModeButton = self.GetChild("RightMouseButton") - mouseLeftButtonModeButton.SetEvent(ui.__mem_func__(self.ToggleLeftMouseButtonModeWindow)) - mouseRightButtonModeButton.SetEvent(ui.__mem_func__(self.ToggleRightMouseButtonModeWindow)) - self.curMouseModeButton = [ mouseLeftButtonModeButton, mouseRightButtonModeButton ] - - (xLocalRight, yLocalRight) = mouseRightButtonModeButton.GetLocalPosition() - self.curSkillButton = self.SkillButton() - self.curSkillButton.SetParent(self) - self.curSkillButton.SetPosition(xLocalRight, 3) - self.curSkillButton.SetSkillEvent(ui.__mem_func__(self.ToggleRightMouseButtonModeWindow)) - self.curSkillButton.Hide() - - (xLeft, yLeft) = mouseLeftButtonModeButton.GetGlobalPosition() - (xRight, yRight) = mouseRightButtonModeButton.GetGlobalPosition() - leftModeButtonList = self.mouseModeButtonList[self.MOUSE_BUTTON_LEFT] - leftModeButtonList.SetPosition(xLeft, yLeft - leftModeButtonList.GetHeight()-5) - rightModeButtonList = self.mouseModeButtonList[self.MOUSE_BUTTON_RIGHT] - rightModeButtonList.SetPosition(xRight - rightModeButtonList.GetWidth() + 32, yRight - rightModeButtonList.GetHeight()-5) - rightModeButtonList.GetChild("button_skill").SetEvent(lambda adir=self.MOUSE_BUTTON_RIGHT, aevent=self.EVENT_SKILL: self.SelectMouseButtonEvent(adir, aevent)) - rightModeButtonList.GetChild("button_skill").Hide() - - mouseImage = ui.ImageBox("TOP_MOST") - mouseImage.AddFlag("float") - mouseImage.LoadImage("d:/ymir work/ui/game/taskbar/mouse_button_camera_01.sub") - mouseImage.SetPosition(xRight, wndMgr.GetScreenHeight() - 34) - mouseImage.Hide() - self.mouseImage = mouseImage - - dir = self.MOUSE_BUTTON_LEFT - wnd = self.mouseModeButtonList[dir] - wnd.GetChild("button_move_and_attack").SetEvent(lambda adir=dir, aevent=self.EVENT_MOVE_AND_ATTACK: self.SelectMouseButtonEvent(adir, aevent)) - wnd.GetChild("button_auto_attack").SetEvent(lambda adir=dir, aevent=self.EVENT_AUTO: self.SelectMouseButtonEvent(adir, aevent)) - wnd.GetChild("button_camera").SetEvent(lambda adir=dir, aevent=self.EVENT_CAMERA: self.SelectMouseButtonEvent(adir, aevent)) - - dir = self.MOUSE_BUTTON_RIGHT - wnd = self.mouseModeButtonList[dir] - wnd.GetChild("button_move_and_attack").SetEvent(lambda adir=dir, aevent=self.EVENT_MOVE_AND_ATTACK: self.SelectMouseButtonEvent(adir, aevent)) - wnd.GetChild("button_camera").SetEvent(lambda adir=dir, aevent=self.EVENT_CAMERA: self.SelectMouseButtonEvent(adir, aevent)) - - self.toggleButtonDict = toggleButtonDict - self.expGauge = expGauge - - self.rampageGauge1 = self.GetChild("RampageGauge") - self.rampageGauge1.OnMouseOverIn = ui.__mem_func__(self.__RampageGauge_OverIn) - self.rampageGauge2 = self.GetChild("RampageGauge2") - self.rampageGauge2.OnMouseOverOut = ui.__mem_func__(self.__RampageGauge_OverOut) - self.rampageGauge2.OnMouseLeftButtonUp = ui.__mem_func__(self.__RampageGauge_Click) - self.__RampageGauge_OverOut() - - self.hpGauge = self.GetChild("HPGauge") - self.mpGauge = self.GetChild("SPGauge") - self.stGauge = self.GetChild("STGauge") - self.hpRecoveryGaugeBar = self.GetChild("HPRecoveryGaugeBar") - self.spRecoveryGaugeBar = self.GetChild("SPRecoveryGaugeBar") - - self.hpGaugeBoard=self.GetChild("HPGauge_Board") - self.mpGaugeBoard=self.GetChild("SPGauge_Board") - self.stGaugeBoard=self.GetChild("STGauge_Board") - self.expGaugeBoard=self.GetChild("EXP_Gauge_Board") - - #giftbox object - wndGiftBox = GiftBox() - wndGiftBox.LoadWindow() - self.wndGiftBox = wndGiftBox - - self.__LoadMouseSettings() - self.RefreshStatus() - self.RefreshQuickSlot() - - def __RampageGauge_OverIn(self): - print("rampage_over_in") - self.rampageGauge2.Show() - self.rampageGauge1.Hide() - - def __RampageGauge_OverOut(self): - print("rampage_over_out") - self.rampageGauge2.Hide() - self.rampageGauge1.Show() - - def __RampageGauge_Click(self): - print("rampage_up") - net.SendChatPacket("/in_game_mall") - # gift icon hide when click mall icon - self.wndGiftBox.Hide() - - def __LoadMouseSettings(self): - try: - LoadMouseButtonSettings() - (mouseLeftButtonEvent, mouseRightButtonEvent) = GetMouseButtonSettings() - if not self.__IsInSafeMouseButtonSettingRange(mouseLeftButtonEvent) or not self.__IsInSafeMouseButtonSettingRange(mouseRightButtonEvent): - raise RuntimeError("INVALID_MOUSE_BUTTON_SETTINGS") - except: - InitMouseButtonSettings(self.EVENT_MOVE_AND_ATTACK, self.EVENT_CAMERA) - (mouseLeftButtonEvent, mouseRightButtonEvent) = GetMouseButtonSettings() - - try: - self.SelectMouseButtonEvent(self.MOUSE_BUTTON_LEFT, mouseLeftButtonEvent) - self.SelectMouseButtonEvent(self.MOUSE_BUTTON_RIGHT, mouseRightButtonEvent) - except: - InitMouseButtonSettings(self.EVENT_MOVE_AND_ATTACK, self.EVENT_CAMERA) - (mouseLeftButtonEvent, mouseRightButtonEvent) = GetMouseButtonSettings() - - self.SelectMouseButtonEvent(self.MOUSE_BUTTON_LEFT, mouseLeftButtonEvent) - self.SelectMouseButtonEvent(self.MOUSE_BUTTON_RIGHT, mouseRightButtonEvent) - - - - def __IsInSafeMouseButtonSettingRange(self, arg): - return arg >= self.EVENT_MOVE and arg <= self.EVENT_AUTO - - def Destroy(self): - SaveMouseButtonSettings() - - self.ClearDictionary() - self.mouseModeButtonList[0].ClearDictionary() - self.mouseModeButtonList[1].ClearDictionary() - self.mouseModeButtonList = 0 - self.curMouseModeButton = 0 - self.curSkillButton = 0 - self.selectSkillButtonList = 0 - - - self.expGauge = None - self.hpGauge = None - self.mpGauge = None - self.stGauge = None - self.hpRecoveryGaugeBar = None - self.spRecoveryGaugeBar = None - - self.tooltipItem = 0 - self.tooltipSkill = 0 - self.quickslot = 0 - self.toggleButtonDict = 0 - - self.hpGaugeBoard = 0 - self.mpGaugeBoard = 0 - self.stGaugeBoard = 0 - - self.expGaugeBoard = 0 - - self.tooltipHP = 0 - self.tooltipSP = 0 - self.tooltipST = 0 - self.tooltipEXP = 0 - - self.mouseImage = None - - def __OnClickQuickPageUpButton(self): - player.SetQuickPage(player.GetQuickPage()-1) - - def __OnClickQuickPageDownButton(self): - player.SetQuickPage(player.GetQuickPage()+1) - - def SetToggleButtonEvent(self, eButton, kEventFunc): - self.toggleButtonDict[eButton].SetEvent(kEventFunc) - - def SetItemToolTip(self, tooltipItem): - self.tooltipItem = tooltipItem - - def SetSkillToolTip(self, tooltipSkill): - self.tooltipSkill = tooltipSkill - self.curSkillButton.SetSkillToolTip(self.tooltipSkill) - - ## Mouse Image - def ShowMouseImage(self): - self.mouseImage.SetTop() - self.mouseImage.Show() - - def HideMouseImage(self): - player.SetQuickCameraMode(False) - self.mouseImage.Hide() - - ## Gauge - def RefreshStatus(self): - curHP = player.GetStatus(player.HP) - maxHP = player.GetStatus(player.MAX_HP) - curSP = player.GetStatus(player.SP) - maxSP = player.GetStatus(player.MAX_SP) - curEXP = unsigned32(player.GetStatus(player.EXP)) - nextEXP = unsigned32(player.GetStatus(player.NEXT_EXP)) - recoveryHP = player.GetStatus(player.HP_RECOVERY) - recoverySP = player.GetStatus(player.SP_RECOVERY) - - self.RefreshStamina() - - self.SetHP(curHP, recoveryHP, maxHP) - self.SetSP(curSP, recoverySP, maxSP) - self.SetExperience(curEXP, nextEXP) - - def RefreshStamina(self): - curST = player.GetStatus(player.STAMINA) - maxST = player.GetStatus(player.MAX_STAMINA) - self.SetST(curST, maxST) - - def RefreshSkill(self): - self.curSkillButton.RefreshSkill() - for button in self.selectSkillButtonList: - button.RefreshSkill() - - def SkillClearCoolTime(self, usedSlotIndex): - QUICK_SLOT_SLOT_COUNT = 4 - slotIndex = 0 - - for slotWindow in self.quickslot: - for i in range(QUICK_SLOT_SLOT_COUNT): - (Type, Position) = player.GetLocalQuickSlot(slotIndex) - - if Type == player.SLOT_TYPE_SKILL: - if usedSlotIndex == Position: - slotWindow.SetSlotCoolTime(slotIndex, 0) - - return - - slotIndex += 1 - - def SetHP(self, curPoint, recoveryPoint, maxPoint): - curPoint = min(curPoint, maxPoint) - if maxPoint > 0: - self.hpGauge.SetPercentage(curPoint, maxPoint) - self.tooltipHP.SetText("%s : %d / %d" % (localeInfo.TASKBAR_HP, curPoint, maxPoint)) - - if 0 == recoveryPoint: - self.hpRecoveryGaugeBar.Hide() - else: - destPoint = min(maxPoint, curPoint + recoveryPoint) - newWidth = int(self.GAUGE_WIDTH * (float(destPoint) / float(maxPoint))) - self.hpRecoveryGaugeBar.SetSize(newWidth, self.GAUGE_HEIGHT) - self.hpRecoveryGaugeBar.Show() - - def SetSP(self, curPoint, recoveryPoint, maxPoint): - curPoint = min(curPoint, maxPoint) - if maxPoint > 0: - self.mpGauge.SetPercentage(curPoint, maxPoint) - self.tooltipSP.SetText("%s : %d / %d" % (localeInfo.TASKBAR_SP, curPoint, maxPoint)) - - if 0 == recoveryPoint: - self.spRecoveryGaugeBar.Hide() - else: - destPoint = min(maxPoint, curPoint + recoveryPoint) - newWidth = int(self.GAUGE_WIDTH * (float(destPoint) / float(maxPoint))) - self.spRecoveryGaugeBar.SetSize(newWidth, self.GAUGE_HEIGHT) - self.spRecoveryGaugeBar.Show() - - def SetST(self, curPoint, maxPoint): - curPoint = min(curPoint, maxPoint) - - if maxPoint > 0: - self.stGauge.SetPercentage(curPoint, maxPoint) - self.tooltipST.SetText("%s : %d / %d" % (localeInfo.TASKBAR_ST, curPoint, maxPoint)) - - def SetExperience(self, curPoint, maxPoint): - - curPoint = min(curPoint, maxPoint) - curPoint = max(curPoint, 0) - maxPoint = max(maxPoint, 0) - - quarterPoint = maxPoint // 4 - FullCount = 0 - - if 0 != quarterPoint: - FullCount = min(4, curPoint // quarterPoint) - - for i in range(4): - self.expGauge[i].Hide() - - for i in range(FullCount): - self.expGauge[i].SetRenderingRect(0.0, 0.0, 0.0, 0.0) - self.expGauge[i].Show() - - if 0 != quarterPoint: - if FullCount < 4: - Percentage = float(curPoint % quarterPoint) / quarterPoint - 1.0 - self.expGauge[FullCount].SetRenderingRect(0.0, Percentage, 0.0, 0.0) - self.expGauge[FullCount].Show() - - ##### - self.tooltipEXP.SetText("%s : %.2f%%" % (localeInfo.TASKBAR_EXP, float(curPoint) / max(1, float(maxPoint)) * 100)) - - - ## QuickSlot - def RefreshQuickSlot(self): - - pageNum = player.GetQuickPage() - - try: - self.quickPageNumImageBox.LoadImage(TaskBar.QUICKPAGE_NUMBER_FILENAME[pageNum]) - except: - pass - - startNumber = 0 - - for slot in self.quickslot: - for i in range(4): - slotNumber = i + startNumber - - (Type, Position) = player.GetLocalQuickSlot(slotNumber) - - if player.SLOT_TYPE_NONE == Type: - slot.ClearSlot(slotNumber) - continue - - if player.SLOT_TYPE_INVENTORY == Type: - itemIndex = player.GetItemIndex(Position) - itemCount = player.GetItemCount(Position) - - if itemCount <= 1: - itemCount = 0 - - slot.SetItemSlot(slotNumber, itemIndex, itemCount) - - ## 자동물약 (#72723, #72724) 특수처리 - 아이템인데도 슬롯에 활성화/비활성화 표시를 위한 작업임 - [hyo] - if constInfo.IS_AUTO_POTION(itemIndex): - # metinSocket - [0] : 활성화 여부, [1] : 사용한 양, [2] : 최대 용량 - metinSocket = [player.GetItemMetinSocket(Position, j) for j in range(player.METIN_SOCKET_MAX_NUM)] - - if 0 != int(metinSocket[0]): - slot.ActivateSlot(slotNumber) - else: - slot.DeactivateSlot(slotNumber) - elif player.SLOT_TYPE_SKILL == Type: - skillIndex = player.GetSkillIndex(Position) - - if 0 == skillIndex: - slot.ClearSlot(slotNumber) - - continue - - skillType = skill.GetSkillType(skillIndex) - - if skill.SKILL_TYPE_GUILD == skillType: - import guild - - skillGrade = 0 - skillLevel = guild.GetSkillLevel(Position) - - else: - skillGrade = player.GetSkillGrade(Position) - skillLevel = player.GetSkillLevel(Position) - - slot.SetSkillSlotNew(slotNumber, skillIndex, skillGrade, skillLevel) - slot.SetSlotCountNew(slotNumber, skillGrade, skillLevel) - slot.SetCoverButton(slotNumber) - - ## NOTE : CoolTime 체크 - if player.IsSkillCoolTime(Position) and skillLevel > 0: - (coolTime, elapsedTime) = player.GetSkillCoolTime(Position) - - slot.SetSlotCoolTime(slotNumber, coolTime, elapsedTime) - else: - if skillType != skill.SKILL_TYPE_GUILD and skillLevel <= 0: - slot.SetSlotCoolTime(slotNumber, 0, 0) - - ## NOTE : Activate 되어 있다면 아이콘도 업데이트 - if player.IsSkillActive(Position): - slot.ActivateSlot(slotNumber) - else: - slot.DeactivateSlot(slotNumber) - - elif player.SLOT_TYPE_EMOTION == Type: - - emotionIndex = Position - slot.SetEmotionSlot(slotNumber, emotionIndex) - slot.SetCoverButton(slotNumber) - slot.SetSlotCount(slotNumber, 0) - - slot.RefreshSlot() - startNumber += 4 - - def canAddQuickSlot(self, Type, slotNumber): - - if player.SLOT_TYPE_INVENTORY == Type: - - itemIndex = player.GetItemIndex(slotNumber) - return item.CanAddToQuickSlotItem(itemIndex) - - return True - - def AddQuickSlot(self, localSlotIndex): - AttachedSlotType = mouseModule.mouseController.GetAttachedType() - AttachedSlotNumber = mouseModule.mouseController.GetAttachedSlotNumber() - AttachedItemIndex = mouseModule.mouseController.GetAttachedItemIndex() - - # MR-3: Swap slots if dragging an item from another window already exists in quickslots and tries to replace another one - if AttachedSlotType != player.SLOT_TYPE_QUICK_SLOT: - # Search for the same item/skill/emotion in quickslots - for slotIdx in range(constInfo.QUICKSLOT_MAX_NUM): # Use your actual max quickslot count - (Type, Position) = player.GetLocalQuickSlot(slotIdx) - if Type == AttachedSlotType and Position == AttachedSlotNumber: - # Found, swap instead of replace - player.RequestMoveGlobalQuickSlotToLocalQuickSlot(slotIdx, localSlotIndex) - mouseModule.mouseController.DeattachObject() - self.RefreshQuickSlot() - return - # MR-3: -- END OF -- Swap slots if dragging an item from another window already exists in quickslots and tries to replace another one - - if player.SLOT_TYPE_QUICK_SLOT == AttachedSlotType: - player.RequestMoveGlobalQuickSlotToLocalQuickSlot(AttachedSlotNumber, localSlotIndex) - - elif player.SLOT_TYPE_EMOTION == AttachedSlotType: - - player.RequestAddLocalQuickSlot(localSlotIndex, AttachedSlotType, AttachedItemIndex) - - elif True == self.canAddQuickSlot(AttachedSlotType, AttachedSlotNumber): - - ## Online Code - player.RequestAddLocalQuickSlot(localSlotIndex, AttachedSlotType, AttachedSlotNumber) - - mouseModule.mouseController.DeattachObject() - self.RefreshQuickSlot() - - def SelectEmptyQuickSlot(self, slotIndex): - - if True == mouseModule.mouseController.isAttached(): - self.AddQuickSlot(slotIndex) - - def SelectItemQuickSlot(self, localQuickSlotIndex): - - if True == mouseModule.mouseController.isAttached(): - self.AddQuickSlot(localQuickSlotIndex) - - else: - globalQuickSlotIndex=player.LocalQuickSlotIndexToGlobalQuickSlotIndex(localQuickSlotIndex) - mouseModule.mouseController.AttachObject(self, player.SLOT_TYPE_QUICK_SLOT, globalQuickSlotIndex, globalQuickSlotIndex) - - def UnselectItemQuickSlot(self, localSlotIndex): - - if False == mouseModule.mouseController.isAttached(): - player.RequestUseLocalQuickSlot(localSlotIndex) - return - - elif mouseModule.mouseController.isAttached(): - mouseModule.mouseController.DeattachObject() - return - - - def OnUseSkill(self, usedSlotIndex, coolTime): - - QUICK_SLOT_SLOT_COUNT = 4 - slotIndex = 0 - - ## Current Skill Button - if usedSlotIndex == self.curSkillButton.GetSlotIndex(): - self.curSkillButton.Activate(coolTime) - - ## Quick Slot - for slotWindow in self.quickslot: - - for i in range(QUICK_SLOT_SLOT_COUNT): - - (Type, Position) = player.GetLocalQuickSlot(slotIndex) - - if Type == player.SLOT_TYPE_SKILL: - if usedSlotIndex == Position: - slotWindow.SetSlotCoolTime(slotIndex, coolTime) - return - - slotIndex += 1 - - def OnActivateSkill(self, usedSlotIndex): - slotIndex = 0 - - ## Current Skill Button - if usedSlotIndex == self.curSkillButton.GetSlotIndex(): - self.curSkillButton.Deactivate() - - ## Quick Slot - for slotWindow in self.quickslot: - - for i in range(4): - - (Type, Position) = player.GetLocalQuickSlot(slotIndex) - - if Type == player.SLOT_TYPE_SKILL: - if usedSlotIndex == Position: - slotWindow.ActivateSlot(slotIndex) - return - - slotIndex += 1 - - def OnDeactivateSkill(self, usedSlotIndex): - slotIndex = 0 - - ## Current Skill Button - if usedSlotIndex == self.curSkillButton.GetSlotIndex(): - self.curSkillButton.Deactivate() - - ## Quick Slot - for slotWindow in self.quickslot: - - for i in range(4): - - (Type, Position) = player.GetLocalQuickSlot(slotIndex) - - if Type == player.SLOT_TYPE_SKILL: - if usedSlotIndex == Position: - slotWindow.DeactivateSlot(slotIndex) - return - - slotIndex += 1 - - ## ToolTip - def OverInItem(self, slotNumber): - if mouseModule.mouseController.isAttached(): - return - - (Type, Position) = player.GetLocalQuickSlot(slotNumber) - - if player.SLOT_TYPE_INVENTORY == Type: - self.tooltipItem.SetInventoryItem(Position) - self.tooltipSkill.HideToolTip() - - elif player.SLOT_TYPE_SKILL == Type: - - skillIndex = player.GetSkillIndex(Position) - skillType = skill.GetSkillType(skillIndex) - - if skill.SKILL_TYPE_GUILD == skillType: - import guild - skillGrade = 0 - skillLevel = guild.GetSkillLevel(Position) - - else: - skillGrade = player.GetSkillGrade(Position) - skillLevel = player.GetSkillLevel(Position) - - self.tooltipSkill.SetSkillNew(Position, skillIndex, skillGrade, skillLevel) - self.tooltipItem.HideToolTip() - - def OverOutItem(self): - if 0 != self.tooltipItem: - self.tooltipItem.HideToolTip() - if 0 != self.tooltipSkill: - self.tooltipSkill.HideToolTip() - - def OnUpdate(self): - if app.GetGlobalTime() - self.lastUpdateQuickSlot > 500: - self.lastUpdateQuickSlot = app.GetGlobalTime() - self.RefreshQuickSlot() - - if True == self.hpGaugeBoard.IsIn(): - self.tooltipHP.Show() - else: - self.tooltipHP.Hide() - - if True == self.mpGaugeBoard.IsIn(): - self.tooltipSP.Show() - else: - self.tooltipSP.Hide() - - if True == self.stGaugeBoard.IsIn(): - self.tooltipST.Show() - else: - self.tooltipST.Hide() - - if True == self.expGaugeBoard.IsIn(): - self.tooltipEXP.Show() - else: - self.tooltipEXP.Hide() - - ## Skill - def ToggleLeftMouseButtonModeWindow(self): - - wndMouseButtonMode = self.mouseModeButtonList[self.MOUSE_BUTTON_LEFT] - - if True == wndMouseButtonMode.IsShow(): - - wndMouseButtonMode.Hide() - - else: - wndMouseButtonMode.Show() - - def ToggleRightMouseButtonModeWindow(self): - - wndMouseButtonMode = self.mouseModeButtonList[self.MOUSE_BUTTON_RIGHT] - - if True == wndMouseButtonMode.IsShow(): - - wndMouseButtonMode.Hide() - self.CloseSelectSkill() - - else: - wndMouseButtonMode.Show() - self.OpenSelectSkill() - - def OpenSelectSkill(self): - - PAGE_SLOT_COUNT = 6 - - (xSkillButton, y) = self.curSkillButton.GetGlobalPosition() - y -= (37 + 32 + 1) - - for key in self.skillCategoryNameList: - - appendCount = 0 - startNumber = self.skillPageStartSlotIndexDict[key] - x = xSkillButton - - getSkillIndex=player.GetSkillIndex - getSkillLevel=player.GetSkillLevel - for i in range(PAGE_SLOT_COUNT): - - skillIndex = getSkillIndex(startNumber+i) - skillLevel = getSkillLevel(startNumber+i) - - if 0 == skillIndex: - continue - if 0 == skillLevel: - continue - if skill.IsStandingSkill(skillIndex): - continue - - ## FIXME : 스킬 하나당 슬롯 하나씩 할당하는건 아무리 봐도 부하가 크다. - ## 이 부분은 시간을 나면 고치도록. - [levites] - skillButton = self.SkillButton() - skillButton.SetSkill(startNumber+i) - skillButton.SetPosition(x, y) - skillButton.SetSkillEvent(ui.__mem_func__(self.CloseSelectSkill), startNumber+i+1) - skillButton.SetSkillToolTip(self.tooltipSkill) - skillButton.SetTop() - skillButton.Show() - self.selectSkillButtonList.append(skillButton) - - appendCount += 1 - x -= 32 - - if appendCount > 0: - y -= 32 - - def CloseSelectSkill(self, slotIndex=-1): - - self.mouseModeButtonList[self.MOUSE_BUTTON_RIGHT].Hide() - for button in self.selectSkillButtonList: - button.Destroy() - - self.selectSkillButtonList = [] - - if -1 != slotIndex: - self.curSkillButton.Show() - self.curMouseModeButton[self.MOUSE_BUTTON_RIGHT].Hide() - player.SetMouseFunc(player.MBT_RIGHT, player.MBF_SKILL) - player.ChangeCurrentSkillNumberOnly(slotIndex-1) - else: - self.curSkillButton.Hide() - self.curMouseModeButton[self.MOUSE_BUTTON_RIGHT].Show() - - def SelectMouseButtonEvent(self, dir, event): - SetMouseButtonSetting(dir, event) - - self.CloseSelectSkill() - self.mouseModeButtonList[dir].Hide() - - btn = 0 - type = self.NONE - func = self.NONE - tooltip_text = "" - - if self.MOUSE_BUTTON_LEFT == dir: - type = player.MBT_LEFT - - elif self.MOUSE_BUTTON_RIGHT == dir: - type = player.MBT_RIGHT - - if self.EVENT_MOVE == event: - btn = self.mouseModeButtonList[dir].GetChild("button_move") - func = player.MBF_MOVE - tooltip_text = localeInfo.TASKBAR_MOVE - elif self.EVENT_ATTACK == event: - btn = self.mouseModeButtonList[dir].GetChild("button_attack") - func = player.MBF_ATTACK - tooltip_text = localeInfo.TASKBAR_ATTACK - elif self.EVENT_AUTO == event: - btn = self.mouseModeButtonList[dir].GetChild("button_auto_attack") - func = player.MBF_AUTO - tooltip_text = localeInfo.TASKBAR_AUTO - elif self.EVENT_MOVE_AND_ATTACK == event: - btn = self.mouseModeButtonList[dir].GetChild("button_move_and_attack") - func = player.MBF_SMART - tooltip_text = localeInfo.TASKBAR_ATTACK - elif self.EVENT_CAMERA == event: - btn = self.mouseModeButtonList[dir].GetChild("button_camera") - func = player.MBF_CAMERA - tooltip_text = localeInfo.TASKBAR_CAMERA - elif self.EVENT_SKILL == event: - btn = self.mouseModeButtonList[dir].GetChild("button_skill") - func = player.MBF_SKILL - tooltip_text = localeInfo.TASKBAR_SKILL - - if 0 != btn: - self.curMouseModeButton[dir].SetToolTipText(tooltip_text, 0, -18) - self.curMouseModeButton[dir].SetUpVisual(btn.GetUpVisualFileName()) - self.curMouseModeButton[dir].SetOverVisual(btn.GetOverVisualFileName()) - self.curMouseModeButton[dir].SetDownVisual(btn.GetDownVisualFileName()) - self.curMouseModeButton[dir].Show() - - player.SetMouseFunc(type, func) - - def OnChangeCurrentSkill(self, skillSlotNumber): - self.curSkillButton.SetSkill(skillSlotNumber) - self.curSkillButton.Show() - self.curMouseModeButton[self.MOUSE_BUTTON_RIGHT].Hide() - diff --git a/tools/root/uitip.py b/tools/root/uitip.py deleted file mode 100644 index cc820ed2..00000000 --- a/tools/root/uitip.py +++ /dev/null @@ -1,327 +0,0 @@ -import ui -import grp -import app - -import wndMgr - -class TextBar(ui.Window): - def __init__(self, width, height): - ui.Window.__init__(self) - self.handle = grp.CreateTextBar(width, height) - - def __del__(self): - ui.Window.__del__(self) - grp.DestroyTextBar(self.handle) - - def ClearBar(self): - grp.ClearTextBar(self.handle) - - def SetClipRect(self, x1, y1, x2, y2): - grp.SetTextBarClipRect(self.handle, x1, y1, x2, y2) - - def TextOut(self, x, y, text): - grp.TextBarTextOut(self.handle, x, y, text) - - def OnRender(self): - x, y = self.GetGlobalPosition() - grp.RenderTextBar(self.handle, x, y) - - def SetTextColor(self, r, g, b): - grp.TextBarSetTextColor(self.handle, r, g, b) - - def GetTextExtent(self, text): - return grp.TextBarGetTextExtent(self.handle, text) - -class TipBoard(ui.Bar): - - SCROLL_WAIT_TIME = 3.0 - TIP_DURATION = 5.0 - STEP_HEIGHT = 17 - - def __init__(self): - ui.Bar.__init__(self) - - self.AddFlag("not_pick") - self.tipList = [] - self.curPos = 0 - self.dstPos = 0 - self.nextScrollTime = 0 - - self.width = 370 - - self.SetPosition(0, 70) - self.SetSize(370, 20) - self.SetColor(grp.GenerateColor(0.0, 0.0, 0.0, 0.5)) - self.SetWindowHorizontalAlignCenter() - - self.__CreateTextBar() - - def __del__(self): - ui.Bar.__del__(self) - - def __CreateTextBar(self): - - x, y = self.GetGlobalPosition() - - self.textBar = TextBar(370, 300) - self.textBar.SetParent(self) - self.textBar.SetPosition(3, 5) - self.textBar.SetClipRect(0, y, wndMgr.GetScreenWidth(), y+18) - self.textBar.Show() - - def __CleanOldTip(self): - leaveList = [] - for tip in self.tipList: - madeTime = tip[0] - if app.GetTime() - madeTime > self.TIP_DURATION: - pass - else: - leaveList.append(tip) - - self.tipList = leaveList - - if not leaveList: - self.textBar.ClearBar() - self.Hide() - return - - self.__RefreshBoard() - - def __RefreshBoard(self): - - self.textBar.ClearBar() - - index = 0 - for tip in self.tipList: - text = tip[1] - self.textBar.TextOut(0, index*self.STEP_HEIGHT, text) - index += 1 - - def SetTip(self, text): - - if not app.IsVisibleNotice(): - return - - curTime = app.GetTime() - self.tipList.append((curTime, text)) - self.__RefreshBoard() - - self.nextScrollTime = app.GetTime() + 1.0 - - if not self.IsShow(): - self.curPos = -self.STEP_HEIGHT - self.dstPos = -self.STEP_HEIGHT - self.textBar.SetPosition(3, 5 - self.curPos) - self.Show() - - def OnUpdate(self): - - if not self.tipList: - self.Hide() - return - - if app.GetTime() > self.nextScrollTime: - self.nextScrollTime = app.GetTime() + self.SCROLL_WAIT_TIME - - self.dstPos = self.curPos + self.STEP_HEIGHT - - if self.dstPos > self.curPos: - self.curPos += 1 - self.textBar.SetPosition(3, 5 - self.curPos) - - if self.curPos > len(self.tipList)*self.STEP_HEIGHT: - self.curPos = -self.STEP_HEIGHT - self.dstPos = -self.STEP_HEIGHT - - self.__CleanOldTip() - - -class BigTextBar(TextBar): - def __init__(self, width, height, fontSize): - ui.Window.__init__(self) - self.handle = grp.CreateBigTextBar(width, height, fontSize) - - -class BigBoard(ui.Bar): - - SCROLL_WAIT_TIME = 5.0 - TIP_DURATION = 10.0 - FONT_WIDTH = 18 - FONT_HEIGHT = 18 - LINE_WIDTH = 500 - LINE_HEIGHT = FONT_HEIGHT + 5 - STEP_HEIGHT = LINE_HEIGHT * 2 - LINE_CHANGE_LIMIT_WIDTH = 350 - - FRAME_IMAGE_FILE_NAME_LIST = [ - "season1/interface/oxevent/frame_0.sub", - "season1/interface/oxevent/frame_1.sub", - "season1/interface/oxevent/frame_2.sub", - ] - - FRAME_IMAGE_STEP = 256 - - FRAME_BASE_X = -20 - FRAME_BASE_Y = -12 - - def __init__(self): - ui.Bar.__init__(self) - - self.AddFlag("not_pick") - self.tipList = [] - self.curPos = 0 - self.dstPos = 0 - self.nextScrollTime = 0 - - self.SetPosition(0, 150) - self.SetSize(512, 55) - self.SetColor(grp.GenerateColor(0.0, 0.0, 0.0, 0.5)) - self.SetWindowHorizontalAlignCenter() - - self.__CreateTextBar() - self.__LoadFrameImages() - - - def __LoadFrameImages(self): - x = self.FRAME_BASE_X - y = self.FRAME_BASE_Y - self.imgList = [] - for imgFileName in self.FRAME_IMAGE_FILE_NAME_LIST: - self.imgList.append(self.__LoadImage(x, y, imgFileName)) - x += self.FRAME_IMAGE_STEP - - def __LoadImage(self, x, y, fileName): - img = ui.ImageBox() - img.SetParent(self) - img.AddFlag("not_pick") - img.LoadImage(fileName) - img.SetPosition(x, y) - img.Show() - return img - - def __del__(self): - ui.Bar.__del__(self) - - def __CreateTextBar(self): - - x, y = self.GetGlobalPosition() - - self.textBar = BigTextBar(self.LINE_WIDTH, 300, self.FONT_HEIGHT) - self.textBar.SetParent(self) - self.textBar.SetPosition(6, 8) - self.textBar.SetTextColor(242, 231, 193) - self.textBar.SetClipRect(0, y+8, wndMgr.GetScreenWidth(), y+8+self.STEP_HEIGHT) - self.textBar.Show() - - def __CleanOldTip(self): - curTime = app.GetTime() - leaveList = [] - for madeTime, text in self.tipList: - if curTime + self.TIP_DURATION <= madeTime: - leaveList.append(text) - - self.tipList = leaveList - - if not leaveList: - self.textBar.ClearBar() - self.Hide() - return - - self.__RefreshBoard() - - def __RefreshBoard(self): - - self.textBar.ClearBar() - - if len(self.tipList) == 1: - checkTime, text = self.tipList[0] - (text_width, text_height) = self.textBar.GetTextExtent(text) - self.textBar.TextOut((500-text_width)//2, (self.STEP_HEIGHT-8-text_height)//2, text) - - else: - index = 0 - for checkTime, text in self.tipList: - (text_width, text_height) = self.textBar.GetTextExtent(text) - self.textBar.TextOut((500-text_width)//2, index*self.LINE_HEIGHT, text) - index += 1 - - def SetTip(self, text): - - if not app.IsVisibleNotice(): - return - - curTime = app.GetTime() - self.__AppendText(curTime, text) - self.__RefreshBoard() - - self.nextScrollTime = curTime + 1.0 - - if not self.IsShow(): - self.curPos = -self.STEP_HEIGHT - self.dstPos = -self.STEP_HEIGHT - self.textBar.SetPosition(3, 8 - self.curPos) - self.Show() - - def __AppendText(self, curTime, text): - import dbg - prevPos = 0 - while 1: - curPos = text.find(" ", prevPos) - if curPos < 0: - break - - (text_width, text_height) = self.textBar.GetTextExtent(text[:curPos]) - if text_width > self.LINE_CHANGE_LIMIT_WIDTH: - self.tipList.append((curTime, text[:prevPos])) - self.tipList.append((curTime, text[prevPos:])) - return - - prevPos = curPos + 1 - - self.tipList.append((curTime, text)) - - def OnUpdate(self): - - if not self.tipList: - self.Hide() - return - - if app.GetTime() > self.nextScrollTime: - self.nextScrollTime = app.GetTime() + self.SCROLL_WAIT_TIME - - self.dstPos = self.curPos + self.STEP_HEIGHT - - if self.dstPos > self.curPos: - self.curPos += 1 - self.textBar.SetPosition(3, 8 - self.curPos) - - if self.curPos > len(self.tipList)*self.LINE_HEIGHT: - self.curPos = -self.STEP_HEIGHT - self.dstPos = -self.STEP_HEIGHT - - self.__CleanOldTip() - -if __name__ == "__main__": - import app - import wndMgr - import systemSetting - import mouseModule - import grp - import ui - - #wndMgr.SetOutlineFlag(True) - - app.SetMouseHandler(mouseModule.mouseController) - app.SetHairColorEnable(True) - wndMgr.SetMouseHandler(mouseModule.mouseController) - wndMgr.SetScreenSize(systemSetting.GetWidth(), systemSetting.GetHeight()) - app.Create("METIN2 CLOSED BETA", systemSetting.GetWidth(), systemSetting.GetHeight(), 1) - mouseModule.mouseController.Create() - - wnd = BigBoard() - wnd.Show() - wnd.SetTip("안녕하세요") - wnd.SetTip("저는 빗자루 입니다") - - app.Loop() - diff --git a/tools/root/uitooltip.py b/tools/root/uitooltip.py deleted file mode 100644 index 3ff2dc74..00000000 --- a/tools/root/uitooltip.py +++ /dev/null @@ -1,2718 +0,0 @@ -import dbg -import player -import item -import grp -import wndMgr -import skill -import shop -import exchange -import grpText -import safebox -import localeInfo -import app -import background -import nonplayer -import chr - -import ui -import mouseModule -import constInfo - -WARP_SCROLLS = [22011, 22000, 22010] - -# Tooltip max width when descriptions are long -DESC_MAX_WIDTH = 280 - -def chop(n): - return round(n - 0.5, 1) - -def SplitDescriptionByPixelWidth(desc, maxWidthPx, fontName): - """ - Splits description into lines that fit in maxWidthPx, measured in pixels. - Respects forced breaks: '\n' and '|'. - """ - if not desc: - return [] - - # Normalize breaks - desc = desc.replace("\r\n", "\n").replace("\r", "\n").replace("|", "\n") - - measure = ui.TextLine() - measure.SetFontName(fontName) - - out = [] - for raw in desc.split("\n"): - raw = raw.strip() - if not raw: - continue - - tokens = raw.split() - cur = "" - - for token in tokens: - candidate = token if not cur else (cur + " " + token) - - measure.SetText(candidate) - w, _ = measure.GetTextSize() - - if w <= maxWidthPx: - cur = candidate - else: - # push current line if it exists - if cur: - out.append(cur) - - # token alone might be wider than max: keep it as its own line - # (or you could implement character splitting, but this is safer) - cur = token - - if cur: - out.append(cur) - - return out - -################################################################################################### -## ToolTip -## NOTE: Currently Item and Skill are specialized through inheritance -## However, this doesn't seem very meaningful -## -class ToolTip(ui.ThinBoard): - - TOOL_TIP_WIDTH = 190 - TOOL_TIP_HEIGHT = 10 - - TEXT_LINE_HEIGHT = 17 - - TITLE_COLOR = grp.GenerateColor(0.9490, 0.9058, 0.7568, 1.0) - SPECIAL_TITLE_COLOR = grp.GenerateColor(1.0, 0.7843, 0.0, 1.0) - NORMAL_COLOR = grp.GenerateColor(0.7607, 0.7607, 0.7607, 1.0) - FONT_COLOR = grp.GenerateColor(0.7607, 0.7607, 0.7607, 1.0) - PRICE_COLOR = 0xffFFB96D - - HIGH_PRICE_COLOR = SPECIAL_TITLE_COLOR - MIDDLE_PRICE_COLOR = grp.GenerateColor(0.85, 0.85, 0.85, 1.0) - LOW_PRICE_COLOR = grp.GenerateColor(0.7, 0.7, 0.7, 1.0) - - ENABLE_COLOR = grp.GenerateColor(0.7607, 0.7607, 0.7607, 1.0) - DISABLE_COLOR = grp.GenerateColor(0.9, 0.4745, 0.4627, 1.0) - - NEGATIVE_COLOR = grp.GenerateColor(0.9, 0.4745, 0.4627, 1.0) - POSITIVE_COLOR = grp.GenerateColor(0.5411, 0.7254, 0.5568, 1.0) - SPECIAL_POSITIVE_COLOR = grp.GenerateColor(0.6911, 0.8754, 0.7068, 1.0) - SPECIAL_POSITIVE_COLOR2 = grp.GenerateColor(0.8824, 0.9804, 0.8824, 1.0) - - CONDITION_COLOR = 0xffBEB47D - CAN_LEVEL_UP_COLOR = 0xff8EC292 - CANNOT_LEVEL_UP_COLOR = DISABLE_COLOR - NEED_SKILL_POINT_COLOR = 0xff9A9CDB - - def __init__(self, width = TOOL_TIP_WIDTH, isPickable=False): - ui.ThinBoard.__init__(self, "TOP_MOST") - - if isPickable: - pass - else: - self.AddFlag("not_pick") - - self.AddFlag("float") - - self.followFlag = True - self.toolTipWidth = width - - self.xPos = -1 - self.yPos = -1 - - self.timeInfoList = [] - - self.defFontName = localeInfo.UI_DEF_FONT - self.ClearToolTip() - - def __del__(self): - ui.ThinBoard.__del__(self) - - def ClearToolTip(self): - self.toolTipHeight = 12 - self.childrenList = [] - self.timeInfoList = [] - - def SetFollow(self, flag): - self.followFlag = flag - - def SetDefaultFontName(self, fontName): - self.defFontName = fontName - - def AppendSpace(self, size): - self.toolTipHeight += size - self.ResizeToolTip() - - def AppendHorizontalLine(self): - - for i in range(2): - horizontalLine = ui.Line() - horizontalLine.SetParent(self) - horizontalLine.SetPosition(0, self.toolTipHeight + 3 + i) - horizontalLine.SetWindowHorizontalAlignCenter() - horizontalLine.SetSize(150, 0) - horizontalLine.Show() - - if 0 == i: - horizontalLine.SetColor(0xff555555) - else: - horizontalLine.SetColor(0xff000000) - - self.childrenList.append(horizontalLine) - - self.toolTipHeight += 11 - self.ResizeToolTip() - - def AlignHorizonalCenter(self): - for child in self.childrenList: - (x, y) = child.GetLocalPosition() - - child.SetPosition(self.toolTipWidth // 2, y) - - self.ResizeToolTip() - - def AlignTextLineHorizonalCenter(self): - for child in self.childrenList: - # MR-10: Fix element centering in tooltips - if type(child).__name__ == "TextLine" and getattr(child, "_centerAlign", False): - (x, y) = child.GetLocalPosition() - - child.SetPosition(self.toolTipWidth // 2, y) - # MR-10: -- END OF -- Fix element centering in tooltips - - self.ResizeToolTip() - - def AutoAppendTextLine(self, text, color = FONT_COLOR, centerAlign = True): - textLine = ui.TextLine() - - textLine.SetParent(self) - textLine.SetFontName(self.defFontName) - textLine.SetPackedFontColor(color) - textLine.SetText(text) - textLine.SetOutline() - textLine.SetFeather(False) - textLine.Show() - - # MR-10: Fix element centering in tooltips - textLine._centerAlign = centerAlign - # MR-10: -- END OF -- Fix element centering in tooltips - - if centerAlign: - textLine.SetPosition(self.toolTipWidth // 2, self.toolTipHeight) - textLine.SetHorizontalAlignCenter() - - else: - textLine.SetPosition(10, self.toolTipHeight) - - self.childrenList.append(textLine) - - (textWidth, textHeight)=textLine.GetTextSize() - - textWidth += 40 - textHeight += 5 - - if self.toolTipWidth < textWidth: - self.toolTipWidth = textWidth - - self.toolTipHeight += textHeight - - return textLine - - def AppendTextLine(self, text, color=FONT_COLOR, centerAlign=True, show=True): - textLine = ui.TextLine() - textLine.SetParent(self) - textLine.SetFontName(self.defFontName) - textLine.SetPackedFontColor(color) - textLine.SetText(text) - textLine.SetOutline() - textLine.SetFeather(False) - if show: - textLine.Show() - - # MR-10: Fix element centering in tooltips - textLine._centerAlign = centerAlign - # MR-10: -- END OF -- Fix element centering in tooltips - - textWidth, _ = textLine.GetTextSize() - textWidth += 20 - - tooltipWidthChanged = False - if self.toolTipWidth < textWidth: - self.toolTipWidth = textWidth - tooltipWidthChanged = True - - if centerAlign: - textLine.SetHorizontalAlignCenter() - textLine.SetPosition(self.toolTipWidth // 2, self.toolTipHeight) - else: - textLine.SetPosition(10, self.toolTipHeight) - - self.childrenList.append(textLine) - - self.toolTipHeight += self.TEXT_LINE_HEIGHT - self.ResizeToolTip() - - if tooltipWidthChanged: - self.AlignTextLineHorizonalCenter() - - return textLine - - def AppendDescription(self, desc, color = FONT_COLOR): - if not desc: - return - - # We wrap based on pixels, not on "limit" columns. - # This makes it consistent across languages/fonts. - padding = 20 # left+right safe padding inside tooltip - maxWidthPx = max(50, self.toolTipWidth - padding) - - lines = SplitDescriptionByPixelWidth(desc, maxWidthPx, self.defFontName) - if not lines: - return - - self.AppendSpace(5) - for line in lines: - self.AppendTextLine(line, color) - - def ResizeToolTip(self): - self.SetSize(self.toolTipWidth, self.TOOL_TIP_HEIGHT + self.toolTipHeight) - - def SetTitle(self, name): - self.AppendTextLine(name, self.TITLE_COLOR) - - def GetLimitTextLineColor(self, curValue, limitValue): - if curValue < limitValue: - return self.DISABLE_COLOR - - return self.ENABLE_COLOR - - def GetChangeTextLineColor(self, value, isSpecial=False): - if value > 0: - if isSpecial: - return self.SPECIAL_POSITIVE_COLOR - else: - return self.POSITIVE_COLOR - - if 0 == value: - return self.NORMAL_COLOR - - return self.NEGATIVE_COLOR - - def SetToolTipPosition(self, x = -1, y = -1): - self.xPos = x - self.yPos = y - - def ShowToolTip(self): - self.SetTop() - self.Show() - - self.OnUpdate() - - def HideToolTip(self): - self.Hide() - - def OnUpdate(self): - - if not self.followFlag: - return - - for timeText in self.timeInfoList: - if timeText["line"]: - leftSec = max(0, timeText["value"] - app.GetGlobalTimeStamp()) - if not self.isShopItem: - timeText["line"].SetText(localeInfo.LEFT_TIME + ": " + localeInfo.RTSecondToDHMS(leftSec)) - - x = 0 - y = 0 - width = self.GetWidth() - height = self.toolTipHeight - - if -1 == self.xPos and -1 == self.yPos: - - (mouseX, mouseY) = wndMgr.GetMousePosition() - - if mouseY < wndMgr.GetScreenHeight() - 300: - y = mouseY + 40 - else: - y = mouseY - height - 30 - - x = mouseX - width // 2 - - else: - - x = self.xPos - width // 2 - y = self.yPos - height - - x = max(x, 0) - y = max(y, 0) - x = min(x + width // 2, wndMgr.GetScreenWidth() - width // 2) - width // 2 - y = min(y + self.GetHeight(), wndMgr.GetScreenHeight()) - self.GetHeight() - - parentWindow = self.GetParentProxy() - if parentWindow: - (gx, gy) = parentWindow.GetGlobalPosition() - x -= gx - y -= gy - - self.SetPosition(x, y) - -class ItemToolTip(ToolTip): - CHARACTER_NAMES = ( - localeInfo.TOOLTIP_WARRIOR, - localeInfo.TOOLTIP_ASSASSIN, - localeInfo.TOOLTIP_SURA, - localeInfo.TOOLTIP_SHAMAN - ) - - CHARACTER_COUNT = len(CHARACTER_NAMES) - WEAR_NAMES = ( - localeInfo.TOOLTIP_ARMOR, - localeInfo.TOOLTIP_HELMET, - localeInfo.TOOLTIP_SHOES, - localeInfo.TOOLTIP_WRISTLET, - localeInfo.TOOLTIP_WEAPON, - localeInfo.TOOLTIP_NECK, - localeInfo.TOOLTIP_EAR, - localeInfo.TOOLTIP_UNIQUE, - localeInfo.TOOLTIP_SHIELD, - localeInfo.TOOLTIP_ARROW, - ) - WEAR_COUNT = len(WEAR_NAMES) - - AFFECT_DICT = { - item.APPLY_MAX_HP : localeInfo.TOOLTIP_MAX_HP, - item.APPLY_MAX_SP : localeInfo.TOOLTIP_MAX_SP, - item.APPLY_CON : localeInfo.TOOLTIP_CON, - item.APPLY_INT : localeInfo.TOOLTIP_INT, - item.APPLY_STR : localeInfo.TOOLTIP_STR, - item.APPLY_DEX : localeInfo.TOOLTIP_DEX, - item.APPLY_ATT_SPEED : localeInfo.TOOLTIP_ATT_SPEED, - item.APPLY_MOV_SPEED : localeInfo.TOOLTIP_MOV_SPEED, - item.APPLY_CAST_SPEED : localeInfo.TOOLTIP_CAST_SPEED, - item.APPLY_HP_REGEN : localeInfo.TOOLTIP_HP_REGEN, - item.APPLY_SP_REGEN : localeInfo.TOOLTIP_SP_REGEN, - item.APPLY_POISON_PCT : localeInfo.TOOLTIP_APPLY_POISON_PCT, - item.APPLY_STUN_PCT : localeInfo.TOOLTIP_APPLY_STUN_PCT, - item.APPLY_SLOW_PCT : localeInfo.TOOLTIP_APPLY_SLOW_PCT, - item.APPLY_CRITICAL_PCT : localeInfo.TOOLTIP_APPLY_CRITICAL_PCT, - item.APPLY_PENETRATE_PCT : localeInfo.TOOLTIP_APPLY_PENETRATE_PCT, - - item.APPLY_ATTBONUS_WARRIOR : localeInfo.TOOLTIP_APPLY_ATTBONUS_WARRIOR, - item.APPLY_ATTBONUS_ASSASSIN : localeInfo.TOOLTIP_APPLY_ATTBONUS_ASSASSIN, - item.APPLY_ATTBONUS_SURA : localeInfo.TOOLTIP_APPLY_ATTBONUS_SURA, - item.APPLY_ATTBONUS_SHAMAN : localeInfo.TOOLTIP_APPLY_ATTBONUS_SHAMAN, - item.APPLY_ATTBONUS_MONSTER : localeInfo.TOOLTIP_APPLY_ATTBONUS_MONSTER, - - item.APPLY_ATTBONUS_HUMAN : localeInfo.TOOLTIP_APPLY_ATTBONUS_HUMAN, - item.APPLY_ATTBONUS_ANIMAL : localeInfo.TOOLTIP_APPLY_ATTBONUS_ANIMAL, - item.APPLY_ATTBONUS_ORC : localeInfo.TOOLTIP_APPLY_ATTBONUS_ORC, - item.APPLY_ATTBONUS_MILGYO : localeInfo.TOOLTIP_APPLY_ATTBONUS_MILGYO, - item.APPLY_ATTBONUS_UNDEAD : localeInfo.TOOLTIP_APPLY_ATTBONUS_UNDEAD, - item.APPLY_ATTBONUS_DEVIL : localeInfo.TOOLTIP_APPLY_ATTBONUS_DEVIL, - item.APPLY_STEAL_HP : localeInfo.TOOLTIP_APPLY_STEAL_HP, - item.APPLY_STEAL_SP : localeInfo.TOOLTIP_APPLY_STEAL_SP, - item.APPLY_MANA_BURN_PCT : localeInfo.TOOLTIP_APPLY_MANA_BURN_PCT, - item.APPLY_DAMAGE_SP_RECOVER : localeInfo.TOOLTIP_APPLY_DAMAGE_SP_RECOVER, - item.APPLY_BLOCK : localeInfo.TOOLTIP_APPLY_BLOCK, - item.APPLY_DODGE : localeInfo.TOOLTIP_APPLY_DODGE, - item.APPLY_RESIST_SWORD : localeInfo.TOOLTIP_APPLY_RESIST_SWORD, - item.APPLY_RESIST_TWOHAND : localeInfo.TOOLTIP_APPLY_RESIST_TWOHAND, - item.APPLY_RESIST_DAGGER : localeInfo.TOOLTIP_APPLY_RESIST_DAGGER, - item.APPLY_RESIST_BELL : localeInfo.TOOLTIP_APPLY_RESIST_BELL, - item.APPLY_RESIST_FAN : localeInfo.TOOLTIP_APPLY_RESIST_FAN, - item.APPLY_RESIST_BOW : localeInfo.TOOLTIP_RESIST_BOW, - item.APPLY_RESIST_FIRE : localeInfo.TOOLTIP_RESIST_FIRE, - item.APPLY_RESIST_ELEC : localeInfo.TOOLTIP_RESIST_ELEC, - item.APPLY_RESIST_MAGIC : localeInfo.TOOLTIP_RESIST_MAGIC, - item.APPLY_RESIST_WIND : localeInfo.TOOLTIP_APPLY_RESIST_WIND, - item.APPLY_REFLECT_MELEE : localeInfo.TOOLTIP_APPLY_REFLECT_MELEE, - item.APPLY_REFLECT_CURSE : localeInfo.TOOLTIP_APPLY_REFLECT_CURSE, - item.APPLY_POISON_REDUCE : localeInfo.TOOLTIP_APPLY_POISON_REDUCE, - item.APPLY_KILL_SP_RECOVER : localeInfo.TOOLTIP_APPLY_KILL_SP_RECOVER, - item.APPLY_EXP_DOUBLE_BONUS : localeInfo.TOOLTIP_APPLY_EXP_DOUBLE_BONUS, - item.APPLY_GOLD_DOUBLE_BONUS : localeInfo.TOOLTIP_APPLY_GOLD_DOUBLE_BONUS, - item.APPLY_ITEM_DROP_BONUS : localeInfo.TOOLTIP_APPLY_ITEM_DROP_BONUS, - item.APPLY_POTION_BONUS : localeInfo.TOOLTIP_APPLY_POTION_BONUS, - item.APPLY_KILL_HP_RECOVER : localeInfo.TOOLTIP_APPLY_KILL_HP_RECOVER, - item.APPLY_IMMUNE_STUN : localeInfo.TOOLTIP_APPLY_IMMUNE_STUN, - item.APPLY_IMMUNE_SLOW : localeInfo.TOOLTIP_APPLY_IMMUNE_SLOW, - item.APPLY_IMMUNE_FALL : localeInfo.TOOLTIP_APPLY_IMMUNE_FALL, - item.APPLY_BOW_DISTANCE : localeInfo.TOOLTIP_BOW_DISTANCE, - item.APPLY_DEF_GRADE_BONUS : localeInfo.TOOLTIP_DEF_GRADE, - item.APPLY_ATT_GRADE_BONUS : localeInfo.TOOLTIP_ATT_GRADE, - item.APPLY_MAGIC_ATT_GRADE : localeInfo.TOOLTIP_MAGIC_ATT_GRADE, - item.APPLY_MAGIC_DEF_GRADE : localeInfo.TOOLTIP_MAGIC_DEF_GRADE, - item.APPLY_MAX_STAMINA : localeInfo.TOOLTIP_MAX_STAMINA, - item.APPLY_MALL_ATTBONUS : localeInfo.TOOLTIP_MALL_ATTBONUS, - item.APPLY_MALL_DEFBONUS : localeInfo.TOOLTIP_MALL_DEFBONUS, - item.APPLY_MALL_EXPBONUS : localeInfo.TOOLTIP_MALL_EXPBONUS, - item.APPLY_MALL_ITEMBONUS : localeInfo.TOOLTIP_MALL_ITEMBONUS, - item.APPLY_MALL_GOLDBONUS : localeInfo.TOOLTIP_MALL_GOLDBONUS, - item.APPLY_SKILL_DAMAGE_BONUS : localeInfo.TOOLTIP_SKILL_DAMAGE_BONUS, - item.APPLY_NORMAL_HIT_DAMAGE_BONUS : localeInfo.TOOLTIP_NORMAL_HIT_DAMAGE_BONUS, - item.APPLY_SKILL_DEFEND_BONUS : localeInfo.TOOLTIP_SKILL_DEFEND_BONUS, - item.APPLY_NORMAL_HIT_DEFEND_BONUS : localeInfo.TOOLTIP_NORMAL_HIT_DEFEND_BONUS, - item.APPLY_PC_BANG_EXP_BONUS : localeInfo.TOOLTIP_MALL_EXPBONUS_P_STATIC, - item.APPLY_PC_BANG_DROP_BONUS : localeInfo.TOOLTIP_MALL_ITEMBONUS_P_STATIC, - item.APPLY_RESIST_WARRIOR : localeInfo.TOOLTIP_APPLY_RESIST_WARRIOR, - item.APPLY_RESIST_ASSASSIN : localeInfo.TOOLTIP_APPLY_RESIST_ASSASSIN, - item.APPLY_RESIST_SURA : localeInfo.TOOLTIP_APPLY_RESIST_SURA, - item.APPLY_RESIST_SHAMAN : localeInfo.TOOLTIP_APPLY_RESIST_SHAMAN, - item.APPLY_MAX_HP_PCT : localeInfo.TOOLTIP_APPLY_MAX_HP_PCT, - item.APPLY_MAX_SP_PCT : localeInfo.TOOLTIP_APPLY_MAX_SP_PCT, - item.APPLY_ENERGY : localeInfo.TOOLTIP_ENERGY, - item.APPLY_COSTUME_ATTR_BONUS : localeInfo.TOOLTIP_COSTUME_ATTR_BONUS, - - item.APPLY_MAGIC_ATTBONUS_PER : localeInfo.TOOLTIP_MAGIC_ATTBONUS_PER, - item.APPLY_MELEE_MAGIC_ATTBONUS_PER : localeInfo.TOOLTIP_MELEE_MAGIC_ATTBONUS_PER, - item.APPLY_RESIST_ICE : localeInfo.TOOLTIP_RESIST_ICE, - item.APPLY_RESIST_EARTH : localeInfo.TOOLTIP_RESIST_EARTH, - item.APPLY_RESIST_DARK : localeInfo.TOOLTIP_RESIST_DARK, - item.APPLY_ANTI_CRITICAL_PCT : localeInfo.TOOLTIP_ANTI_CRITICAL_PCT, - item.APPLY_ANTI_PENETRATE_PCT : localeInfo.TOOLTIP_ANTI_PENETRATE_PCT, - } - - ATTRIBUTE_NEED_WIDTH = { - 23 : 230, - 24 : 230, - 25 : 230, - 26 : 220, - 27 : 210, - - 35 : 210, - 36 : 210, - 37 : 210, - 38 : 210, - 39 : 210, - 40 : 210, - 41 : 210, - - 42 : 220, - 43 : 230, - 45 : 230, - } - - ANTI_FLAG_DICT = { - 0 : item.ITEM_ANTIFLAG_WARRIOR, - 1 : item.ITEM_ANTIFLAG_ASSASSIN, - 2 : item.ITEM_ANTIFLAG_SURA, - 3 : item.ITEM_ANTIFLAG_SHAMAN, - } - - FONT_COLOR = grp.GenerateColor(0.7607, 0.7607, 0.7607, 1.0) - - def __init__(self, *args, **kwargs): - ToolTip.__init__(self, *args, **kwargs) - - self.itemVnum = 0 - self.metinSlot = [] - self.isShopItem = False - # When displaying item tooltip, if the current character cannot equip the item, force it to use Disable Color (already works this way but needed ability to turn it off) - self.bCannotUseItemForceSetDisableColor = True - - self.itemWindowType = None - self.itemSlotIndex = -1 - self.wndDragonSoul = None - self.dsActivatedTimeCache = {} - # MR-10: Add accessorySocketTimeCache for real-time remaining time display of accessory sockets. - - cache = getattr(app, "_accessorySocketTimeCache", None) - - if cache is None: - cache = getattr(player, "_accessorySocketTimeCache", None) - if cache is None: - cache = constInfo.ACCESSORY_SOCKET_TIME_CACHE - - app._accessorySocketTimeCache = cache - player._accessorySocketTimeCache = cache - - constInfo.ACCESSORY_SOCKET_TIME_CACHE = cache - - self.accessorySocketTimeCache = cache - # MR-10: -- END OF -- Add accessorySocketTimeCache for real-time remaining time display of accessory sockets. - self.hairIcon = None - - def __del__(self): - ToolTip.__del__(self) - self.metinSlot = None - - def SetDragonSoulWindow(self, wnd): - self.wndDragonSoul = wnd - - def ClearDragonSoulTimeCache(self): - self.dsActivatedTimeCache = {} - - # MR-11: Fix Dragon stones timer auto-start - def WarmDragonSoulTimeCache(self, slotNumbers): - if not slotNumbers: - return - - now = app.GetGlobalTimeStamp() - - for slotNumber in slotNumbers: - itemVnum = player.GetItemIndex(slotNumber) - - if itemVnum == 0: - continue - - item.SelectItem(itemVnum) - - remainSec = None - - for i in range(item.LIMIT_MAX_NUM): - (limitType, limitValue) = item.GetLimit(i) - - if item.LIMIT_TIMER_BASED_ON_WEAR == limitType: - remainSec = player.GetItemMetinSocket(player.INVENTORY, slotNumber, 0) - - break - - if remainSec is None or remainSec <= 0: - continue - - key = (itemVnum, slotNumber) - self.dsActivatedTimeCache[key] = { "remainSec": remainSec, "endTime": now + remainSec } - # MR-11: -- END OF -- Fix Dragon stones timer auto-start - - def SetCannotUseItemForceSetDisableColor(self, enable): - self.bCannotUseItemForceSetDisableColor = enable - - def CanEquip(self): - if not item.IsEquipmentVID(self.itemVnum): - return True - - race = player.GetRace() - job = chr.RaceToJob(race) - if job not in self.ANTI_FLAG_DICT: - return False - - if item.IsAntiFlag(self.ANTI_FLAG_DICT[job]): - return False - - sex = chr.RaceToSex(race) - - MALE = 1 - FEMALE = 0 - - if item.IsAntiFlag(item.ITEM_ANTIFLAG_MALE) and sex == MALE: - return False - - if item.IsAntiFlag(item.ITEM_ANTIFLAG_FEMALE) and sex == FEMALE: - return False - - for i in range(item.LIMIT_MAX_NUM): - (limitType, limitValue) = item.GetLimit(i) - - if item.LIMIT_LEVEL == limitType: - if player.GetStatus(player.LEVEL) < limitValue: - return False - """ - elif item.LIMIT_STR == limitType: - if player.GetStatus(player.ST) < limitValue: - return False - elif item.LIMIT_DEX == limitType: - if player.GetStatus(player.DX) < limitValue: - return False - elif item.LIMIT_INT == limitType: - if player.GetStatus(player.IQ) < limitValue: - return False - elif item.LIMIT_CON == limitType: - if player.GetStatus(player.HT) < limitValue: - return False - """ - - return True - - def AppendTextLine(self, text, color = FONT_COLOR, centerAlign = True): - if not self.CanEquip() and self.bCannotUseItemForceSetDisableColor: - color = self.DISABLE_COLOR - - return ToolTip.AppendTextLine(self, text, color, centerAlign) - - def AppendTextLineTime(self, endTime, getLimit): - color = self.FONT_COLOR - - if not self.CanEquip() and self.bCannotUseItemForceSetDisableColor: - color = self.DISABLE_COLOR - - return ToolTip.AppendTextLineTime(self, endTime, getLimit, color) - - def ClearToolTip(self): - # MR-10: Fix element centering in tooltips - hairIcon = getattr(self, "hairIcon", None) - - if hairIcon: - hairIcon.Hide() - self.hairIcon = None - # MR-10: -- END OF -- Fix element centering in tooltips - - self.isShopItem = False - self.toolTipWidth = self.TOOL_TIP_WIDTH - self.itemWindowType = None - self.itemSlotIndex = -1 - ToolTip.ClearToolTip(self) - - def SetInventoryItem(self, slotIndex, window_type = player.INVENTORY): - itemVnum = player.GetItemIndex(window_type, slotIndex) - if 0 == itemVnum: - return - - self.ClearToolTip() - if shop.IsOpen(): - if not shop.IsPrivateShop(): - item.SelectItem(itemVnum) - self.AppendSellingPrice(player.GetISellItemPrice(window_type, slotIndex)) - - metinSlot = [player.GetItemMetinSocket(window_type, slotIndex, i) for i in range(player.METIN_SOCKET_MAX_NUM)] - attrSlot = [player.GetItemAttribute(window_type, slotIndex, i) for i in range(player.ATTRIBUTE_SLOT_MAX_NUM)] - - self.itemWindowType = window_type - self.itemSlotIndex = slotIndex - self.AddItemData(itemVnum, metinSlot, attrSlot) - - def SetShopItem(self, slotIndex): - itemVnum = shop.GetItemID(slotIndex) - if 0 == itemVnum: - return - - price = shop.GetItemPrice(slotIndex) - self.ClearToolTip() - self.itemWindowType = None - self.itemSlotIndex = slotIndex - self.isShopItem = True - - metinSlot = [] - for i in range(player.METIN_SOCKET_MAX_NUM): - metinSlot.append(shop.GetItemMetinSocket(slotIndex, i)) - attrSlot = [] - for i in range(player.ATTRIBUTE_SLOT_MAX_NUM): - attrSlot.append(shop.GetItemAttribute(slotIndex, i)) - - self.AddItemData(itemVnum, metinSlot, attrSlot) - self.AppendPrice(price) - - def SetShopItemBySecondaryCoin(self, slotIndex): - itemVnum = shop.GetItemID(slotIndex) - if 0 == itemVnum: - return - - price = shop.GetItemPrice(slotIndex) - self.ClearToolTip() - self.itemWindowType = None - self.itemSlotIndex = slotIndex - self.isShopItem = True - - metinSlot = [] - for i in range(player.METIN_SOCKET_MAX_NUM): - metinSlot.append(shop.GetItemMetinSocket(slotIndex, i)) - attrSlot = [] - for i in range(player.ATTRIBUTE_SLOT_MAX_NUM): - attrSlot.append(shop.GetItemAttribute(slotIndex, i)) - - self.AddItemData(itemVnum, metinSlot, attrSlot) - self.AppendPriceBySecondaryCoin(price) - - def SetExchangeOwnerItem(self, slotIndex): - itemVnum = exchange.GetItemVnumFromSelf(slotIndex) - if 0 == itemVnum: - return - - self.ClearToolTip() - self.itemWindowType = None - self.itemSlotIndex = slotIndex - - metinSlot = [] - for i in range(player.METIN_SOCKET_MAX_NUM): - metinSlot.append(exchange.GetItemMetinSocketFromSelf(slotIndex, i)) - attrSlot = [] - for i in range(player.ATTRIBUTE_SLOT_MAX_NUM): - attrSlot.append(exchange.GetItemAttributeFromSelf(slotIndex, i)) - self.AddItemData(itemVnum, metinSlot, attrSlot) - - def SetExchangeTargetItem(self, slotIndex): - itemVnum = exchange.GetItemVnumFromTarget(slotIndex) - if 0 == itemVnum: - return - - self.ClearToolTip() - self.itemWindowType = None - self.itemSlotIndex = slotIndex - - metinSlot = [] - for i in range(player.METIN_SOCKET_MAX_NUM): - metinSlot.append(exchange.GetItemMetinSocketFromTarget(slotIndex, i)) - attrSlot = [] - for i in range(player.ATTRIBUTE_SLOT_MAX_NUM): - attrSlot.append(exchange.GetItemAttributeFromTarget(slotIndex, i)) - self.AddItemData(itemVnum, metinSlot, attrSlot) - - def SetPrivateShopBuilderItem(self, invenType, invenPos, privateShopSlotIndex): - itemVnum = player.GetItemIndex(invenType, invenPos) - if 0 == itemVnum: - return - - item.SelectItem(itemVnum) - self.ClearToolTip() - self.itemWindowType = None - self.itemSlotIndex = privateShopSlotIndex - self.AppendSellingPrice(shop.GetPrivateShopItemPrice(invenType, invenPos)) - - metinSlot = [] - for i in range(player.METIN_SOCKET_MAX_NUM): - metinSlot.append(player.GetItemMetinSocket(invenPos, i)) - attrSlot = [] - for i in range(player.ATTRIBUTE_SLOT_MAX_NUM): - attrSlot.append(player.GetItemAttribute(invenPos, i)) - - self.AddItemData(itemVnum, metinSlot, attrSlot) - - def SetSafeBoxItem(self, slotIndex): - itemVnum = safebox.GetItemID(slotIndex) - if 0 == itemVnum: - return - - self.ClearToolTip() - self.itemWindowType = None - self.itemSlotIndex = slotIndex - metinSlot = [] - for i in range(player.METIN_SOCKET_MAX_NUM): - metinSlot.append(safebox.GetItemMetinSocket(slotIndex, i)) - attrSlot = [] - for i in range(player.ATTRIBUTE_SLOT_MAX_NUM): - attrSlot.append(safebox.GetItemAttribute(slotIndex, i)) - - self.AddItemData(itemVnum, metinSlot, attrSlot, safebox.GetItemFlags(slotIndex)) - - def SetMallItem(self, slotIndex): - itemVnum = safebox.GetMallItemID(slotIndex) - if 0 == itemVnum: - return - - self.ClearToolTip() - self.itemWindowType = None - self.itemSlotIndex = slotIndex - metinSlot = [] - for i in range(player.METIN_SOCKET_MAX_NUM): - metinSlot.append(safebox.GetMallItemMetinSocket(slotIndex, i)) - attrSlot = [] - for i in range(player.ATTRIBUTE_SLOT_MAX_NUM): - attrSlot.append(safebox.GetMallItemAttribute(slotIndex, i)) - - self.AddItemData(itemVnum, metinSlot, attrSlot) - - def SetItemToolTip(self, itemVnum): - self.ClearToolTip() - metinSlot = [] - for i in range(player.METIN_SOCKET_MAX_NUM): - metinSlot.append(0) - attrSlot = [] - for i in range(player.ATTRIBUTE_SLOT_MAX_NUM): - attrSlot.append((0, 0)) - - self.AddItemData(itemVnum, metinSlot, attrSlot) - - def __AppendAttackSpeedInfo(self, item): - atkSpd = item.GetValue(0) - - if atkSpd < 80: - stSpd = localeInfo.TOOLTIP_ITEM_VERY_FAST - elif atkSpd <= 95: - stSpd = localeInfo.TOOLTIP_ITEM_FAST - elif atkSpd <= 105: - stSpd = localeInfo.TOOLTIP_ITEM_NORMAL - elif atkSpd <= 120: - stSpd = localeInfo.TOOLTIP_ITEM_SLOW - else: - stSpd = localeInfo.TOOLTIP_ITEM_VERY_SLOW - - self.AppendTextLine(localeInfo.TOOLTIP_ITEM_ATT_SPEED % stSpd, self.NORMAL_COLOR) - - def __AppendAttackGradeInfo(self): - atkGrade = item.GetValue(1) - self.AppendTextLine(localeInfo.TOOLTIP_ITEM_ATT_GRADE % atkGrade, self.GetChangeTextLineColor(atkGrade)) - - def __AppendAttackPowerInfo(self): - minPower = item.GetValue(3) - maxPower = item.GetValue(4) - addPower = item.GetValue(5) - if maxPower > minPower: - self.AppendTextLine(localeInfo.TOOLTIP_ITEM_ATT_POWER % (minPower+addPower, maxPower+addPower), self.POSITIVE_COLOR) - else: - self.AppendTextLine(localeInfo.TOOLTIP_ITEM_ATT_POWER_ONE_ARG % (minPower+addPower), self.POSITIVE_COLOR) - - def __AppendMagicAttackInfo(self): - minMagicAttackPower = item.GetValue(1) - maxMagicAttackPower = item.GetValue(2) - addPower = item.GetValue(5) - - if minMagicAttackPower > 0 or maxMagicAttackPower > 0: - if maxMagicAttackPower > minMagicAttackPower: - self.AppendTextLine(localeInfo.TOOLTIP_ITEM_MAGIC_ATT_POWER % (minMagicAttackPower+addPower, maxMagicAttackPower+addPower), self.POSITIVE_COLOR) - else: - self.AppendTextLine(localeInfo.TOOLTIP_ITEM_MAGIC_ATT_POWER_ONE_ARG % (minMagicAttackPower+addPower), self.POSITIVE_COLOR) - - def __AppendMagicDefenceInfo(self): - magicDefencePower = item.GetValue(0) - - if magicDefencePower > 0: - self.AppendTextLine(localeInfo.TOOLTIP_ITEM_MAGIC_DEF_POWER % magicDefencePower, self.GetChangeTextLineColor(magicDefencePower)) - - def __AppendAttributeInformation(self, attrSlot): - if 0 != attrSlot: - - for i in range(player.ATTRIBUTE_SLOT_MAX_NUM): - type = attrSlot[i][0] - value = attrSlot[i][1] - - if 0 == value: - continue - - affectString = self.__GetAffectString(type, value) - if affectString: - affectColor = self.__GetAttributeColor(i, value) - self.AppendTextLine(affectString, affectColor) - - def __GetAttributeColor(self, index, value): - if value > 0: - if index >= 5: - return self.SPECIAL_POSITIVE_COLOR2 - else: - return self.SPECIAL_POSITIVE_COLOR - elif value == 0: - return self.NORMAL_COLOR - else: - return self.NEGATIVE_COLOR - - def __IsPolymorphItem(self, itemVnum): - if itemVnum >= 70103 and itemVnum <= 70106: - return 1 - return 0 - - def __SetPolymorphItemTitle(self, monsterVnum): - itemName =nonplayer.GetMonsterName(monsterVnum) - itemName+=" " - itemName+=item.GetItemName() - self.SetTitle(itemName) - - def __SetNormalItemTitle(self): - self.SetTitle(item.GetItemName()) - - def __SetSpecialItemTitle(self): - self.AppendTextLine(item.GetItemName(), self.SPECIAL_TITLE_COLOR) - - def __SetItemTitle(self, itemVnum, metinSlot, attrSlot): - if self.__IsPolymorphItem(itemVnum): - self.__SetPolymorphItemTitle(metinSlot[0]) - else: - if self.__IsAttr(attrSlot): - self.__SetSpecialItemTitle() - return - - self.__SetNormalItemTitle() - - def __IsAttr(self, attrSlot): - if not attrSlot: - return False - - for i in range(player.ATTRIBUTE_SLOT_MAX_NUM): - type = attrSlot[i][0] - - if 0 != type: - return True - - return False - - # MR-12: Fix broken metin stones showing as empty sockets in item tooltip - def AddRefineItemData(self, itemVnum, metinSlot, attrSlot = 0): - # Separate metin slots into filled (non-broken) and empty slots - filledSlots = [] - emptySlots = [] - - for i in range(player.METIN_SOCKET_MAX_NUM): - metinSlotData = metinSlot[i] - metin_index = self.GetMetinItemIndex(metinSlotData) - - if metin_index == constInfo.ERROR_METIN_STONE: - # Broken stone - convert to empty silver socket - emptySlots.append(player.METIN_SOCKET_TYPE_SILVER) - elif metin_index == 0: - # Empty slot - emptySlots.append(metinSlotData) - else: - # Valid metin stone - filledSlots.append(metinSlotData) - - # Rebuild metinSlot with filled slots first, then empty slots - newSlots = filledSlots + emptySlots - - for i in range(player.METIN_SOCKET_MAX_NUM): - if i < len(newSlots): - metinSlot[i] = newSlots[i] - else: - metinSlot[i] = 0 - # MR-12: -- END OF -- Fix broken metin stones showing as empty sockets in item tooltip - - self.AddItemData(itemVnum, metinSlot, attrSlot) - - def AddItemData_Offline(self, itemVnum, itemDesc, itemSummary, metinSlot, attrSlot): - self.__AdjustMaxWidth(attrSlot, itemDesc) - self.__SetItemTitle(itemVnum, metinSlot, attrSlot) - - if self.__IsHair(itemVnum): - self.__AppendHairIcon(itemVnum) - - ### Description ### - self.AppendDescription(itemDesc) - self.AppendDescription(itemSummary, self.CONDITION_COLOR) - - def AddItemData(self, itemVnum, metinSlot, attrSlot = 0, flags = 0, unbindTime = 0): - self.itemVnum = itemVnum - self.metinSlot = metinSlot - item.SelectItem(itemVnum) - itemType = item.GetItemType() - itemSubType = item.GetItemSubType() - - if not item.GetItemDescription(): - self.__CalculateToolTipWidth() - - if 50026 == itemVnum: - if 0 != metinSlot: - name = item.GetItemName() - if metinSlot[0] > 0: - name += " " - name += localeInfo.NumberToMoneyString(metinSlot[0]) - self.SetTitle(name) - - self.ShowToolTip() - return - - ### Skill Book ### - elif 50300 == itemVnum: - if 0 != metinSlot: - self.__SetSkillBookToolTip(metinSlot[0], localeInfo.TOOLTIP_SKILLBOOK_NAME, 1) - - self.ShowToolTip() - return - elif 70037 == itemVnum: - if 0 != metinSlot: - self.__SetSkillBookToolTip(metinSlot[0], localeInfo.TOOLTIP_SKILL_FORGET_BOOK_NAME, 0) - self.AppendDescription(item.GetItemDescription()) - self.AppendDescription(item.GetItemSummary(), self.CONDITION_COLOR) - - - self.ShowToolTip() - return - elif 70055 == itemVnum: - if 0 != metinSlot: - self.__SetSkillBookToolTip(metinSlot[0], localeInfo.TOOLTIP_SKILL_FORGET_BOOK_NAME, 0) - self.AppendDescription(item.GetItemDescription()) - self.AppendDescription(item.GetItemSummary(), self.CONDITION_COLOR) - - self.ShowToolTip() - return - ########################################################################################### - - - itemDesc = item.GetItemDescription() - itemSummary = item.GetItemSummary() - - isCostumeItem = 0 - isCostumeHair = 0 - isCostumeBody = 0 - - if app.ENABLE_COSTUME_SYSTEM: - if item.ITEM_TYPE_COSTUME == itemType: - isCostumeItem = 1 - isCostumeHair = item.COSTUME_TYPE_HAIR == itemSubType - isCostumeBody = item.COSTUME_TYPE_BODY == itemSubType - - #dbg.TraceError("IS_COSTUME_ITEM! body(%d) hair(%d)" % (isCostumeBody, isCostumeHair)) - - self.__AdjustMaxWidth(attrSlot, itemDesc) - self.__SetItemTitle(itemVnum, metinSlot, attrSlot) - - ### Hair Preview Image ### - if self.__IsHair(itemVnum): - self.__AppendHairIcon(itemVnum) - - ### Description ### - self.AppendDescription(itemDesc) - self.AppendDescription(itemSummary, self.CONDITION_COLOR) - - ### Weapon ### - if item.ITEM_TYPE_WEAPON == itemType: - - self.__AppendLimitInformation() - - self.AppendSpace(5) - - ## For fans, display magic attack first. - if item.WEAPON_FAN == itemSubType: - self.__AppendMagicAttackInfo() - self.__AppendAttackPowerInfo() - - else: - self.__AppendAttackPowerInfo() - self.__AppendMagicAttackInfo() - - self.__AppendAffectInformation() - self.__AppendAttributeInformation(attrSlot) - - self.AppendWearableInformation() - self.__AppendMetinSlotInfo(metinSlot) - - ### Armor ### - elif item.ITEM_TYPE_ARMOR == itemType: - self.__AppendLimitInformation() - - ## Defense - defGrade = item.GetValue(1) - defBonus = item.GetValue(5)*2 ## Fixed an issue where defense power was displayed incorrectly. - if defGrade > 0: - self.AppendSpace(5) - self.AppendTextLine(localeInfo.TOOLTIP_ITEM_DEF_GRADE % (defGrade+defBonus), self.GetChangeTextLineColor(defGrade)) - - self.__AppendMagicDefenceInfo() - self.__AppendAffectInformation() - self.__AppendAttributeInformation(attrSlot) - - self.AppendWearableInformation() - - if itemSubType in (item.ARMOR_WRIST, item.ARMOR_NECK, item.ARMOR_EAR): - self.__AppendAccessoryMetinSlotInfo(metinSlot, constInfo.GET_ACCESSORY_MATERIAL_VNUM(itemVnum, itemSubType)) - else: - self.__AppendMetinSlotInfo(metinSlot) - - ### Ring Slot Item (Not UNIQUE) ### - elif item.ITEM_TYPE_RING == itemType: - self.__AppendLimitInformation() - self.__AppendAffectInformation() - self.__AppendAttributeInformation(attrSlot) - - #Planning for the ring socket system has not yet been decided - #self.__AppendAccessoryMetinSlotInfo(metinSlot, 99001) - - bHasRealtimeFlag = 0 - for i in range(item.LIMIT_MAX_NUM): - (limitType, limitValue) = item.GetLimit(i) - - if item.LIMIT_REAL_TIME == limitType: - bHasRealtimeFlag = 1 - - if 1 == bHasRealtimeFlag: - if item.LIMIT_REAL_TIME == item.GetLimitType(0) or item.LIMIT_REAL_TIME_START_FIRST_USE == item.GetLimitType(0): - self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(0)) - else: - self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(1)) - - self.AppendSpace(5) - - ### Belt Item ### - elif item.ITEM_TYPE_BELT == itemType: - self.__AppendLimitInformation() - self.__AppendAffectInformation() - self.__AppendAttributeInformation(attrSlot) - - self.__AppendAccessoryMetinSlotInfo(metinSlot, constInfo.GET_BELT_MATERIAL_VNUM(itemVnum)) - - ## Costume Item ## - elif 0 != isCostumeItem: - self.__AppendLimitInformation() - self.__AppendAffectInformation() - self.__AppendAttributeInformation(attrSlot) - - self.AppendWearableInformation() - - bHasRealtimeFlag = 0 - for i in range(item.LIMIT_MAX_NUM): - (limitType, limitValue) = item.GetLimit(i) - - if item.LIMIT_REAL_TIME == limitType: - bHasRealtimeFlag = 1 - - if 1 == bHasRealtimeFlag: - if item.LIMIT_REAL_TIME == item.GetLimitType(0) or item.LIMIT_REAL_TIME_START_FIRST_USE == item.GetLimitType(0): - self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(0)) - else: - self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(1)) - - ## Rod ## - elif item.ITEM_TYPE_ROD == itemType: - if 0 != metinSlot: - curLevel = item.GetValue(0) // 10 - curEXP = metinSlot[0] - maxEXP = item.GetValue(2) - self.__AppendLimitInformation() - self.__AppendRodInformation(curLevel, curEXP, maxEXP) - - ## Pick ## - elif item.ITEM_TYPE_PICK == itemType: - - if 0 != metinSlot: - curLevel = item.GetValue(0) // 10 - curEXP = metinSlot[0] - maxEXP = item.GetValue(2) - self.__AppendLimitInformation() - self.__AppendPickInformation(curLevel, curEXP, maxEXP) - - ## Lottery ## - elif item.ITEM_TYPE_LOTTERY == itemType: - if 0 != metinSlot: - - ticketNumber = int(metinSlot[0]) - stepNumber = int(metinSlot[1]) - - self.AppendSpace(5) - self.AppendTextLine(localeInfo.TOOLTIP_LOTTERY_STEP_NUMBER % (stepNumber), self.NORMAL_COLOR) - self.AppendTextLine(localeInfo.TOOLTIP_LOTTO_NUMBER % (ticketNumber), self.NORMAL_COLOR); - - ### Metin ### - elif item.ITEM_TYPE_METIN == itemType: - self.AppendMetinInformation() - self.AppendMetinWearInformation() - - ### Fish ### - elif item.ITEM_TYPE_FISH == itemType: - if 0 != metinSlot: - self.__AppendFishInfo(metinSlot[0]) - - ## item.ITEM_TYPE_BLEND - elif item.ITEM_TYPE_BLEND == itemType: - self.__AppendLimitInformation() - - if metinSlot: - affectType = metinSlot[0] - affectValue = metinSlot[1] - time = metinSlot[2] - self.AppendSpace(5) - affectText = self.__GetAffectString(affectType, affectValue) - - self.AppendTextLine(affectText, self.NORMAL_COLOR) - - if time > 0: - minute = (time // 60) - second = (time % 60) - timeString = localeInfo.TOOLTIP_POTION_TIME - - if minute > 0: - timeString += str(minute) + localeInfo.TOOLTIP_POTION_MIN - if second > 0: - timeString += " " + str(second) + localeInfo.TOOLTIP_POTION_SEC - - self.AppendTextLine(timeString) - else: - self.AppendTextLine(localeInfo.BLEND_POTION_NO_TIME) - else: - self.AppendTextLine("BLEND_POTION_NO_INFO") - - elif item.ITEM_TYPE_UNIQUE == itemType: - if 0 != metinSlot: - bHasRealtimeFlag = 0 - for i in range(item.LIMIT_MAX_NUM): - (limitType, limitValue) = item.GetLimit(i) - - if item.LIMIT_REAL_TIME == limitType: - bHasRealtimeFlag = 1 - - if 1 == bHasRealtimeFlag: - if item.LIMIT_REAL_TIME == item.GetLimitType(0) or item.LIMIT_REAL_TIME_START_FIRST_USE == item.GetLimitType(0): - self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(0)) - else: - self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(1)) - else: - time = metinSlot[player.METIN_SOCKET_MAX_NUM - 1] - - if 1 == item.GetValue(2): ## Real-time use flag / given even if not equipped - if item.LIMIT_REAL_TIME == item.GetLimitType(0) or item.LIMIT_REAL_TIME_START_FIRST_USE == item.GetLimitType(0): - self.AppendMallItemLastTime(time, item.GetLimitValue(0)) - else: - self.AppendMallItemLastTime(time, item.GetLimitValue(1)) - else: - self.AppendUniqueItemLastTime(time) - - ### Use ### - elif item.ITEM_TYPE_USE == itemType: - self.__AppendLimitInformation() - - if item.USE_POTION == itemSubType or item.USE_POTION_NODELAY == itemSubType: - self.__AppendPotionInformation() - - elif item.USE_ABILITY_UP == itemSubType: - self.__AppendAbilityPotionInformation() - - - ## Spirit Detector - if 27989 == itemVnum or 76006 == itemVnum: - if 0 != metinSlot: - useCount = int(metinSlot[0]) - - self.AppendSpace(5) - self.AppendTextLine(localeInfo.TOOLTIP_REST_USABLE_COUNT % (6 - useCount), self.NORMAL_COLOR) - - ## Event Detector - elif 50004 == itemVnum: - if 0 != metinSlot: - useCount = int(metinSlot[0]) - - self.AppendSpace(5) - self.AppendTextLine(localeInfo.TOOLTIP_REST_USABLE_COUNT % (10 - useCount), self.NORMAL_COLOR) - - ## Automatic potion - elif constInfo.IS_AUTO_POTION(itemVnum): - if 0 != metinSlot: - # # 0: Activate, 1: Power, 2: Cooldown - isActivated = int(metinSlot[0]) - usedAmount = float(metinSlot[1]) - totalAmount = float(metinSlot[2]) - - if 0 == totalAmount: - totalAmount = 1 - - self.AppendSpace(5) - - ## 0: active, 1: usage amount, 2: total amount - if 0 != isActivated: - self.AppendTextLine("(%s)" % (localeInfo.TOOLTIP_AUTO_POTION_USING), self.SPECIAL_POSITIVE_COLOR) - self.AppendSpace(5) - - self.AppendTextLine(localeInfo.TOOLTIP_AUTO_POTION_REST % (100.0 - ((usedAmount / totalAmount) * 100.0)), self.POSITIVE_COLOR) - - ## Return Memory - elif itemVnum in WARP_SCROLLS: - if 0 != metinSlot: - xPos = int(metinSlot[0]) - yPos = int(metinSlot[1]) - - if xPos != 0 and yPos != 0: - (mapName, xBase, yBase) = background.GlobalPositionToMapInfo(xPos, yPos) - - localeMapName=localeInfo.MINIMAP_ZONE_NAME_DICT.get(mapName, "") - - self.AppendSpace(5) - - if localeMapName!="": - self.AppendTextLine(localeInfo.TOOLTIP_MEMORIZED_POSITION % (localeMapName, int(xPos-xBase) // 100, int(yPos-yBase) // 100), self.NORMAL_COLOR) - else: - self.AppendTextLine(localeInfo.TOOLTIP_MEMORIZED_POSITION_ERROR % (int(xPos) // 100, int(yPos) // 100), self.NORMAL_COLOR) - dbg.TraceError("NOT_EXIST_IN_MINIMAP_ZONE_NAME_DICT: %s" % mapName) - - ##### - if item.USE_SPECIAL == itemSubType: - bHasRealtimeFlag = 0 - for i in range(item.LIMIT_MAX_NUM): - (limitType, limitValue) = item.GetLimit(i) - - if item.LIMIT_REAL_TIME == limitType: - bHasRealtimeFlag = 1 - - if 1 == bHasRealtimeFlag: - if item.LIMIT_REAL_TIME == item.GetLimitType(0) or item.LIMIT_REAL_TIME_START_FIRST_USE == item.GetLimitType(0): - self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(0)) - else: - self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(1)) - else: - if 0 != metinSlot: - time = metinSlot[player.METIN_SOCKET_MAX_NUM - 1] - - if 1 == item.GetValue(2): - if item.LIMIT_REAL_TIME == item.GetLimitType(0) or item.LIMIT_REAL_TIME_START_FIRST_USE == item.GetLimitType(0): - self.AppendMallItemLastTime(time, item.GetLimitValue(0)) - else: - self.AppendMallItemLastTime(time, item.GetLimitValue(1)) - - elif item.USE_TIME_CHARGE_PER == itemSubType: - bHasRealtimeFlag = 0 - for i in range(item.LIMIT_MAX_NUM): - (limitType, limitValue) = item.GetLimit(i) - - if item.LIMIT_REAL_TIME == limitType: - bHasRealtimeFlag = 1 - - if metinSlot[2]: - self.AppendTextLine(localeInfo.TOOLTIP_TIME_CHARGER_PER(metinSlot[2])) - else: - self.AppendTextLine(localeInfo.TOOLTIP_TIME_CHARGER_PER(item.GetValue(0))) - - if 1 == bHasRealtimeFlag: - if item.LIMIT_REAL_TIME == item.GetLimitType(0) or item.LIMIT_REAL_TIME_START_FIRST_USE == item.GetLimitType(0): - self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(0)) - else: - self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(1)) - - elif item.USE_TIME_CHARGE_FIX == itemSubType: - bHasRealtimeFlag = 0 - for i in range(item.LIMIT_MAX_NUM): - (limitType, limitValue) = item.GetLimit(i) - - if item.LIMIT_REAL_TIME == limitType: - bHasRealtimeFlag = 1 - - if metinSlot[2]: - self.AppendTextLine(localeInfo.TOOLTIP_TIME_CHARGER_FIX(metinSlot[2])) - else: - self.AppendTextLine(localeInfo.TOOLTIP_TIME_CHARGER_FIX(item.GetValue(0))) - - if 1 == bHasRealtimeFlag: - if item.LIMIT_REAL_TIME == item.GetLimitType(0) or item.LIMIT_REAL_TIME_START_FIRST_USE == item.GetLimitType(0): - self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(0)) - else: - self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(1)) - - elif item.ITEM_TYPE_QUEST == itemType: - bHasRealtimeFlag = 0 - for i in range(item.LIMIT_MAX_NUM): - (limitType, limitValue) = item.GetLimit(i) - - if item.LIMIT_REAL_TIME == limitType: - bHasRealtimeFlag = 1 - - if 1 == bHasRealtimeFlag: - if item.LIMIT_REAL_TIME == item.GetLimitType(0) or item.LIMIT_REAL_TIME_START_FIRST_USE == item.GetLimitType(0): - self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(0)) - else: - self.AppendMallItemLastTime(metinSlot[0], item.GetLimitValue(1)) - - elif item.ITEM_TYPE_DS == itemType: - self.AppendTextLine(self.__DragonSoulInfoString(itemVnum)) - self.__AppendAttributeInformation(attrSlot) - else: - self.__AppendLimitInformation() - - for i in range(item.LIMIT_MAX_NUM): - (limitType, limitValue) = item.GetLimit(i) - limitValue2 = item.GetLimitValue(i) - - if item.LIMIT_REAL_TIME_START_FIRST_USE == limitType: - self.AppendRealTimeStartFirstUseLastTime(item, metinSlot, i, limitValue2) - - elif item.LIMIT_TIMER_BASED_ON_WEAR == limitType: - self.AppendTimerBasedOnWearLastTime(metinSlot, limitValue2) - - self.ShowToolTip() - - def __DragonSoulInfoString (self, dwVnum): - step = (dwVnum // 100) % 10 - refine = (dwVnum // 10) % 10 - - if 0 == step: - return localeInfo.DRAGON_SOUL_STEP_LEVEL1 + " " + localeInfo.DRAGON_SOUL_STRENGTH(refine) - elif 1 == step: - return localeInfo.DRAGON_SOUL_STEP_LEVEL2 + " " + localeInfo.DRAGON_SOUL_STRENGTH(refine) - elif 2 == step: - return localeInfo.DRAGON_SOUL_STEP_LEVEL3 + " " + localeInfo.DRAGON_SOUL_STRENGTH(refine) - elif 3 == step: - return localeInfo.DRAGON_SOUL_STEP_LEVEL4 + " " + localeInfo.DRAGON_SOUL_STRENGTH(refine) - elif 4 == step: - return localeInfo.DRAGON_SOUL_STEP_LEVEL5 + " " + localeInfo.DRAGON_SOUL_STRENGTH(refine) - else: - return "" - - - ## Is it hair? - def __IsHair(self, itemVnum): - return (self.__IsOldHair(itemVnum) or - self.__IsNewHair(itemVnum) or - self.__IsNewHair2(itemVnum) or - self.__IsNewHair3(itemVnum) or - self.__IsCostumeHair(itemVnum) - ) - - def __IsOldHair(self, itemVnum): - return itemVnum > 73000 and itemVnum < 74000 - - def __IsNewHair(self, itemVnum): - return itemVnum > 74000 and itemVnum < 75000 - - def __IsNewHair2(self, itemVnum): - return itemVnum > 75000 and itemVnum < 76000 - - def __IsNewHair3(self, itemVnum): - return ((74012 < itemVnum and itemVnum < 74022) or - (74262 < itemVnum and itemVnum < 74272) or - (74512 < itemVnum and itemVnum < 74522) or - (74762 < itemVnum and itemVnum < 74772) or - (45000 < itemVnum and itemVnum < 47000)) - - def __IsCostumeHair(self, itemVnum): - return app.ENABLE_COSTUME_SYSTEM and self.__IsNewHair3(itemVnum - 100000) - - def __AppendHairIcon(self, itemVnum): - itemImage = ui.ImageBox() - itemImage.SetParent(self) - itemImage.Show() - - if self.__IsOldHair(itemVnum): - itemImage.LoadImage("d:/ymir work/item/quest/" + str(itemVnum) + ".tga") - elif self.__IsNewHair3(itemVnum): - itemImage.LoadImage("icon/hair/%d.sub" % (itemVnum)) - elif self.__IsNewHair(itemVnum): # Use by linking to existing hair numbers. New items have numbers increased by 1000. - itemImage.LoadImage("d:/ymir work/item/quest/" + str(itemVnum - 1000) + ".tga") - elif self.__IsNewHair2(itemVnum): - itemImage.LoadImage("icon/hair/%d.sub" % (itemVnum)) - elif self.__IsCostumeHair(itemVnum): - itemImage.LoadImage("icon/hair/%d.sub" % (itemVnum - 100000)) - - # MR-10: Fix element centering in tooltips - self.hairIcon = itemImage - xPos = max(0, (self.toolTipWidth - itemImage.GetWidth()) // 2) - - itemImage.SetPosition(xPos, self.toolTipHeight) - # MR-10: -- END OF -- Fix element centering in tooltips - self.toolTipHeight += itemImage.GetHeight() - #self.toolTipWidth += itemImage.GetWidth()/2 - self.childrenList.append(itemImage) - self.ResizeToolTip() - # MR-10: Fix element centering in tooltips - self.__CenterHairIcon() - # MR-10: -- END OF -- Fix element centering in tooltips - - # MR-10: Fix element centering in tooltips - def __CenterHairIcon(self): - if not self.hairIcon: - return - - (xPos, yPos) = self.hairIcon.GetLocalPosition() - xPos = max(0, (self.toolTipWidth - self.hairIcon.GetWidth()) // 2) - - self.hairIcon.SetPosition(xPos, yPos) - # MR-10: -- END OF -- Fix element centering in tooltips - - ## If the Description is large, adjust the tooltip size. - def __AdjustMaxWidth(self, attrSlot, desc): - newToolTipWidth = self.toolTipWidth - newToolTipWidth = max(self.__AdjustAttrMaxWidth(attrSlot), newToolTipWidth) - newToolTipWidth = max(self.__AdjustDescMaxWidth(desc), newToolTipWidth) - if newToolTipWidth > self.toolTipWidth: - self.toolTipWidth = newToolTipWidth - self.ResizeToolTip() - # MR-10: Fix element centering in tooltips - self.AlignTextLineHorizonalCenter() - self.__CenterHairIcon() - # MR-10: -- END OF -- Fix element centering in tooltips - - def __AdjustAttrMaxWidth(self, attrSlot): - if 0 == attrSlot: - return self.toolTipWidth - - maxWidth = self.toolTipWidth - for i in range(player.ATTRIBUTE_SLOT_MAX_NUM): - type = attrSlot[i][0] - value = attrSlot[i][1] - - attrText = self.AppendTextLine(self.__GetAffectString(type, value)) - (tW, _) = attrText.GetTextSize() - self.childrenList.remove(attrText) - self.toolTipHeight -= self.TEXT_LINE_HEIGHT - - maxWidth = max(tW + 12, maxWidth) - - return maxWidth - - def __AdjustDescMaxWidth(self, desc): - if not desc: - return self.toolTipWidth - - padding = 20 - maxWidthPx = max(50, self.toolTipWidth - padding) - - lines = SplitDescriptionByPixelWidth(desc, maxWidthPx, self.defFontName) - if len(lines) >= 2: - return DESC_MAX_WIDTH - - return self.toolTipWidth - - def ResizeToolTipWidth(self, width): - self.toolTipWidth = width - - # MR-10: Fix element centering in tooltips - self.AlignTextLineHorizonalCenter() - self.__CenterHairIcon() - # MR-10: -- END OF -- Fix element centering in tooltips - - def __CalculateToolTipWidth(self): - affectTextLineLenList = [] - - metinSocket = self.metinSlot - if metinSocket: - for socketIndex in metinSocket: - if socketIndex: - item.SelectItem(socketIndex) - - affectType, affectValue = item.GetAffect(0) - affectString = self.__GetAffectString(affectType, affectValue) - if affectString: - affectTextLineLenList.append(len(affectString)) - - if self.itemVnum: - item.SelectItem(self.itemVnum) - self.metinSlot = None - - if self.toolTipWidth == self.TOOL_TIP_WIDTH: - if affectTextLineLenList: - self.toolTipWidth += max(affectTextLineLenList) + 10 - - self.AlignTextLineHorizonalCenter() - - # MR-10: Fix element centering in tooltips - self.__CenterHairIcon() - # MR-10: -- END OF -- Fix element centering in tooltips - - def __SetSkillBookToolTip(self, skillIndex, bookName, skillGrade): - skillName = skill.GetSkillName(skillIndex) - - if not skillName: - return - - itemName = skillName + " " + bookName - self.SetTitle(itemName) - - def __AppendPickInformation(self, curLevel, curEXP, maxEXP): - self.AppendSpace(5) - self.AppendTextLine(localeInfo.TOOLTIP_PICK_LEVEL % (curLevel), self.NORMAL_COLOR) - self.AppendTextLine(localeInfo.TOOLTIP_PICK_EXP % (curEXP, maxEXP), self.NORMAL_COLOR) - - if curEXP == maxEXP: - self.AppendSpace(5) - self.AppendTextLine(localeInfo.TOOLTIP_PICK_UPGRADE1, self.NORMAL_COLOR) - self.AppendTextLine(localeInfo.TOOLTIP_PICK_UPGRADE2, self.NORMAL_COLOR) - self.AppendTextLine(localeInfo.TOOLTIP_PICK_UPGRADE3, self.NORMAL_COLOR) - - - def __AppendRodInformation(self, curLevel, curEXP, maxEXP): - self.AppendSpace(5) - self.AppendTextLine(localeInfo.TOOLTIP_FISHINGROD_LEVEL % (curLevel), self.NORMAL_COLOR) - self.AppendTextLine(localeInfo.TOOLTIP_FISHINGROD_EXP % (curEXP, maxEXP), self.NORMAL_COLOR) - - if curEXP == maxEXP: - self.AppendSpace(5) - self.AppendTextLine(localeInfo.TOOLTIP_FISHINGROD_UPGRADE1, self.NORMAL_COLOR) - self.AppendTextLine(localeInfo.TOOLTIP_FISHINGROD_UPGRADE2, self.NORMAL_COLOR) - self.AppendTextLine(localeInfo.TOOLTIP_FISHINGROD_UPGRADE3, self.NORMAL_COLOR) - - def __AppendLimitInformation(self): - - appendSpace = False - - for i in range(item.LIMIT_MAX_NUM): - - (limitType, limitValue) = item.GetLimit(i) - - if limitValue > 0: - if False == appendSpace: - self.AppendSpace(5) - appendSpace = True - - else: - continue - - if item.LIMIT_LEVEL == limitType: - color = self.GetLimitTextLineColor(player.GetStatus(player.LEVEL), limitValue) - self.AppendTextLine(localeInfo.TOOLTIP_ITEM_LIMIT_LEVEL % (limitValue), color) - """ - elif item.LIMIT_STR == limitType: - color = self.GetLimitTextLineColor(player.GetStatus(player.ST), limitValue) - self.AppendTextLine(localeInfo.TOOLTIP_ITEM_LIMIT_STR % (limitValue), color) - elif item.LIMIT_DEX == limitType: - color = self.GetLimitTextLineColor(player.GetStatus(player.DX), limitValue) - self.AppendTextLine(localeInfo.TOOLTIP_ITEM_LIMIT_DEX % (limitValue), color) - elif item.LIMIT_INT == limitType: - color = self.GetLimitTextLineColor(player.GetStatus(player.IQ), limitValue) - self.AppendTextLine(localeInfo.TOOLTIP_ITEM_LIMIT_INT % (limitValue), color) - elif item.LIMIT_CON == limitType: - color = self.GetLimitTextLineColor(player.GetStatus(player.HT), limitValue) - self.AppendTextLine(localeInfo.TOOLTIP_ITEM_LIMIT_CON % (limitValue), color) - """ - - - - - - - - - - - - - def __GetAffectString(self, affectType, affectValue): - if 0 == affectType: - return None - - if 0 == affectValue: - return None - - try: - return self.AFFECT_DICT[affectType](affectValue) - except TypeError: - return "UNKNOWN_VALUE[%s] %s" % (affectType, affectValue) - except KeyError: - return "UNKNOWN_TYPE[%s] %s" % (affectType, affectValue) - - def __AppendAffectInformation(self): - for i in range(item.ITEM_APPLY_MAX_NUM): - - (affectType, affectValue) = item.GetAffect(i) - - affectString = self.__GetAffectString(affectType, affectValue) - if affectString: - self.AppendTextLine(affectString, self.GetChangeTextLineColor(affectValue)) - - def AppendWearableInformation(self): - - self.AppendSpace(5) - self.AppendTextLine(localeInfo.TOOLTIP_ITEM_WEARABLE_JOB, self.NORMAL_COLOR) - - flagList = ( - not item.IsAntiFlag(item.ITEM_ANTIFLAG_WARRIOR), - not item.IsAntiFlag(item.ITEM_ANTIFLAG_ASSASSIN), - not item.IsAntiFlag(item.ITEM_ANTIFLAG_SURA), - not item.IsAntiFlag(item.ITEM_ANTIFLAG_SHAMAN)) - - characterNames = "" - for i in range(self.CHARACTER_COUNT): - - name = self.CHARACTER_NAMES[i] - flag = flagList[i] - - if flag: - characterNames += " " - characterNames += name - - textLine = self.AppendTextLine(characterNames, self.NORMAL_COLOR, True) - textLine.SetFeather() - - if item.IsAntiFlag(item.ITEM_ANTIFLAG_MALE): - textLine = self.AppendTextLine(localeInfo.FOR_FEMALE, self.NORMAL_COLOR, True) - textLine.SetFeather() - - if item.IsAntiFlag(item.ITEM_ANTIFLAG_FEMALE): - textLine = self.AppendTextLine(localeInfo.FOR_MALE, self.NORMAL_COLOR, True) - textLine.SetFeather() - - def __AppendPotionInformation(self): - self.AppendSpace(5) - - healHP = item.GetValue(0) - healSP = item.GetValue(1) - healStatus = item.GetValue(2) - healPercentageHP = item.GetValue(3) - healPercentageSP = item.GetValue(4) - - if healHP > 0: - self.AppendTextLine(localeInfo.TOOLTIP_POTION_PLUS_HP_POINT % healHP, self.GetChangeTextLineColor(healHP)) - if healSP > 0: - self.AppendTextLine(localeInfo.TOOLTIP_POTION_PLUS_SP_POINT % healSP, self.GetChangeTextLineColor(healSP)) - if healStatus != 0: - self.AppendTextLine(localeInfo.TOOLTIP_POTION_CURE) - if healPercentageHP > 0: - self.AppendTextLine(localeInfo.TOOLTIP_POTION_PLUS_HP_PERCENT % healPercentageHP, self.GetChangeTextLineColor(healPercentageHP)) - if healPercentageSP > 0: - self.AppendTextLine(localeInfo.TOOLTIP_POTION_PLUS_SP_PERCENT % healPercentageSP, self.GetChangeTextLineColor(healPercentageSP)) - - def __AppendAbilityPotionInformation(self): - - self.AppendSpace(5) - - abilityType = item.GetValue(0) - time = item.GetValue(1) - point = item.GetValue(2) - - if abilityType == item.APPLY_ATT_SPEED: - self.AppendTextLine(localeInfo.TOOLTIP_POTION_PLUS_ATTACK_SPEED % point, self.GetChangeTextLineColor(point)) - elif abilityType == item.APPLY_MOV_SPEED: - self.AppendTextLine(localeInfo.TOOLTIP_POTION_PLUS_MOVING_SPEED % point, self.GetChangeTextLineColor(point)) - - if time > 0: - minute = (time // 60) - second = (time % 60) - timeString = localeInfo.TOOLTIP_POTION_TIME - - if minute > 0: - timeString += " " + str(minute) + localeInfo.TOOLTIP_POTION_MIN - if second > 0: - timeString += " " + str(second) + localeInfo.TOOLTIP_POTION_SEC - - self.AppendTextLine(timeString) - - def GetPriceColor(self, price): - if price >= constInfo.HIGH_PRICE: - return self.HIGH_PRICE_COLOR - - if price >= constInfo.MIDDLE_PRICE: - return self.MIDDLE_PRICE_COLOR - else: - return self.LOW_PRICE_COLOR - - def AppendPrice(self, price): - self.AppendSpace(5) - self.AppendTextLine(localeInfo.TOOLTIP_BUYPRICE % (localeInfo.NumberToMoneyString(price)), self.GetPriceColor(price)) - - def AppendPriceBySecondaryCoin(self, price): - self.AppendSpace(5) - self.AppendTextLine(localeInfo.TOOLTIP_BUYPRICE % (localeInfo.NumberToSecondaryCoinString(price)), self.GetPriceColor(price)) - - def AppendSellingPrice(self, price): - if item.IsAntiFlag(item.ITEM_ANTIFLAG_SELL): - self.AppendTextLine(localeInfo.TOOLTIP_ANTI_SELL, self.DISABLE_COLOR) - self.AppendSpace(5) - else: - self.AppendTextLine(localeInfo.TOOLTIP_SELLPRICE % (localeInfo.NumberToMoneyString(price)), self.GetPriceColor(price)) - self.AppendSpace(5) - - def AppendMetinInformation(self): - affectType, affectValue = item.GetAffect(0) - #affectType = item.GetValue(0) - #affectValue = item.GetValue(1) - - affectString = self.__GetAffectString(affectType, affectValue) - - if affectString: - self.AppendSpace(5) - self.AppendTextLine(affectString, self.GetChangeTextLineColor(affectValue)) - - def AppendMetinWearInformation(self): - - self.AppendSpace(5) - self.AppendTextLine(localeInfo.TOOLTIP_SOCKET_REFINABLE_ITEM, self.NORMAL_COLOR) - - flagList = (item.IsWearableFlag(item.WEARABLE_BODY), - item.IsWearableFlag(item.WEARABLE_HEAD), - item.IsWearableFlag(item.WEARABLE_FOOTS), - item.IsWearableFlag(item.WEARABLE_WRIST), - item.IsWearableFlag(item.WEARABLE_WEAPON), - item.IsWearableFlag(item.WEARABLE_NECK), - item.IsWearableFlag(item.WEARABLE_EAR), - item.IsWearableFlag(item.WEARABLE_UNIQUE), - item.IsWearableFlag(item.WEARABLE_SHIELD), - item.IsWearableFlag(item.WEARABLE_ARROW)) - - wearNames = "" - for i in range(self.WEAR_COUNT): - - name = self.WEAR_NAMES[i] - flag = flagList[i] - - if flag: - wearNames += " " - wearNames += name - - textLine = ui.TextLine() - textLine.SetParent(self) - textLine.SetFontName(self.defFontName) - textLine.SetPosition(self.toolTipWidth // 2, self.toolTipHeight) - textLine.SetHorizontalAlignCenter() - textLine.SetPackedFontColor(self.NORMAL_COLOR) - textLine.SetText(wearNames) - textLine.Show() - self.childrenList.append(textLine) - - self.toolTipHeight += self.TEXT_LINE_HEIGHT - self.ResizeToolTip() - - def GetMetinSocketType(self, number): - if player.METIN_SOCKET_TYPE_NONE == number: - return player.METIN_SOCKET_TYPE_NONE - elif player.METIN_SOCKET_TYPE_SILVER == number: - return player.METIN_SOCKET_TYPE_SILVER - elif player.METIN_SOCKET_TYPE_GOLD == number: - return player.METIN_SOCKET_TYPE_GOLD - else: - item.SelectItem(number) - if item.METIN_NORMAL == item.GetItemSubType(): - return player.METIN_SOCKET_TYPE_SILVER - elif item.METIN_GOLD == item.GetItemSubType(): - return player.METIN_SOCKET_TYPE_GOLD - elif "USE_PUT_INTO_ACCESSORY_SOCKET" == item.GetUseType(number): - return player.METIN_SOCKET_TYPE_SILVER - elif "USE_PUT_INTO_RING_SOCKET" == item.GetUseType(number): - return player.METIN_SOCKET_TYPE_SILVER - elif "USE_PUT_INTO_BELT_SOCKET" == item.GetUseType(number): - return player.METIN_SOCKET_TYPE_SILVER - - return player.METIN_SOCKET_TYPE_NONE - - def GetMetinItemIndex(self, number): - if player.METIN_SOCKET_TYPE_SILVER == number: - return 0 - if player.METIN_SOCKET_TYPE_GOLD == number: - return 0 - - return number - - def __AppendAccessoryMetinSlotInfo(self, metinSlot, mtrlVnum): - ACCESSORY_SOCKET_MAX_SIZE = 3 - - cur = min(metinSlot[0], ACCESSORY_SOCKET_MAX_SIZE) - end = min(metinSlot[1], ACCESSORY_SOCKET_MAX_SIZE) - - affectType1, affectValue1 = item.GetAffect(0) - affectList1=[0, max(1, affectValue1 * 10 // 100), max(2, affectValue1 * 20 // 100), max(3, affectValue1 * 40 // 100)] - - affectType2, affectValue2 = item.GetAffect(1) - affectList2 = [0, max(1, affectValue2 * 10 // 100), max(2, affectValue2 * 20 // 100), max(3, affectValue2 * 40 // 100)] - - mtrlPos = 0 - mtrlList = [mtrlVnum] * cur + [player.METIN_SOCKET_TYPE_SILVER] * (end-cur) - - for mtrl in mtrlList: - affectString1 = self.__GetAffectString(affectType1, affectList1[mtrlPos + 1] - affectList1[mtrlPos]) - affectString2 = self.__GetAffectString(affectType2, affectList2[mtrlPos + 1] - affectList2[mtrlPos]) - - leftTime = 0 - - if cur == mtrlPos + 1: - leftTime = metinSlot[2] - - self.__AppendMetinSlotInfo_AppendMetinSocketData(mtrlPos, mtrl, affectString1, affectString2, leftTime) - - mtrlPos += 1 - - def __AppendMetinSlotInfo(self, metinSlot): - if self.__AppendMetinSlotInfo_IsEmptySlotList(metinSlot): - return - - for i in range(player.METIN_SOCKET_MAX_NUM): - self.__AppendMetinSlotInfo_AppendMetinSocketData(i, metinSlot[i]) - - def __AppendMetinSlotInfo_IsEmptySlotList(self, metinSlot): - if 0 == metinSlot: - return 1 - - for i in range(player.METIN_SOCKET_MAX_NUM): - metinSlotData=metinSlot[i] - if 0 != self.GetMetinSocketType(metinSlotData): - if 0 != self.GetMetinItemIndex(metinSlotData): - return 0 - - return 1 - - def __AppendMetinSlotInfo_AppendMetinSocketData(self, index, metinSlotData, custumAffectString="", custumAffectString2="", leftTime=0): - - slotType = self.GetMetinSocketType(metinSlotData) - itemIndex = self.GetMetinItemIndex(metinSlotData) - - if 0 == slotType: - return - - self.AppendSpace(5) - - slotImage = ui.ImageBox() - slotImage.SetParent(self) - slotImage.Show() - - ## Name - nameTextLine = ui.TextLine() - nameTextLine.SetParent(self) - nameTextLine.SetFontName(self.defFontName) - nameTextLine.SetPackedFontColor(self.NORMAL_COLOR) - nameTextLine.SetOutline() - nameTextLine.SetFeather() - nameTextLine.Show() - - self.childrenList.append(nameTextLine) - - if player.METIN_SOCKET_TYPE_SILVER == slotType: - slotImage.LoadImage("d:/ymir work/ui/game/windows/metin_slot_silver.sub") - elif player.METIN_SOCKET_TYPE_GOLD == slotType: - slotImage.LoadImage("d:/ymir work/ui/game/windows/metin_slot_gold.sub") - - self.childrenList.append(slotImage) - - if app.IsRTL(): - slotImage.SetPosition(self.toolTipWidth - slotImage.GetWidth() - 9, self.toolTipHeight-1) - nameTextLine.SetPosition(self.toolTipWidth - 50, self.toolTipHeight + 2) - else: - slotImage.SetPosition(9, self.toolTipHeight-1) - nameTextLine.SetPosition(50, self.toolTipHeight + 2) - - metinImage = ui.ImageBox() - metinImage.SetParent(self) - metinImage.Show() - self.childrenList.append(metinImage) - - if itemIndex: - - item.SelectItem(itemIndex) - - ## Image - try: - metinImage.LoadImage(item.GetIconImageFileName()) - except: - dbg.TraceError("ItemToolTip.__AppendMetinSocketData() - Failed to find image file %d:%s" % - (itemIndex, item.GetIconImageFileName()) - ) - - nameTextLine.SetText(item.GetItemName()) - - ## Affect - affectTextLine = ui.TextLine() - affectTextLine.SetParent(self) - affectTextLine.SetFontName(self.defFontName) - affectTextLine.SetPackedFontColor(self.POSITIVE_COLOR) - affectTextLine.SetOutline() - affectTextLine.SetFeather() - affectTextLine.Show() - - if app.IsRTL(): - metinImage.SetPosition(self.toolTipWidth - metinImage.GetWidth() - 10, self.toolTipHeight) - affectTextLine.SetPosition(self.toolTipWidth - 50, self.toolTipHeight + 16 + 2) - else: - metinImage.SetPosition(10, self.toolTipHeight) - affectTextLine.SetPosition(50, self.toolTipHeight + 16 + 2) - - if custumAffectString: - affectTextLine.SetText(custumAffectString) - elif itemIndex!=constInfo.ERROR_METIN_STONE: - affectType, affectValue = item.GetAffect(0) - affectString = self.__GetAffectString(affectType, affectValue) - if affectString: - affectTextLine.SetText(affectString) - else: - affectTextLine.SetText(localeInfo.TOOLTIP_APPLY_NOAFFECT) - - self.childrenList.append(affectTextLine) - - if custumAffectString2: - affectTextLine = ui.TextLine() - affectTextLine.SetParent(self) - affectTextLine.SetFontName(self.defFontName) - affectTextLine.SetPackedFontColor(self.POSITIVE_COLOR) - affectTextLine.SetPosition(50, self.toolTipHeight + 16 + 2 + 16 + 2) - affectTextLine.SetOutline() - affectTextLine.SetFeather() - affectTextLine.Show() - affectTextLine.SetText(custumAffectString2) - self.childrenList.append(affectTextLine) - self.toolTipHeight += 16 + 2 - - # MR-10: Add real-time remaining time display for accessory sockets. - if 0 != leftTime: - isEquipped = False - - if self.itemWindowType == player.INVENTORY and self.itemSlotIndex >= 0: - isEquipped = player.IsEquipmentSlot(self.itemSlotIndex) - - if isEquipped: - endTime = self.__GetAccessorySocketEndTime(leftTime, index) - leftSec = max(0, endTime - app.GetGlobalTimeStamp()) - timeText = localeInfo.LEFT_TIME + " : " + localeInfo.RTSecondToDHMS(leftSec) - else: - endTime = None - timeText = localeInfo.LEFT_TIME + " : " + localeInfo.RTSecondToDHMS(leftTime) - # MR-10: -- END OF -- Add real-time remaining time display for accessory sockets. - - timeTextLine = ui.TextLine() - timeTextLine.SetParent(self) - timeTextLine.SetFontName(self.defFontName) - timeTextLine.SetPackedFontColor(self.POSITIVE_COLOR) - timeTextLine.SetPosition(50, self.toolTipHeight + 16 + 2 + 16 + 2) - timeTextLine.SetOutline() - timeTextLine.SetFeather() - timeTextLine.Show() - timeTextLine.SetText(timeText) - self.childrenList.append(timeTextLine) - - # MR-10: Add real-time remaining time display for accessory sockets. - if isEquipped and endTime is not None: - self.timeInfoList.append({"line": timeTextLine, "value": endTime, "limit": None}) - # MR-10: -- END OF -- Add real-time remaining time display for accessory sockets. - - self.toolTipHeight += 16 + 2 - - else: - nameTextLine.SetText(localeInfo.TOOLTIP_SOCKET_EMPTY) - - self.toolTipHeight += 35 - self.ResizeToolTip() - - def __AppendFishInfo(self, size): - if size > 0: - self.AppendSpace(5) - self.AppendTextLine(localeInfo.TOOLTIP_FISH_LEN % (float(size) / 100.0), self.NORMAL_COLOR) - - def AppendUniqueItemLastTime(self, restMin): - if restMin > 0: - restSecond = restMin * 60 - - self.AppendSpace(5) - self.AppendTextLine(localeInfo.LEFT_TIME + " : " + localeInfo.RTSecondToDHMS(restSecond), self.NORMAL_COLOR) - - def AppendMallItemLastTime(self, endTime, getLimit): - if endTime > 0: - self.AppendSpace(5) - self.AppendTextLineTime(endTime, getLimit) - - def AppendTextLineTime(self, endTime, getLimit, color = FONT_COLOR): - leftSec = max(0, endTime - app.GetGlobalTimeStamp()) - - timeTextLine = ui.TextLine() - timeTextLine.SetParent(self) - timeTextLine.SetFontName(self.defFontName) - timeTextLine.SetPackedFontColor(color) - - if not self.isShopItem: - timeTextLine.SetText(localeInfo.LEFT_TIME + ": " + localeInfo.RTSecondToDHMS(leftSec)) - - timeTextLine.SetOutline() - timeTextLine.SetFeather(False) - timeTextLine.SetPosition(self.toolTipWidth // 2, self.toolTipHeight) - timeTextLine.SetHorizontalAlignCenter() - timeTextLine.Show() - - self.timeInfoList.append({"line": timeTextLine, "value": endTime, "limit": getLimit}) - - self.toolTipHeight += self.TEXT_LINE_HEIGHT - self.ResizeToolTip() - - return timeTextLine - - def AppendTimerBasedOnWearLastTime(self, metinSlot, getLimit): - remainSec = metinSlot[0] - - if remainSec <= 0: - self.AppendSpace(5) - self.AppendTextLine(localeInfo.CANNOT_USE, self.DISABLE_COLOR) - - return - - isTimerActive = self.__IsTimerBasedOnWearActive() - - if not isTimerActive: - self.AppendSpace(5) - self.AppendTextLine(localeInfo.LEFT_TIME + ": " + localeInfo.RTSecondToDHMS(remainSec), self.NORMAL_COLOR) - - return - - endTime = self.__GetOrCreateCachedEndTime(remainSec) - - self.AppendMallItemLastTime(endTime, getLimit) - - def __IsTimerBasedOnWearActive(self): - item.SelectItem(self.itemVnum) - - if item.GetItemType() == item.ITEM_TYPE_DS: - isEquippedOnDeck = (self.itemWindowType == player.INVENTORY) - isDeckActivated = self.wndDragonSoul and self.wndDragonSoul.isActivated - return isEquippedOnDeck and isDeckActivated - - return True - - def __GetOrCreateCachedEndTime(self, remainSec): - key = (self.itemVnum, self.itemSlotIndex) - cache = self.dsActivatedTimeCache.get(key) - - if cache and cache["remainSec"] == remainSec: - return cache["endTime"] - - now = app.GetGlobalTimeStamp() - endTime = now + remainSec - self.dsActivatedTimeCache[key] = {"remainSec": remainSec, "endTime": endTime} - return endTime - - # MR-10: Add real-time remaining time display for accessory sockets. - def __GetAccessorySocketEndTime(self, remainSec, socketIndex): - key = (self.itemWindowType, self.itemSlotIndex, socketIndex, self.itemVnum) - cache = self.accessorySocketTimeCache.get(key) - - now = app.GetGlobalTimeStamp() - - if cache: - cachedEnd = cache.get("endTime", 0) - cachedRemain = cache.get("remainSec", remainSec) - - if cachedEnd > now and remainSec >= cachedRemain: - return cachedEnd - - endTime = now + remainSec - self.accessorySocketTimeCache[key] = {"remainSec": remainSec, "endTime": endTime} - - return endTime - # MR-10: -- END OF -- Add real-time remaining time display for accessory sockets. - - def AppendRealTimeStartFirstUseLastTime(self, item, metinSlot, limitIndex, getLimit): - useCount = metinSlot[1] - endTime = metinSlot[0] - - # If it has been used even once, Socket0 will have an end time (such as 13:01 on March 1, 2012). - # If it has not been used, Socket0 may have an available time (such as 600, in seconds). If it is 0, the available time in the Limit Value is used. - if 0 == useCount: - if 0 == endTime: - (limitType, limitValue) = item.GetLimit(limitIndex) - endTime = limitValue - - self.AppendUniqueItemLastTime(endTime // 60) - - return - - endTime += app.GetGlobalTimeStamp() - - self.AppendMallItemLastTime(endTime, getLimit) - -class HyperlinkItemToolTip(ItemToolTip): - def __init__(self): - ItemToolTip.__init__(self, isPickable=True) - - def SetHyperlinkItem(self, tokens): - minTokenCount = 3 + player.METIN_SOCKET_MAX_NUM - maxTokenCount = minTokenCount + 2 * player.ATTRIBUTE_SLOT_MAX_NUM - if tokens and len(tokens) >= minTokenCount and len(tokens) <= maxTokenCount: - head, vnum, flag = tokens[:3] - itemVnum = int(vnum, 16) - metinSlot = [int(metin, 16) for metin in tokens[3:6]] - - rests = tokens[6:] - if rests: - attrSlot = [] - - rests.reverse() - while rests: - key = int(rests.pop(), 16) - if rests: - val = int(rests.pop()) - attrSlot.append((key, val)) - - attrSlot += [(0, 0)] * (player.ATTRIBUTE_SLOT_MAX_NUM - len(attrSlot)) - else: - attrSlot = [(0, 0)] * player.ATTRIBUTE_SLOT_MAX_NUM - - self.ClearToolTip() - self.AddItemData(itemVnum, metinSlot, attrSlot) - - ItemToolTip.OnUpdate(self) - - def OnUpdate(self): - pass - - def OnMouseLeftButtonDown(self): - self.Hide() - -class SkillToolTip(ToolTip): - - POINT_NAME_DICT = { - player.LEVEL : localeInfo.SKILL_TOOLTIP_LEVEL, - player.IQ : localeInfo.SKILL_TOOLTIP_INT, - } - - SKILL_TOOL_TIP_WIDTH = 200 - PARTY_SKILL_TOOL_TIP_WIDTH = 340 - - PARTY_SKILL_EXPERIENCE_AFFECT_LIST = ( ( 2, 2, 10,), - ( 8, 3, 20,), - (14, 4, 30,), - (22, 5, 45,), - (28, 6, 60,), - (34, 7, 80,), - (38, 8, 100,), ) - - PARTY_SKILL_PLUS_GRADE_AFFECT_LIST = ( ( 4, 2, 1, 0,), - (10, 3, 2, 0,), - (16, 4, 2, 1,), - (24, 5, 2, 2,), ) - - PARTY_SKILL_ATTACKER_AFFECT_LIST = ( ( 36, 3, ), - ( 26, 1, ), - ( 32, 2, ), ) - - SKILL_GRADE_NAME = {} - AFFECT_NAME_DICT = {} - AFFECT_APPEND_TEXT_DICT = { - "DODGE" : "%", - "RESIST_NORMAL" : "%", - "REFLECT_MELEE" : "%", - } - - @staticmethod - def _RebuildLocaleStrings(): - SkillToolTip.SKILL_GRADE_NAME = { - player.SKILL_GRADE_MASTER : localeInfo.SKILL_GRADE_NAME_MASTER, - player.SKILL_GRADE_GRAND_MASTER : localeInfo.SKILL_GRADE_NAME_GRAND_MASTER, - player.SKILL_GRADE_PERFECT_MASTER : localeInfo.SKILL_GRADE_NAME_PERFECT_MASTER, - } - SkillToolTip.AFFECT_NAME_DICT = { - "HP" : localeInfo.TOOLTIP_SKILL_AFFECT_ATT_POWER, - "ATT_GRADE" : localeInfo.TOOLTIP_SKILL_AFFECT_ATT_GRADE, - "DEF_GRADE" : localeInfo.TOOLTIP_SKILL_AFFECT_DEF_GRADE, - "ATT_SPEED" : localeInfo.TOOLTIP_SKILL_AFFECT_ATT_SPEED, - "MOV_SPEED" : localeInfo.TOOLTIP_SKILL_AFFECT_MOV_SPEED, - "DODGE" : localeInfo.TOOLTIP_SKILL_AFFECT_DODGE, - "RESIST_NORMAL" : localeInfo.TOOLTIP_SKILL_AFFECT_RESIST_NORMAL, - "REFLECT_MELEE" : localeInfo.TOOLTIP_SKILL_AFFECT_REFLECT_MELEE, - } - - def __init__(self): - ToolTip.__init__(self, self.SKILL_TOOL_TIP_WIDTH) - def __del__(self): - ToolTip.__del__(self) - - def SetSkill(self, skillIndex, skillLevel = -1): - - if 0 == skillIndex: - return - - if skill.SKILL_TYPE_GUILD == skill.GetSkillType(skillIndex): - - if self.SKILL_TOOL_TIP_WIDTH != self.toolTipWidth: - self.toolTipWidth = self.SKILL_TOOL_TIP_WIDTH - self.ResizeToolTip() - - self.AppendDefaultData(skillIndex) - self.AppendSkillConditionData(skillIndex) - self.AppendGuildSkillData(skillIndex, skillLevel) - - else: - - if self.SKILL_TOOL_TIP_WIDTH != self.toolTipWidth: - self.toolTipWidth = self.SKILL_TOOL_TIP_WIDTH - self.ResizeToolTip() - - slotIndex = player.GetSkillSlotIndex(skillIndex) - skillGrade = player.GetSkillGrade(slotIndex) - skillLevel = player.GetSkillLevel(slotIndex) - skillCurrentPercentage = player.GetSkillCurrentEfficientPercentage(slotIndex) - skillNextPercentage = player.GetSkillNextEfficientPercentage(slotIndex) - - self.AppendDefaultData(skillIndex) - self.AppendSkillConditionData(skillIndex) - self.AppendSkillDataNew(slotIndex, skillIndex, skillGrade, skillLevel, skillCurrentPercentage, skillNextPercentage) - self.AppendSkillRequirement(skillIndex, skillLevel) - - self.ShowToolTip() - - def SetSkillNew(self, slotIndex, skillIndex, skillGrade, skillLevel): - - if 0 == skillIndex: - return - - if player.SKILL_INDEX_TONGSOL == skillIndex: - - slotIndex = player.GetSkillSlotIndex(skillIndex) - skillLevel = player.GetSkillLevel(slotIndex) - - self.AppendDefaultData(skillIndex) - self.AppendPartySkillData(skillGrade, skillLevel) - - elif player.SKILL_INDEX_RIDING == skillIndex: - - slotIndex = player.GetSkillSlotIndex(skillIndex) - self.AppendSupportSkillDefaultData(skillIndex, skillGrade, skillLevel, 30) - - elif player.SKILL_INDEX_SUMMON == skillIndex: - - maxLevel = 10 - - self.ClearToolTip() - self.__SetSkillTitle(skillIndex, skillGrade) - - ## Description - description = skill.GetSkillDescription(skillIndex) - self.AppendDescription(description) - - if skillLevel == 10: - self.AppendSpace(5) - self.AppendTextLine(localeInfo.TOOLTIP_SKILL_LEVEL_MASTER % (skillLevel), self.NORMAL_COLOR) - self.AppendTextLine(localeInfo.SKILL_SUMMON_DESCRIPTION % (skillLevel*10), self.NORMAL_COLOR) - - else: - self.AppendSpace(5) - self.AppendTextLine(localeInfo.TOOLTIP_SKILL_LEVEL % (skillLevel), self.NORMAL_COLOR) - self.__AppendSummonDescription(skillLevel, self.NORMAL_COLOR) - - self.AppendSpace(5) - self.AppendTextLine(localeInfo.TOOLTIP_SKILL_LEVEL % (skillLevel+1), self.NEGATIVE_COLOR) - self.__AppendSummonDescription(skillLevel+1, self.NEGATIVE_COLOR) - - elif skill.SKILL_TYPE_GUILD == skill.GetSkillType(skillIndex): - - if self.SKILL_TOOL_TIP_WIDTH != self.toolTipWidth: - self.toolTipWidth = self.SKILL_TOOL_TIP_WIDTH - self.ResizeToolTip() - - self.AppendDefaultData(skillIndex) - self.AppendSkillConditionData(skillIndex) - self.AppendGuildSkillData(skillIndex, skillLevel) - - else: - - if self.SKILL_TOOL_TIP_WIDTH != self.toolTipWidth: - self.toolTipWidth = self.SKILL_TOOL_TIP_WIDTH - self.ResizeToolTip() - - slotIndex = player.GetSkillSlotIndex(skillIndex) - - skillCurrentPercentage = player.GetSkillCurrentEfficientPercentage(slotIndex) - skillNextPercentage = player.GetSkillNextEfficientPercentage(slotIndex) - - self.AppendDefaultData(skillIndex, skillGrade) - self.AppendSkillConditionData(skillIndex) - self.AppendSkillDataNew(slotIndex, skillIndex, skillGrade, skillLevel, skillCurrentPercentage, skillNextPercentage) - self.AppendSkillRequirement(skillIndex, skillLevel) - - self.ShowToolTip() - - def __SetSkillTitle(self, skillIndex, skillGrade): - self.SetTitle(skill.GetSkillName(skillIndex, skillGrade)) - self.__AppendSkillGradeName(skillIndex, skillGrade) - - def __AppendSkillGradeName(self, skillIndex, skillGrade): - if skillGrade in self.SKILL_GRADE_NAME: - self.AppendSpace(5) - self.AppendTextLine(self.SKILL_GRADE_NAME[skillGrade] % (skill.GetSkillName(skillIndex, 0)), self.CAN_LEVEL_UP_COLOR) - - def SetSkillOnlyName(self, slotIndex, skillIndex, skillGrade): - if 0 == skillIndex: - return - - slotIndex = player.GetSkillSlotIndex(skillIndex) - - self.toolTipWidth = self.SKILL_TOOL_TIP_WIDTH - self.ResizeToolTip() - - self.ClearToolTip() - self.__SetSkillTitle(skillIndex, skillGrade) - self.AppendDefaultData(skillIndex, skillGrade) - self.AppendSkillConditionData(skillIndex) - self.ShowToolTip() - - def AppendDefaultData(self, skillIndex, skillGrade = 0): - self.ClearToolTip() - self.__SetSkillTitle(skillIndex, skillGrade) - - ## Level Limit - levelLimit = skill.GetSkillLevelLimit(skillIndex) - if levelLimit > 0: - - color = self.NORMAL_COLOR - if player.GetStatus(player.LEVEL) < levelLimit: - color = self.NEGATIVE_COLOR - - self.AppendSpace(5) - self.AppendTextLine(localeInfo.TOOLTIP_ITEM_LIMIT_LEVEL % (levelLimit), color) - - ## Description - description = skill.GetSkillDescription(skillIndex) - self.AppendDescription(description) - - def AppendSupportSkillDefaultData(self, skillIndex, skillGrade, skillLevel, maxLevel): - self.ClearToolTip() - self.__SetSkillTitle(skillIndex, skillGrade) - - ## Description - description = skill.GetSkillDescription(skillIndex) - self.AppendDescription(description) - - if 1 == skillGrade: - skillLevel += 19 - elif 2 == skillGrade: - skillLevel += 29 - elif 3 == skillGrade: - skillLevel = 40 - - self.AppendSpace(5) - self.AppendTextLine(localeInfo.TOOLTIP_SKILL_LEVEL_WITH_MAX % (skillLevel, maxLevel), self.NORMAL_COLOR) - - def AppendSkillConditionData(self, skillIndex): - conditionDataCount = skill.GetSkillConditionDescriptionCount(skillIndex) - if conditionDataCount > 0: - self.AppendSpace(5) - - for i in range(conditionDataCount): - self.AppendTextLine(skill.GetSkillConditionDescription(skillIndex, i), self.CONDITION_COLOR) - - def AppendGuildSkillData(self, skillIndex, skillLevel): - skillMaxLevel = 7 - skillCurrentPercentage = float(skillLevel) / float(skillMaxLevel) - skillNextPercentage = float(skillLevel + 1) / float(skillMaxLevel) - - ## Current Level - if skillLevel > 0: - if self.HasSkillLevelDescription(skillIndex, skillLevel): - self.AppendSpace(5) - - if skillLevel == skillMaxLevel: - self.AppendTextLine(localeInfo.TOOLTIP_SKILL_LEVEL_MASTER % (skillLevel), self.NORMAL_COLOR) - else: - self.AppendTextLine(localeInfo.TOOLTIP_SKILL_LEVEL % (skillLevel), self.NORMAL_COLOR) - - ##### - - for i in range(skill.GetSkillAffectDescriptionCount(skillIndex)): - self.AppendTextLine(skill.GetSkillAffectDescription(skillIndex, i, skillCurrentPercentage), self.ENABLE_COLOR) - - ## Cooltime - coolTime = skill.GetSkillCoolTime(skillIndex, skillCurrentPercentage) - - if coolTime > 0: - self.AppendTextLine(localeInfo.TOOLTIP_SKILL_COOL_TIME + str(coolTime), self.ENABLE_COLOR) - - ## SP - needGSP = skill.GetSkillNeedSP(skillIndex, skillCurrentPercentage) - if needGSP > 0: - self.AppendTextLine(localeInfo.TOOLTIP_NEED_GSP % (needGSP), self.ENABLE_COLOR) - - ## Next Level - if skillLevel < skillMaxLevel: - if self.HasSkillLevelDescription(skillIndex, skillLevel+1): - self.AppendSpace(5) - self.AppendTextLine(localeInfo.TOOLTIP_NEXT_SKILL_LEVEL_1 % (skillLevel+1, skillMaxLevel), self.DISABLE_COLOR) - - ##### - - for i in range(skill.GetSkillAffectDescriptionCount(skillIndex)): - self.AppendTextLine(skill.GetSkillAffectDescription(skillIndex, i, skillNextPercentage), self.DISABLE_COLOR) - - ## Cooltime - coolTime = skill.GetSkillCoolTime(skillIndex, skillNextPercentage) - if coolTime > 0: - self.AppendTextLine(localeInfo.TOOLTIP_SKILL_COOL_TIME + str(coolTime), self.DISABLE_COLOR) - - ## SP - needGSP = skill.GetSkillNeedSP(skillIndex, skillNextPercentage) - if needGSP > 0: - self.AppendTextLine(localeInfo.TOOLTIP_NEED_GSP % (needGSP), self.DISABLE_COLOR) - - def AppendSkillDataNew(self, slotIndex, skillIndex, skillGrade, skillLevel, skillCurrentPercentage, skillNextPercentage): - - self.skillMaxLevelStartDict = { 0 : 17, 1 : 7, 2 : 10, } - self.skillMaxLevelEndDict = { 0 : 20, 1 : 10, 2 : 10, } - - skillLevelUpPoint = 1 - realSkillGrade = player.GetSkillGrade(slotIndex) - skillMaxLevelStart = self.skillMaxLevelStartDict.get(realSkillGrade, 15) - skillMaxLevelEnd = self.skillMaxLevelEndDict.get(realSkillGrade, 20) - - ## Current Level - if skillLevel > 0: - if self.HasSkillLevelDescription(skillIndex, skillLevel): - self.AppendSpace(5) - if skillGrade == skill.SKILL_GRADE_COUNT: - pass - elif skillLevel == skillMaxLevelEnd: - self.AppendTextLine(localeInfo.TOOLTIP_SKILL_LEVEL_MASTER % (skillLevel), self.NORMAL_COLOR) - else: - self.AppendTextLine(localeInfo.TOOLTIP_SKILL_LEVEL % (skillLevel), self.NORMAL_COLOR) - self.AppendSkillLevelDescriptionNew(skillIndex, skillCurrentPercentage, self.ENABLE_COLOR) - - ## Next Level - if skillGrade != skill.SKILL_GRADE_COUNT: - if skillLevel < skillMaxLevelEnd: - if self.HasSkillLevelDescription(skillIndex, skillLevel+skillLevelUpPoint): - self.AppendSpace(5) - ## In case of HP reinforcement, penetration evasion auxiliary skills - if skillIndex == 141 or skillIndex == 142: - self.AppendTextLine(localeInfo.TOOLTIP_NEXT_SKILL_LEVEL_3 % (skillLevel+1), self.DISABLE_COLOR) - else: - self.AppendTextLine(localeInfo.TOOLTIP_NEXT_SKILL_LEVEL_1 % (skillLevel+1, skillMaxLevelEnd), self.DISABLE_COLOR) - self.AppendSkillLevelDescriptionNew(skillIndex, skillNextPercentage, self.DISABLE_COLOR) - - def AppendSkillLevelDescriptionNew(self, skillIndex, skillPercentage, color): - - affectDataCount = skill.GetNewAffectDataCount(skillIndex) - if affectDataCount > 0: - for i in range(affectDataCount): - type, minValue, maxValue = skill.GetNewAffectData(skillIndex, i, skillPercentage) - - if type not in self.AFFECT_NAME_DICT: - continue - - minValue = int(minValue) - maxValue = int(maxValue) - affectText = self.AFFECT_NAME_DICT[type] - - if "HP" == type: - if minValue < 0 and maxValue < 0: - minValue *= -1 - maxValue *= -1 - - else: - affectText = localeInfo.TOOLTIP_SKILL_AFFECT_HEAL - - affectText += str(minValue) - if minValue != maxValue: - affectText += " - " + str(maxValue) - affectText += self.AFFECT_APPEND_TEXT_DICT.get(type, "") - - #import debugInfo - #if debugInfo.IsDebugMode(): - # affectText = "!!" + affectText - - self.AppendTextLine(affectText, color) - - else: - for i in range(skill.GetSkillAffectDescriptionCount(skillIndex)): - self.AppendTextLine(skill.GetSkillAffectDescription(skillIndex, i, skillPercentage), color) - - - ## Duration - duration = skill.GetDuration(skillIndex, skillPercentage) - if duration > 0: - self.AppendTextLine(localeInfo.TOOLTIP_SKILL_DURATION % (duration), color) - - ## Cooltime - coolTime = skill.GetSkillCoolTime(skillIndex, skillPercentage) - if coolTime > 0: - self.AppendTextLine(localeInfo.TOOLTIP_SKILL_COOL_TIME + str(coolTime), color) - - ## SP - needSP = skill.GetSkillNeedSP(skillIndex, skillPercentage) - if needSP != 0: - continuationSP = skill.GetSkillContinuationSP(skillIndex, skillPercentage) - - if skill.IsUseHPSkill(skillIndex): - self.AppendNeedHP(needSP, continuationSP, color) - else: - self.AppendNeedSP(needSP, continuationSP, color) - - def AppendSkillRequirement(self, skillIndex, skillLevel): - - skillMaxLevel = skill.GetSkillMaxLevel(skillIndex) - - if skillLevel >= skillMaxLevel: - return - - isAppendHorizontalLine = False - - ## Requirement - if skill.IsSkillRequirement(skillIndex): - - if not isAppendHorizontalLine: - isAppendHorizontalLine = True - self.AppendHorizontalLine() - - requireSkillName, requireSkillLevel = skill.GetSkillRequirementData(skillIndex) - - color = self.CANNOT_LEVEL_UP_COLOR - if skill.CheckRequirementSueccess(skillIndex): - color = self.CAN_LEVEL_UP_COLOR - self.AppendTextLine(localeInfo.TOOLTIP_REQUIREMENT_SKILL_LEVEL % (requireSkillName, requireSkillLevel), color) - - ## Require Stat - requireStatCount = skill.GetSkillRequireStatCount(skillIndex) - if requireStatCount > 0: - - for i in range(requireStatCount): - type, level = skill.GetSkillRequireStatData(skillIndex, i) - if type in self.POINT_NAME_DICT: - - if not isAppendHorizontalLine: - isAppendHorizontalLine = True - self.AppendHorizontalLine() - - name = self.POINT_NAME_DICT[type] - color = self.CANNOT_LEVEL_UP_COLOR - if player.GetStatus(type) >= level: - color = self.CAN_LEVEL_UP_COLOR - self.AppendTextLine(localeInfo.TOOLTIP_REQUIREMENT_STAT_LEVEL % (name, level), color) - - def HasSkillLevelDescription(self, skillIndex, skillLevel): - if skill.GetSkillAffectDescriptionCount(skillIndex) > 0: - return True - if skill.GetSkillCoolTime(skillIndex, skillLevel) > 0: - return True - if skill.GetSkillNeedSP(skillIndex, skillLevel) > 0: - return True - - return False - - def AppendMasterAffectDescription(self, index, desc, color): - self.AppendTextLine(desc, color) - - def AppendNextAffectDescription(self, index, desc): - self.AppendTextLine(desc, self.DISABLE_COLOR) - - def AppendNeedHP(self, needSP, continuationSP, color): - - self.AppendTextLine(localeInfo.TOOLTIP_NEED_HP % (needSP), color) - - if continuationSP > 0: - self.AppendTextLine(localeInfo.TOOLTIP_NEED_HP_PER_SEC % (continuationSP), color) - - def AppendNeedSP(self, needSP, continuationSP, color): - - if -1 == needSP: - self.AppendTextLine(localeInfo.TOOLTIP_NEED_ALL_SP, color) - - else: - self.AppendTextLine(localeInfo.TOOLTIP_NEED_SP % (needSP), color) - - if continuationSP > 0: - self.AppendTextLine(localeInfo.TOOLTIP_NEED_SP_PER_SEC % (continuationSP), color) - - def AppendPartySkillData(self, skillGrade, skillLevel): - - if 1 == skillGrade: - skillLevel += 19 - elif 2 == skillGrade: - skillLevel += 29 - elif 3 == skillGrade: - skillLevel = 40 - - if skillLevel <= 0: - return - - skillIndex = player.SKILL_INDEX_TONGSOL - slotIndex = player.GetSkillSlotIndex(skillIndex) - skillPower = player.GetSkillCurrentEfficientPercentage(slotIndex) - k = player.GetSkillLevel(skillIndex) / 100.0 - - self.AppendSpace(5) - self.AutoAppendTextLine(localeInfo.TOOLTIP_PARTY_SKILL_LEVEL % skillLevel, self.NORMAL_COLOR) - - if skillLevel >= 10: - self.AutoAppendTextLine(localeInfo.PARTY_SKILL_ATTACKER % chop( 10 + 60 * k )) - - if skillLevel >= 20: - self.AutoAppendTextLine(localeInfo.PARTY_SKILL_BERSERKER % chop(1 + 5 * k)) - self.AutoAppendTextLine(localeInfo.PARTY_SKILL_TANKER % chop(50 + 1450 * k)) - - if skillLevel >= 25: - self.AutoAppendTextLine(localeInfo.PARTY_SKILL_BUFFER % chop(5 + 45 * k )) - - if skillLevel >= 35: - self.AutoAppendTextLine(localeInfo.PARTY_SKILL_SKILL_MASTER % chop(25 + 600 * k )) - - if skillLevel >= 40: - self.AutoAppendTextLine(localeInfo.PARTY_SKILL_DEFENDER % chop( 5 + 30 * k )) - - self.AlignHorizonalCenter() - - def __AppendSummonDescription(self, skillLevel, color): - if skillLevel > 1: - self.AppendTextLine(localeInfo.SKILL_SUMMON_DESCRIPTION % (skillLevel * 10), color) - elif 1 == skillLevel: - self.AppendTextLine(localeInfo.SKILL_SUMMON_DESCRIPTION % (15), color) - elif 0 == skillLevel: - self.AppendTextLine(localeInfo.SKILL_SUMMON_DESCRIPTION % (10), color) - - -if __name__ == "__main__": - import app - import wndMgr - import systemSetting - import mouseModule - import grp - import ui - - #wndMgr.SetOutlineFlag(True) - - app.SetMouseHandler(mouseModule.mouseController) - app.SetHairColorEnable(True) - wndMgr.SetMouseHandler(mouseModule.mouseController) - wndMgr.SetScreenSize(systemSetting.GetWidth(), systemSetting.GetHeight()) - app.Create("METIN2 CLOSED BETA", systemSetting.GetWidth(), systemSetting.GetHeight(), 1) - mouseModule.mouseController.Create() - - toolTip = ItemToolTip() - toolTip.ClearToolTip() - #toolTip.AppendTextLine("Test") - desc = "Item descriptions:|increase of width of display to 35 digits per row AND installation of function that the displayed words are not broken up in two parts, but instead if one word is too long to be displayed in this row, this word will start in the next row." - summ = "" - - toolTip.AddItemData_Offline(10, desc, summ, 0, 0) - toolTip.Show() - - app.Loop() - -SkillToolTip._RebuildLocaleStrings() -localeInfo.RegisterReloadCallback(SkillToolTip._RebuildLocaleStrings) diff --git a/tools/root/uiuploadmark.py b/tools/root/uiuploadmark.py deleted file mode 100644 index 8c1d3d99..00000000 --- a/tools/root/uiuploadmark.py +++ /dev/null @@ -1,392 +0,0 @@ -import app -import ui -import localeInfo -import uiScriptLocale - -class MarkItem(ui.ListBoxEx.Item): - def __init__(self, fileName): - ui.ListBoxEx.Item.__init__(self) - self.fileName = fileName - self.fullPath = "upload/" + fileName - self.imgWidth = 0 - self.imgHeight = 0 - self.canLoad = 0 - self.imgBox = None - self.imageLoaded = False - self.textLine = self.__CreateTextLine(fileName) - - def __del__(self): - ui.ListBoxEx.Item.__del__(self) - - def GetText(self): - return self.textLine.GetText() - - def SetSize(self, width, height): - ui.ListBoxEx.Item.SetSize(self, 20 + 6*len(self.textLine.GetText()) + 4, height) - - def __CreateTextLine(self, fileName): - textLine = ui.TextLine() - textLine.SetParent(self) - textLine.SetPosition(20, 0) - textLine.SetText(fileName) - textLine.Show() - return textLine - - def LoadImageInfo(self): - """Load image info lazily when needed (e.g., when selected or validated)""" - if self.imageLoaded: - return - - self.imageLoaded = True - (self.canLoad, self.imgWidth, self.imgHeight) = app.GetImageInfo(self.fullPath) - - if self.canLoad == 1 and self.imgWidth == 16 and self.imgHeight == 12: - imgBox = ui.ImageBox() - imgBox.AddFlag("not_pick") - imgBox.SetParent(self) - imgBox.SetPosition(0, 2) - imgBox.LoadImageFromFile(self.fullPath) - imgBox.Show() - self.imgBox = imgBox - - def OnRender(self): - # Load image when item becomes visible (rendered) - if not self.imageLoaded: - self.LoadImageInfo() - # Call parent to draw selection bar - ui.ListBoxEx.Item.OnRender(self) - -class SymbolItem(ui.ListBoxEx.Item): - def __init__(self, fileName): - ui.ListBoxEx.Item.__init__(self) - self.fileName = fileName - self.fullPath = "upload/" + fileName - self.imgWidth = 0 - self.imgHeight = 0 - self.canLoad = 0 - self.imageLoaded = False - self.textLine = self.__CreateTextLine(fileName) - - def __del__(self): - ui.ListBoxEx.Item.__del__(self) - - def GetText(self): - return self.textLine.GetText() - - def SetSize(self, width, height): - ui.ListBoxEx.Item.SetSize(self, 6*len(self.textLine.GetText()) + 4, height) - - def __CreateTextLine(self, fileName): - textLine = ui.TextLine() - textLine.SetParent(self) - textLine.SetPosition(1, 2) - textLine.SetText(fileName) - textLine.Show() - return textLine - - def LoadImageInfo(self): - """Load image info lazily when needed""" - if self.imageLoaded: - return - - self.imageLoaded = True - (self.canLoad, self.imgWidth, self.imgHeight) = app.GetImageInfo(self.fullPath) - - def OnRender(self): - # Load image when item becomes visible (rendered) - if not self.imageLoaded: - self.LoadImageInfo() - # Call parent to draw selection bar - ui.ListBoxEx.Item.OnRender(self) - -class PopupDialog(ui.ScriptWindow): - def __init__(self, parent): - print("NEW POPUP WINDOW ----------------------------------------------------------------------------") - ui.ScriptWindow.__init__(self) - - self.__Load() - self.__Bind() - - def __del__(self): - ui.ScriptWindow.__del__(self) - print("---------------------------------------------------------------------------- DELETE POPUP WINDOW") - - def __Load(self): - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "UIScript/PopupDialog.py") - except: - import exception - exception.Abort("PopupDialog.__Load") - - def __Bind(self): - try: - self.textLine=self.GetChild("message") - self.okButton=self.GetChild("accept") - except: - import exception - exception.Abort("PopupDialog.__Bind") - - self.okButton.SetEvent(ui.__mem_func__(self.__OnOK)) - - def Open(self, msg): - self.textLine.SetText(msg) - self.SetCenterPosition() - self.Show() - self.SetTop() - - def __OnOK(self): - self.Hide() - -class MarkSelectDialog(ui.ScriptWindow): - def __init__(self): - print("NEW MARK LIST WINDOW ----------------------------------------------------------------------------") - ui.ScriptWindow.__init__(self) - - self.selectEvent=None - self.isLoaded=0 - - def __del__(self): - ui.ScriptWindow.__del__(self) - print("---------------------------------------------------------------------------- DELETE MARK LIST WINDOW") - - def Show(self): - if self.isLoaded==0: - self.isLoaded=1 - - self.__Load() - - ui.ScriptWindow.Show(self) - - def Open(self): - self.Show() - - self.SetCenterPosition() - self.SetTop() - - if self.markListBox.IsEmpty(): - self.__PopupMessage(localeInfo.GUILDMARK_UPLOADER_ERROR_PATH) - - def Close(self): - self.popupDialog.Hide() - self.Hide() - - def OnPressEscapeKey(self): - self.Close() - return True - - def SAFE_SetSelectEvent(self, event): - self.selectEvent=ui.__mem_func__(event) - - def __CreateMarkListBox(self): - markListBox=ui.ListBoxEx() - markListBox.SetParent(self) - markListBox.SetPosition(15, 50) - markListBox.Show() - return markListBox - - def __Load(self): - self.popupDialog=PopupDialog(self) - - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "UIScript/MarkListWindow.py") - except: - import exception - exception.Abort("MarkListBox.__Load") - - try: - self.markListBox=self.__CreateMarkListBox() - self.markListBox.SetScrollBar(self.GetChild("ScrollBar")) - - self.popupText = self.popupDialog.GetChild("message") - self.popupDialog.GetChild("accept").SetEvent(ui.__mem_func__(self.popupDialog.Hide)) - - self.board=self.GetChild("board") - self.okButton=self.GetChild("ok") - self.cancelButton=self.GetChild("cancel") - self.refreshButton=self.GetChild("refresh") - - except: - import exception - exception.Abort("MarkListBox.__Bind") - - self.refreshButton.SetEvent(ui.__mem_func__(self.__OnRefresh)) - self.cancelButton.SetEvent(ui.__mem_func__(self.__OnCancel)) - self.okButton.SetEvent(ui.__mem_func__(self.__OnOK)) - self.board.SetCloseEvent(ui.__mem_func__(self.__OnCancel)) - self.UpdateRect() - - self.__RefreshFileList() - - def __PopupMessage(self, msg): - self.popupDialog.Open(msg) - - def __OnOK(self): - selItem = self.markListBox.GetSelectedItem() - if selItem: - # Ensure image info is loaded before validation - selItem.LoadImageInfo() - - if selItem.canLoad != 1: - self.__PopupMessage(localeInfo.GUILDMARK_UPLOADER_ERROR_FILE_FORMAT) - elif selItem.imgWidth != 16: - self.__PopupMessage(localeInfo.GUILDMARK_UPLOADER_ERROR_16_WIDTH) - elif selItem.imgHeight != 12: - self.__PopupMessage(localeInfo.GUILDMARK_UPLOADER_ERROR_12_HEIGHT) - else: - self.selectEvent(selItem.GetText()) - self.Hide() - else: - self.__PopupMessage(localeInfo.GUILDMARK_UPLOADER_ERROR_SELECT) - - def __OnCancel(self): - self.Hide() - - def __OnRefresh(self): - self.__RefreshFileList() - - def __RefreshFileList(self): - self.__ClearFileList() - # Collect all files first, then batch add to avoid multiple UI updates - allFiles = [] - for ext in ("bmp", "tga", "jpg", "jpeg", "png"): - fileNameList = app.GetFileList("upload/*." + ext) - allFiles.extend(fileNameList) - - # Sort alphabetically for consistent display - allFiles.sort() - - # Add all files at once - for fileName in allFiles: - self.__AppendFile(fileName) - - def __ClearFileList(self): - self.markListBox.RemoveAllItems() - - def __AppendFile(self, fileName): - self.markListBox.AppendItem(MarkItem(fileName)) - -class SymbolSelectDialog(ui.ScriptWindow): - def __init__(self): - print("NEW SYMBOL LIST WINDOW ----------------------------------------------------------------------------") - ui.ScriptWindow.__init__(self) - - self.selectEvent=None - self.isLoaded=0 - - def __del__(self): - ui.ScriptWindow.__del__(self) - print("---------------------------------------------------------------------------- DELETE SYMBOL LIST WINDOW") - - def Show(self): - if self.isLoaded==0: - self.isLoaded=1 - - self.__Load() - - ui.ScriptWindow.Show(self) - - def Open(self): - self.Show() - - self.SetCenterPosition() - self.SetTop() - - if self.symbolListBox.IsEmpty(): - self.__PopupMessage(localeInfo.GUILDMARK_UPLOADER_ERROR_PATH) - - def Close(self): - self.popupDialog.Hide() - self.Hide() - - def OnPressEscapeKey(self): - self.Close() - return True - - def SAFE_SetSelectEvent(self, event): - self.selectEvent=ui.__mem_func__(event) - - def __CreateSymbolListBox(self): - symbolListBox=ui.ListBoxEx() - symbolListBox.SetParent(self) - symbolListBox.SetPosition(15, 50) - symbolListBox.Show() - return symbolListBox - - def __Load(self): - self.popupDialog=PopupDialog(self) - - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "UIScript/MarkListWindow.py") - except: - import exception - exception.Abort("SymbolListBox.__Load") - - try: - self.symbolListBox=self.__CreateSymbolListBox() - self.symbolListBox.SetScrollBar(self.GetChild("ScrollBar")) - - self.popupText = self.popupDialog.GetChild("message") - self.popupDialog.GetChild("accept").SetEvent(ui.__mem_func__(self.popupDialog.Hide)) - - self.board=self.GetChild("board") - self.okButton=self.GetChild("ok") - self.cancelButton=self.GetChild("cancel") - self.refreshButton=self.GetChild("refresh") - - except: - import exception - exception.Abort("SymbolListBox.__Bind") - - self.refreshButton.SetEvent(ui.__mem_func__(self.__OnRefresh)) - self.cancelButton.SetEvent(ui.__mem_func__(self.__OnCancel)) - self.okButton.SetEvent(ui.__mem_func__(self.__OnOK)) - self.board.SetCloseEvent(ui.__mem_func__(self.__OnCancel)) - self.board.SetTitleName(localeInfo.SYMBOLLIST_TITLE) - self.UpdateRect() - - self.__RefreshFileList() - - def __PopupMessage(self, msg): - self.popupDialog.Open(msg) - - def __OnOK(self): - selItem = self.symbolListBox.GetSelectedItem() - if selItem: - # Ensure image info is loaded before validation - selItem.LoadImageInfo() - - if selItem.canLoad != 1: - self.__PopupMessage(localeInfo.GUILDMARK_UPLOADER_ERROR_FILE_FORMAT) - elif selItem.imgWidth != 64: - self.__PopupMessage(localeInfo.GUILDMARK_UPLOADER_ERROR_64_WIDTH) - elif selItem.imgHeight != 128: - self.__PopupMessage(localeInfo.GUILDMARK_UPLOADER_ERROR_128_HEIGHT) - else: - self.selectEvent(selItem.GetText()) - self.Hide() - else: - self.__PopupMessage(localeInfo.GUILDMARK_UPLOADER_ERROR_SELECT) - - def __OnCancel(self): - self.Hide() - - def __OnRefresh(self): - self.__RefreshFileList() - - def __RefreshFileList(self): - self.__ClearFileList() - self.__AppendFileList("jpg") - - def __ClearFileList(self): - self.symbolListBox.RemoveAllItems() - - def __AppendFileList(self, filter): - fileNameList=app.GetFileList("upload/*."+filter) - for fileName in fileNameList: - self.__AppendFile(fileName) - - def __AppendFile(self, fileName): - self.symbolListBox.AppendItem(SymbolItem(fileName)) diff --git a/tools/root/uiweb.py b/tools/root/uiweb.py deleted file mode 100644 index adf2f4dd..00000000 --- a/tools/root/uiweb.py +++ /dev/null @@ -1,127 +0,0 @@ -import ui -import uiScriptLocale -import net -import snd -import app -import mouseModule -import constInfo - -class WebWindow(ui.ScriptWindow): - def __init__(self): - ui.ScriptWindow.__init__(self, "TOP_MOST") - - self.oldPos = None - - def __del__(self): - ui.ScriptWindow.__del__(self) - - def LoadWindow(self): - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "UIScript/WebWindow.py") - except: - import exception - exception.Abort("WebWindow.LoadDialog.LoadScript") - - try: - GetObject=self.GetChild - self.titleBar = GetObject("TitleBar") - - except: - import exception - exception.Abort("WebWindow.LoadDialog.BindObject") - - self.titleBar.SetCloseEvent(ui.__mem_func__(self.__OnCloseButtonClick)) - - def Destroy(self): - app.HideWebPage() - self.ClearDictionary() - self.titleBar = None - - def Open(self, url): - self.Refresh() - self.Show() - self.SetCenterPosition() - - x, y = self.GetGlobalPosition() - sx, sy = x + 10, y + 30 - ex, ey = sx + self.GetWidth() - 20, sy + self.GetHeight() - 40 - - app.ShowWebPage(url, (sx, sy, ex, ey)) - - - def Close(self): - app.HideWebPage() - self.Hide() - - def Clear(self): - self.Refresh() - - def Refresh(self): - pass - - def __OnCloseButtonClick(self): - print("close_web:click_close_button") - self.Close() - - def OnPressEscapeKey(self): - print("close_web:esc_key") - self.Close() - return True - - def OnUpdate(self): - newPos = self.GetGlobalPosition() - if newPos == self.oldPos: - return - - self.oldPos = newPos - - x, y = newPos - sx, sy = x + 10, y + 30 - ex, ey = sx + self.GetWidth() - 20, sy + self.GetHeight() - 40 - app.MoveWebPage((sx, sy, ex, ey)) - -if __name__ == "__main__": - - import app - import wndMgr - import systemSetting - import mouseModule - import grp - import ui - import uiToolTip - import localeInfo - - app.SetMouseHandler(mouseModule.mouseController) - app.SetHairColorEnable(True) - wndMgr.SetMouseHandler(mouseModule.mouseController) - wndMgr.SetScreenSize(systemSetting.GetWidth(), systemSetting.GetHeight()) - app.Create("METIN2", systemSetting.GetWidth(), systemSetting.GetHeight(), 1) - mouseModule.mouseController.Create() - - class TestGame(ui.Window): - def __init__(self): - ui.Window.__init__(self) - - localeInfo.LoadLocaleData() - - self.mallWindow = WebWindow() - self.mallWindow.LoadWindow() - self.mallWindow.Open() - - def __del__(self): - ui.Window.__del__(self) - - def OnUpdate(self): - app.UpdateGame() - - def OnRender(self): - app.RenderGame() - grp.PopState() - grp.SetInterfaceRenderState() - - game = TestGame() - game.SetSize(systemSetting.GetWidth(), systemSetting.GetHeight()) - game.Show() - - app.Loop() diff --git a/tools/root/uiwhisper.py b/tools/root/uiwhisper.py deleted file mode 100644 index 6cfe6f32..00000000 --- a/tools/root/uiwhisper.py +++ /dev/null @@ -1,330 +0,0 @@ -import ui -import net -import chat -import player -import app -import localeInfo -import ime -import chr - -class WhisperButton(ui.Button): - def __init__(self): - ui.Button.__init__(self, "TOP_MOST") - - def __del__(self): - ui.Button.__del__(self) - - def SetToolTipText(self, text, x=0, y = 32): - ui.Button.SetToolTipText(self, text, x, y) - self.ToolTipText.Show() - - def SetToolTipTextWithColor(self, text, color, x=0, y = 32): - ui.Button.SetToolTipText(self, text, x, y) - self.ToolTipText.SetPackedFontColor(color) - self.ToolTipText.Show() - - def ShowToolTip(self): - if 0 != self.ToolTipText: - self.ToolTipText.Show() - - def HideToolTip(self): - if 0 != self.ToolTipText: - self.ToolTipText.Show() - -class WhisperDialog(ui.ScriptWindow): - - class TextRenderer(ui.Window): - def SetTargetName(self, targetName): - self.targetName = targetName - - def OnRender(self): - (x, y) = self.GetGlobalPosition() - chat.RenderWhisper(self.targetName, x, y) - - class ResizeButton(ui.DragButton): - - def __init__(self): - ui.DragButton.__init__(self) - - def __del__(self): - ui.DragButton.__del__(self) - - def OnMouseOverIn(self): - app.SetCursor(app.HVSIZE) - - def OnMouseOverOut(self): - app.SetCursor(app.NORMAL) - - def __init__(self, eventMinimize, eventClose): - print("NEW WHISPER DIALOG ----------------------------------------------------------------------------") - ui.ScriptWindow.__init__(self) - self.targetName = "" - self.eventMinimize = eventMinimize - self.eventClose = eventClose - self.eventAcceptTarget = None - def __del__(self): - print("---------------------------------------------------------------------------- DELETE WHISPER DIALOG") - ui.ScriptWindow.__del__(self) - - def LoadDialog(self): - try: - pyScrLoader = ui.PythonScriptLoader() - pyScrLoader.LoadScriptFile(self, "UIScript/WhisperDialog.py") - except: - import exception - exception.Abort("WhisperDialog.LoadDialog.LoadScript") - - try: - GetObject=self.GetChild - self.titleName = GetObject("titlename") - self.titleNameEdit = GetObject("titlename_edit") - self.closeButton = GetObject("closebutton") - self.scrollBar = GetObject("scrollbar") - self.chatLine = GetObject("chatline") - self.minimizeButton = GetObject("minimizebutton") - self.ignoreButton = GetObject("ignorebutton") - self.reportViolentWhisperButton = GetObject("reportviolentwhisperbutton") - self.acceptButton = GetObject("acceptbutton") - self.sendButton = GetObject("sendbutton") - self.board = GetObject("board") - self.editBar = GetObject("editbar") - self.gamemasterMark = GetObject("gamemastermark") - except: - import exception - exception.Abort("DialogWindow.LoadDialog.BindObject") - - self.gamemasterMark.Hide() - self.titleName.SetText("") - self.titleNameEdit.SetText("") - self.minimizeButton.SetEvent(ui.__mem_func__(self.Minimize)) - self.closeButton.SetEvent(ui.__mem_func__(self.Close)) - self.scrollBar.SetPos(1.0) - self.scrollBar.SetScrollEvent(ui.__mem_func__(self.OnScroll)) - self.chatLine.SetReturnEvent(ui.__mem_func__(self.SendWhisper)) - self.chatLine.SetEscapeEvent(ui.__mem_func__(self.Minimize)) - self.chatLine.SetMultiLine() - self.sendButton.SetEvent(ui.__mem_func__(self.SendWhisper)) - self.titleNameEdit.SetReturnEvent(ui.__mem_func__(self.AcceptTarget)) - self.titleNameEdit.SetEscapeEvent(ui.__mem_func__(self.Close)) - self.ignoreButton.SetToggleDownEvent(ui.__mem_func__(self.IgnoreTarget)) - self.ignoreButton.SetToggleUpEvent(ui.__mem_func__(self.IgnoreTarget)) - self.reportViolentWhisperButton.SetEvent(ui.__mem_func__(self.ReportViolentWhisper)) - self.acceptButton.SetEvent(ui.__mem_func__(self.AcceptTarget)) - - self.textRenderer = self.TextRenderer() - self.textRenderer.SetParent(self) - self.textRenderer.SetPosition(20, 28) - self.textRenderer.SetTargetName("") - self.textRenderer.Show() - - self.resizeButton = self.ResizeButton() - self.resizeButton.SetParent(self) - self.resizeButton.SetSize(20, 20) - self.resizeButton.SetPosition(280, 180) - self.resizeButton.SetMoveEvent(ui.__mem_func__(self.ResizeWhisperDialog)) - self.resizeButton.Show() - - self.ResizeWhisperDialog() - - def Destroy(self): - - self.eventMinimize = None - self.eventClose = None - self.eventAcceptTarget = None - - self.ClearDictionary() - self.scrollBar.Destroy() - self.titleName = None - self.titleNameEdit = None - self.closeButton = None - self.scrollBar = None - self.chatLine = None - self.sendButton = None - self.ignoreButton = None - self.reportViolentWhisperButton = None - self.acceptButton = None - self.minimizeButton = None - self.textRenderer = None - self.board = None - self.editBar = None - self.resizeButton = None - - def ResizeWhisperDialog(self): - (xPos, yPos) = self.resizeButton.GetLocalPosition() - if xPos < 280: - self.resizeButton.SetPosition(280, yPos) - return - if yPos < 150: - self.resizeButton.SetPosition(xPos, 150) - return - self.SetWhisperDialogSize(xPos + 20, yPos + 20) - - def SetWhisperDialogSize(self, width, height): - try: - - max = int((width-90)/6) * 3 - 6 - - self.board.SetSize(width, height) - self.scrollBar.SetPosition(width-25, 35) - self.scrollBar.SetScrollBarSize(height-100) - self.scrollBar.SetPos(1.0) - self.editBar.SetSize(width-18, 50) - self.chatLine.SetSize(width-90, 40) - self.chatLine.SetLimitWidth(width-90) - self.SetSize(width, height) - - if 0 != self.targetName: - chat.SetWhisperBoxSize(self.targetName, width - 50, height - 90) - - if app.IsRTL(): - self.textRenderer.SetPosition(width-20, 28) - self.scrollBar.SetPosition(width-25+self.scrollBar.GetWidth(), 35) - self.editBar.SetPosition(10 + self.editBar.GetWidth(), height-60) - self.sendButton.SetPosition(width - 80 + self.sendButton.GetWidth(), 10) - self.minimizeButton.SetPosition(width-42 + self.minimizeButton.GetWidth(), 12) - self.closeButton.SetPosition(width-24+self.closeButton.GetWidth(), 12) - self.chatLine.SetPosition(5 + self.chatLine.GetWidth(), 5) - self.board.SetPosition(self.board.GetWidth(), 0) - else: - self.textRenderer.SetPosition(20, 28) - self.scrollBar.SetPosition(width-25, 35) - self.editBar.SetPosition(10, height-60) - self.sendButton.SetPosition(width-80, 10) - self.minimizeButton.SetPosition(width-42, 12) - self.closeButton.SetPosition(width-24, 12) - - self.SetChatLineMax(max) - - except: - import exception - exception.Abort("WhisperDialog.SetWhisperDialogSize.BindObject") - - def SetChatLineMax(self, max): - self.chatLine.SetMax(max) - - from grpText import GetSplitingTextLine - - text = self.chatLine.GetText() - if text: - self.chatLine.SetText(GetSplitingTextLine(text, max, 0)) - - def OpenWithTarget(self, targetName): - chat.CreateWhisper(targetName) - chat.SetWhisperBoxSize(targetName, self.GetWidth() - 60, self.GetHeight() - 90) - self.chatLine.SetFocus() - self.titleName.SetText(targetName) - self.targetName = targetName - self.textRenderer.SetTargetName(targetName) - self.titleNameEdit.Hide() - self.ignoreButton.Hide() - self.reportViolentWhisperButton.Hide() - self.acceptButton.Hide() - self.gamemasterMark.Hide() - self.minimizeButton.Show() - - def OpenWithoutTarget(self, event): - self.eventAcceptTarget = event - self.titleName.SetText("") - self.titleNameEdit.SetText("") - self.titleNameEdit.SetFocus() - self.targetName = 0 - self.titleNameEdit.Show() - self.ignoreButton.Hide() - self.reportViolentWhisperButton.Hide() - self.acceptButton.Show() - self.minimizeButton.Hide() - self.gamemasterMark.Hide() - - def SetGameMasterLook(self): - self.gamemasterMark.Show() - self.reportViolentWhisperButton.Hide() - - def Minimize(self): - self.titleNameEdit.KillFocus() - self.chatLine.KillFocus() - self.Hide() - - if None != self.eventMinimize: - self.eventMinimize(self.targetName) - - def Close(self): - chat.ClearWhisper(self.targetName) - self.titleNameEdit.KillFocus() - self.chatLine.KillFocus() - self.Hide() - - if None != self.eventClose: - self.eventClose(self.targetName) - - def ReportViolentWhisper(self): - net.SendChatPacket("/reportviolentwhisper " + self.targetName) - - def IgnoreTarget(self): - net.SendChatPacket("/ignore " + self.targetName) - - def AcceptTarget(self): - name = self.titleNameEdit.GetText() - if len(name) <= 0: - self.Close() - return - - if None != self.eventAcceptTarget: - self.titleNameEdit.KillFocus() - self.eventAcceptTarget(name) - - def OnScroll(self): - chat.SetWhisperPosition(self.targetName, self.scrollBar.GetPos()) - - def SendWhisper(self): - - text = self.chatLine.GetText() - textLength = len(text) - - if textLength > 0: - if net.IsInsultIn(text): - chat.AppendChat(chat.CHAT_TYPE_INFO, localeInfo.CHAT_INSULT_STRING) - return - - net.SendWhisperPacket(self.targetName, text) - self.chatLine.SetText("") - - chat.AppendWhisper(chat.WHISPER_TYPE_CHAT, self.targetName, player.GetName() + " : " + text) - - def OnTop(self): - self.chatLine.SetFocus() - - def BindInterface(self, interface): - self.interface = interface - - def OnMouseLeftButtonDown(self): - hyperlink = ui.GetHyperlink() - if hyperlink: - if app.IsPressed(app.DIK_LALT): - link = chat.GetLinkFromHyperlink(hyperlink) - ime.PasteString(link) - else: - self.interface.MakeHyperlinkTooltip(hyperlink) - -if "__main__" == __name__: - import uiTest - - class TestApp(uiTest.App): - def OnInit(self): - wnd = WhisperDialog(self.OnMax, self.OnMin) - wnd.LoadDialog() - wnd.OpenWithoutTarget(self.OnNew) - wnd.SetPosition(0, 0) - wnd.Show() - - self.wnd = wnd - - def OnMax(self): - pass - - def OnMin(self): - pass - - def OnNew(self): - pass - - TestApp().MainLoop() diff --git a/tools/root/utils.py b/tools/root/utils.py deleted file mode 100644 index 51d0d734..00000000 --- a/tools/root/utils.py +++ /dev/null @@ -1,66 +0,0 @@ -class Sandbox(object): - # DO NOT REMOVE ANY ENTRY OF WHITE LIST - # THIS ENTIES ARE USED FOR Sandbox. - # (If sys.modules['__main__'] is changed, you can see the hell.) - WHITE_LIST = ['__builtin__', 'types', __name__, '__main__', 'sys'] - def __init__(self, prevent_imported_modules = False, allowed_modules = [], prevented_modules = [], allowed_paths = []): - self.prevent_imported_modules = prevent_imported_modules - self.allowed_modules = allowed_modules - self.prevented_modules = prevented_modules - self.allowed_paths = allowed_paths - - def add_allowed_modules(self, allowed_modules): - self.allowed_modules = self.allowed_modules + allowed_modules - - def add_prevented_modules(self, prevented_modules): - self.prevented_modules = self.prevented_modules + prevented_modules - - def execfile(self, filename, dic): - import sys - import copy - - for allowed_module_name in self.allowed_modules: - try: - exec('import {0}'.format(allowed_module_name)) - except: - # Just now, pass the exception. - # (filename could not use this module) - sys.stderr.write("Could not import %s" % allowed_module_name) - pass - # shallow copy of sys.modules - old_modules = copy.copy(sys.modules) - - old_path = sys.path - sys.path = self.allowed_paths - - # set current imported modules None - if self.prevent_imported_modules: - import types - for k, v in list(old_modules.items()): - if type(v) == types.ModuleType: - if not (k in self.WHITE_LIST or k in self.allowed_modules): - sys.modules[k] = None - - # set prevented modules None. - for prevented_module_name in self.prevented_modules: - sys.modules[prevented_module_name] = None - - try: - with open(filename, 'rb') as f: - data = f.read() - code = compile(data, filename, 'exec') - exec(code, dic) - except Exception as e: - sys.stderr.write(e) - finally: - # Restore original settings. - #sys.modules = old_modules# <- This is not effective. I don't know why, but I guess some where got old sys.modules reference and access old one. - for k, v in list(sys.modules.items()): - if not k in old_modules: - del sys.modules[k] - for k, v in list(old_modules.items()): - sys.modules[k] = v - - sys.path = old_path - -