MRMJ-1: Messenger & Skills fixes
This commit is contained in:
62
.gitignore
vendored
62
.gitignore
vendored
@@ -1 +1,63 @@
|
||||
/build/
|
||||
|
||||
# =======================================================
|
||||
# FULLY CASE-INSENSITIVE BACKUP EXCLUSIONS
|
||||
# Matches all files and folders ending in:
|
||||
# _BK, _BAK, .BK, .BAK (and all case permutations)
|
||||
# =======================================================
|
||||
|
||||
# -------------------------------------------------------
|
||||
# 1. EXCLUSIONS ENDING IN .BK / _BK
|
||||
# -------------------------------------------------------
|
||||
|
||||
# Files/Folders ending in _BK (e.g., File_Bk, Folder_bK)
|
||||
*_BK
|
||||
*_Bk
|
||||
*_bK
|
||||
*_bk
|
||||
|
||||
# Files ending in .BK (e.g., File.BK, File.bK)
|
||||
*.BK
|
||||
*.Bk
|
||||
*.bK
|
||||
*.bk
|
||||
|
||||
# Files ending in "double extension" .X.BK (e.g., File.txt.Bk)
|
||||
*.*.BK
|
||||
*.*.Bk
|
||||
*.*.bK
|
||||
*.*.bk
|
||||
|
||||
# -------------------------------------------------------
|
||||
# 2. EXCLUSIONS ENDING IN .BAK / _BAK
|
||||
# -------------------------------------------------------
|
||||
|
||||
# Files/Folders ending in _BAK (e.g., File_BAK, Folder_bak)
|
||||
*_BAK
|
||||
*_BAk
|
||||
*_BaK
|
||||
*_Bak
|
||||
*_bAK
|
||||
*_bAk
|
||||
*_baK
|
||||
*_bak
|
||||
|
||||
# Files ending in .BAK (e.g., File.BAK, File.bak)
|
||||
*.BAK
|
||||
*.BAk
|
||||
*.BaK
|
||||
*.Bak
|
||||
*.bAK
|
||||
*.bAk
|
||||
*.baK
|
||||
*.bak
|
||||
|
||||
# Files ending in "double extension" .X.BAK (e.g., File.txt.Bak)
|
||||
*.*.BAK
|
||||
*.*.BAk
|
||||
*.*.BaK
|
||||
*.*.Bak
|
||||
*.*.bAK
|
||||
*.*.bAk
|
||||
*.*.baK
|
||||
*.*.bak
|
||||
|
||||
26
README.md
26
README.md
@@ -10,16 +10,20 @@ This repository contains the source code necessary to compile the game client ex
|
||||
|
||||
---
|
||||
|
||||
## ✨ Key Source Code Fixes
|
||||
## Changelog 📋
|
||||
|
||||
The following fixes address critical issues related to locale compilation and texture loading, ensuring compatibility with new content and correct language output.
|
||||
### 🐛 Bug Fixes
|
||||
* **Character Selection:** Corrected the display of character stats and ensured gauge bars accurately reflect the character's stats during the selection phase.
|
||||
* **Changing skill group:** Fixed an issue involving incorrect skill dictionary clearing/restructuring when changing a skill group. This previously caused the client to be unable to find the correct skill slot after a skill group reset, preventing the display of newly added points on level-up and/or clearing cooldown and active state when used and applied new point (if clearing cooldowns for level-0 skills enabled).
|
||||
|
||||
### 🖼️ Texture and Resource Loading Fix
|
||||
|
||||
* **Fix: Missing Texture Cache:** Resolved an issue in `UserInterface/UserInterface.cpp` by adding the necessary missing resource directory names (`"_texcache"`) within the `PackInitialize` function.
|
||||
* **Impact:** This ensures that texture files for mobs and terrain for the new maps (Cape, Bay, Dawn, Thunder) are displayed.
|
||||
|
||||
### 🌐 Build Configuration Fix
|
||||
|
||||
* **Fix: Locale Build Typos:** Corrected a critical typo in `UserInterface/locale.cpp` where the `RelWithDebInfo` build configuration incorrectly referenced `tr (1253)`.
|
||||
* **Impact:** The value was updated to **`gr (1253)`** to correctly reference the Greek locale option before game launch.
|
||||
### ⬆️ Feature Improvements
|
||||
* **Messenger System:**
|
||||
* **Live Removal Updates:** The client now receives immediate live updates when a player is removed by a friend, improving synchronization.
|
||||
* **Skill Cooldowns and States:** Enhanced reliability and persistence across numerous client actions:
|
||||
* **Persistence:** Cooldowns and active slot effects are now correctly maintained when changing the Character Window view, switching skill tabs, mounting/unmounting, leveling up a skill or relogging. This persistence is ensured for togglable, non-togglable, and togglable skills with cooldowns.
|
||||
* **Grade Transfer:** Cooldowns and active slot states are correctly transferred when a skill's grade is changed (e.g., to Master or Perfect).
|
||||
* **Reset Logic:** Skill cooldowns are cleared and/or active slots are disabled when a skill is reset (individually or via a skill group reset).
|
||||
* **Support Skills:** Support skill levels are correctly maintained when the active skill group is changed/reset.
|
||||
* **Horse Skills:** Implemented special handling to ensure horse skill cooldowns are cleared when their level is changed to 0 (via commands like `/setsk`).
|
||||
* **Combo Skills:** Combo skills are automatically disabled if their level is changed to 0 (via commands like `/setsk`).
|
||||
* **.gitignore file:** Ignoring all files and directories ending in `_BAK` or `.BAK` (case-insensitive)
|
||||
|
||||
@@ -269,6 +269,9 @@ void CEffectInstance::Clear()
|
||||
|
||||
void CEffectInstance::__Initialize()
|
||||
{
|
||||
#ifdef __ENABLE_STEALTH_FIX__
|
||||
ReleaseAlwaysHidden();
|
||||
#endif
|
||||
m_isAlive = FALSE;
|
||||
m_dwFrame = 0;
|
||||
m_pSoundInstanceVector = NULL;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "Eterlib/Pool.h"
|
||||
#include "AudioLib/Type.h"
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "EffectElementBaseInstance.h"
|
||||
#include "EffectData.h"
|
||||
#include "EffectMeshInstance.h"
|
||||
@@ -41,6 +42,14 @@ class CEffectInstance : public CGraphicObjectInstance
|
||||
bool LessRenderOrder(CEffectInstance* pkEftInst);
|
||||
|
||||
void SetEffectDataPointer(CEffectData * pEffectData);
|
||||
|
||||
#ifdef __ENABLE_STEALTH_FIX__ //EXP
|
||||
// Returns the pointer to the effect data associated with this instance.
|
||||
CEffectData* GetEffectDataPointer() const
|
||||
{
|
||||
return m_pkEftData;
|
||||
}
|
||||
#endif
|
||||
|
||||
void Clear();
|
||||
BOOL isAlive();
|
||||
@@ -85,6 +94,7 @@ class CEffectInstance : public CGraphicObjectInstance
|
||||
float m_fLastTime;
|
||||
|
||||
public:
|
||||
|
||||
static CDynamicPool<CEffectInstance> ms_kPool;
|
||||
static int ms_iRenderingEffectCount;
|
||||
};
|
||||
|
||||
@@ -351,6 +351,24 @@ void CEffectManager::HideEffect()
|
||||
m_pSelectedEffectInstance->Hide();
|
||||
}
|
||||
|
||||
#ifdef __ENABLE_STEALTH_FIX__
|
||||
void CEffectManager::ApplyAlwaysHidden()
|
||||
{
|
||||
if (!m_pSelectedEffectInstance)
|
||||
return;
|
||||
|
||||
m_pSelectedEffectInstance->ApplyAlwaysHidden();
|
||||
}
|
||||
|
||||
void CEffectManager::ReleaseAlwaysHidden()
|
||||
{
|
||||
if (!m_pSelectedEffectInstance)
|
||||
return;
|
||||
|
||||
m_pSelectedEffectInstance->ReleaseAlwaysHidden();
|
||||
}
|
||||
#endif
|
||||
|
||||
bool CEffectManager::GetEffectData(DWORD dwID, CEffectData ** ppEffect)
|
||||
{
|
||||
TEffectDataMap::iterator itor = m_kEftDataMap.find(dwID);
|
||||
@@ -462,5 +480,25 @@ CEffectManager::~CEffectManager()
|
||||
Destroy();
|
||||
}
|
||||
|
||||
#ifdef __ENABLE_STEALTH_FIX__ //EXP
|
||||
DWORD CEffectManager::GetSelectedEffectDataCRC() const
|
||||
{
|
||||
if (!m_pSelectedEffectInstance)
|
||||
return 0;
|
||||
|
||||
CEffectData* pData = m_pSelectedEffectInstance->GetEffectDataPointer();
|
||||
if (!pData)
|
||||
return 0;
|
||||
|
||||
const char* cszFile = pData->GetFileName();
|
||||
if (!cszFile || !cszFile[0])
|
||||
return 0;
|
||||
|
||||
std::string str;
|
||||
StringPath(cszFile, str);
|
||||
return GetCaseCRC32(str.c_str(), (int)str.length());
|
||||
}
|
||||
#endif
|
||||
|
||||
// just for map effect
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "EffectInstance.h"
|
||||
|
||||
class CEffectManager : public CScreen, public CSingleton<CEffectManager>
|
||||
@@ -56,6 +57,11 @@ class CEffectManager : public CScreen, public CSingleton<CEffectManager>
|
||||
void ShowEffect();
|
||||
void HideEffect();
|
||||
|
||||
#ifdef __ENABLE_STEALTH_FIX__
|
||||
void ApplyAlwaysHidden();
|
||||
void ReleaseAlwaysHidden();
|
||||
#endif
|
||||
|
||||
// Temporary function
|
||||
DWORD GetRandomEffect();
|
||||
int GetEmptyIndex();
|
||||
@@ -69,6 +75,11 @@ class CEffectManager : public CScreen, public CSingleton<CEffectManager>
|
||||
|
||||
int GetRenderingEffectCount();
|
||||
|
||||
#ifdef __ENABLE_STEALTH_FIX__ //EXP
|
||||
// Return the CRC of the effect-data for the selected effect instance.
|
||||
DWORD GetSelectedEffectDataCRC() const;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void __Initialize();
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
#include "AudioLib/StdAfx.h"
|
||||
|
||||
#include "UserInterface/Locale_inc.h"
|
||||
|
||||
/*
|
||||
#include "FrameController.h"
|
||||
|
||||
|
||||
@@ -200,9 +200,24 @@ void CGraphicObjectInstance::Hide()
|
||||
{
|
||||
m_isVisible = false;
|
||||
}
|
||||
|
||||
#ifdef __ENABLE_STEALTH_FIX__
|
||||
void CGraphicObjectInstance::ApplyAlwaysHidden() {
|
||||
m_isAlwaysHidden = true;
|
||||
}
|
||||
|
||||
void CGraphicObjectInstance::ReleaseAlwaysHidden() {
|
||||
m_isAlwaysHidden = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool CGraphicObjectInstance::isShow()
|
||||
{
|
||||
#ifdef __ENABLE_STEALTH_FIX__
|
||||
return m_isVisible && !m_isAlwaysHidden;
|
||||
#else
|
||||
return m_isVisible;
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
@@ -276,6 +291,11 @@ void CGraphicObjectInstance::Initialize()
|
||||
m_isVisible = TRUE;
|
||||
|
||||
m_BlockCamera = false;
|
||||
|
||||
#ifdef __ENABLE_STEALTH_FIX__
|
||||
m_isAlwaysHidden = false;
|
||||
#endif
|
||||
|
||||
|
||||
m_v3Position.x = m_v3Position.y = m_v3Position.z = 0.0f;
|
||||
m_v3Scale.x = m_v3Scale.y = m_v3Scale.z = 1.0f;
|
||||
|
||||
@@ -57,6 +57,12 @@ class CGraphicObjectInstance : public CGraphicCollisionObject
|
||||
void Hide();
|
||||
bool isShow();
|
||||
|
||||
#ifdef __ENABLE_STEALTH_FIX__
|
||||
void ApplyAlwaysHidden();
|
||||
void ReleaseAlwaysHidden();
|
||||
#endif
|
||||
|
||||
|
||||
// Camera Block
|
||||
void BlockCamera(bool bBlock) {m_BlockCamera = bBlock;}
|
||||
bool BlockCamera() { return m_BlockCamera; }
|
||||
@@ -109,6 +115,10 @@ class CGraphicObjectInstance : public CGraphicCollisionObject
|
||||
D3DXMATRIX m_mRotation;
|
||||
|
||||
bool m_isVisible;
|
||||
#ifdef __ENABLE_STEALTH_FIX__
|
||||
bool m_isAlwaysHidden;
|
||||
#endif
|
||||
|
||||
D3DXMATRIX m_worldMatrix;
|
||||
|
||||
// Camera Block
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
#include "EterBase/Debug.h"
|
||||
#include "EterLocale/CodePageId.h"
|
||||
|
||||
#include "UserInterface/Locale_inc.h"
|
||||
|
||||
#ifndef VC_EXTRALEAN
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
#include "PythonWindow.h"
|
||||
#include "PythonSlotWindow.h"
|
||||
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
#include "UserInterface/PythonSkill.h"
|
||||
#include "UserInterface/PythonPlayer.h"
|
||||
#endif
|
||||
|
||||
//#define __RENDER_SLOT_AREA__
|
||||
|
||||
using namespace UI;
|
||||
@@ -204,6 +209,14 @@ void CSlotWindow::SetSlotType(DWORD dwType)
|
||||
m_dwSlotType = dwType;
|
||||
}
|
||||
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
DWORD CSlotWindow::GetSlotType() const
|
||||
{
|
||||
return m_dwSlotType;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void CSlotWindow::SetSlotStyle(DWORD dwStyle)
|
||||
{
|
||||
m_dwSlotStyle = dwStyle;
|
||||
@@ -499,6 +512,7 @@ void CSlotWindow::SetSlotCountNew(DWORD dwIndex, DWORD dwGrade, DWORD dwCount)
|
||||
void CSlotWindow::SetSlotCoolTime(DWORD dwIndex, float fCoolTime, float fElapsedTime)
|
||||
{
|
||||
TSlot * pSlot;
|
||||
|
||||
if (!GetSlotPointer(dwIndex, &pSlot))
|
||||
return;
|
||||
|
||||
@@ -506,9 +520,94 @@ void CSlotWindow::SetSlotCoolTime(DWORD dwIndex, float fCoolTime, float fElapsed
|
||||
pSlot->fStartCoolTime = CTimer::Instance().GetCurrentSecond() - fElapsedTime;
|
||||
}
|
||||
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
void CSlotWindow::StoreSlotCoolTime(DWORD dwKey, DWORD dwSlotIndex, float fCoolTime, float fElapsedTime)
|
||||
{
|
||||
std::map<DWORD, SStoreCoolDown>::iterator it = m_CoolDownStore[dwKey].find(dwSlotIndex);
|
||||
|
||||
if (it != m_CoolDownStore[dwKey].end())
|
||||
{
|
||||
it->second.fCoolTime = fCoolTime;
|
||||
it->second.fElapsedTime = CTimer::Instance().GetCurrentSecond() - fElapsedTime;
|
||||
it->second.bActive = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
SStoreCoolDown m_storeCoolDown;
|
||||
|
||||
m_storeCoolDown.fCoolTime = fCoolTime;
|
||||
m_storeCoolDown.fElapsedTime = CTimer::Instance().GetCurrentSecond() - fElapsedTime;
|
||||
m_storeCoolDown.bActive = false;
|
||||
|
||||
m_CoolDownStore[dwKey].insert(std::map<DWORD, SStoreCoolDown>::value_type(dwSlotIndex, m_storeCoolDown));
|
||||
}
|
||||
}
|
||||
|
||||
void CSlotWindow::RestoreSlotCoolTime(DWORD dwKey)
|
||||
{
|
||||
for (std::map<DWORD, SStoreCoolDown>::iterator it = m_CoolDownStore[dwKey].begin(); it != m_CoolDownStore[dwKey].end(); it++)
|
||||
{
|
||||
TSlot* pSlot;
|
||||
|
||||
if (!GetSlotPointer(it->first, &pSlot))
|
||||
return;
|
||||
|
||||
pSlot->fCoolTime = it->second.fCoolTime;
|
||||
pSlot->fStartCoolTime = it->second.fElapsedTime;
|
||||
|
||||
if (it->second.bActive)
|
||||
ActivateSlot(it->first);
|
||||
else
|
||||
DeactivateSlot(it->first);
|
||||
}
|
||||
}
|
||||
|
||||
void CSlotWindow::TransferSlotCoolTime(DWORD dwIndex1, DWORD dwIndex2)
|
||||
{
|
||||
std::map<DWORD, SStoreCoolDown>::iterator it = m_CoolDownStore[CPythonSkill::SKILL_TYPE_ACTIVE].find(dwIndex1);
|
||||
|
||||
if (it != m_CoolDownStore[CPythonSkill::SKILL_TYPE_ACTIVE].end())
|
||||
{
|
||||
TSlot* pSlot1;
|
||||
|
||||
if (!GetSlotPointer(dwIndex1, &pSlot1))
|
||||
return;
|
||||
|
||||
TSlot* pSlot2;
|
||||
|
||||
if (!GetSlotPointer(dwIndex2, &pSlot2))
|
||||
return;
|
||||
|
||||
// Replacing the cooldown from slot 1 to slot 2 and removing the slot 1 from the map.
|
||||
SStoreCoolDown slotCooldown = it->second;
|
||||
|
||||
int iDestSkillGrade = CPythonPlayer::Instance().GetSkillGrade(dwIndex2);
|
||||
int iDestSkillLevel = CPythonPlayer::Instance().GetSkillLevel(dwIndex2);
|
||||
|
||||
m_CoolDownStore[CPythonSkill::SKILL_TYPE_ACTIVE][dwIndex2] = slotCooldown;
|
||||
m_CoolDownStore[CPythonSkill::SKILL_TYPE_ACTIVE].erase(dwIndex1);
|
||||
|
||||
// Removing the cooldown from the slot 1.
|
||||
pSlot1->fCoolTime = 0;
|
||||
pSlot1->fStartCoolTime = 0;
|
||||
|
||||
if (slotCooldown.bActive)
|
||||
ActivateSlot(dwIndex2);
|
||||
|
||||
if (iDestSkillLevel > 0)
|
||||
{
|
||||
// Setting the cooldown from slot 1 to slot 2.
|
||||
pSlot2->fCoolTime = slotCooldown.fCoolTime;
|
||||
pSlot2->fStartCoolTime = slotCooldown.fElapsedTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void CSlotWindow::ActivateSlot(DWORD dwIndex)
|
||||
{
|
||||
TSlot * pSlot;
|
||||
|
||||
if (!GetSlotPointer(dwIndex, &pSlot))
|
||||
return;
|
||||
|
||||
@@ -518,20 +617,36 @@ void CSlotWindow::ActivateSlot(DWORD dwIndex)
|
||||
{
|
||||
__CreateSlotEnableEffect();
|
||||
}
|
||||
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
std::map<DWORD, SStoreCoolDown>::iterator it = m_CoolDownStore[1].find(dwIndex);
|
||||
|
||||
if (it != m_CoolDownStore[1].end())
|
||||
it->second.bActive = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CSlotWindow::DeactivateSlot(DWORD dwIndex)
|
||||
{
|
||||
TSlot * pSlot;
|
||||
|
||||
if (!GetSlotPointer(dwIndex, &pSlot))
|
||||
return;
|
||||
|
||||
pSlot->bActive = FALSE;
|
||||
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
std::map<DWORD, SStoreCoolDown>::iterator it = m_CoolDownStore[1].find(dwIndex);
|
||||
|
||||
if (it != m_CoolDownStore[1].end())
|
||||
it->second.bActive = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void CSlotWindow::ClearSlot(DWORD dwIndex)
|
||||
{
|
||||
TSlot * pSlot;
|
||||
|
||||
if (!GetSlotPointer(dwIndex, &pSlot))
|
||||
return;
|
||||
|
||||
@@ -1262,6 +1377,17 @@ void CSlotWindow::ReserveDestroyCoolTimeFinishEffect(DWORD dwSlotIndex)
|
||||
m_ReserveDestroyEffectDeque.push_back(dwSlotIndex);
|
||||
}
|
||||
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
void CSlotWindow::ClearStoredSlotCoolTime(DWORD dwKey, DWORD dwSlotIndex)
|
||||
{
|
||||
std::map<DWORD, SStoreCoolDown>& store = m_CoolDownStore[dwKey];
|
||||
std::map<DWORD, SStoreCoolDown>::iterator it = store.find(dwSlotIndex);
|
||||
|
||||
if (it != store.end())
|
||||
store.erase(it);
|
||||
}
|
||||
#endif
|
||||
|
||||
DWORD CSlotWindow::Type()
|
||||
{
|
||||
static int s_Type = GetCRC32("CSlotWindow", strlen("CSlotWindow"));
|
||||
@@ -1383,6 +1509,11 @@ void CSlotWindow::__Initialize()
|
||||
m_dwSlotStyle = SLOT_STYLE_PICK_UP;
|
||||
m_dwToolTipSlotNumber = SLOT_NUMBER_NONE;
|
||||
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
m_CoolDownStore.clear();
|
||||
#endif
|
||||
|
||||
|
||||
m_isUseMode = FALSE;
|
||||
m_isUsableItem = FALSE;
|
||||
|
||||
|
||||
@@ -75,6 +75,10 @@ namespace UI
|
||||
} TSlot;
|
||||
typedef std::list<TSlot> TSlotList;
|
||||
typedef TSlotList::iterator TSlotListIterator;
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
typedef struct SStoreCoolDown { float fCoolTime; float fElapsedTime; bool bActive; };
|
||||
#endif
|
||||
|
||||
|
||||
public:
|
||||
CSlotWindow(PyObject * ppyObject);
|
||||
@@ -84,6 +88,9 @@ namespace UI
|
||||
|
||||
// Manage Slot
|
||||
void SetSlotType(DWORD dwType);
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
DWORD GetSlotType() const;
|
||||
#endif
|
||||
void SetSlotStyle(DWORD dwStyle);
|
||||
|
||||
void AppendSlot(DWORD dwIndex, int ixPosition, int iyPosition, int ixCellSize, int iyCellSize);
|
||||
@@ -107,6 +114,11 @@ namespace UI
|
||||
void SetSlotCount(DWORD dwIndex, DWORD dwCount);
|
||||
void SetSlotCountNew(DWORD dwIndex, DWORD dwGrade, DWORD dwCount);
|
||||
void SetSlotCoolTime(DWORD dwIndex, float fCoolTime, float fElapsedTime = 0.0f);
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
void StoreSlotCoolTime(DWORD dwKey, DWORD dwSlotIndex, float fCoolTime, float fElapsedTime = .0f);
|
||||
void RestoreSlotCoolTime(DWORD dwKey);
|
||||
void TransferSlotCoolTime(DWORD dwIndex1, DWORD dwIndex2);
|
||||
#endif
|
||||
void ActivateSlot(DWORD dwIndex);
|
||||
void DeactivateSlot(DWORD dwIndex);
|
||||
void RefreshSlot();
|
||||
@@ -150,6 +162,10 @@ namespace UI
|
||||
// CallBack
|
||||
void ReserveDestroyCoolTimeFinishEffect(DWORD dwSlotIndex);
|
||||
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
void ClearStoredSlotCoolTime(DWORD dwKey, DWORD dwSlotIndex);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void __Initialize();
|
||||
void __CreateToggleSlotImage();
|
||||
@@ -199,6 +215,9 @@ namespace UI
|
||||
std::list<DWORD> m_dwSelectedSlotIndexList;
|
||||
TSlotList m_SlotList;
|
||||
DWORD m_dwToolTipSlotNumber;
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
std::map<DWORD, std::map<DWORD, SStoreCoolDown>> m_CoolDownStore;
|
||||
#endif
|
||||
|
||||
BOOL m_isUseMode;
|
||||
BOOL m_isUsableItem;
|
||||
|
||||
@@ -81,6 +81,9 @@ namespace UI
|
||||
bool HasParent() { return m_pParent ? true : false; }
|
||||
bool HasChild() { return m_pChildList.empty() ? false : true; }
|
||||
int GetChildCount() { return m_pChildList.size(); }
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
const TWindowContainer& GetChildList() const { return m_pChildList; }
|
||||
#endif
|
||||
|
||||
CWindow * GetRoot();
|
||||
CWindow * GetParent();
|
||||
|
||||
@@ -652,6 +652,39 @@ namespace UI
|
||||
m_pRightCaptureWindow = NULL;
|
||||
}
|
||||
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
void CWindowManager::ClearStoredSlotCoolTimeInAllSlotWindows(DWORD dwKey, DWORD dwSlotIndex)
|
||||
{
|
||||
// recursively walk the window tree starting from layers and clear stored cooldown entries
|
||||
std::function<void(CWindow*)> recurse;
|
||||
|
||||
recurse = [&](CWindow* pWin)
|
||||
{
|
||||
if (!pWin)
|
||||
return;
|
||||
|
||||
// If this is a slot window, call its helper
|
||||
if (pWin->IsType(UI::CSlotWindow::Type()))
|
||||
{
|
||||
UI::CSlotWindow * pSlotWin = static_cast<UI::CSlotWindow*>(pWin);
|
||||
pSlotWin->ClearStoredSlotCoolTime(dwKey, dwSlotIndex);
|
||||
}
|
||||
|
||||
// Visit children
|
||||
for (CWindow* pChild : pWin->GetChildList())
|
||||
{
|
||||
recurse(pChild);
|
||||
}
|
||||
};
|
||||
|
||||
// Walk all layer roots
|
||||
for (CWindow* pLayer : m_LayerWindowList)
|
||||
{
|
||||
recurse(pLayer);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void CWindowManager::SetResolution(int hres, int vres)
|
||||
{
|
||||
if (hres<=0 || vres<=0)
|
||||
|
||||
@@ -106,6 +106,10 @@ namespace UI
|
||||
void SetTop(CWindow * pWin);
|
||||
void SetTopUIWindow();
|
||||
void ResetCapture();
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
void ClearStoredSlotCoolTimeInAllSlotWindows(DWORD dwKey, DWORD dwSlotIndex);
|
||||
#endif
|
||||
|
||||
|
||||
void Update();
|
||||
void Render();
|
||||
|
||||
@@ -1254,6 +1254,80 @@ PyObject * wndMgrSetSlotCoolTime(PyObject * poSelf, PyObject * poArgs)
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
PyObject* wndMgrStoreSlotCoolTime(PyObject* poSelf, PyObject* poArgs)
|
||||
{
|
||||
UI::CWindow* pWin;
|
||||
if (!PyTuple_GetWindow(poArgs, 0, &pWin))
|
||||
return Py_BuildException();
|
||||
|
||||
int iKey;
|
||||
if (!PyTuple_GetInteger(poArgs, 1, &iKey))
|
||||
return Py_BuildException();
|
||||
|
||||
int iSlotIndex;
|
||||
if (!PyTuple_GetInteger(poArgs, 2, &iSlotIndex))
|
||||
return Py_BuildException();
|
||||
|
||||
float fCoolTime;
|
||||
if (!PyTuple_GetFloat(poArgs, 3, &fCoolTime))
|
||||
return Py_BuildException();
|
||||
|
||||
float fElapsedTime = 0.0f;
|
||||
PyTuple_GetFloat(poArgs, 4, &fElapsedTime);
|
||||
|
||||
if (!pWin->IsType(UI::CSlotWindow::Type()))
|
||||
return Py_BuildException();
|
||||
|
||||
UI::CSlotWindow* pSlotWin = (UI::CSlotWindow*)pWin;
|
||||
pSlotWin->StoreSlotCoolTime(iKey, iSlotIndex, fCoolTime, fElapsedTime);
|
||||
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject* wndMgrRestoreSlotCoolTime(PyObject* poSelf, PyObject* poArgs)
|
||||
{
|
||||
UI::CWindow* pWin;
|
||||
if (!PyTuple_GetWindow(poArgs, 0, &pWin))
|
||||
return Py_BuildException();
|
||||
|
||||
int iKey;
|
||||
if (!PyTuple_GetInteger(poArgs, 1, &iKey))
|
||||
return Py_BuildException();
|
||||
|
||||
if (!pWin->IsType(UI::CSlotWindow::Type()))
|
||||
return Py_BuildException();
|
||||
|
||||
UI::CSlotWindow* pSlotWin = (UI::CSlotWindow*)pWin;
|
||||
pSlotWin->RestoreSlotCoolTime(iKey);
|
||||
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject* wndMgrTransferSlotCoolTime(PyObject* poSelf, PyObject* poArgs)
|
||||
{
|
||||
UI::CWindow* pWin;
|
||||
if (!PyTuple_GetWindow(poArgs, 0, &pWin))
|
||||
return Py_BuildException();
|
||||
|
||||
int iIndex1;
|
||||
if (!PyTuple_GetInteger(poArgs, 1, &iIndex1))
|
||||
return Py_BuildException();
|
||||
|
||||
int iIndex2;
|
||||
if (!PyTuple_GetInteger(poArgs, 2, &iIndex2))
|
||||
return Py_BuildException();
|
||||
|
||||
if (!pWin->IsType(UI::CSlotWindow::Type()))
|
||||
return Py_BuildException();
|
||||
|
||||
UI::CSlotWindow* pSlotWin = (UI::CSlotWindow*)pWin;
|
||||
pSlotWin->TransferSlotCoolTime(iIndex1, iIndex2);
|
||||
|
||||
return Py_BuildNone();
|
||||
}
|
||||
#endif
|
||||
|
||||
PyObject * wndMgrSetToggleSlot(PyObject * poSelf, PyObject * poArgs)
|
||||
{
|
||||
assert(!"wndMgrSetToggleSlot");
|
||||
@@ -2423,6 +2497,11 @@ void initwndMgr()
|
||||
{ "SetSlotCount", wndMgrSetSlotCount, METH_VARARGS },
|
||||
{ "SetSlotCountNew", wndMgrSetSlotCountNew, METH_VARARGS },
|
||||
{ "SetSlotCoolTime", wndMgrSetSlotCoolTime, METH_VARARGS },
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
{ "StoreSlotCoolTime", wndMgrStoreSlotCoolTime, METH_VARARGS },
|
||||
{ "RestoreSlotCoolTime", wndMgrRestoreSlotCoolTime, METH_VARARGS },
|
||||
{ "TransferSlotCoolTime", wndMgrTransferSlotCoolTime, METH_VARARGS },
|
||||
#endif
|
||||
{ "SetToggleSlot", wndMgrSetToggleSlot, METH_VARARGS },
|
||||
{ "ActivateSlot", wndMgrActivateSlot, METH_VARARGS },
|
||||
{ "DeactivateSlot", wndMgrDeactivateSlot, METH_VARARGS },
|
||||
|
||||
@@ -362,10 +362,22 @@ class CActorInstance : public IActorInstance, public IFlyTargetableObject
|
||||
BOOL IsActEmotion();
|
||||
DWORD GetComboIndex();
|
||||
float GetAttackingElapsedTime();
|
||||
#ifdef FIX_POS_SYNC
|
||||
void SetBlendingPosition(const TPixelPosition& c_rPosition, float fBlendingTime = 1.0f);
|
||||
#else
|
||||
void SetBlendingPosition(const TPixelPosition & c_rPosition, float fBlendingTime = 1.0f);
|
||||
#endif
|
||||
void ResetBlendingPosition();
|
||||
void GetBlendingPosition(TPixelPosition * pPosition);
|
||||
|
||||
#ifdef FIX_POS_SYNC
|
||||
struct BlendingPosition {
|
||||
D3DXVECTOR3 source;
|
||||
D3DXVECTOR3 dest;
|
||||
float duration;
|
||||
};
|
||||
#endif
|
||||
|
||||
BOOL NormalAttack(float fDirRot, float fBlendTime = 0.1f);
|
||||
BOOL ComboAttack(DWORD wMotionIndex, float fDirRot, float fBlendTime = 0.1f);
|
||||
|
||||
@@ -479,6 +491,12 @@ class CActorInstance : public IActorInstance, public IFlyTargetableObject
|
||||
void RenderCollisionData();
|
||||
void RenderToShadowMap();
|
||||
|
||||
#ifdef FIX_POS_SYNC
|
||||
void ClientAttack(DWORD dwVID);
|
||||
void ServerAttack(DWORD dwVID);
|
||||
bool ProcessingClientAttack(DWORD dwVID);
|
||||
bool ServerAttackCameFirst(DWORD dwVID);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void __AdjustCollisionMovement(const CGraphicObjectInstance * c_pGraphicObjectInstance);
|
||||
@@ -497,6 +515,9 @@ class CActorInstance : public IActorInstance, public IFlyTargetableObject
|
||||
float GetHeight();
|
||||
void ShowAllAttachingEffect();
|
||||
void HideAllAttachingEffect();
|
||||
#ifdef __ENABLE_STEALTH_FIX__ //EXP
|
||||
void HideAllAttachingEffectForEunhyeong();
|
||||
#endif
|
||||
void ClearAttachingEffect();
|
||||
|
||||
// Fishing
|
||||
@@ -603,6 +624,10 @@ class CActorInstance : public IActorInstance, public IFlyTargetableObject
|
||||
void __ClearCombo();
|
||||
void __OnEndCombo();
|
||||
|
||||
#ifdef FIX_POS_SYNC
|
||||
void __Push(const TPixelPosition& c_rkPPosDst, unsigned int unDuration);
|
||||
#endif
|
||||
|
||||
void __ProcessDataAttackSuccess(const NRaceData::TAttackData & c_rAttackData, CActorInstance & rVictim, const D3DXVECTOR3 & c_rv3Position, UINT uiSkill = 0, BOOL isSendPacket = TRUE);
|
||||
void __ProcessMotionEventAttackSuccess(DWORD dwMotionKey, BYTE byEventIndex, CActorInstance & rVictim);
|
||||
void __ProcessMotionAttackSuccess(DWORD dwMotionKey, CActorInstance & rVictim);
|
||||
@@ -610,7 +635,11 @@ class CActorInstance : public IActorInstance, public IFlyTargetableObject
|
||||
|
||||
void __HitStone(CActorInstance& rVictim);
|
||||
void __HitGood(CActorInstance& rVictim);
|
||||
#ifdef FIX_POS_SYNC
|
||||
void __HitGreate(CActorInstance& rVictim, UINT uiSkill);
|
||||
#else
|
||||
void __HitGreate(CActorInstance& rVictim);
|
||||
#endif
|
||||
|
||||
void __PushDirect(CActorInstance & rVictim);
|
||||
void __PushCircle(CActorInstance & rVictim);
|
||||
|
||||
@@ -580,27 +580,90 @@ void CActorInstance::ShowAllAttachingEffect()
|
||||
{
|
||||
CEffectManager::Instance().SelectEffectInstance(it->dwEffectIndex);
|
||||
CEffectManager::Instance().ShowEffect();
|
||||
#ifdef __ENABLE_STEALTH_FIX__
|
||||
CEffectManager::Instance().ReleaseAlwaysHidden();
|
||||
//CEffectManager::Instance().Update();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::HideAllAttachingEffect()
|
||||
{
|
||||
std::list<TAttachingEffect>::iterator it;
|
||||
for(it = m_AttachingEffectList.begin(); it!= m_AttachingEffectList.end();++it)
|
||||
|
||||
for(it = m_AttachingEffectList.begin(); it!= m_AttachingEffectList.end(); ++it)
|
||||
{
|
||||
CEffectManager::Instance().SelectEffectInstance(it->dwEffectIndex);
|
||||
CEffectManager::Instance().HideEffect();
|
||||
#ifdef __ENABLE_STEALTH_FIX__
|
||||
CEffectManager::Instance().ApplyAlwaysHidden();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __ENABLE_STEALTH_FIX__ //EXP
|
||||
void CActorInstance::HideAllAttachingEffectForEunhyeong()
|
||||
{
|
||||
std::list<TAttachingEffect>::iterator it;
|
||||
CEffectManager& mgr = CEffectManager::Instance();
|
||||
|
||||
for (it = m_AttachingEffectList.begin(); it != m_AttachingEffectList.end(); ++it)
|
||||
{
|
||||
mgr.SelectEffectInstance(it->dwEffectIndex);
|
||||
DWORD crc = mgr.GetSelectedEffectDataCRC();
|
||||
CEffectData* pData = nullptr;
|
||||
bool isEunh = false;
|
||||
|
||||
if (crc != 0 && mgr.GetEffectData(crc, &pData) && pData)
|
||||
{
|
||||
std::string fname = pData->GetFileName();
|
||||
std::string fnameLower = fname;
|
||||
|
||||
// normalize for case-insensitive search and path separators
|
||||
for (char& c: fnameLower)
|
||||
{
|
||||
if (c == '\\') c = '/';
|
||||
c = (char)tolower((unsigned char)c);
|
||||
}
|
||||
|
||||
// Match any eunhyeongbeop variant (eunhyeongbeop, eunhyeongbeop_2, eunhyeongbeop_3, etc.)
|
||||
if (fnameLower.find("eunhyeongbeop") != std::string::npos)
|
||||
isEunh = true;
|
||||
|
||||
Tracef("Effect Instance %u -> file=%s crc=0x%08X\n", it->dwEffectIndex, fname.c_str(), crc);
|
||||
}
|
||||
else
|
||||
{
|
||||
Tracef("Effect Instance %u -> no effect-data (crc=0x%08X)\n", it->dwEffectIndex, crc);
|
||||
}
|
||||
|
||||
// If this attaching effect is an eunhyeongbeop variant, do NOT hide it (show it).
|
||||
if (isEunh)
|
||||
{
|
||||
mgr.SelectEffectInstance(it->dwEffectIndex);
|
||||
mgr.ShowEffect();
|
||||
mgr.ReleaseAlwaysHidden();
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
CEffectManager::Instance().SelectEffectInstance(it->dwEffectIndex);
|
||||
CEffectManager::Instance().HideEffect();
|
||||
CEffectManager::Instance().ApplyAlwaysHidden();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void CActorInstance::__ClearAttachingEffect()
|
||||
{
|
||||
m_bEffectInitialized = false;
|
||||
|
||||
std::list<TAttachingEffect>::iterator it;
|
||||
for(it = m_AttachingEffectList.begin(); it!= m_AttachingEffectList.end();++it)
|
||||
|
||||
for(it = m_AttachingEffectList.begin(); it!= m_AttachingEffectList.end(); ++it)
|
||||
{
|
||||
CEffectManager::Instance().DestroyEffectInstance(it->dwEffectIndex);
|
||||
}
|
||||
|
||||
m_AttachingEffectList.clear();
|
||||
}
|
||||
|
||||
@@ -314,6 +314,76 @@ void CActorInstance::__ClearCombo()
|
||||
m_pkCurRaceMotionData = NULL;
|
||||
}
|
||||
|
||||
#ifdef FIX_POS_SYNC
|
||||
void CActorInstance::__Push(const TPixelPosition& c_rkPPosDst, unsigned int unDuration)
|
||||
{
|
||||
DWORD dwVID = GetVirtualID();
|
||||
Tracenf("VID %d SyncPixelPosition %f %f", dwVID, c_rkPPosDst.x, c_rkPPosDst.y);
|
||||
|
||||
if (unDuration == 0)
|
||||
unDuration = 1000;
|
||||
|
||||
const D3DXVECTOR3& c_rv3Src = GetPosition();
|
||||
const D3DXVECTOR3 c_v3Delta = c_rkPPosDst - c_rv3Src;
|
||||
|
||||
SetBlendingPosition(c_rkPPostDst, float(unDuration) / 1000);
|
||||
|
||||
if (!IsUsingSkill() && !IsResistFallen())
|
||||
{
|
||||
int len = sqrt(c_v3Delta.x * c_v3Delta.x + c_v3Delta.y * c_v3Delta.y);
|
||||
if (len > 150.0f)
|
||||
{
|
||||
InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE_FLYING);
|
||||
PushOnceMotion(CRaceMotionData::NAME_STAND_UP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CActorInstance::ClientAttack(DWORD dwVID)
|
||||
{
|
||||
if (m_mapAttackSync.find(dwVID) == m_mapAttackSync.end()) {
|
||||
m_mapAttackSync.insert(std::make_pair(dwVID, -1));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_mapAttackSync[dwVID] == 1)
|
||||
{
|
||||
m_mapAttackSync.erase(dwVID);
|
||||
return;
|
||||
}
|
||||
m_mapAttackSync[dwVID]--;
|
||||
}
|
||||
}
|
||||
|
||||
// server attack increases
|
||||
void CActorInstance::ServerAttack(DWORD dwVID)
|
||||
{
|
||||
if (m_mapAttackSync.find(dwVID) == m_mapAttackSync.end()) {
|
||||
m_mapAttackSync.insert(std::make_pair(dwVID, 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_mapAttackSync[dwVID] == -1)
|
||||
{
|
||||
m_mapAttackSync.erase(dwVID);
|
||||
return;
|
||||
}
|
||||
m_mapAttackSync[dwVID]++;
|
||||
}
|
||||
}
|
||||
|
||||
bool CActorInstance::ProcessingClientAttack(DWORD dwVID)
|
||||
{
|
||||
return m_mapAttackSync.find(dwVID) != m_mapAttackSync.end() && m_mapAttackSync[dwVID] < 0;
|
||||
}
|
||||
|
||||
//
|
||||
bool CActorInstance::ServerAttackCameFirst(DWORD dwVID)
|
||||
{
|
||||
return m_mapAttackSync.find(dwVID) != m_mapAttackSync.end() && m_mapAttackSync[dwVID] > 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
BOOL CActorInstance::isAttacking()
|
||||
@@ -610,15 +680,33 @@ void CActorInstance::__ProcessDataAttackSuccess(const NRaceData::TAttackData & c
|
||||
|
||||
InsertDelay(c_rAttackData.fStiffenTime);
|
||||
|
||||
#ifdef FIX_POS_SYNC
|
||||
BlendingPosition sBlending;
|
||||
memset(&sBlending, 0, sizeof(sBlending));
|
||||
sBlending.source = rVictim.NEW_GetCurPixelPositionRef();
|
||||
#endif
|
||||
|
||||
if (__CanPushDestActor(rVictim) && c_rAttackData.fExternalForce > 0.0f)
|
||||
{
|
||||
__PushCircle(rVictim);
|
||||
|
||||
// VICTIM_COLLISION_TEST
|
||||
const D3DXVECTOR3& kVictimPos = rVictim.GetPosition();
|
||||
rVictim.m_PhysicsObject.IncreaseExternalForce(kVictimPos, c_rAttackData.fExternalForce); //*nForceRatio/100.0f);
|
||||
#ifdef FIX_POS_SYNC
|
||||
const bool bServerAttackAlreadyCame = rVictim.ServerAttackCameFirst(GetVirtualID());
|
||||
rVictim.ClientAttack(GetVirtualID());
|
||||
|
||||
// VICTIM_COLLISION_TEST_END
|
||||
if (!bServerAttackAlreadyCame)
|
||||
{
|
||||
#endif
|
||||
__PushCircle(rVictim);
|
||||
|
||||
// VICTIM_COLLISION_TEST
|
||||
const D3DXVECTOR3& kVictimPos = rVictim.GetPosition();
|
||||
rVictim.m_PhysicsObject.IncreaseExternalForce(kVictimPos, c_rAttackData.fExternalForce); //*nForceRatio/100.0f);
|
||||
// VICTIM_COLLISION_TEST_END
|
||||
|
||||
#ifdef FIX_POS_SYNC
|
||||
rVictim.GetBlendingPosition(&(sBlending.dest));
|
||||
sBlending.duration = rVictim.m_PhysicsObject.GetRemainingTime();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Invisible Time
|
||||
@@ -690,7 +778,11 @@ void CActorInstance::__ProcessDataAttackSuccess(const NRaceData::TAttackData & c
|
||||
}
|
||||
else if (NRaceData::HIT_TYPE_GREAT == c_rAttackData.iHittingType)
|
||||
{
|
||||
#ifdef FIX_POS_SYNC
|
||||
__HitGreate(rVictim, uiSkill);
|
||||
#else
|
||||
__HitGreate(rVictim);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -820,10 +912,18 @@ void CActorInstance::__HitGood(CActorInstance& rVictim)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FIX_POS_SYNC
|
||||
void CActorInstance::__HitGreate(CActorInstance& rVictim, UINT uiSkill)
|
||||
#else
|
||||
void CActorInstance::__HitGreate(CActorInstance& rVictim)
|
||||
#endif
|
||||
{
|
||||
// DISABLE_KNOCKDOWN_ATTACK
|
||||
#ifdef FIX_POS_SYNC
|
||||
if (!uiSkill && rVictim.IsKnockDown())
|
||||
#else
|
||||
if (rVictim.IsKnockDown())
|
||||
#endif
|
||||
return;
|
||||
if (rVictim.__IsStandUpMotion())
|
||||
return;
|
||||
@@ -907,16 +1007,24 @@ void CActorInstance::GetBlendingPosition(TPixelPosition * pPosition)
|
||||
{
|
||||
if (m_PhysicsObject.isBlending())
|
||||
{
|
||||
#ifdef FIX_POS_SYNC
|
||||
m_PhysicsObject.GetFinalPosition(pPosition);
|
||||
#else
|
||||
m_PhysicsObject.GetLastPosition(pPosition);
|
||||
pPosition->x += m_x;
|
||||
pPosition->y += m_y;
|
||||
pPosition->z += m_z;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef FIX_POS_SYNC
|
||||
GetPixelPosition(pPosition);
|
||||
#else
|
||||
pPosition->x = m_x;
|
||||
pPosition->y = m_y;
|
||||
pPosition->z = m_z;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "EterLib/GrpSubImage.h"
|
||||
#include "EterGrnLib/Thing.h"
|
||||
#include "GameType.h"
|
||||
|
||||
class CItemData
|
||||
{
|
||||
|
||||
@@ -107,6 +107,32 @@ void CPhysicsObject::IncreaseExternalForce(const D3DXVECTOR3 & c_rvBasePosition,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FIX_POS_SYNC
|
||||
void CPhysicsObject::SetLastPosition(const TPixelPosition& c_rPosition, const TPixelPosition& c_rDeltaPosition, float fBlendingTime)
|
||||
{
|
||||
m_v3FinalPosition.x = float(c_rPosition.x + c_rDeltaPosition.x);
|
||||
m_v3FinalPosition.y = float(c_rPosition.y + c_rDeltaPosition.y);
|
||||
m_v3FinalPosition.z = float(c_rPosition.z + c_rDeltaPosition.z);
|
||||
m_v3DeltaPosition.x = float(c_rDeltaPosition.x);
|
||||
m_v3DeltaPosition.y = float(c_rDeltaPosition.y);
|
||||
m_v3DeltaPosition.z = float(c_rDeltaPosition.z);
|
||||
m_xPushingPosition.Setup(0.0f, c_rDeltaPosition.x, fBlendingTime);
|
||||
m_yPushingPosition.Setup(0.0f, c_rDeltaPosition.y, fBlendingTime);
|
||||
}
|
||||
void CPhysicsObject::GetFinalPosition(TPixelPosition* pPosition)
|
||||
{
|
||||
pPosition->x = (m_v3FinalPosition.x);
|
||||
pPosition->y = (m_v3FinalPosition.y);
|
||||
pPosition->z = (m_v3FinalPosition.z);
|
||||
}
|
||||
|
||||
void CPhysicsObject::GetDeltaPosition(TPixelPosition* pPosition)
|
||||
{
|
||||
pPosition->x = (m_v3DeltaPosition.x);
|
||||
pPosition->y = (m_v3DeltaPosition.y);
|
||||
pPosition->z = (m_v3DeltaPosition.z);
|
||||
}
|
||||
#else
|
||||
void CPhysicsObject::SetLastPosition(const TPixelPosition & c_rPosition, float fBlendingTime)
|
||||
{
|
||||
m_v3LastPosition.x = float(c_rPosition.x);
|
||||
@@ -115,6 +141,7 @@ void CPhysicsObject::SetLastPosition(const TPixelPosition & c_rPosition, float f
|
||||
m_xPushingPosition.Setup(0.0f, c_rPosition.x, fBlendingTime);
|
||||
m_yPushingPosition.Setup(0.0f, c_rPosition.y, fBlendingTime);
|
||||
}
|
||||
#endif
|
||||
|
||||
void CPhysicsObject::GetLastPosition(TPixelPosition * pPosition)
|
||||
{
|
||||
|
||||
@@ -71,7 +71,13 @@ class CPhysicsObject
|
||||
|
||||
void SetDirection(const D3DXVECTOR3 & c_rv3Direction);
|
||||
void IncreaseExternalForce(const D3DXVECTOR3 & c_rvBasePosition, float fForce);
|
||||
void SetLastPosition(const TPixelPosition & c_rPosition, float fBlendingTime);
|
||||
#ifdef FIX_POS_SYNC
|
||||
void SetLastPosition(const TPixelPosition& c_rPosition, const TPixelPosition& c_rDeltaPosition, float fBlendingTime);
|
||||
void GetFinalPosition(TPixelPosition* pPosition);
|
||||
void GetDeltaPosition(TPixelPosition* pPosition);
|
||||
#else
|
||||
void SetLastPosition(const TPixelPosition& c_rPosition, float fBlendingTime);
|
||||
#endif
|
||||
void GetLastPosition(TPixelPosition * pPosition);
|
||||
|
||||
float GetXMovement();
|
||||
@@ -92,6 +98,10 @@ class CPhysicsObject
|
||||
D3DXVECTOR3 m_v3Velocity;
|
||||
|
||||
D3DXVECTOR3 m_v3LastPosition;
|
||||
#ifdef FIX_POS_SYNC
|
||||
D3DXVECTOR3 m_v3FinalPosition;
|
||||
D3DXVECTOR3 m_v3DeltaPosition;
|
||||
#endif
|
||||
CEaseOutInterpolation m_xPushingPosition;
|
||||
CEaseOutInterpolation m_yPushingPosition;
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#include "AudioLib/StdAfx.h"
|
||||
#include "EffectLib/StdAfx.h"
|
||||
|
||||
#include "UserInterface/Locale_inc.h"
|
||||
|
||||
#include "GameType.h"
|
||||
#include "GameUtil.h"
|
||||
#include "MapType.h"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "AbstractSingleton.h"
|
||||
#include "GameType.h"
|
||||
|
||||
class CInstanceBase;
|
||||
|
||||
|
||||
@@ -448,7 +448,11 @@ BOOL CInstanceBase::IsMovieMode()
|
||||
|
||||
BOOL CInstanceBase::IsInvisibility()
|
||||
{
|
||||
#ifdef __ENABLE_STEALTH_FIX__
|
||||
if (IsAffect(AFFECT_INVISIBILITY) || IsAffect(AFFECT_EUNHYEONG) || IsAffect(AFFECT_REVIVE_INVISIBILITY))
|
||||
#else
|
||||
if (IsAffect(AFFECT_INVISIBILITY))
|
||||
#endif
|
||||
return true;
|
||||
|
||||
return false;
|
||||
@@ -1556,7 +1560,11 @@ void CInstanceBase::StateProcess()
|
||||
SetAdvancingRotation(fRotDst);
|
||||
SetRotation(fRotDst);
|
||||
|
||||
#ifdef FIX_POS_SYNC
|
||||
NEW_UseSkill(1, eFunc& FUNC_SKILL - 1, uArg & 0x0f, (uArg >> 4) ? true : false);
|
||||
#else
|
||||
NEW_UseSkill(0, eFunc & 0x7f, uArg&0x0f, (uArg>>4) ? true : false);
|
||||
#endif
|
||||
//Tracen("가깝기 때문에 워프 공격");
|
||||
}
|
||||
}
|
||||
@@ -1734,7 +1742,11 @@ void CInstanceBase::MovementProcess()
|
||||
{
|
||||
SetAdvancingRotation(m_fDstRot);
|
||||
BlendRotation(m_fDstRot);
|
||||
#ifdef FIX_POS_SYNC
|
||||
NEW_UseSkill(1, m_kMovAfterFunc.eFunc& FUNC_SKILL - 1, m_kMovAfterFunc.uArg & 0x0f, (m_kMovAfterFunc.uArg >> 4) ? true : false);
|
||||
#else
|
||||
NEW_UseSkill(0, m_kMovAfterFunc.eFunc & 0x7f, m_kMovAfterFunc.uArg&0x0f, (m_kMovAfterFunc.uArg>>4) ? true : false);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1790,7 +1802,11 @@ void CInstanceBase::MovementProcess()
|
||||
m_GraphicThingInstance.SetRotation(fRotation);
|
||||
}
|
||||
|
||||
#ifdef __ENABLE_STEALTH_FIX__
|
||||
if (__IsInDustRange() && !IsAffect(AFFECT_INVISIBILITY) && !IsAffect(AFFECT_EUNHYEONG) && !IsAffect(AFFECT_REVIVE_INVISIBILITY))
|
||||
#else
|
||||
if (__IsInDustRange())
|
||||
#endif
|
||||
{
|
||||
float fDustDistance = NEW_GetDistanceFromDestPixelPosition(m_kPPosDust);
|
||||
if (IsMountingHorse())
|
||||
@@ -1906,7 +1922,7 @@ void CInstanceBase::Update()
|
||||
}
|
||||
|
||||
__ComboProcess();
|
||||
|
||||
|
||||
ProcessDamage();
|
||||
|
||||
}
|
||||
@@ -1968,7 +1984,30 @@ void CInstanceBase::Render()
|
||||
++ms_dwRenderCounter;
|
||||
|
||||
m_kHorse.Render();
|
||||
m_GraphicThingInstance.Render();
|
||||
m_GraphicThingInstance.Render();
|
||||
|
||||
#ifdef __ENABLE_STEALTH_FIX__
|
||||
CPythonCharacterManager& rkChrMgr = CPythonCharacterManager::Instance();
|
||||
|
||||
for (auto ptr = rkChrMgr.CharacterInstanceBegin(); ptr != rkChrMgr.CharacterInstanceEnd(); ++ptr)
|
||||
{
|
||||
CInstanceBase* pkInstEach = *ptr;
|
||||
|
||||
if (pkInstEach)
|
||||
{
|
||||
if (pkInstEach->IsAffect(AFFECT_INVISIBILITY) || pkInstEach->IsAffect(AFFECT_EUNHYEONG) || pkInstEach->IsAffect(AFFECT_REVIVE_INVISIBILITY))
|
||||
{
|
||||
if (CPythonPlayer::Instance().IsMainCharacterIndex(pkInstEach->GetVirtualID()))
|
||||
continue;
|
||||
|
||||
if (pkInstEach->IsAffect(AFFECT_EUNHYEONG) && !pkInstEach->IsAffect(AFFECT_INVISIBILITY) && !pkInstEach->IsAffect(AFFECT_REVIVE_INVISIBILITY))
|
||||
pkInstEach->m_GraphicThingInstance.HideAllAttachingEffectForEunhyeong();
|
||||
else
|
||||
pkInstEach->m_GraphicThingInstance.HideAllAttachingEffect();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (CActorInstance::IsDirLine())
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "GameLib/RaceData.h"
|
||||
#include "GameLib/ActorInstance.h"
|
||||
|
||||
#include "StdAfx.h"
|
||||
#include "AffectFlagContainer.h"
|
||||
|
||||
class CInstanceBase
|
||||
@@ -632,6 +633,11 @@ class CInstanceBase
|
||||
bool NEW_AttackToDestInstanceDirection(CInstanceBase& rkInstDst, IFlyEventHandler* pkFlyHandler);
|
||||
bool NEW_AttackToDestInstanceDirection(CInstanceBase& rkInstDst);
|
||||
|
||||
#ifdef FIX_POS_SYNC
|
||||
void ServerAttack(DWORD dwVID);
|
||||
bool ProcessingClientAttack(DWORD dwVID);
|
||||
#endif
|
||||
|
||||
bool NEW_MoveToDestPixelPositionDirection(const TPixelPosition& c_rkPPosDst);
|
||||
void NEW_MoveToDestInstanceDirection(CInstanceBase& rkInstDst);
|
||||
void NEW_MoveToDirection(float fDirRot);
|
||||
|
||||
@@ -410,6 +410,18 @@ bool CInstanceBase::NEW_AttackToDestInstanceDirection(CInstanceBase& rkInstDst)
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef FIX_POS_SYNC
|
||||
void CInstanceBase::ServerAttack(DWORD dwVID)
|
||||
{
|
||||
m_GraphicThingInstance.ServerAttack(dwVID);
|
||||
}
|
||||
|
||||
bool CInstanceBase::ProcessingClientAttack(DWORD dwVID)
|
||||
{
|
||||
return m_GraphicThingInstance.ProcessingClientAttack(dwVID);
|
||||
}
|
||||
#endif
|
||||
|
||||
void CInstanceBase::AttackProcess()
|
||||
{
|
||||
if (!m_GraphicThingInstance.CanCheckAttacking())
|
||||
|
||||
@@ -84,7 +84,7 @@ const D3DXCOLOR& CInstanceBase::GetIndexedNameColor(UINT eNameColor)
|
||||
return g_akD3DXClrName[eNameColor];
|
||||
}
|
||||
|
||||
void CInstanceBase::AddDamageEffect(DWORD damage,BYTE flag,BOOL bSelf,BOOL bTarget)
|
||||
void CInstanceBase::AddDamageEffect(DWORD damage, BYTE flag, BOOL bSelf, BOOL bTarget)
|
||||
{
|
||||
if(CPythonSystem::Instance().IsShowDamage())
|
||||
{
|
||||
@@ -149,19 +149,26 @@ void CInstanceBase::ProcessDamage()
|
||||
else
|
||||
*/
|
||||
{
|
||||
if(bSelf)
|
||||
if (bSelf)
|
||||
{
|
||||
strDamageType = "damage_";
|
||||
if(m_bDamageEffectType==0)
|
||||
|
||||
if (m_bDamageEffectType == 0)
|
||||
rdwCRCEft = EFFECT_DAMAGE_SELFDAMAGE;
|
||||
else
|
||||
rdwCRCEft = EFFECT_DAMAGE_SELFDAMAGE2;
|
||||
|
||||
m_bDamageEffectType = !m_bDamageEffectType;
|
||||
}
|
||||
else if(bTarget == false)
|
||||
#ifdef __ENABLE_STEALTH_FIX__ //EXP
|
||||
else if (!bTarget || ((IsAffect(AFFECT_INVISIBILITY) || IsAffect(AFFECT_EUNHYEONG)) && bTarget))
|
||||
#else
|
||||
else if (bTarget == false)
|
||||
#endif
|
||||
{
|
||||
strDamageType = "nontarget_";
|
||||
rdwCRCEft = EFFECT_DAMAGE_NOT_TARGET;
|
||||
|
||||
return;//현재 적용 안됨.
|
||||
}
|
||||
else
|
||||
@@ -174,34 +181,41 @@ void CInstanceBase::ProcessDamage()
|
||||
DWORD index = 0;
|
||||
DWORD num = 0;
|
||||
std::vector<std::string> textures;
|
||||
while(damage>0)
|
||||
|
||||
while (damage > 0)
|
||||
{
|
||||
if(index > 7)
|
||||
if (index > 7)
|
||||
{
|
||||
TraceError("ProcessDamage무한루프 가능성");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
num = damage%10;
|
||||
damage /= 10;
|
||||
char numBuf[MAX_PATH];
|
||||
sprintf(numBuf,"%d.dds",num);
|
||||
textures.push_back("d:/ymir work/effect/affect/damagevalue/"+strDamageType+numBuf);
|
||||
sprintf(numBuf, "%d.dds", num);
|
||||
textures.push_back("d:/ymir work/effect/affect/damagevalue/" +strDamageType + numBuf);
|
||||
|
||||
rkEftMgr.SetEffectTextures(ms_adwCRCAffectEffect[rdwCRCEft],textures);
|
||||
|
||||
D3DXMATRIX matrix,matTrans;
|
||||
D3DXMATRIX matrix, matTrans;
|
||||
D3DXMatrixIdentity(&matrix);
|
||||
|
||||
matrix._41 = v3Pos.x;
|
||||
matrix._42 = v3Pos.y;
|
||||
matrix._43 = v3Pos.z;
|
||||
D3DXMatrixTranslation(&matrix,v3Pos.x,v3Pos.y,v3Pos.z);
|
||||
D3DXMatrixMultiply(&matrix,&pCamera->GetInverseViewMatrix(),&matrix);
|
||||
D3DXMatrixTranslation(&matTrans,FONT_WIDTH*index,0,0);
|
||||
|
||||
D3DXMatrixTranslation(&matrix, v3Pos.x, v3Pos.y, v3Pos.z);
|
||||
D3DXMatrixMultiply(&matrix, &pCamera->GetInverseViewMatrix(), &matrix);
|
||||
D3DXMatrixTranslation(&matTrans, FONT_WIDTH * index, 0, 0);
|
||||
|
||||
matTrans._41 = -matTrans._41;
|
||||
matrix = matTrans*matrix;
|
||||
D3DXMatrixMultiply(&matrix,&pCamera->GetViewMatrix(),&matrix);
|
||||
|
||||
D3DXMatrixMultiply(&matrix, &pCamera->GetViewMatrix(), &matrix);
|
||||
|
||||
rkEftMgr.CreateEffect(ms_adwCRCAffectEffect[rdwCRCEft],D3DXVECTOR3(matrix._41,matrix._42,matrix._43)
|
||||
rkEftMgr.CreateEffect(ms_adwCRCAffectEffect[rdwCRCEft], D3DXVECTOR3(matrix._41, matrix._42, matrix._43)
|
||||
,v3Rot);
|
||||
|
||||
textures.clear();
|
||||
@@ -784,11 +798,31 @@ void CInstanceBase::__SetReviveInvisibilityAffect(bool isVisible)
|
||||
if (IsWearingDress())
|
||||
return;
|
||||
|
||||
m_GraphicThingInstance.BlendAlphaValue(0.5f, 1.0f);
|
||||
#ifdef __ENABLE_STEALTH_FIX__
|
||||
if (__IsMainInstance() || __MainCanSeeHiddenThing())
|
||||
{
|
||||
#endif
|
||||
m_GraphicThingInstance.BlendAlphaValue(0.5f, 1.0f);
|
||||
#ifdef __ENABLE_STEALTH_FIX__
|
||||
}
|
||||
else
|
||||
{
|
||||
m_GraphicThingInstance.BlendAlphaValue(0.0f, 1.0f);
|
||||
m_GraphicThingInstance.HideAllAttachingEffect();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
m_GraphicThingInstance.BlendAlphaValue(1.0f, 1.0f);
|
||||
#ifdef __ENABLE_STEALTH_FIX__
|
||||
if (!IsAffect(AFFECT_EUNHYEONG) && !IsAffect(AFFECT_INVISIBILITY))
|
||||
{
|
||||
#endif
|
||||
m_GraphicThingInstance.BlendAlphaValue(1.0f, 1.0f);
|
||||
#ifdef __ENABLE_STEALTH_FIX__
|
||||
m_GraphicThingInstance.ShowAllAttachingEffect();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -808,13 +842,26 @@ void CInstanceBase::__Assassin_SetEunhyeongAffect(bool isVisible)
|
||||
{
|
||||
// 2004.10.16.myevan.은형법 완전 투명
|
||||
m_GraphicThingInstance.BlendAlphaValue(0.0f, 1.0f);
|
||||
m_GraphicThingInstance.HideAllAttachingEffect();
|
||||
#ifdef __ENABLE_STEALTH_FIX__ //EXP
|
||||
if (!IsAffect(AFFECT_INVISIBILITY) && !IsAffect(AFFECT_REVIVE_INVISIBILITY))
|
||||
m_GraphicThingInstance.HideAllAttachingEffectForEunhyeong();
|
||||
else
|
||||
#endif
|
||||
m_GraphicThingInstance.HideAllAttachingEffect();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_GraphicThingInstance.BlendAlphaValue(1.0f, 1.0f);
|
||||
m_GraphicThingInstance.ShowAllAttachingEffect();
|
||||
#ifdef __ENABLE_STEALTH_FIX__
|
||||
if (!IsAffect(AFFECT_REVIVE_INVISIBILITY) && !IsAffect(AFFECT_INVISIBILITY))
|
||||
{
|
||||
#endif
|
||||
m_GraphicThingInstance.BlendAlphaValue(1.0f, 1.0f);
|
||||
m_GraphicThingInstance.ShowAllAttachingEffect();
|
||||
#ifdef __ENABLE_STEALTH_FIX__
|
||||
ProcessDamage();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -823,8 +870,6 @@ void CInstanceBase::__Shaman_SetParalysis(bool isParalysis)
|
||||
m_GraphicThingInstance.SetParalysis(isParalysis);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CInstanceBase::__Warrior_SetGeomgyeongAffect(bool isVisible)
|
||||
{
|
||||
if (isVisible)
|
||||
@@ -895,7 +940,11 @@ void CInstanceBase::__SetAffect(UINT eAffect, bool isVisible)
|
||||
return;
|
||||
break;
|
||||
case AFFECT_REVIVE_INVISIBILITY:
|
||||
#ifdef __ENABLE_STEALTH_FIX__
|
||||
__SetReviveInvisibilityAffect(isVisible);
|
||||
#else
|
||||
__Assassin_SetEunhyeongAffect(isVisible);
|
||||
#endif
|
||||
break;
|
||||
case AFFECT_EUNHYEONG:
|
||||
__Assassin_SetEunhyeongAffect(isVisible);
|
||||
@@ -911,15 +960,28 @@ void CInstanceBase::__SetAffect(UINT eAffect, bool isVisible)
|
||||
// 2004.07.17.levites.isShow를 ViewFrustumCheck로 변경
|
||||
if (isVisible)
|
||||
{
|
||||
#ifndef __ENABLE_STEALTH_FIX__
|
||||
m_GraphicThingInstance.ClearAttachingEffect();
|
||||
__EffectContainer_Destroy();
|
||||
DetachTextTail();
|
||||
#else
|
||||
m_GraphicThingInstance.HideAllAttachingEffect();
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef __ENABLE_STEALTH_FIX__
|
||||
if (!IsAffect(AFFECT_EUNHYEONG) && !IsAffect(AFFECT_REVIVE_INVISIBILITY))
|
||||
{
|
||||
m_GraphicThingInstance.BlendAlphaValue(1.0f, 1.0f);
|
||||
m_GraphicThingInstance.ShowAllAttachingEffect();
|
||||
ProcessDamage();
|
||||
}
|
||||
#else
|
||||
m_GraphicThingInstance.BlendAlphaValue(1.0f, 1.0f);
|
||||
AttachTextTail();
|
||||
RefreshTextTail();
|
||||
#endif
|
||||
}
|
||||
return;
|
||||
break;
|
||||
|
||||
@@ -259,8 +259,8 @@ struct SLOCALEDATA
|
||||
const char* szSecurityKey;
|
||||
} gs_stLocaleData[] = {
|
||||
{ LSS_YMIR, "ymir", 949, "testtesttesttest" }, // Korea
|
||||
{ LSS_EUROPE, "de", 1252, "1234abcd5678efgh" }, // GameForge (Germany)
|
||||
{ LSS_EUROPE, "en", 1252, "1234abcd5678efgh" }, // GameForge (United Kingdom)
|
||||
{ LSS_EUROPE, "de", 1252, "1234abcd5678efgh" }, // GameForge (Germany)
|
||||
{ LSS_EUROPE, "us", 1252, "1234abcd5678efgh" }, // GameForge (USA)
|
||||
{ LSS_EUROPE, "es", 1252, "1234abcd5678efgh" }, // GameForge (Spain)
|
||||
{ LSS_EUROPE, "it", 1252, "1234abcd5678efgh" }, // GameForge (Italy)
|
||||
|
||||
@@ -6,3 +6,14 @@
|
||||
#define ENABLE_DRAGON_SOUL_SYSTEM
|
||||
#define ENABLE_NEW_EQUIPMENT_SYSTEM
|
||||
//#define ENABLE_DISCORD_RPC
|
||||
|
||||
// Fixes
|
||||
#define FIX_MESSENGER_ACTION_SYNC
|
||||
#define FIX_REFRESH_SKILL_COOLDOWN
|
||||
#define FIX_SEQ_254
|
||||
#define CHAR_SELECT_STATS_IMPROVEMENT // Improve stats values in character select screen
|
||||
#define __ENABLE_STEALTH_FIX__
|
||||
//#define FIX_POS_SYNC
|
||||
|
||||
// Python-only
|
||||
#define FIX_HORSE_SKILLS_TAB
|
||||
|
||||
@@ -536,6 +536,41 @@ void CNetworkActorManager::MoveActor(const SNetworkMoveActorData& c_rkNetMoveAct
|
||||
rkNetActorData.m_fRot=c_rkNetMoveActorData.m_fRot;
|
||||
}
|
||||
|
||||
#ifdef FIX_POS_SYNC
|
||||
void CNetworkActorManager::AttackActor(DWORD dwVID, DWORD dwAttacakerVID, LONG lDestPosX, LONG lDestPosY, const TPixelPosition& k_pSyncPos, DWORD dwBlendDuration)
|
||||
{
|
||||
std::map<DWORD, SNetworkActorData>::iterator f = m_kNetActorDict.find(dwVID);
|
||||
if (m_kNetActorDict.end() == f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SNetworkActorData& rkNetActorData = f->second;
|
||||
|
||||
if (k_pSyncPos.x && k_pSyncPos.y) {
|
||||
CInstanceBase* pkInstFind = __FindActor(rkNetActorData);
|
||||
|
||||
if (pkInstFind)
|
||||
{
|
||||
const bool bProcessingClientAttack = pkInstFind->ProcessingClientAttack(dwAttacakerVID);
|
||||
pkInstFind->ServerAttack(dwAttacakerVID);
|
||||
|
||||
// if already blending, update
|
||||
if (bProcessingClientAttack && pkInstFind->IsPushing() && pkInstFind->GetBlendingRemainTime() > 0.15) {
|
||||
pkInstFind->SetBlendingPosition(k_pSyncPos, pkInstFind->GetBlendingRemainTime());
|
||||
}
|
||||
else {
|
||||
// otherwise sync
|
||||
//pkInstFind->SCRIPT_SetPixelPosition(k_pSyncPos.x, k_pSyncPos.y);
|
||||
pkInstFind->NEW_SyncPixelPosition(k_pSyncPos, dwBlendDuration);
|
||||
}
|
||||
}
|
||||
|
||||
rkNetActorData.SetPosition(long(k_pSyncPos.x), long(k_pSyncPos.y));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void CNetworkActorManager::SyncActor(DWORD dwVID, LONG lPosX, LONG lPosY)
|
||||
{
|
||||
std::map<DWORD, SNetworkActorData>::iterator f=m_kNetActorDict.find(dwVID);
|
||||
|
||||
@@ -127,6 +127,10 @@ class CNetworkActorManager : public CReferenceObject
|
||||
void UpdateActor(const SNetworkUpdateActorData& c_rkNetUpdateActorData);
|
||||
void MoveActor(const SNetworkMoveActorData& c_rkNetMoveActorData);
|
||||
|
||||
#ifdef FIX_POS_SYNC
|
||||
void AttackActor(DWORD dwVID, DWORD dwAttacakerVID, LONG lDestPosX, LONG lDestPosY, const TPixelPosition& k_pSyncPos, DWORD dwBlendDuration);
|
||||
#endif
|
||||
|
||||
void SyncActor(DWORD dwVID, LONG lPosX, LONG lPosY);
|
||||
void SetActorOwner(DWORD dwOwnerVID, DWORD dwVictimVID);
|
||||
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
#pragma once
|
||||
#include "Gamelib/RaceData.h"
|
||||
#include "StdAfx.h"
|
||||
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
#include "GameType.h"
|
||||
#endif
|
||||
|
||||
typedef uint8_t TPacketHeader;
|
||||
|
||||
@@ -511,6 +516,18 @@ typedef struct command_attack
|
||||
uint32_t dwVictimVID; // 적 VID
|
||||
uint8_t bCRCMagicCubeProcPiece;
|
||||
uint8_t bCRCMagicCubeFilePiece;
|
||||
#ifdef FIX_POS_SYNC
|
||||
BOOL bPacket;
|
||||
LONG lSX;
|
||||
LONG lSY;
|
||||
LONG lX;
|
||||
LONG lY;
|
||||
float fSyncDestX;
|
||||
float fSyncDestY;
|
||||
DWORD dwBlendDuration;
|
||||
DWORD dwComboMotion;
|
||||
DWORD dwTime;
|
||||
#endif
|
||||
} TPacketCGAttack;
|
||||
|
||||
typedef struct command_chat
|
||||
@@ -730,6 +747,9 @@ enum
|
||||
MESSENGER_SUBHEADER_GC_LOGOUT,
|
||||
MESSENGER_SUBHEADER_GC_INVITE,
|
||||
MESSENGER_SUBHEADER_GC_MOBILE,
|
||||
#ifdef FIX_MESSENGER_ACTION_SYNC
|
||||
MESSENGER_SUBHEADER_GC_REMOVE_FRIEND
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct packet_messenger
|
||||
@@ -1862,6 +1882,16 @@ typedef struct packet_attack
|
||||
uint32_t dwVID;
|
||||
uint32_t dwVictimVID; // 적 VID
|
||||
uint8_t bType; // 공격 유형
|
||||
#ifdef FIX_POS_SYNC
|
||||
BOOL bPacket;
|
||||
LONG lSX;
|
||||
LONG lSY;
|
||||
LONG lX;
|
||||
LONG lY;
|
||||
float fSyncDestX;
|
||||
float fSyncDestY;
|
||||
DWORD dwBlendDuration;
|
||||
#endif
|
||||
} TPacketGCAttack;
|
||||
|
||||
typedef struct packet_c2c
|
||||
|
||||
@@ -1305,7 +1305,6 @@ void initapp()
|
||||
{ "OnLogoRender", appLogoRender, METH_VARARGS },
|
||||
{ "OnLogoOpen", appLogoOpen, METH_VARARGS },
|
||||
{ "OnLogoClose", appLogoClose, METH_VARARGS },
|
||||
|
||||
|
||||
{ NULL, NULL },
|
||||
};
|
||||
@@ -1490,4 +1489,22 @@ void initapp()
|
||||
#else
|
||||
PyModule_AddIntConstant(poModule, "ENABLE_NEW_EQUIPMENT_SYSTEM", 0);
|
||||
#endif
|
||||
|
||||
#ifdef FIX_MESSENGER_ACTION_SYNC
|
||||
PyModule_AddIntConstant(poModule, "FIX_MESSENGER_ACTION_SYNC", 1);
|
||||
#else
|
||||
PyModule_AddIntConstant(poModule, "FIX_MESSENGER_ACTION_SYNC", 0);
|
||||
#endif
|
||||
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
PyModule_AddIntConstant(poModule, "FIX_REFRESH_SKILL_COOLDOWN", 1);
|
||||
#else
|
||||
PyModule_AddIntConstant(poModule, "FIX_REFRESH_SKILL_COOLDOWN", 0);
|
||||
#endif
|
||||
|
||||
#ifdef FIX_HORSE_SKILLS_TAB
|
||||
PyModule_AddIntConstant(poModule, "FIX_HORSE_SKILLS_TAB", 1);
|
||||
#else
|
||||
PyModule_AddIntConstant(poModule, "FIX_HORSE_SKILLS_TAB", 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
void CPythonMessenger::RemoveFriend(const char * c_szKey)
|
||||
{
|
||||
m_FriendNameMap.erase(c_szKey);
|
||||
|
||||
#ifdef FIX_MESSENGER_ACTION_SYNC
|
||||
if (m_poMessengerHandler)
|
||||
PyCallClassMemberFunc(m_poMessengerHandler, "OnRemoveList", Py_BuildValue("(is)", MESSENGER_GRUOP_INDEX_FRIEND, c_szKey));
|
||||
#endif
|
||||
}
|
||||
|
||||
void CPythonMessenger::OnFriendLogin(const char * c_szKey/*, const char * c_szName*/)
|
||||
@@ -161,6 +166,7 @@ void initMessenger()
|
||||
{ "Destroy", messengerDestroy, METH_VARARGS },
|
||||
{ "RefreshGuildMember", messengerRefreshGuildMember, METH_VARARGS },
|
||||
{ "SetMessengerHandler", messengerSetMessengerHandler, METH_VARARGS },
|
||||
|
||||
{ NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
|
||||
class CPythonMessenger : public CSingleton<CPythonMessenger>
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -662,10 +662,14 @@ bool CPythonNetworkStream::RecvPingPacket()
|
||||
if (!Send(sizeof(TPacketCGPong), &kPacketPong))
|
||||
return false;
|
||||
|
||||
#ifdef FIX_SEQ_254
|
||||
return SendSequence();
|
||||
#else
|
||||
if (IsSecurityMode())
|
||||
return SendSequence();
|
||||
else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CPythonNetworkStream::RecvDefaultPacket(int header)
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
|
||||
#include "packet.h"
|
||||
|
||||
#ifdef FIX_POS_SYNC
|
||||
#include <GameLib/ActorInstance.h>
|
||||
#endif
|
||||
|
||||
class CInstanceBase;
|
||||
class CNetworkActorManager;
|
||||
struct SNetworkActorData;
|
||||
@@ -136,7 +140,11 @@ class CPythonNetworkStream : public CNetworkStream, public CSingleton<CPythonNet
|
||||
|
||||
bool SendSyncPositionElementPacket(DWORD dwVictimVID, DWORD dwVictimX, DWORD dwVictimY);
|
||||
|
||||
#ifdef FIX_POS_SYNC
|
||||
bool SendAttackPacket(UINT uMotAttack, DWORD dwVIDVictim, BOOL bPacket, CActorInstance::BlendingPosition& sBlending);
|
||||
#else
|
||||
bool SendAttackPacket(UINT uMotAttack, DWORD dwVIDVictim);
|
||||
#endif
|
||||
bool SendCharacterStatePacket(const TPixelPosition& c_rkPPosDst, float fDstRot, UINT eFunc, UINT uArg);
|
||||
bool SendUseSkillPacket(DWORD dwSkillIndex, DWORD dwTargetVID=0);
|
||||
bool SendTargetPacket(DWORD dwVID);
|
||||
@@ -478,6 +486,9 @@ class CPythonNetworkStream : public CNetworkStream, public CSingleton<CPythonNet
|
||||
bool RecvTargetPacket();
|
||||
bool RecvViewEquipPacket();
|
||||
bool RecvDamageInfoPacket();
|
||||
#ifdef FIX_POS_SYNC
|
||||
bool RecvCharacterAttackPacket();
|
||||
#endif
|
||||
|
||||
// Mount
|
||||
bool RecvMountPacket();
|
||||
|
||||
@@ -1495,7 +1495,18 @@ bool CPythonNetworkStream::RecvPointChange()
|
||||
case POINT_STAT_RESET_COUNT:
|
||||
__RefreshStatus();
|
||||
break;
|
||||
#ifdef CHAR_SELECT_STATS_IMPROVEMENT
|
||||
case POINT_PLAYTIME:
|
||||
m_akSimplePlayerInfo[m_dwSelectedCharacterIndex].dwPlayMinutes = PointChange.value;
|
||||
break;
|
||||
case POINT_LEVEL:
|
||||
m_akSimplePlayerInfo[m_dwSelectedCharacterIndex].byLevel = PointChange.value;
|
||||
__RefreshStatus();
|
||||
__RefreshSkillWindow();
|
||||
break;
|
||||
#else
|
||||
case POINT_LEVEL:
|
||||
#endif
|
||||
case POINT_ST:
|
||||
case POINT_DX:
|
||||
case POINT_HT:
|
||||
@@ -2332,16 +2343,19 @@ bool CPythonNetworkStream::RecvSkillCoolTimeEnd()
|
||||
bool CPythonNetworkStream::RecvSkillLevel()
|
||||
{
|
||||
assert(!"CPythonNetworkStream::RecvSkillLevel - 사용하지 않는 함수");
|
||||
|
||||
TPacketGCSkillLevel packet;
|
||||
|
||||
if (!Recv(sizeof(TPacketGCSkillLevel), &packet))
|
||||
{
|
||||
Tracen("CPythonNetworkStream::RecvSkillLevel - RecvError");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD dwSlotIndex;
|
||||
CPythonPlayer& rkPlayer = CPythonPlayer::Instance();
|
||||
|
||||
CPythonPlayer& rkPlayer=CPythonPlayer::Instance();
|
||||
for (int i = 0; i < SKILL_MAX_NUM; ++i)
|
||||
{
|
||||
if (rkPlayer.GetSkillSlotIndex(i, &dwSlotIndex))
|
||||
@@ -2350,7 +2364,9 @@ bool CPythonNetworkStream::RecvSkillLevel()
|
||||
|
||||
__RefreshSkillWindow();
|
||||
__RefreshStatus();
|
||||
|
||||
Tracef(" >> RecvSkillLevel\n");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2364,7 +2380,7 @@ bool CPythonNetworkStream::RecvSkillLevelNew()
|
||||
return false;
|
||||
}
|
||||
|
||||
CPythonPlayer& rkPlayer=CPythonPlayer::Instance();
|
||||
CPythonPlayer& rkPlayer = CPythonPlayer::Instance();
|
||||
|
||||
rkPlayer.SetSkill(7, 0);
|
||||
rkPlayer.SetSkill(8, 0);
|
||||
@@ -2412,6 +2428,31 @@ bool CPythonNetworkStream::RecvDamageInfoPacket()
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef FIX_POS_SYNC
|
||||
bool CPythonNetworkStream::RecvCharacterAttackPacket()
|
||||
{
|
||||
TPacketGCAttack kPacket;
|
||||
|
||||
if (!Recv(sizeof(TPacketGCAttack), &kPacket))
|
||||
{
|
||||
Tracen("CPythonNetworkStream::RecvCharacterAttackPacket - PACKET READ ERROR");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (kPacket.lX && kPacket.lY) {
|
||||
__GlobalPositionToLocalPosition(kPacket.lX, kPacket.lY);
|
||||
}
|
||||
__GlobalPositionToLocalPosition(kPacket.lSX, kPacket.lSY);
|
||||
|
||||
TPixelPosition tSyncPosition = TPixelPosition{ kPacket.fSyncDestX, kPacket.fSyncDestY, 0 };
|
||||
|
||||
m_rokNetActorMgr->AttackActor(kPacket.dwVID, kPacket.dwVictimVID, kPacket.lX, kPacket.lY, tSyncPosition, kPacket.dwBlendDuration);
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool CPythonNetworkStream::RecvTargetPacket()
|
||||
{
|
||||
TPacketGCTarget TargetPacket;
|
||||
@@ -2503,11 +2544,20 @@ bool CPythonNetworkStream::RecvChangeSpeedPacket()
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Recv
|
||||
|
||||
#ifdef FIX_POS_SYNC
|
||||
bool CPythonNetworkStream::SendAttackPacket(UINT uMotAttack, DWORD dwVIDVictim, BOOL bPacket, CActorInstance::BlendingPosition& sBlending)
|
||||
#else
|
||||
bool CPythonNetworkStream::SendAttackPacket(UINT uMotAttack, DWORD dwVIDVictim)
|
||||
#endif
|
||||
{
|
||||
if (!__CanActMainInstance())
|
||||
return true;
|
||||
|
||||
#ifdef FIX_POS_SYNC
|
||||
CPythonCharacterManager& rkChrMgr = CPythonCharacterManager::Instance();
|
||||
CInstanceBase* pkInstMain = rkChrMgr.GetMainInstancePtr();
|
||||
#endif
|
||||
|
||||
#ifdef ATTACK_TIME_LOG
|
||||
static DWORD prevTime = timeGetTime();
|
||||
DWORD curTime = timeGetTime();
|
||||
@@ -2520,6 +2570,25 @@ bool CPythonNetworkStream::SendAttackPacket(UINT uMotAttack, DWORD dwVIDVictim)
|
||||
kPacketAtk.header = HEADER_CG_ATTACK;
|
||||
kPacketAtk.bType = uMotAttack;
|
||||
kPacketAtk.dwVictimVID = dwVIDVictim;
|
||||
#ifdef FIX_POS_SYNC
|
||||
kPacketAtk.bPacket = bPacket;
|
||||
kPacketAtk.lX = (long)sBlending.dest.x;
|
||||
kPacketAtk.lY = (long)sBlending.dest.y;
|
||||
kPacketAtk.lSX = (long)sBlending.source.x;
|
||||
kPacketAtk.lSY = (long)sBlending.source.y;
|
||||
kPacketAtk.fSyncDestX = sBlending.dest.x;
|
||||
// sources and dest are normalized with both coordinates positive
|
||||
// since fSync are ment to be broadcasted to other clients, the Y has to preserve the negative coord
|
||||
kPacketAtk.fSyncDestY = -sBlending.dest.y;
|
||||
kPacketAtk.dwBlendDuration = (unsigned int)(sBlending.duration * 1000);
|
||||
kPacketAtk.dwComboMotion = pkInstMain->GetComboMotion();
|
||||
kPacketAtk.dwTime = ELTimer_GetServerMSec();
|
||||
|
||||
if (kPacketAtk.lX && kPacketAtk.lY)
|
||||
__LocalPositionToGlobalPosition(kPacketAtk.lX, kPacketAtk.lY);
|
||||
|
||||
__LocalPositionToGlobalPosition(kPacketAtk.lSX, kPacketAtk.lSY);
|
||||
#endif
|
||||
|
||||
if (!SendSpecial(sizeof(kPacketAtk), &kPacketAtk))
|
||||
{
|
||||
@@ -2814,6 +2883,26 @@ bool CPythonNetworkStream::RecvMessenger()
|
||||
CPythonMessenger::Instance().SetMobile(char_name, byState);
|
||||
break;
|
||||
}
|
||||
|
||||
#ifdef FIX_MESSENGER_ACTION_SYNC
|
||||
case MESSENGER_SUBHEADER_GC_REMOVE_FRIEND:
|
||||
{
|
||||
BYTE bLength;
|
||||
|
||||
if (!Recv(sizeof(bLength), &bLength))
|
||||
return false;
|
||||
|
||||
if (!Recv(bLength, char_name))
|
||||
return false;
|
||||
|
||||
char_name[bLength] = 0;
|
||||
|
||||
CPythonMessenger::Instance().RemoveFriend(char_name);
|
||||
__RefreshTargetBoardByName(char_name);
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -3984,6 +4073,7 @@ bool CPythonNetworkStream::RecvWalkModePacket()
|
||||
bool CPythonNetworkStream::RecvChangeSkillGroupPacket()
|
||||
{
|
||||
TPacketGCChangeSkillGroup ChangeSkillGroup;
|
||||
|
||||
if (!Recv(sizeof(ChangeSkillGroup), &ChangeSkillGroup))
|
||||
return false;
|
||||
|
||||
@@ -3991,6 +4081,7 @@ bool CPythonNetworkStream::RecvChangeSkillGroupPacket()
|
||||
|
||||
CPythonPlayer::Instance().NEW_ClearSkillData();
|
||||
__RefreshCharacterWindow();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -324,6 +324,10 @@ void CPythonNetworkStream::__RecvCharacterUpdatePacket(SNetworkUpdateActorData *
|
||||
__RefreshAlignmentWindow();
|
||||
__RefreshEquipmentWindow();
|
||||
__RefreshInventoryWindow();
|
||||
#ifdef CHAR_SELECT_STATS_IMPROVEMENT
|
||||
m_akSimplePlayerInfo[m_dwSelectedCharacterIndex].wHairPart = pkNetUpdateActorData->m_dwHair;
|
||||
m_akSimplePlayerInfo[m_dwSelectedCharacterIndex].wMainPart = pkNetUpdateActorData->m_dwArmor;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -326,7 +326,21 @@ bool CPythonNetworkStream::__RecvPlayerPoints()
|
||||
return false;
|
||||
|
||||
for (DWORD i = 0; i < POINT_MAX_NUM; ++i)
|
||||
{
|
||||
CPythonPlayer::Instance().SetStatus(i, PointsPacket.points[i]);
|
||||
#ifdef CHAR_SELECT_STATS_IMPROVEMENT
|
||||
if (i == POINT_LEVEL)
|
||||
m_akSimplePlayerInfo[m_dwSelectedCharacterIndex].byLevel = PointsPacket.points[i];
|
||||
else if (i == POINT_ST)
|
||||
m_akSimplePlayerInfo[m_dwSelectedCharacterIndex].byST = PointsPacket.points[i];
|
||||
else if (i == POINT_HT)
|
||||
m_akSimplePlayerInfo[m_dwSelectedCharacterIndex].byHT = PointsPacket.points[i];
|
||||
else if (i == POINT_DX)
|
||||
m_akSimplePlayerInfo[m_dwSelectedCharacterIndex].byDX = PointsPacket.points[i];
|
||||
else if (i == POINT_IQ)
|
||||
m_akSimplePlayerInfo[m_dwSelectedCharacterIndex].byIQ = PointsPacket.points[i];
|
||||
#endif
|
||||
}
|
||||
|
||||
PyCallClassMemberFunc(m_apoPhaseWnd[PHASE_WINDOW_GAME], "RefreshStatus", Py_BuildValue("()"));
|
||||
return true;
|
||||
|
||||
@@ -532,6 +532,74 @@ void CPythonPlayer::NotifyChangePKMode()
|
||||
PyCallClassMemberFunc(m_ppyGameWindow, "OnChangePKMode", Py_BuildValue("()"));
|
||||
}
|
||||
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
void CPythonPlayer::ResetSkillCoolTimes()
|
||||
{
|
||||
for (int i = 0; i < SKILL_MAX_NUM; ++i)
|
||||
ResetSkillCoolTimeForSlot(i);
|
||||
}
|
||||
|
||||
void CPythonPlayer::ResetSkillCoolTimeForSlot(DWORD dwSlotIndex)
|
||||
{
|
||||
if (dwSlotIndex >= SKILL_MAX_NUM)
|
||||
return;
|
||||
|
||||
TSkillInstance& rkSkillInst = m_playerStatus.aSkill[dwSlotIndex];
|
||||
|
||||
// If this skill is a toggle and currently active, deactivate it so UI/state is consistent.
|
||||
// __DeactivateSkillSlot is a private/protected helper on this class.
|
||||
if (IsToggleSkill(dwSlotIndex) && IsSkillActive(dwSlotIndex))
|
||||
__DeactivateSkillSlot(dwSlotIndex);
|
||||
|
||||
// If nothing to clear, skip
|
||||
if (!rkSkillInst.fLastUsedTime && !rkSkillInst.fCoolTime)
|
||||
return;
|
||||
|
||||
// Clear cooldown timers
|
||||
rkSkillInst.fLastUsedTime = rkSkillInst.fCoolTime = 0.0f;
|
||||
|
||||
// Get the actual skill type to clear cooldowns from the correct storage
|
||||
DWORD dwSkillType = CPythonSkill::SKILL_TYPE_ACTIVE; // default
|
||||
DWORD dwSkillIndex = rkSkillInst.dwIndex;
|
||||
CPythonSkill::TSkillData* pSkillData = NULL;
|
||||
|
||||
if (dwSkillIndex != 0 && CPythonSkill::Instance().GetSkillData(dwSkillIndex, &pSkillData))
|
||||
{
|
||||
dwSkillType = pSkillData->byType;
|
||||
}
|
||||
|
||||
if (dwSkillType == CPythonSkill::SKILL_TYPE_ACTIVE)
|
||||
{
|
||||
for (int iGrade = 0; iGrade < CPythonSkill::SKILL_GRADE_COUNT; ++iGrade)
|
||||
{
|
||||
UI::CWindowManager::Instance().ClearStoredSlotCoolTimeInAllSlotWindows(
|
||||
dwSkillType,
|
||||
dwSlotIndex + iGrade * CPythonSkill::SKILL_GRADE_STEP_COUNT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UI::CWindowManager::Instance().ClearStoredSlotCoolTimeInAllSlotWindows(dwSkillType, dwSlotIndex);
|
||||
}
|
||||
|
||||
// Inform Python/UI which slot was cleared
|
||||
PyCallClassMemberFunc(m_ppyGameWindow, "SkillClearCoolTime", Py_BuildValue("(i)", (int)dwSlotIndex));
|
||||
}
|
||||
|
||||
void CPythonPlayer::ResetHorseSkillCoolTime(DWORD dwSkillIndex, DWORD dwVisualSlotIndex)
|
||||
{
|
||||
// Clear both the source slot (137-140) and the visual slot (0-3)
|
||||
// so RestoreSlotCoolTime won't have anything to restore
|
||||
|
||||
UI::CWindowManager::Instance().ClearStoredSlotCoolTimeInAllSlotWindows(
|
||||
CPythonSkill::SKILL_TYPE_HORSE,
|
||||
dwSkillIndex);
|
||||
|
||||
UI::CWindowManager::Instance().ClearStoredSlotCoolTimeInAllSlotWindows(
|
||||
CPythonSkill::SKILL_TYPE_HORSE,
|
||||
dwVisualSlotIndex);
|
||||
}
|
||||
#endif
|
||||
|
||||
void CPythonPlayer::MoveItemData(TItemPos SrcCell, TItemPos DstCell)
|
||||
{
|
||||
@@ -993,6 +1061,7 @@ void CPythonPlayer::SetSkillLevel(DWORD dwSlotIndex, DWORD dwSkillLevel)
|
||||
void CPythonPlayer::SetSkillLevel_(DWORD dwSkillIndex, DWORD dwSkillGrade, DWORD dwSkillLevel)
|
||||
{
|
||||
DWORD dwSlotIndex;
|
||||
|
||||
if (!GetSkillSlotIndex(dwSkillIndex, &dwSlotIndex))
|
||||
return;
|
||||
|
||||
@@ -1004,39 +1073,46 @@ void CPythonPlayer::SetSkillLevel_(DWORD dwSkillIndex, DWORD dwSkillGrade, DWORD
|
||||
case 0:
|
||||
m_playerStatus.aSkill[dwSlotIndex].iGrade = dwSkillGrade;
|
||||
m_playerStatus.aSkill[dwSlotIndex].iLevel = dwSkillLevel;
|
||||
|
||||
break;
|
||||
case 1:
|
||||
m_playerStatus.aSkill[dwSlotIndex].iGrade = dwSkillGrade;
|
||||
m_playerStatus.aSkill[dwSlotIndex].iLevel = dwSkillLevel-20+1;
|
||||
m_playerStatus.aSkill[dwSlotIndex].iLevel = dwSkillLevel - 20 + 1;
|
||||
|
||||
break;
|
||||
case 2:
|
||||
m_playerStatus.aSkill[dwSlotIndex].iGrade = dwSkillGrade;
|
||||
m_playerStatus.aSkill[dwSlotIndex].iLevel = dwSkillLevel-30+1;
|
||||
m_playerStatus.aSkill[dwSlotIndex].iLevel = dwSkillLevel - 30 + 1;
|
||||
|
||||
break;
|
||||
case 3:
|
||||
m_playerStatus.aSkill[dwSlotIndex].iGrade = dwSkillGrade;
|
||||
m_playerStatus.aSkill[dwSlotIndex].iLevel = dwSkillLevel-40+1;
|
||||
m_playerStatus.aSkill[dwSlotIndex].iLevel = dwSkillLevel - 40 + 1;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
const DWORD SKILL_MAX_LEVEL = 40;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if (dwSkillLevel>SKILL_MAX_LEVEL)
|
||||
if (dwSkillLevel > SKILL_MAX_LEVEL)
|
||||
{
|
||||
m_playerStatus.aSkill[dwSlotIndex].fcurEfficientPercentage = 0.0f;
|
||||
m_playerStatus.aSkill[dwSlotIndex].fnextEfficientPercentage = 0.0f;
|
||||
|
||||
TraceError("CPythonPlayer::SetSkillLevel(SlotIndex=%d, SkillLevel=%d)", dwSlotIndex, dwSkillLevel);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_playerStatus.aSkill[dwSlotIndex].fcurEfficientPercentage = LocaleService_GetSkillPower(dwSkillLevel)/100.0f;
|
||||
m_playerStatus.aSkill[dwSlotIndex].fnextEfficientPercentage = LocaleService_GetSkillPower(dwSkillLevel+1)/100.0f;
|
||||
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
if (m_playerStatus.aSkill[dwSlotIndex].iLevel <= 0)
|
||||
{
|
||||
ResetSkillCoolTimeForSlot(dwSlotIndex);
|
||||
}
|
||||
#endif
|
||||
|
||||
m_playerStatus.aSkill[dwSlotIndex].fcurEfficientPercentage = LocaleService_GetSkillPower(dwSkillLevel) / 100.0f;
|
||||
m_playerStatus.aSkill[dwSlotIndex].fnextEfficientPercentage = LocaleService_GetSkillPower(dwSkillLevel + 1) / 100.0f;
|
||||
}
|
||||
|
||||
void CPythonPlayer::SetSkillCoolTime(DWORD dwSkillIndex)
|
||||
@@ -1568,7 +1644,19 @@ void CPythonPlayer::NEW_ClearSkillData(bool bAll)
|
||||
|
||||
for (it = m_skillSlotDict.begin(); it != m_skillSlotDict.end();)
|
||||
{
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
CPythonSkill::TSkillData* data = nullptr;
|
||||
|
||||
if (!CPythonSkill::Instance().GetSkillData(it->first, &data))
|
||||
{
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bAll || (data->byType != CPythonSkill::SKILL_TYPE_SUPPORT && data->byType != CPythonSkill::SKILL_TYPE_HORSE && data->byType != CPythonSkill::SKILL_TYPE_GUILD))
|
||||
#else
|
||||
if (bAll || __GetSkillType(it->first) == CPythonSkill::SKILL_TYPE_ACTIVE)
|
||||
#endif
|
||||
it = m_skillSlotDict.erase(it);
|
||||
else
|
||||
++it;
|
||||
@@ -1576,6 +1664,24 @@ void CPythonPlayer::NEW_ClearSkillData(bool bAll)
|
||||
|
||||
for (int i = 0; i < SKILL_MAX_NUM; ++i)
|
||||
{
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
DWORD dwSkillIndex = m_playerStatus.aSkill[i].dwIndex;
|
||||
CPythonSkill::TSkillData* pSkillData = NULL;
|
||||
|
||||
// Skip empty slots
|
||||
if (dwSkillIndex == 0)
|
||||
continue;
|
||||
|
||||
if (!CPythonSkill::Instance().GetSkillData(dwSkillIndex, &pSkillData))
|
||||
continue;
|
||||
|
||||
// If not clearing all, skip persistent skill types (SUPPORT, HORSE, GUILD)
|
||||
if (!bAll && (pSkillData->byType == CPythonSkill::SKILL_TYPE_SUPPORT ||
|
||||
pSkillData->byType == CPythonSkill::SKILL_TYPE_HORSE ||
|
||||
pSkillData->byType == CPythonSkill::SKILL_TYPE_GUILD))
|
||||
continue;
|
||||
#endif
|
||||
|
||||
ZeroMemory(&m_playerStatus.aSkill[i], sizeof(TSkillInstance));
|
||||
}
|
||||
|
||||
@@ -1583,8 +1689,22 @@ void CPythonPlayer::NEW_ClearSkillData(bool bAll)
|
||||
{
|
||||
// 2004.09.30.myevan.스킬갱신시 스킬 포인트업[+] 버튼이 안나와 처리
|
||||
m_playerStatus.aSkill[j].iGrade = 0;
|
||||
m_playerStatus.aSkill[j].fcurEfficientPercentage=0.0f;
|
||||
m_playerStatus.aSkill[j].fnextEfficientPercentage=0.05f;
|
||||
m_playerStatus.aSkill[j].fcurEfficientPercentage = 0.0f;
|
||||
m_playerStatus.aSkill[j].fnextEfficientPercentage = 0.05f;
|
||||
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
m_playerStatus.aSkill[j].isCoolTime = false;
|
||||
m_playerStatus.aSkill[j].fCoolTime = 0.0f;
|
||||
m_playerStatus.aSkill[j].fLastUsedTime = 0.0f;
|
||||
|
||||
//ResetSkillCoolTimeForSlot(j);
|
||||
for (int iGrade = 0; iGrade < CPythonSkill::SKILL_GRADE_COUNT; ++iGrade)
|
||||
{
|
||||
UI::CWindowManager::Instance().ClearStoredSlotCoolTimeInAllSlotWindows(
|
||||
CPythonSkill::SKILL_TYPE_ACTIVE,
|
||||
j + iGrade * CPythonSkill::SKILL_GRADE_STEP_COUNT);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (m_ppyGameWindow)
|
||||
|
||||
@@ -262,6 +262,11 @@ class CPythonPlayer : public CSingleton<CPythonPlayer>, public IAbstractPlayer
|
||||
void NotifyCharacterUpdate(DWORD dwVID);
|
||||
void NotifyDeadMainCharacter();
|
||||
void NotifyChangePKMode();
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
void ResetSkillCoolTimes();
|
||||
void ResetSkillCoolTimeForSlot(DWORD dwSlotIndex);
|
||||
void ResetHorseSkillCoolTime(DWORD dwSkillIndex, DWORD dwVisualSlotIndex);
|
||||
#endif
|
||||
|
||||
|
||||
// Player Status
|
||||
|
||||
@@ -132,10 +132,26 @@ void CPythonPlayerEventHandler::OnChangeShape()
|
||||
CPythonPlayer::Instance().NEW_Stop();
|
||||
}
|
||||
|
||||
#ifdef FIX_POS_SYNC
|
||||
void CPythonPlayerEventHandler::OnHit(UINT uSkill, CActorInstance& rkActorVictim, BOOL isSendPacket, CActorInstance::BlendingPosition* sBlending)
|
||||
#else
|
||||
void CPythonPlayerEventHandler::OnHit(UINT uSkill, CActorInstance& rkActorVictim, BOOL isSendPacket)
|
||||
#endif
|
||||
{
|
||||
DWORD dwVIDVictim=rkActorVictim.GetVirtualID();
|
||||
|
||||
#ifdef FIX_POS_SYNC
|
||||
CPythonCharacterManager::Instance().AdjustCollisionWithOtherObjects(&rkActorVictim);
|
||||
CActorInstance::BlendingPosition kBlendingPacket;
|
||||
memset(&kBlendingPacket, 0, sizeof(kBlendingPacket));
|
||||
|
||||
kBlendingPacket.source = rkActorVictim.NEW_GetCurPixelPositionRef();
|
||||
if (rkActorVictim.IsPushing()) {
|
||||
kBlendingPacket.dest = rkActorVictim.NEW_GetLastPixelPositionRef();
|
||||
kBlendingPacket.duration = sBlending->duration;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Update Target
|
||||
CPythonPlayer::Instance().SetTarget(dwVIDVictim, FALSE);
|
||||
// Update Target
|
||||
@@ -165,7 +181,11 @@ void CPythonPlayerEventHandler::OnHit(UINT uSkill, CActorInstance& rkActorVictim
|
||||
s_prevTimed[dwVIDVictim] = curTime;
|
||||
#endif
|
||||
CPythonNetworkStream& rkStream=CPythonNetworkStream::Instance();
|
||||
#ifdef FIX_POS_SYNC
|
||||
rkStream.SendAttackPacket(uSkill, dwVIDVictim, isSendPacket, kBlendingPacket);
|
||||
#else
|
||||
rkStream.SendAttackPacket(uSkill, dwVIDVictim);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!rkActorVictim.IsPushing())
|
||||
|
||||
@@ -27,7 +27,11 @@ class CPythonPlayerEventHandler : public CActorInstance::IEventHandler
|
||||
virtual void OnUseSkill(const SState& c_rkState, UINT uMotSkill, UINT uArg);
|
||||
virtual void OnUpdate();
|
||||
virtual void OnChangeShape();
|
||||
#ifdef FIX_POS_SYNC
|
||||
virtual void OnHit(UINT uSkill, CActorInstance& rkActorVictim, BOOL isSendPacket, CActorInstance::BlendingPosition* sBlending);
|
||||
#else
|
||||
virtual void OnHit(UINT uSkill, CActorInstance& rkActorVictim, BOOL isSendPacket);
|
||||
#endif
|
||||
|
||||
void FlushVictimList();
|
||||
|
||||
|
||||
@@ -543,6 +543,31 @@ PyObject * playerGetSkillCoolTime(PyObject* poSelf, PyObject* poArgs)
|
||||
return Py_BuildValue("ff", fCoolTime, fElapsedCoolTime);
|
||||
}
|
||||
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
PyObject * playerResetSkillCoolTimeForSlot(PyObject* poSelf, PyObject* poArgs)
|
||||
{
|
||||
int iSlotIndex;
|
||||
if (!PyTuple_GetInteger(poArgs, 0, &iSlotIndex))
|
||||
return Py_BuildException();
|
||||
|
||||
CPythonPlayer::Instance().ResetSkillCoolTimeForSlot(iSlotIndex);
|
||||
return Py_BuildNone();
|
||||
}
|
||||
|
||||
PyObject* playerResetHorseSkillCoolTime(PyObject* poSelf, PyObject* poArgs)
|
||||
{
|
||||
DWORD dwSkillIndex;
|
||||
DWORD dwVisualSlotIndex;
|
||||
|
||||
if (!PyArg_ParseTuple(poArgs, "ii", &dwSkillIndex, &dwVisualSlotIndex))
|
||||
return Py_BuildException();
|
||||
|
||||
CPythonPlayer::Instance().ResetHorseSkillCoolTime(dwSkillIndex, dwVisualSlotIndex);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
PyObject * playerIsSkillActive(PyObject* poSelf, PyObject* poArgs)
|
||||
{
|
||||
int iSlotIndex;
|
||||
@@ -2233,6 +2258,10 @@ void initPlayer()
|
||||
|
||||
{ "IsSkillCoolTime", playerIsSkillCoolTime, METH_VARARGS },
|
||||
{ "GetSkillCoolTime", playerGetSkillCoolTime, METH_VARARGS },
|
||||
#ifdef FIX_REFRESH_SKILL_COOLDOWN
|
||||
{ "ResetSkillCoolTimeForSlot", playerResetSkillCoolTimeForSlot, METH_VARARGS },
|
||||
{ "ResetHorseSkillCoolTime", playerResetHorseSkillCoolTime, METH_VARARGS },
|
||||
#endif
|
||||
{ "IsSkillActive", playerIsSkillActive, METH_VARARGS },
|
||||
{ "UseGuildSkill", playerUseGuildSkill, METH_VARARGS },
|
||||
{ "AffectIndexToSkillIndex", playerAffectIndexToSkillIndex, METH_VARARGS },
|
||||
|
||||
Reference in New Issue
Block a user