diff --git a/src/engine/N3Base/N3FXBundle.cpp b/src/engine/N3Base/N3FXBundle.cpp index b3aa1600..0f5e57cd 100644 --- a/src/engine/N3Base/N3FXBundle.cpp +++ b/src/engine/N3Base/N3FXBundle.cpp @@ -457,6 +457,15 @@ bool CN3FXBundle::Load(HANDLE hFile) { ReadFile(hFile, &m_bStatic, sizeof(bool), &dwRWC, NULL); } + if (m_iVersion == 3) { + ReadFile(hFile, &m_bEarthQuake, sizeof(bool), &dwRWC, NULL); + if (m_bEarthQuake) { + ReadFile(hFile, &m_fEarthQuakeStartTime, sizeof(float), &dwRWC, NULL); + } else { + m_fEarthQuakeStartTime = 0; + } + } + return true; } diff --git a/src/engine/N3Base/N3FXBundle.h b/src/engine/N3Base/N3FXBundle.h index 039e2511..c2fd1ecc 100644 --- a/src/engine/N3Base/N3FXBundle.h +++ b/src/engine/N3Base/N3FXBundle.h @@ -37,6 +37,8 @@ class CN3FXBundle : public CN3BaseFileAccess { int m_iSourceJoint; bool m_bDependScale; + bool m_bEarthQuake; // Needs Implementation + float m_fEarthQuakeStartTime; // Needs Implementation //__Vector3 m_vTargetScale; float m_fTargetScale; diff --git a/src/engine/N3Base/N3FXPartBillBoard.cpp b/src/engine/N3Base/N3FXPartBillBoard.cpp index 3275c962..2ac07fbb 100644 --- a/src/engine/N3Base/N3FXPartBillBoard.cpp +++ b/src/engine/N3Base/N3FXPartBillBoard.cpp @@ -200,6 +200,14 @@ bool CN3FXPartBillBoard::Load(HANDLE hFile) { ReadFile(hFile, &m_mtxRot, sizeof(m_mtxRot), &dwRWC, NULL); } + if (m_iVersion >= 6) { + ReadFile(hFile, &m_bRotationRate, sizeof(bool), &dwRWC, NULL); + } + + if (m_iVersion >= 7) { + ReadFile(hFile, &m_bOnScreen, sizeof(bool), &dwRWC, NULL); // is this on screen bool? + } + CreateVB(); Init(); diff --git a/src/engine/N3Base/N3FXPartBillBoard.h b/src/engine/N3Base/N3FXPartBillBoard.h index 6fa23584..01a63fff 100644 --- a/src/engine/N3Base/N3FXPartBillBoard.h +++ b/src/engine/N3Base/N3FXPartBillBoard.h @@ -38,6 +38,8 @@ class CN3FXPartBillBoard : public CN3FXPartBase { float m_fRotBillBoardY; float m_fRotBillBoardZ; + bool m_bRotationRate; // Needs Implementation + bool m_bOnScreen; // Needs Implementation protected: __Vector3 m_vUnit[4]; diff --git a/src/engine/N3Base/N3FXPartMesh.cpp b/src/engine/N3Base/N3FXPartMesh.cpp index 6ff0acf1..f140d17d 100644 --- a/src/engine/N3Base/N3FXPartMesh.cpp +++ b/src/engine/N3Base/N3FXPartMesh.cpp @@ -228,6 +228,10 @@ bool CN3FXPartMesh::Load(HANDLE hFile) { ReadFile(hFile, &m_vUnitScale, sizeof(__Vector3), &dwRWC, NULL); } + if (m_iVersion == 6) { + ReadFile(hFile, &m_bShapeLoop, sizeof(bool), &dwRWC, NULL); //? true true false + } + if (m_pShape) { for (int i = 0; i < m_pShape->PartCount(); i++) { m_pShape->Part(i)->m_fTexFPS = m_fTexFPS; diff --git a/src/engine/N3Base/N3FXPartMesh.h b/src/engine/N3Base/N3FXPartMesh.h index a56f3352..ddbd0751 100644 --- a/src/engine/N3Base/N3FXPartMesh.h +++ b/src/engine/N3Base/N3FXPartMesh.h @@ -27,6 +27,7 @@ class CN3FXPartMesh : public CN3FXPartBase { bool m_bTexLoop; float m_fMeshFPS; + bool m_bShapeLoop; // Needs Implementation protected: bool IsDead(); diff --git a/src/engine/N3Base/N3FXPartParticles.cpp b/src/engine/N3Base/N3FXPartParticles.cpp index 125e3c11..75e0be6b 100644 --- a/src/engine/N3Base/N3FXPartParticles.cpp +++ b/src/engine/N3Base/N3FXPartParticles.cpp @@ -415,6 +415,22 @@ bool CN3FXPartParticles::Load(HANDLE hFile) { ReadFile(hFile, &m_fScaleVelY, sizeof(float), &dwRWC, NULL); } + if (m_iVersion >= 6) { + ReadFile(hFile, &m_bDistanceNumFix, sizeof(bool), &dwRWC, NULL); + } + if (m_iVersion >= 7) { + ReadFile(hFile, &m_bParticleYAxisFix, sizeof(bool), &dwRWC, NULL); + } + + if (m_iVersion >= 8) { + /* + ReadFile(hFile, &m_bParticle_Not_Rot, sizeof(bool), &dwRWC, NULL); + ReadFile(hFile, &m_vParticle_Not_Rot, sizeof(__Vector3), &dwRWC, NULL); + ReadFile(hFile, &m_fPtRangeMin, sizeof(float), &dwRWC, NULL); + ReadFile(hFile, &m_fPtRangeMax, sizeof(float), &dwRWC, NULL); + */ + } + Init(); return true; @@ -1287,7 +1303,7 @@ void CN3FXPartParticles::Duplicate(CN3FXPartParticles * pSrc) { if (m_dwEmitType == FX_PART_PARTICLE_EMIT_TYPE_SPREAD) { m_uEmitCon.fEmitAngle = pSrc->m_uEmitCon.fEmitAngle; } else if (m_dwEmitType == FX_PART_PARTICLE_EMIT_TYPE_GATHER) { - m_uEmitCon.vGatherPoint = m_uEmitCon.vGatherPoint; + m_uEmitCon.vGatherPoint = pSrc->m_uEmitCon.vGatherPoint; } m_vPtEmitDir = pSrc->m_vPtEmitDir; diff --git a/src/engine/N3Base/N3FXPartParticles.h b/src/engine/N3Base/N3FXPartParticles.h index 0b75c2f9..77d8a29a 100644 --- a/src/engine/N3Base/N3FXPartParticles.h +++ b/src/engine/N3Base/N3FXPartParticles.h @@ -68,6 +68,9 @@ class CN3FXPartParticles : public CN3FXPartBase { float m_fScaleVelX; float m_fScaleVelY; + bool m_bDistanceNumFix; // Needs Implementation + bool m_bParticleYAxisFix; // Needs Implementation + protected: void Rotate(); void Scaling(); diff --git a/src/engine/N3Base/N3ShapeMgr.cpp b/src/engine/N3Base/N3ShapeMgr.cpp index fd19144b..ad8a68eb 100644 --- a/src/engine/N3Base/N3ShapeMgr.cpp +++ b/src/engine/N3Base/N3ShapeMgr.cpp @@ -90,7 +90,12 @@ void CN3ShapeMgr::ReleaseShapes() { bool CN3ShapeMgr::Load(HANDLE hFile) { DWORD dwRWC; int nL = 0; - + int TempVersion, TempIntStringLength; + ReadFile(hFile, &(TempVersion), sizeof(int), &dwRWC, NULL); // Read the map version + ReadFile(hFile, &(TempIntStringLength), sizeof(int), &dwRWC, NULL); // Read the map name char length + CHAR * TempOPDMapNamebuffer = new CHAR[TempIntStringLength / sizeof(char) + 1]{}; // Zero-initialized + ReadFile(hFile, TempOPDMapNamebuffer, TempIntStringLength, &dwRWC, NULL); // Now read it and push it back to the OPDMapName char buffer + if (false == LoadCollisionData(hFile)) { return false; } diff --git a/src/game/GameDef.h b/src/game/GameDef.h index 61af78fb..304f24ff 100644 --- a/src/game/GameDef.h +++ b/src/game/GameDef.h @@ -1055,7 +1055,11 @@ typedef struct __TABLE_PLAYER_LOOKS // NPC, Mob std::string szName; // ij¸¯ÅÍ À̸§ std::string szJointFN; // °üÀý ÆÄÀÏ À̸§ std::string szAniFN; // ¿¡´Ï¸ÞÀÌ¼Ç ÆÄÀÏ À̸§ - std::string szPartFNs[7]; // °¢ Character Part - »óü, ÇÏü, ¸Ó¸®, ÆÈ, ´Ù¸®, ¸Ó¸®Ä«¶ô, ¸ÁÅä + std::string szPartFNs[10]; // °¢ Character Part - »óü, ÇÏü, ¸Ó¸®, ÆÈ, ´Ù¸®, ¸Ó¸®Ä«¶ô, ¸ÁÅä + std::string skipn3cskin0; + std::string skipn3char0; + std::string skipFXPlug; + int iunknownplooks0; int iJointRH; // ¿À¸¥¼Õ ³¡ °üÀý¹øÈ£ int iJointLH; // ¿Þ¼Õ ³¡ °üÀý¹øÈ£ @@ -1072,7 +1076,12 @@ typedef struct __TABLE_PLAYER_LOOKS // NPC, Mob int iSndID_Breathe0; int iSndID_Breathe1; int iSndID_Reserved0; + int iunknownplooks1; // not sure if this one is supposed to be here int iSndID_Reserved1; + int iunknownplooks2; // not sure if this one is supposed to be here + BYTE byunknownplooks1; + BYTE byunknownplooks2; + BYTE byunknownplooks3; } TABLE_PLAYER; typedef struct __TABLE_EXCHANGE_QUEST { @@ -1129,11 +1138,13 @@ typedef struct __TABLE_UPC_SKILL { int iCastTime; // ij½ºÆÃ ½Ã°£ int iReCastTime; // ´Ù½Ã ij½ºÆÃÇÒ¶§±îÁö °É¸®´Â ½Ã°£. - float fUnkown1; // TODO: implement + float fUnkown1; // TODO: implement does this have to do with cooldown timers ?? + float fUnkown2; // TODO: implement does this have to do with cooldown timers ?? int iPercentSuccess; // ¼º°ø·ü DWORD dw1stTableType; // ù¹øÂ° ŸÀÔ. DWORD dw2ndTableType; // µÎ¹øÂ° ŸÀÔ. int iValidDist; // À¯È¿°Å¸® + int iUnkown1; // TODO: implement } TABLE_UPC_ATTACK_B; @@ -1160,6 +1171,7 @@ typedef struct __TABLE_UPC_SKILL_TYPE_2 { typedef struct __TABLE_UPC_SKILL_TYPE_3 { DWORD dwID; // SKILL °íÀ¯ ID + int iRadius; // TODO: Implement yo! int iDDType; int iStartDamage; int iDuraDamage; @@ -1170,14 +1182,18 @@ typedef struct __TABLE_UPC_SKILL_TYPE_3 { typedef struct __TABLE_UPC_SKILL_TYPE_4 { DWORD dwID; // ÀϷùøÈ£ int iBuffType; // ¹öÇÁŸÀÔ + int iRadius; // TODO: implement int iDuration; int iAttackSpeed; // °ø°Ý¼Óµµ int iMoveSpeed; // À̵¿¼Óµµ int iAC; // ¹æ¾î·Â + int iACPCT; // TODO: implement int iAttack; // °ø°Ý·Â + int iMagicAttack; // TODO: implement int iMaxHP; // MAXHP int iMaxHPPct; // TODO: implement int iMaxMP; // TODO: implement + int iMaxMPPct; // TODO: implement int iStr; // Èû int iSta; // ü·Â int iDex; // ¹Îø @@ -1189,6 +1205,7 @@ typedef struct __TABLE_UPC_SKILL_TYPE_4 { int iMagicResist; // ¸¶¹ýÀúÇ× int iDeseaseResist; // ÀúÁÖÀúÇ× int iPoisonResist; // µ¶ÀúÇ× + int iScrollMoveSpeed; // TODO: implement } TABLE_UPC_SKILL_TYPE_4; typedef struct __TABLE_UPC_SKILL_TYPE_5 { diff --git a/src/game/GameProcMain.cpp b/src/game/GameProcMain.cpp index 2e6bb4b0..7a6d11e5 100644 --- a/src/game/GameProcMain.cpp +++ b/src/game/GameProcMain.cpp @@ -4173,7 +4173,7 @@ void CGameProcMain::MsgSend_Warp() // int iOffset = 0; CAPISocket::MP_AddByte(byBuff, iOffset, N3_WARP_LIST); - CAPISocket::MP_AddByte(byBuff, iOffset, WI.iID); // ¿öÇÁ ¾ÆÀ̵𠺸³»±â... + CAPISocket::MP_AddShort(byBuff, iOffset, WI.iID); // ¿öÇÁ ¾ÆÀ̵𠺸³»±â... s_pSocket->Send(byBuff, iOffset); } diff --git a/src/game/MagicSkillMng.cpp b/src/game/MagicSkillMng.cpp index 5ddf4e62..23ccf24b 100644 --- a/src/game/MagicSkillMng.cpp +++ b/src/game/MagicSkillMng.cpp @@ -207,15 +207,35 @@ bool CMagicSkillMng::CheckValidSkillMagic(__TABLE_UPC_SKILL * pSkill) { int LeftItem = s_pPlayer->ItemClass_LeftHand(); int RightItem = s_pPlayer->ItemClass_RightHand(); - if (pSkill->iNeedSkill == 1055 || pSkill->iNeedSkill == 2055) { - if ((LeftItem != ITEM_CLASS_SWORD && LeftItem != ITEM_CLASS_AXE && LeftItem != ITEM_CLASS_MACE) || - (RightItem != ITEM_CLASS_SWORD && RightItem != ITEM_CLASS_AXE && RightItem != ITEM_CLASS_MACE)) { + if (pSkill->iNeedSkill == 1055 || pSkill->iNeedSkill == 2055 || pSkill->iNeedSkill == 1065 || + pSkill->iNeedSkill == 2065) + { + // Check for a shield in the left hand or right hand + if (LeftItem == ITEM_CLASS_SHIELD || RightItem == ITEM_CLASS_SHIELD) + { return false; } - } else if (pSkill->iNeedSkill == 1056 || pSkill->iNeedSkill == 2056) { - if (RightItem != ITEM_CLASS_SWORD_2H && RightItem != ITEM_CLASS_AXE_2H && RightItem != ITEM_CLASS_MACE_2H && - RightItem != ITEM_CLASS_POLEARM) { + + // Check for a weapon in the left hand + if (LeftItem != ITEM_CLASS_SWORD && LeftItem != ITEM_CLASS_AXE && LeftItem != ITEM_CLASS_MACE) { + // If there is no weapon in the left hand, check for a right-handed two-handed weapon + if (RightItem != ITEM_CLASS_SWORD_2H && RightItem != ITEM_CLASS_AXE_2H && RightItem != ITEM_CLASS_MACE_2H && + RightItem != ITEM_CLASS_POLEARM) { + return false; + } + } + } + else if (pSkill->iNeedSkill == 1056 || pSkill->iNeedSkill == 2056 || pSkill->iNeedSkill == 1066 || + pSkill->iNeedSkill == 2066) + { + if (pSkill->dwNeedItem != 9) + { + // Check for a right-handed two-handed weapon + if (RightItem != ITEM_CLASS_SWORD_2H && RightItem != ITEM_CLASS_AXE_2H && RightItem != ITEM_CLASS_MACE_2H && + RightItem != ITEM_CLASS_POLEARM) + { return false; + } } } @@ -226,11 +246,12 @@ bool CMagicSkillMng::CheckValidSkillMagic(__TABLE_UPC_SKILL * pSkill) { int LeftItem1 = LeftItem / 10; int RightItem1 = RightItem / 10; - if (pSkill->dwNeedItem != 0 && pSkill->dwNeedItem != LeftItem1 && pSkill->dwNeedItem != RightItem1) { + if (pSkill->dwNeedItem != 0 && pSkill->dwNeedItem != 9 && pSkill->dwNeedItem != LeftItem1 && + pSkill->dwNeedItem != RightItem1) { return false; } if (pSkill->dwNeedItem == 0 && (pSkill->dw1stTableType == 1 || pSkill->dw2ndTableType == 1)) { - if (LeftItem != 11 && (LeftItem1 < 1 || LeftItem1 > 5) && RightItem1 != 11 && + if (LeftItem != ITEM_CLASS_DAGGER && (LeftItem1 < 1 || LeftItem1 > 5) && RightItem1 != ITEM_CLASS_DAGGER && (RightItem1 < 1 || RightItem1 > 5)) { return false; } @@ -558,23 +579,59 @@ bool CMagicSkillMng::CheckValidCondition(int iTargetID, __TABLE_UPC_SKILL * pSki int LeftItem = s_pPlayer->ItemClass_LeftHand(); int RightItem = s_pPlayer->ItemClass_RightHand(); - if (pSkill->iNeedSkill == 1055 || pSkill->iNeedSkill == 2055) { - if ((LeftItem != ITEM_CLASS_SWORD && LeftItem != ITEM_CLASS_AXE && LeftItem != ITEM_CLASS_MACE) || - (RightItem != ITEM_CLASS_SWORD && RightItem != ITEM_CLASS_AXE && RightItem != ITEM_CLASS_MACE)) { + if (pSkill->iNeedSkill == 1055 || pSkill->iNeedSkill == 2055 || pSkill->iNeedSkill == 1065 || + pSkill->iNeedSkill == 2065) + { + // Check for a shield in the left hand or right hand + if (LeftItem == ITEM_CLASS_SHIELD || RightItem == ITEM_CLASS_SHIELD) + { std::string buff; ::_LoadStringFromResource(IDS_SKILL_FAIL_INVALID_ITEM, buff); m_pGameProcMain->MsgOutput(buff, 0xffffff00); return false; } - } else if (pSkill->iNeedSkill == 1056 || pSkill->iNeedSkill == 2056) { - if (RightItem != ITEM_CLASS_SWORD_2H && RightItem != ITEM_CLASS_AXE_2H && RightItem != ITEM_CLASS_MACE_2H && - RightItem != ITEM_CLASS_POLEARM) { - std::string buff; - ::_LoadStringFromResource(IDS_SKILL_FAIL_INVALID_ITEM, buff); - m_pGameProcMain->MsgOutput(buff, 0xffffff00); - return false; + + // Check for a weapon in the left hand + if (LeftItem != ITEM_CLASS_SWORD && LeftItem != ITEM_CLASS_AXE && LeftItem != ITEM_CLASS_MACE ) { + // If there is no weapon in the left hand, check for a right-handed two-handed weapon + if (RightItem != ITEM_CLASS_SWORD_2H && RightItem != ITEM_CLASS_AXE_2H && RightItem != ITEM_CLASS_MACE_2H && + RightItem != ITEM_CLASS_POLEARM) { + std::string buff; + ::_LoadStringFromResource(IDS_SKILL_FAIL_INVALID_ITEM, buff); + m_pGameProcMain->MsgOutput(buff, 0xffffff00); + return false; + } + } + } + else if (pSkill->iNeedSkill == 1056 || pSkill->iNeedSkill == 2056 || pSkill->iNeedSkill == 1066 || + pSkill->iNeedSkill == 2066) + { + if (pSkill->dw1stTableType == 1 || pSkill->dw2ndTableType == 1) + { + // Check for a right-handed two-handed weapon + if (LeftItem != ITEM_CLASS_SWORD && LeftItem != ITEM_CLASS_AXE && LeftItem != ITEM_CLASS_MACE) + { + // If there is no weapon in the left hand, check for a right-handed two-handed weapon + if (RightItem != ITEM_CLASS_SWORD_2H && RightItem != ITEM_CLASS_AXE_2H && + RightItem != ITEM_CLASS_MACE_2H && RightItem != ITEM_CLASS_POLEARM) + { + std::string buff; + ::_LoadStringFromResource(IDS_SKILL_FAIL_INVALID_ITEM, buff); + m_pGameProcMain->MsgOutput(buff, 0xffffff00); + return false; + } + } } } + // + //if (RightItem != ITEM_CLASS_SWORD_2H && RightItem != ITEM_CLASS_AXE_2H && RightItem != ITEM_CLASS_MACE_2H && + // RightItem != ITEM_CLASS_POLEARM) { + // std::string buff; + // ::_LoadStringFromResource(IDS_SKILL_FAIL_INVALID_ITEM, buff); + // m_pGameProcMain->MsgOutput(buff, 0xffffff00); + // /*return false;*/ + //} + if (pInfoBase->iHP < pSkill->iExhaustHP) { std::string buff; @@ -586,7 +643,8 @@ bool CMagicSkillMng::CheckValidCondition(int iTargetID, __TABLE_UPC_SKILL * pSki int LeftItem1 = LeftItem / 10; int RightItem1 = RightItem / 10; - if (pSkill->dwNeedItem != 0 && pSkill->dwNeedItem != LeftItem1 && pSkill->dwNeedItem != RightItem1) { + if (pSkill->dwNeedItem != 0 && pSkill->dwNeedItem != 9&& pSkill->dwNeedItem != LeftItem1 && + pSkill->dwNeedItem != RightItem1) { std::string buff; ::_LoadStringFromResource(IDS_SKILL_FAIL_INVALID_ITEM, buff); m_pGameProcMain->MsgOutput(buff, 0xffffff00); diff --git a/src/game/N3FXBundleGame.cpp b/src/game/N3FXBundleGame.cpp index 56a818ca..c0696e34 100644 --- a/src/game/N3FXBundleGame.cpp +++ b/src/game/N3FXBundleGame.cpp @@ -590,6 +590,15 @@ bool CN3FXBundleGame::Load(HANDLE hFile) { ReadFile(hFile, &m_bStatic, sizeof(bool), &dwRWC, NULL); } + if (m_iVersion == 3) { + ReadFile(hFile, &m_bEarthQuake, sizeof(bool), &dwRWC, NULL); + if (m_bEarthQuake) { + ReadFile(hFile, &m_fEarthQuakeStartTime, sizeof(float), &dwRWC, NULL); + } else { + m_fEarthQuakeStartTime = 0; + } + } + return true; } diff --git a/src/game/N3Terrain.cpp b/src/game/N3Terrain.cpp index 61395299..975ea99c 100644 --- a/src/game/N3Terrain.cpp +++ b/src/game/N3Terrain.cpp @@ -389,6 +389,11 @@ bool CN3Terrain::Load(HANDLE hFile) { } DWORD dwRWC; + int TempVersion, TempIntStringLength; + ReadFile(hFile, &(TempVersion), sizeof(int), &dwRWC, NULL); // Read the map version + ReadFile(hFile, &(TempIntStringLength), sizeof(int), &dwRWC, NULL); // Read the map name char length + CHAR * TempGTDMapNamebuffer = new CHAR[TempIntStringLength / sizeof(char) + 1]{}; // Zero-initialized + ReadFile(hFile, TempGTDMapNamebuffer, TempIntStringLength, &dwRWC, NULL); // Now read it and push it back to the GTDMapName char buffer ReadFile(hFile, &(m_ti_MapSize), sizeof(int), &dwRWC, NULL); m_pat_MapSize = (m_ti_MapSize - 1) / PATCH_TILE_SIZE; diff --git a/src/game/UISkillTreeDlg.cpp b/src/game/UISkillTreeDlg.cpp index 63c5fab7..184e95d5 100644 --- a/src/game/UISkillTreeDlg.cpp +++ b/src/game/UISkillTreeDlg.cpp @@ -906,38 +906,52 @@ void CUISkillTreeDlg::TooltipRenderEnable(__IconItemSkill * spSkill) { } m_pStr_info->SetString(spSkill->pSkill->szDesc); - if ((spSkill->pSkill->dw1stTableType != 1) && (spSkill->pSkill->dw1stTableType != 2)) { - if (!m_pStr_skill_mp->IsVisible()) { - m_pStr_skill_mp->SetVisible(true); - } - if (spSkill->pSkill->iExhaustMSP == 0) { - ::_LoadStringFromResource(IDS_SKILL_TOOLTIP_NO_MANA, szFmt); - sprintf(pszDesc, "%s", szFmt.c_str()); - } else { - ::_LoadStringFromResource(IDS_SKILL_TOOLTIP_USE_MANA, szFmt); - sprintf(pszDesc, szFmt.c_str(), spSkill->pSkill->iExhaustMSP); + //if ((spSkill->pSkill->dw1stTableType != 1) && (spSkill->pSkill->dw1stTableType != 2)) { + // if (!m_pStr_skill_mp->IsVisible()) { + // m_pStr_skill_mp->SetVisible(true); + // } + // if (spSkill->pSkill->iExhaustMSP == 0) { + // ::_LoadStringFromResource(IDS_SKILL_TOOLTIP_NO_MANA, szFmt); + // sprintf(pszDesc, "%s", szFmt.c_str()); + // } else { + // ::_LoadStringFromResource(IDS_SKILL_TOOLTIP_USE_MANA, szFmt); + // sprintf(pszDesc, szFmt.c_str(), spSkill->pSkill->iExhaustMSP); + // } + // m_pStr_skill_mp->SetString(pszDesc); + //} + if (m_pStr_skill_mp) + { + m_pStr_skill_mp->SetVisible(true); + if (spSkill->pSkill->iExhaustMSP == 0) + { + ::_LoadStringFromResource(IDS_SKILL_TOOLTIP_NO_MANA, szFmt); + sprintf(pszDesc, "%s", szFmt.c_str()); + } + else + { + ::_LoadStringFromResource(IDS_SKILL_TOOLTIP_USE_MANA, szFmt); + sprintf(pszDesc, szFmt.c_str(), spSkill->pSkill->iExhaustMSP); } - m_pStr_skill_mp->SetString(pszDesc); + m_pStr_skill_mp->SetString(pszDesc); } if (!m_pStr_skill_item0->IsVisible()) { m_pStr_skill_item0->SetVisible(true); } - switch (spSkill->pSkill->iNeedSkill) { - case 1055: - case 2055: - ::_LoadStringFromResource(IDS_SKILL_TOOLTIP_NEED_ITEM_DUAL, szFmt); - sprintf(pszDesc, szFmt.c_str()); - bFound = true; - break; - - case 1056: - case 2056: - ::_LoadStringFromResource(IDS_SKILL_TOOLTIP_DOUBLE, szFmt); - sprintf(pszDesc, szFmt.c_str()); - bFound = true; - break; - } + //switch (spSkill->pSkill->iNeedSkill) { + //case 1055: + //case 2055: + // ::_LoadStringFromResource(IDS_SKILL_TOOLTIP_NEED_ITEM_DUAL, szFmt); + // sprintf(pszDesc, szFmt.c_str()); + // bFound = true; + // break; + //case 1056: + //case 2056: + // ::_LoadStringFromResource(IDS_SKILL_TOOLTIP_DOUBLE, szFmt); + // sprintf(pszDesc, szFmt.c_str()); + // bFound = true; + // break; + //} if (!bFound) { switch (spSkill->pSkill->dwNeedItem) { diff --git a/src/server/AIServer/Npc.cpp b/src/server/AIServer/Npc.cpp index 10de96a8..0f47fcc1 100644 --- a/src/server/AIServer/Npc.cpp +++ b/src/server/AIServer/Npc.cpp @@ -348,6 +348,12 @@ void CNpc::NpcTracing(CIOCPort * pIOCP) { } } + if (m_byMoveType == 4) + { + m_NpcState = NPC_FIGHTING; + return; + } + if (cur_test) { NpcTrace("NpcTracing()"); } @@ -1058,6 +1064,11 @@ BOOL CNpc::RandomMove() { // º¸ÅëÀ̵¿À϶§´Â °È´Â ¼Óµµ·Î ¸ÂÃß¾îÁØ´Ù... m_fSecForMetor = m_fSpeed_1; + if (m_byMoveType == 4) + { + return FALSE; + } + if (m_bySearchRange == 0) { return FALSE; } diff --git a/src/server/AIServer/NpcTable.h b/src/server/AIServer/NpcTable.h index e8cafa35..361ada5b 100644 --- a/src/server/AIServer/NpcTable.h +++ b/src/server/AIServer/NpcTable.h @@ -13,7 +13,7 @@ class CNpcTable { int m_iWeapon_1; // ¹«±â°è¿­(¿À¸¥¼Õ) int m_iWeapon_2; // ¹«±â°è¿­(¿Þ¼Õ) BYTE m_byGroup; // ¼Ò¼ÓÁý´Ü - BYTE m_byActType; // ÇൿÆÐÅÏ + int m_byActType; // ÇൿÆÐÅÏ BYTE m_tNpcType; // NPC Type // 0 : Monster // 1 : Normal NPC diff --git a/src/server/AIServer/NpcTableSet.cpp b/src/server/AIServer/NpcTableSet.cpp index d0951fa7..6dfcd350 100644 --- a/src/server/AIServer/NpcTableSet.cpp +++ b/src/server/AIServer/NpcTableSet.cpp @@ -88,7 +88,7 @@ void CNpcTableSet::DoFieldExchange(CFieldExchange * pFX) { RFX_Long(pFX, _T("[iWeapon2]"), m_iWeapon2); RFX_Byte(pFX, _T("[byGroup]"), m_byGroup); RFX_Byte(pFX, _T("[byActType]"), m_byActType); - RFX_Byte(pFX, _T("[byType]"), m_byType); + RFX_Int(pFX, _T("[byType]"), m_byType); RFX_Byte(pFX, _T("[byFamily]"), m_byFamily); RFX_Byte(pFX, _T("[byRank]"), m_byRank); RFX_Byte(pFX, _T("[byTitle]"), m_byTitle); diff --git a/src/server/AIServer/NpcTableSet.h b/src/server/AIServer/NpcTableSet.h index 1bd02787..3a244374 100644 --- a/src/server/AIServer/NpcTableSet.h +++ b/src/server/AIServer/NpcTableSet.h @@ -21,7 +21,7 @@ class CNpcTableSet : public CRecordset { long m_iWeapon2; BYTE m_byGroup; BYTE m_byActType; - BYTE m_byType; + int m_byType; BYTE m_byFamily; BYTE m_byRank; BYTE m_byTitle; diff --git a/src/server/Ebenezer/MagicProcess.cpp b/src/server/Ebenezer/MagicProcess.cpp index 588cdcca..b8d250eb 100644 --- a/src/server/Ebenezer/MagicProcess.cpp +++ b/src/server/Ebenezer/MagicProcess.cpp @@ -712,30 +712,33 @@ _MAGIC_TABLE * CMagicProcess::IsAvailable(int magicid, int tid, int sid, BYTE ty goto fail_return; } - if (pTable->bType1 == 1) { // Weapons verification in case of COMBO attack (another hacking prevention). + if (pTable->bType1 == 1) + { // Weapons verification in case of COMBO attack (another hacking prevention). if (pTable->sSkill == 1055 || - pTable->sSkill == 2055) { // Weapons verification in case of DUAL ATTACK (type 1)! - _ITEM_TABLE * pLeftHand = NULL; // Get item info for left hand. + pTable->sSkill == 2055) + { // Weapons verification in case of DUAL ATTACK (type 1)! + _ITEM_TABLE * pLeftHand = NULL; // Get item info for left hand. + _ITEM_TABLE * pRightHand = NULL; // Get item info for right hand pLeftHand = m_pMain->m_ItemtableArray.GetData(m_pSrcUser->m_pUserData->m_sItemArray[LEFTHAND].nNum); - if (!pLeftHand) { - return NULL; - } - - _ITEM_TABLE * pRightHand = NULL; // Get item info for right hand. pRightHand = m_pMain->m_ItemtableArray.GetData(m_pSrcUser->m_pUserData->m_sItemArray[RIGHTHAND].nNum); - if (!pRightHand) { - return NULL; + if (pLeftHand != nullptr) { + int left_index = pLeftHand->m_bKind/* / 10*/; + if ((left_index != 21/*WEAPON_SWORD*/ && left_index != 31/*WEAPON_AXE*/ && left_index != 41/*WEAPON_MACE*/)) { + return NULL; + } } - - int left_index = pLeftHand->m_bKind / 10; - int right_index = pRightHand->m_bKind / 10; - - if ((left_index != WEAPON_SWORD && left_index != WEAPON_AXE && left_index != WEAPON_MACE) && - (right_index != WEAPON_SWORD && right_index != WEAPON_AXE && right_index != WEAPON_MACE)) { - return NULL; + if (pLeftHand == nullptr && pRightHand != nullptr) + { + int right_index = pRightHand->m_bKind /* / 10*/; + if (right_index != 22 /*ITEM_CLASS_SWORD_2H*/ && right_index != 32 /*ITEM_CLASS_AXE_2H*/ && + right_index != 42 /*ITEM_CLASS_MACE_2H*/ && right_index != 52 /*ITEM_CLASS_POLEARM*/) + { + return NULL; + } } - } else if (pTable->sSkill == 1056 || - pTable->sSkill == 2056) { // Weapons verification in case of DOUBLE ATTACK ! + } + else if (pTable->sSkill == 1056 || pTable->sSkill == 2056) // todo + { // Weapons verification in case of DOUBLE ATTACK ! _ITEM_TABLE * pRightHand = NULL; // Get item info for right hand. pRightHand = m_pMain->m_ItemtableArray.GetData(m_pSrcUser->m_pUserData->m_sItemArray[RIGHTHAND].nNum); if (!pRightHand) {