Facebook
From oguzhan, 4 Years ago, written in Plain Text.
Embed
Download Paste or View Raw
Hits: 136
  1. #include "StdAfx.h"
  2. #include "PythonSkill.h"
  3.  
  4. #include "../EterBase/Poly/Poly.h"
  5. #include "../EterPack/EterPackManager.h"
  6. #include "InstanceBase.h"
  7. #include "PythonPlayer.h"
  8.  
  9. #ifdef PYTHON_DYNAMIC_MODULE_NAME
  10. #include "PythonDynamicModuleNames.h"
  11. #endif
  12.  
  13. std::map<std::string, DWORD> CPythonSkill::SSkillData::ms_StatusNameMap;
  14. std::map<std::string, DWORD> CPythonSkill::SSkillData::ms_NewMinStatusNameMap;
  15. std::map<std::string, DWORD> CPythonSkill::SSkillData::ms_NewMaxStatusNameMap;
  16. DWORD CPythonSkill::SSkillData::ms_dwTimeIncreaseSkillNumber = 0;
  17.  
  18. BOOL SKILL_EFFECT_UPGRADE_ENABLE = FALSE;
  19.  
  20. int SplitLine(const char * c_szText, CTokenVector* pstTokenVector, const char * c_szDelimeter)
  21. {
  22.         pstTokenVector->reserve(10);
  23.         pstTokenVector->clear();
  24.  
  25.         std::string stToken;
  26.         std::string stLine = c_szText;
  27.  
  28.         DWORD basePos = 0;
  29.  
  30.         do
  31.         {
  32.                 int beginPos = stLine.find_first_not_of(c_szDelimeter, basePos);
  33.  
  34.                 if (beginPos < 0)
  35.                         return -1;
  36.  
  37.                 int endPos;
  38.  
  39.                 if (stLine[beginPos] == '"')
  40.                 {
  41.                         ++beginPos;
  42.                         endPos = stLine.find_first_of("\"", beginPos);
  43.  
  44.                         if (endPos < 0)
  45.                                 return -2;
  46.  
  47.                         basePos = endPos + 1;
  48.                 }
  49.                 else
  50.                 {
  51.                         endPos = stLine.find_first_of(c_szDelimeter, beginPos);
  52.                         basePos = endPos;
  53.                 }
  54.  
  55.                 pstTokenVector->push_back(stLine.substr(beginPos, endPos - beginPos));
  56.  
  57.                 // 추가 코드. 맨뒤에 탭이 있는 경우를 체크한다. - [levites]
  58.                 if (int(stLine.find_first_not_of(c_szDelimeter, basePos)) < 0)
  59.                         break;
  60.         } while (basePos < stLine.length());
  61.  
  62.         return 0;
  63. }
  64.  
  65. // OVERWRITE_SKILLPROTO_POLY
  66. void string_replace_word(const char* base, int base_len, const char* src, int src_len, const char* dst, int dst_len, std::string& result)
  67. {
  68.         result.resize(0);
  69.         if (base_len > 0 && dst_len > src_len)
  70.                 result.reserve(base_len + (dst_len-src_len) * (base_len/src_len));
  71.         else
  72.                 result.reserve(base_len);
  73.  
  74.         int prev = 0;
  75.         int cur = 0;
  76.         while (cur < base_len)
  77.         {
  78.                 if (memcmp(base + cur, src, src_len) == 0)
  79.                 {
  80.                         result.append(base + prev, cur - prev);
  81.                         result.append(dst, dst_len);                   
  82.                         cur += src_len;
  83.                         prev = cur;
  84.                 }              
  85.                 else
  86.                 {
  87.                         ++cur;
  88.                 }              
  89.         }
  90.         result.append(base + prev, cur - prev);
  91. }
  92. // END_OF_OVERWRITE_SKILLPROTO_POLY
  93.  
  94. bool CPythonSkill::RegisterSkillTable(const char * c_szFileName)
  95. {
  96.         const VOID* pvData;
  97.         CMappedFile kFile;
  98.         if (!CEterPackManager::Instance().Get(kFile, c_szFileName, &pvData))
  99.                 return false;
  100.  
  101.         CMemoryTextFileLoader textFileLoader;
  102.         textFileLoader.Bind(kFile.Size(), pvData);
  103.  
  104.         // OVERWRITE_SKILLPROTO_POLY
  105.         string src_poly_rand;
  106.         string src_poly_atk;
  107.         string src_poly_mwep;
  108.         // END_OF_OVERWRITE_SKILLPROTO_POLY
  109.  
  110.         CTokenVector TokenVector;
  111.         for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i)
  112.         {
  113.                 if (!textFileLoader.SplitLineByTab(i, &TokenVector))
  114.                         continue;
  115.  
  116.                 std::string strLine = textFileLoader.GetLineString(i);
  117.  
  118.                 if (TABLE_TOKEN_TYPE_MAX_NUM != TokenVector.size())
  119.                 {
  120.                         Tracef("CPythonSkill::RegisterSkillTable(%s) - Strange Token Count [Line:%d / TokenCount:%d]\n", c_szFileName, i, TokenVector.size());
  121.                         continue;
  122.                 }
  123.  
  124.                 int iVnum = atoi(TokenVector[TABLE_TOKEN_TYPE_VNUM].c_str());
  125.  
  126.                 TSkillDataMap::iterator itor = m_SkillDataMap.find(iVnum);
  127.                 if (m_SkillDataMap.end() == itor)
  128.                 {
  129.                         Tracef("CPythonSkill::RegisterSkillTable(%s) - NOT EXIST SkillDesc [Vnum:%d Line:%d]\n", c_szFileName, iVnum, i);
  130.                         continue;
  131.                 }
  132.  
  133.                 TSkillData & rSkillData = itor->second;
  134.  
  135.                 const std::string & c_strSPCostPoly = TokenVector[TABLE_TOKEN_TYPE_SP_COST_POLY];
  136.                 if (!c_strSPCostPoly.empty())
  137.                 {
  138.                         rSkillData.strNeedSPFormula = c_strSPCostPoly;
  139.                 }
  140.  
  141.                 const std::string & c_strCooldownPoly = TokenVector[TABLE_TOKEN_TYPE_COOLDOWN_POLY];
  142.                 if (!c_strCooldownPoly.empty())
  143.                 {
  144.                         rSkillData.strCoolTimeFormula = c_strCooldownPoly;
  145.                 }
  146.  
  147.                 const std::string & c_strDurationSPCostPoly = TokenVector[TABLE_TOKEN_TYPE_DURATION_SP_COST_POLY];
  148.                 if (!c_strDurationSPCostPoly.empty())
  149.                 {
  150.                         rSkillData.strContinuationSPFormula = c_strDurationSPCostPoly;
  151.                 }
  152.  
  153.                 const std::string & c_strTargetRange = TokenVector[TABLE_TOKEN_TYPE_TARGET_RANGE];
  154.                 if (!c_strTargetRange.empty())
  155.                 {
  156.                         rSkillData.dwTargetRange = atoi(c_strTargetRange.c_str());
  157.                 }
  158.  
  159.                 rSkillData.strDuration = TokenVector[TABLE_TOKEN_TYPE_DURATION_POLY];
  160.  
  161.                
  162.                 const DWORD LevelEmpty = 1;
  163.  
  164.                 const std::string & c_strMaxLevel = TokenVector[TABLE_TOKEN_TYPE_MAX_LEVEL];
  165.                 if (!c_strMaxLevel.empty())
  166.                 {
  167.                         int maxLevel = atoi(c_strMaxLevel.c_str());
  168.                         if(maxLevel > LevelEmpty)
  169.                                 rSkillData.byMaxLevel = maxLevel;
  170.                 }
  171.  
  172.                 const std::string & c_strLevelLimit = TokenVector[TABLE_TOKEN_TYPE_LEVEL_LIMIT];               
  173.                 if (!c_strLevelLimit.empty())
  174.                 {
  175.                         int levelLimit = atoi(c_strLevelLimit.c_str());
  176.                         if(rSkillData.byLevelLimit > LevelEmpty)
  177.                                 rSkillData.byLevelLimit = levelLimit;
  178.                 }
  179.                 const std::string & c_strPointPoly = TokenVector[TABLE_TOKEN_TYPE_POINT_POLY];
  180.  
  181.                 // OVERWRITE_SKILLPROTO_POLY
  182.                 bool USE_SKILL_PROTO = true;
  183.  
  184.                 switch (iVnum)
  185.                 {
  186.                         case 34:
  187.  
  188.                         // GUILD_SKILL_DISPLAY_BUG_FIX
  189.                         case 151:
  190.                         case 152:
  191.                         case 153:
  192.                         case 154:
  193.                         case 155:
  194.                         case 156:
  195.                         case 157:
  196.                         // END_OF_GUILD_SKILL_DISPLAY_BUG_FIX
  197.                                 USE_SKILL_PROTO = false;
  198.                                 break;
  199.                 }
  200.                
  201.                 if (!rSkillData.AffectDataVector.empty() && USE_SKILL_PROTO)
  202.                 {      
  203.                         TAffectData& affect = rSkillData.AffectDataVector[0];
  204.  
  205.                         if (strstr(c_strPointPoly.c_str(), "atk")               != NULL ||
  206.                                 strstr(c_strPointPoly.c_str(), "mwep")          != NULL ||
  207.                                 strstr(c_strPointPoly.c_str(), "number")        != NULL)
  208.                         {
  209.                                 src_poly_rand = "";
  210.                                 src_poly_atk = "";
  211.                                 src_poly_mwep = "";
  212.  
  213.                                 // MIN
  214.                                 string_replace_word(c_strPointPoly.c_str(), c_strPointPoly.length(),
  215.                                         "number", 6, "min", 3, src_poly_rand);                         
  216.                                 string_replace_word(src_poly_rand.c_str(), src_poly_rand.length(),
  217.                                         "atk", 3, "minatk", 6, src_poly_atk);
  218.                                 string_replace_word(src_poly_atk.c_str(), src_poly_atk.length(),
  219.                                         "mwep", 4, "minmwep", 7, affect.strAffectMinFormula);
  220.                                 // END_OF_MIN
  221.  
  222.                                 // MAX
  223.                                 string_replace_word(c_strPointPoly.c_str(), c_strPointPoly.length(),
  224.                                         "number", 6, "max", 3, src_poly_rand);                         
  225.                                 string_replace_word(src_poly_rand.c_str(), src_poly_rand.length(),
  226.                                         "atk", 3, "maxatk", 6, src_poly_atk);
  227.                                 string_replace_word(src_poly_atk.c_str(), src_poly_atk.length(),
  228.                                         "mwep", 4, "maxmwep", 7, affect.strAffectMaxFormula);
  229.                                 // END_OF_MAX
  230.                                                                
  231.                                 switch (iVnum)
  232.                                 {
  233.                                         case 1: // 삼연참
  234.                                                 affect.strAffectMinFormula += "* 3";
  235.                                                 affect.strAffectMaxFormula += "* 3";
  236.                                                 break;                                 
  237.                                 }
  238.                                
  239.                         }
  240.                         else
  241.                         {
  242.                                 affect.strAffectMinFormula = c_strPointPoly;
  243.                                 affect.strAffectMaxFormula = "";
  244.                         }                                      
  245.                 }              
  246.                 // END_OF_OVERWRITE_SKILLPROTO_POLY
  247.         }
  248.  
  249.         return true;
  250. }
  251.  
  252. void CPythonSkill::__RegisterGradeIconImage(TSkillData & rData, const char * c_szHeader, const char * c_szImageName)
  253. {
  254.         for (int j = 0; j < SKILL_GRADE_COUNT; ++j)
  255.         {
  256.                 TGradeData & rGradeData = rData.GradeData[j];
  257.  
  258.                 char szCount[8+1];
  259.                 _snprintf(szCount, sizeof(szCount), "_%02d", j+1);
  260.  
  261.                 std::string strFileName = "";
  262.                 strFileName += c_szHeader;
  263.                 strFileName += c_szImageName;
  264.                 strFileName += szCount;
  265.                 strFileName += ".sub";
  266.                 rGradeData.pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(strFileName.c_str());
  267.         }
  268. }
  269.  
  270. void CPythonSkill::__RegisterNormalIconImage(TSkillData & rData, const char * c_szHeader, const char * c_szImageName)
  271. {
  272.         std::string strFileName = "";
  273.         strFileName += c_szHeader;
  274.         strFileName += c_szImageName;
  275.         strFileName += ".sub";
  276.         rData.pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(strFileName.c_str());
  277.         for (int j = 0; j < SKILL_GRADE_COUNT; ++j)
  278.         {
  279.                 TGradeData & rGradeData = rData.GradeData[j];
  280.                 rGradeData.pImage = rData.pImage;
  281.         }
  282. }
  283. extern const DWORD c_iSkillIndex_Riding;
  284. bool CPythonSkill::RegisterSkillDesc(const char * c_szFileName)
  285. {
  286.         const VOID* pvData;
  287.         CMappedFile kFile;
  288.         if (!CEterPackManager::Instance().Get(kFile, c_szFileName, &pvData))
  289.                 return false;
  290.  
  291.         CMemoryTextFileLoader textFileLoader;
  292.         textFileLoader.Bind(kFile.Size(), pvData);
  293.  
  294.         CTokenVector TokenVector;
  295.         for (DWORD i = 0; i < textFileLoader.GetLineCount(); ++i)
  296.         {
  297.                 if (!textFileLoader.SplitLineByTab(i, &TokenVector))
  298.                         continue;
  299.  
  300.                 if (DESC_TOKEN_TYPE_VNUM >= TokenVector.size())
  301.                 {
  302.                         TraceError("SkillDesc.line(%d).NO_VNUM_ERROR\n", i + 1);
  303.                         continue;
  304.                 }
  305.                
  306.                 DWORD iSkillIndex = atoi(TokenVector[DESC_TOKEN_TYPE_VNUM].c_str());
  307.                 if (iSkillIndex == 0)
  308.                 {
  309.                         TraceError("SkillDesc.line(%d).NO_INDEX_ERROR\n", i + 1);
  310.                         continue;
  311.                 }
  312.  
  313.                 if (DESC_TOKEN_TYPE_JOB >= TokenVector.size())
  314.                 {
  315.                         TraceError("SkillDesc.line(%d).NO_JOB_ERROR\n", i + 1);
  316.                         continue;
  317.                 }
  318.  
  319.                 m_SkillDataMap.insert(make_pair(iSkillIndex, TSkillData()));
  320.                 TSkillData & rSkillData = m_SkillDataMap[iSkillIndex];
  321.  
  322.                 // Vnum
  323.                 rSkillData.dwSkillIndex = iSkillIndex;
  324.  
  325.                 // Type
  326.                 {
  327.                         std::string strJob = TokenVector[DESC_TOKEN_TYPE_JOB];
  328.                         stl_lowers(strJob);
  329.  
  330.                         std::map<std::string, DWORD>::iterator it = m_SkillTypeIndexMap.find(strJob.c_str());
  331.                         if (m_SkillTypeIndexMap.end() == it)
  332.                         {
  333.                                 TraceError("CPythonSkill::RegisterSkillDesc(dwSkillIndex=%d, strType=%s).STRANGE_SKILL_TYPE", iSkillIndex, strJob.c_str());
  334.                                 continue;
  335.                         }
  336.  
  337.                         rSkillData.byType = BYTE(it->second);
  338.                 }
  339.  
  340.                 // Name
  341.                 {
  342.                         rSkillData.strName = TokenVector[DESC_TOKEN_TYPE_NAME1];
  343.                         rSkillData.GradeData[0].strName = TokenVector[DESC_TOKEN_TYPE_NAME1];
  344.                         rSkillData.GradeData[1].strName = TokenVector[DESC_TOKEN_TYPE_NAME2];
  345.                         rSkillData.GradeData[2].strName = TokenVector[DESC_TOKEN_TYPE_NAME3];
  346.  
  347.                         if (rSkillData.GradeData[1].strName.empty())
  348.                                 rSkillData.GradeData[1].strName = TokenVector[DESC_TOKEN_TYPE_NAME1];
  349.                         if (rSkillData.GradeData[2].strName.empty())
  350.                                 rSkillData.GradeData[2].strName = TokenVector[DESC_TOKEN_TYPE_NAME1];
  351.                 }
  352.  
  353.                 // Description
  354.                 {
  355.                         rSkillData.strDescription = TokenVector[DESC_TOKEN_TYPE_DESCRIPTION];
  356.                 }
  357.  
  358.                 // Condition
  359.                 {
  360.                         rSkillData.ConditionDataVector.clear();
  361.                         for (int j = 0; j < CONDITION_COLUMN_COUNT; ++j)
  362.                         {
  363.                                 const std::string & c_rstrCondition = TokenVector[DESC_TOKEN_TYPE_CONDITION1+j];
  364.                                 if (!c_rstrCondition.empty())
  365.                                         rSkillData.ConditionDataVector.push_back(c_rstrCondition);
  366.                         }
  367.                 }
  368.  
  369.                 // Attribute
  370.                 {
  371.                         const std::string & c_rstrAttribute = TokenVector[DESC_TOKEN_TYPE_ATTRIBUTE];
  372.                         CTokenVector AttributeTokenVector;
  373.                         SplitLine(c_rstrAttribute.c_str(), &AttributeTokenVector, "|");
  374.  
  375.                         for (CTokenVector::iterator it = AttributeTokenVector.begin(); it != AttributeTokenVector.end(); ++it)
  376.                         {
  377.                                 std::string & rstrToken = *it;
  378.                                 std::map<std::string, DWORD>::iterator it2 = m_SkillAttributeIndexMap.find(rstrToken);
  379.                                 if (m_SkillAttributeIndexMap.end() == it2)
  380.                                 {
  381.                                         TraceError("CPythonSkill::RegisterSkillDesc(dwSkillIndex=%d) - Strange Skill Attribute(%s)", iSkillIndex, rstrToken.c_str());
  382.                                         continue;
  383.                                 }
  384.                                 rSkillData.dwSkillAttribute |= it2->second;
  385.                         }
  386.                 }
  387.  
  388.                 // Weapon
  389.                 {
  390.                         const std::string & c_rstrWeapon = TokenVector[DESC_TOKEN_TYPE_WEAPON];
  391.                         CTokenVector WeaponTokenVector;
  392.                         SplitLine(c_rstrWeapon.c_str(), &WeaponTokenVector, "|");
  393.  
  394.                         for (CTokenVector::iterator it = WeaponTokenVector.begin(); it != WeaponTokenVector.end(); ++it)
  395.                         {
  396.                                 std::string & rstrToken = *it;
  397.                                 std::map<std::string, DWORD>::iterator it2 = m_SkillNeedWeaponIndexMap.find(rstrToken);
  398.                                 if (m_SkillNeedWeaponIndexMap.end() == it2)
  399.                                 {
  400.                                         TraceError("CPythonSkill::RegisterSkillDesc(dwSkillIndex=%d) - Strange Skill Need Weapon(%s)", iSkillIndex, rstrToken.c_str());
  401.                                         continue;
  402.                                 }
  403.                                 rSkillData.dwNeedWeapon |= it2->second;
  404.                         }
  405.                 }
  406.  
  407.                 // Icon Name
  408.                 {
  409.                         const std::string & c_rstrJob = TokenVector[DESC_TOKEN_TYPE_JOB];
  410.                         const std::string & c_rstrIconName = TokenVector[DESC_TOKEN_TYPE_ICON_NAME];
  411.  
  412.                         // NOTE : Support 스킬임에도 3단계를 지원해야 해서 예외 처리 - [levites]
  413.                         if (c_iSkillIndex_Riding == iSkillIndex)
  414.                         {
  415.                                 char szIconFileNameHeader[64+1];
  416.                                 _snprintf(szIconFileNameHeader, sizeof(szIconFileNameHeader), "%sskill/common/support/", g_strImagePath.c_str());
  417.  
  418.                                 __RegisterGradeIconImage(rSkillData, szIconFileNameHeader, c_rstrIconName.c_str());
  419.                         }
  420.                         else if (m_PathNameMap.end() != m_PathNameMap.find(c_rstrJob))
  421.                         {
  422.                                 char szIconFileNameHeader[64+1];
  423.                                 _snprintf(szIconFileNameHeader, sizeof(szIconFileNameHeader), "%sskill/%s/", g_strImagePath.c_str(), m_PathNameMap[c_rstrJob].c_str());
  424.  
  425.                                 switch (rSkillData.byType)
  426.                                 {
  427.                                         case SKILL_TYPE_ACTIVE:
  428.                                         {
  429.                                                 __RegisterGradeIconImage(rSkillData, szIconFileNameHeader, c_rstrIconName.c_str());
  430.                                                 break;
  431.                                         }
  432.                                         case SKILL_TYPE_SUPPORT:
  433.                                         case SKILL_TYPE_GUILD:
  434.                                         case SKILL_TYPE_HORSE:
  435.                                         {
  436.                                                 __RegisterNormalIconImage(rSkillData, szIconFileNameHeader, c_rstrIconName.c_str());
  437.                                                 break;
  438.                                         }
  439.                                 }
  440.                         }
  441.                 }
  442.  
  443.                 // Motion Index
  444.                 if (TokenVector.size() > DESC_TOKEN_TYPE_MOTION_INDEX)
  445.                 {
  446.                         const std::string & c_rstrMotionIndex = TokenVector[DESC_TOKEN_TYPE_MOTION_INDEX];
  447.                         if (c_rstrMotionIndex.empty())
  448.                         {
  449.                                 rSkillData.bNoMotion = TRUE;
  450.                                 rSkillData.wMotionIndex = 0;
  451.                         }
  452.                         else
  453.                         {
  454.                                 rSkillData.bNoMotion = FALSE;
  455.                                 rSkillData.wMotionIndex = (WORD)atoi(c_rstrMotionIndex.c_str());
  456.                         }
  457.                 }
  458.                 else
  459.                 {
  460.                         rSkillData.wMotionIndex = 0;
  461.                 }
  462.  
  463.                 if (TokenVector.size() > DESC_TOKEN_TYPE_TARGET_COUNT_FORMULA)
  464.                         rSkillData.strTargetCountFormula = TokenVector[DESC_TOKEN_TYPE_TARGET_COUNT_FORMULA].c_str();
  465.                 if (TokenVector.size() > DESC_TOKEN_TYPE_MOTION_LOOP_COUNT_FORMULA)
  466.                         rSkillData.strMotionLoopCountFormula = TokenVector[DESC_TOKEN_TYPE_MOTION_LOOP_COUNT_FORMULA].c_str();
  467.  
  468.                 rSkillData.AffectDataNewVector.clear();
  469.                 rSkillData.AffectDataNewVector.reserve(3);
  470.  
  471.                 // Affect
  472.                 for (int j = 0; j < AFFECT_COLUMN_COUNT; ++j)
  473.                 {
  474.                         int iDescriptionSlotIndex = DESC_TOKEN_TYPE_AFFECT_DESCRIPTION_1 + j*AFFECT_STEP_COUNT;
  475.                         int iMinSlotIndex = DESC_TOKEN_TYPE_AFFECT_MIN_1 + j*AFFECT_STEP_COUNT;
  476.                         int iMaxSlotIndex = DESC_TOKEN_TYPE_AFFECT_MAX_1 + j*AFFECT_STEP_COUNT;
  477.  
  478.                         if (TokenVector.size() > iDescriptionSlotIndex)
  479.                         if (!TokenVector[iDescriptionSlotIndex].empty())
  480.                         {
  481.                                 rSkillData.AffectDataVector.push_back(TAffectData());
  482.  
  483.                                 TAffectData & rAffectData = *rSkillData.AffectDataVector.rbegin();
  484.                                 rAffectData.strAffectDescription = "";
  485.                                 rAffectData.strAffectMinFormula = "";
  486.                                 rAffectData.strAffectMaxFormula = "";
  487.  
  488.                                 rAffectData.strAffectDescription = TokenVector[iDescriptionSlotIndex];
  489.                                 if (TokenVector.size() > iMinSlotIndex)
  490.                                 if (!TokenVector[iMinSlotIndex].empty())
  491.                                         rAffectData.strAffectMinFormula = TokenVector[iMinSlotIndex];
  492.                                 if (TokenVector.size() > iMaxSlotIndex)
  493.                                 if (!TokenVector[iMaxSlotIndex].empty())
  494.                                         rAffectData.strAffectMaxFormula = TokenVector[iMaxSlotIndex];
  495.                         }
  496.                 }
  497.  
  498.                 if (TokenVector.size() > DESC_TOKEN_TYPE_MOTION_INDEX_GRADE_NUM)
  499.                 {
  500.                         int numGrade = atoi(TokenVector[DESC_TOKEN_TYPE_MOTION_INDEX_GRADE_NUM].c_str());
  501.                         if (SKILL_EFFECT_COUNT < numGrade)
  502.                         {
  503.                                 TraceError("%s[%s] 가 등급 제한[%d]을 넘어갔습니다.",rSkillData.strName.c_str(), TokenVector[DESC_TOKEN_TYPE_MOTION_INDEX_GRADE_NUM].c_str(), SKILL_EFFECT_COUNT);
  504.                                 return false;
  505.                         }
  506.                         for (int iGrade = 0; iGrade < numGrade; iGrade++)
  507.                         {
  508.                                 //if (iGrade == SKILL_GRADE_COUNT)
  509.                                 //      rSkillData.GradeData[iGrade] = rSkillData.GradeData[iGrade-1];
  510.                                 rSkillData.GradeData[iGrade].wMotionIndex = rSkillData.wMotionIndex+iGrade*SKILL_GRADEGAP;
  511.                         }
  512.                         for(int iSpace = numGrade; iSpace < SKILL_EFFECT_COUNT; iSpace++)
  513.                         {
  514.                                 rSkillData.GradeData[iSpace].wMotionIndex = rSkillData.wMotionIndex;
  515.                         }
  516.                 }
  517.  
  518.                 if (TokenVector.size() > DESC_TOKEN_TYPE_LEVEL_LIMIT)
  519.                 {
  520.                         const std::string & c_rstrLevelLimit = TokenVector[DESC_TOKEN_TYPE_LEVEL_LIMIT];
  521.                         if (c_rstrLevelLimit.empty())
  522.                                 rSkillData.byLevelLimit = 0;
  523.                         else
  524.                                 rSkillData.byLevelLimit = (WORD)atoi(c_rstrLevelLimit.c_str());
  525.                 }
  526.  
  527.                 if (TokenVector.size() > DESC_TOKEN_TYPE_MAX_LEVEL)
  528.                 {
  529.                         const std::string & c_rstrMaxLevel = TokenVector[DESC_TOKEN_TYPE_MAX_LEVEL];
  530.                         const DWORD LevelLimitEmpty = 1;
  531.                         if (c_rstrMaxLevel.empty())
  532.                         {
  533.                                 if(rSkillData.byLevelLimit > LevelLimitEmpty)
  534.                                         rSkillData.byMaxLevel = rSkillData.byLevelLimit;
  535.                                 else
  536.                                         rSkillData.byMaxLevel = 20;
  537.                         }
  538.                         else
  539.                                 rSkillData.byMaxLevel = (BYTE)atoi(c_rstrMaxLevel.c_str());
  540.                 }
  541.         }
  542.  
  543.         return true;
  544. }
  545.  
  546. void CPythonSkill::Destroy()
  547. {
  548.         m_SkillDataMap.clear();
  549. }
  550.  
  551. bool CPythonSkill::RegisterSkill(DWORD dwSkillIndex, const char * c_szFileName)
  552. {
  553.         CTextFileLoader TextFileLoader;
  554.         if (!TextFileLoader.Load(c_szFileName))
  555.         {
  556.                 TraceError("CPythonSkill::RegisterSkill(dwSkillIndex=%d, c_szFileName=%s) - Failed to find file", dwSkillIndex, c_szFileName);
  557.                 return false;
  558.         }
  559.  
  560.         TextFileLoader.SetTop();
  561.  
  562.         TSkillData SkillData;
  563.         SkillData.dwSkillIndex = dwSkillIndex;
  564.  
  565.         std::string strTypeName;
  566.         if (TextFileLoader.GetTokenString("type", &strTypeName))
  567.         {
  568.                 stl_lowers(strTypeName);
  569.                 std::map<std::string, DWORD>::iterator it = m_SkillTypeIndexMap.find(strTypeName.c_str());
  570.                 if (m_SkillTypeIndexMap.end() == it)
  571.                 {
  572.                         TraceError("Strange Skill Type - CPythonSkill::RegisterSkill(dwSkillIndex=%d, c_szFileName=%s)", dwSkillIndex, c_szFileName);
  573.                         return false;
  574.                 }
  575.  
  576.                 SkillData.byType = (BYTE)it->second;
  577.         }
  578.         else
  579.         {
  580.                 TraceError("CPythonSkill::RegisterSkill(dwSkillIndex=%d, c_szFileName=%s) - Failed to find key [type]", dwSkillIndex, c_szFileName);
  581.                 return false;
  582.         }
  583.  
  584.         CTokenVector * pAttributeTokenVector;
  585.         if (TextFileLoader.GetTokenVector("attribute", &pAttributeTokenVector))
  586.         {
  587.                 for (CTokenVector::iterator it = pAttributeTokenVector->begin(); it != pAttributeTokenVector->end(); ++it)
  588.                 {
  589.                         std::string & rstrToken = *it;
  590.                         std::map<std::string, DWORD>::iterator it2 = m_SkillAttributeIndexMap.find(rstrToken.c_str());
  591.                         if (m_SkillAttributeIndexMap.end() == it2)
  592.                         {
  593.                                 TraceError("Strange Skill Attribute - CPythonSkill::RegisterSkill(dwSkillIndex=%d, c_szFileName=%s)", dwSkillIndex, c_szFileName);
  594.                                 continue;
  595.                         }
  596.                         SkillData.dwSkillAttribute |= it2->second;
  597.                 }
  598.         }
  599.  
  600.         CTokenVector * pNeedWeaponVector;
  601.         if (TextFileLoader.GetTokenVector("needweapon", &pNeedWeaponVector))
  602.         {
  603.                 for (CTokenVector::iterator it = pNeedWeaponVector->begin(); it != pNeedWeaponVector->end(); ++it)
  604.                 {
  605.                         std::string & rstrToken = *it;
  606.                         std::map<std::string, DWORD>::iterator it2 = m_SkillNeedWeaponIndexMap.find(rstrToken.c_str());
  607.                         if (m_SkillNeedWeaponIndexMap.end() == it2)
  608.                         {
  609.                                 TraceError("Strange Skill Need Weapon - CPythonSkill::RegisterSkill(dwSkillIndex=%d, c_szFileName=%s)", dwSkillIndex, c_szFileName);
  610.                                 continue;
  611.                         }
  612.                         SkillData.dwNeedWeapon |= it2->second;
  613.                 }
  614.         }
  615.  
  616.         {
  617.                 char szName[256];
  618.                 sprintf(szName, "%dname", LocaleService_GetCodePage());
  619.                 if (!TextFileLoader.GetTokenString(szName, &SkillData.strName))
  620.                         if (!TextFileLoader.GetTokenString("name", &SkillData.strName))
  621.                         {
  622.                                 TraceError("CPythonSkill::RegisterSkill(dwSkillIndex=%d, c_szFileName=%s) - Failed to find [%s]", dwSkillIndex, c_szFileName, szName);
  623.                                 return false;  
  624.                         }
  625.         }
  626.  
  627.         {
  628.                 char szName[256];
  629.                 sprintf(szName, "%ddescription", LocaleService_GetCodePage());
  630.                 if (!TextFileLoader.GetTokenString(szName, &SkillData.strDescription))
  631.                         TextFileLoader.GetTokenString("description", &SkillData.strDescription);
  632.         }
  633.  
  634.         if (!TextFileLoader.GetTokenString("iconfilename", &SkillData.strIconFileName))
  635.         {
  636.                 TraceError("CPythonSkill::RegisterSkill(dwSkillIndex=%d, c_szFileName=%s) - Failed to find [iconfilename]", dwSkillIndex, c_szFileName);
  637.                 return false;
  638.         }
  639.  
  640.         {
  641.                 CTokenVector * pConditionDataVector;
  642.  
  643.                 char szConditionData[256];
  644.                 sprintf(szConditionData, "%dconditiondata", LocaleService_GetCodePage());
  645.  
  646.                 bool isConditionData=true;
  647.                 if (!TextFileLoader.GetTokenVector(szConditionData, &pConditionDataVector))
  648.                         if (!TextFileLoader.GetTokenVector("conditiondata", &pConditionDataVector))
  649.                                 isConditionData=false;
  650.  
  651.                 if (isConditionData)
  652.                 {
  653.                         DWORD dwSize = pConditionDataVector->size();
  654.                         SkillData.ConditionDataVector.clear();
  655.                         SkillData.ConditionDataVector.resize(dwSize);
  656.                         for (DWORD i = 0; i < dwSize; ++i)
  657.                         {
  658.                                 SkillData.ConditionDataVector[i] = pConditionDataVector->at(i);
  659.                         }
  660.                 }
  661.         }
  662.  
  663.         {
  664.                 CTokenVector * pAffectDataVector;
  665.  
  666.                 char szAffectData[256];
  667.                 sprintf(szAffectData, "%daffectdata", LocaleService_GetCodePage());
  668.  
  669.                 bool isAffectData=true;
  670.                 if (!TextFileLoader.GetTokenVector(szAffectData, &pAffectDataVector))
  671.                         if (!TextFileLoader.GetTokenVector("affectdata", &pAffectDataVector))
  672.                                 isAffectData=false;
  673.  
  674.                 if (isAffectData)
  675.                 {
  676.                         DWORD dwSize = pAffectDataVector->size()/3;
  677.                         SkillData.AffectDataVector.clear();
  678.                         SkillData.AffectDataVector.resize(dwSize);
  679.                         for (DWORD i = 0; i < dwSize; ++i)
  680.                         {
  681.                                 SkillData.AffectDataVector[i].strAffectDescription = pAffectDataVector->at(i*3+0);
  682.                                 SkillData.AffectDataVector[i].strAffectMinFormula = pAffectDataVector->at(i*3+1);
  683.                                 SkillData.AffectDataVector[i].strAffectMaxFormula = pAffectDataVector->at(i*3+2);
  684.                         }
  685.                 }
  686.         }
  687.  
  688.         {
  689.                 CTokenVector * pGradeDataVector;
  690.  
  691.                 char szGradeData[256];
  692.                 sprintf(szGradeData, "%dgradedata", LocaleService_GetCodePage());
  693.  
  694.                 if (TextFileLoader.GetTokenVector(szGradeData, &pGradeDataVector))
  695.                 {
  696.                         if (SKILL_GRADE_COUNT*2 != pGradeDataVector->size())
  697.                                 TraceError("CPythonSkill::RegisterSkill(dwSkillIndex=%d, c_szFileName=%s) - Strange Grade Data Count", dwSkillIndex, c_szFileName);
  698.  
  699.                         //for (DWORD i = 0; i < min(SKILL_GRADE_COUNT, pGradeDataVector->size() / 2); ++i)
  700.                         for (DWORD i = 0; i < std::min<DWORD>(SKILL_GRADE_COUNT, pGradeDataVector->size() / 2); ++i)
  701.                         {
  702.                                 SkillData.GradeData[i].strName = pGradeDataVector->at(i*2+0);
  703.                                 std::string strIconFileName = g_strImagePath + pGradeDataVector->at(i*2+1);
  704.                                 SkillData.GradeData[i].pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(strIconFileName.c_str());
  705.                         }
  706.                 }
  707.         }
  708.  
  709.         TextFileLoader.GetTokenString("cooltimeformula", &SkillData.strCoolTimeFormula);
  710.         TextFileLoader.GetTokenString("targetcountformula", &SkillData.strTargetCountFormula);
  711.         TextFileLoader.GetTokenString("motionloopcountformula", &SkillData.strMotionLoopCountFormula);
  712.         TextFileLoader.GetTokenString("needspformula", &SkillData.strNeedSPFormula);
  713.         TextFileLoader.GetTokenString("continuationspformula", &SkillData.strContinuationSPFormula);
  714.         TextFileLoader.GetTokenDoubleWord("range", &SkillData.dwTargetRange);
  715.         TextFileLoader.GetTokenByte("maxlevel", &SkillData.byMaxLevel);
  716.         TextFileLoader.GetTokenByte("leveluppoint", &SkillData.byLevelUpPoint);
  717.  
  718.         WORD wMotionIndex;
  719.         if (TextFileLoader.GetTokenWord("motionindex", &wMotionIndex))
  720.         {
  721.                 SkillData.wMotionIndex = wMotionIndex;
  722.         }
  723.         else
  724.         {
  725.                 SkillData.wMotionIndex = 0;
  726.         }
  727.  
  728.         WORD wMotionIndexForMe;
  729.         if (TextFileLoader.GetTokenWord("motionindexforme", &wMotionIndexForMe))
  730.         {
  731.                 SkillData.wMotionIndexForMe = wMotionIndexForMe;
  732.         }
  733.         else
  734.         {
  735.                 SkillData.wMotionIndexForMe = 0;
  736.         }
  737.  
  738.         SkillData.strIconFileName = g_strImagePath + SkillData.strIconFileName;
  739.         SkillData.pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(SkillData.strIconFileName.c_str());
  740.  
  741.         m_SkillDataMap.insert(TSkillDataMap::value_type(dwSkillIndex, SkillData));
  742.  
  743.         /////
  744.  
  745.         if (SkillData.IsTimeIncreaseSkill())
  746.         {
  747.                 CPythonSkill::SSkillData::ms_dwTimeIncreaseSkillNumber = SkillData.dwSkillIndex;
  748.         }
  749.  
  750.         return true;
  751. }
  752.  
  753. BOOL CPythonSkill::GetSkillData(DWORD dwSkillIndex, TSkillData ** ppSkillData)
  754. {
  755.         TSkillDataMap::iterator it = m_SkillDataMap.find(dwSkillIndex);
  756.  
  757.         if (m_SkillDataMap.end() == it)
  758.                 return FALSE;
  759.  
  760.         *ppSkillData = &(it->second);
  761.         return TRUE;
  762. }
  763.  
  764. bool CPythonSkill::GetSkillDataByName(const char * c_szName, TSkillData ** ppSkillData)
  765. {
  766.         TSkillDataMap::iterator itor = m_SkillDataMap.begin();
  767.         for (; itor != m_SkillDataMap.end(); ++itor)
  768.         {
  769.                 TSkillData * pData = &(itor->second);
  770.                 if (0 == pData->strName.compare(c_szName))
  771.                 {
  772.                         *ppSkillData = &(itor->second);
  773.                         return true;
  774.                 }
  775.         }
  776.         return false;
  777. }
  778.  
  779. void CPythonSkill::SetPathName(const char * c_szFileName)
  780. {
  781.         m_strPathName = c_szFileName;
  782. }
  783.  
  784. const char * CPythonSkill::GetPathName()
  785. {
  786.         return m_strPathName.c_str();
  787. }
  788.  
  789. void CPythonSkill::TEST()
  790. {
  791.         BOOL isFirst;
  792.         std::map<std::string, DWORD>::iterator itorSub;
  793.  
  794.         FILE * File = fopen("test.txt", "w");
  795.  
  796.         for (TSkillDataMap::iterator itor = m_SkillDataMap.begin(); itor != m_SkillDataMap.end(); ++itor)
  797.         {
  798.                 TSkillData & rSkillData = itor->second;
  799.  
  800.                 std::string strLine = "";
  801.                 strLine += rSkillData.strName.c_str();
  802.                 strLine += "\t";
  803.                 // Name2
  804.                 strLine += "\t";
  805.                 // Name3
  806.                 strLine += "\t";
  807.                 strLine += rSkillData.strDescription;
  808.                 strLine += "\t";
  809.                 if (rSkillData.ConditionDataVector.size() > 0)
  810.                         strLine += rSkillData.ConditionDataVector[0];
  811.                 strLine += "\t";
  812.                 if (rSkillData.ConditionDataVector.size() > 1)
  813.                         strLine += rSkillData.ConditionDataVector[1];
  814.                 strLine += "\t";
  815.                 if (rSkillData.ConditionDataVector.size() > 2)
  816.                         strLine += rSkillData.ConditionDataVector[2];
  817.                 strLine += "\t";
  818.                 if (rSkillData.ConditionDataVector.size() > 3)
  819.                         strLine += rSkillData.ConditionDataVector[3];
  820.  
  821.                 strLine += "\t";
  822.                 isFirst = TRUE;
  823.                 for (itorSub = m_SkillAttributeIndexMap.begin(); itorSub != m_SkillAttributeIndexMap.end(); ++itorSub)
  824.                 {
  825.                         if (itorSub->second & rSkillData.dwSkillAttribute)
  826.                         {
  827.                                 if (isFirst)
  828.                                 {
  829.                                         isFirst = FALSE;
  830.                                 }
  831.                                 else
  832.                                 {
  833.                                         strLine += "|";
  834.                                 }
  835.                                 strLine += itorSub->first.c_str();
  836.                         }
  837.                 }
  838.  
  839.                 strLine += "\t";
  840.                 isFirst = TRUE;
  841.                 for (itorSub = m_SkillNeedWeaponIndexMap.begin(); itorSub != m_SkillNeedWeaponIndexMap.end(); ++itorSub)
  842.                 {
  843.                         if (itorSub->second & rSkillData.dwNeedWeapon)
  844.                         {
  845.                                 if (isFirst)
  846.                                 {
  847.                                         isFirst = FALSE;
  848.                                 }
  849.                                 else
  850.                                 {
  851.                                         strLine += "|";
  852.                                 }
  853.                                 strLine += itorSub->first.c_str();
  854.                         }
  855.                 }
  856.  
  857.                 strLine += "\t";
  858.                 std::string strFileName = rSkillData.strIconFileName;
  859.                 int iPos = strFileName.find_last_of("/", rSkillData.strIconFileName.length());
  860.                 if (iPos > 0)
  861.                         strFileName = strFileName.substr(iPos+1, strFileName.length() - iPos - 4 - 1);
  862.                 strLine += strFileName;
  863.  
  864.                 strLine += "\t";
  865.                 char szMotionIndex[32+1];
  866.                 _snprintf(szMotionIndex, sizeof(szMotionIndex), "%d", rSkillData.wMotionIndex);
  867.                 strLine += szMotionIndex;
  868.  
  869.                 strLine += "\t";
  870.                 if (rSkillData.wMotionIndexForMe > 1)
  871.                 {
  872.                         char szMotionIndexForMe[32+1];
  873.                         _snprintf(szMotionIndexForMe, sizeof(szMotionIndexForMe), "%d", rSkillData.wMotionIndexForMe);
  874.                         strLine += szMotionIndexForMe;
  875.                 }
  876.  
  877.                 assert(rSkillData.AffectDataVector.size() <= 3);
  878.                 strLine += "\t";
  879.                 if (rSkillData.AffectDataVector.size() > 0)
  880.                 {
  881.                         strLine += rSkillData.AffectDataVector[0].strAffectDescription;
  882.                         strLine += "\t";
  883.                         strLine += rSkillData.AffectDataVector[0].strAffectMinFormula;
  884.                         strLine += "\t";
  885.                         strLine += rSkillData.AffectDataVector[0].strAffectMaxFormula;
  886.                 }
  887.                 strLine += "\t";
  888.                 if (rSkillData.AffectDataVector.size() > 1)
  889.                 {
  890.                         strLine += rSkillData.AffectDataVector[1].strAffectDescription;
  891.                         strLine += "\t";
  892.                         strLine += rSkillData.AffectDataVector[1].strAffectMinFormula;
  893.                         strLine += "\t";
  894.                         strLine += rSkillData.AffectDataVector[1].strAffectMaxFormula;
  895.                 }
  896.                 strLine += "\t";
  897.                 if (rSkillData.AffectDataVector.size() > 2)
  898.                 {
  899.                         strLine += rSkillData.AffectDataVector[2].strAffectDescription;
  900.                         strLine += "\t";
  901.                         strLine += rSkillData.AffectDataVector[2].strAffectMinFormula;
  902.                         strLine += "\t";
  903.                         strLine += rSkillData.AffectDataVector[2].strAffectMaxFormula;
  904.                 }
  905.  
  906.                 fprintf(File, "%s\n", strLine.c_str());
  907.         }
  908.  
  909.         fclose(File);
  910. }
  911.  
  912. CPythonSkill::CPythonSkill()
  913. {
  914.         m_SkillTypeIndexMap.insert(std::map<std::string, DWORD>::value_type("none", SKILL_TYPE_NONE));
  915.         m_SkillTypeIndexMap.insert(std::map<std::string, DWORD>::value_type("active", SKILL_TYPE_ACTIVE));
  916.         m_SkillTypeIndexMap.insert(std::map<std::string, DWORD>::value_type("support", SKILL_TYPE_SUPPORT));
  917.         m_SkillTypeIndexMap.insert(std::map<std::string, DWORD>::value_type("guild", SKILL_TYPE_GUILD));
  918.         m_SkillTypeIndexMap.insert(std::map<std::string, DWORD>::value_type("horse", SKILL_TYPE_HORSE));
  919.         m_SkillTypeIndexMap.insert(std::map<std::string, DWORD>::value_type("warrior", SKILL_TYPE_ACTIVE));
  920.         m_SkillTypeIndexMap.insert(std::map<std::string, DWORD>::value_type("assassin", SKILL_TYPE_ACTIVE));
  921.         m_SkillTypeIndexMap.insert(std::map<std::string, DWORD>::value_type("sura", SKILL_TYPE_ACTIVE));
  922.         m_SkillTypeIndexMap.insert(std::map<std::string, DWORD>::value_type("shaman", SKILL_TYPE_ACTIVE));
  923.         m_SkillTypeIndexMap.insert(std::map<std::string, DWORD>::value_type("wolfman", SKILL_TYPE_ACTIVE));
  924.         m_SkillTypeIndexMap.insert(std::map<std::string, DWORD>::value_type("passive", SKILL_TYPE_ACTIVE));
  925.  
  926.         m_SkillAttributeIndexMap.insert(std::map<std::string, DWORD>::value_type("NEED_POISON_BOTTLE", SKILL_ATTRIBUTE_NEED_POISON_BOTTLE));
  927.         m_SkillAttributeIndexMap.insert(std::map<std::string, DWORD>::value_type("NEED_EMPTY_BOTTLE", SKILL_ATTRIBUTE_NEED_EMPTY_BOTTLE));
  928.         m_SkillAttributeIndexMap.insert(std::map<std::string, DWORD>::value_type("CAN_USE_IF_NOT_ENOUGH", SKILL_ATTRIBUTE_CAN_USE_IF_NOT_ENOUGH));
  929.         m_SkillAttributeIndexMap.insert(std::map<std::string, DWORD>::value_type("FAN_RANGE", SKILL_ATTRIBUTE_FAN_RANGE));
  930.         m_SkillAttributeIndexMap.insert(std::map<std::string, DWORD>::value_type("NEED_CORPSE", SKILL_ATTRIBUTE_NEED_CORPSE));
  931.         m_SkillAttributeIndexMap.insert(std::map<std::string, DWORD>::value_type("NEED_TARGET", SKILL_ATTRIBUTE_NEED_TARGET));
  932.         m_SkillAttributeIndexMap.insert(std::map<std::string, DWORD>::value_type("TOGGLE", SKILL_ATTRIBUTE_TOGGLE));
  933.         m_SkillAttributeIndexMap.insert(std::map<std::string, DWORD>::value_type("WEAPON_LIMITATION", SKILL_ATTRIBUTE_WEAPON_LIMITATION));
  934.         m_SkillAttributeIndexMap.insert(std::map<std::string, DWORD>::value_type("MELEE_ATTACK", SKILL_ATTRIBUTE_MELEE_ATTACK));
  935.         m_SkillAttributeIndexMap.insert(std::map<std::string, DWORD>::value_type("CHARGE_ATTACK", SKILL_ATTRIBUTE_CHARGE_ATTACK));
  936.         m_SkillAttributeIndexMap.insert(std::map<std::string, DWORD>::value_type("USE_HP", SKILL_ATTRIBUTE_USE_HP));
  937.         m_SkillAttributeIndexMap.insert(std::map<std::string, DWORD>::value_type("CAN_CHANGE_DIRECTION", SKILL_ATTRIBUTE_CAN_CHANGE_DIRECTION));
  938.         m_SkillAttributeIndexMap.insert(std::map<std::string, DWORD>::value_type("STANDING_SKILL", SKILL_ATTRIBUTE_STANDING_SKILL));
  939.         m_SkillAttributeIndexMap.insert(std::map<std::string, DWORD>::value_type("ONLY_FOR_ALLIANCE", SKILL_ATTRIBUTE_ONLY_FOR_ALLIANCE));
  940.         m_SkillAttributeIndexMap.insert(std::map<std::string, DWORD>::value_type("CAN_USE_FOR_ME", SKILL_ATTRIBUTE_CAN_USE_FOR_ME));
  941.         m_SkillAttributeIndexMap.insert(std::map<std::string, DWORD>::value_type("ATTACK_SKILL", SKILL_ATTRIBUTE_ATTACK_SKILL));
  942.         m_SkillAttributeIndexMap.insert(std::map<std::string, DWORD>::value_type("MOVING_SKILL", SKILL_ATTRIBUTE_MOVING_SKILL));
  943.         m_SkillAttributeIndexMap.insert(std::map<std::string, DWORD>::value_type("HORSE_SKILL", SKILL_ATTRIBUTE_HORSE_SKILL));
  944.         m_SkillAttributeIndexMap.insert(std::map<std::string, DWORD>::value_type("TIME_INCREASE_SKILL", SKILL_ATTRIBUTE_TIME_INCREASE_SKILL));
  945.         m_SkillAttributeIndexMap.insert(std::map<std::string, DWORD>::value_type("PASSIVE", SKILL_ATTRIBUTE_PASSIVE));
  946.         m_SkillAttributeIndexMap.insert(std::map<std::string, DWORD>::value_type("CANNOT_LEVEL_UP", SKILL_ATTRIBUTE_CANNOT_LEVEL_UP));
  947.         m_SkillAttributeIndexMap.insert(std::map<std::string, DWORD>::value_type("ONLY_FOR_GUILD_WAR", SKILL_ATTRIBUTE_ONLY_FOR_GUILD_WAR));
  948.         m_SkillAttributeIndexMap.insert(std::map<std::string, DWORD>::value_type("CIRCLE_RANGE", SKILL_ATTRIBUTE_CIRCLE_RANGE));
  949.         m_SkillAttributeIndexMap.insert(std::map<std::string, DWORD>::value_type("SEARCH_TARGET", SKILL_ATTRIBUTE_SEARCH_TARGET));
  950.  
  951.         m_SkillNeedWeaponIndexMap.insert(std::map<std::string, DWORD>::value_type("SWORD", SKILL_NEED_WEAPON_SWORD));
  952.         m_SkillNeedWeaponIndexMap.insert(std::map<std::string, DWORD>::value_type("DAGGER", SKILL_NEED_WEAPON_DAGGER));
  953.         m_SkillNeedWeaponIndexMap.insert(std::map<std::string, DWORD>::value_type("BOW", SKILL_NEED_WEAPON_BOW));
  954.         m_SkillNeedWeaponIndexMap.insert(std::map<std::string, DWORD>::value_type("TWO_HANDED", SKILL_NEED_WEAPON_TWO_HANDED));
  955.         m_SkillNeedWeaponIndexMap.insert(std::map<std::string, DWORD>::value_type("DOUBLE_SWORD", SKILL_NEED_WEAPON_DOUBLE_SWORD));
  956.         m_SkillNeedWeaponIndexMap.insert(std::map<std::string, DWORD>::value_type("BELL", SKILL_NEED_WEAPON_BELL));
  957.         m_SkillNeedWeaponIndexMap.insert(std::map<std::string, DWORD>::value_type("FAN", SKILL_NEED_WEAPON_FAN));
  958.         m_SkillNeedWeaponIndexMap.insert(std::map<std::string, DWORD>::value_type("ARROW", SKILL_NEED_WEAPON_ARROW));
  959.         m_SkillNeedWeaponIndexMap.insert(std::map<std::string, DWORD>::value_type("WEAPON_MOUNT_SPEAR", SKILL_NEED_WEAPON_MOUNT_SPEAR));
  960.         m_SkillNeedWeaponIndexMap.insert(std::map<std::string, DWORD>::value_type("CLAW", SKILL_NEED_WEAPON_CLAW));
  961.         m_SkillNeedWeaponIndexMap.insert(std::map<std::string, DWORD>::value_type("EMPTY_HAND", SKILL_NEED_WEAPON_EMPTY_HAND));
  962.  
  963.         m_SkillWeaponTypeIndexMap.insert(make_pair(std::string("SWORD"), CItemData::WEAPON_SWORD));
  964.         m_SkillWeaponTypeIndexMap.insert(make_pair(std::string("DAGGER"), CItemData::WEAPON_DAGGER));
  965.         m_SkillWeaponTypeIndexMap.insert(make_pair(std::string("BOW"), CItemData::WEAPON_BOW));
  966.         m_SkillWeaponTypeIndexMap.insert(make_pair(std::string("TWO_HANDED"), CItemData::WEAPON_TWO_HANDED));
  967.         m_SkillWeaponTypeIndexMap.insert(make_pair(std::string("DOUBLE_SWORD"), CItemData::WEAPON_DAGGER));
  968.         m_SkillWeaponTypeIndexMap.insert(make_pair(std::string("BELL"), CItemData::WEAPON_BELL));
  969.         m_SkillWeaponTypeIndexMap.insert(make_pair(std::string("FAN"), CItemData::WEAPON_FAN));
  970.         m_SkillWeaponTypeIndexMap.insert(make_pair(std::string("ARROW"), CItemData::WEAPON_ARROW));
  971.         m_SkillWeaponTypeIndexMap.insert(make_pair(std::string("WEAPON_MOUNT_SPEAR"), CItemData::WEAPON_MOUNT_SPEAR));
  972.         m_SkillWeaponTypeIndexMap.insert(make_pair(std::string("CLAW"), CItemData::WEAPON_CLAW));
  973.  
  974.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("chain"), POINT_NONE));
  975.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("HR"), POINT_HIT_RATE));
  976.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("LV"), POINT_LEVEL));
  977.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("Level"), POINT_LEVEL));
  978.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("MaxHP"), POINT_MAX_HP));
  979.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("MaxSP"), POINT_MAX_SP));    
  980.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("MinMWEP"), POINT_MIN_WEP));
  981.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("MaxMWEP"), POINT_MAX_WEP));
  982.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("MinWEP"), POINT_MIN_WEP));
  983.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("MaxWEP"), POINT_MAX_WEP));
  984.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("MinATK"), POINT_MIN_ATK));
  985.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("MaxATK"), POINT_MAX_ATK));
  986.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("ATKSPD"), POINT_ATT_SPEED));
  987.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("AttackPower"), POINT_MIN_ATK));     
  988.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("AtkMin"), POINT_MIN_ATK));
  989.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("AtkMax"), POINT_MAX_ATK));
  990.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("DefencePower"), POINT_DEF_GRADE));
  991.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("DEF"), POINT_DEF_GRADE));
  992.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("MWEP"), POINT_MAGIC_ATT_GRADE));
  993.  
  994.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("MagicAttackPower"), POINT_MAGIC_ATT_GRADE));
  995.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("INT"), POINT_IQ));
  996.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("STR"), POINT_ST));
  997.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("DEX"), POINT_DX));
  998.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("CON"), POINT_HT));
  999.  
  1000.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("minatk"), POINT_MIN_ATK));
  1001.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("maxatk"), POINT_MAX_ATK));
  1002.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("minmtk"), POINT_MIN_WEP));
  1003.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("maxmtk"), POINT_MAX_WEP));
  1004.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("maxhp"), POINT_MAX_HP));
  1005.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("maxsp"), POINT_MAX_SP));    
  1006.  
  1007.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("odef"), POINT_DEF_GRADE));
  1008.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("minwep"), POINT_MIN_WEP));
  1009.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("maxwep"), POINT_MAX_WEP));
  1010.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("minmwep"), POINT_MIN_MAGIC_WEP));
  1011.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("maxmwep"), POINT_MAX_MAGIC_WEP));
  1012.  
  1013.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("lv"), POINT_LEVEL));
  1014.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("ar"), POINT_HIT_RATE));
  1015.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("iq"), POINT_IQ));
  1016.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("str"), POINT_ST));
  1017.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("dex"), POINT_DX));
  1018.         SSkillData::ms_StatusNameMap.insert(make_pair(std::string("con"), POINT_HT));
  1019.  
  1020.         SSkillData::ms_NewMinStatusNameMap.insert(make_pair(std::string("atk"), POINT_MIN_ATK));
  1021.         SSkillData::ms_NewMinStatusNameMap.insert(make_pair(std::string("mtk"), POINT_MIN_WEP));
  1022.         SSkillData::ms_NewMinStatusNameMap.insert(make_pair(std::string("wep"), POINT_MIN_WEP));
  1023.         SSkillData::ms_NewMinStatusNameMap.insert(make_pair(std::string("lv"), POINT_LEVEL));
  1024.         SSkillData::ms_NewMinStatusNameMap.insert(make_pair(std::string("ar"), POINT_HIT_RATE));
  1025.         SSkillData::ms_NewMinStatusNameMap.insert(make_pair(std::string("iq"), POINT_IQ));
  1026.         SSkillData::ms_NewMinStatusNameMap.insert(make_pair(std::string("str"), POINT_ST));
  1027.         SSkillData::ms_NewMinStatusNameMap.insert(make_pair(std::string("dex"), POINT_DX));
  1028.         SSkillData::ms_NewMinStatusNameMap.insert(make_pair(std::string("con"), POINT_HT));
  1029.         SSkillData::ms_NewMaxStatusNameMap.insert(make_pair(std::string("atk"), POINT_MAX_ATK));
  1030.         SSkillData::ms_NewMaxStatusNameMap.insert(make_pair(std::string("mtk"), POINT_MAX_WEP));
  1031.         SSkillData::ms_NewMinStatusNameMap.insert(make_pair(std::string("wep"), POINT_MAX_WEP));
  1032.         SSkillData::ms_NewMaxStatusNameMap.insert(make_pair(std::string("lv"), POINT_LEVEL));
  1033.         SSkillData::ms_NewMaxStatusNameMap.insert(make_pair(std::string("ar"), POINT_HIT_RATE));
  1034.         SSkillData::ms_NewMaxStatusNameMap.insert(make_pair(std::string("iq"), POINT_IQ));
  1035.         SSkillData::ms_NewMaxStatusNameMap.insert(make_pair(std::string("str"), POINT_ST));
  1036.         SSkillData::ms_NewMaxStatusNameMap.insert(make_pair(std::string("dex"), POINT_DX));
  1037.         SSkillData::ms_NewMaxStatusNameMap.insert(make_pair(std::string("con"), POINT_HT));    
  1038.  
  1039.         m_PathNameMap.insert(make_pair(std::string("WARRIOR"), std::string("warrior")));
  1040.         m_PathNameMap.insert(make_pair(std::string("ASSASSIN"), std::string("assassin")));
  1041.         m_PathNameMap.insert(make_pair(std::string("SURA"), std::string("sura")));
  1042.         m_PathNameMap.insert(make_pair(std::string("SHAMAN"), std::string("shaman")));
  1043.         m_PathNameMap.insert(make_pair(std::string("WOLFMAN"), std::string("wolfman")));
  1044.         m_PathNameMap.insert(make_pair(std::string("PASSIVE"), std::string("passive")));
  1045.         m_PathNameMap.insert(make_pair(std::string("SUPPORT"), std::string("common/support")));
  1046.         m_PathNameMap.insert(make_pair(std::string("GUILD"), std::string("common/guild")));
  1047.         m_PathNameMap.insert(make_pair(std::string("HORSE"), std::string("common/horse")));
  1048. }
  1049. CPythonSkill::~CPythonSkill()
  1050. {
  1051. }
  1052.  
  1053. ///////////////////////////////////////////////////////////////////////////////////////////////////
  1054. ///////////////////////////////////////////////////////////////////////////////////////////////////
  1055. ///////////////////////////////////////////////////////////////////////////////////////////////////
  1056.  
  1057. DWORD CPythonSkill::SSkillData::MELEE_SKILL_TARGET_RANGE=170;
  1058.  
  1059. const std::string CPythonSkill::SSkillData::GetName() const
  1060. {
  1061.         return strName;
  1062. }
  1063.  
  1064. BYTE CPythonSkill::SSkillData::GetType() const
  1065. {
  1066.         return byType;
  1067. }
  1068.  
  1069. BOOL CPythonSkill::SSkillData::IsMeleeSkill()
  1070. {
  1071.         if (dwSkillAttribute & SKILL_ATTRIBUTE_MELEE_ATTACK)
  1072.                 return TRUE;
  1073.  
  1074.         return FALSE;
  1075. }
  1076.  
  1077. BOOL CPythonSkill::SSkillData::IsChargeSkill()
  1078. {
  1079.         if (dwSkillAttribute & SKILL_ATTRIBUTE_CHARGE_ATTACK)
  1080.                 return TRUE;
  1081.  
  1082.         return FALSE;
  1083. }
  1084.  
  1085. BOOL CPythonSkill::SSkillData::IsOnlyForGuildWar()
  1086. {
  1087.         if (dwSkillAttribute & SKILL_ATTRIBUTE_ONLY_FOR_GUILD_WAR)
  1088.                 return TRUE;
  1089.  
  1090.         return FALSE;
  1091. }
  1092.                        
  1093. DWORD CPythonSkill::SSkillData::GetTargetRange() const
  1094. {
  1095.         if (dwSkillAttribute & SKILL_ATTRIBUTE_MELEE_ATTACK)
  1096.                 return MELEE_SKILL_TARGET_RANGE;
  1097.  
  1098.         if (dwSkillAttribute & SKILL_ATTRIBUTE_CHARGE_ATTACK)
  1099.                 return MELEE_SKILL_TARGET_RANGE;
  1100.  
  1101.         return dwTargetRange;
  1102. }
  1103.  
  1104. BOOL CPythonSkill::SSkillData::CanChangeDirection()
  1105. {
  1106.         return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_CAN_CHANGE_DIRECTION);
  1107. }
  1108.  
  1109. BOOL CPythonSkill::SSkillData::IsFanRange()
  1110. {
  1111.         return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_FAN_RANGE);
  1112. }
  1113.  
  1114. BOOL CPythonSkill::SSkillData::IsCircleRange()
  1115. {
  1116.         return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_CIRCLE_RANGE);
  1117. }
  1118.  
  1119. BOOL CPythonSkill::SSkillData::IsAutoSearchTarget()
  1120. {
  1121.         return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_SEARCH_TARGET);
  1122. }
  1123.  
  1124. BOOL CPythonSkill::SSkillData::IsNeedCorpse()
  1125. {
  1126.         return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_NEED_CORPSE);
  1127. }
  1128.  
  1129. BOOL CPythonSkill::SSkillData::IsNeedTarget()
  1130. {
  1131.         return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_NEED_TARGET);
  1132. }
  1133.  
  1134. BOOL CPythonSkill::SSkillData::IsToggleSkill()
  1135. {
  1136.         return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_TOGGLE);
  1137. }
  1138.  
  1139. BOOL CPythonSkill::SSkillData::IsUseHPSkill()
  1140. {
  1141.         return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_USE_HP);
  1142. }
  1143.  
  1144. BOOL CPythonSkill::SSkillData::IsStandingSkill()
  1145. {
  1146.         return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_STANDING_SKILL);
  1147. }
  1148.  
  1149. BOOL CPythonSkill::SSkillData::CanUseWeaponType(DWORD dwWeaponType)
  1150. {
  1151.         if (!(dwSkillAttribute & SKILL_ATTRIBUTE_WEAPON_LIMITATION))
  1152.                 return TRUE;
  1153.  
  1154.         return 0 != (dwNeedWeapon & (1 << dwWeaponType));
  1155. }
  1156.  
  1157. BOOL CPythonSkill::SSkillData::IsOnlyForAlliance()
  1158. {
  1159.         return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_ONLY_FOR_ALLIANCE);
  1160. }
  1161.  
  1162. BOOL CPythonSkill::SSkillData::CanUseForMe()
  1163. {
  1164.         return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_CAN_USE_FOR_ME);
  1165. }
  1166.  
  1167. BOOL CPythonSkill::SSkillData::CanUseIfNotEnough()
  1168. {
  1169.         return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_CAN_USE_IF_NOT_ENOUGH);
  1170. }
  1171.  
  1172. BOOL CPythonSkill::SSkillData::IsNeedEmptyBottle()
  1173. {
  1174.         return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_NEED_EMPTY_BOTTLE);
  1175. }
  1176.  
  1177. BOOL CPythonSkill::SSkillData::IsNeedPoisonBottle()
  1178. {
  1179.         return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_NEED_POISON_BOTTLE);
  1180. }
  1181.  
  1182. BOOL CPythonSkill::SSkillData::IsNeedBow()
  1183. {
  1184.         if (!(dwSkillAttribute & SKILL_ATTRIBUTE_WEAPON_LIMITATION))
  1185.                 return FALSE;
  1186.  
  1187.         return 0 != (dwNeedWeapon & SKILL_NEED_WEAPON_BOW);
  1188. }
  1189.  
  1190. BOOL CPythonSkill::SSkillData::IsHorseSkill()
  1191. {
  1192.         return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_HORSE_SKILL);
  1193. }
  1194.  
  1195. BOOL CPythonSkill::SSkillData::IsMovingSkill()
  1196. {
  1197.         return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_MOVING_SKILL);
  1198. }
  1199.  
  1200. BOOL CPythonSkill::SSkillData::IsAttackSkill()
  1201. {
  1202.         return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_ATTACK_SKILL);
  1203. }
  1204.  
  1205. BOOL CPythonSkill::SSkillData::IsTimeIncreaseSkill()
  1206. {
  1207.         return 0 != (dwSkillAttribute & SKILL_ATTRIBUTE_TIME_INCREASE_SKILL);
  1208. }
  1209.  
  1210. bool CPythonSkill::SSkillData::GetState(const char * c_szStateName, int * piState, int iMinMaxType)
  1211. {
  1212.         std::map<std::string, DWORD> * pStatusNameMap = NULL;
  1213.  
  1214.         switch (iMinMaxType)
  1215.         {
  1216.                 case VALUE_TYPE_FREE:
  1217.                         pStatusNameMap = &ms_StatusNameMap;
  1218.                         break;
  1219.                 case VALUE_TYPE_MIN:
  1220.                         pStatusNameMap = &ms_NewMinStatusNameMap;
  1221.                         break;
  1222.                 case VALUE_TYPE_MAX:
  1223.                         pStatusNameMap = &ms_NewMaxStatusNameMap;
  1224.                         break;
  1225.                 default:
  1226.                         return false;
  1227.                         break;
  1228.         }
  1229.  
  1230.         std::map<std::string, DWORD>::iterator it = pStatusNameMap->find(c_szStateName);
  1231.  
  1232.         if (it != pStatusNameMap->end())
  1233.         {
  1234.                 *piState = CPythonPlayer::Instance().GetStatus(it->second);
  1235.         }
  1236.         else if (0 == strncmp(c_szStateName, "JeungJi", 7))
  1237.         {
  1238.                 *piState = 0;
  1239.  
  1240.                 // 증지술 임시 제외
  1241. /*
  1242.                 if (0 != ms_dwTimeIncreaseSkillNumber)
  1243.                 {
  1244.                         DWORD dwSkillSlotIndex;
  1245.                         if (!CPythonPlayer::Instance().FindSkillSlotIndexBySkillIndex(ms_dwTimeIncreaseSkillNumber, &dwSkillSlotIndex))
  1246.                                 return false;
  1247.  
  1248.                         *piState = CPythonPlayer::Instance().GetSkillLevel(dwSkillSlotIndex);
  1249.                 }
  1250. */
  1251.         }
  1252.  
  1253.         return true;
  1254. }
  1255.  
  1256. float CPythonSkill::SSkillData::ProcessFormula(CPoly * pPoly, float fSkillLevel, int iMinMaxType)
  1257. {
  1258.         if (pPoly->Analyze())
  1259.         {
  1260.                 for (DWORD i = 0; i < pPoly->GetVarCount(); ++i)
  1261.                 {
  1262.                         const char * c_szVarName = pPoly->GetVarName(i);
  1263.                         float fState;
  1264.                         if (!strcmp("SkillPoint", c_szVarName) || !strcmp("k", c_szVarName))
  1265.                         {
  1266.                                 fState = fSkillLevel;
  1267.                         }
  1268.                         else
  1269.                         {
  1270.                                 int iState;
  1271.                                 if (!GetState(c_szVarName, &iState, iMinMaxType))
  1272.                                         return 0.0f;
  1273.  
  1274.                                 fState = float(iState);
  1275.  
  1276.                                 if (!strcmp("ar", c_szVarName))
  1277.                                         fState /= 100.0f;
  1278.                         }
  1279.                         pPoly->SetVar(c_szVarName, fState);
  1280.                 }
  1281.         }
  1282.         else
  1283.         {
  1284.                 TraceError("skillGetAffect - Strange Formula [%s]", strName.c_str());
  1285.                 return 0.0f;
  1286.         }
  1287.  
  1288.         return pPoly->Eval();
  1289. }
  1290.  
  1291. const char * CPythonSkill::SSkillData::GetAffectDescription(DWORD dwIndex, float fSkillLevel)
  1292. {
  1293.         if (dwIndex >= AffectDataVector.size())
  1294.                 return NULL;
  1295.  
  1296.         const std::string & c_rstrAffectDescription = AffectDataVector[dwIndex].strAffectDescription;
  1297.         const std::string & c_rstrAffectMinFormula = AffectDataVector[dwIndex].strAffectMinFormula;
  1298.         const std::string & c_rstrAffectMaxFormula = AffectDataVector[dwIndex].strAffectMaxFormula;
  1299.  
  1300.         CPoly minPoly;
  1301.         CPoly maxPoly;
  1302.         minPoly.SetStr(c_rstrAffectMinFormula.c_str());
  1303.         maxPoly.SetStr(c_rstrAffectMaxFormula.c_str());
  1304.        
  1305.         // OVERWRITE_SKILLPROTO_POLY
  1306.         float fMinValue = ProcessFormula(&minPoly, fSkillLevel);
  1307.         float fMaxValue = ProcessFormula(&maxPoly, fSkillLevel);
  1308.  
  1309.         if (fMinValue < 0.0)
  1310.                 fMinValue = - fMinValue;
  1311.         if (fMaxValue < 0.0)
  1312.                 fMaxValue = - fMaxValue;
  1313.  
  1314.         if (CP_ARABIC == ::GetDefaultCodePage())
  1315.         {
  1316.                 // #0000870: [M2AE] 한국어 모드일때 특정 아랍어 문장에서 크래쉬 발생
  1317.                 static std::string strDescription;
  1318.                 strDescription = c_rstrAffectDescription;
  1319.                 int first = strDescription.find("%.0f");
  1320.                 if (first >= 0)
  1321.                 {
  1322.                         fMinValue = floorf(fMinValue);
  1323.  
  1324.                         char szMinValue[256];
  1325.                         _snprintf(szMinValue, sizeof(szMinValue), "%.0f", fMinValue);
  1326.                         strDescription.replace(first, 4, szMinValue);
  1327.  
  1328.                         int second = strDescription.find("%.0f", first);
  1329.                         if (second >= 0)
  1330.                         {
  1331.                                 fMaxValue = floorf(fMaxValue);
  1332.  
  1333.                                 char szMaxValue[256];
  1334.                                 _snprintf(szMaxValue, sizeof(szMaxValue), "%.0f", fMaxValue);
  1335.                                 strDescription.replace(second, 4, szMaxValue);
  1336.                         }
  1337.                 }
  1338.                 return strDescription.c_str();
  1339.         }
  1340.         else
  1341.         {
  1342.                 if (strstr(c_rstrAffectDescription.c_str(), "%.0f"))
  1343.                 {
  1344.                         fMinValue = floorf(fMinValue);
  1345.                         fMaxValue = floorf(fMaxValue);
  1346.                 }
  1347.  
  1348.                 static char szDescription[64+1];
  1349.                 _snprintf(szDescription, sizeof(szDescription), c_rstrAffectDescription.c_str(), fMinValue, fMaxValue);
  1350.                
  1351.                 return szDescription;
  1352.         }
  1353. }
  1354.  
  1355. DWORD CPythonSkill::SSkillData::GetSkillCoolTime(float fSkillPoint)
  1356. {
  1357.         if (strCoolTimeFormula.empty())
  1358.                 return 0;
  1359.  
  1360.         CPoly poly;
  1361.         poly.SetStr(strCoolTimeFormula.c_str());
  1362.  
  1363.         return DWORD(ProcessFormula(&poly, fSkillPoint));
  1364. }
  1365.  
  1366.  
  1367. DWORD CPythonSkill::SSkillData::GetTargetCount(float fSkillPoint)
  1368. {
  1369.         if (strTargetCountFormula.empty())
  1370.                 return 0;
  1371.  
  1372.         CPoly poly;
  1373.         poly.SetStr(strTargetCountFormula.c_str());
  1374.  
  1375.         return DWORD(ProcessFormula(&poly, fSkillPoint));
  1376. }
  1377.  
  1378. DWORD CPythonSkill::SSkillData::GetSkillMotionIndex(int iGrade)
  1379. {
  1380.         if (-1 != iGrade && SKILL_EFFECT_UPGRADE_ENABLE)
  1381.         {
  1382.                 assert(iGrade >= 0 && iGrade < SKILL_EFFECT_COUNT);
  1383.                 /*
  1384.                 if (SKILL_GRADE_COUNT == iGrade)
  1385.                 {
  1386.                         return GradeData[SKILL_GRADE_COUNT-1].wMotionIndex;
  1387.                 }
  1388.                 else */
  1389.                 if (iGrade >= 0 && iGrade < SKILL_EFFECT_COUNT)
  1390.                 {
  1391.                         return GradeData[iGrade].wMotionIndex;
  1392.                 }
  1393.         }
  1394.  
  1395.         return wMotionIndex;
  1396. }
  1397.  
  1398. BYTE CPythonSkill::SSkillData::GetMaxLevel()
  1399. {
  1400.         return byMaxLevel;
  1401. }
  1402.  
  1403. BYTE CPythonSkill::SSkillData::GetLevelUpPoint()
  1404. {
  1405.         return byLevelUpPoint;
  1406. }
  1407.  
  1408. BOOL CPythonSkill::SSkillData::IsNoMotion()
  1409. {
  1410.         return bNoMotion;
  1411. }
  1412.  
  1413. bool CPythonSkill::SSkillData::IsCanUseSkill()
  1414. {
  1415.         if (0 != (dwSkillAttribute & SKILL_ATTRIBUTE_PASSIVE))
  1416.                 return false;
  1417.  
  1418.         return true;
  1419. }
  1420.  
  1421. DWORD CPythonSkill::SSkillData::GetMotionLoopCount(float fSkillPoint)
  1422. {
  1423.         if (strMotionLoopCountFormula.empty())
  1424.                 return 0;
  1425.  
  1426.         CPoly poly;
  1427.         poly.SetStr(strMotionLoopCountFormula.c_str());
  1428.  
  1429.         return DWORD(ProcessFormula(&poly, fSkillPoint));
  1430. }
  1431.  
  1432. int CPythonSkill::SSkillData::GetNeedSP(float fSkillPoint)
  1433. {
  1434.         if (strNeedSPFormula.empty())
  1435.                 return 0;
  1436.  
  1437.         CPoly poly;
  1438.         poly.SetStr(strNeedSPFormula.c_str());
  1439.  
  1440.         return int(ProcessFormula(&poly, fSkillPoint));
  1441. }
  1442.  
  1443. DWORD CPythonSkill::SSkillData::GetContinuationSP(float fSkillPoint)
  1444. {
  1445.         if (strContinuationSPFormula.empty())
  1446.                 return 0;
  1447.  
  1448.         CPoly poly;
  1449.         poly.SetStr(strContinuationSPFormula.c_str());
  1450.  
  1451.         return DWORD(ProcessFormula(&poly, fSkillPoint));
  1452. }
  1453.  
  1454. DWORD CPythonSkill::SSkillData::GetDuration(float fSkillPoint)
  1455. {
  1456.         if (strDuration.empty())
  1457.                 return 0;
  1458.  
  1459.         CPoly poly;
  1460.         poly.SetStr(strDuration.c_str());
  1461.  
  1462.         return DWORD(ProcessFormula(&poly, fSkillPoint));
  1463. }
  1464.  
  1465. CPythonSkill::SSkillData::SSkillData()
  1466. {
  1467.         byType = SKILL_TYPE_ACTIVE;
  1468.         byMaxLevel = 20;
  1469.         byLevelUpPoint = 1;
  1470.         dwSkillAttribute = 0;
  1471.         dwNeedWeapon = 0;
  1472.         dwTargetRange = 0;
  1473.         strCoolTimeFormula = "";
  1474.         strMotionLoopCountFormula = "";
  1475.         strNeedSPFormula = "";
  1476.         strContinuationSPFormula = "";
  1477.         isRequirement = FALSE;
  1478.         strRequireSkillName = "";
  1479.         byRequireSkillLevel = 0;
  1480.         strDuration = "";
  1481.         byLevelLimit = 0;
  1482.         bNoMotion = FALSE;
  1483.  
  1484.         strName = "";
  1485.         pImage = NULL;
  1486.  
  1487.         for (int j = 0; j < SKILL_GRADE_COUNT; ++j)
  1488.         {
  1489.                 TGradeData & rGradeData = GradeData[j];
  1490.                 rGradeData.strName = "";
  1491.                 rGradeData.pImage = NULL;
  1492.                 rGradeData.wMotionIndex = 0;
  1493.         }
  1494. }
  1495.  
  1496. ///////////////////////////////////////////////////////////////////////////////////////////////////
  1497. ///////////////////////////////////////////////////////////////////////////////////////////////////
  1498. ///////////////////////////////////////////////////////////////////////////////////////////////////
  1499.  
  1500. PyObject * skillSetPathName(PyObject * poSelf, PyObject * poArgs)
  1501. {
  1502.         char * szPathName;
  1503.         if (!PyTuple_GetString(poArgs, 0, &szPathName))
  1504.                 return Py_BadArgument();
  1505.  
  1506.         CPythonSkill::Instance().SetPathName(szPathName);
  1507.         return Py_BuildNone();
  1508. }
  1509.  
  1510. PyObject * skillRegisterSkill(PyObject * poSelf, PyObject * poArgs)
  1511. {
  1512.         int iSkillIndex;
  1513.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  1514.                 return Py_BadArgument();
  1515.         char * szFileName;
  1516.         if (!PyTuple_GetString(poArgs, 1, &szFileName))
  1517.                 return Py_BadArgument();
  1518.  
  1519.         std::string strFullFileName;
  1520.         strFullFileName = CPythonSkill::Instance().GetPathName();
  1521.         strFullFileName += szFileName;
  1522.  
  1523.         if (!CPythonSkill::Instance().RegisterSkill(iSkillIndex, strFullFileName.c_str()))
  1524.                 return Py_BuildException("skill.RegisterSkill - Failed to find skill data file : %d, %s", iSkillIndex, strFullFileName.c_str());
  1525.  
  1526.         return Py_BuildNone();
  1527. }
  1528.  
  1529. PyObject * skillLoadSkillData(PyObject * poSelf, PyObject * poArgs)
  1530. {
  1531.  
  1532.  
  1533.        
  1534.         return Py_BuildNone();
  1535. }
  1536.  
  1537. PyObject * skillRegisterSkillDesc(PyObject * poSelf, PyObject * poArgs)
  1538. {
  1539.         char * szFileName;
  1540.         if (!PyTuple_GetString(poArgs, 0, &szFileName))
  1541.                 return Py_BadArgument();
  1542.  
  1543.         if (!CPythonSkill::Instance().RegisterSkillDesc(szFileName))
  1544.                 return Py_BuildException("Failed to load Skill Desc");
  1545.  
  1546.         return Py_BuildNone();
  1547. }
  1548.  
  1549. PyObject * skillClearSkillData(PyObject * poSelf, PyObject * poArgs)
  1550. {
  1551.         CPythonSkill::SSkillData::ms_dwTimeIncreaseSkillNumber = 0;
  1552.         return Py_BuildNone();
  1553. }
  1554.  
  1555. PyObject * skillGetSkillName(PyObject * poSelf, PyObject * poArgs)
  1556. {
  1557.         int iSkillIndex;
  1558.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  1559.                 return Py_BadArgument();
  1560.  
  1561.         int iSkillGrade = -1;
  1562.         PyTuple_GetInteger(poArgs, 1, &iSkillGrade);
  1563.  
  1564.         CPythonSkill::SSkillData * c_pSkillData;
  1565.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  1566.                 return Py_BuildException("skill.GetSkillName - Failed to find skill by %d", iSkillIndex);
  1567.  
  1568.         if (iSkillGrade != -1)
  1569.         {
  1570. #ifdef ENABLE_SKILLS_LEVEL_OVER_P
  1571.                 if (iSkillGrade >= 0 && iSkillGrade <= CPythonSkill::SKILL_GRADE_COUNT)
  1572. #else
  1573.                 if (iSkillGrade >= 0 && iSkillGrade < CPythonSkill::SKILL_GRADE_COUNT)
  1574. #endif
  1575.                 {
  1576. #ifdef ENABLE_SKILLS_LEVEL_OVER_P
  1577.                         if (iSkillGrade >= 3)
  1578.                                 iSkillGrade = 2;
  1579. #endif
  1580.  
  1581.                         return Py_BuildValue("s", c_pSkillData->GradeData[iSkillGrade].strName.c_str());
  1582.                 }
  1583.         }
  1584.  
  1585.         return Py_BuildValue("s", c_pSkillData->strName.c_str());
  1586. }
  1587.  
  1588. PyObject * skillGetSkillDescription(PyObject * poSelf, PyObject * poArgs)
  1589. {
  1590.         int iSkillIndex;
  1591.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  1592.                 return Py_BadArgument();
  1593.  
  1594.         CPythonSkill::SSkillData * c_pSkillData;
  1595.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  1596.                 return Py_BuildException("skill.GetSkillDescription - Failed to find skill by %d", iSkillIndex);
  1597.  
  1598.         return Py_BuildValue("s", c_pSkillData->strDescription.c_str());
  1599. }
  1600.  
  1601. PyObject * skillGetSkillType(PyObject * poSelf, PyObject * poArgs)
  1602. {
  1603.         int iSkillIndex;
  1604.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  1605.                 return Py_BadArgument();
  1606.  
  1607.         CPythonSkill::SSkillData * c_pSkillData;
  1608.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  1609.                 return Py_BuildException("skill.GetSkillType - Failed to find skill by %d", iSkillIndex);
  1610.  
  1611.         return Py_BuildValue("i", c_pSkillData->byType);
  1612. }
  1613.  
  1614. PyObject * skillGetSkillConditionDescriptionCount(PyObject * poSelf, PyObject * poArgs)
  1615. {
  1616.         int iSkillIndex;
  1617.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  1618.                 return Py_BadArgument();
  1619.  
  1620.         CPythonSkill::SSkillData * c_pSkillData;
  1621.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  1622.                 return Py_BuildException("skill.GetSkillConditionDescriptionCount - Failed to find skill by %d", iSkillIndex);
  1623.  
  1624.         return Py_BuildValue("i", c_pSkillData->ConditionDataVector.size());
  1625. }
  1626.  
  1627. PyObject * skillGetSkillConditionDescription(PyObject * poSelf, PyObject * poArgs)
  1628. {
  1629.         int iSkillIndex;
  1630.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  1631.                 return Py_BadArgument();
  1632.  
  1633.         int iConditionIndex;
  1634.         if (!PyTuple_GetInteger(poArgs, 1, &iConditionIndex))
  1635.                 return Py_BadArgument();
  1636.  
  1637.         CPythonSkill::SSkillData * c_pSkillData;
  1638.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  1639.                 return Py_BuildException("skill.GetSkillConditionDescription() - Failed to find skill by %d", iSkillIndex);
  1640.  
  1641.         if (iConditionIndex >= c_pSkillData->ConditionDataVector.size())
  1642.                 return Py_BuildValue("None");
  1643.  
  1644.         return Py_BuildValue("s", c_pSkillData->ConditionDataVector[iConditionIndex].c_str());
  1645. }
  1646.  
  1647. PyObject * skillGetSkillAffectDescriptionCount(PyObject * poSelf, PyObject * poArgs)
  1648. {
  1649.         int iSkillIndex;
  1650.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  1651.                 return Py_BadArgument();
  1652.  
  1653.         CPythonSkill::SSkillData * c_pSkillData;
  1654.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  1655.                 return Py_BuildException("skill.GetSkillAffectDescriptionCount - Failed to find skill by %d", iSkillIndex);
  1656.  
  1657.         return Py_BuildValue("i", c_pSkillData->AffectDataVector.size());
  1658. }
  1659.  
  1660. PyObject * skillGetSkillAffectDescription(PyObject * poSelf, PyObject * poArgs)
  1661. {
  1662.         int iSkillIndex;
  1663.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  1664.                 return Py_BadArgument();
  1665.  
  1666.         int iAffectIndex;
  1667.         if (!PyTuple_GetInteger(poArgs, 1, &iAffectIndex))
  1668.                 return Py_BadArgument();
  1669.  
  1670.         float fSkillPoint;
  1671.         if (!PyTuple_GetFloat(poArgs, 2, &fSkillPoint))
  1672.                 return Py_BadArgument();
  1673.  
  1674.         CPythonSkill::SSkillData * c_pSkillData;
  1675.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  1676.                 return Py_BuildException("skill.GetSkillAffectDescription - Failed to find skill by %d", iSkillIndex);
  1677.  
  1678.         return Py_BuildValue("s", c_pSkillData->GetAffectDescription(iAffectIndex, fSkillPoint));
  1679. }
  1680.  
  1681. PyObject * skillGetSkillCoolTime(PyObject * poSelf, PyObject * poArgs)
  1682. {
  1683.         int iSkillIndex;
  1684.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  1685.                 return Py_BadArgument();
  1686.  
  1687.         float fSkillPoint;
  1688.         if (!PyTuple_GetFloat(poArgs, 1, &fSkillPoint))
  1689.                 return Py_BadArgument();
  1690.  
  1691.         CPythonSkill::SSkillData * c_pSkillData;
  1692.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  1693.                 return Py_BuildException("skill.GetSkillCoolTime - Failed to find skill by %d", iSkillIndex);
  1694.  
  1695.         return Py_BuildValue("i", c_pSkillData->GetSkillCoolTime(fSkillPoint));
  1696. }
  1697.  
  1698. PyObject * skillGetSkillNeedSP(PyObject * poSelf, PyObject * poArgs)
  1699. {
  1700.         int iSkillIndex;
  1701.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  1702.                 return Py_BadArgument();
  1703.  
  1704.         float fSkillPoint;
  1705.         if (!PyTuple_GetFloat(poArgs, 1, &fSkillPoint))
  1706.                 return Py_BadArgument();
  1707.  
  1708.         CPythonSkill::SSkillData * c_pSkillData;
  1709.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  1710.                 return Py_BuildException("skill.GetSkillNeedSP Failed to find skill by %d", iSkillIndex);
  1711.  
  1712.         return Py_BuildValue("i", c_pSkillData->GetNeedSP(fSkillPoint));
  1713. }
  1714.  
  1715. PyObject * skillGetSkillContinuationSP(PyObject * poSelf, PyObject * poArgs)
  1716. {
  1717.         int iSkillIndex;
  1718.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  1719.                 return Py_BadArgument();
  1720.  
  1721.         float fSkillPoint;
  1722.         if (!PyTuple_GetFloat(poArgs, 1, &fSkillPoint))
  1723.                 return Py_BadArgument();
  1724.  
  1725.         CPythonSkill::SSkillData * c_pSkillData;
  1726.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  1727.                 return Py_BuildException("skill.GetSkillContinuationSP - Failed to find skill by %d", iSkillIndex);
  1728.  
  1729.         return Py_BuildValue("i", c_pSkillData->GetContinuationSP(fSkillPoint));
  1730. }
  1731.  
  1732. PyObject * skillGetSkillMaxLevel(PyObject * poSelf, PyObject * poArgs)
  1733. {
  1734.         int iSkillIndex;
  1735.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  1736.                 return Py_BadArgument();
  1737.  
  1738.         CPythonSkill::SSkillData * c_pSkillData;
  1739.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  1740.                 return Py_BuildException("skill.GetSkillMaxLevel - Failed to find skill by %d", iSkillIndex);
  1741.  
  1742.         return Py_BuildValue("i", c_pSkillData->GetMaxLevel());
  1743. }
  1744.  
  1745. PyObject * skillGetSkillLevelUpPoint(PyObject * poSelf, PyObject * poArgs)
  1746. {
  1747.         int iSkillIndex;
  1748.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  1749.                 return Py_BadArgument();
  1750.  
  1751.         CPythonSkill::SSkillData * c_pSkillData;
  1752.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  1753.                 return Py_BuildException("skill.GetSkillLevelUpPoint - Failed to find skill by %d", iSkillIndex);
  1754.  
  1755.         return Py_BuildValue("i", c_pSkillData->GetLevelUpPoint());
  1756. }
  1757.  
  1758. PyObject * skillGetSkillLevelLimit(PyObject * poSelf, PyObject * poArgs)
  1759. {
  1760.         int iSkillIndex;
  1761.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  1762.                 return Py_BadArgument();
  1763.  
  1764.         CPythonSkill::SSkillData * c_pSkillData;
  1765.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  1766.                 return Py_BuildException("skill.GetSkillLevelLimit - Failed to find skill by %d", iSkillIndex);
  1767.  
  1768.         return Py_BuildValue("i", c_pSkillData->byLevelLimit);
  1769. }
  1770.  
  1771. PyObject * skillIsSkillRequirement(PyObject * poSelf, PyObject * poArgs)
  1772. {
  1773.         int iSkillIndex;
  1774.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  1775.                 return Py_BadArgument();
  1776.  
  1777.         CPythonSkill::SSkillData * c_pSkillData;
  1778.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  1779.                 return Py_BuildException("skill.IsSkillRequirement - Failed to find skill by %d", iSkillIndex);
  1780.  
  1781.         if (c_pSkillData->isRequirement)
  1782.         {
  1783.                 CPythonSkill::SSkillData * pRequireSkillData;
  1784.                 if (!CPythonSkill::Instance().GetSkillDataByName(c_pSkillData->strRequireSkillName.c_str(), &pRequireSkillData))
  1785.                 {
  1786.                         TraceError("skill.IsSkillRequirement - Failed to find skill : [%d/%s] can't find [%s]\n", c_pSkillData->dwSkillIndex, c_pSkillData->strName.c_str(), c_pSkillData->strRequireSkillName.c_str());
  1787.                         return Py_BuildValue("i", FALSE);
  1788.                 }
  1789.  
  1790.                 DWORD dwRequireSkillSlotIndex;
  1791.                 if (!CPythonPlayer::Instance().FindSkillSlotIndexBySkillIndex(pRequireSkillData->dwSkillIndex, &dwRequireSkillSlotIndex))
  1792.                         return Py_BuildValue("i", FALSE);
  1793.         }
  1794.  
  1795.         return Py_BuildValue("i", c_pSkillData->isRequirement);
  1796. }
  1797.  
  1798. PyObject * skillGetSkillRequirementData(PyObject * poSelf, PyObject * poArgs)
  1799. {
  1800.         int iSkillIndex;
  1801.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  1802.                 return Py_BadArgument();
  1803.  
  1804.         CPythonSkill::SSkillData * c_pSkillData;
  1805.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  1806.                 return Py_BuildException("skill.GetSkillRequirementData - Failed to find skill by %d", iSkillIndex);
  1807.  
  1808.         CPythonSkill::SSkillData * pRequireSkillData;
  1809.         if (!CPythonSkill::Instance().GetSkillDataByName(c_pSkillData->strRequireSkillName.c_str(), &pRequireSkillData))
  1810.                 return Py_BuildValue("si", 0, "None", 0);
  1811.  
  1812.         int ireqLevel = (int)ceil(float(c_pSkillData->byRequireSkillLevel) / float(max(1, pRequireSkillData->byLevelUpPoint)));
  1813.         return Py_BuildValue("si", c_pSkillData->strRequireSkillName.c_str(), ireqLevel);
  1814. }
  1815.  
  1816. PyObject * skillGetSkillRequireStatCount(PyObject * poSelf, PyObject * poArgs)
  1817. {
  1818.         int iSkillIndex;
  1819.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  1820.                 return Py_BadArgument();
  1821.  
  1822.         CPythonSkill::SSkillData * c_pSkillData;
  1823.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  1824.                 return Py_BuildException("skill.GetSkillRequireStatCount - Failed to find skill by %d", iSkillIndex);
  1825.  
  1826.         return Py_BuildValue("i", c_pSkillData->RequireStatDataVector.size());
  1827. }
  1828.  
  1829. PyObject * skillGetSkillRequireStatData(PyObject * poSelf, PyObject * poArgs)
  1830. {
  1831.         int iSkillIndex;
  1832.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  1833.                 return Py_BadArgument();
  1834.         int iStatIndex;
  1835.         if (!PyTuple_GetInteger(poArgs, 1, &iStatIndex))
  1836.                 return Py_BadArgument();
  1837.  
  1838.         CPythonSkill::SSkillData * c_pSkillData;
  1839.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  1840.                 return Py_BuildException("skill.GetSkillRequireStatData - Failed to find skill by %d", iSkillIndex);
  1841.  
  1842.         if (iStatIndex >= c_pSkillData->RequireStatDataVector.size())
  1843.                 return Py_BuildValue("ii", 0, 0);
  1844.  
  1845.         const CPythonSkill::TRequireStatData & c_rRequireStatData = c_pSkillData->RequireStatDataVector[iStatIndex];
  1846.  
  1847.         return Py_BuildValue("ii", c_rRequireStatData.byPoint, c_rRequireStatData.byLevel);
  1848. }
  1849.  
  1850. PyObject * skillCanLevelUpSkill(PyObject * poSelf, PyObject * poArgs)
  1851. {
  1852.         int iSkillIndex;
  1853.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  1854.                 return Py_BadArgument();
  1855.         int iSkillLevel;
  1856.         if (!PyTuple_GetInteger(poArgs, 1, &iSkillLevel))
  1857.                 return Py_BadArgument();
  1858.  
  1859.         CPythonSkill::SSkillData * c_pSkillData;
  1860.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  1861.                 return Py_BuildException("skill.CanLevelUpSkill - Failed to find skill by %d", iSkillIndex);
  1862.  
  1863.         if (iSkillLevel >= c_pSkillData->GetMaxLevel())
  1864.                 return Py_BuildValue("i", FALSE);
  1865.  
  1866.         if (c_pSkillData->isRequirement)
  1867.         {
  1868.                 CPythonSkill::SSkillData * pRequireSkillData;
  1869.                 if (CPythonSkill::Instance().GetSkillDataByName(c_pSkillData->strRequireSkillName.c_str(), &pRequireSkillData))
  1870.                 {
  1871.                         DWORD dwRequireSkillSlotIndex;
  1872.                         if (CPythonPlayer::Instance().FindSkillSlotIndexBySkillIndex(pRequireSkillData->dwSkillIndex, &dwRequireSkillSlotIndex))
  1873.                         {
  1874.                                 int iSkillGrade = CPythonPlayer::Instance().GetSkillGrade(dwRequireSkillSlotIndex);
  1875.                                 int iSkillLevel = CPythonPlayer::Instance().GetSkillLevel(dwRequireSkillSlotIndex);
  1876.                                 if (iSkillGrade <= 0)
  1877.                                 if (iSkillLevel < c_pSkillData->byRequireSkillLevel)
  1878.                                         return Py_BuildValue("i", FALSE);
  1879.                         }
  1880.                 }
  1881.         }
  1882.  
  1883.         for (DWORD i = 0; i < c_pSkillData->RequireStatDataVector.size(); ++i)
  1884.         {
  1885.                 const CPythonSkill::TRequireStatData & c_rRequireStatData = c_pSkillData->RequireStatDataVector[i];
  1886.                 if (CPythonPlayer::Instance().GetStatus(c_rRequireStatData.byPoint) < c_rRequireStatData.byLevel)
  1887.                         return Py_BuildValue("i", FALSE);
  1888.         }
  1889.  
  1890.         if (0 != (c_pSkillData->dwSkillAttribute & CPythonSkill::SKILL_ATTRIBUTE_CANNOT_LEVEL_UP))
  1891.                 return Py_BuildValue("i", FALSE);
  1892.  
  1893.         return Py_BuildValue("i", TRUE);
  1894. }
  1895.  
  1896. PyObject * skillCheckRequirementSueccess(PyObject * poSelf, PyObject * poArgs)
  1897. {
  1898.         int iSkillIndex;
  1899.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  1900.                 return Py_BadArgument();
  1901.  
  1902.         CPythonSkill::SSkillData * c_pSkillData;
  1903.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  1904.                 return Py_BuildException("skill.CheckRequirementSueccess - Failed to find skill by %d", iSkillIndex);
  1905.  
  1906.         if (c_pSkillData->isRequirement)
  1907.         {
  1908.                 CPythonSkill::SSkillData * pRequireSkillData;
  1909.                 if (CPythonSkill::Instance().GetSkillDataByName(c_pSkillData->strRequireSkillName.c_str(), &pRequireSkillData))
  1910.                 {
  1911.                         DWORD dwRequireSkillSlotIndex;
  1912.                         if (CPythonPlayer::Instance().FindSkillSlotIndexBySkillIndex(pRequireSkillData->dwSkillIndex, &dwRequireSkillSlotIndex))
  1913.                         {
  1914.                                 int iSkillGrade = CPythonPlayer::Instance().GetSkillGrade(dwRequireSkillSlotIndex);
  1915.                                 int iSkillLevel = CPythonPlayer::Instance().GetSkillLevel(dwRequireSkillSlotIndex);
  1916.                                 if (iSkillGrade <= 0)
  1917.                                 if (iSkillLevel < c_pSkillData->byRequireSkillLevel)
  1918.                                         return Py_BuildValue("i", FALSE);
  1919.                         }
  1920.                 }
  1921.         }
  1922.  
  1923.         return Py_BuildValue("i", TRUE);
  1924. }
  1925.  
  1926. PyObject * skillGetNeedCharacterLevel(PyObject * poSelf, PyObject * poArgs)
  1927. {
  1928.         int iSkillIndex;
  1929.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  1930.                 return Py_BadArgument();
  1931.  
  1932.         CPythonSkill::SSkillData * c_pSkillData;
  1933.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  1934.                 return Py_BuildException("skill.GetNeedCharacterLevel - Failed to find skill by %d", iSkillIndex);
  1935.  
  1936.         std::vector<CPythonSkill::TRequireStatData>::iterator itor = c_pSkillData->RequireStatDataVector.begin();
  1937.         for (; itor != c_pSkillData->RequireStatDataVector.end(); ++itor)
  1938.         {
  1939.                 const CPythonSkill::TRequireStatData & c_rRequireStatData = *itor;
  1940.  
  1941.                 if (POINT_LEVEL == c_rRequireStatData.byPoint)
  1942.                         return Py_BuildValue("i", c_rRequireStatData.byLevel);
  1943.         }
  1944.  
  1945.         return Py_BuildValue("i", 0);
  1946. }
  1947.  
  1948. PyObject * skillIsToggleSkill(PyObject * poSelf, PyObject * poArgs)
  1949. {
  1950.         int iSkillIndex;
  1951.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  1952.                 return Py_BadArgument();
  1953.  
  1954.         CPythonSkill::SSkillData * c_pSkillData;
  1955.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  1956.                 return Py_BuildException("skill.IsToggleSkill - Failed to find skill by %d", iSkillIndex);
  1957.  
  1958.         return Py_BuildValue("i", c_pSkillData->IsToggleSkill());
  1959. }
  1960.  
  1961. PyObject * skillIsUseHPSkill(PyObject * poSelf, PyObject * poArgs)
  1962. {
  1963.         int iSkillIndex;
  1964.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  1965.                 return Py_BadArgument();
  1966.  
  1967.         CPythonSkill::SSkillData * c_pSkillData;
  1968.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  1969.                 return Py_BuildException("skill.IsUseHPSkill - Failed to find skill by %d", iSkillIndex);
  1970.  
  1971.         return Py_BuildValue("i", c_pSkillData->IsUseHPSkill());
  1972. }
  1973.  
  1974. PyObject * skillIsStandingSkill(PyObject * poSelf, PyObject * poArgs)
  1975. {
  1976.         int iSkillIndex;
  1977.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  1978.                 return Py_BadArgument();
  1979.  
  1980.         CPythonSkill::SSkillData * c_pSkillData;
  1981.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  1982.                 return Py_BuildException("skill.IsStandingSkill - Failed to find skill by %d", iSkillIndex);
  1983.  
  1984.         return Py_BuildValue("i", c_pSkillData->IsStandingSkill());
  1985. }
  1986.  
  1987. PyObject * skillCanUseSkill(PyObject * poSelf, PyObject * poArgs)
  1988. {
  1989.         int iSkillIndex;
  1990.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  1991.                 return Py_BadArgument();
  1992.  
  1993.         CPythonSkill::SSkillData * c_pSkillData;
  1994.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  1995.                 return Py_BuildException("skill.CanUseSkill - Failed to find skill by %d", iSkillIndex);
  1996.  
  1997.         return Py_BuildValue("i", c_pSkillData->IsCanUseSkill());
  1998. }
  1999.  
  2000. PyObject * skillIsLevelUpSkill(PyObject * poSelf, PyObject * poArgs)
  2001. {
  2002.         int iSkillIndex;
  2003.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  2004.                 return Py_BadArgument();
  2005.  
  2006.         CPythonSkill::SSkillData * c_pSkillData;
  2007.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  2008.                 return Py_BuildException("skill.IsLevelUpSkill - Failed to find skill by %d", iSkillIndex);
  2009.  
  2010.         // 모두 레벨업 가능
  2011.  
  2012.         return Py_BuildValue("i", TRUE);
  2013. }
  2014.  
  2015. PyObject * skillGetIconName(PyObject * poSelf, PyObject * poArgs)
  2016. {
  2017.         int iSkillIndex;
  2018.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  2019.                 return Py_BadArgument();
  2020.  
  2021.         CPythonSkill::SSkillData * c_pSkillData;
  2022.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  2023.                 return Py_BuildValue("s", "");
  2024.  
  2025.         return Py_BuildValue("s", c_pSkillData->strIconFileName.c_str());
  2026. }
  2027.  
  2028. PyObject * skillGetIconImage(PyObject * poSelf, PyObject * poArgs)
  2029. {
  2030.         int iSkillIndex;
  2031.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  2032.                 return Py_BadArgument();
  2033.  
  2034.         CPythonSkill::SSkillData * c_pSkillData;
  2035.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  2036.                 return Py_BuildValue("i", 0);   // 익셉션을 내는 대신 0을 리턴한다.
  2037.  
  2038.         return Py_BuildValue("i", c_pSkillData->pImage);
  2039. }
  2040.  
  2041.  
  2042.  
  2043. PyObject * skillGetIconInstance(PyObject * poSelf, PyObject * poArgs)
  2044. {
  2045.         int iSkillIndex;
  2046.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  2047.                 return Py_BadArgument();
  2048.  
  2049.         CPythonSkill::SSkillData * c_pSkillData;
  2050.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  2051.                 return Py_BuildException("skill.GetIconInstance - Failed to find skill by %d", iSkillIndex);
  2052.  
  2053.         CGraphicImageInstance * pImageInstance = CGraphicImageInstance::New();
  2054.         pImageInstance->SetImagePointer(c_pSkillData->pImage);
  2055.  
  2056.         return Py_BuildValue("i", pImageInstance);
  2057. }
  2058.  
  2059. PyObject * skillGetIconImageNew(PyObject * poSelf, PyObject * poArgs)
  2060. {
  2061.         int iSkillIndex;
  2062.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  2063.                 return Py_BadArgument();
  2064.  
  2065.         int iGradeIndex;
  2066.         if (!PyTuple_GetInteger(poArgs, 1, &iGradeIndex))
  2067.                 return Py_BadArgument();
  2068.  
  2069.         CPythonSkill::SSkillData * c_pSkillData;
  2070.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  2071.                 return Py_BuildValue("i", 0);   // 익셉션을 내는 대신 0을 리턴한다.
  2072.  
  2073.         if (iGradeIndex < 0)
  2074.                 iGradeIndex = 0;
  2075.        
  2076.         if (iGradeIndex >= CPythonSkill::SKILL_GRADE_COUNT)            
  2077.                 iGradeIndex = CPythonSkill::SKILL_GRADE_COUNT-1;
  2078.  
  2079.         return Py_BuildValue("i", c_pSkillData->GradeData[iGradeIndex].pImage);
  2080. }
  2081.  
  2082. PyObject * skillGetIconInstanceNew(PyObject * poSelf, PyObject * poArgs)
  2083. {
  2084.         int iSkillIndex;
  2085.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  2086.                 return Py_BadArgument();
  2087.  
  2088.         int iGradeIndex;
  2089.         if (!PyTuple_GetInteger(poArgs, 1, &iGradeIndex))
  2090.                 return Py_BadArgument();
  2091.  
  2092.         CPythonSkill::SSkillData * c_pSkillData;
  2093.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  2094.                 return Py_BuildException("skill.GetIconInstanceNew - Failed to find skill by %d", iSkillIndex);
  2095.  
  2096.         //CGraphicImage * pImage = c_pSkillData->pImage;
  2097.  
  2098.         if (iGradeIndex < 0)
  2099.                 iGradeIndex = 0;
  2100.        
  2101.         if (iGradeIndex >= CPythonSkill::SKILL_GRADE_COUNT)            
  2102.                 iGradeIndex = CPythonSkill::SKILL_GRADE_COUNT-1;
  2103.  
  2104.         CGraphicImageInstance * pImageInstance = CGraphicImageInstance::New();
  2105.         pImageInstance->SetImagePointer(c_pSkillData->GradeData[iGradeIndex].pImage);
  2106.  
  2107.         return Py_BuildValue("i", pImageInstance);
  2108. }
  2109.  
  2110. PyObject * skillDeleteIconInstance(PyObject * poSelf, PyObject * poArgs)
  2111. {
  2112.         int iHandle;
  2113.         if (!PyTuple_GetInteger(poArgs, 0, &iHandle))
  2114.                 return Py_BadArgument();
  2115.  
  2116.         CGraphicImageInstance::Delete((CGraphicImageInstance *) iHandle);
  2117.         return Py_BuildNone();
  2118. }
  2119.  
  2120. PyObject * skillGetGradeData(PyObject * poSelf, PyObject * poArgs)
  2121. {
  2122.         int iSkillIndex;
  2123.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  2124.                 return Py_BadArgument();
  2125.  
  2126.         int iGradeIndex;
  2127.         if (!PyTuple_GetInteger(poArgs, 1, &iGradeIndex))
  2128.                 return Py_BadArgument();
  2129.  
  2130.         CPythonSkill::SSkillData * c_pSkillData;
  2131.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  2132.                 return Py_BuildException("skill.GetGradeData - Failed to find skill by %d", iSkillIndex);
  2133.  
  2134.         if (iGradeIndex < 0 || iGradeIndex >= CPythonSkill::SKILL_GRADE_COUNT)
  2135.                 return Py_BuildException("Strange grade index [%d]", iSkillIndex, iGradeIndex);
  2136.  
  2137.         return Py_BuildValue("i", c_pSkillData->GradeData[iGradeIndex]);
  2138. }
  2139.  
  2140. PyObject * skillGetNewAffectDataCount(PyObject * poSelf, PyObject * poArgs)
  2141. {
  2142.         int iSkillIndex;
  2143.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  2144.                 return Py_BadArgument();
  2145.  
  2146.         CPythonSkill::SSkillData * c_pSkillData;
  2147.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  2148.                 return Py_BuildException("skill.GetNewAffectDataCount - Failed to find skill by %d", iSkillIndex);
  2149.  
  2150.         return Py_BuildValue("i", c_pSkillData->AffectDataNewVector.size());
  2151. }
  2152.  
  2153. PyObject * skillGetNewAffectData(PyObject * poSelf, PyObject * poArgs)
  2154. {
  2155.         int iSkillIndex;
  2156.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  2157.                 return Py_BadArgument();
  2158.         int iAffectIndex;
  2159.         if (!PyTuple_GetInteger(poArgs, 1, &iAffectIndex))
  2160.                 return Py_BadArgument();
  2161.         float fSkillLevel;
  2162.         if (!PyTuple_GetFloat(poArgs, 2, &fSkillLevel))
  2163.                 return Py_BadArgument();
  2164.  
  2165.         CPythonSkill::SSkillData * pSkillData;
  2166.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &pSkillData))
  2167.                 return Py_BuildException("skill.GetNewAffectData - Failed to find skill by %d", iSkillIndex);
  2168.  
  2169.         if (iAffectIndex < 0 || iAffectIndex >= pSkillData->AffectDataNewVector.size())
  2170.                 return Py_BuildException(" skill.GetNewAffectData - Strange AffectIndex %d", iAffectIndex);
  2171.  
  2172.         CPythonSkill::TAffectDataNew & rAffectData = pSkillData->AffectDataNewVector[iAffectIndex];
  2173.  
  2174.         CPoly minPoly;
  2175.         CPoly maxPoly;
  2176.         minPoly.SetRandom(CPoly::RANDOM_TYPE_FORCE_MIN);
  2177.         maxPoly.SetRandom(CPoly::RANDOM_TYPE_FORCE_MAX);
  2178.         minPoly.SetStr(rAffectData.strPointPoly.c_str());
  2179.         maxPoly.SetStr(rAffectData.strPointPoly.c_str());
  2180.         float fMinValue = pSkillData->ProcessFormula(&minPoly, fSkillLevel, CPythonSkill::VALUE_TYPE_MIN);
  2181.         float fMaxValue = pSkillData->ProcessFormula(&maxPoly, fSkillLevel, CPythonSkill::VALUE_TYPE_MAX);
  2182.  
  2183.         return Py_BuildValue("sff", rAffectData.strPointType.c_str(), fMinValue, fMaxValue);
  2184. }
  2185.  
  2186. PyObject * skillGetDuration(PyObject * poSelf, PyObject * poArgs)
  2187. {
  2188.         int iSkillIndex;
  2189.         if (!PyTuple_GetInteger(poArgs, 0, &iSkillIndex))
  2190.                 return Py_BadArgument();
  2191.         float fSkillLevel;
  2192.         if (!PyTuple_GetFloat(poArgs, 1, &fSkillLevel))
  2193.                 return Py_BadArgument();
  2194.  
  2195.         CPythonSkill::SSkillData * c_pSkillData;
  2196.         if (!CPythonSkill::Instance().GetSkillData(iSkillIndex, &c_pSkillData))
  2197.                 return Py_BuildException("skill.GetDuration - Failed to find skill by %d", iSkillIndex);
  2198.  
  2199.         return Py_BuildValue("i", c_pSkillData->GetDuration(fSkillLevel));
  2200. }
  2201.  
  2202. PyObject * skillTEST(PyObject * poSelf, PyObject * poArgs)
  2203. {
  2204.         CPythonSkill::Instance().TEST();
  2205.         return Py_BuildNone();
  2206. }
  2207.  
  2208. void initskill()
  2209. {
  2210.         static PyMethodDef s_methods[] =
  2211.         {
  2212.                 { "SetPathName",                                        skillSetPathName,                                               METH_VARARGS },
  2213.                 { "RegisterSkill",                                      skillRegisterSkill,                                             METH_VARARGS },
  2214.                 { "LoadSkillData",                                      skillLoadSkillData,                                             METH_VARARGS },
  2215.                 { "ClearSkillData",                                     skillClearSkillData,                                    METH_VARARGS },
  2216.  
  2217.                 /////
  2218.  
  2219.                 { "GetSkillName",                                                       skillGetSkillName,                                                      METH_VARARGS },
  2220.                 { "GetSkillDescription",                                        skillGetSkillDescription,                                       METH_VARARGS },
  2221.                 { "GetSkillType",                                                       skillGetSkillType,                                                      METH_VARARGS },
  2222.                 { "GetSkillConditionDescriptionCount",          skillGetSkillConditionDescriptionCount,         METH_VARARGS },
  2223.                 { "GetSkillConditionDescription",                       skillGetSkillConditionDescription,                      METH_VARARGS },
  2224.                 { "GetSkillAffectDescriptionCount",                     skillGetSkillAffectDescriptionCount,            METH_VARARGS },
  2225.                 { "GetSkillAffectDescription",                          skillGetSkillAffectDescription,                         METH_VARARGS },
  2226.                 { "GetSkillCoolTime",                                           skillGetSkillCoolTime,                                          METH_VARARGS },
  2227.                 { "GetSkillNeedSP",                                                     skillGetSkillNeedSP,                                            METH_VARARGS },
  2228.                 { "GetSkillContinuationSP",                                     skillGetSkillContinuationSP,                            METH_VARARGS },
  2229.                 { "GetSkillMaxLevel",                                           skillGetSkillMaxLevel,                                          METH_VARARGS },
  2230.                 { "GetSkillLevelUpPoint",                                       skillGetSkillLevelUpPoint,                                      METH_VARARGS },
  2231.                 { "GetSkillLevelLimit",                                         skillGetSkillLevelLimit,                                        METH_VARARGS },
  2232.                 { "IsSkillRequirement",                                         skillIsSkillRequirement,                                        METH_VARARGS },
  2233.                 { "GetSkillRequirementData",                            skillGetSkillRequirementData,                           METH_VARARGS },
  2234.                 { "GetSkillRequireStatCount",                           skillGetSkillRequireStatCount,                          METH_VARARGS },
  2235.                 { "GetSkillRequireStatData",                            skillGetSkillRequireStatData,                           METH_VARARGS },
  2236.                 { "CanLevelUpSkill",                                            skillCanLevelUpSkill,                                           METH_VARARGS },
  2237.                 { "IsLevelUpSkill",                                                     skillIsLevelUpSkill,                                            METH_VARARGS },
  2238.                 { "CheckRequirementSueccess",                           skillCheckRequirementSueccess,                          METH_VARARGS },
  2239.                 { "GetNeedCharacterLevel",                                      skillGetNeedCharacterLevel,                                     METH_VARARGS },
  2240.                 { "IsToggleSkill",                                                      skillIsToggleSkill,                                                     METH_VARARGS },
  2241.                 { "IsUseHPSkill",                                                       skillIsUseHPSkill,                                                      METH_VARARGS },
  2242.                 { "IsStandingSkill",                                            skillIsStandingSkill,                                           METH_VARARGS },
  2243.                 { "CanUseSkill",                                                        skillCanUseSkill,                                                       METH_VARARGS },
  2244.                 { "GetIconName",                                                        skillGetIconName,                                                       METH_VARARGS },
  2245.                 { "GetIconImage",                                                       skillGetIconImage,                                                      METH_VARARGS },
  2246.                 { "GetIconImageNew",                                            skillGetIconImageNew,                                           METH_VARARGS },
  2247.                 { "GetIconInstance",                                            skillGetIconInstance,                                           METH_VARARGS },
  2248.                 { "GetIconInstanceNew",                                         skillGetIconInstanceNew,                                        METH_VARARGS },
  2249.                 { "DeleteIconInstance",                                         skillDeleteIconInstance,                                        METH_VARARGS },
  2250.                 { "GetGradeData",                                                       skillGetGradeData,                                                      METH_VARARGS },
  2251.  
  2252.                 { "GetNewAffectDataCount",                                      skillGetNewAffectDataCount,                                     METH_VARARGS },
  2253.                 { "GetNewAffectData",                                           skillGetNewAffectData,                                          METH_VARARGS },
  2254.                 { "GetDuration",                                                        skillGetDuration,                                                       METH_VARARGS },
  2255.  
  2256.                 { "TEST",                                                                       skillTEST,                                                                      METH_VARARGS },
  2257.  
  2258.                 { NULL,                                                                         NULL,                                                                           NULL },
  2259.         };
  2260.        
  2261. #ifdef PYTHON_DYNAMIC_MODULE_NAME
  2262.         PyObject* poModule = Py_InitModule(GetModuleName(SKILL_MODULE).c_str(), s_methods);
  2263. #else
  2264.         PyObject* poModule = Py_InitModule("skill", s_methods);
  2265. #endif
  2266.  
  2267.         PyModule_AddIntConstant(poModule, "SKILL_TYPE_NONE",    CPythonSkill::SKILL_TYPE_NONE);
  2268.         PyModule_AddIntConstant(poModule, "SKILL_TYPE_ACTIVE",  CPythonSkill::SKILL_TYPE_ACTIVE);
  2269.         PyModule_AddIntConstant(poModule, "SKILL_TYPE_SUPPORT", CPythonSkill::SKILL_TYPE_SUPPORT);
  2270.         PyModule_AddIntConstant(poModule, "SKILL_TYPE_GUILD",   CPythonSkill::SKILL_TYPE_GUILD);
  2271.         PyModule_AddIntConstant(poModule, "SKILL_TYPE_HORSE",   CPythonSkill::SKILL_TYPE_HORSE);
  2272.         PyModule_AddIntConstant(poModule, "SKILL_TYPE_MAX_NUM", CPythonSkill::SKILL_TYPE_MAX_NUM);
  2273.  
  2274.         PyModule_AddIntConstant(poModule, "SKILL_GRADE_COUNT",          CPythonSkill::SKILL_GRADE_COUNT);
  2275.         PyModule_AddIntConstant(poModule, "SKILL_GRADE_STEP_COUNT",     CPythonSkill::SKILL_GRADE_STEP_COUNT);
  2276.         PyModule_AddIntConstant(poModule, "SKILL_GRADEGAP",                     CPythonSkill::SKILL_GRADEGAP);
  2277.         PyModule_AddIntConstant(poModule, "SKILL_EFFECT_COUNT",         CPythonSkill::SKILL_EFFECT_COUNT);
  2278. }
  2279.