618 lines
15 KiB
C++
618 lines
15 KiB
C++
#include "StdAfx.h"
|
|
#include "../EffectLib/EffectManager.h"
|
|
#include "FlyingObjectManager.h"
|
|
#include "RaceMotionData.h"
|
|
|
|
CDynamicPool<CRaceMotionData> CRaceMotionData::ms_kPool;
|
|
|
|
void CRaceMotionData::CreateSystem(UINT uCapacity)
|
|
{
|
|
ms_kPool.Create(uCapacity);
|
|
}
|
|
|
|
void CRaceMotionData::DestroySystem()
|
|
{
|
|
ms_kPool.Clear();
|
|
}
|
|
|
|
CRaceMotionData* CRaceMotionData::New()
|
|
{
|
|
return ms_kPool.Alloc();
|
|
}
|
|
|
|
void CRaceMotionData::Delete(CRaceMotionData* pkData)
|
|
{
|
|
pkData->Destroy();
|
|
|
|
ms_kPool.Free(pkData);
|
|
}
|
|
|
|
void CRaceMotionData::SetName(UINT eName)
|
|
{
|
|
m_eName=eName;
|
|
|
|
switch (m_eName)
|
|
{
|
|
case NAME_NONE:
|
|
SetType(TYPE_NONE);
|
|
break;
|
|
case NAME_WAIT:
|
|
case NAME_INTRO_WAIT:
|
|
case NAME_STOP:
|
|
SetType(TYPE_WAIT);
|
|
break;
|
|
case NAME_WALK:
|
|
case NAME_RUN:
|
|
SetType(TYPE_MOVE);
|
|
break;
|
|
case NAME_DAMAGE:
|
|
case NAME_DAMAGE_BACK:
|
|
SetType(TYPE_DAMAGE);
|
|
break;
|
|
case NAME_DAMAGE_FLYING:
|
|
case NAME_DAMAGE_FLYING_BACK:
|
|
SetType(TYPE_KNOCKDOWN);
|
|
break;
|
|
case NAME_STAND_UP:
|
|
case NAME_STAND_UP_BACK:
|
|
SetType(TYPE_STANDUP);
|
|
break;
|
|
case NAME_SPAWN:
|
|
case NAME_CHANGE_WEAPON:
|
|
case NAME_INTRO_SELECTED:
|
|
case NAME_INTRO_NOT_SELECTED:
|
|
case NAME_SPECIAL_1:
|
|
case NAME_SPECIAL_2:
|
|
case NAME_SPECIAL_3:
|
|
case NAME_SPECIAL_4:
|
|
case NAME_SPECIAL_5:
|
|
case NAME_SPECIAL_6:
|
|
case NAME_CLAP:
|
|
case NAME_DANCE_1:
|
|
case NAME_DANCE_2:
|
|
case NAME_DANCE_3:
|
|
case NAME_DANCE_4:
|
|
case NAME_DANCE_5:
|
|
case NAME_DANCE_6:
|
|
case NAME_CONGRATULATION:
|
|
case NAME_FORGIVE:
|
|
case NAME_ANGRY:
|
|
case NAME_ATTRACTIVE:
|
|
case NAME_SAD:
|
|
case NAME_SHY:
|
|
case NAME_CHEERUP:
|
|
case NAME_BANTER:
|
|
case NAME_JOY:
|
|
case NAME_CHEERS_1:
|
|
case NAME_CHEERS_2:
|
|
case NAME_KISS_WITH_WARRIOR:
|
|
case NAME_KISS_WITH_ASSASSIN:
|
|
case NAME_KISS_WITH_SURA:
|
|
case NAME_KISS_WITH_SHAMAN:
|
|
case NAME_FRENCH_KISS_WITH_WARRIOR:
|
|
case NAME_FRENCH_KISS_WITH_ASSASSIN:
|
|
case NAME_FRENCH_KISS_WITH_SURA:
|
|
case NAME_FRENCH_KISS_WITH_SHAMAN:
|
|
case NAME_SLAP_HIT_WITH_WARRIOR:
|
|
case NAME_SLAP_HIT_WITH_ASSASSIN:
|
|
case NAME_SLAP_HIT_WITH_SURA:
|
|
case NAME_SLAP_HIT_WITH_SHAMAN:
|
|
case NAME_SLAP_HURT_WITH_WARRIOR:
|
|
case NAME_SLAP_HURT_WITH_ASSASSIN:
|
|
case NAME_SLAP_HURT_WITH_SURA:
|
|
case NAME_SLAP_HURT_WITH_SHAMAN:
|
|
case NAME_DIG:
|
|
SetType(TYPE_EVENT);
|
|
break;
|
|
case NAME_DEAD:
|
|
case NAME_DEAD_BACK:
|
|
SetType(TYPE_DIE);
|
|
break;
|
|
case NAME_NORMAL_ATTACK:
|
|
SetType(TYPE_ATTACK);
|
|
break;
|
|
case NAME_COMBO_ATTACK_1:
|
|
case NAME_COMBO_ATTACK_2:
|
|
case NAME_COMBO_ATTACK_3:
|
|
case NAME_COMBO_ATTACK_4:
|
|
case NAME_COMBO_ATTACK_5:
|
|
case NAME_COMBO_ATTACK_6:
|
|
case NAME_COMBO_ATTACK_7:
|
|
case NAME_COMBO_ATTACK_8:
|
|
SetType(TYPE_COMBO);
|
|
break;
|
|
case NAME_FISHING_THROW:
|
|
case NAME_FISHING_WAIT:
|
|
case NAME_FISHING_REACT:
|
|
case NAME_FISHING_CATCH:
|
|
case NAME_FISHING_FAIL:
|
|
case NAME_FISHING_STOP:
|
|
SetType(TYPE_FISHING);
|
|
break;
|
|
default:
|
|
if (eName>=NAME_SKILL && eName<=NAME_SKILL+SKILL_NUM)
|
|
SetType(TYPE_SKILL);
|
|
else
|
|
TraceError("CRaceMotionData::SetName - UNKNOWN NAME %d", eName);
|
|
break;
|
|
}
|
|
}
|
|
void CRaceMotionData::SetType(UINT eType)
|
|
{
|
|
m_eType=eType;
|
|
|
|
switch (m_eType)
|
|
{
|
|
case TYPE_ATTACK:
|
|
case TYPE_COMBO:
|
|
case TYPE_SKILL:
|
|
m_isLock=TRUE;
|
|
break;
|
|
default:
|
|
m_isLock=FALSE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
UINT CRaceMotionData::GetType() const
|
|
{
|
|
return m_eType;
|
|
}
|
|
|
|
bool CRaceMotionData::IsLock() const
|
|
{
|
|
return m_isLock ? true : false;
|
|
}
|
|
|
|
int CRaceMotionData::GetLoopCount() const
|
|
{
|
|
return m_iLoopCount;
|
|
}
|
|
|
|
float CRaceMotionData::GetMotionDuration()
|
|
{
|
|
return m_fMotionDuration;
|
|
}
|
|
|
|
void CRaceMotionData::SetMotionDuration(float fDuration)
|
|
{
|
|
m_fMotionDuration = fDuration;
|
|
}
|
|
|
|
// Combo
|
|
BOOL CRaceMotionData::IsComboInputTimeData() const
|
|
{
|
|
return m_isComboMotion;
|
|
}
|
|
|
|
float CRaceMotionData::GetComboInputStartTime() const
|
|
{
|
|
assert(m_isComboMotion);
|
|
return m_ComboInputData.fInputStartTime;
|
|
}
|
|
|
|
float CRaceMotionData::GetNextComboTime() const
|
|
{
|
|
assert(m_isComboMotion);
|
|
return m_ComboInputData.fNextComboTime;
|
|
}
|
|
|
|
float CRaceMotionData::GetComboInputEndTime() const
|
|
{
|
|
assert(m_isComboMotion);
|
|
return m_ComboInputData.fInputEndTime;
|
|
}
|
|
|
|
// Attacking
|
|
BOOL CRaceMotionData::isAttackingMotion() const
|
|
{
|
|
return m_isAttackingMotion;
|
|
}
|
|
|
|
const NRaceData::TMotionAttackData * CRaceMotionData::GetMotionAttackDataPointer() const
|
|
{
|
|
return & m_MotionAttackData;
|
|
}
|
|
|
|
const NRaceData::TMotionAttackData & CRaceMotionData::GetMotionAttackDataReference() const
|
|
{
|
|
assert(m_isAttackingMotion);
|
|
return m_MotionAttackData;
|
|
}
|
|
|
|
BOOL CRaceMotionData::HasSplashMotionEvent() const
|
|
{
|
|
return m_hasSplashEvent;
|
|
}
|
|
|
|
// Skill
|
|
BOOL CRaceMotionData::IsCancelEnableSkill() const
|
|
{
|
|
return m_bCancelEnableSkill;
|
|
}
|
|
|
|
// Loop
|
|
BOOL CRaceMotionData::IsLoopMotion() const
|
|
{
|
|
return m_isLoopMotion;
|
|
}
|
|
|
|
float CRaceMotionData::GetLoopStartTime() const
|
|
{
|
|
return m_fLoopStartTime;
|
|
}
|
|
|
|
float CRaceMotionData::GetLoopEndTime() const
|
|
{
|
|
return m_fLoopEndTime;
|
|
}
|
|
|
|
// Motion Event Data
|
|
DWORD CRaceMotionData::GetMotionEventDataCount() const
|
|
{
|
|
return m_MotionEventDataVector.size();
|
|
}
|
|
|
|
BOOL CRaceMotionData::GetMotionEventDataPointer(BYTE byIndex, const CRaceMotionData::TMotionEventData ** c_ppData) const
|
|
{
|
|
if (byIndex >= m_MotionEventDataVector.size())
|
|
return FALSE;
|
|
|
|
*c_ppData = m_MotionEventDataVector[byIndex];
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CRaceMotionData::GetMotionAttackingEventDataPointer(BYTE byIndex, const CRaceMotionData::TMotionAttackingEventData ** c_ppData) const
|
|
{
|
|
if (byIndex >= m_MotionEventDataVector.size())
|
|
return FALSE;
|
|
|
|
const CRaceMotionData::TMotionEventData * pData = m_MotionEventDataVector[byIndex];
|
|
const CRaceMotionData::TMotionAttackingEventData * pAttackingEvent = (const CRaceMotionData::TMotionAttackingEventData *)pData;
|
|
|
|
if (MOTION_EVENT_TYPE_SPECIAL_ATTACKING == pAttackingEvent->iType)
|
|
return FALSE;
|
|
|
|
*c_ppData = pAttackingEvent;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
int CRaceMotionData::GetEventType(DWORD dwIndex) const
|
|
{
|
|
if (dwIndex >= m_MotionEventDataVector.size())
|
|
return MOTION_EVENT_TYPE_NONE;
|
|
|
|
return m_MotionEventDataVector[dwIndex]->iType;
|
|
}
|
|
|
|
float CRaceMotionData::GetEventStartTime(DWORD dwIndex) const
|
|
{
|
|
if (dwIndex >= m_MotionEventDataVector.size())
|
|
return 0.0f;
|
|
|
|
return m_MotionEventDataVector[dwIndex]->fStartingTime;
|
|
}
|
|
|
|
const NSound::TSoundInstanceVector * CRaceMotionData::GetSoundInstanceVectorPointer() const
|
|
{
|
|
return &m_SoundInstanceVector;
|
|
}
|
|
|
|
void CRaceMotionData::SetAccumulationPosition(const TPixelPosition & c_rPos)
|
|
{
|
|
m_accumulationPosition = c_rPos;
|
|
m_isAccumulationMotion = TRUE;
|
|
}
|
|
|
|
bool CRaceMotionData::LoadMotionData(const char * c_szFileName)
|
|
{
|
|
const float c_fFrameTime = 1.0f / g_fGameFPS;
|
|
|
|
CTextFileLoader* pkTextFileLoader=CTextFileLoader::Cache(c_szFileName);
|
|
if (!pkTextFileLoader)
|
|
return false;
|
|
|
|
CTextFileLoader& rkTextFileLoader=*pkTextFileLoader;
|
|
|
|
if (rkTextFileLoader.IsEmpty())
|
|
return false;
|
|
|
|
rkTextFileLoader.SetTop();
|
|
|
|
if (!rkTextFileLoader.GetTokenString("motionfilename", &m_strMotionFileName))
|
|
return false;
|
|
|
|
if (!rkTextFileLoader.GetTokenFloat("motionduration", &m_fMotionDuration))
|
|
return false;
|
|
|
|
CTokenVector * pTokenVector;
|
|
|
|
if (rkTextFileLoader.GetTokenVector("accumulation", &pTokenVector))
|
|
{
|
|
if (pTokenVector->size() != 3)
|
|
{
|
|
TraceError("CRaceMotioNData::LoadMotionData : syntax error on accumulation, vector size %d", pTokenVector->size());
|
|
return false;
|
|
}
|
|
|
|
TPixelPosition pos(atof(pTokenVector->at(0).c_str()),
|
|
atof(pTokenVector->at(1).c_str()),
|
|
atof(pTokenVector->at(2).c_str()));
|
|
|
|
SetAccumulationPosition(pos);
|
|
}
|
|
|
|
std::string strNodeName;
|
|
for (DWORD i = 0; i < rkTextFileLoader.GetChildNodeCount(); ++i)
|
|
{
|
|
CTextFileLoader::CGotoChild GotoChild(&rkTextFileLoader, i);
|
|
|
|
rkTextFileLoader.GetCurrentNodeName(&strNodeName);
|
|
|
|
if (0 == strNodeName.compare("comboinputdata"))
|
|
{
|
|
m_isComboMotion = TRUE;
|
|
|
|
if (!rkTextFileLoader.GetTokenFloat("preinputtime", &m_ComboInputData.fInputStartTime))
|
|
return false;
|
|
if (!rkTextFileLoader.GetTokenFloat("directinputtime", &m_ComboInputData.fNextComboTime))
|
|
return false;
|
|
if (!rkTextFileLoader.GetTokenFloat("inputlimittime", &m_ComboInputData.fInputEndTime))
|
|
return false;
|
|
}
|
|
else if (0 == strNodeName.compare("attackingdata"))
|
|
{
|
|
m_isAttackingMotion = TRUE;
|
|
|
|
if (!NRaceData::LoadMotionAttackData(rkTextFileLoader, &m_MotionAttackData))
|
|
return false;
|
|
}
|
|
else if (0 == strNodeName.compare("loopdata"))
|
|
{
|
|
m_isLoopMotion = TRUE;
|
|
if (!rkTextFileLoader.GetTokenInteger("motionloopcount", &m_iLoopCount))
|
|
{
|
|
m_iLoopCount = -1;
|
|
}
|
|
if (!rkTextFileLoader.GetTokenInteger("loopcancelenable", &m_bCancelEnableSkill))
|
|
{
|
|
m_bCancelEnableSkill = FALSE;
|
|
}
|
|
if (!rkTextFileLoader.GetTokenFloat("loopstarttime", &m_fLoopStartTime))
|
|
return false;
|
|
if (!rkTextFileLoader.GetTokenFloat("loopendtime", &m_fLoopEndTime))
|
|
return false;
|
|
}
|
|
else if (0 == strNodeName.compare("motioneventdata"))
|
|
{
|
|
DWORD dwMotionEventDataCount;
|
|
|
|
if (!rkTextFileLoader.GetTokenDoubleWord("motioneventdatacount", &dwMotionEventDataCount))
|
|
continue;
|
|
|
|
stl_wipe(m_MotionEventDataVector);
|
|
|
|
m_MotionEventDataVector.resize(dwMotionEventDataCount, NULL);
|
|
|
|
for (DWORD j = 0; j < m_MotionEventDataVector.size(); ++j)
|
|
{
|
|
if (!rkTextFileLoader.SetChildNode("event", j))
|
|
return false;
|
|
|
|
int iType;
|
|
if (!rkTextFileLoader.GetTokenInteger("motioneventtype", &iType))
|
|
return false;
|
|
|
|
TMotionEventData * pData = NULL;
|
|
switch(iType)
|
|
{
|
|
case MOTION_EVENT_TYPE_FLY:
|
|
pData = new TMotionFlyEventData;
|
|
break;
|
|
case MOTION_EVENT_TYPE_EFFECT:
|
|
pData = new TMotionEffectEventData;
|
|
break;
|
|
case MOTION_EVENT_TYPE_SCREEN_WAVING:
|
|
pData = new TScreenWavingEventData;
|
|
break;
|
|
case MOTION_EVENT_TYPE_SPECIAL_ATTACKING:
|
|
pData = new TMotionAttackingEventData;
|
|
m_hasSplashEvent = TRUE;
|
|
break;
|
|
case MOTION_EVENT_TYPE_SOUND:
|
|
pData = new TMotionSoundEventData;
|
|
break;
|
|
case MOTION_EVENT_TYPE_CHARACTER_SHOW:
|
|
pData = new TMotionCharacterShowEventData;
|
|
break;
|
|
case MOTION_EVENT_TYPE_CHARACTER_HIDE:
|
|
pData = new TMotionCharacterHideEventData;
|
|
break;
|
|
case MOTION_EVENT_TYPE_WARP:
|
|
pData = new TMotionWarpEventData;
|
|
break;
|
|
case MOTION_EVENT_TYPE_EFFECT_TO_TARGET:
|
|
pData = new TMotionEffectToTargetEventData;
|
|
break;
|
|
default:
|
|
assert(!" CRaceMotionData::LoadMotionData - Strange Event Type");
|
|
return false;
|
|
break;
|
|
}
|
|
m_MotionEventDataVector[j] = pData;
|
|
m_MotionEventDataVector[j]->Load(rkTextFileLoader);
|
|
m_MotionEventDataVector[j]->iType = iType;
|
|
if (!rkTextFileLoader.GetTokenFloat("startingtime", &m_MotionEventDataVector[j]->fStartingTime))
|
|
return false;
|
|
|
|
m_MotionEventDataVector[j]->dwFrame = (m_MotionEventDataVector[j]->fStartingTime / c_fFrameTime);
|
|
|
|
rkTextFileLoader.SetParentNode();
|
|
}
|
|
}
|
|
}
|
|
|
|
std::string strSoundFileNameTemp=c_szFileName;
|
|
strSoundFileNameTemp = CFileNameHelper::NoExtension(strSoundFileNameTemp);
|
|
strSoundFileNameTemp+= ".mss";
|
|
|
|
if (strSoundFileNameTemp.length() > 13)
|
|
{
|
|
const char * c_szHeader = &strSoundFileNameTemp[13];
|
|
|
|
m_strSoundScriptDataFileName = "sound/";
|
|
m_strSoundScriptDataFileName += c_szHeader;
|
|
|
|
LoadSoundScriptData(m_strSoundScriptDataFileName.c_str());
|
|
}
|
|
|
|
return true;
|
|
}
|
|
#ifdef WORLD_EDITOR
|
|
bool CRaceMotionData::SaveMotionData(const char * c_szFileName)
|
|
{
|
|
FILE * File;
|
|
|
|
SetFileAttributes(c_szFileName, FILE_ATTRIBUTE_NORMAL);
|
|
File = fopen(c_szFileName, "w");
|
|
|
|
if (!File)
|
|
{
|
|
TraceError("CRaceMotionData::SaveMotionData : cannot open file for writing (filename: %s)", c_szFileName);
|
|
return false;
|
|
}
|
|
|
|
fprintf(File, "ScriptType MotionData\n");
|
|
fprintf(File, "\n");
|
|
|
|
fprintf(File, "MotionFileName \"%s\"\n", m_strMotionFileName.c_str());
|
|
fprintf(File, "MotionDuration %f\n", m_fMotionDuration);
|
|
|
|
if (m_isAccumulationMotion)
|
|
fprintf(File, "Accumulation %.2f\t%.2f\t%.2f\n", m_accumulationPosition.x, m_accumulationPosition.y, m_accumulationPosition.z);
|
|
|
|
fprintf(File, "\n");
|
|
|
|
if (m_isComboMotion)
|
|
{
|
|
fprintf(File, "Group ComboInputData\n");
|
|
fprintf(File, "{\n");
|
|
fprintf(File, " PreInputTime %f\n", m_ComboInputData.fInputStartTime);
|
|
fprintf(File, " DirectInputTime %f\n", m_ComboInputData.fNextComboTime);
|
|
fprintf(File, " InputLimitTime %f\n", m_ComboInputData.fInputEndTime);
|
|
fprintf(File, "}\n");
|
|
fprintf(File, "\n");
|
|
}
|
|
|
|
if (m_isAttackingMotion)
|
|
{
|
|
fprintf(File, "Group AttackingData\n");
|
|
fprintf(File, "{\n");
|
|
NRaceData::SaveMotionAttackData(File, 1, m_MotionAttackData);
|
|
fprintf(File, "}\n");
|
|
fprintf(File, "\n");
|
|
}
|
|
|
|
if (m_isLoopMotion)
|
|
{
|
|
fprintf(File, "Group LoopData\n");
|
|
fprintf(File, "{\n");
|
|
fprintf(File, " MotionLoopCount %d\n", m_iLoopCount);
|
|
fprintf(File, " LoopCancelEnable %d\n", m_bCancelEnableSkill);
|
|
fprintf(File, " LoopStartTime %f\n", m_fLoopStartTime);
|
|
fprintf(File, " LoopEndTime %f\n", m_fLoopEndTime);
|
|
fprintf(File, "}\n");
|
|
fprintf(File, "\n");
|
|
}
|
|
|
|
if (!m_MotionEventDataVector.empty())
|
|
{
|
|
fprintf(File, "Group MotionEventData\n");
|
|
fprintf(File, "{\n");
|
|
fprintf(File, " MotionEventDataCount %d\n", m_MotionEventDataVector.size());
|
|
|
|
for (DWORD j = 0; j < m_MotionEventDataVector.size(); ++j)
|
|
{
|
|
TMotionEventData * c_pData = m_MotionEventDataVector[j];
|
|
|
|
fprintf(File, " Group Event%02d\n", j);
|
|
fprintf(File, " {\n");
|
|
fprintf(File, " MotionEventType %d\n", c_pData->iType);
|
|
fprintf(File, " StartingTime %f\n", c_pData->fStartingTime);
|
|
c_pData->Save(File, 2);
|
|
fprintf(File, " }\n");
|
|
}
|
|
fprintf(File, "}\n");
|
|
}
|
|
|
|
fclose(File);
|
|
return true;
|
|
}
|
|
#endif
|
|
bool CRaceMotionData::LoadSoundScriptData(const char * c_szFileName)
|
|
{
|
|
NSound::TSoundDataVector SoundDataVector;
|
|
if (!NSound::LoadSoundInformationPiece(c_szFileName, SoundDataVector))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
NSound::DataToInstance(SoundDataVector, &m_SoundInstanceVector);
|
|
return true;
|
|
}
|
|
|
|
const char * CRaceMotionData::GetMotionFileName() const
|
|
{
|
|
return m_strMotionFileName.c_str();
|
|
}
|
|
|
|
const char * CRaceMotionData::GetSoundScriptFileName() const
|
|
{
|
|
return m_strSoundScriptDataFileName.c_str();
|
|
}
|
|
|
|
void CRaceMotionData::Initialize()
|
|
{
|
|
m_iLoopCount = 0;
|
|
m_fMotionDuration = 0.0f;
|
|
m_accumulationPosition.x = 0.0f;
|
|
m_accumulationPosition.y = 0.0f;
|
|
m_accumulationPosition.z = 0.0f;
|
|
m_fLoopStartTime = 0.0f;
|
|
m_fLoopEndTime = 0.0f;
|
|
|
|
m_isAccumulationMotion = FALSE;
|
|
m_isComboMotion = FALSE;
|
|
m_isLoopMotion = FALSE;
|
|
m_isAttackingMotion = FALSE;
|
|
m_bCancelEnableSkill = FALSE;
|
|
|
|
m_hasSplashEvent = FALSE;
|
|
|
|
m_isLock = FALSE;
|
|
|
|
m_eType=TYPE_NONE;
|
|
m_eName=NAME_NONE;
|
|
|
|
m_MotionEventDataVector.clear();
|
|
m_SoundInstanceVector.clear();
|
|
}
|
|
|
|
void CRaceMotionData::Destroy()
|
|
{
|
|
stl_wipe(m_MotionEventDataVector);
|
|
Initialize();
|
|
}
|
|
|
|
CRaceMotionData::CRaceMotionData()
|
|
{
|
|
Initialize();
|
|
}
|
|
|
|
CRaceMotionData::~CRaceMotionData()
|
|
{
|
|
Destroy();
|
|
}
|