#include "gamesrv.h" #include "stdafx.h" #include "Player.h" #include "BaseObject_Common.h" #include "ObjectManager.h" #include "Protocol.h" #include "Skill_Common.h" #include "SkillManager.h" #include "SkillScript.h" #include "Status_Common.h" #include "DamageCalc.h" #include "StatusCalc_Server.h" #include "StatusScript.h" #include "RangeCheck.h" #include "LevelScript.h" #include "PartyManager.h" #include "Drop.h" #include "AIManager.h" #include "PVPManager.h" #include "DeathMatchObject.h" #include "DuelManager.h" #include "TutorialScript.h" #include "NpcScript.h" #include "ItemManager.h" #include "Tarot_Common.h" #include "Tutorial_Common.h" #include "Monster.h" #include "Npc.h" #include "Item.h" #include "Communityscript.h" #include "StageScript.h" #include "MonsterScript.h" #include "Cheat_Common.h" #include "Protocol_Cheat.h" #include "PVP_Common.h" #include "StatusCalc_Server.h" #include "Gathering.h" #include "VehicleScript.h" #include "Vehicle_Common.h" #include "VehicleScript.h" #include "MakeSkill_Common.h" #include "MakeSkillScript.h" #include "Guild.h" #include "GuildManager.h" #include "GridManager.h" #include "RandomTable.h" #include "AppTimer.h" #include "PartyUnion.h" #include "PartyUnionManager.h" #include "Theme_Common.h" #include "ThemeManager.h" #include "UserPortal.h" /// ġƮ #include "Protocol_Cheat.h" #include "Cheat_Common.h" // Áö¿¬½Ã°£ #define DELAY_ITEM_AGENT_CHECK 600000 // ÆÇ¸Å´ëÇà Áö¿¬½Ã°£ - 10ºÐ(MS) #define DELAY_POST_CHECK 600000 // ¿ìÆí°Ë»ç Áö¿¬½Ã°£ - 10ºÐ(MS) #define DELAY_ITEM_BILL 600 // ¾ÆÀÌÅÛ ºô¸µ Áö¿¬½Ã°£ - 10ºÐ(SS) int StallSellItemCompare( const void *arg1, const void *arg2 ) { StallSellItem* item1 = (StallSellItem*)arg1; StallSellItem* item2 = (StallSellItem*)arg2; // ³»¸²Â÷¼ø Á¤·Ä return (item2->status != StallSellItemNone) - (item1->status != StallSellItemNone); } bool InfLeftTimeSort( unsigned long arg1, unsigned long arg2 ) { cInfluenceObject* pLeft = SKILLMANAGER->GetInfluence( arg1 ); cInfluenceObject* pRight = SKILLMANAGER->GetInfluence( arg2 ); if( pLeft == NULL ) return true; if( pRight == NULL ) return false; return pLeft->GetChangeMPValue() > pRight->GetChangeMPValue(); } bool InfChangeMPMinSort( unsigned long arg1, unsigned long arg2 ) { cInfluenceObject* pLeft = SKILLMANAGER->GetInfluence( arg1 ); cInfluenceObject* pRight = SKILLMANAGER->GetInfluence( arg2 ); if( pLeft == NULL ) return true; if( pRight == NULL ) return false; return pLeft->GetInfluenceEndTime() < pRight->GetInfluenceEndTime(); } cPlayer::cPlayer() : cBaseObject( eOBJECTTYPE_PLAYER ) { //mpSkill = NULL; mPlayerWeaponState = eWEAPON_STATE_NONE; mNpcIdx = 0; mRange = 0.0f; mRangeTargetPos = NiPoint2::ZERO; mRangeTarget.type = eOBJECTTYPE_NONE; mRangeTarget.index = 0; mPartyState = ePARTY_NONE; mIsGuildAddReq = false; mMonsterImportance = 0; memset( mStatus2Plus, 0 , sizeof(mStatus2Plus) ); memset( mStatus2Per, 0 , sizeof(mStatus2Per) ); mNextRecoveryTime = 0; mGameIn = false; memset( mFollowPos, 0, sizeof(mFollowPos) ); mStatus2.mMoveSpeed = 500; mStatus2.mAttackSpeed = 1.0f; mPlayerExrInfo.mFixedObjectSizePer = 0; mIsRequestRejection = eREQREJCT_NONE; mThemePartyDb = false; mDuelPlayerIdx = 0; mIsDuelRequester = false; mDuelStraightWin = 0; mPlayerExrInfo.mBaseFixedSize = FIXED_OBJECT_SIZE; CalcFixedObjectSize( 0 ); mTitleUniqIndex = 0; memset( &mOptionData1, 0, sizeof(mOptionData1) ); /// ġƮ mCheatHideMode = false; mCheatUndeadMode = false; mCheatChatDuration = 0; mCheatChatAccumTime = 0; mCheatStopDuration = 0; mCheatSpeedUp = eCHEATSPEEDUP_NONE; mJobUsedSpArr.Resize(5); for( unsigned int i=0;iGetAccumTime(); mIsDbUpdate = false; mServerPosTime = 0; mReadyGotoPos = NiPoint2::ZERO; mJumpEndTime = 0; mJumpTime = 0; mThemeRoomIdx = 0; mThemeUserRoot.pool = NULL; mThemeUserRoot.root = NULL; mThemeMode = 0; mItemEnhanceEndTime = 0; mEnhanceSlot1 = USHRT_MAX; mEnhanceSlot2 = USHRT_MAX; mEnhanceSlot3 = USHRT_MAX; memset( mTempNpcTarotCards, 0, sizeof(mTempNpcTarotCards) ); mTutorialModeIndex = -1; mPvPDieEndTime = 0; mPvPDieTime = 0; mFriendUseDB = false; mFriendSend = false; mAutoPlayer = false; mAutoTrial = false; mTrialAnswerCount = 0; mTrialMemberIdx = 0; mTrialAnswerTime = 0; mLastAttackTime = 0; mCaptchaCount = 0; mPcBangNextCheckTime = ULONG_MAX; mGMEventNextCheckTime = ULONG_MAX; mGMEventDelNextCheckTime = ULONG_MAX; mExpRecoverEndTime = TIMER->GetRealTime(); mInfNoSave = false; mCashInfNextSaveTime = 0; mIsCashInfSave = false; mIsCashInfCycleSave = false; mMapNum0Save = false; mJumpMoveSpeedDownEndTime = 0; mJumpSpeedState = 0; mIsMoveMsg = false; memset( &mMoveMsg, 0, sizeof(mMoveMsg) ); memset( mCaptchaName, 0x00, sizeof(mCaptchaName) ); mChannelPvPGoCid = 0; mChannelPvPMoveTime = 0; mPvPJoinAryPos = ULONG_MAX; mOriMaxHP = 0; mOriMaxMP = 0; mWaitSaveExp = 0; } cPlayer::~cPlayer() { if( mSkillCoolTimeFail > 10 || mMonSkillCoolTimeFail > 10 ) { NETWORK2->PostServerEvent("skill log player[%d][%d][%d,%d,%d][%d,%d,%d]", mObject.index, NETWORK2->GetAccumTime()-mGameInTime, mSkillReqCnt, mSkillSuccessCnt, mSkillCoolTimeFail, mMonSkillReqCnt, mMonSkillSuccessCnt, mMonSkillCoolTimeFail ); } while ( mItemBillRoot.pool != NULL ) { ITEMBILLPOOL->ReleaseItemBill( &mItemBillRoot, (PerItemBill*)mItemBillRoot.pool ); } while ( mItemGetRoot.pool != NULL ) { ITEMGETPOOL->ReleaseItemGet( &mItemGetRoot, (PerItemGet*)mItemGetRoot.pool ); } while ( mItemCountRoot.pool != NULL ) { ITEMCOUNTPOOL->ReleaseItemCount( &mItemCountRoot, (PerItemCount*)mItemCountRoot.pool ); } mObject.index = 0; } void* cPlayer::operator new( size_t n ) { if( n != sizeof(cPlayer) ) { assert(0); return NULL; } return OBJECTMANAGER->AllocPlayer(); } void cPlayer::operator delete( void* ptr, size_t n ) { /// NULL Æ÷ÀÎÅÍ °Ë»ç if( ptr == 0 ) { assert(0); return; } if( n != sizeof(cPlayer) ) { assert(0); return; } OBJECTMANAGER->FreePlayer( static_cast(ptr) ); return; } // Init Method bool cPlayer::Init(unsigned long connectionIdx, unsigned long playerIdx, unsigned long money, unsigned long deposit) { // sObject & sPlayerInfo ÃʱâÈ­. cBaseObject::SetObjectID(playerIdx); mPlayerInfo.CharacterIdx = playerIdx; // ConnectionIdx ÃʱâÈ­. mConnectionIdx = connectionIdx; /// ±âº»Á¤º¸¼ÂÆÃ - ÃʱâÈ­ mPlayerExrInfo.RestHP = 0; mPlayerExrInfo.MaxHP = 0; mPlayerExrInfo.MaxMP = 0; mPlayerInfo.Level = 0; mPlayerInfo.Job = ePLAYER_NONEJOB; mIsSkillResurrection = false; mSkillResurrectionHP = 0; mSkillResurrectionMP = 0; mPlayerExrInfo.mStateIdle = eIDLE_NORMAL; mPlayerExrInfo.mState = eOBJECT_STATE_IDLE; mPlayerExrInfo.mStateStop = eSTOP_NONE; mMapChange = false; mMapTargetPos.mMapNumber = 0; mMapTargetPos.mPosX = 0.0f; mMapTargetPos.mPosY = 0.0f; mMapTargetPos.mRotAngle = 0.0f; mThemePartyDb = false; /// ¼ÒÁö±Ý¾× & ¿¹Ä¡±Ý¾× ¼³Á¤. mMoney = money; mDeposit = deposit; memset( mODDITY, 0, sizeof(mODDITY) ); /// ¾ÆÀÌÅÛ °ü·Ã º¯¼ö ÃʱâÈ­. mInventoryDatabase = 0; memset( mInventory, 0, sizeof(mInventory) ); mItemActiveWeapon = ItemActiveFront; mItemChange = false; mItemWeight = 0; mXCopyComplete = false; memset( &mEquipAbility, 0, sizeof(mEquipAbility) ); mArmorSets = ARMOR_SETS_NONE; mItemEnhancedSeed = RANDOMTABLE->GetSeed( ); mItemChangeSeed = RANDOMTABLE->GetSeed( ); mItemBillRoot.pool = NULL; mItemBillRoot.root = NULL; mItemBillStart = false; mItemGetRoot.pool = NULL; mItemGetRoot.root = NULL; mItemCountRoot.pool = NULL; mItemCountRoot.root = NULL; mCooltimeRoot.pool = NULL; mCooltimeRoot.root = NULL; /// ¾ÆÀÌÅÛÁݱ⠰ü·Ã º¯¼ö ÃʱâÈ­. mItemGetOpen = false; mItemGetIdx = 0; mItemGetCount = 0; memset( mItemGetData, 0, sizeof(mItemGetData) ); /// °Å·¡ °ü·Ã º¯¼ö ÃʱâÈ­. mExchangeStatus = ItemExchangeNone; mExchangeItems = 0; mExchangeMoney = 0; /// ³ëÁ¡ °ü·Ã º¯¼ö ÃʱâÈ­. mStallSell = false; memset( mStallSellTitle, 0, sizeof(mStallSellTitle) ); memset( mStallSellItems, 0, sizeof(mStallSellItems) ); mStallSellItemOffset = 0; memset( mStallSellGuests, 0, sizeof(mStallSellGuests) ); mStallSellGuestOffset = 0; memset( &mStallSellOwner, 0, sizeof(mStallSellOwner) ); /// ÆÇ¸Å´ëÇà °ü·Ã º¯¼ö ÃʱâÈ­. SetItemAgentCheck( DELAY_ITEM_AGENT_CHECK ); /// ¿ìÆí °ü·Ã º¯¼ö ÃʱâÈ­. SetPostCheck( DELAY_POST_CHECK ); /// Ÿ·ÎÄ«µå °ü·Ã º¯¼ö ÃʱâÈ­. memset( mTarotTitle, 0, sizeof(mTarotTitle) ); mTarotPrice = 0; mTarotUserCount = 0; mTarotItemCount = 0; mTarotCloseReserved = false; memset( mTarotCards, 0, sizeof(mTarotCards) ); memset( mSpread, 0, sizeof(mSpread) ); mSpreadOffset = 0; mTarotReaderIdx = 0; memset( mTarotGuests, 0, sizeof(mTarotGuests) ); mTarotGuestOffset = 0; mTarotResultIndex = 0; mTarotResultValue = 0; mDuelIdx = 0; mPvPDMIdx = 0; mIsInDunJoin = false; mInDunMapDataNum = 0; /// Äù½ºÆ® °ü·Ã º¯¼ö ÃʱâÈ­ memset( mQuest, 0, sizeof(TB_QUEST_PROGRESS) * MAX_KEEPQUEST ); /// TIMESTAMP_STRUCT timestamp; timestamp.year = 1900; timestamp.month = 1; timestamp.day = 1; timestamp.hour = 0; timestamp.minute = 0; timestamp.second = 0; timestamp.fraction = 0; for( int i = 0; i < 5; ++i ) { mFortuneThru[i] = timestamp; } /// Ä¿¹Â´ÏƼ °ü·Ã º¯¼ö ÃʱâÈ­. ClearFriends( ); mMapNum0Save = false; mIsDbUpdate = false; // ºí·Ï °ü·Ã º¯¼ö ÃʱâÈ­. mBlockApply = false; mBlockValidThru = 0; mClientMoveDefTime = 0; mClientMovePlusMinus = 0; mServerMoveTime = 0; mSkillLastAttack = mObject; mSkillLastKind = eDAMAGE_MISS; mKeyboardMove = false; mThemeMode = 0; mItemEnhanceEndTime = 0; mEnhanceSlot1 = USHRT_MAX; mEnhanceSlot2 = USHRT_MAX; mEnhanceSlot3 = USHRT_MAX; mTutorialModeIndex = -1; mPvPDieEndTime = 0; mPvPDieTime = 0; mFriendUseDB = false; mFriendSend = false; mExpRecoverEndTime = TIMER->GetRealTime(); mInfNoSave = false; mCashInfNextSaveTime = NETWORK2->GetAccumTime() + INFLUENCE_CASH_NEXT_SAVETIME; mIsCashInfSave = false; mIsCashInfCycleSave = false; mIsMoveMsg = false; memset( &mMoveMsg, 0, sizeof(mMoveMsg) ); mJumpMoveSpeedDownEndTime = 0; mJumpSpeedState = 0; mChannelPvPGoCid = 0; mChannelPvPMoveTime = 0; mPvPJoinAryPos = ULONG_MAX; mOriMaxHP = 0; mOriMaxMP = 0; // ÃʱâÈ­ ³Ö¾îÁÜ. [3/31/2010 Jo_Client] mGuardAry.Clear(); mChangeMPDamageAry.Clear(); mDeleteTypeDamagedAry.Clear(); return true; } void cPlayer::Update( unsigned long elapsedTime, unsigned long accumTime ) { if( mChannelPvPMoveTime != 0 && mChannelPvPMoveTime < accumTime ) { NETWORK2->GotoInstantDungeon( mConnectionIdx, mChannelPvPGoCid ); return; } if( mIsMoveMsg == true ) { mIsMoveMsg = false; switch( mMoveMsg.mProtocol ) { case NM_PLAYER_KEYMOVE_REQ: { if( mMoveMsg.mMsgError == false ) { if( GetCheatHideMode() == false ) { // ´Ù¸¥ Ç÷¹À̾îµé¿¡°Ôµµ ¾Ë¸² MSG_SYN_MOVE Msg; Msg.Category = NM_PLAYER; Msg.Protocol = NM_PLAYER_MOVE_SYN; Msg.characterIdx = mObject.index; Msg.destX = mMoveMsg.mDestPos.x; Msg.destY = mMoveMsg.mDestPos.y; Msg.moveSpeed = GetMoveSpeed(); NETWORK2->QuickSendExcept( this, (char*)&Msg, sizeof(Msg) ); } } else { // 070625 PKH ½ÇÆÐ ¸Þ¼¼Áö ¹ß¼Û - ¼­¹ö»óÀÇ ÁÂÇ¥·Î Ŭ¶óÀÌ¾ðÆ®¸¦ ¿Å±â°Ô ÇÔ HANDLE handle = NULL; MSG_RES_KEYMOVE* msg = (MSG_RES_KEYMOVE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_KEYMOVE_RES ); msg->mCharacterPosX = mMoveMsg.mDestPos.x; msg->mCharacterPosY = mMoveMsg.mDestPos.y; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_KEYMOVE) ); if( GetState() == eOBJECT_STATE_MOVE ) { if( GetCheatHideMode() == false ) { // ´Ù¸¥ Ç÷¹À̾îµé¿¡°Ôµµ ¾Ë¸² MSG_SYN_MOVE_STOP Msg; Msg.Category = NM_PLAYER; Msg.Protocol = NM_PLAYER_MOVE_STOP_SYN; Msg.mCharacterIdx = mObject.index; Msg.mCharacterPosX = GetXPos(); Msg.mCharacterPosY = GetYPos(); NETWORK2->QuickSendExcept( this, (char*)&Msg, sizeof(Msg) ); } } } } break; case NM_PLAYER_MOVE_REQ: { if( mMoveMsg.mMsgError == false ) { if( GetCheatHideMode() == false ) { // ´Ù¸¥ Ç÷¹À̾îµé¿¡°Ôµµ ¾Ë¸² MSG_SYN_MOVE Msg; Msg.Category = NM_PLAYER; Msg.Protocol = NM_PLAYER_MOVE_SYN; Msg.characterIdx = mObject.index; Msg.destX = mMoveMsg.mDestPos.x; Msg.destY = mMoveMsg.mDestPos.y; Msg.moveSpeed = GetMoveSpeed(); NETWORK2->QuickSendExcept( this, (char*)&Msg, sizeof(Msg) ); } } else { // 070625 PKH ½ÇÆÐ ¸Þ¼¼Áö ¹ß¼Û - ¼­¹ö»óÀÇ ÁÂÇ¥·Î Ŭ¶óÀÌ¾ðÆ®¸¦ ¿Å±â°Ô ÇÔ HANDLE handle = NULL; MSG_RES_ERR_MOVE* msg = (MSG_RES_ERR_MOVE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_MOVE_RES ); msg->destX = mMoveMsg.mDestPos.x; msg->destY = mMoveMsg.mDestPos.y; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_ERR_MOVE) ); if( GetState() == eOBJECT_STATE_MOVE ) { if( GetCheatHideMode() == false ) { // ´Ù¸¥ Ç÷¹À̾îµé¿¡°Ôµµ ¾Ë¸² MSG_SYN_MOVE_STOP Msg; Msg.Category = NM_PLAYER; Msg.Protocol = NM_PLAYER_MOVE_STOP_SYN; Msg.mCharacterIdx = mObject.index; Msg.mCharacterPosX = GetXPos(); Msg.mCharacterPosY = GetYPos(); NETWORK2->QuickSendExcept( this, (char*)&Msg, sizeof(Msg) ); } } } } break; case NM_PLAYER_ACTIONMOVE_REQ: { if( mMoveMsg.mMsgError == false ) { if( GetCheatHideMode() == false ) { // ´Ù¸¥ Ç÷¹À̾îµé¿¡°Ôµµ ¾Ë¸² MSG_SYN_ACTIONMOVE Msg; Msg.Category = NM_PLAYER; Msg.Protocol = NM_PLAYER_ACTIONMOVE_SYN; Msg.characterIdx = mObject.index; Msg.destX = mMoveMsg.mDestPos.x; Msg.destY = mMoveMsg.mDestPos.y; Msg.targetX = mMoveMsg.mTargetPos.x; Msg.targetY = mMoveMsg.mTargetPos.y; Msg.range = mMoveMsg.mRange; Msg.targetInfo = mMoveMsg.mTargetInfo; Msg.moveSpeed = GetMoveSpeed(); NETWORK2->QuickSendExcept( this, (char*)&Msg, sizeof(Msg) ); } } else { HANDLE handle = NULL; MSG_RES_ERR_MOVE* sendMsg = (MSG_RES_ERR_MOVE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_ACTIONMOVE_RES ); sendMsg->destX = mMoveMsg.mDestPos.x; sendMsg->destY = mMoveMsg.mDestPos.y; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_ERR_MOVE) ); if( GetState() == eOBJECT_STATE_MOVE ) { if( GetCheatHideMode() == false ) { // ´Ù¸¥ Ç÷¹À̾îµé¿¡°Ôµµ ¾Ë¸² MSG_SYN_MOVE_STOP Msg; Msg.Category = NM_PLAYER; Msg.Protocol = NM_PLAYER_MOVE_STOP_SYN; Msg.mCharacterIdx = mObject.index; Msg.mCharacterPosX = GetXPos(); Msg.mCharacterPosY = GetYPos(); NETWORK2->QuickSendExcept( this, (char*)&Msg, sizeof(Msg) ); } } } } break; case NM_PLAYER_ACTIONMOVE_STOP_REQ: { if( mMoveMsg.mMsgError == true ) { // ¼­¹ö»óÀÇ ÁÂÇ¥·Î Ŭ¶óÀÌ¾ðÆ®¸¦ ¿Å±â°Ô ÇÔ HANDLE handle = NULL; MSG_RES_MOVE_STOP* msg = (MSG_RES_MOVE_STOP*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_ACTIONMOVE_STOP_RES ); if ( msg != NULL ) { msg->mCharacterPosX = mObjectPos.x; msg->mCharacterPosY = mObjectPos.y; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_MOVE_STOP) ); } } if( GetCheatHideMode() == false ) { // ´Ù¸¥ Ç÷¹À̾îµé¿¡°Ôµµ ¾Ë¸² MSG_SYN_MOVE_STOP Msg; Msg.Category = NM_PLAYER; Msg.Protocol = NM_PLAYER_ACTIONMOVE_STOP_SYN; Msg.mCharacterIdx = mObject.index; Msg.mCharacterPosX = GetXPos(); Msg.mCharacterPosY = GetYPos(); NETWORK2->QuickSendExcept( this, (char*)&Msg, sizeof(Msg) ); } } break; case NM_PLAYER_KEYMOVE_STOP_REQ: { if( mMoveMsg.mMsgError == true ) { // ¼­¹ö»óÀÇ ÁÂÇ¥·Î Ŭ¶óÀÌ¾ðÆ®¸¦ ¿Å±â°Ô ÇÔ HANDLE handle = NULL; MSG_RES_MOVE_STOP* msg = (MSG_RES_MOVE_STOP*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_KEYMOVE_STOP_RES ); if ( msg != NULL ) { msg->mCharacterPosX = mObjectPos.x; msg->mCharacterPosY = mObjectPos.y; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_MOVE_STOP) ); } } if( GetCheatHideMode() == false ) { // ´Ù¸¥ Ç÷¹À̾îµé¿¡°Ôµµ ¾Ë¸² MSG_SYN_MOVE_STOP Msg; Msg.Category = NM_PLAYER; Msg.Protocol = NM_PLAYER_KEYMOVE_STOP_SYN; Msg.mCharacterIdx = mObject.index; Msg.mCharacterPosX = GetXPos(); Msg.mCharacterPosY = GetYPos(); NETWORK2->QuickSendExcept( this, (char*)&Msg, sizeof(Msg) ); } } break; case NM_PLAYER_FOLLOWMOVE_STOP_REQ: { if( mMoveMsg.mMsgError == true ) { // ¼­¹ö»óÀÇ ÁÂÇ¥·Î Ŭ¶óÀÌ¾ðÆ®¸¦ ¿Å±â°Ô ÇÔ HANDLE handle = NULL; MSG_RES_MOVE_STOP* msg = (MSG_RES_MOVE_STOP*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_FOLLOWMOVE_STOP_RES ); if ( msg != NULL ) { msg->mCharacterPosX = mObjectPos.x; msg->mCharacterPosY = mObjectPos.y; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_MOVE_STOP) ); } } if( GetCheatHideMode() == false ) { // ´Ù¸¥ Ç÷¹À̾îµé¿¡°Ôµµ ¾Ë¸² MSG_SYN_MOVE_STOP Msg; Msg.Category = NM_PLAYER; Msg.Protocol = NM_PLAYER_FOLLOWMOVE_STOP_SYN; Msg.mCharacterIdx = mObject.index; Msg.mCharacterPosX = GetXPos(); Msg.mCharacterPosY = GetYPos(); NETWORK2->QuickSendExcept( this, (char*)&Msg, sizeof(Msg) ); } } break; case NM_PLAYER_FINDPOSITIONMOVE_STOP_REQ: { if( mMoveMsg.mMsgError == true ) { // ¼­¹ö»óÀÇ ÁÂÇ¥·Î Ŭ¶óÀÌ¾ðÆ®¸¦ ¿Å±â°Ô ÇÔ HANDLE handle = NULL; MSG_RES_MOVE_STOP* msg = (MSG_RES_MOVE_STOP*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_FINDPOSITIONMOVE_STOP_RES ); if ( msg != NULL ) { msg->mCharacterPosX = mObjectPos.x; msg->mCharacterPosY = mObjectPos.y; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_MOVE_STOP) ); } } if( GetCheatHideMode() == false ) { // ´Ù¸¥ Ç÷¹À̾îµé¿¡°Ôµµ ¾Ë¸² MSG_SYN_MOVE_STOP Msg; Msg.Category = NM_PLAYER; Msg.Protocol = NM_PLAYER_FINDPOSITIONMOVE_STOP_SYN; Msg.mCharacterIdx = mObject.index; Msg.mCharacterPosX = GetXPos(); Msg.mCharacterPosY = GetYPos(); NETWORK2->QuickSendExcept( this, (char*)&Msg, sizeof(Msg) ); } } break; } } /// Ç÷¹À̾î À̵¿ ó¸® switch( GetState() ) { case eOBJECT_STATE_MOVE: { /// À̵¿ºÒ°¡ »óÅ ÀÌ»óÀÎ °æ¿ì if( IsCantMove() == true ) return; float moveElapsedTime = (float)(elapsedTime) / SECOND_THOUSAND; unsigned long applyElapsedTime = elapsedTime; if( mKeyboardMove == true ) { long gap = 1; if( mClientMoveDefTime > 0 ) { if( mClientMoveDefTime < gap ) gap = mClientMoveDefTime; /// ÃÖ¼Ò´ÜÀ§¸¦ ´õÇØ¼­ Áõ°¡ float changeGap = (float)gap * mClientMovePlusMinus / SECOND_THOUSAND; moveElapsedTime = moveElapsedTime + changeGap; mClientMoveDefTime -= gap; } else if( mClientMoveDefTime < 0 ) { gap *= -1; if( mClientMoveDefTime > gap ) gap = mClientMoveDefTime; /// ÃÖ¼Ò´ÜÀ§¸¦ ´õÇØ¼­ Áõ°¡ float changeGap = (float)gap * mClientMovePlusMinus / SECOND_THOUSAND; moveElapsedTime = moveElapsedTime - changeGap; mClientMoveDefTime -= gap; } } /// Ç÷¹À̾îÀÇ À̵¿¼Óµµ NiPoint2 pos = mObjectPos; float speed = (float)GetMoveUpdateSpeed( accumTime ); /// ¹æÇâ ¼³Á¤ NiPoint2 dir1; dir1.x = mGotoX - GetXPos(); dir1.y = mGotoY - GetYPos(); dir1.Unitize(); /// ¼Óµµ * °æ°ú½Ã°£ ¸¸Å­ÀÇ ¿¹»ó À̵¿ À§Ä¡ °è»ê pos.x += (speed * moveElapsedTime * dir1.x); pos.y += (speed * moveElapsedTime * dir1.y); /// ¸ñÀûÁö ÁÂÇ¥¿Í ¿¹»ó À̵¿ À§Ä¡¸¦ ºñ±³ NiPoint2 dir2; dir2.x = mGotoX - pos.x; dir2.y = mGotoY - pos.y; dir2.Unitize(); /// ¿¹»ó À̵¿À§Ä¡°¡ ¸ñÀûÁö ÁÂÇ¥¸¦ ³Ñ¾î°¡¸é ¸ñÀûÁö µµ´Þ·Î ÆÇÁ¤ if( dir2.Dot(dir1) <= 0.0f ) { /// Ç÷¹À̾ ¸ñÀûÁö±îÁö µµ´Þ Çß´Ù°í ÆÇÁ¤ÀÌ ³­°æ¿ì pos.x = mGotoX; pos.y = mGotoY; if( mKeyboardMove == false ) ClearMoveSyncCalc(); NiPoint2 target( mGotoX, mGotoY ); float applyRange = (target - pos).Length(); if( applyRange > 0.0f && speed > 0 ) { applyElapsedTime = (unsigned long)( applyRange * SECOND_THOUSAND / speed ); if( elapsedTime < applyElapsedTime ) applyElapsedTime = 0; } /// ´ë±â »óÅ·Π¹Ù²Þ if( ChangeState( eOBJECT_STATE_IDLE ) == false ) { assert(NULL); NETWORK2->PostServerEvent("Player[%d] Update ChangeState( eOBJECT_STATE_IDLE ) == false", mObject.index ); } } else { if( FloatToInt(mRange) != 0 ) { /// Ÿ°Ù ÁÂÇ¥ ¼³Á¤ NiPoint3 targetPos( mRangeTargetPos.x, mRangeTargetPos.y, 0.0f ); NiPoint3 playerGuessPos( pos.x, pos.y, 0.0f ); AIMANAGER->CalcHeight( mMapNumber, &playerGuessPos.z, playerGuessPos.x, playerGuessPos.y ); NiPoint3 playerNowPos( GetXPos(), GetYPos(), Height() ); if( mRangeTarget.type == eOBJECTTYPE_NONE ) { AIMANAGER->CalcHeight( mMapNumber, &targetPos.z, targetPos.x, targetPos.y ); float rangeFix = OBJECTMANAGER->ObjectSizeRange( this, 0, mRange ); cRangeCheck range( rangeFix ); if( range.IsRange( playerGuessPos, targetPos ) ) { NiPoint3 p; NiPoint3 d = playerNowPos - targetPos; d.Unitize(); p.x = targetPos.x + (rangeFix-1.0f)*d.x; p.y = targetPos.y + (rangeFix-1.0f)*d.y; pos.x = p.x; pos.y = p.y; if( mKeyboardMove == false ) ClearMoveSyncCalc(); SetMoveTargetPos( p.x, p.y ); mRange = 0.0f; /// ´ë±â »óÅ·Π¹Ù²Þ if( ChangeState( eOBJECT_STATE_IDLE ) == false ) { assert(NULL); NETWORK2->PostServerEvent("Player[%d] Update ChangeState( eOBJECT_STATE_IDLE ) == false", mObject.index ); } } } else { cBaseObject* pTarget = OBJECTMANAGER->GetObject( mRangeTarget.type, mRangeTarget.index ); if( pTarget != NULL ) { targetPos.x = pTarget->GetXPos(); targetPos.y = pTarget->GetYPos(); targetPos.z = pTarget->Height(); float rangeFix = OBJECTMANAGER->ObjectSizeRange( this, pTarget, mRange ); cRangeCheck range( rangeFix ); if( range.IsRange( playerGuessPos, targetPos ) ) { NiPoint3 p; NiPoint3 d = playerNowPos - targetPos; d.Unitize(); p.x = targetPos.x + (rangeFix-1.0f)*d.x; p.y = targetPos.y + (rangeFix-1.0f)*d.y; pos.x = p.x; pos.y = p.y; if( mKeyboardMove == false ) ClearMoveSyncCalc(); SetMoveTargetPos( p.x, p.y ); mRange = 0.0f; /// ´ë±â »óÅ·Π¹Ù²Þ if( ChangeState( eOBJECT_STATE_IDLE ) == false ) { assert(NULL); NETWORK2->PostServerEvent("Player[%d] Update ChangeState( eOBJECT_STATE_IDLE ) == false", mObject.index ); } } } else { mRange = 0; /// ´ë±â »óÅ·Π¹Ù²Þ if( ChangeState( eOBJECT_STATE_IDLE ) == false ) { assert(NULL); NETWORK2->PostServerEvent("Player[%d] Update ChangeState( eOBJECT_STATE_IDLE ) == false", mObject.index ); } } } } } SetPos( pos.x, pos.y ); if( mReadyGotoPos != NiPoint2::ZERO && AIMANAGER->IsPossible( mMapNumber, mObjectPos, mReadyGotoPos, mObject ) == true ) { mGotoX = mReadyGotoPos.x; mGotoY = mReadyGotoPos.y; mReadyGotoPos = NiPoint2::ZERO; if( mCheatHideMode == false ) { // ´Ù¸¥ Ç÷¹À̾îµé¿¡°Ôµµ ¾Ë¸² MSG_SYN_MOVE Msg; Msg.Category = NM_PLAYER; Msg.Protocol = NM_PLAYER_MOVE_SYN; Msg.characterIdx = mObject.index; Msg.destX = mGotoX; Msg.destY = mGotoY; Msg.moveSpeed = GetMoveSpeed(); NETWORK2->QuickSendExcept( this, (char*)&Msg, sizeof(Msg) ); } } mServerMoveTime += applyElapsedTime; } break; case eOBJECT_STATE_PUSHPULL: { /// Ç÷¹À̾îÀÇ À̵¿¼Óµµ NiPoint2 pos = mObjectPos; float speed = SKILL_PUSHPULL_SPEED; /// ¹æÇâ ¼³Á¤ NiPoint2 dir1; dir1.x = mGotoX - GetXPos(); dir1.y = mGotoY - GetYPos(); dir1.Unitize(); /// ¼Óµµ * °æ°ú½Ã°£ ¸¸Å­ÀÇ ¿¹»ó À̵¿ À§Ä¡ °è»ê pos.x += (speed * ( (float)elapsedTime / SECOND_THOUSAND ) * dir1.x); pos.y += (speed * ( (float)elapsedTime / SECOND_THOUSAND ) * dir1.y); /// ¸ñÀûÁö ÁÂÇ¥¿Í ¿¹»ó À̵¿ À§Ä¡¸¦ ºñ±³ NiPoint2 dir2; dir2.x = mGotoX - pos.x; dir2.y = mGotoY - pos.y; dir2.Unitize(); /// ¿¹»ó À̵¿À§Ä¡°¡ ¸ñÀûÁö ÁÂÇ¥¸¦ ³Ñ¾î°¡¸é ¸ñÀûÁö µµ´Þ·Î ÆÇÁ¤ if( dir2.Dot(dir1) <= 0.0f ) { /// Ç÷¹À̾ ¸ñÀûÁö±îÁö µµ´Þ Çß´Ù°í ÆÇÁ¤ÀÌ ³­°æ¿ì pos.x = mGotoX; pos.y = mGotoY; if( mKeyboardMove == false ) ClearMoveSyncCalc(); /// ´ë±â »óÅ·Π¹Ù²Þ if( ChangeState( eOBJECT_STATE_IDLE ) == false ) { assert(NULL); NETWORK2->PostServerEvent("Player[%d] Update ChangeState( eOBJECT_STATE_IDLE ) == false", mObject.index ); } } SetPos( pos.x, pos.y ); } break; case ePLAYER_STATE_RUSH: { /// Ç÷¹À̾îÀÇ À̵¿¼Óµµ NiPoint2 pos = mObjectPos; float speed = SKILL_RUSH_SPEED; /// ¹æÇâ ¼³Á¤ NiPoint2 dir1; dir1.x = mGotoX - GetXPos(); dir1.y = mGotoY - GetYPos(); dir1.Unitize(); /// ¼Óµµ * °æ°ú½Ã°£ ¸¸Å­ÀÇ ¿¹»ó À̵¿ À§Ä¡ °è»ê pos.x += (speed * ( (float)elapsedTime / SECOND_THOUSAND ) * dir1.x); pos.y += (speed * ( (float)elapsedTime / SECOND_THOUSAND ) * dir1.y); /// ¸ñÀûÁö ÁÂÇ¥¿Í ¿¹»ó À̵¿ À§Ä¡¸¦ ºñ±³ NiPoint2 dir2; dir2.x = mGotoX - pos.x; dir2.y = mGotoY - pos.y; dir2.Unitize(); /// ¿¹»ó À̵¿À§Ä¡°¡ ¸ñÀûÁö ÁÂÇ¥¸¦ ³Ñ¾î°¡¸é ¸ñÀûÁö µµ´Þ·Î ÆÇÁ¤ if( dir2.Dot(dir1) <= 0.0f ) { /// Ç÷¹À̾ ¸ñÀûÁö±îÁö µµ´Þ Çß´Ù°í ÆÇÁ¤ÀÌ ³­°æ¿ì pos.x = mGotoX; pos.y = mGotoY; if( mKeyboardMove == false ) ClearMoveSyncCalc(); /// ´ë±â »óÅ·Π¹Ù²Þ if( ChangeState( eOBJECT_STATE_IDLE ) == false ) { assert(NULL); NETWORK2->PostServerEvent("Player[%d] Update ChangeState( eOBJECT_STATE_IDLE ) == false", mObject.index ); } } else { if( FloatToInt(mRange) != 0 ) { /// Ÿ°Ù ÁÂÇ¥ ¼³Á¤ NiPoint3 targetPos( mRangeTargetPos.x, mRangeTargetPos.y, 0.0f ); NiPoint3 playerGuessPos( pos.x, pos.y, 0.0f ); AIMANAGER->CalcHeight( mMapNumber, &playerGuessPos.z, playerGuessPos.x, playerGuessPos.y ); NiPoint3 playerNowPos( GetXPos(), GetYPos(), Height() ); if( mRangeTarget.type == eOBJECTTYPE_NONE ) { AIMANAGER->CalcHeight( mMapNumber, &targetPos.z, targetPos.x, targetPos.y ); float rangeFix = OBJECTMANAGER->ObjectSizeRange( this, 0, mRange ); cRangeCheck range( rangeFix ); if( range.IsRange( playerGuessPos, targetPos ) ) { NiPoint3 p; NiPoint3 d = playerNowPos - targetPos; d.Unitize(); p.x = targetPos.x + (rangeFix-1.0f)*d.x; p.y = targetPos.y + (rangeFix-1.0f)*d.y; pos.x = p.x; pos.y = p.y; if( mKeyboardMove == false ) ClearMoveSyncCalc(); SetMoveTargetPos( p.x, p.y ); mRange = 0.0f; /// ´ë±â »óÅ·Π¹Ù²Þ if( ChangeState( eOBJECT_STATE_IDLE ) == false ) { assert(NULL); NETWORK2->PostServerEvent("Player[%d] Update ChangeState( eOBJECT_STATE_IDLE ) == false", mObject.index ); } } } else { cBaseObject* pTarget = OBJECTMANAGER->GetObject( mRangeTarget.type, mRangeTarget.index ); if( pTarget != NULL ) { targetPos.x = pTarget->GetXPos(); targetPos.y = pTarget->GetYPos(); targetPos.z = pTarget->Height(); mGotoX = targetPos.x; mGotoY = targetPos.y; float rangeFix = OBJECTMANAGER->ObjectSizeRange( this, pTarget, mRange ); cRangeCheck range( rangeFix ); if( range.IsRange( playerGuessPos, targetPos ) ) { NiPoint3 p; NiPoint3 d = playerNowPos - targetPos; d.Unitize(); p.x = targetPos.x + (rangeFix-1.0f)*d.x; p.y = targetPos.y + (rangeFix-1.0f)*d.y; pos.x = p.x; pos.y = p.y; if( mKeyboardMove == false ) ClearMoveSyncCalc(); SetMoveTargetPos( p.x, p.y ); mRange = 0.0f; /// ´ë±â »óÅ·Π¹Ù²Þ if( ChangeState( eOBJECT_STATE_IDLE ) == false ) { assert(NULL); NETWORK2->PostServerEvent("Player[%d] Update ChangeState( eOBJECT_STATE_IDLE ) == false", mObject.index ); } } } else { mRange = 0; /// ´ë±â »óÅ·Π¹Ù²Þ if( ChangeState( eOBJECT_STATE_IDLE ) == false ) { assert(NULL); NETWORK2->PostServerEvent("Player[%d] Update ChangeState( eOBJECT_STATE_IDLE ) == false", mObject.index ); } } } } } if( IsMovePossible( mObjectPos, pos ) != 0 ) { ChangeState( eOBJECT_STATE_IDLE ); // ´Ù¸¥ Ç÷¹À̾îµé¿¡°Ôµµ ¾Ë¸² MSG_SYN_MOVE_STOP Msg; Msg.Category = NM_PLAYEREXT; Msg.Protocol = NM_PLAYEREXT_RUSHMOVESTOP_SYN; Msg.mCharacterIdx = mObject.index; Msg.mCharacterPosX = GetXPos(); Msg.mCharacterPosY = GetYPos(); NETWORK2->QuickSend( this, (char*)&Msg, sizeof(Msg) ); } else { SetPos( pos.x, pos.y ); } } break; case eOBJECT_STATE_ATTACK: { if( SKILLMANAGER->IsUsingSkill( mObject.type, mObject.index ) == false ) { if( ChangeState( eOBJECT_STATE_IDLE ) == false ) { assert(NULL); NETWORK2->PostServerEvent("Player[%d] Update ChangeState( eOBJECT_STATE_IDLE ) == false", mObject.index ); } } } break; case eOBJECT_STATE_STOP: if ( GetStateStop( ) == eSTOP_OPENTAROT ) { if ( IsTarotReaderClose( ) == true ) { if ( IsTarotCloseReserved( ) == true ) { TarotReaderClose( ERROR_TAROT_READER_CLOSE_SUCCESS ); } else if( !(GetTarotItemCount( ) > 0) || IsAddMoney( GetTarotPrice() ) == false ) { TarotReaderClose( ERROR_TAROT_READER_CLOSE_ITEM ); } } } else if ( GetStateStop() == eSTOP_CHEATSTOP ) { if( mCheatStopDuration < accumTime ) { mCheatStopDuration = 0; ChangeState( eOBJECT_STATE_IDLE ); SetStateStop( eSTOP_NONE ); } } else if( GetStateStop() == eSTOP_ENHANCED ) { if( mInventoryDb.enhanced == false && mItemEnhanceEndTime <= accumTime ) { ItemEnhancedEnd(); } } else if( GetStateStop() == eSTOP_ITEMMIX ) { /// Á¶ÇÕ ½Ã°£ üũ if( mInventoryDb.itemMix == false && mItemMixEndTime <= accumTime ) { ItemMixEnd(); } } break; } /// ÀÚ¿¬ ȸº¹ CalcNatureRecovery(); /// »ýȰ ½ºÅ³ Á¾·á üũ if( mPlayerExrInfo.mCommunitySkillIdx != 0 ) { if( mCommunitySkillEndTime < accumTime || GetState() != eOBJECT_STATE_IDLE ) { mPlayerExrInfo.mCommunitySkillIdx = 0; mCommunitySkillEndTime = 0.0f; } } /// °Å·¡ »ó´ë¹æ üũ if( mExchangeStatus > ItemExchangeAsk ) { cPlayer* player = GRIDMANAGER->GetPlayer( mExchangeTarget.index ); if ( player != NULL ) { float tempRange = OBJECTMANAGER->ObjectSizeRange( this, player, ITEM_VALID_DISTANCE + SYNC_MOVE_RANGE ); if ( (mObjectPos - player->GetPos( )).Length( ) > tempRange ) { ExchangeCancel(); } } } /// ¾ÆÁ÷ °É¸®Áö ¾ÊÀº pc¹æ ¹öÇÁ¸¦ °É¾îº»´Ù. if( mGameIn == true && mPcBangNextCheckTime < accumTime && mReadyPcInfSet.GetSize() != 0 ) { mPcBangNextCheckTime = accumTime + INFLUENE_PCBANG_NEXT_ADDTIME; cHashSet::cIterator i = mReadyPcInfSet.Begin(); while( i != mReadyPcInfSet.End() ) { unsigned long infIdx = (*i++); if( SKILLMANAGER->AddInfluence( mObject, mObject, infIdx, 0, true ) == true ) mReadyPcInfSet.Erase( infIdx ); } } /// ¾ÆÁ÷ »èÁ¦ÇÏÁö ¾ÊÀº GMÀ̺¥Æ® ¹öÇÁ¸¦ »èÁ¦ÇÑ´Ù. if( mReadyDelGMEventList.GetSize() != 0 && mGameIn == true && mGMEventDelNextCheckTime < accumTime ) { mGMEventDelNextCheckTime = accumTime + INFLUENCE_GMEVENT_NEXT_ADDTIME; time_t now; time( &now ); cGMEventList::cIterator pos = mReadyDelGMEventList.Begin(); while ( pos != mReadyDelGMEventList.End() ) { sGMEventInfo& eventInfo = (*pos); /// ½Ã°£ÀÌ Áö³­°ÍÀÌ ÀÖÀ¸¸é delete ·Î »©±â. if( difftime( eventInfo.validThru, now ) < 1 ) { SKILLMANAGER->DeleteInfluenceClassIdx( mObject, eventInfo.influenceIdx ); pos = mReadyDelGMEventList.Erase( pos ); continue; } ++pos; } } /// ¾ÆÁ÷ °É¸®Áö ¾ÊÀº GMÀ̺¥Æ® ¹öÇÁ¸¦ °É¾îº»´Ù. if( mReadyGMEventList.GetSize() != 0 && mGameIn == true && mGMEventNextCheckTime < accumTime ) { mGMEventNextCheckTime = accumTime + INFLUENCE_GMEVENT_NEXT_ADDTIME; time_t now; time( &now ); cGMEventList::cIterator pos = mReadyGMEventList.Begin(); while ( pos != mReadyGMEventList.End() ) { sGMEventInfo& eventInfo = (*pos); if( difftime( now, eventInfo.startTime ) > 0 && difftime( eventInfo.validThru, now ) > 0 ) { /// Àû¿ëµÉ ½Ã°£ÀÌ Àִ°ÍÀÌ ÀÖ´Ù¸é Àû¿ë½Ã۱â if( SKILLMANAGER->AddInfluence( mObject, mObject, eventInfo.influenceIdx, 0, true ) == true ) { ///½ÇÀç Àû¿ëµÈ °ÍµéÀ» »èÁ¦ ´ë±â ¸®½ºÆ®¿¡ ³Ö´Â´Ù. ///ÀÌ¹Ì »èÁ¦ ´ë±â Å¥¿¡ ÀÖ´Â °æ¿ì ¹«½ÃÇÑ´Ù. cGMEventList::cIterator find = mReadyDelGMEventList.Begin(); cGMEventList::cIterator end = mReadyDelGMEventList.End(); for ( ;find != end ;++find ) { sGMEventInfo& delEventInfo = (*find); if( delEventInfo.index == eventInfo.index && delEventInfo.influenceIdx == eventInfo.influenceIdx ) break; } if( find == end ) mReadyDelGMEventList.PushBack( eventInfo ); mGMEventDelNextCheckTime = 0; ///½ÇÀç Àû¿ëµÈ °ÍÀº Ãß°¡ ´ë±â ¸®½ºÆ®¿¡¼­ »«´Ù. pos = mReadyGMEventList.Erase( pos ); continue; } } ++pos; } } /// Àϰý ÀúÀå if( mBatchSaveTime <= accumTime ) { if( NETWORK2->GetServerType() != _E_ST_ID_PVP_ ) DBUpdate( false, PLAYER_DBUPDATE_PROCESS ); } #ifdef _DEBUG /// Å×½ºÆ®ÄÚµå static bool check = false; static unsigned long delayTime = 100; static bool sync = false; if( check == true && mServerPosTime < NETWORK2->GetAccumTime() ) { mServerPosTime += delayTime; HANDLE handle = NULL; MSG_SERVERPOS_TEST* resMsg = (MSG_SERVERPOS_TEST*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_TEST_SERVERPOS ); if ( resMsg != NULL ) { resMsg->mCharacterIdx = mObject.index; resMsg->mServerPosX = mObjectPos.x; resMsg->mServerPosY = mObjectPos.y; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SERVERPOS_TEST) ); } if( sync == true ) { MSG_SERVERPOS_TEST msg; msg.Category = NM_PLAYER; msg.Protocol = NM_PLAYER_TEST_SERVERPOS; msg.mCharacterIdx = mObject.index; msg.mServerPosX = mObjectPos.x; msg.mServerPosY = mObjectPos.y; NETWORK2->QuickSendExcept( this, (char*)&msg, sizeof(MSG_SERVERPOS_TEST) ); } } #endif // ¾ÆÀÌÅÛ ÆÇ¸Å´ëÇà °Ë»ç. if ( mItemAgentCheck == true ) { if ( mItemAgentNextCheck < accumTime ) { HANDLE handle = NULL; ITEM_AGENT_CHECK* check = (ITEM_AGENT_CHECK*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_AGENT_CHECK ); check->characterIdx = mObject.index; NETWORK2->SendSQL( mConnectionIdx, handle, sizeof(ITEM_AGENT_CHECK) ); SetItemAgentCheck( DELAY_ITEM_AGENT_CHECK ); } } // ¿ìÆí °Ë»ç. if ( mPostCheck == true ) { if ( mPostNextCheck < accumTime ) { HANDLE handle = NULL; POST_CHECK* check = (POST_CHECK*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_POST_CHECK ); check->characterIdx = mObject.index; NETWORK2->SendSQL( handle, sizeof(POST_CHECK) ); SetPostCheck( DELAY_POST_CHECK ); } } // ¾ÆÀÌÅÛ ºô. if ( mItemBillRoot.pool && mItemBillStart == true ) { PerItemBill* itemBill = (PerItemBill*)mItemBillRoot.pool; PerItemBill* nextBill; time_t current; double result; long elapsed; long before; long after; time( ¤t ); while ( itemBill != NULL && mInventoryDb.itemBill == false ) { nextBill = (PerItemBill*)itemBill->next; result = difftime( itemBill->timeEnd, current ); if ( (result <= 0) || (itemBill->apply == ItemBillApplyReserved) ) { // Á¾·áµÊ. if ( itemBill->type == ITEM_BILL_TIME ) { elapsed = (long)difftime( current, itemBill->timeBegin ); before = itemBill->validTime; after = itemBill->validTime-(before < elapsed ? before : elapsed); SaveItemBill( itemBill->idx, elapsed, before, after, itemBill->inventoryIdx ); } TB_INVENTORY* inventory = SelectInventoryIdx( itemBill->inventoryIdx, INVENTORY_EQUIP_BEGIN, INVENTORY_WAREHOUSE_END ); HANDLE handle = NULL; ITEM_BILL_REMOVE* remove = (ITEM_BILL_REMOVE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_BILL_REMOVE ); remove->idx = itemBill->idx; if ( inventory != NULL ) { remove->inventory = (*inventory); RemoveInventory( inventory ); } mInventoryDb.itemBill = NETWORK2->SendSQL( mConnectionIdx, handle, sizeof(ITEM_BILL_REMOVE) ); ITEMBILLPOOL->ReleaseItemBill( &mItemBillRoot, itemBill ); } else if ( itemBill->type == ITEM_BILL_TIME ) { // »ç¿ëÁß - ½Ã°£Á¦¸¸, ´ÜÀ§ ½Ã°£¸¸´Ù LOG ¹ß»ý. elapsed = (long)difftime( current, itemBill->timeBegin ); if ( elapsed >= DELAY_ITEM_BILL ) { before = itemBill->validTime; after = itemBill->validTime-(before < elapsed ? before : elapsed); SaveItemBill( itemBill->idx, elapsed, before, after, itemBill->inventoryIdx ); itemBill->validTime = after; itemBill->timeBegin = current; } } itemBill = nextBill; } } // ¾ÆÀÌÅÛ Áö±Þ. if ( mItemGetRoot.pool ) { HANDLE handle = NULL; ITEM_GET* itemGet = (ITEM_GET*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_GET_QUEST ); u_long length = sizeof(ITEM_GET) - sizeof(itemGet->table); TB_INVENTORY* table = itemGet->table; itemGet->characterIdx = mObject.index; while ( mItemGetRoot.pool != NULL ) { (*table) = ((PerItemGet*)mItemGetRoot.pool)->inventory; itemGet->rowCount++; table++; ITEMGETPOOL->ReleaseItemGet( &mItemGetRoot, (PerItemGet*)mItemGetRoot.pool ); } length += (itemGet->rowCount * sizeof(itemGet->table)); NETWORK2->SendSQL( mConnectionIdx, handle, length ); } // ¾ÆÀÌÅÛ º¯°æ. if ( mItemChange == true ) { // Àκ¥Å丮 ¹«°Ô °»½Å. TB_INVENTORY* inventory; TB_ITEM_DEFINE* itemDefine; mItemWeight = 0; inventory = SelectInventory( INVENTORY_CHARACTER_BEGIN ); for ( int i = INVENTORY_CHARACTER_BEGIN; i <= INVENTORY_CHARACTER_END; ++i, ++inventory ) { itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if ( itemDefine != NULL ) { mItemWeight = mItemWeight + (itemDefine->weight * inventory->count); } } // Àû¿ë¿Ï·á. mItemChange = false; } if( mXCopyComplete == true ) { // Äù½ºÆ® °»½Å. UpdateDutyItem( ); mXCopyComplete = false; } /// ij½Ã ¹öÇÁµé ÁÖ±â ÀúÀå if( mCashInfNextSaveTime < accumTime && mIsCashInfCycleSave == false ) { if( mMapChange == false && mGameIn == true ) { SKILLMANAGER->CycleSaveCashInfluence( this ); mCashInfNextSaveTime = accumTime + INFLUENCE_CASH_NEXT_SAVETIME; } } else if ( mAutoPlayer == true || (mTrialAnswerTime > 0 && mTrialAnswerTime < accumTime) ) { TrialEnd( true ); } } /// Á÷¾÷ üÀÎÁö void cPlayer::SetJob(ePLAYER_JOB job, unsigned long* skillList, unsigned char skillListCnt ) { mPlayerInfo.Job = job; SetJumpTime(); /// ÀüÁ÷ °ü·Ã Äù½ºÆ® Æ®¸®°Å °Ë»ç SendNewQuestList(); if( GetGuildIndex() > 0 ) { GUILDMAN->RequestUpdateUser( GetGuildIndex(), GetObjectID() ); } HANDLE handle = NULL; MSG_RES_JOB* resMsg = (MSG_RES_JOB*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_JOB_RES ); if ( resMsg != NULL ) { resMsg->mJob = (unsigned short)mPlayerInfo.Job; resMsg->mSkillListCnt = skillListCnt; memcpy( resMsg->mSkillClassIdx, skillList, sizeof(unsigned long) * skillListCnt ); NETWORK2->SendMsgRoot( handle, resMsg->GetMsgLength() ); } for( int i = 0 ; i < skillListCnt ; ++i ) { unsigned char error = SKILLMANAGER->AddPlayerHaveSkill( mObject.index, skillList[i], 0, 0 ); if( error != SKILL_ADD_ERR_SUCCESS ) { NETWORK2->PostServerEvent("cPlayer::SetJob AddPlayerHaveSkill[%d][%d,%d][%d] == false", mObject.index, skillList[i], 0, error ); } } MSG_SYN_JOB synMsg; synMsg.Category = NM_PLAYER; synMsg.Protocol = NM_PLAYER_JOB_SYN; synMsg.mPlayerIdx = mObject.index; synMsg.mJob = (unsigned short)job; NETWORK2->QuickSendExcept( this, (char*)&synMsg, sizeof(synMsg) ); /// ÆÄƼ¿¡ ÀüÁ÷ ½ÌÅ© º¸³»±â PARTYMAN->SendToJobChange( this ); } int cPlayer::SkillResetReq( unsigned short itemSlotNum ) { /*-- ¾ÆÀÌÅÛ »ç¿ë½Ã °Ë»çÇÒ ³»¿ëµé. */ /// db »ç¿ëºÎ üũ if ( mInventoryDatabase ) return ERROR_SKILLRESET_DBERROR; if ( IsInventoryBag( itemSlotNum ) == false ) return ERROR_SKILLRESET_ITEM; TB_INVENTORY* inventory = SelectInventory( itemSlotNum ); if( IsInventory( inventory ) == false ) return ERROR_SKILLRESET_ITEM; if( inventory->apply != InventoryApplyNone ) return ERROR_SKILLRESET_ITEM; TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if( itemDefine == NULL ) return ERROR_SKILLRESET_ITEM; if ( IsInventorySeal( itemDefine, inventory ) == true ) return ERROR_SKILLRESET_ITEM_LICENSE; /*-- Item Limit Table(TB_ITEM_LIMIT) Àû¿ë --*/ if ( !IsItemLimit( inventory->itemDefineIdx) ) return ERROR_SKILLRESET_ITEM; /// ½ºÅ³ ÃʱâÈ­ ¾ÆÀÌÅÛ ÀÎÁö È®ÀÎ if( !(itemDefine->type == ITEM_ETC1 && itemDefine->subType == ITEM_ETC1_SKILLRESET) ) return ERROR_SKILLRESET_ITEM; /// ij¸¯ÅÍ Á¤º¸db »ç¿ëÁßÀÎÁö üũ if( mIsDbUpdate == true ) return ERROR_SKILLRESET_DBERROR; /// »óÅ ¼³Á¤ if( ChangeState( eOBJECT_STATE_STOP ) == false ) return ERROR_SKILLRESET_STATE; SetStateStop( eSTOP_SKILLRESET ); /// ¾ÆÀÌÅÛ Â÷°¨ unsigned long inventoryIdx = inventory->idx; if ( inventory->count == 1 ) RemoveInventory( inventory->number ); else UpdateInventory( inventory, (-1) ); /// db ÀúÀå HANDLE handle = NULL; CHARACTER_SKILL_RESET* reset = (CHARACTER_SKILL_RESET*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_CHARACTER_SKILLRESET ); unsigned long length = sizeof(CHARACTER_SKILL_RESET) - sizeof(reset->mTable); reset->mCharacterIdx = mObject.index; reset->mRace = mPlayerInfo.Race; reset->mJobStep = (unsigned char)STATUSSCRIPT->GetJobStep( mPlayerInfo.Job ); reset->mJob = mPlayerInfo.Job; reset->mInventoryIdx = inventoryIdx; reset->mRetvalue = -1; if( NETWORK2->SendSQL( mConnectionIdx, handle, length ) == false ) return ERROR_SKILLRESET_DBERROR; mInventoryDb.skillReset = true; mIsDbUpdate = true; return ERROR_SKILLRESET_SUCCESS; } int cPlayer::ThemeResetReq( unsigned short itemSlotNum, unsigned short themeNum, unsigned char themeMode ) { /*-- ¾ÆÀÌÅÛ »ç¿ë½Ã °Ë»çÇÒ ³»¿ëµé. */ /// db »ç¿ëºÎ üũ if ( mInventoryDatabase ) return ERROR_THEMERESET_DBERROR; if ( IsInventoryBag( itemSlotNum ) == false ) return ERROR_THEMERESET_ITEM; TB_INVENTORY* inventory = SelectInventory( itemSlotNum ); if( IsInventory( inventory ) == false ) return ERROR_THEMERESET_ITEM; if( inventory->apply != InventoryApplyNone ) return ERROR_THEMERESET_ITEM; TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if( itemDefine == NULL ) return ERROR_THEMERESET_ITEM; if ( IsInventorySeal( itemDefine, inventory ) == true ) return ERROR_THEMERESET_ITEM_LICENSE; /*-- Item Limit Table(TB_ITEM_LIMIT) Àû¿ë --*/ if ( !IsItemLimit( inventory->itemDefineIdx) ) return ERROR_THEMERESET_ITEM; /// Å׸¶ ÃʱâÈ­ ¾ÆÀÌÅÛ ÀÎÁö È®ÀÎ if( !(itemDefine->type == ITEM_ETC1 && itemDefine->subType == ITEM_ETC1_THEME_RESET) ) return ERROR_THEMERESET_ITEM; PerThemeUser* pTheme = SearchThemeUser( MAKETHEMECID( themeNum, themeMode ) ); if( pTheme == NULL ) return ERROR_THEMERESET_READY; time_t ltime; time( <ime ); long result = (long)difftime( pTheme->validThru, ltime ); if ( result * SECOND < 5 * MINUTE ) return ERROR_THEMERESET_READY; /// »óÅ ¼³Á¤ if( ChangeState( eOBJECT_STATE_STOP ) == false ) return ERROR_THEMERESET_STATE; SetStateStop( eSTOP_THEMERESET ); /// ¾ÆÀÌÅÛ Â÷°¨ unsigned long inventoryIdx = inventory->idx; if ( inventory->count == 1 ) RemoveInventory( inventory->number ); else UpdateInventory( inventory, (-1) ); /// db ÀúÀå HANDLE handle = NULL; CHARACTER_THEME_RESET* reset = (CHARACTER_THEME_RESET*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_CHARACTER_THEMERESET ); unsigned long length = sizeof(CHARACTER_THEME_RESET) - sizeof(reset->mTable); reset->mCharacterIdx = mObject.index; reset->mThemeIdx = themeNum; reset->mThemeMode = themeMode; reset->mInventoryIdx = inventoryIdx; reset->mSlotNum = itemSlotNum; reset->mRetvalue = -1; if( NETWORK2->SendSQL( mConnectionIdx, handle, length ) == false ) return ERROR_THEMERESET_DBERROR; mInventoryDb.themeReset = true; return ERROR_THEMERESET_SUCCESS; } void cPlayer::AddExp( unsigned long addExp, bool addOption, bool expRecover ) { if( addExp == 0 ) return; unsigned char level = mPlayerInfo.Level; unsigned long totalExp = mHeroInfo.Exp; unsigned long calcAddExp = 0; ////////////////////////////////////////////////////////////////////////// /// Ãß°¡ °æÇèÄ¡ °è»ê if( addOption == true ) { /// Ãß°¡¿É¼Ç °æÇèÄ¡ Áõ°¡Ä¡ float addExpPer = (float)mStatusEtc.mExpAddPer; float addExpPlus = (float)mStatusEtc.mExpAddPlus; /// °æÇèÄ¡ °è»ê calcAddExp = FloatToInt( addExp + ( addExp * addExpPer / 100.0f ) + addExpPlus ); /// °æÇèÄ¡ = °æÇèÄ¡ + %È¿°ú + È¿°ú } else calcAddExp = addExp; ////////////////////////////////////////////////////////////////////////// /// ·¹º§¾÷ ¼öÄ¡¿Í ³²Àº °æÇèÄ¡ °è»ê /// ´ÙÀ½ ·¹º§·Î ³Ñ¾î°¡±â À§ÇÑ ÇÊ¿ä °æÇèÄ¡¸¦ ¾ò¾î¿È sExpTable* pExpTable = LEVELSCRIPT->GetExpTable( level ); if( pExpTable == NULL ) return; /// ÀúÀå ¾ÈµÈ °æÇèÄ¡ ±â·Ï mWaitSaveExp += addExp; /// °æÇèÄ¡°¡ ÀÏÁ¤·® ÀÌ»ó ½×ÀλóÅ·ΠÀúÀåÀÌ ¾ÈµÆÀ¸¸é ÀúÀåÇÏ°Ô ÇÑ´Ù if( mPlayerInfo.Level > 15 ) { if( mPlayerInfo.Level < 20 ) { if( mWaitSaveExp > (unsigned long)( pExpTable->mExp * 0.20f ) ) mBatchSaveTime = 0; } else if( mPlayerInfo.Level < 25 ) { if( mWaitSaveExp > (unsigned long)( pExpTable->mExp * 0.15f ) ) mBatchSaveTime = 0; } else if( mPlayerInfo.Level < 30 ) { if( mWaitSaveExp > (unsigned long)( pExpTable->mExp * 0.10f ) ) mBatchSaveTime = 0; } else if( mPlayerInfo.Level < 35 ) { if( mWaitSaveExp > (unsigned long)( pExpTable->mExp * 0.05f ) ) mBatchSaveTime = 0; } else { if( mWaitSaveExp > (unsigned long)( pExpTable->mExp * 0.02f ) ) mBatchSaveTime = 0; } } sExpTable* pMax = LEVELSCRIPT->GetExpTable( level + 1 ); if( pMax == NULL ) /// ´ÙÀ½ ·¹º§Á¤º¸°¡ ¾øÀ¸¸é ·¹º§¾÷ ¾ÈÇÏ°í °æÇèÄ¡¸¸ Áõ°¡ { /// ÇöÀç °æÇèÄ¡ Ãִ뺸´Ù ¸¹Àº°æ¿ì ÃÖ´ë -1 ¼³Á¤ if( pExpTable->mExp <= totalExp + calcAddExp ) mHeroInfo.Exp = pExpTable->mExp - 1; else mHeroInfo.Exp += calcAddExp; /// ½ÀµæÇÑ °æÇèÄ¡¸¦ ÇöÀç°æÇèÄ¡¿¡ ´õÇÔ } else /// Á¤»óÀûÀÎ ¹üÀ§³»¿¡¼­ÀÇ ·¹º§¾÷ ó¸® { /// ½ÀµæÇÑ °æÇèÄ¡¸¦ ÇöÀç°æÇèÄ¡¿¡ ´õÇÔ totalExp += calcAddExp; /// ÇöÀç ·¹º§ °æÇèÄ¡ ÃÖ´ë °ªÀ» °¡Á®¿È unsigned long maxExp = pExpTable->mExp; /// ·¹º§¾÷ ¼öÄ¡ unsigned char levelUp = 0; /// °æÇèÄ¡ ÃÑÇÕÀÌ ´ÙÀ½ ·¹º§·Î ³Ñ¾î°¡±â À§ÇÑ °æÇèÄ¡ º¸´Ù Å©¸é ·¹º§¾÷ while( totalExp >= maxExp ) { /// ÇöÀç °æÇèÄ¡¿¡¼­ ·¹º§¾÷ÇÒ ¸¸Å­ÀÇ °æÇèÄ¡¸¦ °¨¼Ò totalExp -= maxExp; ++levelUp; /// ·¹º§¾÷ÇÑ ÈÄ´ÙÀ½ ·¹º§·Î ³Ñ¾î °¡±â À§ÇÑ °æÇèÄ¡ ÃÖ´ë °ª pExpTable = LEVELSCRIPT->GetExpTable( level + levelUp ); if( pExpTable == NULL ) { /// 2´Ü°è ·¹º§¾÷À» Çϴµ¥ ±×»çÀÌ¿¡ ¸¸·¾ÀÌ ²¸Àմ°æ¿ì´Â ¾ø°ÚÁö? NETWORK2->PostServerEvent("cPlayer::AddExp pExpTable == NULL [%d,%d,%d]", mObject.index, level, levelUp ); return; } maxExp = pExpTable->mExp; } ////////////////////////////////////////////////////////////////////////// /// Àû¿ëºÎ if( levelUp > 0 ) { unsigned long recoverValue = 0; if( expRecover == true ) recoverValue = calcAddExp; /// ·¹º§Á¤º¸ ÀúÀå & °æÇèÄ¡ Àû¿ë if( LevelUp( levelUp, totalExp, false ) == false ) return; } else mHeroInfo.Exp = totalExp; /// °æÇèÄ¡ Àû¿ë } if( expRecover == false ) { ////////////////////////////////////////////////////////////////////////// /// °æÇèÄ¡ ¸Þ¼¼Áö ¹ß¼Û HANDLE handle = NULL; MSG_RES_EXP* msgExp = (MSG_RES_EXP*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_EXP_RES ); if ( msgExp != NULL ) { msgExp->mExp = calcAddExp; msgExp->mTotalExp = mHeroInfo.Exp; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_EXP) ); } } else { ////////////////////////////////////////////////////////////////////////// /// °æÇèÄ¡ ¸Þ¼¼Áö ¹ß¼Û HANDLE handle = NULL; MSG_RES_RECOVER_EXP* msgExp = (MSG_RES_RECOVER_EXP*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_EXP_RECOVER_RES ); if ( msgExp != NULL ) { msgExp->mExp = calcAddExp; msgExp->mTotalExp = mHeroInfo.Exp; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_RECOVER_EXP) ); } } } void cPlayer::AddPartyExp( unsigned long addExp, bool addOption, bool expRecover, unsigned long addBaseExp, unsigned long addPartyExp ) { if( addExp == 0 ) return; unsigned char level = mPlayerInfo.Level; unsigned long totalExp = mHeroInfo.Exp; unsigned long calcAddExp = 0; /// Ãß°¡ °æÇèÄ¡ °è»ê unsigned long addPlusBaseExp = addBaseExp; unsigned long addPlusPartyExp = addPartyExp; ////////////////////////////////////////////////////////////////////////// /// Ãß°¡ °æÇèÄ¡ °è»ê if( addOption == true ) { /// Ãß°¡¿É¼Ç °æÇèÄ¡ Áõ°¡Ä¡ float addExpPer = (float)mStatusEtc.mExpAddPer; float addExpPlus = (float)mStatusEtc.mExpAddPlus; addPlusBaseExp = FloatToInt( addBaseExp + ( addBaseExp * addExpPer / 100.0f ) + addExpPlus ); /// °æÇèÄ¡ = °æÇèÄ¡ + %È¿°ú + È¿°ú addPlusPartyExp = FloatToInt( addPartyExp + ( addPartyExp * addExpPer / 100.0f ) ); /// °æÇèÄ¡ = °æÇèÄ¡ + %È¿°ú calcAddExp = addPlusBaseExp + addPlusPartyExp; } else calcAddExp = addExp; ////////////////////////////////////////////////////////////////////////// /// ·¹º§¾÷ ¼öÄ¡¿Í ³²Àº °æÇèÄ¡ °è»ê /// ´ÙÀ½ ·¹º§·Î ³Ñ¾î°¡±â À§ÇÑ ÇÊ¿ä °æÇèÄ¡¸¦ ¾ò¾î¿È sExpTable* pExpTable = LEVELSCRIPT->GetExpTable( level ); if( pExpTable == NULL ) return; /// ÀúÀå ¾ÈµÈ °æÇèÄ¡ ±â·Ï mWaitSaveExp += addExp; /// °æÇèÄ¡°¡ ÀÏÁ¤·® ÀÌ»ó ½×ÀλóÅ·ΠÀúÀåÀÌ ¾ÈµÆÀ¸¸é ÀúÀåÇÏ°Ô ÇÑ´Ù if( mPlayerInfo.Level > 15 ) { if( mPlayerInfo.Level < 20 ) { if( mWaitSaveExp > (unsigned long)( pExpTable->mExp * 0.20f ) ) mBatchSaveTime = 0; } else if( mPlayerInfo.Level < 25 ) { if( mWaitSaveExp > (unsigned long)( pExpTable->mExp * 0.15f ) ) mBatchSaveTime = 0; } else if( mPlayerInfo.Level < 30 ) { if( mWaitSaveExp > (unsigned long)( pExpTable->mExp * 0.10f ) ) mBatchSaveTime = 0; } else if( mPlayerInfo.Level < 35 ) { if( mWaitSaveExp > (unsigned long)( pExpTable->mExp * 0.05f ) ) mBatchSaveTime = 0; } else { if( mWaitSaveExp > (unsigned long)( pExpTable->mExp * 0.02f ) ) mBatchSaveTime = 0; } } sExpTable* pMax = LEVELSCRIPT->GetExpTable( level + 1 ); if( pMax == NULL ) /// ´ÙÀ½ ·¹º§Á¤º¸°¡ ¾øÀ¸¸é ·¹º§¾÷ ¾ÈÇÏ°í °æÇèÄ¡¸¸ Áõ°¡ { /// ÇöÀç °æÇèÄ¡ Ãִ뺸´Ù ¸¹Àº°æ¿ì ÃÖ´ë -1 ¼³Á¤ if( pExpTable->mExp <= totalExp + calcAddExp ) mHeroInfo.Exp = pExpTable->mExp - 1; else mHeroInfo.Exp += calcAddExp; /// ½ÀµæÇÑ °æÇèÄ¡¸¦ ÇöÀç°æÇèÄ¡¿¡ ´õÇÔ } else /// Á¤»óÀûÀÎ ¹üÀ§³»¿¡¼­ÀÇ ·¹º§¾÷ ó¸® { /// ½ÀµæÇÑ °æÇèÄ¡¸¦ ÇöÀç°æÇèÄ¡¿¡ ´õÇÔ totalExp += calcAddExp; /// ÇöÀç ·¹º§ °æÇèÄ¡ ÃÖ´ë °ªÀ» °¡Á®¿È unsigned long maxExp = pExpTable->mExp; /// ·¹º§¾÷ ¼öÄ¡ unsigned char levelUp = 0; /// °æÇèÄ¡ ÃÑÇÕÀÌ ´ÙÀ½ ·¹º§·Î ³Ñ¾î°¡±â À§ÇÑ °æÇèÄ¡ º¸´Ù Å©¸é ·¹º§¾÷ while( totalExp >= maxExp ) { /// ÇöÀç °æÇèÄ¡¿¡¼­ ·¹º§¾÷ÇÒ ¸¸Å­ÀÇ °æÇèÄ¡¸¦ °¨¼Ò totalExp -= maxExp; ++levelUp; /// ·¹º§¾÷ÇÑ ÈÄ´ÙÀ½ ·¹º§·Î ³Ñ¾î °¡±â À§ÇÑ °æÇèÄ¡ ÃÖ´ë °ª pExpTable = LEVELSCRIPT->GetExpTable( level + levelUp ); if( pExpTable == NULL ) { /// 2´Ü°è ·¹º§¾÷À» Çϴµ¥ ±×»çÀÌ¿¡ ¸¸·¾ÀÌ ²¸Àմ°æ¿ì´Â ¾ø°ÚÁö? NETWORK2->PostServerEvent("cPlayer::AddExp pExpTable == NULL [%d,%d,%d]", mObject.index, level, levelUp ); return; } maxExp = pExpTable->mExp; } ////////////////////////////////////////////////////////////////////////// /// Àû¿ëºÎ if( levelUp > 0 ) { unsigned long recoverValue = 0; if( expRecover == true ) recoverValue = calcAddExp; /// ·¹º§Á¤º¸ ÀúÀå & °æÇèÄ¡ Àû¿ë if( LevelUp( levelUp, totalExp, false ) == false ) return; } else mHeroInfo.Exp = totalExp; /// °æÇèÄ¡ Àû¿ë } if( expRecover == false ) { ////////////////////////////////////////////////////////////////////////// /// °æÇèÄ¡ ¸Þ¼¼Áö ¹ß¼Û if( addPlusPartyExp < 1 ) { HANDLE handle = NULL; MSG_RES_EXP* msgExp = (MSG_RES_EXP*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_EXP_RES ); if ( msgExp != NULL ) { msgExp->mExp = calcAddExp; msgExp->mTotalExp = mHeroInfo.Exp; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_EXP) ); } } else { HANDLE handle = NULL; MSG_RES_PARTY_EXP* msgExp = (MSG_RES_PARTY_EXP*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_PARTY_EXP_RES ); if ( msgExp != NULL ) { msgExp->mExp = calcAddExp; msgExp->mPartyExp = addPlusPartyExp; msgExp->mTotalExp = mHeroInfo.Exp; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_PARTY_EXP) ); } } } else { ////////////////////////////////////////////////////////////////////////// /// °æÇèÄ¡ ¸Þ¼¼Áö ¹ß¼Û HANDLE handle = NULL; MSG_RES_RECOVER_EXP* msgExp = (MSG_RES_RECOVER_EXP*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_EXP_RECOVER_RES ); if ( msgExp != NULL ) { msgExp->mExp = calcAddExp; msgExp->mTotalExp = mHeroInfo.Exp; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_RECOVER_EXP) ); } } } bool cPlayer::LevelUp( unsigned char addLevel, unsigned long totalExp, bool isCheat ) { unsigned short sumLevel = mPlayerInfo.Level + addLevel; if( LEVELSCRIPT->GetMaxLevel() < sumLevel ) return false; /// ·¹º§¾÷Àü ½ºÅÝ1 ÀúÀå sStatus1 oldStatus1; oldStatus1 = mStatus1; mPlayerInfo.Level = (unsigned char)sumLevel; mHeroInfo.Exp = totalExp; /// Àåºñ ¾ÆÀÌÅÛ Á¤º¸ °»½Å. EquipItems( ); STATUSCALC->CalcPlayerInit( mObject ); /// ġƮ·Î ÀÎÇÑ ·¹º§¾÷ÀÎÁö È®ÀÎ int updateFlag = PLAYER_DBUPDATE_LEVELUP; if( isCheat == true ) updateFlag = PLAYER_DBUPDATE_LEVELCHEAT; /// ¹«Á¶°Ç ÀúÀå if( DBUpdate( false, updateFlag ) == false ) mBatchSaveTime = 0; HPHeal( GetMaxHP( ), false, mObject, 0, eTAKEDAMAGETYPE_NONE ); MPHeal( GetMaxMP( ), false ); if( GetGuildIndex() > 0 ) GUILDMAN->RequestUpdateUser( GetGuildIndex(), GetObjectID() ); /// hero ¿¡°Ô ·¹º§¾÷ ¸Þ¼¼Áö ¹ß¼Û HANDLE handle = NULL; MSG_RES_LEVEL* msgExp = (MSG_RES_LEVEL*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_LEVEL_RES ); if ( msgExp != NULL ) { msgExp->mLevel = mPlayerInfo.Level; msgExp->mExp = totalExp; msgExp->mStr = (unsigned char)(FloatToInt( mStatus1.mStr ) - FloatToInt( oldStatus1.mStr )); msgExp->mDex = (unsigned char)(FloatToInt( mStatus1.mDex ) - FloatToInt( oldStatus1.mDex )); msgExp->mCon = (unsigned char)(FloatToInt( mStatus1.mCon ) - FloatToInt( oldStatus1.mCon )); msgExp->mInt = (unsigned char)(FloatToInt( mStatus1.mInt ) - FloatToInt( oldStatus1.mInt )); msgExp->mWis = (unsigned char)(FloatToInt( mStatus1.mWis ) - FloatToInt( oldStatus1.mWis )); msgExp->mHP = mPlayerExrInfo.RestHP; msgExp->mMaxHP = mPlayerExrInfo.MaxHP; msgExp->mMP = mPlayerExrInfo.RestMP; msgExp->mMaxMP = mPlayerExrInfo.MaxMP; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_LEVEL) ); } /// ÁÖº¯ Ç÷¹À̾°Ô ·¹º§¾÷ ÀÌÆåÆ®¸¦ ºÙÀ̱âÀ§ÇÑ ¸Þ¼¼Áö ¹ß¼Û MSG_SYN_LEVEL synMsg; synMsg.Category = NM_PLAYER; synMsg.Protocol = NM_PLAYER_LEVEL_SYN; synMsg.mCharacterIdx = mObject.index; synMsg.mLevel = mPlayerInfo.Level; synMsg.mHP = mPlayerExrInfo.RestHP; synMsg.mMaxHP = mPlayerExrInfo.MaxHP; synMsg.mMP = mPlayerExrInfo.RestMP; synMsg.mMaxMP = mPlayerExrInfo.MaxMP; NETWORK2->QuickSendExcept( this, (char*)&synMsg, sizeof(synMsg) ); /// ·¹º§¾÷ Äù½ºÆ® Æ®¸®°Å °Ë»ç SendNewQuestList(); return true; } void cPlayer::AddSxp( unsigned long addSxp, bool addOption ) { if( addSxp == 0 ) return; /// ½ºÅ³ ÃʱâÈ­ Áß¿£ sxp ¸¦ ¹ÞÁö ¾Ê´Â´Ù. if( mInventoryDb.skillReset == true ) return; if( GetStateStop() == eSTOP_SKILLRESET ) return; unsigned char skillLevel = mHeroInfo.SkillLevel; unsigned long totalSxp = mHeroInfo.SkillExp; unsigned long calcAddSxp = 0; ////////////////////////////////////////////////////////////////////////// /// Ãß°¡ °æÇèÄ¡ °è»ê if( addOption == true ) { /// Ãß°¡¿É¼Ç °æÇèÄ¡ Áõ°¡Ä¡ float addSxpPer = (float)mStatusEtc.mSxpAddPer; float addSxpPlus = (float)mStatusEtc.mSxpAddPlus; calcAddSxp = FloatToInt( addSxp + ( addSxp * addSxpPer / 100.0f ) + addSxpPlus ); /// ½ºÅ³°æÇèÄ¡2 = ½ºÅ³°æÇèÄ¡1 + %È¿°ú + È¿°ú } else calcAddSxp = addSxp; ////////////////////////////////////////////////////////////////////////// /// ·¹º§¾÷ ¼öÄ¡¿Í ³²Àº °æÇèÄ¡ °è»ê /// ÇöÀç·¹º§ °æÇèÄ¡ Ãִ븦 °¡Á®¿È sSxpTable* pSxpTable = LEVELSCRIPT->GetSxpTable( skillLevel ); if( pSxpTable == NULL ) return; /// ´ÙÀ½ ·¹º§Á¤º¸°¡ ¾øÀ¸¸é ·¹º§¾÷ ¾ÈÇÏ°í °æÇèÄ¡¸¸ Áõ°¡ sSxpTable* pMax = LEVELSCRIPT->GetSxpTable( skillLevel + 1 ); if( pMax == NULL ) { /// ÇöÀç °æÇèÄ¡ Ãִ뺸´Ù ¸¹Àº°æ¿ì ÃÖ´ë -1 ¼³Á¤ÈÄ ¸®ÅÏ if( pSxpTable->mSxp <= totalSxp + calcAddSxp ) mHeroInfo.SkillExp = pSxpTable->mSxp - 1; else mHeroInfo.SkillExp += calcAddSxp; /// ½ÀµæÇÑ °æÇèÄ¡¸¦ ÇöÀç°æÇèÄ¡¿¡ ´õÇÔ } else { /// ½ÀµæÇÑ °æÇèÄ¡¸¦ ÇöÀç°æÇèÄ¡¿¡ ´õÇÔ totalSxp += calcAddSxp; /// ÇöÀç ·¹º§ °æÇèÄ¡ ÃÖ´ë °ªÀ» °¡Á®¿È unsigned long maxSxp = pSxpTable->mSxp; /// ·¹º§¾÷ ¼öÄ¡ unsigned char levelUp = 0; /// °æÇèÄ¡ ÃÑÇÕÀÌ ´ÙÀ½ ·¹º§·Î ³Ñ¾î°¡±â À§ÇÑ °æÇèÄ¡ º¸´Ù Å©¸é ·¹º§¾÷ while( totalSxp >= maxSxp ) { /// ÇöÀç °æÇèÄ¡¿¡¼­ ·¹º§¾÷ÇÒ ¸¸Å­ÀÇ °æÇèÄ¡¸¦ °¨¼Ò totalSxp -= maxSxp; ++levelUp; /// ´ÙÀ½ ·¹º§·Î ³Ñ¾î °¡±â À§ÇÑ °æÇèÄ¡ ÃÖ´ë °ª pSxpTable = LEVELSCRIPT->GetSxpTable( skillLevel + levelUp ); if( pSxpTable == NULL ) { NETWORK2->PostServerEvent("cPlayer::AddSxp pSxpTable == NULL [%d,%d,%d]", mObject.index, skillLevel, levelUp ); return; } maxSxp = pSxpTable->mSxp; } ////////////////////////////////////////////////////////////////////////// /// Àû¿ëºÎ if( levelUp > 0 ) { if( SkillLevelUp( levelUp, totalSxp, false ) == false ) return; } else mHeroInfo.SkillExp = totalSxp; } ////////////////////////////////////////////////////////////////////////// /// °æÇèÄ¡ ¸Þ¼¼Áö ¹ß¼Û HANDLE handle = NULL; MSG_RES_SXP* msgExp = (MSG_RES_SXP*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_SXP_RES ); if ( msgExp != NULL ) { msgExp->mSxp = calcAddSxp; msgExp->mTotalSxp = mHeroInfo.SkillExp; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SXP) ); } } void cPlayer::AddPartySxp( unsigned long addSxp, bool addOption, unsigned long addBaseSxp, unsigned long addPartySxp ) { if( addSxp == 0 ) return; /// ½ºÅ³ ÃʱâÈ­ Áß¿£ sxp ¸¦ ¹ÞÁö ¾Ê´Â´Ù. if( mInventoryDb.skillReset == true ) return; if( GetStateStop() == eSTOP_SKILLRESET ) return; unsigned char skillLevel = mHeroInfo.SkillLevel; unsigned long totalSxp = mHeroInfo.SkillExp; unsigned long calcAddSxp = 0; /// Ãß°¡ °æÇèÄ¡ °è»ê unsigned long addPlusBaseSxp = addBaseSxp; unsigned long addPlusPartySxp = addPartySxp; ////////////////////////////////////////////////////////////////////////// /// Ãß°¡ °æÇèÄ¡ °è»ê if( addOption == true ) { /// Ãß°¡¿É¼Ç °æÇèÄ¡ Áõ°¡Ä¡ float addSxpPer = (float)mStatusEtc.mSxpAddPer; float addSxpPlus = (float)mStatusEtc.mSxpAddPlus; addPlusBaseSxp = FloatToInt( addBaseSxp + ( addBaseSxp * addSxpPer / 100.0f ) + addSxpPlus ); /// °æÇèÄ¡ = °æÇèÄ¡ + %È¿°ú + È¿°ú addPlusPartySxp = FloatToInt( addPartySxp + ( addPartySxp * addSxpPer / 100.0f ) ); /// °æÇèÄ¡ = °æÇèÄ¡ + %È¿°ú calcAddSxp = addPlusBaseSxp + addPlusPartySxp; } else calcAddSxp = addSxp; ////////////////////////////////////////////////////////////////////////// /// ·¹º§¾÷ ¼öÄ¡¿Í ³²Àº °æÇèÄ¡ °è»ê /// ÇöÀç·¹º§ °æÇèÄ¡ Ãִ븦 °¡Á®¿È sSxpTable* pSxpTable = LEVELSCRIPT->GetSxpTable( skillLevel ); if( pSxpTable == NULL ) return; /// ´ÙÀ½ ·¹º§Á¤º¸°¡ ¾øÀ¸¸é ·¹º§¾÷ ¾ÈÇÏ°í °æÇèÄ¡¸¸ Áõ°¡ sSxpTable* pMax = LEVELSCRIPT->GetSxpTable( skillLevel + 1 ); if( pMax == NULL ) { /// ÇöÀç °æÇèÄ¡ Ãִ뺸´Ù ¸¹Àº°æ¿ì ÃÖ´ë -1 ¼³Á¤ÈÄ ¸®ÅÏ if( pSxpTable->mSxp <= totalSxp + calcAddSxp ) mHeroInfo.SkillExp = pSxpTable->mSxp - 1; else mHeroInfo.SkillExp += calcAddSxp; /// ½ÀµæÇÑ °æÇèÄ¡¸¦ ÇöÀç°æÇèÄ¡¿¡ ´õÇÔ } else { /// ½ÀµæÇÑ °æÇèÄ¡¸¦ ÇöÀç°æÇèÄ¡¿¡ ´õÇÔ totalSxp += calcAddSxp; /// ÇöÀç ·¹º§ °æÇèÄ¡ ÃÖ´ë °ªÀ» °¡Á®¿È unsigned long maxSxp = pSxpTable->mSxp; /// ·¹º§¾÷ ¼öÄ¡ unsigned char levelUp = 0; /// °æÇèÄ¡ ÃÑÇÕÀÌ ´ÙÀ½ ·¹º§·Î ³Ñ¾î°¡±â À§ÇÑ °æÇèÄ¡ º¸´Ù Å©¸é ·¹º§¾÷ while( totalSxp >= maxSxp ) { /// ÇöÀç °æÇèÄ¡¿¡¼­ ·¹º§¾÷ÇÒ ¸¸Å­ÀÇ °æÇèÄ¡¸¦ °¨¼Ò totalSxp -= maxSxp; ++levelUp; /// ´ÙÀ½ ·¹º§·Î ³Ñ¾î °¡±â À§ÇÑ °æÇèÄ¡ ÃÖ´ë °ª pSxpTable = LEVELSCRIPT->GetSxpTable( skillLevel + levelUp ); if( pSxpTable == NULL ) { NETWORK2->PostServerEvent("cPlayer::AddSxp pSxpTable == NULL [%d,%d,%d]", mObject.index, skillLevel, levelUp ); return; } maxSxp = pSxpTable->mSxp; } ////////////////////////////////////////////////////////////////////////// /// Àû¿ëºÎ if( levelUp > 0 ) { if( SkillLevelUp( levelUp, totalSxp, false ) == false ) return; } else mHeroInfo.SkillExp = totalSxp; } ////////////////////////////////////////////////////////////////////////// /// °æÇèÄ¡ ¸Þ¼¼Áö ¹ß¼Û if( addPlusPartySxp < 1 ) { HANDLE handle = NULL; MSG_RES_SXP* msgExp = (MSG_RES_SXP*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_SXP_RES ); if ( msgExp != NULL ) { msgExp->mSxp = calcAddSxp; msgExp->mTotalSxp = mHeroInfo.SkillExp; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SXP) ); } } else { HANDLE handle = NULL; MSG_RES_PARTY_SXP* msgSxp = (MSG_RES_PARTY_SXP*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_PARTY_SXP_RES ); if ( msgSxp != NULL ) { msgSxp->mSxp = calcAddSxp; msgSxp->mPartySxp = addPlusPartySxp; msgSxp->mTotalSxp = mHeroInfo.SkillExp; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_PARTY_SXP) ); } } } bool cPlayer::SkillLevelUp( unsigned char addLevel, unsigned long totalSxp, bool isCheat ) { unsigned short sumLevel = mHeroInfo.SkillLevel + addLevel; if( LEVELSCRIPT->GetMaxSkill() < sumLevel ) return false; mHeroInfo.SkillLevel = mHeroInfo.SkillLevel + addLevel; mHeroInfo.SkillPointRemain += SKILL_LEVELUP_POINT * addLevel; mHeroInfo.SkillPointTotal += SKILL_LEVELUP_POINT * addLevel; mHeroInfo.SkillExp = totalSxp; /// ġƮ·Î ÀÎÇÑ ·¹º§¾÷ÀÎÁö È®ÀÎ int updateFlag = PLAYER_DBUPDATE_SKILLUP; if( isCheat == true ) updateFlag = PLAYER_DBUPDATE_SKILLCHEAT; /// ¹«Á¶°Ç ÀúÀå if( DBUpdate( false, updateFlag ) == false ) mBatchSaveTime = 0; /// ·¹º§¾÷ ¸Þ¼¼Áö ¹ß¼Û HANDLE handle = NULL; MSG_RES_SKILLLEVEL* resMsg = (MSG_RES_SKILLLEVEL*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_SKILLLEVEL_RES ); if ( resMsg != NULL ) { resMsg->mSkillLevel = mHeroInfo.SkillLevel; resMsg->mSkillExp = totalSxp; resMsg->mSkillPoint = mHeroInfo.SkillPointRemain; resMsg->mSkillPointTotal = mHeroInfo.SkillPointTotal; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILLLEVEL) ); } MSG_SYN_SKILLLEVEL syncMsg; syncMsg.Category = NM_PLAYER; syncMsg.Protocol = NM_PLAYER_SKILLLEVEL_SYN; syncMsg.mPlayerIdx = mObject.index; NETWORK2->QuickSend( this, (char*)&syncMsg, sizeof(MSG_SYN_SKILLLEVEL) ); return true; } void cPlayer::InitHP( unsigned long HP ) { mPlayerExrInfo.RestHP = HP; mPlayerExrInfo.MaxHP = GetMaxHP(); if( mPlayerExrInfo.RestHP > GetMaxHP() ) mPlayerExrInfo.MaxHP = mPlayerExrInfo.RestHP; } void cPlayer::InitMP( unsigned long MP ) { mPlayerExrInfo.RestMP = MP; mPlayerExrInfo.MaxMP = GetMaxMP(); if( mPlayerExrInfo.RestMP > GetMaxMP() ) mPlayerExrInfo.MaxMP = mPlayerExrInfo.RestMP; } unsigned long cPlayer::HPDamage( sObject /*attacker*/, unsigned long damage, bool* die, bool msgSend, bool /*cri*/ ) { /// ½ÇÁ¦ Àû¿ëµÈ µ¥¹ÌÁö unsigned long realDamage = 0; *die = false; if( GetStateDie() == true ) { *die = true; return realDamage; } if( mGameIn == false ) return 0; /// °ø°Ý¹ÞÀ¸¸é Á×´Â °æ¿ì if( mPlayerExrInfo.RestHP <= damage ) { /// ġƮ ¹«Àû ¿©ºÎ¸¦ °Ë»ç if( mCheatUndeadMode ) return 0; /// [½ÇÁ¦Àû¿ëµÈµ¥¹ÌÁö]´Â playerÀÇ [½ÇÁ¦HP°ª] realDamage = mPlayerExrInfo.RestHP; /// [½ÇÁ¦HP°ª]Àº 0 mPlayerExrInfo.RestHP = 0; mPlayerExrInfo.RestMP = 0; /// Ç÷¹À̾îÀÇ »óÅ º¯°æ if( ChangeState( eOBJECT_STATE_DIE ) == false ) { assert(NULL); NETWORK2->PostServerEvent("Player[%d] Update ChangeState( eOBJECT_STATE_DIE ) == false", mObject.index ); } *die = true; /// Á×Àº °æ¿ì µ¥¹ÌÁö¸¦ ÀÔ¾úÀ» ¶§ »ç¶óÁö´Â ¹öÇÁµéÀº ¸ðµÎ Á¤¸®µÈ´Ù. // Á×Àº À§Ä¡ ±â·Ï char buffer[260]; int serverType = NETWORK2->GetServerType(); sprintf( buffer, "Die Srv:%d Map:%d MapData:%d, X:%.2f Y:%.2f ", serverType, mMapNumber, mInDunMapDataNum, mObjectPos.x, mObjectPos.y ); PostCharacterEvent( EVENT_CHARACTER_UPDATE, buffer ); } else /// Á×Áö ¾Ê´Â °æ¿ì { /// ÀüÀå ±ê¹ß äÁý ÁßÀΰæ¿ì µ¥¹ÌÁö ¹ÞÀ¸¸é Ãë¼Ò if( GetState() == ePLAYER_STATE_GATHERING && NETWORK2->GetServerType() == _E_ST_ID_PVP_ ) { cGathering* pGather = OBJECTMANAGER->GetGathering( mGatheringIdx ); if( pGather != NULL ) pGather->CancelGatherByOddity( this ); } /// ¹ßµ¿ üũ SKILLMANAGER->CheckActInfluence( eACTSTATUS_DAMAGE, this, 0 ); /// Àáµé¾î ÀÖ´Â »óŶó¸é Ç®¾î ÁØ´Ù. if( mODDITY[eODDITYTYPE_SLEEP] != 0 ) { cSkillInfluenceSet::cIterator begin = mInfluenceSet.Begin(); cSkillInfluenceSet::cIterator end = mInfluenceSet.End(); cInfluenceObject* pInf = NULL; unsigned long influenceIdx = 0; while( begin != end ) { influenceIdx = (*begin++); pInf = SKILLMANAGER->GetInfluence( influenceIdx ); if( pInf == NULL ) continue; if( pInf->IsSleep() == true ) SKILLMANAGER->DeleteInfluenceList( influenceIdx ); } } /// µ¥¹ÌÁö¸¦ ¹ÞÀ¸¸é Ç®¸®´Â È¿°úµé »èÁ¦Çϱâ if( mDeleteTypeDamagedAry.GetSize() > 0 ) { cLongAry::cIterator begin = mDeleteTypeDamagedAry.Begin(); cLongAry::cIterator end = mDeleteTypeDamagedAry.End(); cInfluenceObject* pInf = NULL; unsigned long influenceIdx = 0; while( begin != end ) { influenceIdx = (*begin++); pInf = SKILLMANAGER->GetInfluence( influenceIdx ); if( pInf == NULL ) continue; if( pInf->GetDeleteType() == eDELETETYPE_PLAYER_DAMAGED ) SKILLMANAGER->DeleteInfluenceList( influenceIdx ); } } /// ġƮ ¹«Àû ¿©ºÎ¸¦ °Ë»ç if( mCheatUndeadMode ) return 0; /// [½ÇÁ¦Àû¿ëµÈµ¥¹ÌÁö]´Â [ÆÄ¶ó¸ÞŸµ¥¹ÌÁö] realDamage = damage; /// [½ÇÁ¦HP°ª]Àº [ÆÄ¶ó¸ÞŸµ¥¹ÌÁö]»«°ª mPlayerExrInfo.RestHP -= damage; } if( msgSend == true ) { MSG_SYN_PLAYER_HP synMsg; synMsg.Category = NM_PLAYER; synMsg.Protocol = NM_PLAYER_HP_SYN; synMsg.mCharacterIdx = GetObjectID(); synMsg.mHp = mPlayerExrInfo.RestHP; synMsg.mMaxHp = GetMaxHP(); synMsg.mDie = GetStateDie(); NETWORK2->QuickSend( this, (char*)&synMsg, sizeof(MSG_SYN_PLAYER_HP) ); } /// [½ÇÁ¦Àû¿ëµÈµ¥¹ÌÁö]¸®ÅÏ return realDamage; } void cPlayer::HPUse( unsigned long useValue, bool msgSend ) { if( mPlayerExrInfo.RestHP < useValue ) { assert(NULL); NETWORK2->PostServerEvent("cPlayer::HPUse [%d,%d,%d]", mObject.index, useValue, mPlayerExrInfo.RestHP ); mPlayerExrInfo.RestHP = 1; } else mPlayerExrInfo.RestHP -= useValue; if( msgSend == true ) { MSG_SYN_PLAYER_HP synMsg; synMsg.Category = NM_PLAYER; synMsg.Protocol = NM_PLAYER_HP_SYN; synMsg.mCharacterIdx = GetObjectID(); synMsg.mHp = mPlayerExrInfo.RestHP; synMsg.mMaxHp = GetMaxHP(); synMsg.mDie = GetStateDie(); NETWORK2->QuickSend( this, (char*)&synMsg, sizeof(MSG_SYN_PLAYER_HP) ); } } void cPlayer::HPHeal( unsigned long hp, bool msgSend, sObject healer, long distressPoint, eTAKEDAMAGE_TYPE type ) { unsigned long maxHP = GetMaxHP(); unsigned long restHP = mPlayerExrInfo.RestHP; if( GetStateDie() == true ) return; if ( maxHP == restHP ) return; /// ½ÇÁ¦ Àû¿ëµÇ´Â Èú·® °è»ê unsigned long applyHP = hp; if( mPlayerExrInfo.RestHP + hp > maxHP ) applyHP = maxHP - mPlayerExrInfo.RestHP; /// ½ÇÁ¦ Àû¿ëµÈ ¼öÄ¡¸¸ Å­¸¸ ¾î±×·Î ºñÁß °öÇØ¼­ ³ÖÁØ´Ù. if( healer.index != 0 && healer.type == eOBJECTTYPE_PLAYER && type != eTAKEDAMAGETYPE_NONE ) { HealAttackToMonster( healer.index, applyHP, distressPoint, type ); } unsigned long currentHp = restHP + hp; mPlayerExrInfo.RestHP = (currentHp > maxHP) ? maxHP : currentHp; if ( msgSend == true ) SendHPHeal( ); } bool cPlayer::SendHPHeal( ) { MSG_SYN_PLAYER_HP synMsg; synMsg.Category = NM_PLAYER; synMsg.Protocol = NM_PLAYER_HP_SYN; synMsg.mCharacterIdx = GetObjectID(); synMsg.mHp = mPlayerExrInfo.RestHP; synMsg.mMaxHp = GetMaxHP(); synMsg.mDie = GetStateDie(); return NETWORK2->QuickSend( this, (char*)&synMsg, sizeof(MSG_SYN_PLAYER_HP) ); } void cPlayer::SendMaxHP( ) { MSG_SYN_PLAYER_MAXHP synMsg; synMsg.Category = NM_PLAYER; synMsg.Protocol = NM_PLAYER_MAXHP_SYN; synMsg.mCharacterIdx = GetObjectID(); synMsg.mMaxHp = GetMaxHP(); NETWORK2->QuickSend( this, (char*)&synMsg, sizeof(MSG_SYN_PLAYER_MAXHP) ); } void cPlayer::MPDamage( unsigned long mp, bool msgSend ) { /// ¹ßµ¿ üũ SKILLMANAGER->CheckActInfluence( eACTSTATUS_DAMAGE, this, 0 ); if( mPlayerExrInfo.RestMP < mp ) { mPlayerExrInfo.RestMP = 0; } else { mPlayerExrInfo.RestMP -= mp; } /// µ¥¹ÌÁö¸¦ ¹ÞÀ¸¸é Ç®¸®´Â È¿°úµé »èÁ¦Çϱâ if( mDeleteTypeDamagedAry.GetSize() > 0 ) { cLongAry::cIterator begin = mDeleteTypeDamagedAry.Begin(); cLongAry::cIterator end = mDeleteTypeDamagedAry.End(); cInfluenceObject* pInf = NULL; unsigned long influenceIdx = 0; while( begin != end ) { influenceIdx = (*begin++); pInf = SKILLMANAGER->GetInfluence( influenceIdx ); if( pInf == NULL ) continue; if( pInf->GetDeleteType() == eDELETETYPE_PLAYER_DAMAGED ) SKILLMANAGER->DeleteInfluenceList( influenceIdx ); } } if( msgSend == true ) { MSG_SYN_PLAYER_MP synMsg; synMsg.Category = NM_PLAYER; synMsg.Protocol = NM_PLAYER_MP_SYN; synMsg.mCharacterIdx = GetObjectID(); synMsg.mMp = mPlayerExrInfo.RestMP; synMsg.mMaxMp = GetMaxMP(); NETWORK2->QuickSend( this, (char*)&synMsg, sizeof(synMsg) ); } } void cPlayer::MPUse( unsigned long useValue, bool msgSend ) { if( mPlayerExrInfo.RestMP < useValue ) mPlayerExrInfo.RestMP = 0; else mPlayerExrInfo.RestMP -= useValue; if( msgSend == true ) { MSG_SYN_PLAYER_MP synMsg; synMsg.Category = NM_PLAYER; synMsg.Protocol = NM_PLAYER_MP_SYN; synMsg.mCharacterIdx = GetObjectID(); synMsg.mMp = mPlayerExrInfo.RestMP; synMsg.mMaxMp = GetMaxMP(); NETWORK2->QuickSend( this, (char*)&synMsg, sizeof(synMsg) ); } } void cPlayer::MPHeal( unsigned long mp, bool msgSend ) { unsigned long maxMP = GetMaxMP(); unsigned long restMP = mPlayerExrInfo.RestMP; if( maxMP == restMP ) return; unsigned long currentMp = restMP + mp; mPlayerExrInfo.RestMP = (currentMp > maxMP) ? maxMP : currentMp; if ( msgSend != NULL ) SendMPHeal( ); } bool cPlayer::SendMPHeal( ) { MSG_SYN_PLAYER_MP synMsg; synMsg.Category = NM_PLAYER; synMsg.Protocol = NM_PLAYER_MP_SYN; synMsg.mCharacterIdx = GetObjectID(); synMsg.mMp = mPlayerExrInfo.RestMP; synMsg.mMaxMp = GetMaxMP(); return NETWORK2->QuickSend( this, (char*)&synMsg, sizeof(MSG_SYN_PLAYER_MP) ); } void cPlayer::SendMaxMP( ) { MSG_SYN_PLAYER_MAXMP synMsg; synMsg.Category = NM_PLAYER; synMsg.Protocol = NM_PLAYER_MAXMP_SYN; synMsg.mCharacterIdx = GetObjectID(); synMsg.mMaxMp = GetMaxMP(); NETWORK2->QuickSend( this, (char*)&synMsg, sizeof(MSG_SYN_PLAYER_MAXMP) ); } void cPlayer::SetMoveReq( char protocol, NiPoint2 startPos, NiPoint2 destPos, unsigned long clientTime, float range, sObject targetInfo, NiPoint2 targetPos ) { NiPoint2 tempDest = destPos; mIsMoveMsg = true; memset( &mMoveMsg, 0, sizeof(mMoveMsg) ); mMoveMsg.mMsgError = true; mMoveMsg.mProtocol = protocol; try { if( GetState() == eOBJECT_STATE_PUSHPULL || GetState() == ePLAYER_STATE_RUSH ) throw false; if( IsChangeState( eOBJECT_STATE_MOVE ) == false ) throw false; char errorCode = IsMovePossible( startPos, destPos ); if( errorCode == 1 ) { /// À̵¿ ºÒ°¡´É Áö¿ªÀ̸é Ŭ¶óÀÌ¾ðÆ®°¡ ¼­ÀÖ´ø Àå¼Ò·Î À̵¿½ÃŲ´Ù. if( IsClientMovePossible( startPos, destPos ) == false ) { throw false; } tempDest = startPos; } else if( errorCode == 2 ) throw false; throw true; } catch ( bool isMove ) { if( isMove == true ) { SetMoveTargetPos( destPos.x, destPos.y ); ChangeState( eOBJECT_STATE_MOVE ); CalcClientMoveDeff( clientTime ); SetClientMoveReq( tempDest, startPos, false ); switch( protocol ) { case NM_PLAYER_KEYMOVE_REQ: case NM_PLAYER_MOVE_REQ: { //if( GetCheatHideMode() == false ) //{ // // ´Ù¸¥ Ç÷¹À̾îµé¿¡°Ôµµ ¾Ë¸² // MSG_SYN_MOVE Msg; // Msg.Category = NM_PLAYER; // Msg.Protocol = NM_PLAYER_MOVE_SYN; // Msg.characterIdx = mObject.index; // Msg.destX = tempDest.x; // Msg.destY = tempDest.y; // Msg.moveSpeed = GetMoveSpeed(); // NETWORK2->QuickSendExcept( this, (char*)&Msg, sizeof(Msg) ); //} mMoveMsg.mMsgError = false; mMoveMsg.mProtocol = protocol; mMoveMsg.mStartPos = startPos; mMoveMsg.mDestPos = destPos; mMoveMsg.mRange = range; mMoveMsg.mTargetInfo = targetInfo; mMoveMsg.mTargetPos = targetPos; } break; case NM_PLAYER_ACTIONMOVE_REQ: { SetRangeTarget( targetPos.x, targetPos.y, targetInfo, range ); //if( GetCheatHideMode() == false ) //{ // // ´Ù¸¥ Ç÷¹À̾îµé¿¡°Ôµµ ¾Ë¸² // MSG_SYN_ACTIONMOVE Msg; // Msg.Category = NM_PLAYER; // Msg.Protocol = NM_PLAYER_ACTIONMOVE_SYN; // Msg.characterIdx = mObject.index; // Msg.destX = tempDest.x; // Msg.destY = tempDest.y; // Msg.targetX = targetPos.x; // Msg.targetY = targetPos.y; // Msg.range = range; // Msg.targetInfo = targetInfo; // Msg.moveSpeed = GetMoveSpeed(); // NETWORK2->QuickSendExcept( this, (char*)&Msg, sizeof(Msg) ); //} mMoveMsg.mMsgError = false; mMoveMsg.mProtocol = protocol; mMoveMsg.mStartPos = startPos; mMoveMsg.mDestPos = destPos; mMoveMsg.mRange = range; mMoveMsg.mTargetInfo = targetInfo; mMoveMsg.mTargetPos = targetPos; } break; } } else { float posX = GetXPos(); float posY = GetYPos(); bool possible = AIMANAGER->IsPossible( GetMapNumber(), GetXPos(), GetYPos(), GetObject() ); if( possible == false ) { float tempX = posX; float tempY = posY; /// ·£´ý¹üÀ§ 50, 100, 150 3´Ü°è·Î 5¹ø¾¿ °¥¼öÀÖ´Â Áö¿ª Ã¼Å©ÇØ¼­ °¡´ÉÇϸé À̵¿½ÃŲ´Ù for( int i = 0 ; i < 15 ; ++i ) { /// ·£´ýÆø - 0~4=50, 5~9=100, 10~14=150 unsigned long tempRange = 150; if( i <= 4 ) tempRange = 50; else if( 5 <= i && i <= 9 ) tempRange = 100; else tempRange = 150; tempX = GetXPos() + rand() % ( tempRange * 2 ) - tempRange; tempY = GetYPos() + rand() % ( tempRange * 2 ) - tempRange; possible = AIMANAGER->IsPossible( GetMapNumber(), tempX, tempY, GetObject() ); if( possible == true ) { posX = tempX; posY = tempY; break; } } } SetPos( posX, posY ); ClearMoveSyncCalc(); SetMoveTargetPos( posX, posY ); destPos.x = posX; destPos.y = posY; mMoveMsg.mDestPos = destPos; //// 070625 PKH ½ÇÆÐ ¸Þ¼¼Áö ¹ß¼Û - ¼­¹ö»óÀÇ ÁÂÇ¥·Î Ŭ¶óÀÌ¾ðÆ®¸¦ ¿Å±â°Ô ÇÔ //HANDLE handle = NULL; //MSG_RES_ERR_MOVE* msg = (MSG_RES_ERR_MOVE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_MOVE_RES ); //msg->destX = posX; //msg->destY = posY; //NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_ERR_MOVE) ); } } } void cPlayer::SetMoveTargetPos( float x, float y ) { mRange = 0; mReadyGotoPos = NiPoint2::ZERO; mGotoX = x; mGotoY = y; float viewPosX, viewPosY; viewPosX = mObjectPos.x - x; viewPosY = mObjectPos.y - y; mDirection = atan2( viewPosX, viewPosY ); } char cPlayer::IsMovePossible( NiPoint2 startPos, NiPoint2 goalPos ) { /// À̵¿ºÒ°¡ »óÅ ÀÌ»óÀÎ °æ¿ì if( IsCantMove() == true ) return 2; /// À̵¿ ¸Þ¼¼Áö ½Ã°£Â÷ °í·Á mRangeCheck.SetRadius( SYNC_MOVE_RANGE ); if( mRangeCheck.IsNotRange( startPos, mObjectPos ) == true ) return 2; switch( NETWORK2->GetServerType() ) { case _E_ST_ID_PVP_: { if( mPvPDMIdx == 0 ) /// gmÀº mPvPDMIdx°ªÀÌ 0Àϼö ÀÖ´Ù return 0; cBaseDeathMatch* pDMObject = PVPMANAGER->GetPvPDMObject( mPvPDMIdx ); if( pDMObject == NULL ) return 0; if( pDMObject->IsMovePossible( mObjectPos, goalPos ) == false ) { if( pDMObject->IsMovePossible( startPos, goalPos ) == false ) return 2; else return 1; } } break; case _E_ST_ID_THEME_: case _E_ST_ID_TUTORIAL_: { if( mThemeRoomIdx == 0 ) /// gmÀº mPvPDMIdx°ªÀÌ 0Àϼö ÀÖ´Ù return 0; cThemeObject* ptheme = THEMEMANAGER->GetThemeObject( GetThemeRoomIdx() ); if( ptheme == NULL ) return 0; if( ptheme->IsMovePossible( mObjectPos, goalPos ) == false ) { if( ptheme->IsMovePossible( startPos, goalPos ) == false ) return 2; else return 1; } } break; } /// Á÷¼± ÄÚ½º À̵¿ °¡´É ÀÎÁö È®ÀÎ /// Á÷¼± ºÒ°¡´É À϶§ ±æÃ£±â ÇØº¸°í ¿©·¯ ÄÚ½º°¡ ³ª¿À¸é ¼­¹ö¿Í Ŭ¶ó°¡ ¾È¸ÂÀ» °¡´É¼ºÀÌ Å©´Ù. if( AIMANAGER->IsPossible( mMapNumber, mObjectPos, goalPos, mObject ) == false) { return 1; // if( AIMANAGER->CalcPathCnt( mMapNumber, startPos, goalPos ) > 1 ) // return 1; } return 0; } bool cPlayer::IsPushPullPossible( NiPoint2 startPos, NiPoint2 goalPos ) { switch( NETWORK2->GetServerType() ) { case _E_ST_ID_PVP_: { if( mPvPDMIdx == 0 ) /// gmÀº mPvPDMIdx°ªÀÌ 0Àϼö ÀÖ´Ù return false; cBaseDeathMatch* pDMObject = PVPMANAGER->GetPvPDMObject( mPvPDMIdx ); if( pDMObject == NULL ) return false; if( pDMObject->IsMovePossible( startPos, goalPos ) == false ) return false; } break; case _E_ST_ID_THEME_: case _E_ST_ID_TUTORIAL_: { if( mThemeRoomIdx == 0 ) return false; cThemeObject* ptheme = THEMEMANAGER->GetThemeObject( GetThemeRoomIdx() ); if( ptheme == NULL ) return false; if( ptheme->IsMovePossible( startPos, goalPos ) == false ) return false; } break; } /// Á÷¼± ÄÚ½º À̵¿ °¡´É ÀÎÁö È®ÀÎ if( AIMANAGER->IsPossible( mMapNumber, startPos, goalPos, mObject ) == false ) return false; return true; } bool cPlayer::IsClientMovePossible( NiPoint2 clientPos, NiPoint2 goalPos ) { /// Á÷¼± ÄÚ½º À̵¿ °¡´É ÀÎÁö È®ÀÎ /// Á÷¼± ºÒ°¡´É À϶§ ±æÃ£±â ÇØº¸°í ¿©·¯ ÄÚ½º°¡ ³ª¿À¸é ¼­¹ö¿Í Ŭ¶ó°¡ ¾È¸ÂÀ» °¡´É¼ºÀÌ Å©´Ù. if( AIMANAGER->IsPossible( mMapNumber, mObjectPos, clientPos, mObject ) == false && AIMANAGER->CalcPathCnt( mMapNumber, mObjectPos, clientPos ) != 1 ) { return false; } /// Ŭ¶óÀÌ¾ðÆ®°¡ ÀÖ´ø À§Ä¡·Î À̵¿ÇÏÁö¸¸ player updateÁß ¿ø·¡ À̵¿ ¸ñÀûÁö°¡ °¥¼ö ÀÖÀ¸¸é ¸ñÀûÁö¸¦ ¹Ù²Û´Ù. mReadyGotoPos = goalPos; return true; } void cPlayer::SetClientMoveReq( NiPoint2 targetPos ,NiPoint2 clientPos, bool key ) { mKeyboardMove = key; float clientRange = (targetPos - clientPos).Length(); float serverRange = (targetPos - GetPos()).Length(); if( serverRange > clientRange ) mClientMovePlusMinus = 1; else if( serverRange < clientRange ) mClientMovePlusMinus = -1; else mClientMoveDefTime = 0; } void cPlayer::CalcClientMoveDeff( unsigned long endTime ) { long serverTime = mServerMoveTime; long clientTime = endTime; mServerMoveTime = 0; if( serverTime != clientTime ) mClientMoveDefTime += serverTime - clientTime; } void cPlayer::CalcFixedObjectSize( short sizePer ) { mPlayerExrInfo.mFixedObjectSizePer = 100 + sizePer; if( 100 + sizePer < 0 ) { assert(NULL); NETWORK2->PostServerEvent("cPlayer::GetFixedObjectSize() sizePer < -100"); sizePer = -100; } float objectSize = mPlayerExrInfo.mBaseFixedSize * ( (float)( 100 + sizePer ) / 100 ); if( objectSize <= 0.0f ) { assert(NULL); NETWORK2->PostServerEvent("cPlayer::GetFixedObjectSize() <= 0"); objectSize = 1.0f; } mFixedObjectSize = objectSize; } void cPlayer::SetChgMonster( unsigned long infObjectIdx, unsigned long monsterIdx ) { /// ¸ó½ºÅÍ ¿ÜÇü º¯°æ sMonsterScript* pMScript = MONSTERSCRIPT->GetMonsterListInfo( monsterIdx ); if( pMScript == NULL ) { NETWORK2->PostServerEvent("cPlayer::SetChgMonsterIdx[%d] pMScript == NULL", monsterIdx ); return; } if( pMScript->mMonsterScale <= 0.0f ) { NETWORK2->PostServerEvent("cPlayer::SetChgMonsterIdx MonsterScale ERROR - %d", pMScript->mMonsterScale ); return; } mPlayerExrInfo.mBaseFixedSize = pMScript->mMonsterFixSize * pMScript->mMonsterScale; memset( mChgMonCoolTime, 0, sizeof(mChgMonCoolTime) ); mChgMonsterInfIdx = infObjectIdx; mPlayerExrInfo.mChgMonsterIdx = monsterIdx; MSG_SYN_PLAYER_CHG_MONSTER synMsg; synMsg.Category = NM_PLAYER; synMsg.Protocol = NM_PLAYER_CHG_MONSTER_SYN; synMsg.mCharacterIdx = mObject.index; synMsg.mMonsterIdx = mPlayerExrInfo.mChgMonsterIdx; NETWORK2->QuickSend( this, (char*)&synMsg, sizeof(synMsg) ); /// º¯½Å °ü·Ã Äù½ºÆ®Ã¼Å© SendEventQuestList( eQUEST_TRANSMON ); } void cPlayer::EndChgMonster() { /// ¸ó½ºÅÍ ¿ÜÇü ²¨Áü mPlayerExrInfo.mBaseFixedSize = FIXED_OBJECT_SIZE; mChgMonsterInfIdx = 0; mPlayerExrInfo.mChgMonsterIdx = 0; MSG_SYN_PLAYER_CHG_MONSTER synMsg; synMsg.Category = NM_PLAYER; synMsg.Protocol = NM_PLAYER_CHG_MONSTER_SYN; synMsg.mCharacterIdx = mObject.index; synMsg.mMonsterIdx = mPlayerExrInfo.mChgMonsterIdx; NETWORK2->QuickSend( this, (char*)&synMsg, sizeof(synMsg) ); /// º¯½Å °ü·Ã Äù½ºÆ®Ã¼Å© SendEventQuestList( eQUEST_TRANSMON ); } bool cPlayer::MonsterPrecedeAttackPass() { if( mPlayerExrInfo.mChgMonsterIdx == 0 ) return false; sMonsterScript* pScript = MONSTERSCRIPT->GetMonsterListInfo( mPlayerExrInfo.mChgMonsterIdx ); if( pScript == NULL ) return false; if( pScript->mIsChgMonCheck == false ) return false; return true; } void cPlayer::SetVehicle( unsigned long infObjectIdx, unsigned long vehicleIdx ) { /// Å»°Í º¯°æ sVehicleList* pScript = VEHICLESCRIPT->GetVehicleInfo( vehicleIdx ); if( pScript == NULL ) { NETWORK2->PostServerEvent("cPlayer::SetVehicle[%d,%d] pScript == NULL", mObject.index, vehicleIdx ); return; } mPlayerExrInfo.mBaseFixedSize = pScript->mObjectFixSize; mVehicleInfIdx = infObjectIdx; mPlayerExrInfo.mVehicleIdx = vehicleIdx; MSG_SYN_PLAYER_VEHICLE synMsg; synMsg.Category = NM_PLAYER; synMsg.Protocol = NM_PLAYER_VEHICLE_SYN; synMsg.mCharacterIdx = mObject.index; synMsg.mVehicleIdx = mPlayerExrInfo.mVehicleIdx; NETWORK2->QuickSend( this, (char*)&synMsg, sizeof(synMsg) ); } void cPlayer::ArightVehicle( bool sendMsg, bool sendHero ) { /// Å»°Í ²¨Áü mPlayerExrInfo.mBaseFixedSize = FIXED_OBJECT_SIZE; mVehicleInfIdx = 0; mPlayerExrInfo.mVehicleIdx = 0; if( sendMsg == false ) return; MSG_SYN_PLAYER_VEHICLE synMsg; synMsg.Category = NM_PLAYER; synMsg.Protocol = NM_PLAYER_VEHICLE_SYN; synMsg.mCharacterIdx = mObject.index; synMsg.mVehicleIdx = mPlayerExrInfo.mVehicleIdx; if( sendHero == true ) NETWORK2->QuickSend( this, (char*)&synMsg, sizeof(synMsg) ); else NETWORK2->QuickSendExcept( this, (char*)&synMsg, sizeof(synMsg) ); } void cPlayer::EndVehicleClient( bool sendSync ) { /// ÇÁ·Î¼¼½º ¼ø¼­ È®ÀÎÇÏÀÚ! if( mVehicleInfIdx != 0 ) SKILLMANAGER->VehicleDeleteInfluence( mObject, mVehicleInfIdx, sendSync ); } void cPlayer::EndVehicleItem( unsigned long skillClassIdx ) { sPlayerSkillBaseInfo* pSkill = SKILLSCRIPT->GetPlayerSkillInfo( skillClassIdx ); if( pSkill == NULL ) return; sInfluenceScript* pScript = SKILLSCRIPT->GetInfluenceInfo( pSkill->mpSetpInfoArray[0].mInfulenceIdx ); if( pScript == NULL ) return; if( mPlayerExrInfo.mVehicleIdx == 0 ) return; if( pScript->mStatusPlusIdx1 == eSTATUSPLUS_VEHICLE ) { if( (long)mPlayerExrInfo.mVehicleIdx != pScript->mValue1 ) return; if( mVehicleInfIdx != 0 ) SKILLMANAGER->DeleteInfluence( mObject, mVehicleInfIdx ); } else if( pScript->mStatusPlusIdx2 == eSTATUSPLUS_VEHICLE ) { if( (long)mPlayerExrInfo.mVehicleIdx != pScript->mValue2 ) return; if( mVehicleInfIdx != 0 ) SKILLMANAGER->DeleteInfluence( mObject, mVehicleInfIdx ); } else if( pScript->mStatusPlusIdx3 == eSTATUSPLUS_VEHICLE ) { if( (long)mPlayerExrInfo.mVehicleIdx != pScript->mValue3 ) return; if( mVehicleInfIdx != 0 ) SKILLMANAGER->DeleteInfluence( mObject, mVehicleInfIdx ); } } void cPlayer::SetSkillPushPull( unsigned short type, cBaseObject* pAttacker, unsigned long range ) { if( pAttacker == NULL ) return; if( IsChangeState( eOBJECT_STATE_PUSHPULL ) == false ) return; NiPoint2 attackerPos = pAttacker->GetPos(); if( type == 0 ) return; /// °ø°ÝÀÚ¿¡¼­ Ÿ°Ù(ÇöÀç¿ÀºêÁ§Æ®)ÀÇ ¹æÇâ»êÃâ NiPoint2 dir; dir.x = mObjectPos.x - attackerPos.x; dir.y = mObjectPos.y - attackerPos.y; dir.Unitize(); float fixRange = 0.0f; NiPoint2 targetPos = mObjectPos; if( type == eSTATUSPLUS_AROUND_PUSH ) { fixRange = OBJECTMANAGER->ObjectSizeRange( this, pAttacker, (float)range ); if( (mObjectPos - attackerPos).Length() > fixRange ) return; targetPos = attackerPos + dir * fixRange; } else if( type == eSTATUSPLUS_AROUND_PULL ) { fixRange = OBJECTMANAGER->ObjectSizeRange( this, pAttacker, 100.0f ); if( (mObjectPos - attackerPos).Length() < fixRange ) return; targetPos = attackerPos + dir * fixRange; } else if( type == eSTATUSPLUS_TARGET_PUSH ) { targetPos = mObjectPos + dir * (float)range; } NiPoint2 destPos = mObjectPos; /// ¸ñÀûÁö±îÁöÀÇ ¹æÇâÁ¤º¸ NiPoint2 divideDir = targetPos - mObjectPos; float moveRange = divideDir.Unitize(); /// ºÐÇÒ ¼ýÀÚ unsigned long divideCnt = 10; /// À̵¿°Å¸®¸¦ ºÐÇÒ float divideRange = moveRange / (float)divideCnt; for( unsigned long i = 0 ; i < divideCnt ; ++i ) /// ¸ÕÀú ¼±ÃâµÈ ³¡Á¡ºÎÅÍ °ø°ÝÀÚ¿¡ °¡±î¿î À§Ä¡·Î üũ { /// ¸ñÀûÁö¿¡¼­ ºÐÇÒÇÑ °Å¸®¸¸Å­ »©°¡¸é¼­ À̵¿°¡´ÉÇÑÁö üũÈÄ °¡´ÉÇÏ¸é ±×À§Ä¡·Î À̵¿ÇÑ´Ù. NiPoint2 pos = mObjectPos + ( divideDir * ( moveRange - ( divideRange * i ) ) ); if( IsPushPullPossible( mObjectPos, pos ) == true ) { destPos = pos; break; } } // äÁý Ãë¼Ò if( GetState() == ePLAYER_STATE_GATHERING ) { cGathering* pGathering = OBJECTMANAGER->GetGathering( mGatheringIdx ); if( pGathering != NULL ) pGathering->CancelGatherByOddity( this ); } else if( GetState() == eOBJECT_STATE_STOP ) { // °­È­ Ãë¼Ò if( GetStateStop() == eSTOP_ENHANCED ) { ItemEnhancedForceCancel(); } // Á¶ÇÕ Ãë¼Ò else if( GetStateStop() == eSTOP_ITEMMIX ) { ItemMixForceCancel(); } } else if( GetState() == eOBJECT_STATE_ATTACK ) { SKILLMANAGER->CastSkillCancel( mObject, true, eATTRIBUTETYPE_NONE ); } MSG_SYN_SKLL_PUSHPULL sync; sync.Category = NM_SKILL; sync.Protocol = NM_SKILL_PUSHPULL_SYN; sync.mTarget = mObject; sync.mPosX = destPos.x; sync.mPosY = destPos.y; NETWORK2->QuickSend( this, (char*)&sync, sizeof(sync) ); mGotoX = destPos.x; mGotoY = destPos.y; ChangeState( eOBJECT_STATE_PUSHPULL ); } NiPoint2 cPlayer::SetSkillRush( cBaseObject* pTarget, bool blink, unsigned long skillIdx, unsigned char skillStep ) { if( pTarget == NULL ) return GetPos(); sObject target = pTarget->GetObject(); SetMoveTargetPos( pTarget->GetXPos(), pTarget->GetYPos() ); SetRangeTarget( pTarget->GetXPos(), pTarget->GetYPos(), target, 100 ); mCheckRushSkillIdx = skillIdx; mCheckRushSkillStep = skillStep; if( blink == true ) { NiPoint2 destPos = mObjectPos; /// ¸ñÀûÁö±îÁöÀÇ ¹æÇâÁ¤º¸ NiPoint2 divideDir = pTarget->GetPos() - mObjectPos; divideDir.Unitize(); float fixRange = OBJECTMANAGER->ObjectSizeRange( pTarget, this, 100 ); float moveRange = (mObjectPos - pTarget->GetPos()).Length(); if( moveRange < fixRange ) return GetPos(); moveRange = moveRange - fixRange; /// ºÐÇÒ ¼ýÀÚ unsigned long divideCnt = 10; /// À̵¿°Å¸®¸¦ ºÐÇÒ float divideRange = moveRange / (float)divideCnt; for( unsigned long i = 0 ; i < divideCnt ; ++i ) /// ¸ÕÀú ¼±ÃâµÈ ³¡Á¡ºÎÅÍ °ø°ÝÀÚ¿¡ °¡±î¿î À§Ä¡·Î üũ { /// ¸ñÀûÁö¿¡¼­ ºÐÇÒÇÑ °Å¸®¸¸Å­ »©°¡¸é¼­ À̵¿°¡´ÉÇÑÁö üũÈÄ °¡´ÉÇÏ¸é ±×À§Ä¡·Î À̵¿ÇÑ´Ù. NiPoint2 pos = mObjectPos + ( divideDir * ( moveRange - ( divideRange * i ) ) ); if( IsPushPullPossible( mObjectPos, pos ) == true ) { destPos = pos; break; } } if( ChangeState( eOBJECT_STATE_IDLE ) == false ) return GetPos(); SetPos( destPos.x, destPos.y ); MoveStop(); } else { if( ChangeState( ePLAYER_STATE_RUSH ) == false ) return GetPos(); return pTarget->GetPos(); } return GetPos(); } void cPlayer::SetDoorPushPull( sDoorInfo* pInfo ) { if( IsChangeState( eOBJECT_STATE_PUSHPULL ) == false ) return; if( STAGESCRIPT->InsidePolygon( pInfo->mRectPos, 4, mObjectPos ) != 0 ) return; /// °ø°ÝÀÚ ¹æÇâ NiPoint2 dir = NiPoint2( -sinf(mDirection), -cosf(mDirection) ); dir.Unitize(); NiPoint2 targetPos = mObjectPos + dir * 350; /// ¿¹»ó ÃÖÁ¾ ¸ñÀûÁö NiPoint2 destPos = mObjectPos; /// ½ÃÀÛÀ§Ä¡ºÎÅÍ Á¡ÁøÀûÀ¸·Î ÁøÇàµÇº¼ À§Ä¡ /// ¸ñÀûÁö±îÁöÀÇ ¹æÇâÁ¤º¸ float moveRange = (targetPos - mObjectPos).Length(); /// ºÐÇÒ ¼ýÀÚ unsigned long divideCnt = 10; /// À̵¿°Å¸®¸¦ ºÐÇÒ float divideRange = moveRange / (float)divideCnt; for( unsigned long i = 0 ; i < divideCnt ; ++i ) /// ¸ÕÀú ¼±ÃâµÈ ³¡Á¡ºÎÅÍ °ø°ÝÀÚ¿¡ °¡±î¿î À§Ä¡·Î üũ { /// ¸ñÀûÁö¿¡¼­ ºÐÇÒÇÑ °Å¸®¸¸Å­ »©°¡¸é¼­ À̵¿°¡´ÉÇÑÁö üũÈÄ °¡´ÉÇÏ¸é ±×À§Ä¡·Î À̵¿ÇÑ´Ù. NiPoint2 pos = mObjectPos + ( dir * ( moveRange - ( divideRange * i ) ) ); if( IsPushPullPossible( mObjectPos, pos ) == true ) { destPos = pos; break; } } // äÁý Ãë¼Ò if( GetState() == ePLAYER_STATE_GATHERING ) { cGathering* pGathering = OBJECTMANAGER->GetGathering( mGatheringIdx ); if( pGathering != NULL ) pGathering->CancelGatherByOddity( this ); } else if( GetState() == eOBJECT_STATE_STOP ) { // °­È­ Ãë¼Ò if( GetStateStop() == eSTOP_ENHANCED ) { ItemEnhancedForceCancel(); } // Á¶ÇÕ Ãë¼Ò else if( GetStateStop() == eSTOP_ITEMMIX ) { ItemMixForceCancel(); } } else if( GetState() == eOBJECT_STATE_ATTACK ) { SKILLMANAGER->CastSkillCancel( mObject, true, eATTRIBUTETYPE_NONE ); } MSG_SYN_PLAYEREXT_DOORPUSH sync; sync.Category = NM_PLAYEREXT; sync.Protocol = NM_PLAYEREXT_DOORPUSH_SYN; sync.mTarget = mObject; sync.mPosX = destPos.x; sync.mPosY = destPos.y; NETWORK2->QuickSend( this, (char*)&sync, sizeof(sync) ); mGotoX = destPos.x; mGotoY = destPos.y; ChangeState( eOBJECT_STATE_PUSHPULL ); } void cPlayer::Jump() { /// Á¡ÇÁ ÁßÀÎÁö üũ & Á¡ÇÁ ºÒ°¡´É »óÅÂÀÎÁö üũ if( mJumpEndTime > NETWORK2->GetAccumTime() || IsChangeState( eOBJECT_STATE_MOVE ) == false ) { NETWORK2->SendMsgRoot( mConnectionIdx, NM_PLAYER, NM_PLAYER_JUMP_RES ); return; } if( mPlayerExrInfo.mState == ePLAYER_STATE_SITDOWN ) ChangeState( eOBJECT_STATE_IDLE ); MSG_SYN_PLAYER_JUMP msg; msg.Category = NM_PLAYER; msg.Protocol = NM_PLAYER_JUMP_SYN; msg.mPlayerIdx = mObject.index; NETWORK2->QuickSend( this, (char*)&msg, sizeof(msg) ); unsigned long jumpTime = SYNC_MOVE_TIME; if( mPlayerExrInfo.mChgMonsterIdx == 0 ) jumpTime = mJumpTime; /// Á÷¾÷¿¡ ¸ÂÃ罺ũ¸³Æ®¿¡¼­ Àоî¿Â °ª else jumpTime = PLAYER_JUMPTIME_CHGMONSTER; /// ¸ó½ºÅÍÁ¡ÇÁ ¼öÄ¡´Â °íÁ¤°ª if( jumpTime < SYNC_MOVE_TIME ) jumpTime = 0; else jumpTime -= SYNC_MOVE_TIME; mJumpEndTime = NETWORK2->GetAccumTime() + jumpTime; if( GetState() != eOBJECT_STATE_MOVE ) return; mJumpSpeedState = 1; /// ÀüüÀûÀ¸·Î °¡Àå ¸¹ÀÌ ºÐÆ÷ÇÑ Á¡ÇÁ ½ÃÀÛ Á¤Áö¸ð¼Ç ½Ã°£ mJumpMoveSpeedDownEndTime = NETWORK2->GetAccumTime() + 134; /// Å»°Í Àΰæ¿ì if( mVehicleInfIdx != 0 ) { mJumpMoveSpeedDownEndTime = NETWORK2->GetAccumTime() + 167; } else if( mPlayerExrInfo.mChgMonsterIdx != 0 ) { mJumpMoveSpeedDownEndTime = NETWORK2->GetAccumTime() + 134; } else { /// Á¾Á· º°·Î ½Ã°£¼³Á¤ switch ( mPlayerInfo.Race ) { case eRACE_HUMAN: mJumpMoveSpeedDownEndTime = NETWORK2->GetAccumTime() + 67; break; case eRACE_BEAST: mJumpMoveSpeedDownEndTime = NETWORK2->GetAccumTime() + 134; break; case eRACE_ELF: mJumpMoveSpeedDownEndTime = NETWORK2->GetAccumTime() + 134; break; } } } void cPlayer::SetJumpTime() { mJumpTime = (unsigned long)STATUSSCRIPT->GetStatusExtBaseInfo( ePLAYER_STATUS_EXT_JUMP, mPlayerInfo.Job ) ; } // SearchThemeUser Method. PerThemeUser* cPlayer::SearchThemeUser(long cid) { return THEMEUSERPOOL->SearchThemeUser( &mThemeUserRoot, cid ); } // IsThemeUser Method. bool cPlayer::IsThemeUser(long cid) { return THEMEUSERPOOL->IsThemeUser( &mThemeUserRoot, cid ); } // AddThemeUser Method. void cPlayer::AddThemeUser(THEME_USER* table, long rowCount) { for( int i = 0 ; i < rowCount ; ++i, ++table ) { PerThemeUser* perThemeUser = THEMEUSERPOOL->GetThemeUser( &mThemeUserRoot, MAKETHEMECID( table->themeIdx, table->themeMode ) ); if ( perThemeUser != NULL ) { perThemeUser->themeIdx = table->themeIdx; perThemeUser->roomIdx = table->roomIdx; perThemeUser->mode = table->themeMode; // ¸ðµå perThemeUser->lastDate = timestamp2time_t( table->lastDate ); // ¸¶Áö¸· ¾÷µ¥ÀÌÆ®(ÀÏ) perThemeUser->validThru = timestamp2time_t( table->validThru ); // À¯È¿¸¸±â(ÀÏ) cThemeObject* ptheme = THEMEMANAGER->GetThemeObject( table->roomIdx ); if( ptheme != NULL ) ptheme->Dependency(); } } SendThemeInfo(); } // SaveThemeUser Method. bool cPlayer::SaveThemeUser(long cid) { if ( IsThemeUser( cid ) == false ) { NETWORK2->SendMsgRoot( mConnectionIdx, NM_THEME, NM_THEME_DEPENDENCY_SYN ); HANDLE handle = NULL; THEME_USER_SAVE* save = (THEME_USER_SAVE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_THEME_USER_SAVE ); save->themeIdx = HIWORD( cid ); save->themeMode = (unsigned char)(LOWORD( cid )); save->roomIdx = mMapNumber; save->characterIdx = mObject.index; return NETWORK2->SendSQL( mConnectionIdx, handle, sizeof(THEME_USER_SAVE) ); } return false; } // SendThemeInfo Method. void cPlayer::SendThemeInfo( ) { if( mGameIn == false ) return; PerThemeUser* perThemeUser = (PerThemeUser*)mThemeUserRoot.pool; HANDLE handle = NULL; MSG_SYN_THEME_LIST* sendMsg = (MSG_SYN_THEME_LIST*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_THEME, NM_THEME_HAVE_LIST_SYN ); if ( sendMsg != NULL ) { sPlayerThemeList* themeList = sendMsg->mThemeList; unsigned long& rowCount = sendMsg->mCount; if ( perThemeUser != NULL ) { time_t ltime; long result; time( <ime ); while( perThemeUser != NULL ) { result = (long)difftime( perThemeUser->validThru, ltime ); if ( result > 0 ) { themeList->mMapNumber = HIWORD( perThemeUser->cid ); themeList->mThemeMode = (unsigned char)LOWORD( perThemeUser->cid ); themeList->mUniqueIdx = MAKETHEMECID( perThemeUser->themeIdx, perThemeUser->roomIdx ); themeList->mResetLeftTime = result*SECOND; themeList++; rowCount++; } perThemeUser = (PerThemeUser*)perThemeUser->next; } } else { themeList->mMapNumber = 0; themeList->mThemeMode = 0; themeList->mUniqueIdx = 0; themeList->mResetLeftTime = 0; } NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength() ); } } void cPlayer::SendThemeExpireTime() { long result = THEMEMANAGER->NextResetTime() - NETWORK2->GetAccumTime(); if ( result > 0 ) { HANDLE handle = NULL; MSG_SYN_THEME_EXPIRE_TIME* sendMsg = (MSG_SYN_THEME_EXPIRE_TIME*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_THEME, NM_THEME_EXPIRE_TIME_SYN ); if ( sendMsg != NULL ) { sendMsg->mExpireTime = result; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_THEME_EXPIRE_TIME) ); } } } void cPlayer::AddImmuneApplyType( unsigned char InfluenceType, unsigned short applyType ) { SKILLMANAGER->ClearImmuneApplyType( mObject, InfluenceType, applyType ); if( InfluenceType == eINFLUENCETYPE_BUF ) { mImmuneBuffSet.Insert( applyType ); } else if( InfluenceType == eINFLUENCETYPE_DEBUF ) { mImmuneDebuffSet.Insert( applyType ); } else assert(0); } void cPlayer::AddImmuneKind( unsigned long infKind ) { SKILLMANAGER->ClearImmuneKind( mObject, infKind ); mImmuneKindSet.Insert( infKind ); } bool cPlayer::IsImmuneApplyType( unsigned char InfluenceType, unsigned long applyType ) { if( applyType == 0 ) return false; /// ¸é¿ª ¸ñ·Ï¿¡¼­ ã¾ÆºÁ¼­ ÀÖÀ¸¸é ¸é¿ª if( InfluenceType == eINFLUENCETYPE_BUF ) { cHashSet::cIterator i = mImmuneBuffSet.Find( applyType ); if( i != mImmuneBuffSet.End() ) return true; } else if( InfluenceType == eINFLUENCETYPE_DEBUF ) { cHashSet::cIterator i = mImmuneDebuffSet.Find( applyType ); if( i != mImmuneDebuffSet.End() ) return true; } return false; } bool cPlayer::IsImmuneApplyAll( unsigned long applyType ) { if( applyType == 0 ) return false; /// ¸é¿ª ¸ñ·Ï¿¡¼­ ã¾ÆºÁ¼­ ÀÖÀ¸¸é ¸é¿ª cHashSet::cIterator i; i = mImmuneBuffSet.Find( applyType ); if( i != mImmuneBuffSet.End() ) return true; i = mImmuneDebuffSet.Find( applyType ); if( i != mImmuneDebuffSet.End() ) return true; return false; } bool cPlayer::IsImmuneKind( unsigned long infKind ) { if( infKind == 0 ) return false; /// ¸é¿ª ¸ñ·Ï¿¡¼­ ã¾ÆºÁ¼­ ÀÖÀ¸¸é ¸é¿ª cHashSet::cIterator b = mImmuneKindSet.Find( infKind ); cHashSet::cIterator e = mImmuneKindSet.End(); if( b != e ) return true; return false; } void cPlayer::SetUserPortal( unsigned long userPortalIdx ) { if( mUserPortalIdx == 0 ) { mUserPortalIdx = userPortalIdx; } else { /// ÀÌ¹Ì »ý¼ºµÇ Àִ°æ¿ì ±âÁ¸°ÍÀ»Áö¿ì°í »õ·Î¸¸µç´Ù. OBJECTMANAGER->InsertDeleteUserPortal( mUserPortalIdx ); mUserPortalIdx = userPortalIdx; } } unsigned long cPlayer::CalcChangeMPDamage( unsigned char attributeType, unsigned long damage, bool applyHP ) { unsigned long leftDamage = damage; unsigned long calcMP = GetMP(); if( applyHP == true ) { for( unsigned long i = 0 ; i < mChangeMPDamageAry.GetSize() ; ++i ) { cInfluenceObject* pInf = SKILLMANAGER->GetInfluence( mChangeMPDamageAry[i] ); if( pInf == NULL || pInf->IsDelReady() == true ) continue; /// ¼Ó¼ºÈ®ÀÎ if( ( attributeType == eATTRIBUTETYPE_PHYSICAL && ( pInf->GetChangeMPType() == eINFCHANGEMPTYPE_PHY || pInf->GetChangeMPType() == eINFCHANGEMPTYPE_ALL ) ) || ( attributeType == eATTRIBUTETYPE_MAGIC && ( pInf->GetChangeMPType() == eINFCHANGEMPTYPE_MAG || pInf->GetChangeMPType() == eINFCHANGEMPTYPE_ALL ) ) ) { /// È¿°ú¿¡¼­ µ¥¹ÌÁömpº¯È¯ ¼öÄ¡ °è»ê unsigned long cutMP = (unsigned long)( GetMaxMP() * pInf->GetChangeMPValue() * 0.01f ); cutMP = GetMaxMP() - cutMP; /// °è»êµÈ ÇöÀçmp°¡ È¿°úÁ¦ÇѰªº¸´Ù Å«°æ¿ì¸¸ °è»ê if( calcMP > cutMP ) { /// µ¥¹ÌÁö Àû¿ë°ªÀÌ È¿°ú ĿƮ¶óÀÎ ³Ñ´ÂÁö üũ if( cutMP + leftDamage < calcMP ) { /// ³ÑÁö ¾Ê´Â°æ¿ì µ¥¹ÌÁö ¸¸Å­ °è»êµÈÇöÀçmp¿¡ Àû¿ë calcMP = calcMP - leftDamage; leftDamage = 0; } else { /// ³Ñ´Â °æ¿ì È¿°úµ¥¹ÌÁömpº¯È¯ °ª±îÁö¸¸ Àû¿ë leftDamage = leftDamage - ( calcMP - cutMP ); calcMP = cutMP; /// ÇØ´ç È¿°ú´Â Áö¿î´Ù. SKILLMANAGER->DeleteInfluenceList( mChangeMPDamageAry[i] ); } } else { /// ÀÌ¹Ì ³Ñ´Â °æ¿ìÀ̹ǷΠȿ°ú´Â Áö¿î´Ù. SKILLMANAGER->DeleteInfluenceList( mChangeMPDamageAry[i] ); } } } } else /// mpµ¥¹ÌÁö À̹ǷΠµ¥¹ÌÁö´Â ÀüºÎ´Ù Àû¿ëÇϰí Çã¿ëÄ¡ ¹ØÀ¸·Î³»·Á°£ È¿°ú¸¸ ÀüºÎ Áö¿ö¹ö¸°´Ù. { calcMP = GetMP() - damage; leftDamage = damage; for( unsigned long i = 0 ; i < mChangeMPDamageAry.GetSize() ; ++i ) { cInfluenceObject* pInf = SKILLMANAGER->GetInfluence( mChangeMPDamageAry[i] ); if( pInf == NULL || pInf->IsDelReady() == true ) continue; /// ¼Ó¼ºÈ®ÀÎ if( pInf->GetChangeMPType() == eINFCHANGEMPTYPE_NONE ) continue; /// È¿°ú¿¡¼­ µ¥¹ÌÁömpº¯È¯ ¼öÄ¡ °è»ê unsigned long cutMP = (unsigned long)( GetMaxMP() * pInf->GetChangeMPValue() * 0.01f ); cutMP = GetMaxMP() - cutMP; if( calcMP <= cutMP ) SKILLMANAGER->DeleteInfluenceList( mChangeMPDamageAry[i] ); } } return leftDamage; } unsigned long cPlayer::CalcGuard( unsigned char attributeType, unsigned long damage ) { unsigned long tempDamage = damage; for( unsigned long i = 0 ; i < mGuardAry.GetSize() ; ++i ) { cInfluenceObject* pInf = SKILLMANAGER->GetInfluence( mGuardAry[i] ); if( pInf == NULL || pInf->IsDelReady() == true ) continue; if( pInf->CalcLeftGuard( attributeType, &tempDamage ) == false ) continue; if( pInf->GetLeftGuardValue() == 0 || pInf->GetLeftGuardCnt() == 0) SKILLMANAGER->DeleteInfluenceList( mGuardAry[i] ); else { HANDLE handle = NULL; MSG_SYN_SKILL_INFLUENCE_GUARDCHANGE* pMsg = (MSG_SYN_SKILL_INFLUENCE_GUARDCHANGE*)NETWORK2->GetMsgRoot( &handle ,mConnectionIdx ,NM_SKILL ,NM_SKILL_INFLUENCE_GUARDCHANGE_SYN ); if ( pMsg != NULL ) { pMsg->mInfluenceIdx = pInf->GetUniqueIdx(); pMsg->mChangeValue = pInf->GetLeftGuardValue(); pMsg->mChangeCnt = pInf->GetLeftGuardCnt(); NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_SKILL_INFLUENCE_GUARDCHANGE) ); } } if( tempDamage != 0 ) continue; return 0; } return tempDamage; } bool cPlayer::CalcCashExpGuard( unsigned long* pInfIdx, unsigned char* leftCnt ) { if( pInfIdx == NULL || leftCnt == NULL ) return false; for( unsigned long i = 0 ; i < mGuardAry.GetSize() ; ++i ) { cInfluenceObject* pInf = SKILLMANAGER->GetInfluence( mGuardAry[i] ); if( pInf == NULL || pInf->IsDelReady() == true ) continue; if( pInf->CalcCashExpGuard() == false ) continue; if( pInf->GetLeftGuardCnt() == 0 ) SKILLMANAGER->DeleteInfluenceList( mGuardAry[i] ); *pInfIdx = mGuardAry[i]; *leftCnt = pInf->GetLeftGuardCnt(); return true; } return false; } void cPlayer::CalcDirection( float targetX, float targetY ) { float viewPosX, viewPosY; viewPosX = mObjectPos.x - targetX; viewPosY = mObjectPos.y - targetY; mDirection = atan2( viewPosX, viewPosY ); } void cPlayer::SetForceType( unsigned char forceType, bool msgSend ) { mPlayerExrInfo.mForceType = forceType; if( msgSend == true ) { MSG_SYN_PLAYER_FORCE msg; msg.Category = NM_PLAYER; msg.Protocol = NM_PLAYER_FORCE_SYN; msg.mPlayerIdx = mObject.index; msg.mForceType = forceType; NETWORK2->QuickSend( this, (char*)&msg, sizeof(msg) ); } PostCharacterEvent( EVENT_CHARACTER_UPDATE, "SetForceType=%d", forceType ); } unsigned long cPlayer::WindPointPlus( unsigned long windPoint, bool msgSend ) { mHeroInfo.mWindPoint += windPoint; if( msgSend == true ) { HANDLE handle = NULL; MSG_SYN_PLAYER_FORCEVALUE* pMsg = (MSG_SYN_PLAYER_FORCEVALUE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_FORCEVALUE_SYN ); if ( pMsg != NULL ) { pMsg->mForceType = eFORCETYPE_WIND; pMsg->mValueType = 1; pMsg->mValue = mHeroInfo.mWindPoint; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_PLAYER_FORCEVALUE) ); } } return mHeroInfo.mWindPoint; } unsigned long cPlayer::WindFriendlyPlus( unsigned long windFriendly, bool msgSend ) { mHeroInfo.mWindFriendly += windFriendly; if( msgSend == true ) { HANDLE handle = NULL; MSG_SYN_PLAYER_FORCEVALUE* pMsg = (MSG_SYN_PLAYER_FORCEVALUE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_FORCEVALUE_SYN ); if ( pMsg != NULL ) { pMsg->mForceType = eFORCETYPE_WIND; pMsg->mValueType = 2; pMsg->mValue = mHeroInfo.mWindFriendly; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_PLAYER_FORCEVALUE) ); } } return mHeroInfo.mWindFriendly; } unsigned long cPlayer::EarthPointPlus( unsigned long earthPoint, bool msgSend ) { mHeroInfo.mEarthPoint += earthPoint; if( msgSend == true ) { HANDLE handle = NULL; MSG_SYN_PLAYER_FORCEVALUE* pMsg = (MSG_SYN_PLAYER_FORCEVALUE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_FORCEVALUE_SYN ); if ( pMsg != NULL ) { pMsg->mForceType = eFORCETYPE_EARTH; pMsg->mValueType = 1; pMsg->mValue = mHeroInfo.mEarthPoint; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_PLAYER_FORCEVALUE) ); } } return mHeroInfo.mEarthPoint; } unsigned long cPlayer::EarthFriendlyPlus( unsigned long earthFriendly, bool msgSend ) { mHeroInfo.mEarthFriendly += earthFriendly; if( msgSend == true ) { HANDLE handle = NULL; MSG_SYN_PLAYER_FORCEVALUE* pMsg = (MSG_SYN_PLAYER_FORCEVALUE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_FORCEVALUE_SYN ); if ( pMsg != NULL ) { pMsg->mForceType = eFORCETYPE_EARTH; pMsg->mValueType = 2; pMsg->mValue = mHeroInfo.mEarthFriendly; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_PLAYER_FORCEVALUE) ); } } return mHeroInfo.mEarthFriendly; } unsigned long cPlayer::WaterPointPlus( unsigned long waterPoint, bool msgSend ) { mHeroInfo.mWaterPoint += waterPoint; if( msgSend == true ) { HANDLE handle = NULL; MSG_SYN_PLAYER_FORCEVALUE* pMsg = (MSG_SYN_PLAYER_FORCEVALUE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_FORCEVALUE_SYN ); if ( pMsg != NULL ) { pMsg->mForceType = eFORCETYPE_WATER; pMsg->mValueType = 1; pMsg->mValue = mHeroInfo.mWaterPoint; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_PLAYER_FORCEVALUE) ); } } return mHeroInfo.mWaterPoint; } unsigned long cPlayer::WaterFriendlyPlus( unsigned long waterFriendly, bool msgSend ) { mHeroInfo.mWaterFriendly += waterFriendly; if( msgSend == true ) { HANDLE handle = NULL; MSG_SYN_PLAYER_FORCEVALUE* pMsg = (MSG_SYN_PLAYER_FORCEVALUE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_FORCEVALUE_SYN ); if ( pMsg != NULL ) { pMsg->mForceType = eFORCETYPE_WATER; pMsg->mValueType = 2; pMsg->mValue = mHeroInfo.mWaterFriendly; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_PLAYER_FORCEVALUE) ); } } return mHeroInfo.mWaterFriendly; } unsigned long cPlayer::FirePointPlus( unsigned long firePoint, bool msgSend ) { mHeroInfo.mFirePoint += firePoint; if( msgSend == true ) { HANDLE handle = NULL; MSG_SYN_PLAYER_FORCEVALUE* pMsg = (MSG_SYN_PLAYER_FORCEVALUE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_FORCEVALUE_SYN ); if ( pMsg != NULL ) { pMsg->mForceType = eFORCETYPE_FIRE; pMsg->mValueType = 1; pMsg->mValue = mHeroInfo.mFirePoint; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_PLAYER_FORCEVALUE) ); } } return mHeroInfo.mFirePoint; } unsigned long cPlayer::FireFriendlyPlus( unsigned long fireFriendly, bool msgSend ) { mHeroInfo.mFireFriendly += fireFriendly; if( msgSend == true ) { HANDLE handle = NULL; MSG_SYN_PLAYER_FORCEVALUE* pMsg = (MSG_SYN_PLAYER_FORCEVALUE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_FORCEVALUE_SYN ); if ( pMsg != NULL ) { pMsg->mForceType = eFORCETYPE_FIRE; pMsg->mValueType = 2; pMsg->mValue = mHeroInfo.mFireFriendly; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_PLAYER_FORCEVALUE) ); } } return mHeroInfo.mFireFriendly; } void cPlayer::ForcePointDBUpdate() { HANDLE handle = NULL; FORCE_POINT_UPDATE* pPoint = (FORCE_POINT_UPDATE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_FORCEPOINT_UPDATE ); pPoint->mCharacterIdx = mObject.index; pPoint->mFirePoint = mHeroInfo.mFirePoint; pPoint->mFireFriendly = mHeroInfo.mFireFriendly; pPoint->mWaterPoint = mHeroInfo.mWaterPoint; pPoint->mWaterFriendly = mHeroInfo.mWaterFriendly; pPoint->mWindPoint = mHeroInfo.mWindPoint; pPoint->mWindFriendly = mHeroInfo.mWindFriendly; pPoint->mEarthPoint = mHeroInfo.mEarthPoint; pPoint->mEarthFriendly = mHeroInfo.mEarthFriendly; pPoint->mRetValue = -1; NETWORK2->SendSQL( handle, sizeof(FORCE_POINT_UPDATE) ); } void cPlayer::SetStatus1( ePLAYER_STATUS statusBase, float value ) { if( statusBase >= ePLAYER_STATUS_LEVEL ) { assert(NULL); return; } switch( statusBase ) { case ePLAYER_STATUS_STR: mStatus1.mStr = value; break; case ePLAYER_STATUS_DEX: mStatus1.mDex = value; break; case ePLAYER_STATUS_CON: mStatus1.mCon = value; break; case ePLAYER_STATUS_INT: mStatus1.mInt = value; break; case ePLAYER_STATUS_WIS: mStatus1.mWis = value; break; } } /// 070116 PKH ±âº» ½ºÅÝ Ãß°¡ ¼öÄ¡ µî·Ï void cPlayer::SetStatus1Plus( ePLAYER_STATUS statusBasePlus, float value ) { if( statusBasePlus >= ePLAYER_STATUS_LEVEL ) { assert(NULL); return; } switch( statusBasePlus ) { case ePLAYER_STATUS_STR: mStatus1Plus.mStr = value; break; case ePLAYER_STATUS_DEX: mStatus1Plus.mDex = value; break; case ePLAYER_STATUS_CON: mStatus1Plus.mCon = value; break; case ePLAYER_STATUS_INT: mStatus1Plus.mInt = value; break; case ePLAYER_STATUS_WIS: mStatus1Plus.mWis = value; break; } } void cPlayer::SetStatus1Per( ePLAYER_STATUS statusBasePer, float value ) { if( statusBasePer >= ePLAYER_STATUS_LEVEL ) { assert(NULL); return; } switch( statusBasePer ) { case ePLAYER_STATUS_STR: mStatus1Per.mStr = value; break; case ePLAYER_STATUS_DEX: mStatus1Per.mDex = value; break; case ePLAYER_STATUS_CON: mStatus1Per.mCon = value; break; case ePLAYER_STATUS_INT: mStatus1Per.mInt = value; break; case ePLAYER_STATUS_WIS: mStatus1Per.mWis = value; break; } } float cPlayer::GetStatus2Plus( ePLAYER_STATUS_EXT extStatus ) { if( extStatus >= ePLAYER_STATUS_EXT2_MAX ) { assert(NULL); return 0.0f; } return mStatus2Plus[extStatus]; } float cPlayer::GetStatus2Per( ePLAYER_STATUS_EXT extStatus ) { if( extStatus >= ePLAYER_STATUS_EXT2_MAX ) { assert(NULL); return 0.0f; } return mStatus2Per[extStatus]; } void cPlayer::SetStatus2( ePLAYER_STATUS_EXT extStatus, float value ) { if( extStatus >= ePLAYER_STATUS_EXT2_MAX ) { assert(NULL); return; } switch( extStatus ) { case ePLAYER_STATUS_EXT_ATK: break; /// ÃÖ¼Ò ÃÖ´ë °ªÀ¸·Î ÀçÁ¤ÀÇ case ePLAYER_STATUS_EXT_RATK: break; /// ÃÖ¼Ò ÃÖ´ë °ªÀ¸·Î ÀçÁ¤ÀÇ case ePLAYER_STATUS_EXT_DEF: mStatus2.mPhysicDefense = value; break; case ePLAYER_STATUS_EXT_MATK: break; /// ÃÖ¼Ò ÃÖ´ë °ªÀ¸·Î ÀçÁ¤ÀÇ case ePLAYER_STATUS_EXT_MDEF: mStatus2.mMagicDefense = value; break; case ePLAYER_STATUS_EXT_CRI: mStatus2.mPhysicCritical = value; break; case ePLAYER_STATUS_EXT_MCRI: mStatus2.mMagicCritical = value; break; case ePLAYER_STATUS_EXT_MAXHP: { mPlayerExrInfo.MaxHP = FloatToInt( value ); if( mPlayerExrInfo.MaxHP == 0 ) assert(0); } break; case ePLAYER_STATUS_EXT_MAXMP: { mPlayerExrInfo.MaxMP = FloatToInt( value ); if( mPlayerExrInfo.MaxMP == 0 ) assert(0); } break; case ePLAYER_STATUS_EXT_RECOVHP: mStatus2.mRecovHP = value; break; case ePLAYER_STATUS_EXT_RECOVMP: mStatus2.mRecovMP = value; break; case ePLAYER_STATUS_EXT_HIT: mStatus2.mPhysicAttackRate = value; break; case ePLAYER_STATUS_EXT_MHIT: mStatus2.mMagicAttackRate = value; break; case ePLAYER_STATUS_EXT_AVOID: mStatus2.mPhysicAvoid = value; break; case ePLAYER_STATUS_EXT_WEIGHT: mStatus2.mMaxWeight = value; break; case ePLAYER_STATUS_EXT_ASPD: mPlayerExrInfo.mAttackSpeed = value; mStatus2.mAttackSpeed = (float)value; break; case ePLAYER_STATUS_EXT_COOLTIME: mStatus2.mCooltime = (float)value; break; case ePLAYER_STATUS_EXT_RANGE: mStatus2.mInRange = value; break; case ePLAYER_STATUS_EXT_RRANGE: mStatus2.mOutRange = value; break; case ePLAYER_STATUS_EXT_SPD: mPlayerExrInfo.mMoveSpeed = FloatToInt( value ); mStatus2.mMoveSpeed = value; break; case ePLAYER_STATUS_EXT_HEAL: mStatus2.mHeal = value; break; case ePLAYER_STATUS_EXT_MAVOID: mStatus2.mMagicAvoid = value; break; case ePLAYER_STATUS_EXT_CRIDEF: mStatus2.mPhyCriDef = value; break; case ePLAYER_STATUS_EXT_MCRIDEF: mStatus2.mMagCriDef = value; break; case ePLAYER_STATUS_EXT_ATKMin: mStatus2.mPhysicMinAttack = value; break; case ePLAYER_STATUS_EXT_ATKMax: mStatus2.mPhysicMaxAttack = value; break; case ePLAYER_STATUS_EXT_RATKMin: mStatus2.mPhysicMinRangeAttack = value; break; case ePLAYER_STATUS_EXT_RATKMax: mStatus2.mPhysicMaxRangeAttack = value; break; case ePLAYER_STATUS_EXT_MATKMin: mStatus2.mMagicMinAttack = value; break; case ePLAYER_STATUS_EXT_MATKMax: mStatus2.mMagicMaxAttack = value; break; } } void cPlayer::SetStatusEtc( ePLAYER_STATUS_EXT_ADD statusAdd, float value ) { if( statusAdd >= ePLAYER_STATUS_EXT_ADD_MAX ) { assert(NULL); return; } switch( statusAdd ) { case ePLAYER_STATUS_EXT_ADD_EXPADDPER: mStatusEtc.mExpAddPer = value; break; case ePLAYER_STATUS_EXT_ADD_EXPADDPLUS: mStatusEtc.mExpAddPlus = value; break; case ePLAYER_STATUS_EXT_ADD_SXPADDPER: mStatusEtc.mSxpAddPer = value; break; case ePLAYER_STATUS_EXT_ADD_SXPADDPLUS: mStatusEtc.mSxpAddPlus = value; break; case ePLAYER_STATUS_EXT_ADD_MONEYPER: mStatusEtc.mMoneyAddPer = value; break; case ePLAYER_STATUS_EXT_ADD_PVPPOINTPER: mStatusEtc.mPvPPointAddPer = value; break; } } //void cPlayer::SetDamageCalc( ePLAYER_STATUS_DAMAGE statusDamage, unsigned long value ) //{ // if( statusDamage >= ePLAYER_STATUS_DAMAGE_MAX ) // { // assert(NULL); // return; // } // // switch( statusDamage ) // { // case ePLAYER_STATUS_DAMAGE_INSTANTPERHIT: // mDamageCalc.mInstantPerHit = value; break; // case ePLAYER_STATUS_DAMAGE_INSTANTPLUSHIT: // mDamageCalc.mInstantPlusHit = value; break; // case ePLAYER_STATUS_DAMAGE_PHYINSTANTPERCRI: // mDamageCalc.mPhyInstantPerCri = value; break; // case ePLAYER_STATUS_DAMAGE_PHYINSTANTPLUSCRI: // mDamageCalc.mPhyInstantPlusCri = value; break; // case ePLAYER_STATUS_DAMAGE_MAGICINSTANTPERCRI: // mDamageCalc.mMagicInstantPerCri = value; break; // case ePLAYER_STATUS_DAMAGE_MAGICINSTANTPLUSCRI: // mDamageCalc.mMagicInstantPlusCri = value; break; // case ePLAYER_STATUS_DAMAGE_PHYINSTANTPERATTACK: // mDamageCalc.mPhyInstantPerAttack = value; break; // case ePLAYER_STATUS_DAMAGE_PHYINSTANTPLUSATTACK: // mDamageCalc.mPhyInstantPlusAttack = value; break; // case ePLAYER_STATUS_DAMAGE_MAGICINSTANTPERATTACK: // mDamageCalc.mMagicInstantPerAttack = value; break; // case ePLAYER_STATUS_DAMAGE_MAGICINSTANTPLUSATTACK: // mDamageCalc.mMagicInstantPlusAttack = value; break; // case ePLAYER_STATUS_DAMAGE_INSTANTPERFINAL: // mDamageCalc.mInstantPerFinal = value; break; // case ePLAYER_STATUS_DAMAGE_INSTANTPLUSFINAL: // mDamageCalc.mInstantPlusFinal = value; break; // } // //} unsigned long cPlayer::DamageCalc( sObject target, unsigned long /*skillIdx*/, unsigned long attributeType, unsigned long rangeType, unsigned long skillDamage, unsigned long skillDamagePer,bool isIgnoreDefence, float addTotalDamage, float addPerTotalDamage ) { //return DAMAGECALC->PlayerDamageCalc( mObject.index, target, (eATTRIBUTETYPE)attributeType, (eRANGETYPE)rType ); unsigned long damage = 0; //// ¿ÀÅä´õ¹Ì ¿¹¿Üó¸® //if( target.type == eOBJECTTYPE_MONSTER ) //{ // cMonster* pMonster = OBJECTMANAGER->GetMonster( target.index ); // if( pMonster != NULL ) // { // if( pMonster->IsAutoDummy() == true ) // return 1; // } // else // NETWORK2->PostServerEvent("cPlayer::DamageCalc pMonster == NULL [%d,%d]", target.type, target.index ); //} /// ±âº»Á¤º¸ unsigned char attackerLv = GetLevel(); unsigned char targetLv = 0; /// ¹°¸® ½ºÅ³ ¼º°øÈ®·ü °è»ê ó¸® if( attributeType == eATTRIBUTETYPE_PHYSICAL ) { unsigned long minAttack = 0; unsigned long maxAttack = 0; /// ±ÙÁ¢ / ¿ø°Å¸® °ø°Ý·Â ±¸ºÐ if( rangeType == eRANGETYPE_CLOSE ) { /// Ç÷¹À̾îÀÇ °ø°Ý·Â ÃÖ¼Ò/ÃÖ´ë°ªÀ» Àоî¿È minAttack = FloatToInt( GetStatus2()->mPhysicMinAttack ); maxAttack = FloatToInt( GetStatus2()->mPhysicMaxAttack ); } else if( rangeType == eRANGETYPE_LONG ) { minAttack = FloatToInt( GetStatus2()->mPhysicMinRangeAttack ); maxAttack = FloatToInt( GetStatus2()->mPhysicMaxRangeAttack ); } else { NETWORK2->PostServerEvent("cDamageCalc::PlayerDamageCalc rangeType[%d,%d,%d,%d] == ERROR", rangeType, mObject.index, GetRace(), GetRaceGender() ); return 0; } /// º¯½ÅÁßÀÌ°í ¹«±â¸¦ Âø¿ëÇϰí ÀÖÀ¸¸é ¹«±âÁ¤º¸¸¦ µû¶ó °ø°Ý·ÂÀ» °áÁ¤ÇÑ´Ù. if( mPlayerExrInfo.mChgMonsterIdx != 0 && mPlayerWeaponState != eWEAPON_STATE_NONE ) { /// ±Ù°Å¸® if( mPlayerWeaponState == eWEAPON_STATE_GUN ) { minAttack = FloatToInt( GetStatus2()->mPhysicMinRangeAttack ); maxAttack = FloatToInt( GetStatus2()->mPhysicMaxRangeAttack ); } else { minAttack = FloatToInt( GetStatus2()->mPhysicMinAttack ); maxAttack = FloatToInt( GetStatus2()->mPhysicMaxAttack ); } } /// °ø°Ý·Â ¹üÀ§¾È¿¡¼­ ¼±Á¤ unsigned long attackerStatusAttack = minAttack; if( minAttack < maxAttack ) { attackerStatusAttack = maxAttack - minAttack; if( attackerStatusAttack > 0 ) attackerStatusAttack = rand() % ( attackerStatusAttack + 1 ); attackerStatusAttack = minAttack + attackerStatusAttack; } /// Ÿ°ÙÀÇ ¹æ¾î·Â »êÃâ unsigned long targetStatusDef = 0; if( target.type == eOBJECTTYPE_MONSTER ) { cMonster* pMonster = OBJECTMANAGER->GetMonster( target.index ); if( pMonster == NULL ) return 0; targetStatusDef = pMonster->GetPhysicDefense(); targetLv = pMonster->GetLevel(); } else if( target.type == eOBJECTTYPE_PLAYER ) { cPlayer* pPlayer = OBJECTMANAGER->GetPlayer( target.index ); if( pPlayer == NULL ) return 0; targetStatusDef = FloatToInt( pPlayer->GetStatus2()->mPhysicDefense ); targetLv = pPlayer->GetLevel(); } else { NETWORK2->PostServerEvent("cDamageCalc::PlayerDamageCalc eATTRIBUTETYPE_PHYSICAL target.type[%d,%d,%d,%d] ERROR", target.type, mObject.index, GetRace(), GetRaceGender() ); return 0; } /// ¹æ¾î·Â DEFENSE_RANDOM_PER °ª¸¸Å­ ·£´ý ¼±Åà unsigned long randTargetDef = 0; if( isIgnoreDefence == false ) randTargetDef = targetStatusDef * ( DEFENSE_RANDOM_PER + ( rand() % ( 100 - DEFENSE_RANDOM_PER + 1 ) ) ) / 100; ///// ·£´ý ¹üÀ§ Á¦°Å - Å×½ºÆ®¿ë //attackerStatusAttack = ( maxAttack + minAttack ) / 2; //randTargetDef = targetStatusDef; damage = DAMAGECALC->PhyDamage500( eOBJECTTYPE_PLAYER, attackerLv, target.type, targetLv, attackerStatusAttack, skillDamage, skillDamagePer, randTargetDef, addTotalDamage, addPerTotalDamage ); } /// ¹°¸® ½ºÅ³ ¼º°øÈ®·ü °è»ê ó¸® else if( attributeType == eATTRIBUTETYPE_MAGIC ) { unsigned long minAttack = 0; unsigned long maxAttack = 0; minAttack = FloatToInt( GetStatus2()->mMagicMinAttack ); maxAttack = FloatToInt( GetStatus2()->mMagicMaxAttack ); /// °ø°Ý·Â ¹üÀ§¾È¿¡¼­ ¼±Á¤ unsigned long attackerStatusAttack = minAttack; if( minAttack < maxAttack ) { /// ¸¶¹ý °ø°Ý·ÂÀ» ÃÖ´ë°ª¿¡¼­ ÃÖ¼Ò°ª »çÀÌ¿¡ ·£´ý °ªÀ¸·Î ¼³Á¤ attackerStatusAttack = maxAttack - minAttack; if( attackerStatusAttack > 0 ) attackerStatusAttack = rand() % ( attackerStatusAttack + 1 ); attackerStatusAttack = minAttack + attackerStatusAttack; } /// Ÿ°ÙÀÇ ¹æ¾î·Â »êÃâ unsigned long targetStatusDef = 0; if( target.type == eOBJECTTYPE_MONSTER ) { cMonster* pMonster = OBJECTMANAGER->GetMonster( target.index ); if( pMonster == NULL ) return 0; targetStatusDef = pMonster->GetMagicDefense(); targetLv = pMonster->GetLevel(); } else if( target.type == eOBJECTTYPE_PLAYER ) { cPlayer* pPlayer = OBJECTMANAGER->GetPlayer( target.index ); if( pPlayer == NULL ) return 0; targetStatusDef = FloatToInt( pPlayer->GetStatus2()->mMagicDefense ); targetLv = pPlayer->GetLevel(); } else { NETWORK2->PostServerEvent("cDamageCalc::PlayerDamageCalc eATTRIBUTETYPE_PHYSICAL target.type[%d,%d,%d,%d] ERROR", target.type, mObject.index, GetRace(), GetRaceGender() ); return 0; } /// ¹æ¾î·Â DEFENSE_RANDOM_PER °ª¸¸Å­ ·£´ý ¼±Åà unsigned long randTargetDef = 0; if( isIgnoreDefence == false ) randTargetDef = targetStatusDef * ( DEFENSE_RANDOM_PER + ( rand() % ( 100 - DEFENSE_RANDOM_PER + 1 ) ) ) / 100; ///// ·£´ý ¹üÀ§ Á¦°Å - Å×½ºÆ®¿ë //attackerStatusAttack = ( maxAttack + minAttack ) / 2; //randTargetDef = targetStatusDef; damage = DAMAGECALC->MagDamage530( eOBJECTTYPE_PLAYER, attackerLv, target.type, targetLv, attackerStatusAttack, skillDamage, skillDamagePer, randTargetDef, addTotalDamage, addPerTotalDamage ); } else { NETWORK2->PostServerEvent("cDamageCalc::PlayerDamageCalc attributeType[%d,%d,%d,%d] ERROR", attributeType, mObject.index, GetRace(), GetRaceGender() ); return 0; } return damage; } unsigned long cPlayer::DotDamageCalc( unsigned char attackerType, unsigned char attackerLv, unsigned long attackMin, unsigned long attackMax, unsigned char dotType, unsigned long skillDamage, unsigned long skillDamagePer, unsigned long totalTime, unsigned long dotTime ) { /// ±âº»Á¤º¸ unsigned long damage = 0; unsigned char targetLv = GetLevel(); switch( dotType ) { case eDOTTYPE_PHYSICALCLOSE: case eDOTTYPE_PHYSICALRANGE: { /// °ø°Ý·Â ¹üÀ§¾È¿¡¼­ ¼±Á¤ unsigned long attackerStatusAttack = attackMin; if( attackMin < attackMax ) { attackerStatusAttack = attackMax - attackMin; if( attackerStatusAttack > 0 ) attackerStatusAttack = rand() % ( attackerStatusAttack + 1 ); attackerStatusAttack = attackMin + attackerStatusAttack; } /// ¹æ¾î·Â »êÃâ unsigned long targetStatusDef = FloatToInt( GetStatus2()->mPhysicDefense ); /// ¹æ¾î·Â DEFENSE_RANDOM_PER °ª¸¸Å­ ·£´ý ¼±Åà targetStatusDef = targetStatusDef * ( DEFENSE_RANDOM_PER + ( rand() % ( 100 - DEFENSE_RANDOM_PER + 1 ) ) ) / 100; damage = DAMAGECALC->PhyDotDamage600( attackerType, attackerLv, mObject.type, targetLv, attackerStatusAttack, skillDamage, skillDamagePer, targetStatusDef, totalTime, dotTime ); } break; case eDOTTYPE_MAGIC: { /// °ø°Ý·Â ¹üÀ§¾È¿¡¼­ ¼±Á¤ unsigned long attackerStatusAttack = attackMin; if( attackMin < attackMax ) { /// ¸¶¹ý °ø°Ý·ÂÀ» ÃÖ´ë°ª¿¡¼­ ÃÖ¼Ò°ª »çÀÌ¿¡ ·£´ý °ªÀ¸·Î ¼³Á¤ attackerStatusAttack = attackMax - attackMin; if( attackerStatusAttack > 0 ) attackerStatusAttack = rand() % ( attackerStatusAttack + 1 ); attackerStatusAttack = attackMin + attackerStatusAttack; } /// Ÿ°ÙÀÇ ¹æ¾î·Â »êÃâ targetLv = GetLevel(); unsigned long targetStatusDef = FloatToInt( GetStatus2()->mMagicDefense ); /// ¹æ¾î·Â DEFENSE_RANDOM_PER °ª¸¸Å­ ·£´ý ¼±Åà targetStatusDef = targetStatusDef * ( DEFENSE_RANDOM_PER + ( rand() % ( 100 - DEFENSE_RANDOM_PER + 1 ) ) ) / 100; damage = DAMAGECALC->MagDotDamage630( attackerType, attackerLv, mObject.type, targetLv, attackerStatusAttack, skillDamage, skillDamagePer, targetStatusDef, totalTime, dotTime ); } break; default: NETWORK2->PostServerEvent("cDamageCalc::DotDamageCalc dotType[%d,%d,%d,%d] ERROR", dotType, mObject.index, GetRace(), GetRaceGender() ); return 0; } return damage; } unsigned long cPlayer::HealCalc( sObject target, long skillHealPlus, long skillHealPer, bool applyHP ) { /// Ç÷¹ÀÌ¾î ´ë Ç÷¹À̾î Èú¸»°í ´Ù¸¥ °æ¿ì°¡ »ý±â¸é ¾î¶² ½ÄÀ» »ç¿ëÇÒÁö Á¤Çϰí Ãß°¡ÇÏÀÚ!! if( target.type != eOBJECTTYPE_PLAYER ) { /// Ç÷¹À̾î ÀÌ¿ÜÀÇ ¿ÀºêÁ§Æ®°¡ ÈúÇÏ´Â ¹æ¹ýÀÌ Á¤ÀǵȰÍÀº ¾ø´Ù. NETWORK2->PostServerEvent("cPlayer::HealCalc target.type ERROR [%d,%d,%d,%d,%d]", target.type, target.index, skillHealPlus, skillHealPer, applyHP ); return 0; } cPlayer* pTarget = OBJECTMANAGER->GetPlayer( target.index ); if( pTarget == NULL ) { NETWORK2->PostServerEvent("cPlayer::HealCalc pTarget == NULL [%d,%d,%d,%d,%d]", target.type, target.index, skillHealPlus, skillHealPer, applyHP ); return 0; } /// ¹æ¾îÀÚ Àåºñ Á¤º¸ sEquipAbility* pItem = pTarget->GetEquipAbility(); if( pItem == NULL ) { NETWORK2->PostServerEvent("cPlayer::HealCalc pItem == NULL [%d,%d,%d,%d,%d]", target.type, target.index, skillHealPlus, skillHealPer, applyHP ); return 0; } /// °ø°ÝÀÚ Á¤º¸ unsigned long randHeal = FloatToInt( GetStatus2()->mHeal ); /// ȸº¹·®À» HEAL_RANDOM_PER °ª¸¸Å­ ·£´ý ¼±Åà randHeal = randHeal * ( HEAL_RANDOM_PER + ( rand() % ( 100 - DEFENSE_RANDOM_PER + 1 ) ) ) / 100; /// Ÿ°Ù ¹öÇÁ Á¤º¸ long targetHealPlus = (long)pTarget->GetStatus2Plus( ePLAYER_STATUS_EXT_RECEIVEHEAL ); long targetHealPer = (long)pTarget->GetStatus2Per( ePLAYER_STATUS_EXT_RECEIVEHEAL ); /// Ÿ°Ù ¾ÆÀÌÅÛ Á¤º¸ long targetItemPlus = pItem->mOptPlusHpReceive; long targetItemPer = pItem->mOptPercentHpReceive; /// ȸº¹(Èú) return DAMAGECALC->HealHP1200( randHeal, skillHealPlus, skillHealPer, targetHealPlus, targetHealPer, targetItemPlus, targetItemPer ); } unsigned long cPlayer::DotHealCalc( sObject target, long infHealPlus, long infHealPer, unsigned long heal, unsigned long dotTotalTime, unsigned long dotTime ) { /// Ç÷¹ÀÌ¾î ´ë Ç÷¹À̾î Èú¸»°í ´Ù¸¥ °æ¿ì°¡ »ý±â¸é ¾î¶² ½ÄÀ» »ç¿ëÇÒÁö Á¤Çϰí Ãß°¡ÇÏÀÚ!! if( target.type != eOBJECTTYPE_PLAYER ) { /// Ç÷¹À̾î ÀÌ¿ÜÀÇ ¿ÀºêÁ§Æ®°¡ ÈúÇÏ´Â ¹æ¹ýÀÌ Á¤ÀǵȰÍÀº ¾ø´Ù. NETWORK2->PostServerEvent("cPlayer::DotHealCalc target.type ERROR [%d,%d,%d,%d,%d,%d,%d]", target.type, target.index, infHealPlus, infHealPer, heal, dotTotalTime, dotTime ); return 0; } /// ȸº¹·®À» HEAL_RANDOM_PER °ª¸¸Å­ ·£´ý ¼±Åà unsigned long randHeal = heal * ( HEAL_RANDOM_PER + ( rand() % ( 100 - DEFENSE_RANDOM_PER + 1 ) ) ) / 100; /// ȸº¹(Èú) return DAMAGECALC->DotHealHP1230( randHeal, infHealPlus, infHealPer, dotTotalTime, dotTime ); } unsigned long cPlayer::ConditionOdd( sObject target, long influenceRate, unsigned long skillClassIdx ) { cBaseObject* pTarget = OBJECTMANAGER->GetObject( target.type, target.index ); if( pTarget == NULL ) { NETWORK2->PostServerEvent("cPlayer::ConditionOdd pTarget == NULL[%d,%d,%d,%d]", target.type, target.index, influenceRate, skillClassIdx ); return 0; } /// Ç÷¹ÀÌ¾î ½ºÅ©¸³Æ® ·Îµå sPlayerSkillBaseInfo* pPlayerSkill = SKILLSCRIPT->GetPlayerSkillInfo( skillClassIdx ); if( pPlayerSkill == NULL ) { NETWORK2->PostServerEvent("cPlayer::ConditionOdd pPlayerSkill == NULL[%d,%d,%d,%d]", target.type, target.index, influenceRate, skillClassIdx ); return 0; } /// °ø°ÝÀÚ ·¹º§, Ÿ°Ù ·¹º§ unsigned char attackerLv = GetLevel(); unsigned char targetLv = pTarget->GetLevel(); unsigned long checkPer = 0; if( pPlayerSkill->mAttributeType == eATTRIBUTETYPE_PHYSICAL ) checkPer = DAMAGECALC->PhyConditionOdd900( influenceRate, attackerLv, targetLv ); else if( pPlayerSkill->mAttributeType == eATTRIBUTETYPE_MAGIC ) checkPer = DAMAGECALC->MagConditionOdd930( influenceRate, attackerLv, targetLv ); else { NETWORK2->PostServerEvent("cPlayer::ConditionOdd pPlayerSkill->mAttributeType[%d][%d,%d,%d,%d] ERROR", pPlayerSkill->mAttributeType, target.type, target.index, influenceRate, skillClassIdx ); } return checkPer; } bool cPlayer::AttackSuccess( sObject target, unsigned long attributeType, short accuracyValue, unsigned long instantSuccess, unsigned long instantSuccessPer ) { /// return DAMAGECALC->PlayerAttackSuccess( mObject.index, target, (eATTRIBUTETYPE)aType, accuracyValue ); /// ±âº»Á¤º¸ unsigned char attackerLv = GetLevel(); unsigned char targetLv = 0; /// ¹°¸® ½ºÅ³ ¼º°øÈ®·ü °è»ê ó¸® if( attributeType == eATTRIBUTETYPE_PHYSICAL ) { /// °ø°ÝÀÚ ½ºÅݼº°ø¼öÄ¡ unsigned long attackerStatusRate = FloatToInt( GetStatus2()->mPhysicAttackRate ); /// Ÿ°Ù ȸÇÇ ¼öÄ¡ unsigned long targetStatusAvoid = 0; /// Ÿ°Ù(¸ó½ºÅÍ) if( target.type == eOBJECTTYPE_MONSTER ) { cMonster* pMonster = OBJECTMANAGER->GetMonster( target.index ); if( pMonster == NULL ) { NETWORK2->PostServerEvent("cPlayer::AttackSuccess pMonster[%d] == NULL", target.index ); return false; } targetLv = pMonster->GetLevel(); targetStatusAvoid = pMonster->GetPhysicAvoid(); } /// Ÿ°Ù(Ç÷¹À̾î) else if( target.type == eOBJECTTYPE_PLAYER ) { cPlayer* pTargetPlayer = OBJECTMANAGER->GetPlayer( target.index ); if( pTargetPlayer == NULL ) { NETWORK2->PostServerEvent("cPlayer::AttackSuccess pTargetPlayer[%d] == NULL", target.index ); return false; } targetLv = pTargetPlayer->GetLevel(); targetStatusAvoid = FloatToInt( pTargetPlayer->GetStatus2()->mPhysicAvoid ); } else { NETWORK2->PostServerEvent("cPlayer::AttackSuccess physical target.type[%d] ERROR", target.type ); return false; } /// ¼º°øÀ² ÆÛ¼¾Æ® ¼öÄ¡ ȯ»ê unsigned long resultSuccess = DAMAGECALC->PhyAttackSuccess100( attackerStatusRate, targetStatusAvoid, accuracyValue, eOBJECTTYPE_PLAYER, attackerLv, targetLv, instantSuccess, instantSuccessPer ); /// È®·üüũ unsigned long randvalue = (unsigned long)(RANDOMTABLE->Get( ) * 100 + 1); if( randvalue > resultSuccess ) return false; } else if( attributeType == eATTRIBUTETYPE_MAGIC ) /// ¸¶¹ý ½ºÅ³ ¼º°øÈ®·ü °è»ê ó¸® { /// °ø°ÝÀÚ ½ºÅݼº°ø¼öÄ¡ unsigned long attackerStatusRate = FloatToInt( GetStatus2()->mMagicAttackRate ); /// Ÿ°Ù ȸÇÇ ¼öÄ¡ unsigned long targetStatusAvoid = 0; /// Ÿ°Ù(¸ó½ºÅÍ) if( target.type == eOBJECTTYPE_MONSTER ) { cMonster* pMonster = OBJECTMANAGER->GetMonster( target.index ); if( pMonster == NULL ) { NETWORK2->PostServerEvent("cPlayer::AttackSuccess pMonster[%d] == NULL", target.index ); return false; } targetStatusAvoid = pMonster->GetMagicAvoid(); targetLv = pMonster->GetLevel(); } /// Ÿ°Ù(Ç÷¹À̾î) else if( target.type == eOBJECTTYPE_PLAYER ) { cPlayer* pTargetPlayer = OBJECTMANAGER->GetPlayer( target.index ); if( pTargetPlayer == NULL ) { NETWORK2->PostServerEvent("cPlayer::AttackSuccess pTargetPlayer[%d] == NULL", target.index ); return false; } targetStatusAvoid = FloatToInt( pTargetPlayer->GetStatus2()->mMagicAvoid ); targetLv = pTargetPlayer->GetLevel(); } else { NETWORK2->PostServerEvent("cPlayer::AttackSuccess magic target.type[%d] ERROR", target.type ); return false; } /// ¼º°øÀ² ÆÛ¼¾Æ® ¼öÄ¡ ȯ»ê unsigned long resultSuccess = DAMAGECALC->MagAttackSuccess130( attackerStatusRate, targetStatusAvoid, accuracyValue, eOBJECTTYPE_PLAYER, attackerLv, targetLv, instantSuccess, instantSuccessPer ); /// È®·üüũ unsigned long randvalue = (unsigned long)(RANDOMTABLE->Get( ) * 100 + 1); if( randvalue > resultSuccess ) return false; } else { NETWORK2->PostServerEvent("cPlayer::AttackSuccess attributeType[%d] ERROR", attributeType ); return false; } return true; } bool cPlayer::CriticalSuccess( sObject target, unsigned long attributeType, unsigned short criticalValue, unsigned long instantCri, unsigned long instantCriPer ) { //return DAMAGECALC->PlayerCritical( mObject.index, target, (eATTRIBUTETYPE)attributeType, criticalValue ); cBaseObject* pTarget = OBJECTMANAGER->GetObject( target.type, target.index ); if( pTarget == NULL ) { NETWORK2->PostServerEvent("cPlayer::CriticalSuccess pTarget[%d,%d] == NULL", target.type, target.index ); return false; } sEquipAbility* pItem = GetEquipAbility(); if( pItem == NULL ) { NETWORK2->PostServerEvent("cPlayer::CriticalSuccess pItem[%d,%d] == NULL", target.type, target.index ); return false; } /// ±âº»Á¤º¸ unsigned char attackerLv = GetLevel(); unsigned char targetLv = pTarget->GetLevel(); unsigned long criSuccess = 0; /// ¹°¸® ½ºÅ³ ¼º°øÈ®·ü °è»ê ó¸® if( attributeType == eATTRIBUTETYPE_PHYSICAL ) { unsigned long attackerStatusCri = FloatToInt( GetStatus2()->mPhysicCritical ); long attackerPer = FloatToInt( GetStatus2Per( ePLAYER_STATUS_EXT_CRI ) ); long attackerItemPer = pItem->mOptPercentPhysicCritical; long attackerPlus = FloatToInt( GetStatus2Plus( ePLAYER_STATUS_EXT_CRI ) ); long attackerItemPlus = pItem->mOptPlusPhysicCritical; float targetCriDef = 0.0f; if( target.type == eOBJECTTYPE_PLAYER ) { cPlayer* pPlayerTarget = (cPlayer*)pTarget; sEquipAbility* pTargetItem = pPlayerTarget->GetEquipAbility(); if( pTargetItem == NULL ) { NETWORK2->PostServerEvent("cPlayer::CriticalSuccess eATTRIBUTETYPE_PHYSICAL pTargetItem[%d,%d] == NULL", target.type, target.index ); return false; } targetCriDef = pPlayerTarget->GetStatus2()->mPhyCriDef; } else if( target.type == eOBJECTTYPE_MONSTER ) { float num201 = STATUSSCRIPT->GetDamageCalcNumericalInfo( 201 ); float num204 = STATUSSCRIPT->GetDamageCalcNumericalInfo( 204 ); cMonster* pMonsterTarget = (cMonster*)pTarget; float targetCriDefPlus = pMonsterTarget->GetStatusPlus()->mPhysicCriticalDef; float targetCriDefPer = pMonsterTarget->GetStatusPer()->mPhysicCriticalDef; //¸ó½ºÅÍÀÇ °æ¿ì //A = [°ø°ÝÀÚ] ij¸¯ÅÍ ½ºÅÈ ¹°¸® Å©¸®Æ¼Äà ¼öÄ¡ * {num201} //D = A //[E] = D * ((100 + [¹æ¾îÀÚ]¾ÆÀÌÅÛ ¹°¸® ¹æÈ£[%]°ª + [¹æ¾îÀÚ]¹öÇÁ¼º ¹°¸® ¹æÈ£ [%]°ª) / 100) + ( ([¹æ¾îÀÚ]¾ÆÀÌÅÛ ¹°¸® ¹æÈ£ ¼öÄ¡[+-]°ª + [¹æ¾îÀÚ]¹öÇÁ¼º ¹°¸® ¹æÈ£ ¼öÄ¡[+-]°ª) * {num204} ) float valueD = (float)attackerStatusCri * num201; targetCriDef = valueD * (( 100.0f + 0.0f + targetCriDefPer ) / 100.0f ) + ( ( 0.0f + targetCriDefPlus ) * num204 ); } else { NETWORK2->PostServerEvent("cPlayer::CriticalSuccess eATTRIBUTETYPE_PHYSICAL target.type ERROR [%d,%d][%d,%d]", target.type, target.index, attributeType, criticalValue ); return false; } criSuccess = DAMAGECALC->PhyCritical200( attackerStatusCri, criticalValue, attackerLv, targetLv, attackerPer, attackerItemPer, attackerPlus, attackerItemPlus, targetCriDef, instantCri, instantCriPer ); } else if( attributeType == eATTRIBUTETYPE_MAGIC ) { unsigned long attackerStatusCri = FloatToInt( GetStatus2()->mMagicCritical ); long attackerPer = FloatToInt( GetStatus2Per( ePLAYER_STATUS_EXT_MCRI ) ); long attackerItemPer = pItem->mOptPercentMagicCritical; long attackerPlus = FloatToInt( GetStatus2Plus( ePLAYER_STATUS_EXT_MCRI ) ); long attackerItemPlus = pItem->mOptPlusMagicCritical; float targetCriDef = 0.0f; if( target.type == eOBJECTTYPE_PLAYER ) { cPlayer* pPlayerTarget = (cPlayer*)pTarget; sEquipAbility* pTargetItem = pPlayerTarget->GetEquipAbility(); if( pTargetItem == NULL ) { NETWORK2->PostServerEvent("cPlayer::CriticalSuccess eATTRIBUTETYPE_MAGIC pTargetItem[%d,%d] == NULL", target.type, target.index ); return false; } targetCriDef = pPlayerTarget->GetStatus2()->mMagCriDef; } else if( target.type == eOBJECTTYPE_MONSTER ) { float num231 = STATUSSCRIPT->GetDamageCalcNumericalInfo( 231 ); float num234 = STATUSSCRIPT->GetDamageCalcNumericalInfo( 234 ); cMonster* pMonsterTarget = (cMonster*)pTarget; float targetCriDefPlus = pMonsterTarget->GetStatusPlus()->mMagicCriticalDef; float targetCriDefPer = pMonsterTarget->GetStatusPer()->mMagicCriticalDef; //¸ó½ºÅÍÀÇ °æ¿ì //A = [°ø°ÝÀÚ] ij¸¯ÅÍ ½ºÅÈ ¸¶¹ý Å©¸®Æ¼Äà ¼öÄ¡ * {num231} //D = A //[E] = D * ((100 + [¹æ¾îÀÚ]¾ÆÀÌÅÛ ¸¶¹ý ¹æÈ£[%]°ª + [¹æ¾îÀÚ]¹öÇÁ¼º ¸¶¹ý ¹æÈ£ [%]°ª) / 100) + ( ([¹æ¾îÀÚ]¾ÆÀÌÅÛ ¸¶¹ý ¹æÈ£ ¼öÄ¡[+-]°ª + [¹æ¾îÀÚ]¹öÇÁ¼º ¸¶¹ý ¹æÈ£ ¼öÄ¡[+-]°ª) * {num234} ) float valueD = (float)attackerStatusCri * num231; targetCriDef = valueD * (( 100.0f + 0.0f + targetCriDefPer ) / 100.0f ) + ( ( 0.0f + targetCriDefPlus ) * num234 ); } else { NETWORK2->PostServerEvent("cPlayer::CriticalSuccess eATTRIBUTETYPE_MAGIC target.type ERROR [%d,%d][%d,%d]", target.type, target.index, attributeType, criticalValue ); return false; } criSuccess = DAMAGECALC->MagCritical230( attackerStatusCri, criticalValue, attackerLv, targetLv, attackerPer, attackerItemPer, attackerPlus, attackerItemPlus, targetCriDef, instantCri, instantCriPer ); } else { NETWORK2->PostServerEvent("cPlayer::CriticalSuccess attributeType[%d] ERROR", attributeType ); return false; } /// È®·üüũ unsigned long randvalue = (unsigned long)(RANDOMTABLE->Get( ) * 100 + 1); if( randvalue > criSuccess ) return false; return true; } //void cPlayer::CalcInstantSkill( unsigned long statusType1, unsigned long value1, unsigned long statusType2, unsigned long value2 ) //{ // for( int i = ePLAYER_STATUS_DAMAGE_INSTANTPERHIT ; i < ePLAYER_STATUS_DAMAGE_MAX ; ++i ) // SetDamageCalc( (ePLAYER_STATUS_DAMAGE)i, 0 ); // // eSTATUS_PLUS statusType = (eSTATUS_PLUS)statusType1; // unsigned long value = value1; // unsigned long arrayNum = 0; // // if( statusType != 0 ) // { // if( eSTATUSPLUS_INSTANTPERHIT <= statusType && statusType < eSTATUSPLUS_DAMAGECALC_MAX ) // { // arrayNum = statusType - eSTATUSPLUS_INSTANTPERHIT; // SetDamageCalc( (ePLAYER_STATUS_DAMAGE)arrayNum, value ); // } // } // // statusType = (eSTATUS_PLUS)statusType2; // value = value2; // // if( statusType != 0 ) // { // /// ŸÀÔ1, ŸÀÔ2°¡ °°À¸¸é ´õÇØ¼­ ³Ö´Â´Ù. // if( statusType1 == statusType2 ) // { // NETWORK2->PostServerEvent(" Player::CalcInstantSkill [%d,%d] statusType1 == statusType2", statusType1, statusType2 ); // value = value1 + value2; // } // // if( eSTATUSPLUS_INSTANTPERHIT <= statusType && statusType < eSTATUSPLUS_DAMAGECALC_MAX ) // { // arrayNum = statusType - eSTATUSPLUS_INSTANTPERHIT; // SetDamageCalc( (ePLAYER_STATUS_DAMAGE)arrayNum, value ); // } // } //} float cPlayer::CalcStatusSkillRange( float skillRange, eRANGETYPE mRangeType, bool IsNormalAttack ) { /// ½ºÅ³ »ç°Å¸® float range = skillRange; /// È¿°ú »ç°Å¸® float statusRangePlus = 0; float statusRangePer = 0; if( mRangeType == eRANGETYPE_CLOSE ) { statusRangePlus = GetStatus2Plus( ePLAYER_STATUS_EXT_RANGE ) + mEquipAbility.mOptPlusShortRange; statusRangePer = GetStatus2Per( ePLAYER_STATUS_EXT_RANGE ) + mEquipAbility.mOptPercentShortRange; } else if( mRangeType == eRANGETYPE_LONG ) { statusRangePlus = GetStatus2Plus( ePLAYER_STATUS_EXT_RRANGE ) + mEquipAbility.mOptPlusDistanceRange; statusRangePer = GetStatus2Per( ePLAYER_STATUS_EXT_RRANGE ) + mEquipAbility.mOptPercentDistanceRange; } else assert(NULL); /// »ç°Å¸® °è»ê // ÀÏ¹Ý °ø°Ý if( IsNormalAttack == true ) range = ( range + mEquipAbility.mAttackRange ) * ( ( 100 + statusRangePer ) / 100 ) + statusRangePlus; // ½ºÅ³ °ø°Ý else range = range * ( ( 100 + statusRangePer ) / 100 ) + statusRangePlus; return range; } unsigned short cPlayer::GetMoveSpeed( ) { unsigned short moveSpeed = (unsigned short)FloatToInt( mStatus2.mMoveSpeed ); if( moveSpeed < 0 ) { assert(NULL); NETWORK2->PostServerEvent("cPlayer::GetMoveSpeed( ) <= 0"); moveSpeed = 1; } return moveSpeed; } unsigned short cPlayer::GetMoveUpdateSpeed( unsigned long accumTime ) { unsigned short moveSpeed = GetMoveSpeed(); /// Á¡ÇÁ ½ÃÀÛ ¸ð¼ÇÁß if( mJumpSpeedState == 1 ) { if( mJumpMoveSpeedDownEndTime > accumTime ) moveSpeed = 10; else { mJumpMoveSpeedDownEndTime = 0; mJumpSpeedState = 2; } } /// Á¡ÇÁÇØ¼­ °øÁß¿¡ ¶°¼­ À̵¿ÇÏ´Â Áß if( mJumpEndTime < accumTime && mJumpSpeedState == 2 ) { /// ÀüüÀûÀ¸·Î °¡Àå ¸¹ÀÌ ºÐÆ÷ÇÑ ÂøÁö Á¤Áö ½Ã°£ mJumpMoveSpeedDownEndTime = NETWORK2->GetAccumTime() + 234; /// Å»°Í Àΰæ¿ì if( mVehicleInfIdx != 0 ) { mJumpMoveSpeedDownEndTime = NETWORK2->GetAccumTime() + 267; } else if( mPlayerExrInfo.mChgMonsterIdx != 0 ) { mJumpMoveSpeedDownEndTime = NETWORK2->GetAccumTime() + 234; } else { /// Á¾Á· º°·Î ½Ã°£¼³Á¤ switch ( mPlayerInfo.Race ) { case eRACE_HUMAN: mJumpMoveSpeedDownEndTime = NETWORK2->GetAccumTime() + 200; break; case eRACE_BEAST: mJumpMoveSpeedDownEndTime = NETWORK2->GetAccumTime() + 234; break; case eRACE_ELF: mJumpMoveSpeedDownEndTime = NETWORK2->GetAccumTime() + 234; break; } } mJumpSpeedState = 3; } /// Á¡ÇÁ ÂøÁö ¸ð¼ÇÁß if( mJumpSpeedState == 3 ) { if( mJumpMoveSpeedDownEndTime > accumTime ) moveSpeed = 10; else { mJumpMoveSpeedDownEndTime = 0; mJumpSpeedState = 0; } } return moveSpeed; } bool cPlayer::IsChangeState( unsigned int newState, eCHANGESTATE_OPTION option ) { if( !( newState == eOBJECT_STATE_IDLE || newState == eOBJECT_STATE_MOVE || newState == eOBJECT_STATE_DIE || newState == eOBJECT_STATE_PUSHPULL || newState == ePLAYER_STATE_RUSH ) ) { /// °ÔÀÓ¼­¹ö¸¦ ²ô´ÂÁß¿£ Åë°ú½ÃŲ´Ù. if( ( newState == eOBJECT_STATE_STOP && mPlayerExrInfo.mStateStop == eSTOP_GAMEFINISH ) == false ) { unsigned long accumTime = NETWORK2->GetAccumTime(); if( mJumpEndTime > accumTime ) return false; } } switch( mPlayerExrInfo.mState ) { case ePLAYER_STATE_SITDOWN: case eOBJECT_STATE_IDLE: case eOBJECT_STATE_MOVE: case ePLAYER_STATE_ITEMPICK: /// ¾ÆÀÌÅÛ Áý´Â Áß¿¡ ¸ðµç »óÅ °¡´É break; case eOBJECT_STATE_STOP: { /// Á¤ÁöÁß¿¡ Á×´Â »óÅÂ, ´ë±â »óÅ·θ¸ º¯°æ°¡´É if( newState == eOBJECT_STATE_DIE || newState == eOBJECT_STATE_IDLE || newState == eOBJECT_STATE_PUSHPULL ) break; return false; } break; case ePLAYER_STATE_GATHERING: { /// äÁýÁß¿¡ Á×´Â »óÅÂ, ´ë±â »óÅ·θ¸ º¯°æ°¡´É if( newState == eOBJECT_STATE_DIE || newState == eOBJECT_STATE_IDLE || newState == ePLAYER_STATE_ITEMPICK || newState == eOBJECT_STATE_PUSHPULL ) break; return false; } break; case eOBJECT_STATE_ATTACK: { /// °ø°ÝÁß¿¡ Á×´Â »óÅÂ, ´ë±â »óÅ·θ¸ º¯°æ°¡´É if( newState == eOBJECT_STATE_DIE || newState == eOBJECT_STATE_IDLE || newState == eOBJECT_STATE_PUSHPULL ) break; return false; } break; case eOBJECT_STATE_PUSHPULL: { if( newState == eOBJECT_STATE_IDLE ) break; if( newState == eOBJECT_STATE_DIE ) { //NETWORK2->PostServerEvent("cPlayer::IsChangeState mState == eOBJECT_STATE_PUSHPULL newState == eOBJECT_STATE_DIE"); break; } return false; } break; case ePLAYER_STATE_RUSH: { /// µ¹Áø¿¡ Á×´Â »óÅÂ, ´ë±â »óÅ·θ¸ º¯°æ°¡´É if( newState == eOBJECT_STATE_DIE || newState == eOBJECT_STATE_IDLE || newState == eOBJECT_STATE_PUSHPULL ) break; if( newState == eOBJECT_STATE_ATTACK && option == eCHANGESTATEOPTION_RUSH ) break; return false; } case eOBJECT_STATE_DIE: { /// Á×Àº »óÅ¿¡¼­ »ì¾Æ³ª´Â(IDLE) »óÅ·θ¸ º¯°æ°¡´É if( newState == eOBJECT_STATE_IDLE && option == eCHANGESTATEOPTION_RESURRECTION ) break; return false; } break; default: return false; } return true; } bool cPlayer::ChangeState( unsigned int newState, eCHANGESTATE_OPTION option ) { mVehicleAttack = false; /// º¯°æ °¡´ÉÇÑÁö üũ if( IsChangeState( newState, option ) == false ) return false; /// ±âÁ¸ »óÅ¿¡¼­ ´Ù¸¥ »óÅ·Πº¯ÇÏ´Â °æ¿ì switch( mPlayerExrInfo.mState ) { case eOBJECT_STATE_STOP: { if ( newState == eOBJECT_STATE_DIE || newState == eOBJECT_STATE_PUSHPULL ) { /// »óÅ¿¡ µû¸¥ Á¤¸®. switch ( GetStateStop( ) ) { case eSTOP_READYTAROT: case eSTOP_OPENTAROT: TarotReaderDie( ); break; case eSTOP_ENTERTAROT: case eSTOP_USETAROT: TarotSeekerDie( ); break; case eSTOP_OPENSTALL: StallSellOpenDie( ); break; case eSTOP_USESTALL: StallSellUseDie( ); break; } } /// Á¤Áö»óÅ ¼¼ºÎ°ªÀ» NONE À¸·Î ¹Ù²Þ SetStateStop( eSTOP_NONE ); } break; case eOBJECT_STATE_DIE: { /// ºÎȰ º¯¼ö¸¦ ÃʱâÈ­ mIsSkillResurrection = false; mSkillResurrectionHP = 0; mSkillResurrectionMP = 0; mCheckRushSkillIdx = 0; mCheckRushSkillStep = 0; mNextRecoveryTime = NETWORK2->GetAccumTime() + NATURE_RECOVERY_TIME; } break; case ePLAYER_STATE_SITDOWN: { mNextRecoveryTime = NETWORK2->GetAccumTime() + NATURE_RECOVERY_TIME; } break; case eOBJECT_STATE_MOVE: { mJumpMoveSpeedDownEndTime = 0; mJumpSpeedState = 0; } break; case eOBJECT_STATE_ATTACK: { mCheckRushSkillIdx = 0; mCheckRushSkillStep = 0; } break; } /// ½Å±Ô »óŰ¡ À̵¿ÀÌ ¾Æ´Ñ °æ¿ì À̵¿ ÁßÀÌ´ø ¸ñÇ¥°ª ÃʱâÈ­ ÇØÁØ´Ù. if( newState != eOBJECT_STATE_MOVE && newState != eOBJECT_STATE_PUSHPULL && newState != ePLAYER_STATE_RUSH ) { MoveStop(); } /// ½Å±Ô »óÅÂó¸® switch( newState ) { case eOBJECT_STATE_STOP: { ExchangeCancel( true ); } break; case eOBJECT_STATE_DIE: { /// ¸ó½ºÅͰ¡ ÂѾƿÀ´Â ºñÁßÀ» Ŭ¸®¾î ½ÃŲ´Ù. mMonsterImportance = 0; /// npc¶û ´ëÈ­ ÁßÀ̾úÀ¸¸é ´ëÈ­¸¦ ÃʱâÈ­ÇÑ´Ù. mNpcIdx = 0; mPvPDieTime = NETWORK2->GetAccumTime(); mPvPDieEndTime = mPvPDieTime + PVP_DM_RESURRECTION_TIME - SYNC_MOVE_TIME; /// ÃßÀû À§Ä¡ Ŭ¸®¾î memset( mFollowPos, 0, sizeof(mFollowPos) ); /// È¿°ú¸¦ Á¦°ÅÇÑ´Ù. DieDeleteInfluence(); /// Ÿ°ÙÀ¸·Î ÀâÀ» ¸ó½ºÅÍ¿¡°Ô Àü´Þ DietargetingMonster(); /// äÁý ÁßÀÌ´ø ¸ñ·Ï¿¡¼­ Ç÷¹À̾î Á¦°Å cGathering* pGathering = OBJECTMANAGER->GetGathering( mGatheringIdx ); if( pGathering != NULL ) pGathering->EraseGatherPlayer( this ); mGatheringIdx = 0; // °Å·¡ »óÅÂÀ϶§ Ç®¾îÁÖ±â ExchangeCancel( false ); // ½Åû °ü·Ã Ãë¼Ò ó¸® EndRequestRejectionAll(); } break; case eOBJECT_STATE_PUSHPULL: { /// npc¶û ´ëÈ­ ÁßÀ̾úÀ¸¸é ´ëÈ­¸¦ ÃʱâÈ­ÇÑ´Ù. mNpcIdx = 0; /// äÁý ÁßÀÌ´ø ¸ñ·Ï¿¡¼­ Ç÷¹À̾î Á¦°Å cGathering* pGathering = OBJECTMANAGER->GetGathering( mGatheringIdx ); if( pGathering != NULL ) pGathering->EraseGatherPlayer( this ); mGatheringIdx = 0; // °Å·¡ »óÅÂÀ϶§ Ç®¾îÁÖ±â ExchangeCancel( false ); } break; case ePLAYER_STATE_RUSH: { // ÆòÈ­ ´ë±â Ç®¸² mPlayerExrInfo.mStateIdle = eIDLE_NORMAL; if( mPlayerExrInfo.mVehicleIdx != 0 ) { NETWORK2->PostServerEvent("cPlayer::ChangeState eOBJECT_STATE_ATTACK mPlayerExrInfo.mVehicleIdx[%d,%d][%d] != 0", mObject.index, mPlayerExrInfo.mState, mPlayerExrInfo.mVehicleIdx ); SKILLMANAGER->DeleteInfluence( mObject, mVehicleInfIdx ); mVehicleAttack = true; } } break; case eOBJECT_STATE_ATTACK: { // ÆòÈ­ ´ë±â Ç®¸² mPlayerExrInfo.mStateIdle = eIDLE_NORMAL; if( mPlayerExrInfo.mVehicleIdx != 0 ) { NETWORK2->PostServerEvent("cPlayer::ChangeState eOBJECT_STATE_ATTACK mPlayerExrInfo.mVehicleIdx[%d,%d][%d] != 0", mObject.index, mPlayerExrInfo.mState, mPlayerExrInfo.mVehicleIdx ); SKILLMANAGER->DeleteInfluence( mObject, mVehicleInfIdx ); mVehicleAttack = true; } } break; case ePLAYER_STATE_SITDOWN: { /// ¾É±â ½ÃÀ۽𣠼³Á¤ - 10ÃÊ ÈĺÎÅÍ ÀÚ¿¬È¸º¹ 2¹è mNextRecoveryTime = NETWORK2->GetAccumTime() + SITDOWN_RECOVERY_TIME; if( mPlayerExrInfo.mVehicleIdx != 0 ) { NETWORK2->PostServerEvent("cPlayer::ChangeState ePLAYER_STATE_SITDOWN mPlayerExrInfo.mVehicleIdx[%d,%d][%d] != 0", mObject.index, mPlayerExrInfo.mState, mPlayerExrInfo.mVehicleIdx ); SKILLMANAGER->DeleteInfluence( mObject, mVehicleInfIdx ); } } break; case ePLAYER_STATE_ITEMPICK: { if( mPlayerExrInfo.mVehicleIdx != 0 ) { NETWORK2->PostServerEvent("cPlayer::ChangeState ePLAYER_STATE_ITEMPICK mPlayerExrInfo.mVehicleIdx[%d,%d][%d] != 0", mObject.index, mPlayerExrInfo.mState, mPlayerExrInfo.mVehicleIdx ); SKILLMANAGER->DeleteInfluence( mObject, mVehicleInfIdx ); } } break; case ePLAYER_STATE_GATHERING: { if( mPlayerExrInfo.mVehicleIdx != 0 ) { NETWORK2->PostServerEvent("cPlayer::ChangeState ePLAYER_STATE_GATHERING mPlayerExrInfo.mVehicleIdx[%d,%d][%d] != 0", mObject.index, mPlayerExrInfo.mState, mPlayerExrInfo.mVehicleIdx ); SKILLMANAGER->DeleteInfluence( mObject, mVehicleInfIdx ); } } break; } /// »óÅ º¯°æ mPlayerExrInfo.mState = (unsigned char)newState; return true; } void cPlayer::ShutdownChangeState() { if( mPlayerExrInfo.mState != eOBJECT_STATE_STOP || mPlayerExrInfo.mStateStop != eSTOP_GAMEFINISH || mIsRequestRejection != eREQREJCT_GAMEFINISH ) { NETWORK2->PostServerEvent("cPlayer::ShutdownChangeState( %d[%d,%d,%d] )", mObject.index, mPlayerExrInfo.mState, mPlayerExrInfo.mStateStop, mIsRequestRejection ); } mPlayerExrInfo.mState = eOBJECT_STATE_STOP; mPlayerExrInfo.mStateStop = eSTOP_GAMEFINISH; mIsRequestRejection = eREQREJCT_GAMEFINISH; } void cPlayer::Resurrection( unsigned long resurrectionType ) { unsigned char errorCode = ERROR_PLAYER_RESURRECTION_SUCCESS; unsigned long expDown = 0; bool cashUse = false; unsigned long infIdx = 0; unsigned char cashExpCnt = 0; bool addInf = false; /// Á×¾ú´ÂÁö È®ÀÎ if( GetStateDie() == true ) { /// ½ºÅ³¿¡ ÀÇÇÑ ºÎȰ¿©ºÎ if( resurrectionType == eRESURRECTIONTYPE_SKILL ) { if( SkillResurrection() == false ) errorCode = ERROR_PLAYER_RESURRECTION_FAIL; else { if( NETWORK2->GetServerType() == _E_ST_ID_THEME_ ) expDown = ExpDown( RESURRECTION_THEME_EXP_SKILL_MIN, RESURRECTION_THEME_EXP_SKILL_MAX ); else { if( mPlayerInfo.Level >= 10 && mHeroInfo.Exp != 0 ) { if( CalcCashExpGuard( &infIdx, &cashExpCnt ) == true ) { cashUse = true; expDown = 0; } else expDown = ExpDown( RESURRECTION_EXP_SKILL_MIN, RESURRECTION_EXP_SKILL_MAX ); } } } } else { if( ChangeState( eOBJECT_STATE_IDLE, eCHANGESTATEOPTION_RESURRECTION ) == false ) { assert(NULL); NETWORK2->PostServerEvent("Player[%d] Resurrection ChangeState( eOBJECT_STATE_IDLE, true ) == false", mObject.index ); } InitHP( 10 ); InitMP( 10 ); /// °æÇèÄ¡ Ç϶ô switch( resurrectionType ) { case eRESURRECTIONTYPE_STAND: /// Á¦ÀÚ¸® ºÎȰ { if( mPlayerInfo.Level >= 10 ) { if( NETWORK2->GetServerType() == _E_ST_ID_THEME_ ) { errorCode = ERROR_PLAYER_RESURRECTION_FAIL; NETWORK2->PostServerEvent("cPlayer::Resurrection eRESURRECTIONTYPE_STAND _E_ST_ID_THEME_[%d,%d,%d,]", mObject.index, mPlayerExrInfo.mState, mPlayerExrInfo.mStateStop ); } else { if( mPlayerInfo.Level >= 10 && mHeroInfo.Exp != 0 ) { if( CalcCashExpGuard( &infIdx, &cashExpCnt ) == true ) { cashUse = true; expDown = 0; } else expDown = ExpDown( RESURRECTION_EXP_STAND_MIN, RESURRECTION_EXP_STAND_MAX ); } } addInf = true; } } break; case eRESURRECTIONTYPE_SAFE: /// ¾ÈÀüÁö´ë ºÎȰ { switch( NETWORK2->GetServerType() ) { case _E_ST_NORMAL_MAP_: { NiPoint2 pos = STAGESCRIPT->CalcNearTargetMapPos( mMapNumber, mObjectPos.x, mObjectPos.y ); mObjectPos.x = pos.x; mObjectPos.y = pos.y; float safeMin = RESURRECTION_EXP_SAFE_MIN; float safeMax = RESURRECTION_EXP_SAFE_MAX; if( mPlayerInfo.Level >= 10 && mHeroInfo.Exp != 0 ) { if( CalcCashExpGuard( &infIdx, &cashExpCnt ) == true ) { cashUse = true; expDown = 0; } else expDown = ExpDown( safeMin, safeMax ); } } break; case _E_ST_ID_THEME_: { sTargetPos pos = STAGESCRIPT->GetStageChangePos( THEMEMANAGER->GetStartPosIdx() ); if( pos.mMapNumber != 0 && pos.mMapNumber == mInDunMapDataNum ) { mObjectPos.x = pos.mPosX; mObjectPos.y = pos.mPosY; float safeMin = RESURRECTION_THEME_EXP_SAFE_MIN; float safeMax = RESURRECTION_THEME_EXP_SAFE_MAX; if( mPlayerInfo.Level >= 10 && mHeroInfo.Exp != 0 ) expDown = ExpDown( safeMin, safeMax ); } else { NETWORK2->PostServerEvent("cPlayer::Resurrection NETWORK2->GetServerType() == _E_ST_ID_PVP_[%d]", mInDunMapDataNum ); } } break; case _E_ST_ID_PVP_: { NETWORK2->PostServerEvent("cPlayer::Resurrection NETWORK2->GetServerType() == _E_ST_ID_PVP_[%d]", mInDunMapDataNum ); } break; case _E_ST_ID_TUTORIAL_: { NETWORK2->PostServerEvent("cPlayer::Resurrection NETWORK2->GetServerType() == _E_ST_ID_TUTORIAL_" ); } break; } ClearMoveSyncCalc(); } break; } } } else { NETWORK2->PostServerEvent("cPlayer::Resurrection GetStateDie_%d_%d,%d,%d_%d,%d_%d,%f,%f == false", mObject.index, GetState(), GetStateStop(), mIsRequestRejection, mPlayerExrInfo.RestHP, mPlayerExrInfo.RestMP, mMapNumber, mObjectPos.x, mObjectPos.y ); errorCode = ERROR_PLAYER_RESURRECTION_FAIL; } SetMoveTargetPos( mObjectPos.x, mObjectPos.y ); if( cashUse == false ) { HANDLE handle = NULL; MSG_RES_PLAYER_RESURRECTION* sendMsg = (MSG_RES_PLAYER_RESURRECTION*)NETWORK2->GetMsgRoot( &handle ,mConnectionIdx ,NM_PLAYER ,NM_PLAYER_RESURRECTION_RES ); if ( sendMsg != NULL ) { sendMsg->ErrorCode = errorCode; sendMsg->mHP = mPlayerExrInfo.RestHP; sendMsg->mMaxHP = GetMaxHP(); sendMsg->mMP = mPlayerExrInfo.RestMP; sendMsg->mMaxMP = GetMaxMP(); sendMsg->mExpDown = expDown; sendMsg->mPlayerExp = mHeroInfo.Exp; sendMsg->mPosX = mObjectPos.x; sendMsg->mPosY = mObjectPos.y; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_PLAYER_RESURRECTION) ); } } else { HANDLE handle = NULL; MSG_RES_PLAYER_CASHEXP_RESURRECTION* sendMsg = (MSG_RES_PLAYER_CASHEXP_RESURRECTION*)NETWORK2->GetMsgRoot( &handle ,mConnectionIdx ,NM_PLAYER ,NM_PLAYER_RESURRECTION_CASHEXP_RES ); if ( sendMsg != NULL ) { sendMsg->ErrorCode = errorCode; sendMsg->mHP = mPlayerExrInfo.RestHP; sendMsg->mMaxHP = GetMaxHP(); sendMsg->mMP = mPlayerExrInfo.RestMP; sendMsg->mMaxMP = GetMaxMP(); sendMsg->mExpDown = expDown; sendMsg->mPlayerExp = mHeroInfo.Exp; sendMsg->mPosX = mObjectPos.x; sendMsg->mPosY = mObjectPos.y; sendMsg->mInfluenceIdx = infIdx; sendMsg->mCashExpCnt = cashExpCnt; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_PLAYER_CASHEXP_RESURRECTION) ); } } if( errorCode == 0 ) { /// º¹±¸°¡´ÉÇÑ ¼öÄ¡ ±â·Ï mHeroInfo.mLoseExp = expDown; mExpRecoverEndTime = TIMER->GetRealPlusTime( 1 * DAY ); MSG_SYN_PLAYER_RESURRECTION synMsg; synMsg.Category = NM_PLAYER; synMsg.Protocol = NM_PLAYER_RESURRECTION_SYN; synMsg.mCharacterIdx = mObject.index; synMsg.mHP = mPlayerExrInfo.RestHP; synMsg.mMaxHP = GetMaxHP(); synMsg.mMP = mPlayerExrInfo.RestMP; synMsg.mMaxMP = GetMaxMP(); synMsg.mPosX = mObjectPos.x; synMsg.mPosY = mObjectPos.y; NETWORK2->QuickSendExcept( this, (char*)&synMsg, sizeof(synMsg) ); } if( addInf == true ) SKILLMANAGER->AddInfluence( mObject, mObject, RESURRECTION_STAND_INFLUENCE_CLASSIDX, 0, true ); } bool cPlayer::SkillResurrection() { bool retBool = mIsSkillResurrection; if( mIsSkillResurrection == true ) { InitHP( mSkillResurrectionHP ); InitMP( mSkillResurrectionMP ); if( ChangeState( eOBJECT_STATE_IDLE, eCHANGESTATEOPTION_RESURRECTION ) == false ) { assert(NULL); NETWORK2->PostServerEvent("Player[%d] SkillResurrection ChangeState( eOBJECT_STATE_IDLE, true ) == false", mObject.index ); } mSkillResurrectionHP = 0; mSkillResurrectionMP = 0; mIsSkillResurrection = false; } return retBool; } void cPlayer::PvPResurrection( bool timeCheckPass ) { unsigned long accumTime = NETWORK2->GetAccumTime(); /// Á×¾ú´ÂÁö È®ÀÎ if( GetStateDie() == false ) return; if( mPvPDMIdx == 0 ) { if( timeCheckPass == true ) { NETWORK2->PostServerEvent("cPlayer::PvPResurrection() hero[%d,%d,%d,%d] mPvPDMIdx == 0", mObject.index, mPlayerExrInfo.mState, mPlayerExrInfo.mStateStop, mPvPDieTime, mPvPDieEndTime, accumTime ); return; } } if( mPvPDieEndTime > accumTime && timeCheckPass == true ) { NETWORK2->PostServerEvent("cPlayer::PvPResurrection() hero[%d,%d,%d] mPvPDieEndTime[%d,%d] > accumTime[%d]", mObject.index, mPlayerExrInfo.mState, mPlayerExrInfo.mStateStop, mPvPDieTime, mPvPDieEndTime, accumTime ); } if( ChangeState( eOBJECT_STATE_IDLE, eCHANGESTATEOPTION_RESURRECTION ) == false ) NETWORK2->PostServerEvent("cPlayer::PvPResurrection() hero[%d,%d,%d]->ChangeState() == false", mObject.index, mPlayerExrInfo.mState, mPlayerExrInfo.mStateStop ); NiPoint2 pos; unsigned long posIdx = PVPMANAGER->GetTeamGenPosIdx( (ePVPDM_TEAM_TYPE)mPlayerExrInfo.mPvPDMTeamType ); if( posIdx ) { if( STAGESCRIPT->CalcTargetMapPos( posIdx, &pos.x, &pos.y ) == true ) { mObjectPos.x = pos.x; mObjectPos.y = pos.y; } } else { assert(0); } InitHP( GetMaxHP() ); InitMP( GetMaxMP() ); HANDLE handle = NULL; MSG_RES_PLAYER_RESURRECTION* sendMsg = (MSG_RES_PLAYER_RESURRECTION*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_RESURRECTION_RES ); if ( sendMsg != NULL ) { sendMsg->ErrorCode = 0; sendMsg->mHP = mPlayerExrInfo.RestHP; sendMsg->mMaxHP = GetMaxHP(); sendMsg->mMP = mPlayerExrInfo.RestMP; sendMsg->mMaxMP = GetMaxMP(); sendMsg->mExpDown = 0; sendMsg->mPlayerExp = mHeroInfo.Exp; sendMsg->mPosX = mObjectPos.x; sendMsg->mPosY = mObjectPos.y; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_PLAYER_RESURRECTION) ); } MSG_SYN_PLAYER_RESURRECTION synMsg; synMsg.Category = NM_PLAYER; synMsg.Protocol = NM_PLAYER_RESURRECTION_SYN; synMsg.mCharacterIdx = mObject.index; synMsg.mHP = mPlayerExrInfo.RestHP; synMsg.mMaxHP = GetMaxHP(); synMsg.mMP =mPlayerExrInfo.RestMP; synMsg.mMaxMP = GetMaxMP(); synMsg.mPosX = mObjectPos.x; synMsg.mPosY = mObjectPos.y; NETWORK2->QuickSendExcept( this, (char*)&synMsg, sizeof(synMsg) ); SKILLMANAGER->AddInfluence( mObject, mObject, PVP_DM_NODAMAGE_INFLUENCE, 0, true ); } int cPlayer::TutorialResurrection( ULONG_PTR socketContext ) { if( mTutorialModeIndex == -1 ) { NETWORK2->PostServerEvent("cPlayer::TutorialResurrection modeIndex error(%d, %d, %d)", mObject.index, GetState(), GetStateStop() ); return ERROR_TUTORIAL_RESURRECTION_FAIL; } if( GetStateDie() == false ) { NETWORK2->PostServerEvent("cPlayer::TutorialResurrection GetStateDie_%d_%d,%d,%d_%d,%d_%d,%f,%f == false", mObject.index, GetState(), GetStateStop(), mIsRequestRejection, mPlayerExrInfo.RestHP, mPlayerExrInfo.RestMP, mMapNumber, mObjectPos.x, mObjectPos.y ); return ERROR_TUTORIAL_RESURRECTION_FAIL; } if( ChangeState( eOBJECT_STATE_IDLE, eCHANGESTATEOPTION_RESURRECTION ) == false ) { NETWORK2->PostServerEvent("cPlayer::TutorialResurrection() hero[%d,%d,%d]->ChangeState() == false", mObject.index, mPlayerExrInfo.mState, mPlayerExrInfo.mStateStop ); return ERROR_TUTORIAL_RESURRECTION_FAIL; } cTutorialMode* mode = TUTORIALSCRIPT->GetTutorialMode( mTutorialModeIndex ); if( mode == NULL ) { NETWORK2->PostServerEvent("cPlayer::TutorialResurrection() mode data error(%d,%d)", mObject.index, mTutorialModeIndex ); assert(0); return ERROR_TUTORIAL_RESURRECTION_FAIL; } NiPoint2 pos; if( STAGESCRIPT->CalcTargetMapPos( mode->mStartPosIndex, &pos.x, &pos.y ) == true ) { mObjectPos.x = pos.x; mObjectPos.y = pos.y; } else { NETWORK2->PostServerEvent("cPlayer::TutorialResurrection() CalcTargetMapPos(%d,%d,%d)", mObject.index, mTutorialModeIndex, mode->mStartPosIndex ); assert(0); return ERROR_TUTORIAL_RESURRECTION_FAIL; } InitHP( GetMaxHP() ); InitMP( GetMaxMP() ); HANDLE handle = NULL; MSG_RES_TUTORIAL_RESURRECTION* sendMsg = (MSG_RES_TUTORIAL_RESURRECTION*)NETWORK2->GetMsgRoot( &handle ,(PerSocketContext*)socketContext ,NM_TUTORIAL ,NM_TUTORIAL_REVIVAL_RES ); sendMsg->mHP = mPlayerExrInfo.RestHP; sendMsg->mMaxHP = GetMaxHP(); sendMsg->mMP = mPlayerExrInfo.RestMP; sendMsg->mMaxMP = GetMaxMP(); sendMsg->mPosX = mObjectPos.x; sendMsg->mPosY = mObjectPos.y; sendMsg->ErrorCode = ERROR_TUTORIAL_RESURRECTION_SUCCESS; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_TUTORIAL_RESURRECTION) ); MSG_SYN_TUTORIAL_RESURRECTION synMsg; synMsg.Category = NM_TUTORIAL; synMsg.Protocol = NM_TUTORIAL_REVIVAL_SYN; synMsg.mCharacterIdx = mObject.index; synMsg.mHP = mPlayerExrInfo.RestHP; synMsg.mMaxHP = GetMaxHP(); synMsg.mMP = mPlayerExrInfo.RestMP; synMsg.mMaxMP = GetMaxMP(); synMsg.mPosX = mObjectPos.x; synMsg.mPosY = mObjectPos.y; NETWORK2->QuickSendExcept( this, (char*)&synMsg, sizeof(synMsg) ); return ERROR_TUTORIAL_RESURRECTION_SUCCESS; } //bool cPlayer::AddInfluence( unsigned long uniqueIdx, unsigned long influenceClassIdx ) bool cPlayer::AddInfluence( cInfluenceObject* pInf ) { if( pInf == NULL ) return false; if( mInfluenceSet.Insert( pInf->GetUniqueIdx() ) == false ) { assert(NULL); NETWORK2->PostServerEvent("cPlayer::AddSkillInfluence mInfluenceSet.Insert( %d, %d, %d ) == false", mObject.index, pInf->GetUniqueIdx(), pInf->GetInfluenceClassIdx() ); return false; } sInfluenceScript* pScript = SKILLSCRIPT->GetInfluenceInfo( pInf->GetInfluenceClassIdx() ); if( pScript != NULL ) { switch( pInf->GetChangeMPType() ) { case eINFCHANGEMPTYPE_NONE: break; case eINFCHANGEMPTYPE_PHY: case eINFCHANGEMPTYPE_MAG: case eINFCHANGEMPTYPE_ALL: { mChangeMPDamageAry.PushBack( pInf->GetUniqueIdx() ); std::sort( mChangeMPDamageAry.Begin(), mChangeMPDamageAry.End(), InfChangeMPMinSort ); } break; } switch( pInf->GetGuardType() ) { case eINFGUARDTYPE_NONE: break; case eINFGUARDTYPE_PHY: case eINFGUARDTYPE_MAG: case eINFGUARDTYPE_ALL: case eINFGUARDTYPE_CASHEXP: { mGuardAry.PushBack( pInf->GetUniqueIdx() ); std::sort( mGuardAry.Begin(), mGuardAry.End(), InfLeftTimeSort ); } break; default: NETWORK2->PostServerEvent("cPlayer::AddSkillInfluence pInf->GetGuardType(%d,%d,%d,%d) == false", mObject.index, pInf->GetUniqueIdx(), pInf->GetInfluenceClassIdx(), pInf->GetGuardType() ); break; } switch( pInf->GetDeleteType() ) { case eDELETETYPE_PLAYER_DIE: case eDELETETYPE_NODELETE_PLAYER_DIE: break; case eDELETETYPE_PLAYER_DAMAGED: { mDeleteTypeDamagedAry.PushBack( pInf->GetUniqueIdx() ); } break; default: NETWORK2->PostServerEvent("cPlayer::AddSkillInfluence pInf->GetDeleteType(%d,%d,%d,%d) == false", mObject.index, pInf->GetUniqueIdx(), pInf->GetInfluenceClassIdx(), pInf->GetGuardType() ); break; } /// ÇöÀç Áö¼Ó È¿°ú ¹øÈ£°¡ 3°³ ¹Û¿¡ ¾ø¾î¼­ 3¹ø¸¸ üũ for( int checkCount = 0; checkCount < 3; ++checkCount ) { unsigned short checkStatusPlusIdx = eSTATUSPLUS_NONE; switch(checkCount) { case 0: checkStatusPlusIdx = pScript->mStatusPlusIdx1; break; case 1: checkStatusPlusIdx = pScript->mStatusPlusIdx2; break; case 2: checkStatusPlusIdx = pScript->mStatusPlusIdx3; break; } if( checkStatusPlusIdx != eSTATUSPLUS_NONE ) { if( pScript->mType == eINFLUENCETYPE_BUF ) { cApplyValueTypeMap::cIterator findPos = mBuffmap.Find( checkStatusPlusIdx ); if( findPos != mBuffmap.End() ) { /// ÀÌ¹Ì µé¾î°¡ ÀÖ´Â °æ¿ì cHashSet& influenceSet = (*findPos).mSecond; influenceSet.Insert( pInf->GetUniqueIdx() ); } else { /// »õ·Î Ãß°¡ÇÑ °æ¿ì cHashSet influenceSet; influenceSet.Insert( pInf->GetUniqueIdx() ); mBuffmap.Insert( checkStatusPlusIdx, influenceSet ); } } else if( pScript->mType == eINFLUENCETYPE_DEBUF ) { cApplyValueTypeMap::cIterator findPos = mDeBuffmap.Find( checkStatusPlusIdx ); if( findPos != mDeBuffmap.End() ) { /// ÀÌ¹Ì µé¾î°¡ ÀÖ´Â °æ¿ì cHashSet& influenceSet = (*findPos).mSecond; influenceSet.Insert( pInf->GetUniqueIdx() ); } else { /// »õ·Î Ãß°¡ÇÑ °æ¿ì cHashSet influenceSet; influenceSet.Insert( pInf->GetUniqueIdx() ); mDeBuffmap.Insert( checkStatusPlusIdx, influenceSet ); } } } else { /// È¿°ú´Â ¼øÂ÷ÀûÀ¸·Î Áý¾î ³Ö±â ¶§¹®¿¡ Çϳª¶óµµ ºó À妽º°¡ ³ª¿À¸é ³ª¸ÓÁö´Â üũÇÒ Çʿ䰡 ¾ø´Ù. break; } } } return true; } void cPlayer::ReleaseInfluenceSet( bool logOut ) { cSkillInfluenceSet::cIterator start = mInfluenceSet.Begin(); cSkillInfluenceSet::cIterator end = mInfluenceSet.End(); unsigned long infIdx = 0; while( start != end ) { infIdx = *start++; if( logOut == true ) { cInfluenceObject* pInf = SKILLMANAGER->GetInfluence( infIdx ); if( pInf != NULL ) { pInf->NoSendDelMsg(); pInf->NoStatusCalc(); } } else { cInfluenceObject* pInf = SKILLMANAGER->GetInfluence( infIdx ); if( pInf != NULL ) { /// º¸À¯ÁßÀÌ´ø pc¹æ ¹öÇÁ°¡ ²¨Áö´Â °æ¿ì ÁÖ±âÀûÀ¸·Î ´Ù½Ã µî·Ï ½ÃµµÇÑ´Ù. sInfluenceScript* pScript = SKILLSCRIPT->GetInfluenceInfo( pInf->GetInfluenceClassIdx() ); if( pScript != NULL && pScript->mType == eINFLUENCETYPE_PC ) mReadyPcInfSet.Insert( pInf->GetInfluenceClassIdx() ); else if( pScript != NULL && pScript->mType == eINFLUENCETYPE_GMEVENT ) { ///GameProcess ¿¡¼­ Á¤º¸¸¦ °¡Á®¿Í¼­ À̺¥Æ® ¹öÇÁ ´ë±â ¼Â¿¡ ³Ö´Â´Ù. AddAllGMEvent(); } } } SKILLMANAGER->DeleteInfluenceList( infIdx ); } } void cPlayer::DieDeleteInfluence() { cSkillInfluenceSet::cIterator start = mInfluenceSet.Begin(); cSkillInfluenceSet::cIterator end = mInfluenceSet.End(); unsigned long infIdx = 0; cInfluenceObject* pInfluence = NULL; while( start != end ) { infIdx = *start++; pInfluence = SKILLMANAGER->GetInfluence( infIdx ); if( pInfluence == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cPlayer::ReleaseSkillInfluenceSet pInfluence==NULL[%d]", mObject.index ); continue; } if( pInfluence->GetDeleteType() == eDELETETYPE_NODELETE_PLAYER_DIE ) continue; cInfluenceObject* pInf = SKILLMANAGER->GetInfluence( infIdx ); if( pInf != NULL ) { /// º¸À¯ÁßÀÌ´ø pc¹æ ¹öÇÁ°¡ ²¨Áö´Â °æ¿ì ÁÖ±âÀûÀ¸·Î ´Ù½Ã µî·Ï ½ÃµµÇÑ´Ù. sInfluenceScript* pScript = SKILLSCRIPT->GetInfluenceInfo( pInf->GetInfluenceClassIdx() ); if( pScript != NULL && pScript->mType == eINFLUENCETYPE_PC ) { mReadyPcInfSet.Insert( pInf->GetInfluenceClassIdx() ); } else if( pScript != NULL && pScript->mType == eINFLUENCETYPE_GMEVENT ) { ///GameProcess ¿¡¼­ Á¤º¸¸¦ °¡Á®¿Í¼­ À̺¥Æ® ¹öÇÁ ´ë±â ¼Â¿¡ ³Ö´Â´Ù. AddAllGMEvent(); } } pInfluence->NoSendDelMsg(); /// Ŭ¶óÀÌ¾ðÆ®¿¡ ¹ß¼ÛÀ» ÇÏÁö ¾Ê´Â´Ù. SKILLMANAGER->DeleteInfluenceList( infIdx ); } //mGuardAry.Clear(); //mChangeMPDamageAry.Clear(); } void cPlayer::DeleteInfluence( unsigned long influenceIdx ) { /// Ç÷¹À̾¼­ È¿°ú°¡ »ç¶óÁú¶§ ´Ù¸¥ Ç׸ñ¿¡ È¿°ú°¡ »ç¶óÁö°Å³ª Ãß°¡º¯°æÀÌ Àִ°æ¿ì ó¸® cInfluenceObject* pInf = SKILLMANAGER->GetInfluence( influenceIdx ); if( pInf ) { /// È¿°ú°¡ pvp ±ê¹ß È¿°úÀ̸é È¿°ú°¡ ²¨Áú¶§ ±ê¹ß ¸®Á¨Ã³¸®¸¦ ÇÑ´Ù. if( pInf->GetInfluenceClassIdx() == PVP_DM2_FLAG_INFLUENCE && mPvPDMIdx != 0 ) { cBaseDeathMatch* pDM = PVPMANAGER->GetPvPDMObject( mPvPDMIdx ); if( pDM != NULL && pDM->GetType() == ePVPDM_OBJECTTYPE_2 ) { cDeathMatch2Object* pDM2 = (cDeathMatch2Object*)pDM; if( pDM2->DelInfRegenFlag( mObject.index, mObjectPos.x, mObjectPos.y ) == true ) { /// äÁý ÁßÀ̸é Ãë¼Ò cGathering* pGathering = OBJECTMANAGER->GetGathering( mGatheringIdx ); if( pGathering != NULL ) pGathering->ReqEraseGatherPlayer( this ); } } } sInfluenceScript* pScript = SKILLSCRIPT->GetInfluenceInfo( pInf->GetInfluenceClassIdx() ); if( pScript != NULL ) { /// º¸À¯ÁßÀÌ´ø pc¹æ ¹öÇÁ°¡ ²¨Áö´Â °æ¿ì ÁÖ±âÀûÀ¸·Î ´Ù½Ã µî·Ï ½ÃµµÇÑ´Ù. if( pScript->mType == eINFLUENCETYPE_PC ) mReadyPcInfSet.Insert( pInf->GetInfluenceClassIdx() ); else if( pScript->mType == eINFLUENCETYPE_CASH && mInfNoSave == false ) SKILLMANAGER->SavePlayerInfluence( mObject.index, influenceIdx, true ); else if( pInf->IsDbIdx() == true && mInfNoSave == false ) SKILLMANAGER->SavePlayerInfluence( mObject.index, influenceIdx, true ); } } for( unsigned long i = 0 ; i < mGuardAry.GetSize() ; ++i ) { if( influenceIdx == mGuardAry[i] ) mGuardAry.PopAt( i ); } for( unsigned long i = 0 ; i < mChangeMPDamageAry.GetSize() ; ++i ) { if( influenceIdx == mChangeMPDamageAry[i] ) mChangeMPDamageAry.PopAt( i ); } for( unsigned long i = 0 ; i < mDeleteTypeDamagedAry.GetSize() ; ++i ) { if( influenceIdx == mDeleteTypeDamagedAry[i] ) mDeleteTypeDamagedAry.PopAt( i ); } /// ¹öÇÁ/µð¹öÇÁ °ü¸® map ¿¡¼­ »©±â if( pInf != NULL ) { sInfluenceScript* pScript = SKILLSCRIPT->GetInfluenceInfo( pInf->GetInfluenceClassIdx() ); if( pScript != NULL ) { /// ÇöÀç Áö¼Ó È¿°ú ¹øÈ£°¡ 3°³ ¹Û¿¡ ¾ø¾î¼­ 3¹ø¸¸ üũ for( int checkCount = 0; checkCount < 3; ++checkCount ) { unsigned short checkStatusPlusIdx = eSTATUSPLUS_NONE; switch(checkCount) { case 0: checkStatusPlusIdx = pScript->mStatusPlusIdx1; break; case 1: checkStatusPlusIdx = pScript->mStatusPlusIdx2; break; case 2: checkStatusPlusIdx = pScript->mStatusPlusIdx3; break; } if( checkStatusPlusIdx != eSTATUSPLUS_NONE ) { if( pScript->mType == eINFLUENCETYPE_BUF ) { cApplyValueTypeMap::cIterator findPos = mBuffmap.Find( checkStatusPlusIdx ); if( findPos != mBuffmap.End() ) { /// ãÀº °æ¿ì ÇØ´ç set¿¡¼­ »èÁ¦ cHashSet& influenceSet = (*findPos).mSecond; influenceSet.Erase( pInf->GetUniqueIdx() ); } else { /// È¿°ú ¸Ê¿¡´Â ÀÖÁö¸¸ ¹öÇÁ ¸Ê¿¡ ¾ø´Â °æ¿ì mInfluenceSet °ú mBuffmap ÀÌ µ¿±âÈ­ ¾È¸Â¾ÒÀ½! NETWORK2->PostServerEvent("cMonster::DeleteInfluence mBuffmap.Find(%d)==mBuffmap.End (%d,%d,%d)", checkStatusPlusIdx, mObject.index, pInf->GetUniqueIdx(), pInf->GetInfluenceClassIdx() ); } } else if( pScript->mType == eINFLUENCETYPE_DEBUF ) { cApplyValueTypeMap::cIterator findPos = mDeBuffmap.Find( checkStatusPlusIdx ); if( findPos != mDeBuffmap.End() ) { /// ãÀº °æ¿ì ÇØ´ç set¿¡¼­ »èÁ¦ cHashSet& influenceSet = (*findPos).mSecond; influenceSet.Erase( pInf->GetUniqueIdx() ); } else { /// È¿°ú ¸Ê¿¡´Â ÀÖÁö¸¸ ¹öÇÁ ¸Ê¿¡ ¾ø´Â °æ¿ì mInfluenceSet °ú mBuffmap ÀÌ µ¿±âÈ­ ¾È¸Â¾ÒÀ½! NETWORK2->PostServerEvent("cMonster::DeleteInfluence mDeBuffmap.Find(%d)==mDeBuffmap.End (%d,%d,%d)", checkStatusPlusIdx, mObject.index, pInf->GetUniqueIdx(), pInf->GetInfluenceClassIdx() ); } } } else { /// È¿°ú´Â ¼øÂ÷ÀûÀ¸·Î Áý¾î ³Ö±â ¶§¹®¿¡ Çϳª¶óµµ ºó À妽º°¡ ³ª¿À¸é ³ª¸ÓÁö´Â üũÇÒ Çʿ䰡 ¾ø´Ù. break; } } } } /// Ç÷¹À̾ °¡Áö°í ÀÖ´Â ¸ñ·Ï¿¡¼­ Á¦°Å if( mInfluenceSet.Erase( influenceIdx ) == false ) NETWORK2->PostServerEvent("cPlayer::EraseSkillInfluence[%d][%d]", mObject.index, influenceIdx ); if( pInf != NULL ) { sInfluenceScript* pScript = SKILLSCRIPT->GetInfluenceInfo( pInf->GetInfluenceClassIdx() ); if( pScript != NULL ) { if( pScript->mStatusPlusIdx1 >= eSTATUSPLUS_GUARDMP_PHY && pScript->mStatusPlusIdx1 <= eSTATUSPLUS_GUARDMP_ALL ) std::sort( mChangeMPDamageAry.Begin(), mChangeMPDamageAry.End(), InfChangeMPMinSort ); else if( pScript->mStatusPlusIdx2 >= eSTATUSPLUS_GUARDMP_PHY && pScript->mStatusPlusIdx2 <= eSTATUSPLUS_GUARDMP_ALL ) std::sort( mChangeMPDamageAry.Begin(), mChangeMPDamageAry.End(), InfChangeMPMinSort ); else if( pScript->mStatusPlusIdx3 >= eSTATUSPLUS_GUARDMP_PHY && pScript->mStatusPlusIdx3 <= eSTATUSPLUS_GUARDMP_ALL ) std::sort( mChangeMPDamageAry.Begin(), mChangeMPDamageAry.End(), InfChangeMPMinSort ); else if( pScript->mStatusPlusIdx1 >= eSTATUSPLUS_GUARDCNT_PHY && pScript->mStatusPlusIdx1 <= eSTATUSPLUS_GUARDCNT_ALL ) std::sort( mGuardAry.Begin(), mGuardAry.End(), InfLeftTimeSort ); else if( pScript->mStatusPlusIdx2 >= eSTATUSPLUS_GUARDCNT_PHY && pScript->mStatusPlusIdx2 <= eSTATUSPLUS_GUARDCNT_ALL ) std::sort( mGuardAry.Begin(), mGuardAry.End(), InfLeftTimeSort ); else if( pScript->mStatusPlusIdx3 >= eSTATUSPLUS_GUARDCNT_PHY && pScript->mStatusPlusIdx3 <= eSTATUSPLUS_GUARDCNT_ALL ) std::sort( mGuardAry.Begin(), mGuardAry.End(), InfLeftTimeSort ); } } } void cPlayer::GameInInfApply() { cInfluenceObject* pInfluenceObject = NULL; tHashSet::cIterator start = mInfluenceSet.Begin(); tHashSet::cIterator end = mInfluenceSet.End(); for( ; start != end ; ++start ) { pInfluenceObject = SKILLMANAGER->GetInfluence( (*start) ); if ( pInfluenceObject == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cPlayer::InfluenceProcessStart()"); //-/-//SKILLMANAGER->InsertDeleteInfluenceObject( pInfluenceObject ); /// °´Ã¼ »èÁ¦ ´ë±â¿­¿¡ ³Ö´Â´Ù. continue; } sInfluenceScript* pScript = SKILLSCRIPT->GetInfluenceInfo( pInfluenceObject->GetInfluenceClassIdx() ); if( pScript == NULL ) { SKILLMANAGER->DeleteInfluence( mObject, (*start) ); NETWORK2->PostServerEvent("cPlayer::InfluenceProcessStart pScript == NULL[%d]", pInfluenceObject->GetInfluenceClassIdx() ); continue; } const int colNum = 3; long type[colNum] = { pScript->mStatusPlusIdx1, pScript->mStatusPlusIdx2, pScript->mStatusPlusIdx3 }; long value[colNum] = { pScript->mValue1, pScript->mValue2, pScript->mValue3 }; for( int i = 0 ; i < colNum ; ++i ) SKILLMANAGER->ApplyInfluence( this, this, (*start), pInfluenceObject->GetInfluenceClassIdx(), type[i], value[i], true ); } } void cPlayer::InfluenceProcessStart() { cInfluenceObject* pInfluenceObject = NULL; tHashSet::cIterator start = mInfluenceSet.Begin(); tHashSet::cIterator end = mInfluenceSet.End(); for( ; start != end ; ++start ) { pInfluenceObject = SKILLMANAGER->GetInfluence( (*start) ); if ( pInfluenceObject == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cPlayer::InfluenceProcessStart()"); //-/-//SKILLMANAGER->InsertDeleteInfluenceObject( pInfluenceObject ); /// °´Ã¼ »èÁ¦ ´ë±â¿­¿¡ ³Ö´Â´Ù. continue; } pInfluenceObject->ProcessStart(); sInfluenceScript* pScript = SKILLSCRIPT->GetInfluenceInfo( pInfluenceObject->GetInfluenceClassIdx() ); if( pScript == NULL ) { SKILLMANAGER->DeleteInfluence( mObject, (*start) ); NETWORK2->PostServerEvent("cPlayer::InfluenceProcessStart pScript == NULL[%d]", pInfluenceObject->GetInfluenceClassIdx() ); continue; } const int colNum = 3; long type[colNum] = { pScript->mStatusPlusIdx1, pScript->mStatusPlusIdx2, pScript->mStatusPlusIdx3 }; long value[colNum] = { pScript->mValue1, pScript->mValue2, pScript->mValue3 }; for( int i = 0 ; i < colNum ; ++i ) SKILLMANAGER->ApplyInfluence( this, this, (*start), pInfluenceObject->GetInfluenceClassIdx(), type[i], value[i], true ); } } void cPlayer::InfluenceProcessStop() { cInfluenceObject* pInfluenceObject = NULL; tHashSet::cIterator start = mInfluenceSet.Begin(); tHashSet::cIterator end = mInfluenceSet.End(); for( ; start != end ; ++start ) { pInfluenceObject = SKILLMANAGER->GetInfluence( (*start) ); if ( pInfluenceObject == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cPlayer::InfluenceProcessStart()"); //-/-//SKILLMANAGER->InsertDeleteInfluenceObject( pInfluenceObject ); /// °´Ã¼ »èÁ¦ ´ë±â¿­¿¡ ³Ö´Â´Ù. continue; } pInfluenceObject->ProcessStop(); } } void cPlayer::AddActInfluence( unsigned long actIdx ) { sActInfluenceScript* pInfo = SKILLSCRIPT->GetActInfluenceInfo( actIdx ); if( pInfo == 0 ) { assert(NULL); NETWORK2->PostServerEvent("cPlayer::AddActInfluence(%d)", actIdx ); return; } unsigned long coolTime = pInfo->mCooltime + NETWORK2->GetAccumTime(); if( mActInfluenceMap.Insert( actIdx, coolTime ) == false ) { assert(NULL); NETWORK2->PostServerEvent("cPlayer::AddActInfluence(%d)", actIdx ); } } void cPlayer::ClearActInfluence() { mActInfluenceMap.Clear(); } bool cPlayer::IsParentEqual( unsigned long parentUniqueIdx ) { cSkillInfluenceSet::cIterator beginAura = mInfluenceSet.Begin(); cSkillInfluenceSet::cIterator endAura = mInfluenceSet.End(); cInfluenceObject* pInf = NULL; while( beginAura != endAura ) { /// º¸À¯ È¿°ú ¿ÀºêÁ§Æ® pInf = SKILLMANAGER->GetInfluence( *beginAura++ ); if( !pInf ) { NETWORK2->PostServerEvent("cSkillManager::IsParentEqual pHaveInfluenceObject==NULL Aura" ); continue; } if( pInf->GetSwitchType() == eSWITCHTYPE_PARENT && pInf->GetRarentIdx() == parentUniqueIdx ) return true; } return false; } bool cPlayer::IsInfluenceHave( unsigned long influenceIdx ) { /// ÇöÀç º¸À¯ÁßÀÎÁö üũÇÑ´Ù. cSkillInfluenceSet::cIterator b = mInfluenceSet.Begin(); cSkillInfluenceSet::cIterator end = mInfluenceSet.End(); cInfluenceObject* pHaveInfluenceObject = NULL; while( b != end ) { /// º¸À¯ È¿°ú ¿ÀºêÁ§Æ® pHaveInfluenceObject = SKILLMANAGER->GetInfluence( *b++ ); if( !pHaveInfluenceObject ) { NETWORK2->PostServerEvent("cSkillManager::IsInfluenceHave pHaveInfluenceObject==NULL" ); continue; } if( pHaveInfluenceObject->GetInfluenceClassIdx() == influenceIdx ) return true; } return false; } void cPlayer::SkillResurrectionHP( unsigned long HP ) { mIsSkillResurrection = true; mSkillResurrectionHP = HP; } void cPlayer::SkillResurrectionMP( unsigned long MP ) { if( mIsSkillResurrection == true ) { mSkillResurrectionMP = MP; } } void cPlayer::MonsterInTargeting( tArray* targetAry, float range ) { if( targetAry == NULL ) return; /// ¹üÀ§ ¼³Á¤ mRangeCheck.SetRadius( (float)range ); /// ³ª¸¦ Ÿ°ÙÀ¸·Î ÇÏ´Â ¸ó½ºÅÍ Å¸°Ù ÇØÁ¦ cMonster* pMonster = NULL; cTargetingMonsterSet::cIterator start = mTargetingMonsterSet.Begin(); cTargetingMonsterSet::cIterator end = mTargetingMonsterSet.End(); while( start != end ) { unsigned long monsterIdx = (*start++); if( monsterIdx == 0 ) continue; pMonster = GRIDMANAGER->GetMonster( monsterIdx ); if( pMonster && pMonster->GetTarget() == this ) { /// ¹üÀ§ üũ if( mRangeCheck.IsRange( mObjectPos, pMonster->GetPos() ) == true ) { sObject multiTarget; multiTarget.type = pMonster->GetObjectType(); multiTarget.index = pMonster->GetObjectID(); //multiTarget.mApplyHP = true; targetAry->PushBack( multiTarget ); } } } } /// °¢ Á÷¾÷´ç »ç¿ëÇÑ sp ÀúÀå ó¸® void cPlayer::UpdateJobUsedSP() { /// º¸À¯½ºÅ³ Æ÷ÀÎÅÍ typedef tPointerHashMap cHaveSkillMap; cHaveSkillMap* haveSkillMap = (cHaveSkillMap*)SKILLMANAGER->GetPlayerHaveSkill( mObject.index ); if( haveSkillMap == NULL ) return; for( unsigned int i=0;iBegin(); cHaveSkillMap::cIterator end = haveSkillMap->End(); for( ; begin != end ; ++begin ) { cHaveSkillObject* pHaveSkill = (cHaveSkillObject*)((*begin).mSecond); if( pHaveSkill == NULL ) continue; sPlayerSkillBaseInfo* pSkillInfo = SKILLSCRIPT->GetPlayerSkillInfo( pHaveSkill->GetSkillIdx() ); if( pSkillInfo == 0 ) continue; if( pSkillInfo->mJobStep == 9 ) continue; if( pSkillInfo->mStepCount <= pHaveSkill->GetSkillStep() ) { assert(0); continue; } for( unsigned int i=0;i<=pHaveSkill->GetSkillStep();i++ ) { sPlayerSkillStepInfo* pSkillStep = &pSkillInfo->mpSetpInfoArray[i]; if( pSkillStep != NULL ) { if( pSkillStep->mPlayerLevel != 0 ) mJobUsedSpArr[pSkillInfo->mJobStep] = mJobUsedSpArr[pSkillInfo->mJobStep] + pSkillStep->mRequireSP; } } } } void cPlayer::StatusCalc() { STATUSCALC->CalcPlayerExtensionGlobal( mObject ); } bool cPlayer::CancelGathering( unsigned long gatheringIdx ) { if( mGatheringIdx != 0 && mGatheringIdx != gatheringIdx ) return false; mGatheringIdx = 0; return true; } unsigned char cPlayer::AddMakeSkill( unsigned short itemSlotNum ) { /// ¾ÆÀÌÅÛ »ç¿ë½Ã °Ë»çÇÒ ³»¿ëµé. if( GetStateDie() == true ) return ERROR_MAKESKILL_ADD_STATE; if ( IsInventoryBag( itemSlotNum ) == false ) return ERROR_MAKESKILL_ADD_ITEM; TB_INVENTORY* inventory = SelectInventory( itemSlotNum ); if( IsInventory( inventory ) == false ) return ERROR_MAKESKILL_ADD_ITEM; if( inventory->apply != InventoryApplyNone ) return ERROR_MAKESKILL_ADD_ITEM; TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if( itemDefine == NULL ) return ERROR_MAKESKILL_ADD_ITEM; /// Àü¹® ½ºÅ³ ¾ÆÀÌÅÛÀÎÁö È®ÀÎ if( itemDefine->type != ITEM_MIX_SKILL ) return ERROR_MAKESKILL_ADD_ITEM; switch ( itemDefine->subType ) { case ITEM_MIX_SKILL_L1: case ITEM_MIX_SKILL_L2: case ITEM_MIX_SKILL_L3: case ITEM_MIX_SKILL_L4: break; default: return ERROR_MAKESKILL_ADD_ITEM; } if ( IsInventorySeal( itemDefine, inventory ) == true ) return ERROR_MAKESKILL_ADD_LICENSE; /// Item Limit Table(TB_ITEM_LIMIT) Àû¿ë if ( !IsItemLimit( inventory->itemDefineIdx ) ) return ERROR_MAKESKILL_ADD_ITEM; /// ¾ÆÀÌÅÛ È¿°ú Àû¿ë - ½ºÅ³°ú ¿¬°áÇÏ¿© »ç¿ëÇÑ´Ù. TB_ITEM_ABILITY* itemAbility = ITEMMANAGER->GetItemAbility( inventory->itemDefineIdx ); if( itemAbility == NULL ) return ERROR_MAKESKILL_ADD_ITEM; // Àü¹® ½ºÅ³ À妽º È®ÀÎ if( !(itemAbility->influence_idx > 0) ) return ERROR_MAKESKILL_ADD_ITEM; unsigned char makeSkill = (unsigned char)itemAbility->influence_idx; /// Àü¹® ½ºÅ³ À妽º unsigned char makeSkillStep = (unsigned char)itemDefine->subType; /// Àü¹® ½ºÅ³ ´Ü°è sMakeSkill* pMakeSkill = NULL; unsigned char addNum = 0; if( mHeroInfo.MakeSkill1.mIndex > 0 || mHeroInfo.MakeSkill2.mIndex > 0 ) { if( mHeroInfo.MakeSkillEnd < MAX_MAKESKILL && IsMakeSkill( makeSkill ) == false ) return ERROR_MAKESKILL_ADD_NOTEMPTY; } /// Ãß°¡µÇ´Â À§Ä¡ if( mHeroInfo.MakeSkill1.mIndex == 0 || mHeroInfo.MakeSkill1.mIndex == makeSkill ) { addNum = 1; pMakeSkill = &mHeroInfo.MakeSkill1; } else if( mHeroInfo.MakeSkill2.mIndex == 0 || mHeroInfo.MakeSkill2.mIndex == makeSkill ) { addNum = 2; pMakeSkill = &mHeroInfo.MakeSkill2; } /// ¹è¿ï ¼ö ÀÖ´Â Á÷¾÷ Ãʰú if( addNum == 0 || pMakeSkill == NULL ) return ERROR_MAKESKILL_ADD_NOTEMPTY; /// ´Ü°è üũ if( pMakeSkill->mIndex > 0 ) { if( pMakeSkill->mStep >= makeSkillStep ) return ERROR_MAKESKILL_ADD_ALREADY; if( (pMakeSkill->mStep + 1) != makeSkillStep ) return ERROR_MAKESKILL_ADD_STEP; } else { /// óÀ½ºÎÅÍ ³ôÀº ´Ü°è¸¦ ¹è¿ï ¼ö ¾ø°Ô.. if( makeSkillStep > 0 ) return ERROR_MAKESKILL_ADD_STEP; } unsigned long inventoryIdx = inventory->idx; /// ¾ÆÀÌÅÛ Â÷°¨ if ( inventory->count == 1 ) RemoveInventory( inventory->number ); else UpdateInventory( inventory, (-1) ); /// db ÀúÀå HANDLE handle = NULL; MAKESKILL_INSERT* pInsert = (MAKESKILL_INSERT*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_MAKESKILL_INSERT ); pInsert->mCharacterIdx = mObject.index; pInsert->mIsFirstSkill = addNum == 1 ? true : false; pInsert->mMakeSkillIdx = makeSkill; pInsert->mMakeSkillStep = makeSkillStep; pInsert->mInventoryIdx = inventoryIdx; pInsert->mRetvalue = -1; return (NETWORK2->SendSQL( mConnectionIdx, handle, sizeof(MAKESKILL_INSERT) ) ) ? ERROR_MAKESKILL_ADD_SUCCESS : ERROR_MAKESKILL_ADD_DBERROR; } unsigned char cPlayer::AddRecipe( unsigned short itemSlotNum ) { /// ¾ÆÀÌÅÛ »ç¿ë½Ã °Ë»çÇÒ ³»¿ëµé. if( GetStateDie() == true ) return ERROR_MAKESKILL_RECIPE_ADD_STATE; if ( IsInventoryBag( itemSlotNum ) == false ) return ERROR_MAKESKILL_RECIPE_ADD_ITEM; TB_INVENTORY* inventory = SelectInventory( itemSlotNum ); if( IsInventory( inventory ) == false ) return ERROR_MAKESKILL_RECIPE_ADD_ITEM; if( inventory->apply != InventoryApplyNone ) return ERROR_MAKESKILL_RECIPE_ADD_ITEM; TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if( itemDefine == NULL ) return ERROR_MAKESKILL_RECIPE_ADD_ITEM; if ( IsInventorySeal( itemDefine, inventory ) == true ) return ERROR_MAKESKILL_RECIPE_ADD_LICENSE; /// Item Limit Table(TB_ITEM_LIMIT) Àû¿ë if ( !IsItemLimit( inventory->itemDefineIdx ) ) return ERROR_MAKESKILL_RECIPE_ADD_ITEM; /// ¾ÆÀÌÅÛ È¿°ú Àû¿ë - ½ºÅ³°ú ¿¬°áÇÏ¿© »ç¿ëÇÑ´Ù. TB_ITEM_ABILITY* itemAbility = ITEMMANAGER->GetItemAbility( inventory->itemDefineIdx ); if( itemAbility == NULL ) return ERROR_MAKESKILL_RECIPE_ADD_ITEM; if( !(itemAbility->influence_idx > 0 && itemDefine->type == ITEM_MIX_SKILL ) ) return ERROR_MAKESKILL_RECIPE_ADD_ITEM; /// Äù½ºÆ® ÀÇ·Ú ¾ÆÀÌÅÛÀÎÁö È®ÀÎ if( itemDefine->subType == ITEM_MIX_RECIPE ) { unsigned long recipeIdx = 0; recipeIdx = itemAbility->influence_idx; // ·¹½ÃÇÇ À妽º /// ·¹½ÃÇÇ ½ºÅ©¸³Æ® È®ÀÎ sMakeSkillScript* pRecipeInfo = MAKESKILLSCRIPT->GetMakeSkill( recipeIdx ); if( pRecipeInfo == NULL ) return ERROR_MAKESKILL_RECIPE_ADD_SCRIPT; sMakeSkill* pMakeSkill = NULL; /// º¸À¯ Àü¹®±â¼ú È®ÀÎ & º¸À¯ ·¹½ÃÇÇ ÀÎÁö È®ÀÎ if( mHeroInfo.MakeSkill1.mIndex == pRecipeInfo->mMakeSkill ) { cRecipeGroup::cIterator end = mRecipeGroup1.End(); if( mRecipeGroup1.Find( recipeIdx ) != end ) return ERROR_MAKESKILL_RECIPE_ADD_ALREADY; pMakeSkill = &mHeroInfo.MakeSkill1; } else if( mHeroInfo.MakeSkill2.mIndex == pRecipeInfo->mMakeSkill ) { cRecipeGroup::cIterator end = mRecipeGroup2.End(); if( mRecipeGroup2.Find( recipeIdx ) != end ) return ERROR_MAKESKILL_RECIPE_ADD_ALREADY; pMakeSkill = &mHeroInfo.MakeSkill2; } else return ERROR_MAKESKILL_RECIPE_ADD_NOTHAVE; /// ´Ü°è üũ if( !(pMakeSkill && pMakeSkill->mStep >= pRecipeInfo->mMakeStep) ) return ERROR_MAKESKILL_RECIPE_ADD_STEP; /// ÃÖ¼Ò ¼÷·Ãµµ if( !(pMakeSkill && pMakeSkill->mExp >= pRecipeInfo->mMinExp) ) return ERROR_MAKESKILL_RECIPE_ADD_EXP; unsigned long inventoryIdx = inventory->idx; if ( inventory->count == 1 ) RemoveInventory( inventory->number ); else UpdateInventory( inventory, (-1) ); /// db ÀúÀå HANDLE handle = NULL; RECIPE_INSERT* pInsert = (RECIPE_INSERT*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_RECIPE_INSERT ); pInsert->mCharacterIdx = mObject.index; pInsert->mMakeSkillIdx = pRecipeInfo->mMakeSkill; pInsert->mRecipeIdx = recipeIdx; pInsert->mInventoryIdx = inventoryIdx; pInsert->retvalue = -1; return (NETWORK2->SendSQL( mConnectionIdx, handle, sizeof(RECIPE_INSERT) ) ) ? ERROR_MAKESKILL_RECIPE_ADD_SUCCESS : ERROR_MAKESKILL_RECIPE_ADD_DBERROR; } else if( itemDefine->subType == ITEM_MIX_RECIPEGROUP ) { unsigned long groupIdx = 0; groupIdx = itemAbility->influence_idx; // ·¹½ÃÇÇ ±×·ì À妽º /// ·¹½ÃÇÇ ½ºÅ©¸³Æ® È®ÀÎ sGroupInfo* pGroup = MAKESKILLSCRIPT->GetGroupInfo( groupIdx ); if( pGroup == NULL ) return ERROR_MAKESKILL_RECIPE_ADD_SCRIPT; HANDLE handle = NULL; RECIPE_GROUP_INSERT* pMakeSkill = (RECIPE_GROUP_INSERT*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_RECIPE_GROUP_INSERT ); pMakeSkill->mRowCnt = 0; cAry* pRecipeAry = &pGroup->mRecipeArr; for( unsigned long i = 0 ; i < pRecipeAry->GetSize() ; ++i ) { sRecipeGroupInfo* pGroupInfo = (sRecipeGroupInfo*)(*pRecipeAry)[i]; if( pGroupInfo == NULL ) continue; /// º¸À¯ ·¹½ÃÇÇ ÀÎÁö È®ÀÎ if( mHeroInfo.MakeSkill1.mIndex == pGroupInfo->mMakeSkill ) { if( mHeroInfo.MakeSkill1.mStep < pGroup->mStep ) { NETWORK2->PostServerEvent( "WARNING - cPlayer::AddRecipe - RECIPEGROUP1 - index(%c), step(%c), exp(%ld) / index(%c), step(%c), exp(%ld)", mHeroInfo.MakeSkill1.mIndex, mHeroInfo.MakeSkill1.mStep, mHeroInfo.MakeSkill1.mExp, pGroupInfo->mMakeSkill, pGroup->mStep, pGroup->mExp ); return ERROR_MAKESKILL_RECIPE_ADD_STEP; } if( mHeroInfo.MakeSkill1.mExp < pGroup->mExp ) { NETWORK2->PostServerEvent( "WARNING - cPlayer::AddRecipe - RECIPEGROUP1 - index(%c), step(%c), exp(%ld) / index(%c), step(%c), exp(%ld)", mHeroInfo.MakeSkill1.mIndex, mHeroInfo.MakeSkill1.mStep, mHeroInfo.MakeSkill1.mExp, pGroupInfo->mMakeSkill, pGroup->mStep, pGroup->mExp ); return ERROR_MAKESKILL_RECIPE_ADD_EXP; } cRecipeGroup::cIterator end = mRecipeGroup1.End(); if( mRecipeGroup1.Find( pGroupInfo->mRecipeIdx ) == end ) { pMakeSkill->mRecipeGroup[pMakeSkill->mRowCnt].mRecipeIdx = pGroupInfo->mRecipeIdx; pMakeSkill->mRecipeGroup[pMakeSkill->mRowCnt].mMakeSkill = pGroupInfo->mMakeSkill; ++pMakeSkill->mRowCnt; } } else if( mHeroInfo.MakeSkill2.mIndex == pGroupInfo->mMakeSkill ) { if( mHeroInfo.MakeSkill2.mStep < pGroup->mStep ) { NETWORK2->PostServerEvent( "WARNING - cPlayer::AddRecipe - RECIPEGROUP2 - index(%c), step(%c), exp(%ld) / index(%c), step(%c), exp(%ld)", mHeroInfo.MakeSkill2.mIndex, mHeroInfo.MakeSkill2.mStep, mHeroInfo.MakeSkill2.mExp, pGroupInfo->mMakeSkill, pGroup->mStep, pGroup->mExp ); return ERROR_MAKESKILL_RECIPE_ADD_STEP; } if( mHeroInfo.MakeSkill2.mExp < pGroup->mExp ) { NETWORK2->PostServerEvent( "WARNING - cPlayer::AddRecipe - RECIPEGROUP2 - index(%c), step(%c), exp(%ld) / index(%c), step(%c), exp(%ld)", mHeroInfo.MakeSkill2.mIndex, mHeroInfo.MakeSkill2.mStep, mHeroInfo.MakeSkill2.mExp, pGroupInfo->mMakeSkill, pGroup->mStep, pGroup->mExp ); return ERROR_MAKESKILL_RECIPE_ADD_EXP; } cRecipeGroup::cIterator end = mRecipeGroup2.End(); if( mRecipeGroup2.Find( pGroupInfo->mRecipeIdx ) == end ) { pMakeSkill->mRecipeGroup[pMakeSkill->mRowCnt].mRecipeIdx = pGroupInfo->mRecipeIdx; pMakeSkill->mRecipeGroup[pMakeSkill->mRowCnt].mMakeSkill = pGroupInfo->mMakeSkill; ++pMakeSkill->mRowCnt; } } } unsigned long inventoryIdx = inventory->idx; if ( inventory->count == 1 ) RemoveInventory( inventory->number ); else UpdateInventory( inventory, (-1) ); /// db ÀúÀå pMakeSkill->mCharacterIdx = mObject.index; pMakeSkill->mInventoryIdx = inventoryIdx; pMakeSkill->mRetvalue = -1; return (NETWORK2->SendSQL( mConnectionIdx, handle, pMakeSkill->GetMsgLength() ) ) ? ERROR_MAKESKILL_RECIPE_ADD_SUCCESS : ERROR_MAKESKILL_RECIPE_ADD_DBERROR; } else return ERROR_MAKESKILL_RECIPE_ADD_ITEM; } void cPlayer::SetMakeSkill( MAKESKILL_INSERT* pInsert ) { bool IsfirstSkill = false; unsigned char makeSkill = 0; unsigned char makeSkillStep = 0; if( pInsert != NULL ) { IsfirstSkill = pInsert->mIsFirstSkill; makeSkill = pInsert->mMakeSkillIdx; makeSkillStep = pInsert->mMakeSkillStep; } else NETWORK2->PostServerEvent("cPlayer::SetMakeSkill pInsert == NULL[%d]", mObject.index ); if( IsfirstSkill == true ) { mHeroInfo.MakeSkill1.mIndex = makeSkill; mHeroInfo.MakeSkill1.mStep = makeSkillStep; } else { mHeroInfo.MakeSkill2.mIndex = makeSkill; mHeroInfo.MakeSkill2.mStep = makeSkillStep; } HANDLE handle = NULL; MSG_RES_MAKESKILL_ADD* sendMsg = (MSG_RES_MAKESKILL_ADD*)NETWORK2->GetMsgRoot( &handle ,mConnectionIdx ,NM_MAKESKILL ,NM_MAKESKILL_ADD_RES ); if( sendMsg != NULL ) { sendMsg->mMakeSkill = makeSkill; sendMsg->mMakeSkillStep = makeSkillStep; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_MAKESKILL_ADD) ); } // Äù½ºÆ®¹ß»ý SendNewQuestList(); } unsigned char cPlayer::ReqDelMakeSkill( unsigned char makeSkill ) { if( IsMakeSkill( makeSkill ) == false ) return ERROR_MAKESKILL_DEL_NOTHAVE; /// db ÀúÀå HANDLE handle = NULL; MAKESKILL_DELETE* pMakeSkill= (MAKESKILL_DELETE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_MAKESKILL_DELETE ); pMakeSkill->mCharacterIdx = mObject.index; pMakeSkill->mMakeSkillIdx = makeSkill; pMakeSkill->mRetvalue = -1; return (NETWORK2->SendSQL( mConnectionIdx, handle, sizeof(MAKESKILL_DELETE) ) ) ? ERROR_MAKESKILL_DEL_SUCCESS : ERROR_MAKESKILL_DEL_DBERROR; } void cPlayer::DelMakeSkill( unsigned char makeSkillIdx ) { if( mHeroInfo.MakeSkill1.mIndex == makeSkillIdx ) { mHeroInfo.MakeSkill1.mIndex = 0; mHeroInfo.MakeSkill1.mStep = 0; mHeroInfo.MakeSkill1.mExp = 0; mRecipeGroup1.Clear(); } else if( mHeroInfo.MakeSkill2.mIndex == makeSkillIdx ) { mHeroInfo.MakeSkill2.mIndex = 0; mHeroInfo.MakeSkill2.mStep = 0; mHeroInfo.MakeSkill2.mExp = 0; mRecipeGroup2.Clear(); } HANDLE handle = NULL; MSG_RES_MAKESKILL_DELETE* sendMsg = (MSG_RES_MAKESKILL_DELETE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_MAKESKILL, NM_MAKESKILL_DEL_RES ); if( sendMsg != NULL ) { sendMsg->mMakeSkill = makeSkillIdx; sendMsg->ErrorCode = ERROR_MAKESKILL_DEL_SUCCESS; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_MAKESKILL_DELETE) ); } } void cPlayer::SetRecipe( unsigned char makeSkill, unsigned long recipeIdx ) { if( makeSkill == mHeroInfo.MakeSkill1.mIndex ) { if( mRecipeGroup1.Insert( recipeIdx, 0 ) == false ) NETWORK2->PostServerEvent("cPlayer::SetRecipe mRecipeGroup1.Insert( %d,%d,%d ) == false", mObject.index, makeSkill, recipeIdx ); } else if( makeSkill == mHeroInfo.MakeSkill2.mIndex ) { if( mRecipeGroup2.Insert( recipeIdx, 0 ) == false ) NETWORK2->PostServerEvent("cPlayer::SetRecipe mRecipeGroup2.Insert( %d,%d,%d ) == false", mObject.index, makeSkill, recipeIdx ); } else NETWORK2->PostServerEvent("cPlayer::SetRecipe else( %d,%d,%d ) == false", mObject.index, makeSkill, recipeIdx ); HANDLE handle = NULL; MSG_RES_MAKESKILL_RECIPE_ADD* sendMsg = (MSG_RES_MAKESKILL_RECIPE_ADD *)NETWORK2->GetMsgRoot( &handle ,mConnectionIdx ,NM_MAKESKILL ,NM_MAKESKILL_RECIPE_ADD_RES ); if( sendMsg != NULL ) { sendMsg->mGroupInfo[sendMsg->mCount].mMakeSkill = makeSkill; sendMsg->mGroupInfo[sendMsg->mCount].mRecipeIdx = recipeIdx; sendMsg->mCount = 1; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_MAKESKILL_RECIPE_ADD) ); } } void cPlayer::SetRecipeGroup( sRecipeGroupInfo* groupInfo, unsigned long cnt ) { HANDLE handle = NULL; MSG_RES_MAKESKILL_RECIPE_ADD* sendMsg = (MSG_RES_MAKESKILL_RECIPE_ADD*)NETWORK2->GetMsgRoot( &handle ,mConnectionIdx ,NM_MAKESKILL ,NM_MAKESKILL_RECIPE_ADD_RES ); if( sendMsg != NULL ) { for( unsigned long i = 0 ; i < cnt ; ++i ) { if( groupInfo[i].mMakeSkill == mHeroInfo.MakeSkill1.mIndex ) { if( mRecipeGroup1.Insert( groupInfo[i].mRecipeIdx, 0 ) == false ) NETWORK2->PostServerEvent("cPlayer::SetRecipe mRecipeGroup1.Insert( %d,%d,%d ) == false", mObject.index, groupInfo[i].mMakeSkill, groupInfo[i].mRecipeIdx ); } else if( groupInfo[i].mMakeSkill == mHeroInfo.MakeSkill2.mIndex ) { if( mRecipeGroup2.Insert( groupInfo[i].mRecipeIdx, 0 ) == false ) NETWORK2->PostServerEvent("cPlayer::SetRecipe mRecipeGroup2.Insert( %d,%d,%d ) == false", mObject.index, groupInfo[i].mMakeSkill, groupInfo[i].mRecipeIdx ); } else { NETWORK2->PostServerEvent("cPlayer::SetRecipe else( %d,%d,%d ) == false", mObject.index, groupInfo[i].mMakeSkill, groupInfo[i].mRecipeIdx ); continue; } sendMsg->mGroupInfo[sendMsg->mCount].mMakeSkill = groupInfo[i].mMakeSkill; sendMsg->mGroupInfo[sendMsg->mCount].mRecipeIdx = groupInfo[i].mRecipeIdx; ++sendMsg->mCount; } NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength() ); } } bool cPlayer::InitMakeSkill( MAKESKILL_SELECT* pMakeSkill ) { TB_MAKESKILL* pTable = NULL; for( long i = 0 ; i < pMakeSkill->mRowCount ; ++i ) { pTable = &pMakeSkill->mTable[i]; if( pTable == NULL ) { NETWORK2->PostServerEvent("cPlayer::InitMakeSkill pTable == NULL[%d]", mObject.index ); continue; } if( pTable->mMakeSkill != 0 && pTable->mMakeSkill == mHeroInfo.MakeSkill1.mIndex ) /// Á¦Á¶½ºÅ³ ºñ±³ { unsigned long endTime = ( pTable->mCoolTime * SECOND ) + NETWORK2->GetAccumTime(); if( mRecipeGroup1.Insert( pTable->mRecipeIdx, endTime ) == false ) { NETWORK2->PostServerEvent("cPlayer::InitMakeSkill mRecipeGroup1[%d][%d].Insert[%d]", mObject.index, mHeroInfo.MakeSkill1.mIndex, pTable->mRecipeIdx ); return false; } } else if( pTable->mMakeSkill != 0 && pTable->mMakeSkill == mHeroInfo.MakeSkill2.mIndex ) { unsigned long endTime = ( pTable->mCoolTime * SECOND ) + NETWORK2->GetAccumTime(); if( mRecipeGroup2.Insert( pTable->mRecipeIdx, endTime ) == false ) { NETWORK2->PostServerEvent("cPlayer::InitMakeSkill mRecipeGroup2[%d][%d].Insert[%d]", mObject.index, mHeroInfo.MakeSkill2.mIndex, pTable->mRecipeIdx ); return false; } } else { NETWORK2->PostServerEvent("cPlayer::InitMakeSkill pTable->mMakeSkill[%d][%d] != ERROR", mObject.index, pTable->mMakeSkill ); continue; } } SendMsgRecipeList(); return true; } void cPlayer::SendMsgRecipeList() { HANDLE handle = NULL; cRecipeGroup::cIterator start = mRecipeGroup1.Begin(); cRecipeGroup::cIterator end = mRecipeGroup1.End(); MSG_RES_MAKESKILL_LIST* sendMsg = (MSG_RES_MAKESKILL_LIST*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_MAKESKILL, NM_MAKESKILL_LIST1_RES ); if( sendMsg != NULL ) { unsigned short i = 0; for( ; start != end ; ++start, ++i ) { sendMsg->mRecipeInfo[i].mRecipeIdx = (*start).mFirst; unsigned long endCoolTime = (*start).mSecond; unsigned long accumTime = NETWORK2->GetAccumTime(); if( endCoolTime > accumTime ) sendMsg->mRecipeInfo[i].mCoolTime = endCoolTime - accumTime; else sendMsg->mRecipeInfo[i].mCoolTime = 0; } sendMsg->mCount = i; NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength( ) ); } start = mRecipeGroup2.Begin(); end = mRecipeGroup2.End(); sendMsg = (MSG_RES_MAKESKILL_LIST*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_MAKESKILL, NM_MAKESKILL_LIST2_RES ); if( sendMsg != NULL ) { unsigned short i = 0; for( ; start != end ; ++start, ++i ) { sendMsg->mRecipeInfo[i].mRecipeIdx = (*start).mFirst; unsigned long endCoolTime = (*start).mSecond; unsigned long accumTime = NETWORK2->GetAccumTime(); if( endCoolTime > accumTime ) sendMsg->mRecipeInfo[i].mCoolTime = endCoolTime - accumTime; else sendMsg->mRecipeInfo[i].mCoolTime = 0; } sendMsg->mCount = i; NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength( ) ); } } bool cPlayer::IsMakeSkill( unsigned char makeSkillIdx ) { if( makeSkillIdx == 0 ) return false; if( mHeroInfo.MakeSkill1.mIndex == makeSkillIdx ) return true; if( mHeroInfo.MakeSkill2.mIndex == makeSkillIdx ) return true; return false; } int cPlayer::ItemMixReq( unsigned char makeSkill, unsigned long mixRecipeIdx, unsigned short makeCnt ) { /// db »ç¿ëºÎ üũ if ( mInventoryDatabase ) return ERROR_MAKESKILL_START_DBERROR; /// Á¶ÇÕ ºÒ°¡´É üũ if( mPlayerExrInfo.mIsDuelIdx ) return ERROR_MAKESKILL_START_STATE; /// Ç÷¹ÀÌ¾î »óÅ üũ ( ½ºÅÏ, ½½¸³ ) if( GetStateOddity( eODDITYTYPE_SLEEP ) != 0 ) return ERROR_MAKESKILL_START_STATE; if( GetStateOddity( eODDITYTYPE_STUN ) != 0 ) return ERROR_MAKESKILL_START_STATE; if( (int)mStatus2.mMaxWeight <= mItemWeight ) return ERROR_MAKESKILL_START_STATE; /// ½ºÅ©¸³Æ® üũ sMakeSkillScript* pScript = MAKESKILLSCRIPT->GetMakeSkill( mixRecipeIdx ); if( pScript == NULL ) { NETWORK2->PostServerEvent( "cPlayer::ItemMixStart pScript[%d][%d] == NULL", mObject.index, mixRecipeIdx ); return ERROR_MAKESKILL_START_SCRIPT; } /// º¸À¯ ¿©ºÎ üũ if( makeSkill == mHeroInfo.MakeSkill1.mIndex ) { /// ´Ü°è if( mHeroInfo.MakeSkill1.mStep < pScript->mMakeStep ) return ERROR_MAKESKILL_START_STEP; /// ¼÷·Ãµµ if( mHeroInfo.MakeSkill1.mExp < pScript->mMinExp ) return ERROR_MAKESKILL_START_EXP; /// ÄðŸÀÓ Ã¼Å© cRecipeGroup::cIterator find = mRecipeGroup1.Find( mixRecipeIdx ); cRecipeGroup::cIterator end = mRecipeGroup1.End(); if( find == end || (*find).mSecond > NETWORK2->GetAccumTime() ) return ERROR_MAKESKILL_START_COOLTIME; } else if( makeSkill == mHeroInfo.MakeSkill2.mIndex ) { if( mHeroInfo.MakeSkill2.mStep < pScript->mMakeStep ) return ERROR_MAKESKILL_START_STEP; if( mHeroInfo.MakeSkill2.mExp < pScript->mMinExp ) return ERROR_MAKESKILL_START_EXP; cRecipeGroup::cIterator find = mRecipeGroup2.Find( mixRecipeIdx ); cRecipeGroup::cIterator end = mRecipeGroup2.End(); if( find == end || (*find).mSecond > NETWORK2->GetAccumTime() ) return ERROR_MAKESKILL_START_COOLTIME; } else return ERROR_MAKESKILL_START_HAVESKILL; /// »óÅ º¯°æ if( ChangeState( eOBJECT_STATE_STOP ) == false ) return ERROR_MAKESKILL_START_STATE; SetStateStop( eSTOP_ITEMMIX ); /// Á¶ÇÕ Á¤º¸ ±â·Ï mMixRecipeIdx = mixRecipeIdx; mMixMakeSkill = makeSkill; mMixCnt = makeCnt; mItemMixEndTime = NETWORK2->GetAccumTime() + pScript->mMakeTime; return ERROR_MAKESKILL_START_SUCCESS; } int cPlayer::ItemMix( sMakeSkillScript* script ) { if( script == NULL ) return ERROR_MAKESKILL_END_ITEM; if( mItemMixEndTime > NETWORK2->GetAccumTime() + 1000 ) return ERROR_MAKESKILL_END_TIME; /// »óÅ üũ if( GetState() != eOBJECT_STATE_STOP ) return ERROR_MAKESKILL_END_STATE; if( GetStateStop() != eSTOP_ITEMMIX ) return ERROR_MAKESKILL_END_STATE; tArray* array = script->mpMaterial; if ( array == NULL ) return ERROR_MAKESKILL_END_ITEM; // Àκ¥Å丮 Àç·á °Ë»ç. for ( unsigned long i = 0; i < array->GetSize( ); ++i ) { sMaterialScript* material = (sMaterialScript*)(*array)[i]; PerItemCount* itemCount = ITEMCOUNTPOOL->SearchItemCount( &mItemCountRoot, material->mItemIdx ); if ( itemCount != NULL ) { if ( itemCount->bag < material->mItemCnt ) return ERROR_MAKESKILL_END_ITEM; } else return ERROR_MAKESKILL_END_ITEM; } // Àκ¥Å丮 ¿µ¿ª °Ë»ç & Á¶ÇÕ È®·ü ó¸®. unsigned long* makeItem; // ij½ºÆÃ Æ÷ÀÎÅÍ - Á¶ÇÕ°á°ú ¾ÆÀÌÅÛ unsigned char* makeCount; // " - Á¶ÇÕ°á°ú ¼ö·® unsigned short* makeRate; // " - Á¶ÇÕ È®·ü int sumRate; // ÇÕ°è È®·ü. int addRate; // ´©Àû È®·ü. int rndRate; // ·¥´ý È®·ü. long mixItem; // °á°ú. short mixCount; // °á°ú. makeItem = script->mMakeItemIdx; makeCount = script->mMakeCnt; makeRate = script->mMakeRate; sumRate = 0; for ( int i = 0; (i < MAKESKILL_MAKE_ITEM_CNT) && ((*makeItem) > 0) && ((*makeCount) > 0); i++, makeItem++, makeCount++, makeRate++ ) { if ( CheckInventory( (*makeItem), (*makeCount) ) == false ) return ERROR_MAKESKILL_END_ITEM; sumRate += (*makeRate); } makeItem = script->mMakeItemIdx; makeCount = script->mMakeCnt; makeRate = script->mMakeRate; addRate = 0; unsigned long randValue = (unsigned long)( RANDOMTABLE->Get( ) * 1000000 ); rndRate = randValue % sumRate; mixItem = 0; mixCount = 0; for ( int i = 0; (i < MAKESKILL_MAKE_ITEM_CNT) && ((*makeItem) > 0) && ((*makeCount) > 0); i++, makeItem++, makeCount++, makeRate++ ) { addRate += (*makeRate); if ( rndRate < addRate ) { mixItem = (*makeItem); mixCount = (*makeCount); break; } } if ( !( mixItem > 0 && mixCount > 0 ) ) return ERROR_MAKESKILL_END_ITEM; TB_ITEM_DEFINE* mixItemDefine = ITEMMANAGER->GetItemDefineByIndex( mixItem ); if( mixItemDefine == NULL ) return ERROR_MAKESKILL_END_ITEM; /// ³²Àº º¸À¯°¹¼ö ¸¸Å­¸¸ ¸¸µç´Ù. - IsMaxInventory if ( mixItemDefine->maxInventory > 0 ) { long sumCount = GetItemSumCount( mixItemDefine->index ); if( mixItemDefine->maxInventory < (sumCount + mixCount) ) { mixCount = (short)(mixItemDefine->maxInventory - sumCount); if( mixCount <= 0 ) return ERROR_MAKESKILL_END_MAX_ITEM; } } HANDLE handle = NULL; ITEM_MIX* itemMix = (ITEM_MIX*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_MIX ); long length = sizeof(ITEM_MIX) - sizeof(itemMix->table); TB_INVENTORY* table = itemMix->table; long& rowCount = itemMix->rowCount; itemMix->characterIdx = mObject.index; // Àç·á ¾ÆÀÌÅÛ Â÷°¨. for ( unsigned long i = 0; i < array->GetSize( ); ++i ) { sMaterialScript* material = (sMaterialScript*)(*array)[i]; TB_INVENTORY* tempInv = SelectInventory( INVENTORY_BAG_BEGIN ); short remainCount = material->mItemCnt; short shortCount; for ( short k = INVENTORY_BAG_BEGIN; (k <= mHeroInfo.BagEnd) && (remainCount > 0); k++, tempInv++ ) { if ( (long)material->mItemIdx == tempInv->itemDefineIndex ) { shortCount = UpdateInventory( tempInv, (-remainCount) ); remainCount = remainCount + shortCount; (*table) = (*tempInv); table->count = shortCount; table++; rowCount++; if ( tempInv->count == 0 ) RemoveInventory( tempInv ); } } } // Á¶ÇÕ ¾ÆÀÌÅÛ »ý¼º. { short remainCount = mixCount; TB_INVENTORY* tempInv = NULL; short shortCount = 0; short number = 0; // ¾ÆÀÌÅÛ Á¶ÇÕ º¸»ó. °ãÄ¡±â °Ë»ç ¹× ó¸®. if ( FindFirstInventory( mixItemDefine, &number, remainCount, &shortCount, true ) == true ) { do { tempInv = SelectInventory( number ); shortCount = UpdateInventory( tempInv, remainCount ); remainCount = remainCount - shortCount; (*table) = (*tempInv); table->count = (+shortCount); table++; rowCount++; } while ( FindNextInventory( mixItemDefine, &(++number), remainCount, &shortCount, true ) == true ); } // ¾ÆÀÌÅÛ Á¶ÇÕ º¸»ó. »ý¼º °Ë»ç ¹× µî·Ï. if ( FindFirstInventory( mixItemDefine, &number, remainCount, &shortCount, false ) == true ) { do { CreateInventory( mixItemDefine, number, remainCount, &(shortCount=0) ); remainCount = remainCount - shortCount; table->idx = 0; table->itemDefineIdx = mixItemDefine->idx; table->itemDefineIndex = mixItemDefine->index; table->number = number; table->count = (+shortCount); table++; rowCount++; } while ( FindNextInventory( mixItemDefine, &(++number), remainCount, &shortCount, false ) == true ); } } length += sizeof(TB_INVENTORY) * itemMix->rowCount; mInventoryDb.itemMix = NETWORK2->SendSQL( mConnectionIdx, handle, length ); return ERROR_MAKESKILL_END_SUCCESS; } void cPlayer::ItemMixEnd() { sMakeSkillScript* pScript = MAKESKILLSCRIPT->GetMakeSkill( mMixRecipeIdx ); if( pScript != NULL ) { /// ½ÇÁ¦ ¾ÆÀÌÅÛÀ» Á¶ÇÕÇÔ - db󸮿äû int errorCode = ItemMix( pScript ); if( errorCode != ERROR_MAKESKILL_END_SUCCESS ) { mMixCnt = 0; /// Á¾·á ¼³Á¤ } else /// ´ÙÀ½ Á¶ÇÕ ½Ã°£ ¼³Á¤ { unsigned long oldExp = 0; // ±âÁ¸ exp°ª unsigned long mixExp = 0; mItemMixEndTime = NETWORK2->GetAccumTime() + pScript->mMakeTime; --mMixCnt; /// Á¶ÇÕ °¹¼ö °¨¼Ò /// ÄðŸÀÓÀÌ ÀÖÀ¸¸é Á¶ÇÕ Áß´Ü if( pScript->mNextMakeTime != 0 ) mMixCnt = 0; /// ÄðŸÀÓ º¯°æ if( mMixMakeSkill == mHeroInfo.MakeSkill1.mIndex ) { oldExp = mHeroInfo.MakeSkill1.mExp; MakeSkillExpPlus( &mHeroInfo.MakeSkill1, pScript ); mixExp = mHeroInfo.MakeSkill1.mExp; cRecipeGroup::cIterator find = mRecipeGroup1.Find( mMixRecipeIdx ); cRecipeGroup::cIterator end = mRecipeGroup1.End(); if( find != end ) (*find).mSecond = NETWORK2->GetAccumTime() + pScript->mNextMakeTime; } else if( mMixMakeSkill == mHeroInfo.MakeSkill2.mIndex ) { oldExp = mHeroInfo.MakeSkill2.mExp; MakeSkillExpPlus( &mHeroInfo.MakeSkill2, pScript ); mixExp = mHeroInfo.MakeSkill2.mExp; cRecipeGroup::cIterator find = mRecipeGroup2.Find( mMixRecipeIdx ); cRecipeGroup::cIterator end = mRecipeGroup2.End(); if( find != end ) (*find).mSecond = NETWORK2->GetAccumTime() + pScript->mNextMakeTime; } HANDLE handle = NULL; MSG_SYN_MAKESKILL_ITEMMIX_EXP* sendMsg = (MSG_SYN_MAKESKILL_ITEMMIX_EXP*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_MAKESKILL, NM_MAKESKILL_ITEMMIX_EXP_SYN ); if ( sendMsg != NULL ) { sendMsg->mMakeSkill = mMixMakeSkill; sendMsg->mMakeSkillExp = mixExp; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_MAKESKILL_ITEMMIX_EXP) ); } // Á¶ÇÕ °æÇèÄ¡°¡ ¿Ã¶ó°£ °æ¿ì Äù½ºÆ® üũ if( mixExp > oldExp ) { SendNewQuestList(); } } /// ´õ ÁøÇà ³»¿ªÀÌ ¾øÀ¸¸é Á¾·á ¹ß¼Û if ( mMixCnt == 0 ) { mItemMixEndTime = 0; mMixMakeSkill = 0; mMixRecipeIdx = 0; MSG_SYN_MAKESKILL_ITEMMIX_END synMsg; synMsg.Category = NM_MAKESKILL; synMsg.Protocol = NM_MAKESKILL_ITEMMIX_END_SYN; synMsg.mCharacterIdx = mObject.index; synMsg.ErrorCode = errorCode; NETWORK2->QuickSend( this, (char*)&synMsg, sizeof(MSG_SYN_MAKESKILL_ITEMMIX_END) ); /// »óÅ Ǯ¾îÁÜ if ( GetState( ) == eOBJECT_STATE_STOP && GetStateStop( ) == eSTOP_ITEMMIX ) { ChangeState( eOBJECT_STATE_IDLE ); SetStateStop( eSTOP_NONE ); } } else { MSG_SYN_MAKESKILL_ITEMMIX_MIDDLEEND synMsg; synMsg.Category = NM_MAKESKILL; synMsg.Protocol = NM_MAKESKILL_ITEMMIX_MIDDLEEND_SYN; synMsg.mCharacterIdx = mObject.index; NETWORK2->QuickSend( this, (char*)&synMsg, sizeof(MSG_SYN_MAKESKILL_ITEMMIX_MIDDLEEND) ); } } } void cPlayer::ItemMixCancel() { if( GetStateStop( ) != eSTOP_ITEMMIX ) return; /// Á¶ÇÕ ¼³Á¤ ²û mItemMixEndTime = 0; mMixRecipeIdx = 0; mMixMakeSkill = 0; /// Ç÷¹ÀÌ¾î »óŸ¦ Ç®¾îÁÜ if ( GetState( ) == eOBJECT_STATE_STOP && GetStateStop( ) == eSTOP_ITEMMIX ) { ChangeState( eOBJECT_STATE_IDLE ); SetStateStop( eSTOP_NONE ); } /// hero¿ÜÀÇ Ç÷¹À̾°Ô Ãë¼Ò È®ÀÎ ¸Þ¼¼Áö ¹ß¼Û MSG_SYN_MAKESKILL_ITEMMIX_CANCEL synMsg; synMsg.Category = NM_MAKESKILL; synMsg.Protocol = NM_MAKESKILL_ITEMMIX_CANCEL_SYN; synMsg.mCharacterIdx = mObject.index; NETWORK2->QuickSendExcept( this, (char*)&synMsg, sizeof(MSG_SYN_MAKESKILL_ITEMMIX_CANCEL) ); /// db ó¸®ÁßÀÎ ³»¿ëÀÌ ÀÖÀ¸¸é Ŭ¶óÀÌ¾ðÆ®¿¡ ¾Ë¸² int retcode = ( mInventoryDb.itemMix == true ) ? ERROR_MAKESKILL_CANCEL_DBWORK : ERROR_MAKESKILL_CANCEL_SUCCESS; NETWORK2->SendMsgError( mConnectionIdx, NM_MAKESKILL, NM_MAKESKILL_ITEMMIX_CANCEL_RES, retcode ); } void cPlayer::ItemMixForceCancel() { /// Á¶ÇÕ ÁøÇàÁßÀÎÁö üũ if( GetStateStop( ) != eSTOP_ITEMMIX ) return; /// Á¶ÇÕ ¼³Á¤ ²û mItemMixEndTime = 0; mMixRecipeIdx = 0; mMixMakeSkill = 0; /// Ç÷¹ÀÌ¾î »óŸ¦ Ç®¾îÁÜ if ( GetState( ) == eOBJECT_STATE_STOP && GetStateStop( ) == eSTOP_ITEMMIX ) { ChangeState( eOBJECT_STATE_IDLE ); SetStateStop( eSTOP_NONE ); } /// hero ¿¡°Ô ¹ß¼Û MSG_SYN_MAKESKILL_ITEMMIX_CANCELFORCE msg; msg.Category = NM_MAKESKILL; msg.Protocol = NM_MAKESKILL_ITEMMIX_CANCELFORCE_SYN; NETWORK2->QuickSend( this, (char*)&msg, sizeof(MSG_SYN_MAKESKILL_ITEMMIX_CANCELFORCE) ); /// hero¿ÜÀÇ Ç÷¹À̾°Ô Ãë¼Ò È®ÀÎ ¸Þ¼¼Áö ¹ß¼Û MSG_SYN_MAKESKILL_ITEMMIX_CANCEL synMsg; synMsg.Category = NM_MAKESKILL; synMsg.Protocol = NM_MAKESKILL_ITEMMIX_CANCEL_SYN; synMsg.mCharacterIdx = mObject.index; NETWORK2->QuickSendExcept( this, (char*)&synMsg, sizeof(MSG_SYN_MAKESKILL_ITEMMIX_CANCEL) ); } bool cPlayer::SaveRecipeCoolTime( RECIPE_COOLTIME* pRecipeCoolTime ) { pRecipeCoolTime->mCharacterIdx = mObject.index; pRecipeCoolTime->mRetvalue = -1; unsigned long row = 0; if( mHeroInfo.MakeSkill1.mIndex != 0 ) { cRecipeGroup::cIterator begin = mRecipeGroup1.Begin(); cRecipeGroup::cIterator end = mRecipeGroup1.End(); for( ; begin != end ; ++begin ) { TB_RECIPE_COOLTIME* pCoolTime = &pRecipeCoolTime->mTable[row]; if( pCoolTime != NULL && (*begin).mSecond > NETWORK2->GetAccumTime() ) { pCoolTime->mMakeSkill = mHeroInfo.MakeSkill1.mIndex; pCoolTime->mRecipeIdx = (*begin).mFirst; pCoolTime->mLeftCoolTime = (*begin).mSecond - NETWORK2->GetAccumTime(); ++row; } } } if( mHeroInfo.MakeSkill2.mIndex != 0 ) { cRecipeGroup::cIterator begin = mRecipeGroup2.Begin(); cRecipeGroup::cIterator end = mRecipeGroup2.End(); for( ; begin != end ; ++begin ) { TB_RECIPE_COOLTIME* pCoolTime = &pRecipeCoolTime->mTable[row]; if( pCoolTime != NULL && (*begin).mSecond > NETWORK2->GetAccumTime() ) { pCoolTime->mMakeSkill = mHeroInfo.MakeSkill2.mIndex; pCoolTime->mRecipeIdx = (*begin).mFirst; pCoolTime->mLeftCoolTime = (*begin).mSecond - NETWORK2->GetAccumTime(); ++row; } } } pRecipeCoolTime->mRowCount = row; return true; } void cPlayer::MakeSkillExpPlus( sMakeSkill* pMakeSkill, sMakeSkillScript* Recipe ) { if( !pMakeSkill ) return; if( pMakeSkill->mExp >= Recipe->mMaxDefaultExp && pMakeSkill->mExp < Recipe->mMaxExp ) ++pMakeSkill->mExp; else if( pMakeSkill->mExp >= Recipe->mMinDefaultExp && pMakeSkill->mExp < Recipe->mMaxDefaultExp) pMakeSkill->mExp += 2; else if( pMakeSkill->mExp >= Recipe->mMinExp && pMakeSkill->mExp < Recipe->mMinDefaultExp) pMakeSkill->mExp += 3; /// ÃÖ´ë ¸ñǥġ üũ unsigned long maxStepExp = 0; switch( pMakeSkill->mStep ) { case ITEM_MIX_SKILL_L1: maxStepExp = MIXSKILL_EXP1; break; case ITEM_MIX_SKILL_L2: maxStepExp = MIXSKILL_EXP2; break; case ITEM_MIX_SKILL_L3: maxStepExp = MIXSKILL_EXP3; break; case ITEM_MIX_SKILL_L4: maxStepExp = MIXSKILL_EXP4; break; default: return; } if( maxStepExp != 0 && pMakeSkill->mExp > maxStepExp ) pMakeSkill->mExp = maxStepExp; } bool cPlayer::SkillPointMinus( unsigned short minusSP ) { if( mHeroInfo.SkillPointRemain - minusSP < 0 ) { return false; } mHeroInfo.SkillPointRemain = mHeroInfo.SkillPointRemain - minusSP; return true; } void cPlayer::SkillPointMinusRestore( unsigned short minusSP ) { mHeroInfo.SkillPointRemain = mHeroInfo.SkillPointRemain + minusSP; } bool cPlayer::SkillPointPlus( unsigned short plusSP ) { if( mHeroInfo.SkillPointRemain + plusSP > USHRT_MAX ) { return false; } mHeroInfo.SkillPointRemain = mHeroInfo.SkillPointRemain + plusSP; mHeroInfo.SkillPointTotal = mHeroInfo.SkillPointTotal + plusSP; // ij¸¯ÅÍ À̺¥Æ®. PostCharacterEvent( EVENT_CHARACTER_UPDATE, "Skill - PointPlus" ); SendSkillPoint(); return true; } void cPlayer::SetSkillReset( TB_CHARACTER_SKILL* pSkill, long cnt ) { mHeroInfo.SkillPointRemain = mHeroInfo.SkillPointTotal; /// ½ºÅ³ ÃʱâÈ­ SKILLMANAGER->ReleasePlayerHaveSkill( mObject.index ); /// ÀÚ½ÅÀÌ »ç¿ëÇÑ ¿À¶óÈ¿°ú ¸ðµÎ Á¦°Å SKILLMANAGER->SwitchParentAllOff( mObject.index ); /// ±âº» °ø°Ý µî·Ï SKILLMANAGER->AddSkillReset( mObject.index, NORMAL_ATTACK_SKILL, SKILL_START_STEP ); HANDLE handle = NULL; MSG_RES_PLAYER_SKILLRESET* sendMsg = (MSG_RES_PLAYER_SKILLRESET*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_SKILLRESET_RES ); if ( sendMsg != NULL ) { sendMsg->ErrorCode = ERROR_SKILLRESET_SUCCESS; sendMsg->mRowCount = cnt; sendMsg->mSkillPoint = mHeroInfo.SkillPointRemain; for( long i = 0 ; i < cnt ; ++i ) { /// ±âº» º¸À¯ ½ºÅ³ µî·Ï SKILLMANAGER->AddSkillReset( mObject.index, pSkill[i].mSkillIdx, pSkill[i].mSkillStep ); sendMsg->mTable[i].mSkillIdx = pSkill[i].mSkillIdx; sendMsg->mTable[i].mSkillStep = pSkill[i].mSkillStep; } NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength() ); } } void cPlayer::SendSkillPoint() { HANDLE handle = NULL; MSG_RES_PLAYER_SP* sendMsg = (MSG_RES_PLAYER_SP*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_SP_RES ); if ( sendMsg != NULL ) { unsigned long length = sizeof(MSG_RES_PLAYER_SP) - sizeof(sendMsg->usedSP); sendMsg->mSP = mHeroInfo.SkillPointRemain; sendMsg->mTotalSP = mHeroInfo.SkillPointTotal; unsigned short* list = sendMsg->usedSP; for( unsigned long i = 0; i < mJobUsedSpArr.GetSize(); ++i, ++list ) { *list = mJobUsedSpArr[i]; sendMsg->rowCount++; } length += (sendMsg->rowCount * sizeof(sendMsg->usedSP)); NETWORK2->SendMsgRoot( handle, length ); } } bool cPlayer::MapChange( unsigned long posIdx ) { /// ¸ÊÀ̵¿Áß ¸ÊÀ̵¿ÀÌ ¿Ã¼ö¾øÀ½ if( mMapChange == true ) return false; if( IsAutoTrial() == true ) return false; /// 2Â÷»óÅ üũ if( IsRequestRejection() == true ) return false; float tempRange = OBJECTMANAGER->ObjectSizeRange( this, NULL, 0 ); // À̵¿ ÁÂÇ¥¸¦ ¾ò¾î¿È sTargetPos targetPos; memset( &targetPos, 0 , sizeof(sTargetPos) ); switch( NETWORK2->GetServerType() ) { case _E_ST_ID_PVP_: targetPos = STAGESCRIPT->GetStageChangePos( mObjectPos.x, mObjectPos.y, NETWORK2->GetInDunMapNum(), tempRange, posIdx ); break; case _E_ST_ID_THEME_: { sStageChangePos* pPos = STAGESCRIPT->GetPosScriptInfo( posIdx ); if( pPos != NULL && pPos->mFirstRegen == true ) { targetPos = STAGESCRIPT->GetStageChangePos( pPos->mTargetPosIdx ); } else { NETWORK2->PostServerEvent("cPlayer::MapChange _E_ST_ID_THEME_[%d,%d,%d]", mObject.index, posIdx, NETWORK2->GetInDunMapNum() ); targetPos = STAGESCRIPT->GetStageChangePos( CHARACTER_CREATE_POS_IDX ); } } break; case _E_ST_NORMAL_MAP_: targetPos = STAGESCRIPT->GetStageChangePos( mObjectPos.x, mObjectPos.y, mMapNumber, tempRange, posIdx ); break; case _E_ST_ID_TUTORIAL_: { NETWORK2->PostServerEvent("cPlayer::MapChange _E_ST_ID_TUTORIAL_[%d,%d,%d]", mObject.index, posIdx, NETWORK2->GetInDunMapNum() ); return false; } break; } /// À̵¿ ÁÂÇ¥ ¿À·ù if( targetPos.mMapNumber == 0 ) return false; /// ¸ÊÀ̵¿ °¡´ÉÀÎÁö ÇöÀç »óÅ üũ if( IsChangeState( eOBJECT_STATE_MOVE ) == false ) return false; /// ¸ÊÀ̵¿ ¸ñÀûÁö°¡ ÇöÀç ¸Ê°ú °°´Ù¸é ÅÚ·¹Æ÷Æ®¸¦ ½ÃŲ´Ù. switch( NETWORK2->GetServerType() ) { case _E_ST_NORMAL_MAP_: { mMapChange = true; } break; case _E_ST_ID_PVP_: { return false; } break; case _E_ST_ID_THEME_: { mIsInDunJoin = false; mMapChange = false; mMapNumber = targetPos.mMapNumber; mGotoX = mObjectPos.x = targetPos.mPosX; mGotoY = mObjectPos.y = targetPos.mPosY; mDirection = targetPos.mRotAngle; CalcThemeReturnGameSrv( mMapNumber, mObjectPos.x, mObjectPos.y, false ); } break; case _E_ST_ID_TUTORIAL_: { /// À§¿¡¼­ üũÇÞÀ½! return false; } break; } /// À̵¿ Áö¿ª ¼³Á¤ SetMapTargetPos( targetPos ); InfluenceProcessStop(); SetStateStop( eSTOP_MAPCHANGE ); return true; } bool cPlayer::CheatMapChange( unsigned short mapNumber, float x, float y ) { /// ¸ÊÀ̵¿Áß ¸ÊÀ̵¿ÀÌ ¿Ã¼ö¾øÀ½ if( mMapChange == true ) return false; /// 2Â÷»óÅ üũ if( IsRequestRejection() == true ) return false; /// À̵¿ ÁÂÇ¥ ¿À·ù switch( NETWORK2->GetServerType() ) { case _E_ST_NORMAL_MAP_: { if( mapNumber < MAP_MIN || MAP_MAX < mapNumber ) return false; } break; case _E_ST_ID_PVP_: case _E_ST_ID_THEME_: case _E_ST_ID_TUTORIAL_: { if( mapNumber >= INDUN_MAP_MAX ) return false; } } /// À̵¿ À§Ä¡ üũ float mapMaxSize = AIMANAGER->GetPathMaxSideSize( mapNumber ); if( x < 0 || x > mapMaxSize || y < 0 || y > mapMaxSize ) return false; /// ¸ÊÀ̵¿ °¡´ÉÀÎÁö ÇöÀç »óÅ üũ if( IsChangeState( eOBJECT_STATE_MOVE ) == false ) return false; // À̵¿ ÁÂÇ¥¸¦ ¼³Á¤ sTargetPos targetPos; targetPos.mMapNumber = mapNumber; targetPos.mPosX = x; targetPos.mPosY = y; targetPos.mRotAngle = 0; /// ÁÂÇ¥°ªÀÌ 0( ÀԷ¾øÀ½)À̸é ù¹øÂ° ¸ÊÀ̵¿ Æ÷ÀÎÆ®·Î À̵¿ if( FloatToInt( x ) == 0 && FloatToInt( y ) == 0 ) { unsigned short mapDataNum = mapNumber; switch( NETWORK2->GetServerType() ) { case _E_ST_ID_PVP_: case _E_ST_ID_THEME_: case _E_ST_ID_TUTORIAL_: { mapDataNum = NETWORK2->GetInDunMapNum(); } break; } tPointerArray* ary = (tPointerArray*)STAGESCRIPT->GetMapChangeDestArr( mapDataNum ); if( ary->GetSize() == 0 ) return false; sStageChangePos* pScript = (sStageChangePos*)((*ary)[0]); if( pScript == NULL ) return false; targetPos.mPosX = pScript->mPosX; targetPos.mPosY = pScript->mPosY; } /// À̵¿ Áö¿ª ¼³Á¤ SetMapTargetPos( targetPos ); InfluenceProcessStop(); mMapChange = true; return true; } bool cPlayer::InDunMapChange( unsigned short mapNumber, unsigned short mapDataNumber, float x, float y ) { /// ¸ÊÀ̵¿Áß ¸ÊÀ̵¿ÀÌ ¿Ã¼ö¾øÀ½ if( mMapChange == true ) return false; /// 2Â÷»óÅ üũ if( IsRequestRejection() == true ) return false; /// À̵¿ ÁÂÇ¥ ¿À·ù if( mapNumber > INDUN_MAP_MAX ) return false; /// À̵¿ À§Ä¡ üũ float mapMaxSize = AIMANAGER->GetPathMaxSideSize( mapDataNumber ); if( x < 0 || x > mapMaxSize || y < 0 || y > mapMaxSize ) return false; /// ¸ÊÀ̵¿ °¡´ÉÀÎÁö ÇöÀç »óÅ üũ if( IsChangeState( eOBJECT_STATE_MOVE ) == false ) return false; // À̵¿ ÁÂÇ¥¸¦ ¼³Á¤ sTargetPos targetPos; targetPos.mMapNumber = mapNumber; targetPos.mPosX = x; targetPos.mPosY = y; targetPos.mRotAngle = 0; /// À̵¿ Áö¿ª ¼³Á¤ SetMapTargetPos( targetPos ); InfluenceProcessStop(); mPvPDMIdx = mapNumber; mIsInDunJoin = true; mInDunMapDataNum = mapDataNumber; mMapChange = true; return true; } bool cPlayer::QuestMapChange( unsigned long posIdx ) { /// ¸ÊÀ̵¿Áß ¸ÊÀ̵¿ÀÌ ¿Ã¼ö¾øÀ½ if( mMapChange == true ) { NETWORK2->PostServerEvent("cPlayer::QuestMapChange[%d,%d] mMapChange == true", mObject.index, posIdx); return false; } /// 2Â÷»óÅ üũ if( IsRequestRejection() == true ) { NETWORK2->PostServerEvent("cPlayer::QuestMapChange[%d,%d] IsRequestRejection == true", mObject.index, GetRequestRejection()); return false; } /// NPC ´ëÈ­»óÅÂÀ϶§ °­Á¦·Î Ç®±â if( GetState() == eOBJECT_STATE_STOP && GetStateStop() == eSTOP_NPCSPEECH ) { /// ´ëÈ­ÁßÀÎ npcÀ妽º¸¦ Á¦°Å SetNpcIdx( 0 ); if( ChangeState( eOBJECT_STATE_IDLE ) == true ) { SetStateStop( eSTOP_NONE ); NETWORK2->SendMsgRoot( mConnectionIdx, NM_NPC, NM_NPC_CLOSEFORCE_RES ); } } /// ¸ÊÀ̵¿ °¡´ÉÀÎÁö ÇöÀç »óÅ üũ if( IsChangeState( eOBJECT_STATE_MOVE ) == false ) { NETWORK2->PostServerEvent("cPlayer::QuestMapChange[%d] IsChangeState( eOBJECT_STATE_MOVE ) == false", mObject.index ); return false; } sStageChangePos* scriptPos = STAGESCRIPT->GetPosScriptInfo( posIdx ); if( scriptPos == NULL ) { NETWORK2->PostServerEvent("cPlayer::QuestMapChange[%d] scriptPos == NULL", mObject.index ); return false; } /// À̵¿ ÁÂÇ¥ ¿À·ù if( scriptPos->mMapNumber == 0 ) { NETWORK2->PostServerEvent("cPlayer::QuestMapChange[%d] scriptPos.mMapNumber == 0", mObject.index ); return false; } sTargetPos targetPos; ::memset( &targetPos, 0, sizeof(targetPos) ); targetPos.mMapNumber = scriptPos->mMapNumber; targetPos.mRotAngle = scriptPos->mRotAngle; bool result = false; if( NETWORK2->GetServerType() == _E_ST_NORMAL_MAP_ ) { /// À̵¿ÁÂÇ¥°¡ ¸ø°¡´Â Áö¿ªÀÏ °æ¿ì ¹üÀ§¸¦ ÂÎÇô°¡¸é¼­ À̵¿À§Ä¡¸¦ Àâ´Â´Ù. if( scriptPos->mRange > MAP_RANGE_CHECK_RING ) { for( int i = MAP_RANGE_CHECK_RING ; i > 0 ; --i ) { /// ÃÖ´ë ¹üÀ§¿¡¼­ 20%¾¿ ÁÙ¿©°¡¸é¼­ üũ int range = (int)(scriptPos->mRange * i * ( 1.0f / MAP_RANGE_CHECK_RING )); if( range <= 0 ) continue; targetPos.mPosX = scriptPos->mPosX + ( rand() % range ) - ( rand() % range ); targetPos.mPosY = scriptPos->mPosY + ( rand() % range ) - ( rand() % range ); if( AIMANAGER->IsPossible( targetPos.mMapNumber, targetPos.mPosX, targetPos.mPosY, mObject ) == false ) continue; result = true; break; } } } if( result == false ) { /// À§¿¡ ·£´ý ¹üÀ§ ÁÂÇ¥Áß ¸ðµÎ´Ù ¸ø°¡´Â °æ¿ì ½ºÅ©¸³Æ®»ó Á¤ÇØÁø °íÁ¤À§Ä¡·Î À̵¿½ÃŲ´Ù. targetPos.mPosX = scriptPos->mPosX; targetPos.mPosY = scriptPos->mPosY; } if( NETWORK2->GetServerType() == _E_ST_NORMAL_MAP_ ) { // °íÁ¤ÁÂÇ¥·Î Çѹø ´õ °Ë»ç if( result == false ) { if( AIMANAGER->IsPossible( targetPos.mMapNumber, targetPos.mPosX, targetPos.mPosY, mObject ) == false ) { NETWORK2->PostServerEvent("cPlayer::QuestMapChange[%d] return false", mObject.index ); return false; } } // mMapChange = true; /// À̵¿ Áö¿ª ¼³Á¤ SetMapTargetPos( targetPos ); InfluenceProcessStop(); // SetStateStop( eSTOP_MAPCHANGE ); /// ¸ÊÀ̵¿½Ã hp 10Àΰæ¿ì ·Î±×³²±è if( GetHP() == 10 ) { NETWORK2->PostServerEvent("cPlayer::QuestMapChange hero->GetHP(%d,%d,%d,%d %d,%d,%.2f,%.2f) == 10", mObject.index, GetMaxHP(), GetMP(), GetMaxMP(), NETWORK2->GetServerType(), mMapNumber, mObjectPos.x, mObjectPos.y ); } } else if( NETWORK2->GetServerType() == _E_ST_ID_THEME_ ) { if( NETWORK2->ReturnGameServer( GetConnectionIdx() ) == false ) return false; mIsInDunJoin = false; mMapChange = false; mMapNumber = targetPos.mMapNumber; mGotoX = mObjectPos.x = targetPos.mPosX; mGotoY = mObjectPos.y = targetPos.mPosY; mDirection = targetPos.mRotAngle; CalcThemeReturnGameSrv( mMapNumber, mObjectPos.x, mObjectPos.y, false ); } else if( NETWORK2->GetServerType() == _E_ST_ID_TUTORIAL_ ) { NETWORK2->PostServerEvent("cPlayer::QuestMapChange[%d] NETWORK2->GetServerType() == _E_ST_ID_TUTORIAL_", mObject.index ); return false; } else return false; return true; } // Æ©Å丮¾óÀ» Á¾·áÇÏ°í ±âº» ¸ÊÀ¸·Î µ¹¾Æ°£´Ù bool cPlayer::MapChangeByTutorial( unsigned long posIdx ) { /// ¸ÊÀ̵¿Áß ¸ÊÀ̵¿ÀÌ ¿Ã¼ö¾øÀ½ if( mMapChange == true ) { NETWORK2->PostServerEvent("cPlayer::MapChangeByTutorial[%d,%d] mMapChange == true", mObject.index, posIdx ); return false; } /// 2Â÷»óÅ üũ if( IsRequestRejection() == true ) { NETWORK2->PostServerEvent("cPlayer::MapChangeByTutorial[%d,%d] IsRequestRejection == true", mObject.index, GetRequestRejection()); return false; } /// NPC ´ëÈ­»óÅÂÀ϶§ °­Á¦·Î Ç®±â if( GetState() == eOBJECT_STATE_STOP && GetStateStop() == eSTOP_NPCSPEECH ) { /// ´ëÈ­ÁßÀÎ npcÀ妽º¸¦ Á¦°Å SetNpcIdx( 0 ); if( ChangeState( eOBJECT_STATE_IDLE ) == true ) { SetStateStop( eSTOP_NONE ); NETWORK2->SendMsgRoot( mConnectionIdx, NM_NPC, NM_NPC_CLOSEFORCE_RES ); } } /// ¸ÊÀ̵¿ °¡´ÉÀÎÁö if( IsChangeState( eOBJECT_STATE_MOVE ) == false ) { NETWORK2->PostServerEvent("cPlayer::MapChangeByTutorial[%d] IsChangeState( eOBJECT_STATE_MOVE ) == false", mObject.index ); return false; } sStageChangePos* scriptPos = STAGESCRIPT->GetPosScriptInfo( posIdx ); if( scriptPos == NULL ) { NETWORK2->PostServerEvent("cPlayer::MapChangeByTutorial[%d] scriptPos == NULL", mObject.index ); return false; } /// À̵¿ ÁÂÇ¥ ¿À·ù if( scriptPos->mMapNumber == 0 ) { NETWORK2->PostServerEvent("cPlayer::MapChangeByTutorial[%d] scriptPos.mMapNumber == 0", mObject.index ); return false; } sTargetPos targetPos; ::memset( &targetPos, 0, sizeof(targetPos) ); targetPos.mMapNumber = scriptPos->mMapNumber; targetPos.mRotAngle = scriptPos->mRotAngle; targetPos.mPosX = scriptPos->mPosX; targetPos.mPosY = scriptPos->mPosY; if( NETWORK2->ReturnGameServer( GetConnectionIdx() ) == false ) return false; InfluenceProcessStop(); // SetStateStop( eSTOP_MAPCHANGE ); mIsInDunJoin = false; mMapChange = false; mMapNumber = targetPos.mMapNumber; mGotoX = mObjectPos.x = targetPos.mPosX; mGotoY = mObjectPos.y = targetPos.mPosY; mDirection = targetPos.mRotAngle; ReleaseInfluenceSet( true ); /// À̵¿ Áö¿ª ¼³Á¤ SetMapTargetPos( targetPos ); CalcThemeReturnGameSrv( mMapNumber, mObjectPos.x, mObjectPos.y, false ); return true; } bool cPlayer::GMMapChangeByTutorial( unsigned short mapNum, float x, float y ) { /// ¸ÊÀ̵¿Áß ¸ÊÀ̵¿ÀÌ ¿Ã¼ö¾øÀ½ if( mMapChange == true ) { NETWORK2->PostServerEvent("cPlayer::GMMapChangeByTutorial[%d,%d] mMapChange == true", mObject.index ); return false; } /// 2Â÷»óÅ üũ if( IsRequestRejection() == true ) { NETWORK2->PostServerEvent("cPlayer::GMMapChangeByTutorial[%d,%d] IsRequestRejection == true", mObject.index, GetRequestRejection()); return false; } /// NPC ´ëÈ­»óÅÂÀ϶§ °­Á¦·Î Ç®±â if( GetState() == eOBJECT_STATE_STOP && GetStateStop() == eSTOP_NPCSPEECH ) { /// ´ëÈ­ÁßÀÎ npcÀ妽º¸¦ Á¦°Å SetNpcIdx( 0 ); if( ChangeState( eOBJECT_STATE_IDLE ) == true ) { SetStateStop( eSTOP_NONE ); NETWORK2->SendMsgRoot( mConnectionIdx, NM_NPC, NM_NPC_CLOSEFORCE_RES ); } } /// ¸ÊÀ̵¿ °¡´ÉÀÎÁö if( IsChangeState( eOBJECT_STATE_MOVE ) == false ) { NETWORK2->PostServerEvent("cPlayer::GMMapChangeByTutorial[%d] IsChangeState( eOBJECT_STATE_MOVE ) == false", mObject.index ); return false; } sTargetPos targetPos; ::memset( &targetPos, 0, sizeof(targetPos) ); targetPos.mMapNumber = mapNum; targetPos.mRotAngle = 0; targetPos.mPosX = x; targetPos.mPosY = y; if( NETWORK2->ReturnGameServer( GetConnectionIdx() ) == false ) return false; InfluenceProcessStop(); // SetStateStop( eSTOP_MAPCHANGE ); mIsInDunJoin = false; mMapChange = false; mMapNumber = targetPos.mMapNumber; mGotoX = mObjectPos.x = targetPos.mPosX; mGotoY = mObjectPos.y = targetPos.mPosY; mDirection = targetPos.mRotAngle; ReleaseInfluenceSet( true ); /// À̵¿ Áö¿ª ¼³Á¤ SetMapTargetPos( targetPos ); CalcThemeReturnGameSrv( mMapNumber, mObjectPos.x, mObjectPos.y, false ); return true; } bool cPlayer::IsItemMapChange( unsigned long posIdx ) { /// ¸ÊÀ̵¿Áß ¸ÊÀ̵¿ÀÌ ¿Ã¼ö¾øÀ½ if( mMapChange == true ) { NETWORK2->PostServerEvent("cPlayer::IsItemMapChange[%d,%d] mMapChange == true", mObject.index, posIdx); return false; } /// ¸ÊÀ̵¿ °¡´ÉÀÎÁö ÇöÀç »óÅ üũ if( IsChangeState( eOBJECT_STATE_MOVE ) == false ) { NETWORK2->PostServerEvent("cPlayer::IsItemMapChange[%d] IsChangeState( eOBJECT_STATE_MOVE ) == false", mObject.index ); return false; } if( IsAutoTrial() == true ) { NETWORK2->PostServerEvent("cPlayer::IsItemMapChange[%d] IsAutoTrial() == true", mObject.index ); return false; } sStageChangePos* scriptPos = STAGESCRIPT->GetPosScriptInfo( posIdx ); if( scriptPos == NULL ) { NETWORK2->PostServerEvent("cPlayer::IsItemMapChange[%d] scriptPos == NULL", mObject.index ); return false; } /// À̵¿ ÁÂÇ¥ ¿À·ù if( scriptPos->mMapNumber == 0 ) { NETWORK2->PostServerEvent("cPlayer::IsItemMapChange[%d] scriptPos.mMapNumber == 0", mObject.index ); return false; } if( NETWORK2->GetServerType() == _E_ST_NORMAL_MAP_ ) { if( AIMANAGER->IsPossible( scriptPos->mMapNumber, scriptPos->mPosX, scriptPos->mPosY, mObject ) == true ) return true; } else if( NETWORK2->GetServerType() == _E_ST_ID_THEME_ ) return true; else if( NETWORK2->GetServerType() == _E_ST_ID_TUTORIAL_ ) return false; else return false; return false; } bool cPlayer::ItemMapChange( unsigned long posIdx, unsigned long useItemIdx ) { /// ¸ÊÀ̵¿Áß ¸ÊÀ̵¿ÀÌ ¿Ã¼ö¾øÀ½ if( mMapChange == true ) { NETWORK2->PostServerEvent("cPlayer::ItemMapChange[%d,%d] mMapChange == true", mObject.index, posIdx); return false; } /// 2Â÷»óÅ üũ if( IsRequestRejection() == true ) return false; /// ¸ÊÀ̵¿ °¡´ÉÀÎÁö ÇöÀç »óÅ üũ if( GetState() != eOBJECT_STATE_ATTACK ) { if( GetState() != eOBJECT_STATE_DIE ) NETWORK2->PostServerEvent("cPlayer::ItemMapChange[%d] ChangeState( eOBJECT_STATE_MOVE ) == false[%d,%d,%d]", mPlayerExrInfo.mState, mPlayerExrInfo.mStateStop, mIsRequestRejection, mObject.index ); return false; } if( IsAutoTrial() == true ) { NETWORK2->PostServerEvent("cPlayer::ItemMapChange[%d,%d] IsAutoTrial() == true", mObject.index, posIdx); return false; } sTargetPos targetPos; memset( &targetPos, 0 , sizeof(sTargetPos) ); sStageChangePos* scriptPos = STAGESCRIPT->GetPosScriptInfo( posIdx ); if( scriptPos == NULL ) { NETWORK2->PostServerEvent("cPlayer::ItemMapChange[%d] scriptPos == NULL", mObject.index ); return false; } /// À̵¿ ÁÂÇ¥ ¿À·ù if( scriptPos->mMapNumber == 0 ) { NETWORK2->PostServerEvent("cPlayer::ItemMapChange[%d] scriptPos.mMapNumber == 0", mObject.index ); return false; } targetPos.mMapNumber = scriptPos->mMapNumber; targetPos.mRotAngle = scriptPos->mRotAngle; bool isPos = false; if( NETWORK2->GetServerType() == _E_ST_NORMAL_MAP_ ) { /// À̵¿ÁÂÇ¥°¡ ¸ø°¡´Â Áö¿ªÀÏ °æ¿ì ¹üÀ§¸¦ ÂÎÇô°¡¸é¼­ À̵¿À§Ä¡¸¦ Àâ´Â´Ù. if( scriptPos->mRange > MAP_RANGE_CHECK_RING ) { for( int i = MAP_RANGE_CHECK_RING ; i > 0 ; --i ) { /// ÃÖ´ë ¹üÀ§¿¡¼­ 20%¾¿ ÁÙ¿©°¡¸é¼­ üũ int range = (int)(scriptPos->mRange * i * ( 1.0f / MAP_RANGE_CHECK_RING )); if( range <= 0 ) continue; targetPos.mPosX = scriptPos->mPosX + ( rand() % range ) - ( rand() % range ); targetPos.mPosY = scriptPos->mPosY + ( rand() % range ) - ( rand() % range ); if( AIMANAGER->IsPossible( targetPos.mMapNumber, targetPos.mPosX, targetPos.mPosY, mObject ) == false ) continue; isPos = true; break; } } } if( isPos == false ) { /// À§¿¡ ·£´ý ¹üÀ§ ÁÂÇ¥Áß ¸ðµÎ´Ù ¸ø°¡´Â °æ¿ì ½ºÅ©¸³Æ®»ó Á¤ÇØÁø °íÁ¤À§Ä¡·Î À̵¿½ÃŲ´Ù. targetPos.mPosX = scriptPos->mPosX; targetPos.mPosY = scriptPos->mPosY; } if( NETWORK2->GetServerType() == _E_ST_NORMAL_MAP_ ) { if( AIMANAGER->IsPossible( targetPos.mMapNumber, targetPos.mPosX, targetPos.mPosY, mObject ) == true ) { if( ItemUseMapChange( useItemIdx ) == false ) return false; mMapChange = true; /// À̵¿ Áö¿ª ¼³Á¤ SetMapTargetPos( targetPos ); InfluenceProcessStop(); return true; } } else if( NETWORK2->GetServerType() == _E_ST_ID_THEME_ ) { if( NETWORK2->ReturnGameServer( GetConnectionIdx() ) == false ) return false; if( ItemUseMapChange( useItemIdx ) == false ) return false; mIsInDunJoin = false; mMapChange = false; mMapNumber = targetPos.mMapNumber; mGotoX = mObjectPos.x = targetPos.mPosX; mGotoY = mObjectPos.y = targetPos.mPosY; mDirection = targetPos.mRotAngle; CalcThemeReturnGameSrv( mMapNumber, mObjectPos.x, mObjectPos.y, false ); return true; } else if( NETWORK2->GetServerType() == _E_ST_ID_TUTORIAL_ ) { NETWORK2->PostServerEvent("cPlayer::ItemMapChange[%d] NETWORK2->GetServerType(%d) == _E_ST_ID_TUTORIAL_", mObject.index, NETWORK2->GetServerType() ); return false; } else return false; /// ·£´ýÀÌ Æ÷ÇÔ¾ÈµÈ °íÁ¤ À§Ä¡·Îµµ À̵¿ ¸øÇÏ¸é ½ÇÆÐ ¸®ÅÏ return false; } char cPlayer::UserPortalMapChange( unsigned long userPortalIdx ) { /// ¸ÊÀ̵¿Áß ¸ÊÀ̵¿ÀÌ ¿Ã¼ö¾øÀ½ if( mMapChange == true ) { NETWORK2->PostServerEvent("cPlayer::ItemMapChange[%d] mMapChange == true", mObject.index ); return ERROR_RES_MAPCHANGE_STATE; } /// 2Â÷»óÅ üũ if( IsRequestRejection() == true ) return ERROR_RES_MAPCHANGE_STATE; /// ¸ÊÀ̵¿ °¡´ÉÀÎÁö ÇöÀç »óÅ üũ if( IsChangeState( eOBJECT_STATE_MOVE ) == false ) return ERROR_RES_MAPCHANGE_STATE; cUserPortal* pPortal = GRIDMANAGER->GetUserPortal( userPortalIdx ); if( pPortal == NULL ) return ERROR_RES_MAPCHANGE_NOTPORTAL; if( pPortal->IsMapChange( mObject.index ) == false ) return ERROR_RES_MAPCHANGE_NOTPARTY; sTargetPos targetPos; memset( &targetPos, 0 , sizeof(sTargetPos) ); sStageChangePos* scriptPos = STAGESCRIPT->GetPosScriptInfo( pPortal->GetMapChangePosIdx() ); if( scriptPos == NULL ) { NETWORK2->PostServerEvent("cPlayer::ItemMapChange[%d] scriptPos == NULL", mObject.index ); return ERROR_RES_MAPCHANGE_SCRIPT; } /// À̵¿ ÁÂÇ¥ ¿À·ù if( scriptPos->mMapNumber == 0 ) { NETWORK2->PostServerEvent("cPlayer::ItemMapChange[%d] scriptPos.mMapNumber == 0", mObject.index ); return ERROR_RES_MAPCHANGE_SCRIPT; } float objectSize = OBJECTMANAGER->ObjectSizeRange( this, NULL, 0 ); mRangeCheck.SetRadius( scriptPos->mRange + objectSize + SYNC_MOVE_RANGE ); if( mRangeCheck.IsNotRange( pPortal->GetPos(), GetPos() ) == true ) return ERROR_RES_MAPCHANGE_POSITION; targetPos.mMapNumber = scriptPos->mMapNumber; targetPos.mRotAngle = scriptPos->mRotAngle; bool isPos = false; if( NETWORK2->GetServerType() == _E_ST_NORMAL_MAP_ ) { /// À̵¿ÁÂÇ¥°¡ ¸ø°¡´Â Áö¿ªÀÏ °æ¿ì ¹üÀ§¸¦ ÂÎÇô°¡¸é¼­ À̵¿À§Ä¡¸¦ Àâ´Â´Ù. if( scriptPos->mRange > MAP_RANGE_CHECK_RING ) { for( int i = MAP_RANGE_CHECK_RING ; i > 0 ; --i ) { /// ÃÖ´ë ¹üÀ§¿¡¼­ 20%¾¿ ÁÙ¿©°¡¸é¼­ üũ int range = (int)(scriptPos->mRange * i * ( 1.0f / MAP_RANGE_CHECK_RING )); if( range <= 0 ) continue; targetPos.mPosX = scriptPos->mPosX + ( rand() % range ) - ( rand() % range ); targetPos.mPosY = scriptPos->mPosY + ( rand() % range ) - ( rand() % range ); if( AIMANAGER->IsPossible( targetPos.mMapNumber, targetPos.mPosX, targetPos.mPosY, mObject ) == false ) continue; isPos = true; break; } } } if( isPos == false ) { /// À§¿¡ ·£´ý ¹üÀ§ ÁÂÇ¥Áß ¸ðµÎ´Ù ¸ø°¡´Â °æ¿ì ½ºÅ©¸³Æ®»ó Á¤ÇØÁø °íÁ¤À§Ä¡·Î À̵¿½ÃŲ´Ù. targetPos.mPosX = scriptPos->mPosX; targetPos.mPosY = scriptPos->mPosY; } if( NETWORK2->GetServerType() == _E_ST_NORMAL_MAP_ ) { if( AIMANAGER->IsPossible( targetPos.mMapNumber, targetPos.mPosX, targetPos.mPosY, mObject ) == true ) { mMapChange = true; /// À̵¿ Áö¿ª ¼³Á¤ SetMapTargetPos( targetPos ); InfluenceProcessStop(); return ERROR_RES_MAPCHANGE_SUCCESS; } } else if( NETWORK2->GetServerType() == _E_ST_ID_THEME_ ) { if( NETWORK2->ReturnGameServer( GetConnectionIdx() ) == false ) return ERROR_RES_MAPCHANGE_STATE; mIsInDunJoin = false; mMapChange = false; mMapNumber = targetPos.mMapNumber; mGotoX = mObjectPos.x = targetPos.mPosX; mGotoY = mObjectPos.y = targetPos.mPosY; mDirection = targetPos.mRotAngle; CalcThemeReturnGameSrv( mMapNumber, mObjectPos.x, mObjectPos.y, false ); return ERROR_RES_MAPCHANGE_SUCCESS; } else if( NETWORK2->GetServerType() == _E_ST_ID_TUTORIAL_ ) { NETWORK2->PostServerEvent("cPlayer::ItemMapChange[%d] NETWORK2->GetServerType(%d) == _E_ST_ID_THEME_", mObject.index, NETWORK2->GetServerType() ); return ERROR_RES_MAPCHANGE_SCRIPT; } else return ERROR_RES_MAPCHANGE_STATE; /// ·£´ýÀÌ Æ÷ÇÔ¾ÈµÈ °íÁ¤ À§Ä¡·Îµµ À̵¿ ¸øÇÏ¸é ½ÇÆÐ ¸®ÅÏ return ERROR_RES_MAPCHANGE_STATE; } bool cPlayer::CashItemMapChange( unsigned short mapNumber, float x, float y, unsigned long useItemIdx ) { /// ¸ÊÀ̵¿Áß ¸ÊÀ̵¿ÀÌ ¿Ã¼ö¾øÀ½ if( mMapChange == true ) { NETWORK2->PostServerEvent("cPlayer::CashItemMapChange mMapChange[%d,%d,%f,%f] == true", mObject.index, mapNumber, x, y); return false; } /// 2Â÷»óÅ üũ if( IsRequestRejection() == true ) return false; /// ¸ÊÀ̵¿ °¡´ÉÀÎÁö ÇöÀç »óÅ üũ if( GetState() != eOBJECT_STATE_ATTACK ) { if( GetState() != eOBJECT_STATE_DIE ) NETWORK2->PostServerEvent("cPlayer::CashItemMapChange[%d] GetState() != eOBJECT_STATE_ATTACK[%d,%d,%d]", mPlayerExrInfo.mState, mPlayerExrInfo.mStateStop, mIsRequestRejection, mObject.index ); return false; } if( IsAutoTrial() == true ) { NETWORK2->PostServerEvent("cPlayer::ItemMapChange IsAutoTrial()[%d,%d,%f,%f] == true", mObject.index, mapNumber, x, y); return false; } if( mapNumber < MAP_MIN || MAP_MAX < mapNumber ) { NETWORK2->PostServerEvent("cPlayer::CashItemMapChange MAP_MIN > mapNumber || mapNumber < MAP_MAX[%d,%d,%f,%f]", mObject.index, mapNumber, x, y ); return false; } if( NETWORK2->GetServerType() == _E_ST_NORMAL_MAP_ ) { if( AIMANAGER->IsPossible( mapNumber, x, y, mObject ) == true ) { mMapChange = true; /// À̵¿ Áö¿ª ¼³Á¤ mMapTargetPos.mMapNumber = mapNumber; mMapTargetPos.mPosX = x; mMapTargetPos.mPosY = y; mMapTargetPos.mRotAngle = 0; InfluenceProcessStop(); ItemUseCashMapChange( useItemIdx ); return true; } } else if( NETWORK2->GetServerType() == _E_ST_ID_THEME_ ) { if( NETWORK2->ReturnGameServer( GetConnectionIdx() ) == false ) return false; ItemUseCashMapChange( useItemIdx ); mIsInDunJoin = false; mMapChange = false; mMapNumber = mapNumber; mGotoX = mObjectPos.x = x; mGotoY = mObjectPos.y = y; mDirection = 0; CalcThemeReturnGameSrv( mMapNumber, mObjectPos.x, mObjectPos.y, false ); return true; } else if( NETWORK2->GetServerType() == _E_ST_ID_TUTORIAL_ ) { NETWORK2->PostServerEvent("cPlayer::CashItemMapChange[%d] NETWORK2->GetServerType(%d) == _E_ST_ID_TUTORIAL_", mObject.index, NETWORK2->GetServerType() ); return false; } else return false; return false; } void cPlayer::MoveStopReq( MSG_REQ_MOVE_STOP* pmsg, char reqProtocol, char resProtocol ) { if( pmsg == NULL ) { mIsMoveMsg = false; // ¼­¹ö»óÀÇ ÁÂÇ¥·Î Ŭ¶óÀÌ¾ðÆ®¸¦ ¿Å±â°Ô ÇÔ HANDLE handle = NULL; MSG_RES_MOVE_STOP* msg = (MSG_RES_MOVE_STOP*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, resProtocol ); if ( msg != NULL ) { msg->mCharacterPosX = mObjectPos.x; msg->mCharacterPosY = mObjectPos.y; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_MOVE_STOP) ); } return; } NiPoint2 clientPos( pmsg->mClientPosX, pmsg->mClientPosY ); MoveStop(); if( GetState() == eOBJECT_STATE_MOVE ) ChangeState( eOBJECT_STATE_IDLE ); CalcClientMoveDeff( pmsg->mClientTime ); mIsMoveMsg = true; mMoveMsg.mMsgError = false; mMoveMsg.mProtocol = reqProtocol; /// ¿ÀÂ÷ Çã¿ëÄ¡ È®ÀÎ cRangeCheck rangeCheck( SYNC_MOVE_RANGE ); if( rangeCheck.IsNotRange( clientPos, mObjectPos ) == true ) { mMoveMsg.mMsgError = true; //// ¼­¹ö»óÀÇ ÁÂÇ¥·Î Ŭ¶óÀÌ¾ðÆ®¸¦ ¿Å±â°Ô ÇÔ //HANDLE handle = NULL; //MSG_RES_MOVE_STOP* msg = (MSG_RES_MOVE_STOP*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, resProtocol ); //if ( msg != NULL ) //{ // msg->mCharacterPosX = mObjectPos.x; // msg->mCharacterPosY = mObjectPos.y; // NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_MOVE_STOP) ); //} } //if( GetCheatHideMode() == false ) //{ // // ´Ù¸¥ Ç÷¹À̾îµé¿¡°Ôµµ ¾Ë¸² // MSG_SYN_MOVE_STOP Msg; // Msg.Category = NM_PLAYER; // Msg.Protocol = synProtocol; // Msg.mCharacterIdx = mObject.index; // Msg.mCharacterPosX = GetXPos(); // Msg.mCharacterPosY = GetYPos(); // NETWORK2->QuickSendExcept( this, (char*)&Msg, sizeof(Msg) ); //} } void cPlayer::SendMoveSpeed() { MSG_SYN_MOVESPEED Msg; Msg.Category = NM_PLAYER; Msg.Protocol = NM_PLAYER_MOVESPEED_SYN; Msg.mCharacterIdx = mObject.index; Msg.moveSpeed = GetMoveSpeed(); NETWORK2->QuickSend( this, (char*)&Msg, sizeof(Msg) ); } void cPlayer::SendAttackSpeed() { MSG_SYN_ATTACKSPEED Msg; Msg.Category = NM_PLAYER; Msg.Protocol = NM_PLAYER_ATTACKSPEED_SYN; Msg.mCharacterIdx = mObject.index; Msg.mAttackSpeed = mStatus2.mAttackSpeed; NETWORK2->QuickSend( this, (char*)&Msg, sizeof(Msg) ); } void cPlayer::SendPlayerSize() { MSG_SYN_PLAYER_SIZE synMsg; synMsg.Category = NM_PLAYER; synMsg.Protocol = NM_PLAYER_SCALE_SYN; synMsg.mCharacterIdx = mObject.index; synMsg.mScale = GetFixedObjectSizePer(); NETWORK2->QuickSend( this, (char*)&synMsg, sizeof(synMsg) ); } //void cPlayer::SendSynStatus() //{ // HANDLE handle = NULL; // MSG_SYN_PLAYER_STATUS* sendMsg = (MSG_SYN_PLAYER_STATUS*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx ); // if ( sendMsg != NULL ) // { // sendMsg->Category = NM_PLAYER; // sendMsg->Protocol = NM_PLAYER_STATUS_RES; // sendMsg->mCharacterIdx = mObject.index; // sendMsg->mScale = mPlayerExrInfo.mFixedObjectSizePer; // sendMsg->mMoveSpeed = GetMoveSpeed(); // sendMsg->mAttackSpeed = mStatus2.mAttackSpeed; // sendMsg->mMonsterIdx = mPlayerExrInfo.mChgMonsterIdx; // sendMsg->mIsSleep = mIsSleep; // sendMsg->mIsStun = mIsStun; // sendMsg->mVehicleIdx = mPlayerExrInfo.mVehicleIdx; // NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_PLAYER_STATUS) ); // } // // if( sendMsg->mMonsterIdx != 0 ) // SendCoolTimeChgMon(); //} void cPlayer::SetGameIn() { mGameIn = true; mNextRecoveryTime = NETWORK2->GetAccumTime(); /// Àϰý ÀúÀå ½Ã°£ ¼³Á¤ mBatchSaveTime = NETWORK2->GetAccumTime() + BATCH_SAVE_TIME; /// 061208 PKH À̵¿½Ã ¸ñÀûÁö ÁÂÇ¥ mRangeTargetPos.x = mGotoX = mObjectPos.x; mRangeTargetPos.y = mGotoY = mObjectPos.y; mRange = 0; mNpcIdx = 0; mIsSkillResurrection = false; mSkillResurrectionHP = 0; mSkillResurrectionMP = 0; mNextRecoveryTime = NETWORK2->GetAccumTime() + NATURE_RECOVERY_TIME; mCommunitySkillEndTime = 0; mServerMoveTime = 0; mClientMoveDefTime = 0; mClientMovePlusMinus = 0; mKeyboardMove = false; mJumpEndTime = 0; mPvPDieEndTime = 0; mPvPDieTime = 0; mMapNum0Save = false; mIsMoveMsg = false; memset( &mMoveMsg, 0, sizeof(mMoveMsg) ); mJumpMoveSpeedDownEndTime = 0; mJumpSpeedState = 0; } bool cPlayer::IsGameFinish() { if( GetRequestRejection() != eREQREJCT_GAMEFINISH ) return false; if( GetState( ) != eOBJECT_STATE_STOP ) return false; if( GetStateStop( ) != eSTOP_GAMEFINISH ) return false; return true; } void cPlayer::CalcNatureRecovery() { /// °ÔÀÓ ¹ÛÀ̸é ÀÚ¿¬È¸º¹ ¾ÈÇÔ if( mGameIn == false ) return; /// Á×¾úÀ¸¸é ȸº¹ ¾ÈÇÔ if( GetStateDie() == true ) return; assert( mPlayerExrInfo.RestHP ); /// ½ºÅÝ °è»ê ÀüÀ̸é ÀÚ¿¬È¸º¹ ¾ÈÇÔ if( GetMaxHP() == 0 ) { NETWORK2->PostServerEvent("0 divide 9"); return; } if( mNextRecoveryTime > NETWORK2->GetAccumTime() ) return; /// ¾É¾Ò´ÂÁö üũ float rate = 1.0f; if( mPlayerExrInfo.mState == ePLAYER_STATE_SITDOWN ) { /// ȸº¹ rate = STATUSSCRIPT->GetDamageCalcNumericalInfo( 10 ); mNextRecoveryTime = mNextRecoveryTime + SITDOWN_RECOVERY_TIME; } else { /// ȸº¹ mNextRecoveryTime = mNextRecoveryTime + NATURE_RECOVERY_TIME; } unsigned long recovHP = FloatToInt( mStatus2.mRecovHP * rate ); unsigned long recovMP = FloatToInt( mStatus2.mRecovMP * rate ); if( recovHP != 0 ) HPHeal( recovHP, true, mObject, 0, eTAKEDAMAGETYPE_NONE ); if( recovMP != 0 ) MPHeal( recovMP, true ); } void cPlayer::ApplyInitRest() { if( mInitRestHP != 0 && mInitRestMP != 0 ) { if( mInitRestHP > mPlayerExrInfo.RestHP ) { unsigned long hp = mInitRestHP - mPlayerExrInfo.RestHP; HPHeal( hp, true, mObject, 0, eTAKEDAMAGETYPE_NONE ); } if( mInitRestMP > mPlayerExrInfo.RestMP ) { unsigned long mp = mInitRestMP - mPlayerExrInfo.RestMP; MPHeal( mp, true ); } mInitRestHP = 0; mInitRestMP = 0; } } void cPlayer::SetInitRestHP() { mInitRestHP = mPlayerExrInfo.RestHP; } void cPlayer::SetInitRestMP() { mInitRestMP = mPlayerExrInfo.RestMP; } void cPlayer::SetCommunitySkill( unsigned long communitySkillIdx ) { /// »ýȰ ½ºÅ³ ½ºÅ©¸³Æ®¿¡¼­ Àоî¿Â »ç¿ë ½Ã°£ ¹Ý¿µ mPlayerExrInfo.mCommunitySkillIdx = communitySkillIdx; float skillTime = COMMUNITYSCRIPT->GetEmotingMaintainTime( communitySkillIdx, mPlayerInfo.Race, mPlayerInfo.Gender ); mCommunitySkillEndTime = NETWORK2->GetAccumTime() + skillTime; } unsigned char cPlayer::SelectFollowPos( unsigned char followPos ) { /// ¿äûÇÑÀÚ°¡ ÀÌ¹Ì Á᫐ À§Ä¡¸é ¸®ÅÏ if( followPos == FOLLOW_POS_CENTER ) return followPos; /// ÇöÀç ÃßÀûÀ§Ä¡¸¦ °¡Áö°í ÀÖ´Â ¸ó½ºÅͰ¡ (Áß½ÉÀÚ¸®)¿äûÀ» ÇѰæ¿ì if( mFollowPos[FOLLOW_POS_CENTER] == false ) { /// ÀÚ½ÅÀÌ »ç¿ëÁßÀÌ´ø ÀÚ¸® ¹Ýȯ if( followPos != FOLLOW_POS_MAX ) mFollowPos[followPos] = false; /// ¼¾ÅÍ ¼³Á¤ÈÄ ¸®ÅÏ mFollowPos[FOLLOW_POS_CENTER] = true; return FOLLOW_POS_CENTER; } /// ±âÁ¸ ÀÚ¸®¸¦ ¹è´ç ¹ÞÀº ¿äûÀÚ´Â ¼¾Å͸¸ üũÇÏ°í ¸®ÅÏ if( followPos != FOLLOW_POS_MAX ) return followPos; /// À§Ä¡°¡ ÁöÁ¤µÇÁö ¾ÊÀº ¸ó½ºÅ͵éÀÇ À§Ä¡ ¼±Á¤ ///unsigned char selectPos[FOLLOW_POS_MAX] = { 4, 0, 8, 6, 2, 7, 1, 3, 5 }; unsigned char selectPos[FOLLOW_POS_MAX] = { 4, 0, 2, 8, 6, 1, 5, 7, 3 }; /// Àüü ÀÚ¸® °Ë»ç for( unsigned char i = 0 ; i < FOLLOW_POS_MAX ; ++i ) { /// ¼ø¼­¿¡ ¸Â°Ô À§Ä¡ ºóÀÚ¸® È®ÀÎ if( mFollowPos[selectPos[i]] == false ) { /// ºóÀÚ¸® ¼³Á¤ mFollowPos[selectPos[i]] = true; return selectPos[i]; } } /// ºóÀÚ¸®°¡ Çϳªµµ ¾ø´Â °æ¿ì ¼¾ÅÍ ÀÚ¸® ¼³Á¤ return FOLLOW_POS_MAX; } void cPlayer::UnSelectFollowPos( unsigned char followPos ) { /// »ç¿ë Ç÷¹±× ²û if( followPos != FOLLOW_POS_MAX ) mFollowPos[followPos] = false; } void cPlayer::DuelEnd() { if( mDuelPlayerIdx == 0 ) return; if( mIsDuelRequester == true ) DUELMANAGER->DuelObjectEnd( mObject.index, mDuelPlayerIdx, mDuelIdx, true ); else DUELMANAGER->DuelObjectEnd( mDuelPlayerIdx, mObject.index, mDuelIdx, false ); } void cPlayer::DuelEndDebuffClear( unsigned long enemyIdx ) { cSkillInfluenceSet::cConstIterator start = mInfluenceSet.Begin(); cSkillInfluenceSet::cConstIterator end = mInfluenceSet.End(); unsigned long influenceIdx; cInfluenceObject* pInfluence; sInfluenceScript* pScript; while( start != end ) { influenceIdx = *start++; pInfluence = SKILLMANAGER->GetInfluence( influenceIdx ); if( pInfluence == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cPlayer::DuelEndDebuffClear pInfluence == NULL"); //-/-//SKILLMANAGER->InsertDeleteInfluenceObject( pInfluence ); /// °´Ã¼ »èÁ¦ ´ë±â¿­¿¡ ³Ö´Â´Ù. continue; } pScript = SKILLSCRIPT->GetInfluenceInfo( pInfluence->GetInfluenceClassIdx() ); if( pScript == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cPlayer::DuelEndDebuffClear pScript == NULL"); continue; } /// µð¹öÇÁ¸¸ Á¦°Å if( pScript->mType != eINFLUENCETYPE_DEBUF ) continue; /// °áÅõ »ó´ëÆíÀÌ °É¾îÁØ µð¹öÇÁ¸¸ Á¦°Å if( pInfluence->GetAttacker().index != enemyIdx ) continue; /// ½ºÅ³ ¸Þ´ÏÀú¿¡¼­ °´Ã¼ »èÁ¦ SKILLMANAGER->DeleteInfluenceList( influenceIdx ); } } void cPlayer::CalcPvPReturnGameSrv( unsigned short mapNumber, float beforePosX, float beforePosY ) { mGameSrvReturnMapNum = mapNumber; mGameSrvReturnPos.x = beforePosX; mGameSrvReturnPos.y = beforePosY; NiPoint2 calcPos = STAGESCRIPT->CalcNearTargetMapPos( mapNumber, beforePosX, beforePosY ); if( calcPos != NiPoint2::ZERO ) mGameSrvReturnPos = calcPos; } void cPlayer::ChannelMovePvPWait( long pvpGoCid, unsigned long waitTime ) { mChannelPvPGoCid = pvpGoCid; mChannelPvPMoveTime = NETWORK2->GetAccumTime() + waitTime; } bool cPlayer::CheckPvPJoin() { /// pvp ÁøÀÔ ºÒ°¡ È¿°ú¸¦ °¡Áø »ç¶÷ üũ cSkillInfluenceSet::cIterator infBegin = mInfluenceSet.Begin(); cSkillInfluenceSet::cIterator infEnd = mInfluenceSet.End(); while( infBegin != infEnd ) { cInfluenceObject* pInf = SKILLMANAGER->GetInfluence( (*infBegin++) ); if( pInf != NULL && pInf->GetInfluenceClassIdx() == PVP_DM_CANTPVP_INFLUENCE ) return false; } return true; } void cPlayer::PvPOut() { mIsInDunJoin = false; mPvPDMIdx = 0; /// ¹«Àû È¿°ú Á¦°Å SKILLMANAGER->DeleteInfluenceClassIdx( mObject, PVP_DM_NODAMAGE_INFLUENCE ); /// ¼öÀå È¿°ú Á¦°Å SKILLMANAGER->DeleteInfluenceClassIdx( mObject, PVP_DM_LEADER_INFLUENCE ); SKILLMANAGER->DeleteInfluenceClassIdx( mObject, PVP_DM_LEADER_INFLUENCE2 ); SKILLMANAGER->DeleteInfluenceClassIdx( mObject, PVP_DM2_FLAG_INFLUENCE ); HPHeal( GetMaxHP(), true, mObject, 0, eTAKEDAMAGETYPE_NONE ); MPHeal( GetMaxMP(), true ); } void cPlayer::AutoPvPOut() { PvPOut(); SetStateStop( eSTOP_MAPCHANGE ); /// ¸¶À»À̵¿ ¾Ë¸² NETWORK2->SendMsgRoot( mConnectionIdx, NM_PVP, NM_PVP_DM_END_SYN ); } bool cPlayer::SendPvPTeamChat( char* msg, int length ) { cBaseDeathMatch* pDM = PVPMANAGER->GetPvPDMObject( mPvPDMIdx ); if( pDM != NULL ) { pDM->TeamChatQuickSend( this, (ePVPDM_TEAM_TYPE)mPlayerExrInfo.mPvPDMTeamType, msg, length ); return true; } return false; } void cPlayer::PvPEndDebuffClear() { cSkillInfluenceSet::cConstIterator start = mInfluenceSet.Begin(); cSkillInfluenceSet::cConstIterator end = mInfluenceSet.End(); unsigned long influenceIdx; cInfluenceObject* pInfluence; sInfluenceScript* pScript; while( start != end ) { influenceIdx = *start++; pInfluence = SKILLMANAGER->GetInfluence( influenceIdx ); if( pInfluence == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cPlayer::DuelEndDebuffClear pInfluence == NULL"); //-/-//SKILLMANAGER->InsertDeleteInfluenceObject( pInfluence ); /// °´Ã¼ »èÁ¦ ´ë±â¿­¿¡ ³Ö´Â´Ù. continue; } pScript = SKILLSCRIPT->GetInfluenceInfo( pInfluence->GetInfluenceClassIdx() ); if( pScript == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cPlayer::DuelEndDebuffClear pScript == NULL"); continue; } /// µð¹öÇÁ¸¸ Á¦°Å if( pScript->mType != eINFLUENCETYPE_DEBUF ) continue; /// ½ºÅ³ ¸Þ´ÏÀú¿¡¼­ °´Ã¼ »èÁ¦ SKILLMANAGER->DeleteInfluenceList( influenceIdx ); } } void cPlayer::CalcThemeReturnGameSrv( unsigned short beforeMapNumber, float beforePosX, float beforePosY, bool isAuto ) { mGameSrvReturnMapNum = beforeMapNumber; mGameSrvReturnPos.x = beforePosX; mGameSrvReturnPos.y = beforePosY; if( isAuto == true ) { cThemeObject* ptheme = THEMEMANAGER->GetThemeObject( mThemeRoomIdx ); if( ptheme != NULL ) { sStageChangePos* pCalcPos = ptheme->GetThemeOutPos(); if( pCalcPos != NULL && pCalcPos->mTargetInfo != NULL ) { mGameSrvReturnMapNum = pCalcPos->mTargetInfo->mMapNumber; mGameSrvReturnPos.x = pCalcPos->mTargetInfo->mPosX; mGameSrvReturnPos.y = pCalcPos->mTargetInfo->mPosY; } } } } void cPlayer::AddTakeDamage( sObject attacker, unsigned long damage, long /*distressPoint*/, eTAKEDAMAGE_TYPE /*type*/ ) { if( attacker.type == eOBJECTTYPE_PLAYER ) { cPlayer* pAttacker = GRIDMANAGER->GetPlayer( attacker.index ); if( pAttacker == NULL ) return; if( GetStateDie() == true && mPvPDMIdx != 0 && damage !=0 ) { cBaseDeathMatch* pDM = PVPMANAGER->GetPvPDMObject( mPvPDMIdx ); if( pDM != NULL ) { pDM->ScoreUpdate( attacker.index, (ePVPDM_TEAM_TYPE)pAttacker->GetPvPDMTeam(), mObject.index, (ePVPDM_TEAM_TYPE)mPlayerExrInfo.mPvPDMTeamType ); } } } } bool cPlayer::IsAttack( unsigned long targetIdx ) { if( mObject.index == targetIdx ) return false; cPlayer* pTarget = OBJECTMANAGER->GetPlayer( targetIdx ); if( pTarget == NULL ) return false; /// °áÅõ if( mDuelIdx != 0 ) { cDuelObject* pDuelObject = DUELMANAGER->GetDuel( mDuelIdx ); if( pDuelObject == NULL ) return false; if( pDuelObject->GetDuelProcess() != eDUELPROCESS_FIGHT ) return false; if( !( mObject.index == pDuelObject->GetAttackerIdx() || mObject.index == pDuelObject->GetTargetIdx() ) ) return false; if( !( targetIdx == pDuelObject->GetAttackerIdx() || targetIdx == pDuelObject->GetTargetIdx() ) ) return false; return true; } /// PvP1 if( mPvPDMIdx != 0 ) { cBaseDeathMatch* pPvPDM = PVPMANAGER->GetPvPDMObject( mPvPDMIdx ); if( pPvPDM == NULL ) return false; if( pPvPDM->IsFight() == false ) return false; if( mPvPDMIdx == pTarget->GetPvPDMIdx() && mPlayerExrInfo.mPvPDMTeamType != pTarget->GetPvPDMTeam() ) return true; } return false; } bool cPlayer::IsRequestRejection() { if( mIsRequestRejection != eREQREJCT_NONE ) return true; return false; } void cPlayer::StartRequestRejection( eREQUEST_REJECTION IsRequestRejection ) { if( mIsRequestRejection != eREQREJCT_NONE ) { NETWORK2->PostServerEvent("cPlayer::StartRequestRejection[%d,%d,%d] member[%d] input[%d]", mPlayerExrInfo.mState, mPlayerExrInfo.mStateStop, mObject.index, mIsRequestRejection, IsRequestRejection); } mIsRequestRejection = IsRequestRejection; } void cPlayer::EndRequestRejection( eREQUEST_REJECTION IsRequestRejection ) { if( mIsRequestRejection != IsRequestRejection ) { NETWORK2->PostServerEvent("cPlayer::EndRequestRejection[%d,%d,%d] member[%d] input[%d]", mPlayerExrInfo.mState, mPlayerExrInfo.mStateStop, mObject.index, mIsRequestRejection, IsRequestRejection ); } /// Á¾·á Ãë¼Ò ¿äûÀÌ µé¾î¿Â°æ¿ì ±âº» »óÅ·Πº¯°æ if( mPlayerExrInfo.mState == eOBJECT_STATE_STOP && mPlayerExrInfo.mStateStop == eSTOP_GAMEFINISH && eREQREJCT_GAMEFINISH == IsRequestRejection ) { ChangeState( eOBJECT_STATE_IDLE ); SetStateStop( eSTOP_NONE ); } mIsRequestRejection = eREQREJCT_NONE; } // ¸ÊüÀÎÁö, °ÔÀÓÁ¾·á, Á×¾úÀ»½Ã void cPlayer::EndRequestRejectionAll() { switch( mIsRequestRejection ) { case eREQREJCT_NONE: return; case eREQREJCT_GAMEFINISH: break; case eREQREJCT_DUELWAIT: /// °áÅõ ¿äû ´ë±â »óÅ { cPlayer* pRequestor = GRIDMANAGER->GetPlayer( mDuelPlayerIdx ); // ¿äûÀÚ if( pRequestor != NULL ) DUELMANAGER->DuelAllReady( false, this ); } break; case eREQREJCT_DUELPLAY: { DuelEnd(); // °áÅõ Á¾·á ó¸® } break; case eREQREJCT_EXCHANGE: /// °Å·¡ »óÅ { cPlayer* player = GRIDMANAGER->GetPlayer( mExchangeTarget.index ); // ¿äûÀÚ if ( player != NULL ) { player->ExchangeReplySyn( TYPE_ITEM_EXCHANGE_REP_REJECT, ERROR_ITEM_EXCHANGE_REP_ERROR ); } if ( mExchangeStatus == ItemExchangeAsk ) mExchangeStatus = ItemExchangeNone; } break; case eREQREJCT_PARTY: /// ÆÄƼ »óÅ { PARTYMAN->ClearRequest( this ); } break; case eREQREJCT_GUILD: /// ±æµå »óÅ { GUILDMAN->ClearRequest( this ); } break; case eREQREJCT_THEME: { THEMEMANAGER->ThemeDBErr( mObject.index, ERROR_THEME_READY_STATE ); } break; default: return; } mIsRequestRejection = eREQREJCT_NONE; } unsigned long cPlayer::ExpDown( float minimum, float maximum ) { if( mPlayerInfo.Level < 10 ) return 0; /// ÇöÀç ij¸¯ÅÍ lv¿¡¼­ ´ÙÀ½ lv±îÁö ¾ò¾î¾ß ÇÏ´Â ÃÑ °æÇèÄ¡ sExpTable* pExpTable = LEVELSCRIPT->GetExpTable( mPlayerInfo.Level ); if( pExpTable == NULL ) { NETWORK2->PostServerEvent("cPlayer::ExpDown pExpTable[%d][%f,%f][%d] == NULL", mObject.index, minimum, maximum, mPlayerInfo.Level ); return 0; } /// ·£´ý°ª ÃßÃâ unsigned long randvalue = (unsigned long)( RANDOMTABLE->Get( ) * 1000000 ); /// ·£´ý °¨¼Ò È®·ü ¼±Åà - ¼Ò¼öÁ¡ 2ÀÚ¸® »ì¸² unsigned long downGap = (unsigned long)(( maximum * 100 ) - ( minimum * 100 )); /// ÃÖ¼Ò ÃÖ´ë ±¸°£ »çÀÌÀÇ ·£´ý°ª unsigned long downGapExp = (unsigned long)( pExpTable->mExp * ( ( randvalue % downGap ) * 0.01f ) * 0.01f ); /// ÃÖ¼Ò °æÇèÄ¡ Ç϶ôºÐ unsigned long downMinExp = (unsigned long)( pExpTable->mExp * minimum * 0.01f ); /// Ç϶ôÇÒ °æÇèÄ¡·® unsigned long minusExp = downMinExp + downGapExp; /// °æÇèÄ¡ °¨¼Ò °¡´É ÇÑ ¸¸Å­ ¸¸ °¨¼Ò if( mHeroInfo.Exp < minusExp ) { minusExp = mHeroInfo.Exp; /// ½ÇÁ¦ °¨¼Ò·® ±â·Ï mHeroInfo.Exp = 0; /// °æÇèÄ¡ °¨¼Ò return minusExp; /// °¨¼Ò·® ¸®ÅÏ } else { mHeroInfo.Exp = mHeroInfo.Exp - minusExp; /// °æÇèÄ¡ °¨¼Ò return minusExp; /// °¨¼Ò·® ¸®ÅÏ } } bool cPlayer::DBUpdate( bool updateComplete, int updateFlag ) { if ( updateComplete == false && mIsDbUpdate == true ) return false; /// ´ÙÀ½ ÀúÀå½Ã°£ ¼³Á¤ mBatchSaveTime = NETWORK2->GetAccumTime() + BATCH_SAVE_TIME; /// ½×¿©ÀÖ´Â °æÇèÄ¡·® Á¦°Å mWaitSaveExp = 0; HANDLE handle = NULL; CHARACTER_UPDATE* characterUpdate = (CHARACTER_UPDATE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_CHARACTER_UPDATE ); characterUpdate->cid = mConnectionIdx; characterUpdate->idx = mPlayerInfo.CharacterIdx; characterUpdate->hp = mPlayerExrInfo.RestHP; characterUpdate->mp = mPlayerExrInfo.RestMP; characterUpdate->tarotPoint = mHeroInfo.TarotPoint; characterUpdate->titleIndex = mPlayerExrInfo.mTitleIndex; characterUpdate->guildIndex = mPlayerExrInfo.mGuildIndex; characterUpdate->guildPosition = mPlayerExrInfo.mGuildPosition; characterUpdate->level = mPlayerInfo.Level; characterUpdate->exp = mHeroInfo.Exp; characterUpdate->skillLevel = mHeroInfo.SkillLevel; characterUpdate->skillExp = mHeroInfo.SkillExp; characterUpdate->skillPointRemain = mHeroInfo.SkillPointRemain; characterUpdate->skillPointTotal = mHeroInfo.SkillPointTotal; characterUpdate->makeSkill1_Exp = mHeroInfo.MakeSkill1.mExp; characterUpdate->makeSkill2_Exp = mHeroInfo.MakeSkill2.mExp; if ( mIsInDunJoin == true ) { if( NETWORK2->GetServerType() == _E_ST_ID_TUTORIAL_ ) { // Æ©Å丮¾ó characterUpdate->mapNumber = mInDunMapDataNum; characterUpdate->xPos = mObjectPos.x; characterUpdate->yPos = mObjectPos.y; } else { // ÀÏ¹Ý Àδø characterUpdate->mapNumber = mGameSrvReturnMapNum; characterUpdate->xPos = mGameSrvReturnPos.x; characterUpdate->yPos = mGameSrvReturnPos.y; } } else { // ÀÏ¹Ý¸Ê characterUpdate->mapNumber = mMapNumber; characterUpdate->xPos = mObjectPos.x; characterUpdate->yPos = mObjectPos.y; } characterUpdate->retvalue = -1; characterUpdate->flag = updateFlag; characterUpdate->expRecover = mHeroInfo.mLoseExp; characterUpdate->expRecoverendDate = mExpRecoverEndTime; NETWORK2->SendSQL( mConnectionIdx, handle, sizeof(CHARACTER_UPDATE), updateComplete ? COMMON_DB_CHARACTER_UPDATE : 0 ); return (mIsDbUpdate = true); } bool cPlayer::IsChgMonCoolTimeEnd( eMONSTERATTACK_TYPE type ) { unsigned long check = NETWORK2->GetAccumTime(); if( mChgMonCoolTime[type] > check ) { ++mMonSkillCoolTimeFail; return false; } return true; } void cPlayer::UpdateChgMonCoolTime( eMONSTERATTACK_TYPE type ) { if( type >= eMONSTERATTACK_MAX ) { assert(NULL); NETWORK2->PostServerEvent("cPlayer::UpdateCoolTime type[%d][%d] >= eMONSTERATTACK_MAX", mObject.index, type ); return; } if( mPlayerExrInfo.mChgMonsterIdx == 0 ) { assert(NULL); NETWORK2->PostServerEvent("cPlayer::UpdateCoolTime mPlayerExrInfo.mChgMonsterIdx[%d][%d] != 0", mObject.index, mPlayerExrInfo.mChgMonsterIdx ); return; } sMonsterSkillScript* pScript = SKILLSCRIPT->GetMonsterSkillInfo( mPlayerExrInfo.mChgMonsterIdx, type ); if( pScript == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cPlayer::UpdateCoolTime pScript[%d][%d,%d] == NULL", mObject.index, mPlayerExrInfo.mChgMonsterIdx, type ); return; } /// ½ºÅÝ¿¡¼­ °è»êµÈ °ø°Ý¼Óµµ ( ¾ÆÀÌÅÛ, ¹öÇÁ Æ÷ÇÔ ) float attackSpeed = GetStatus2()->mAttackSpeed; if( attackSpeed <= 0.0f ) attackSpeed = 0.1f; if( attackSpeed >= 2.0f ) attackSpeed = 1.9f; unsigned long fixCoolTime = pScript->mCoolTime; /// ÀϹݰø°ÝÀº °ø¼Ó¹Ý¿µ if( type < eMONSTERATTACK_SKILL1 ) fixCoolTime = (unsigned long)( pScript->mCoolTime * ( 2.0f - attackSpeed ) ); /// Çã¿ë ¿ÀÂ÷ Àû¿ë if( fixCoolTime > SYNC_NORMALATTACK ) fixCoolTime = fixCoolTime - SYNC_NORMALATTACK; else fixCoolTime = 0; mChgMonCoolTime[type] = NETWORK2->GetAccumTime() + fixCoolTime; } void cPlayer::SendCoolTimeChgMon() { if( mPlayerExrInfo.mChgMonsterIdx == 0 ) return; unsigned long accumTime = NETWORK2->GetAccumTime(); unsigned long skill[eMONSTERATTACK_MAX - eMONSTERATTACK_SKILL1] = {0,}; for( int i = 0 ; i < eMONSTERATTACK_MAX - eMONSTERATTACK_SKILL1 ; ++i ) { if( mChgMonCoolTime[ eMONSTERATTACK_SKILL1 + i ] > accumTime ) skill[i] = mChgMonCoolTime[eMONSTERATTACK_SKILL1 + i] - accumTime; else skill[i] = 0; /// º¸À¯ ½ºÅ³ üũ if( SKILLSCRIPT->GetMonsterSkillInfo( mPlayerExrInfo.mChgMonsterIdx, eMONSTERATTACK_TYPE( eMONSTERATTACK_SKILL1 + i ) ) == NULL ) skill[i] = ULONG_MAX; } HANDLE handle = NULL; MSG_RES_SKILL_CHGMON_COOLTIME* sendMsg = (MSG_RES_SKILL_CHGMON_COOLTIME*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_SKILL, NM_SKILL_CHGMON_SKILLCOOLTIME ); if ( sendMsg != NULL ) { sendMsg->mSkill1CoolTime = skill[eMONSTERATTACK_SKILL1 - eMONSTERATTACK_SKILL1]; sendMsg->mSkill2CoolTime = skill[eMONSTERATTACK_SKILL2 - eMONSTERATTACK_SKILL1]; sendMsg->mSkill3CoolTime = skill[eMONSTERATTACK_SKILL3 - eMONSTERATTACK_SKILL1]; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_SKILL_CHGMON_COOLTIME) ); } } void cPlayer::SetDuelIdx( unsigned long duelIdx ) { mDuelIdx = duelIdx; mPlayerExrInfo.mIsDuelIdx = duelIdx == 0 ? false : true; } void cPlayer::SetStateOddity( long* pOddity ) { for( int i = 0 ; i < eODDITYTYPE_MAX ; ++i ) { if( mODDITY[i] != pOddity[i] ) { mODDITY[i] = pOddity[i]; /// Àû¿ë/ÇØÁ¦ ¸Þ¼¼Áö ¹ß¼Ûó¸® if( pOddity[i] != 0 ) { /// »óÅÂÀÌ»ó Àû¿ëºÎ Ŭ¶óÀÌ¾ðÆ®¿¡ ¾Ë¸² HANDLE handle = NULL; switch( i ) { case eODDITYTYPE_CANTMOVE: { MoveStop(); MSG_SYN_PLAYER_CANTMOVE synMsg; synMsg.Category = NM_PLAYER; synMsg.Protocol = NM_PLAYER_CANTMOVE_SYN; synMsg.mIsCantMove = true; synMsg.mCharaterIdx = mObject.index; synMsg.mCharacterPos.x = mObjectPos.x; synMsg.mCharacterPos.y = mObjectPos.y; NETWORK2->QuickSend( this, (char*)&synMsg, sizeof(synMsg) ); } break; case eODDITYTYPE_CANTSKILL_PHY: { MSG_SYN_PLAYER_CANTSKILL* sendMsg = (MSG_SYN_PLAYER_CANTSKILL*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_CANTSKILL_SYN ); if ( sendMsg != NULL ) { sendMsg->mAttributeType = eATTRIBUTETYPE_PHYSICAL; sendMsg->mIsCantSkill = true; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_PLAYER_CANTSKILL) ); } if( GetState() == eOBJECT_STATE_ATTACK /*&& IsImmuneApplyType( eSTATUSPLUS_STOPSKILL_PHY ) == false*/ ) SKILLMANAGER->CastSkillCancel( mObject, true, eATTRIBUTETYPE_PHYSICAL ); } break; case eODDITYTYPE_CANTSKILL_MAG: { MSG_SYN_PLAYER_CANTSKILL* sendMsg = (MSG_SYN_PLAYER_CANTSKILL*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_CANTSKILL_SYN ); if ( sendMsg != NULL ) { sendMsg->mAttributeType = eATTRIBUTETYPE_MAGIC; sendMsg->mIsCantSkill = true; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_PLAYER_CANTSKILL) ); } if( GetState() == eOBJECT_STATE_ATTACK /*&& IsImmuneApplyType( eSTATUSPLUS_STOPSKILL_MAG ) == false*/ ) SKILLMANAGER->CastSkillCancel( mObject, true, eATTRIBUTETYPE_MAGIC ); } break; case eODDITYTYPE_SLEEP: { MoveStop(); MSG_SYN_PLAYER_SLEEP synMsg; synMsg.Category = NM_PLAYER; synMsg.Protocol = NM_PLAYER_SLEEP_SYN; synMsg.mIsSleep = true; synMsg.mCharaterIdx = mObject.index; synMsg.mCharacterPos.x = mObjectPos.x; synMsg.mCharacterPos.y = mObjectPos.y; NETWORK2->QuickSend( this, (char*)&synMsg, sizeof(synMsg) ); // äÁý Ãë¼Ò if( GetState() == ePLAYER_STATE_GATHERING ) { cGathering* pGathering = OBJECTMANAGER->GetGathering( mGatheringIdx ); if( pGathering != NULL ) pGathering->CancelGatherByOddity( this ); } else if( GetState() == eOBJECT_STATE_STOP ) { // °­È­ Ãë¼Ò if( GetStateStop() == eSTOP_ENHANCED ) { ItemEnhancedForceCancel(); } // Á¶ÇÕ Ãë¼Ò else if( GetStateStop() == eSTOP_ITEMMIX ) { ItemMixForceCancel(); } } else if( GetState() == eOBJECT_STATE_ATTACK /*&& IsImmuneApplyType( eSTATUSPLUS_SLEEP ) == false*/ ) { SKILLMANAGER->CastSkillCancel( mObject, true, eATTRIBUTETYPE_NONE ); } } break; case eODDITYTYPE_STUN: { MoveStop(); MSG_SYN_PLAYER_STUN synMsg; synMsg.Category = NM_PLAYER; synMsg.Protocol = NM_PLAYER_STUN_SYN; synMsg.mIsStun = true; synMsg.mCharaterIdx = mObject.index; synMsg.mCharacterPos.x = mObjectPos.x; synMsg.mCharacterPos.y = mObjectPos.y; NETWORK2->QuickSend( this, (char*)&synMsg, sizeof(synMsg) ); // äÁý Ãë¼Ò if( GetState() == ePLAYER_STATE_GATHERING ) { cGathering* pGathering = OBJECTMANAGER->GetGathering( mGatheringIdx ); if( pGathering != NULL ) pGathering->CancelGatherByOddity( this ); } else if( GetState() == eOBJECT_STATE_STOP ) { // °­È­ Ãë¼Ò if( GetStateStop() == eSTOP_ENHANCED ) { ItemEnhancedForceCancel(); } // Á¶ÇÕ Ãë¼Ò else if( GetStateStop() == eSTOP_ITEMMIX ) { ItemMixForceCancel(); } } else if( GetState() == eOBJECT_STATE_ATTACK /*&& IsImmuneApplyType( eSTATUSPLUS_STUN ) == false*/ ) { SKILLMANAGER->CastSkillCancel( mObject, true, eATTRIBUTETYPE_NONE ); } } break; case eODDITYTYPE_AVOID_MON_LOOK: { MSG_SYN_PLAYEREXT_AVOID_MON_LOOK* synMsg = (MSG_SYN_PLAYEREXT_AVOID_MON_LOOK*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYEREXT, NM_PLAYEREXT_AVOID_MON_LOOK_SYN ); if ( synMsg != NULL ) { synMsg->mIsAvoidMonLookOn = true; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_PLAYEREXT_AVOID_MON_LOOK) ); } } break; } } else { /// »óÅÂÀÌ»ó ÇØÁ¦ºÎ Ŭ¶óÀÌ¾ðÆ®¿¡ ¾Ë¸² HANDLE handle = NULL; switch( i ) { case eODDITYTYPE_CANTMOVE: { MSG_SYN_PLAYER_CANTMOVE synMsg; synMsg.Category = NM_PLAYER; synMsg.Protocol = NM_PLAYER_CANTMOVE_SYN; synMsg.mIsCantMove = false; synMsg.mCharaterIdx = mObject.index; synMsg.mCharacterPos.x = mObjectPos.x; synMsg.mCharacterPos.y = mObjectPos.y; NETWORK2->QuickSend( this, (char*)&synMsg, sizeof(synMsg) ); } break; case eODDITYTYPE_CANTSKILL_PHY: { MSG_SYN_PLAYER_CANTSKILL* sendMsg = (MSG_SYN_PLAYER_CANTSKILL*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_CANTSKILL_SYN ); if ( sendMsg != NULL ) { sendMsg->mAttributeType = eATTRIBUTETYPE_PHYSICAL; sendMsg->mIsCantSkill = false; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_PLAYER_CANTSKILL) ); } } break; case eODDITYTYPE_CANTSKILL_MAG: { MSG_SYN_PLAYER_CANTSKILL* sendMsg = (MSG_SYN_PLAYER_CANTSKILL*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_CANTSKILL_SYN ); if ( sendMsg != NULL ) { sendMsg->mAttributeType = eATTRIBUTETYPE_MAGIC; sendMsg->mIsCantSkill = false; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_PLAYER_CANTSKILL) ); } } break; case eODDITYTYPE_SLEEP: { MSG_SYN_PLAYER_SLEEP synMsg; synMsg.Category = NM_PLAYER; synMsg.Protocol = NM_PLAYER_SLEEP_SYN; synMsg.mIsSleep = false; synMsg.mCharaterIdx = mObject.index; synMsg.mCharacterPos.x = mObjectPos.x; synMsg.mCharacterPos.y = mObjectPos.y; NETWORK2->QuickSend( this, (char*)&synMsg, sizeof(synMsg) ); } break; case eODDITYTYPE_STUN: { MSG_SYN_PLAYER_STUN synMsg; synMsg.Category = NM_PLAYER; synMsg.Protocol = NM_PLAYER_STUN_SYN; synMsg.mIsStun = false; synMsg.mCharaterIdx = mObject.index; synMsg.mCharacterPos.x = mObjectPos.x; synMsg.mCharacterPos.y = mObjectPos.y; NETWORK2->QuickSend( this, (char*)&synMsg, sizeof(synMsg) ); } break; case eODDITYTYPE_AVOID_MON_LOOK: { MSG_SYN_PLAYEREXT_AVOID_MON_LOOK* synMsg = (MSG_SYN_PLAYEREXT_AVOID_MON_LOOK*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYEREXT, NM_PLAYEREXT_AVOID_MON_LOOK_SYN ); if ( synMsg != NULL ) { synMsg->mIsAvoidMonLookOn = false; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_PLAYEREXT_AVOID_MON_LOOK) ); } } break; } } } } } bool cPlayer::IsCantSkill( unsigned long attributeType ) { if( attributeType == eATTRIBUTETYPE_PHYSICAL ) return mODDITY[eODDITYTYPE_CANTSKILL_PHY] != 0 || mODDITY[eODDITYTYPE_SLEEP] != 0 || mODDITY[eODDITYTYPE_STUN] != 0; else return mODDITY[eODDITYTYPE_CANTSKILL_MAG] != 0 || mODDITY[eODDITYTYPE_SLEEP] != 0 || mODDITY[eODDITYTYPE_STUN] != 0; } // IsAddMoney Method. bool cPlayer::IsAddMoney(long money) { if ( money > 0 ) { unsigned long newMoney = mMoney + money; // ÃÖ´ë ±Ý¾×º¸´Ù Ä¿Áú°Ü¿ì ¶Ç´Â ¿À¹öÇ÷ΠÀÏ °æ¿ì return ( newMoney > MAX_HAVE_MONEY || newMoney < mMoney ) ? false : true; } else return ( (unsigned long)labs(money) <= mMoney ) ? true : false; } // AddMoney Method - #include ULONG_MAX=[4,294,967,295]. long cPlayer::AddMoney(sObject object, long money, bool save) { if ( money > 0 ) { unsigned long maxMoney = MAX_HAVE_MONEY; unsigned long newMoney = mMoney + money; // ÃÖ´ë ±Ý¾×º¸´Ù Ä¿Áú°Ü¿ì ¶Ç´Â ¿À¹öÇ÷ΠÀÏ °æ¿ì if ( newMoney > maxMoney || newMoney < mMoney ) money = maxMoney - mMoney; // º¯°æµÈ ±Ý¾× ÀúÀå(DB). if ( save == true ) SaveMoney( object, mMoney, mMoney+money, money ); mMoney += money; // º¯°æµÈ ±Ý¾× ¹ß¼Û. SendMoney( object, money ); return money; } else if ( (unsigned long)labs(money) <= mMoney ) { // º¯°æµÈ ±Ý¾× ÀúÀå(DB). if ( save == true ) SaveMoney( object, mMoney, mMoney+money, money ); mMoney += money; // º¯°æµÈ ±Ý¾× ¹ß¼Û. SendMoney( object, money ); return money; } else return 0; } // SaveMoney Method - º¯°æÇÒ ±Ý¾×¸¸ ¹Ý¿µ. bool cPlayer::SaveMoney(sObject object, unsigned long befor, unsigned long after, long money) { HANDLE handle = NULL; CHARACTER_MONEY* characterMoney = (CHARACTER_MONEY*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_CHARACTER_MONEY ); if ( characterMoney != NULL ) { characterMoney->idx = mObject.index; characterMoney->money = (__int64)money; characterMoney->objectType = object.type; characterMoney->objectIndex = object.index; characterMoney->befor = befor; characterMoney->after = after; switch ( object.type ) { case eOBJECTTYPE_MONSTER: { cMonster* monster = OBJECTMANAGER->GetMonster( object.index ); if ( monster != NULL ) characterMoney->objectRaceGender = monster->GetRaceGender( ); } break; case eOBJECTTYPE_NPC: { cNpc* npc = OBJECTMANAGER->GetNpc( object.index ); if ( npc != NULL ) characterMoney->objectRaceGender = npc->GetRaceGender( ); } break; } return NETWORK2->SendSQL( handle, sizeof(CHARACTER_MONEY) ); } return false; } // SendMoney Method. bool cPlayer::SendMoney(sObject object, long addMoney) { HANDLE handle = NULL; MSG_RES_PLAYER_MONEY* sendMsg = (MSG_RES_PLAYER_MONEY*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_MONEY_RES ); if ( sendMsg != NULL ) { sendMsg->mMoney = mMoney; sendMsg->mObjectType = object.type; sendMsg->mAddMoney = addMoney; return NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_PLAYER_MONEY) ); } return false; } // AddDeposit Method - #include ULONG_MAX=[4,294,967,295]. long cPlayer::AddDeposit(sObject object, long deposit) { if ( deposit > 0 ) { unsigned long maxDeposit = MAX_HAVE_MONEY; unsigned long newDeposit = mDeposit + deposit; // ÃÖ´ë ±Ý¾×º¸´Ù Ä¿Áú°Ü¿ì ¶Ç´Â ¿À¹öÇ÷ΠÀÏ °æ¿ì if ( newDeposit > maxDeposit || newDeposit < mDeposit ) deposit = maxDeposit - mDeposit; // º¯°æµÈ ±Ý¾× ÀúÀå(DB). SaveDeposit( object, mDeposit, mDeposit+deposit, deposit ); mDeposit += deposit; // º¯°æµÈ ±Ý¾× ¹ß¼Û. SendDeposit( object, deposit ); return deposit; } else if ( (unsigned long)labs(deposit) <= mDeposit ) { // º¯°æµÈ ±Ý¾× ÀúÀå(DB). SaveDeposit( object, mDeposit, mDeposit+deposit, deposit ); mDeposit += deposit; // º¯°æµÈ ±Ý¾× ¹ß¼Û. SendDeposit( object, deposit ); return deposit; } else return 0; } // SaveDeposit Method - º¯°æÇÒ ±Ý¾×¸¸ ¹Ý¿µ. bool cPlayer::SaveDeposit(sObject object, unsigned long befor, unsigned long after, long deposit) { HANDLE handle = NULL; CHARACTER_DEPOSIT* characterDeposit = (CHARACTER_DEPOSIT*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_CHARACTER_DEPOSIT ); if ( characterDeposit != NULL ) { characterDeposit->idx = mObject.index; characterDeposit->money = (__int64)deposit; characterDeposit->objectType = object.type; characterDeposit->objectIndex = object.index; characterDeposit->befor = befor; characterDeposit->after = after; if ( object.type == eOBJECTTYPE_NPC ) { cNpc* npc = OBJECTMANAGER->GetNpc( object.index ); if ( npc != NULL ) { characterDeposit->objectRaceGender = npc->GetRaceGender( ); } } return NETWORK2->SendSQL( handle, sizeof(CHARACTER_DEPOSIT) ); } return false; } // SendDeposit Method. bool cPlayer::SendDeposit(sObject object, long addDeposit) { HANDLE handle = NULL; MSG_RES_PLAYER_DEPOSIT* sendMsg = (MSG_RES_PLAYER_DEPOSIT*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_DEPOSIT_RES ); if ( sendMsg != NULL ) { sendMsg->mDeposit = mDeposit; sendMsg->mObjectType = object.type; sendMsg->mAddDeposit = addDeposit; return NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_PLAYER_DEPOSIT) ); } return false; } // NpcDeposit Method. void cPlayer::NpcDeposit(MSG_REQ_NPC_DEPOSIT* msg) { // npc ÀÎÁõ if ( GetStateStop() == eSTOP_NPCSPEECH ) { unsigned long retValue = OBJECTMANAGER->IsNpcTalk( msg->npcIdx, this, eNPCTALK_INVENTORY, 0 ); if ( retValue != ERROR_NPC_OPEN_SUCCESS ) { NETWORK2->PostServerEvent( "player[%d,%d,%d] return[%d]cPlayer::NpcDeposit retValue != ERROR_NPC_OPEN_SUCCESS", mObject.index, mPlayerExrInfo.mState, mPlayerExrInfo.mStateStop, retValue ); throw ERROR_NPC_DEPOSIT_NPC; } } else { if ( GetStateStop() != eSTOP_SUMMON_PAPER ) { NETWORK2->PostServerEvent( "ERROR player[%d,%d,%d] cPlayer::NpcDeposit GetStateStop != eSTOP_SUMMON_PAPER", mObject.index, mPlayerExrInfo.mState, mPlayerExrInfo.mStateStop ); throw ERROR_NPC_DEPOSIT_FAIL; } } if ( msg->money > GetMoney( ) || msg->money > MAX_TRADE_MONEY ) throw ERROR_NPC_DEPOSIT_TRADE_MONEY; sObject object = { eOBJECTTYPE_NPC, msg->npcIdx }; long money = -(long)msg->money; long deposit = +(long)msg->money; long result; // ÃÖ´ë º¸À¯±Ý¾× if( GetDeposit() + deposit > MAX_HAVE_MONEY ) throw ERROR_NPC_DEPOSIT_HAVE_MONEY; result = AddMoney( object, money ); if ( result != money ) NETWORK2->PostServerEvent( "WARNING - NM_NPC_DEPOSIT_REQ - CharacterIdx(%u) Money(%u)", mObject.index, GetMoney( ) ); result = AddDeposit( object, deposit ); if ( result != deposit ) NETWORK2->PostServerEvent( "WARNING - NM_NPC_DEPOSIT_REQ - CharacterIdx(%u) Deposit(%u) AddMoney(%u)", mObject.index, GetDeposit( ), deposit ); throw ERROR_NPC_DEPOSIT_SUCCESS; } // NpcWithdraw Method. void cPlayer::NpcWithdraw(MSG_REQ_NPC_WITHDRAW* msg) { // npc ÀÎÁõ if ( GetStateStop() == eSTOP_NPCSPEECH ) { unsigned long retValue = OBJECTMANAGER->IsNpcTalk( msg->npcIdx, this, eNPCTALK_INVENTORY, 0 ); if ( retValue != ERROR_NPC_OPEN_SUCCESS ) { NETWORK2->PostServerEvent( "player[%d,%d,%d] return[%d]cPlayer::NpcWithdraw retValue != ERROR_NPC_OPEN_SUCCESS", mObject.index, mPlayerExrInfo.mState, mPlayerExrInfo.mStateStop, retValue ); throw ERROR_NPC_WITHDRAW_NPC; } } else { if ( GetStateStop() != eSTOP_SUMMON_PAPER ) { NETWORK2->PostServerEvent( "ERROR player[%d,%d,%d] cPlayer::NpcWithdraw GetStateStop != eSTOP_SUMMON_PAPER", mObject.index, mPlayerExrInfo.mState, mPlayerExrInfo.mStateStop ); throw ERROR_NPC_WITHDRAW_FAIL; } } if ( msg->money > GetDeposit() || msg->money > MAX_TRADE_MONEY ) throw ERROR_NPC_WITHDRAW_TRADE_MONEY; sObject object = { eOBJECTTYPE_NPC, msg->npcIdx }; long money = +(long)msg->money; long withdraw = -(long)msg->money; long result; if( IsAddMoney( money ) == false ) throw ERROR_NPC_WITHDRAW_HAVE_MONEY; result = AddMoney( object, money ); if ( result != money ) NETWORK2->PostServerEvent( "WARNING - NM_NPC_WITHDRAW_REQ - CharacterIdx(%u) Money(%u)", mObject.index, GetMoney( ) ); result = AddDeposit( object, withdraw ); if ( result != withdraw ) NETWORK2->PostServerEvent( "WARNING - NM_NPC_WITHDRAW_REQ - CharacterIdx(%u) Deposit(%u)", mObject.index, GetDeposit( ) ); throw ERROR_NPC_WITHDRAW_SUCCESS; } // AddTarotPoint Method long cPlayer::AddTarotPoint(long point) { unsigned long& point_t = mHeroInfo.TarotPoint; if ( point > 0 ) { unsigned long maxPoint = ULONG_MAX - 1UL; unsigned long newPoint = point_t + point; // ÃÖ´ë ±Ý¾×º¸´Ù Ä¿Áú°Ü¿ì ¶Ç´Â ¿À¹öÇ÷ΠÀÏ °æ¿ì if ( newPoint > maxPoint || newPoint < point_t ) { point = maxPoint - point_t; } // º¯°æµÈ ±Ý¾× ÀúÀå(DB). SaveTarotPoint( point ); point_t += point; // º¯°æµÈ ±Ý¾× ¹ß¼Û. SendTarotPoint( point ); return point; } else if ( (unsigned long)labs(point) <= point_t ) { // º¯°æµÈ ±Ý¾× ÀúÀå(DB). SaveTarotPoint( point ); point_t += point; // º¯°æµÈ ±Ý¾× ¹ß¼Û. SendTarotPoint( point ); return point; } else return 0; } // SaveTarotPoint Method bool cPlayer::SaveTarotPoint(long point) { HANDLE handle = NULL; CHARACTER_TAROT_POINT* tarotPoint = (CHARACTER_TAROT_POINT*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_CHARACTER_TAROT_POINT ); if ( point != NULL ) { tarotPoint->idx = mObject.index; tarotPoint->point = point; return NETWORK2->SendSQL( handle, sizeof(CHARACTER_TAROT_POINT) ); } return false; } // SendTarotPoint Method bool cPlayer::SendTarotPoint(long point) { HANDLE handle = NULL; MSG_RES_PLAYER_TAROT_POINT* sendMsg = (MSG_RES_PLAYER_TAROT_POINT*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_TAROT_POINT_RES ); if ( sendMsg != NULL ) { sendMsg->mPoint = mHeroInfo.TarotPoint; sendMsg->mAddPoint = point; return NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_PLAYER_TAROT_POINT) ); } return false; } unsigned long cPlayer::GetPvPPoint( unsigned char forceType ) { switch( forceType ) { case eFORCETYPE_FIRE: return mHeroInfo.mFirePoint; case eFORCETYPE_WATER: return mHeroInfo.mWaterPoint; case eFORCETYPE_WIND: return mHeroInfo.mWindPoint; case eFORCETYPE_EARTH: return mHeroInfo.mEarthPoint; default: return 0; } } // AddPvPPoint Method long cPlayer::AddPvPPoint( long point, unsigned char forceType ) { unsigned long* point_t = NULL; switch( forceType ) { case eFORCETYPE_FIRE: point_t = &mHeroInfo.mFirePoint; break; case eFORCETYPE_WATER: point_t = &mHeroInfo.mWaterPoint; break; case eFORCETYPE_WIND: point_t = &mHeroInfo.mWindPoint; break; case eFORCETYPE_EARTH: point_t = &mHeroInfo.mEarthPoint; break; default: return 0; } if ( point > 0 ) { unsigned long maxPoint = ULONG_MAX - 1UL; unsigned long newPoint = *point_t + point; // ÃÖ´ë ±Ý¾×º¸´Ù Ä¿Áú°Ü¿ì ¶Ç´Â ¿À¹öÇ÷ΠÀÏ °æ¿ì if ( newPoint > maxPoint || newPoint < *point_t ) { point = maxPoint - *point_t; } // º¯°æµÈ ±Ý¾× ÀúÀå(DB). //SaveTarotPoint( point ); *point_t += point; /// point µ¿½Ã ó¸® °æ¿ì°¡ »ý±â¸é +- ÇÕ»ê ÀúÀåÀ¸·Î ¹Ù²ã¾ßÇÔ ForcePointDBUpdate(); // º¯°æµÈ ±Ý¾× ¹ß¼Û. SendPvPPoint( point, forceType ); return point; } else if ( (unsigned long)labs(point) <= *point_t ) { // º¯°æµÈ ±Ý¾× ÀúÀå(DB). //SaveTarotPoint( point ); *point_t += point; /// point µ¿½Ã ó¸® °æ¿ì°¡ »ý±â¸é +- ÇÕ»ê ÀúÀåÀ¸·Î ¹Ù²ã¾ßÇÔ ForcePointDBUpdate(); // º¯°æµÈ ±Ý¾× ¹ß¼Û. SendPvPPoint( point, forceType ); return point; } else return 0; } // SendPvPPoint Method bool cPlayer::SendPvPPoint( long point, unsigned char forceType ) { HANDLE handle = NULL; MSG_RES_PLAYER_PVP_POINT* sendMsg = (MSG_RES_PLAYER_PVP_POINT*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_PVP_POINT_RES ); if ( sendMsg != NULL ) { sendMsg->mForceType = forceType; sendMsg->mPoint = GetPvPPoint( forceType ); sendMsg->mAddPoint = point; return NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_PLAYER_PVP_POINT) ); } return false; } /// InventoryMove Method bool cPlayer::IsInventoryMove(unsigned short number1, unsigned short number2, short* except, int& depth) { TB_INVENTORY* inventory1 = SelectInventory( number1 ); TB_INVENTORY* inventory2 = SelectInventory( number2 ); if ( IsInventory( inventory1 ) == false ) { return false; } else if ( IsInventory( inventory2 ) && depth == 0 ) { if ( IsInventoryMove( number2, number1, except, (--depth) ) == false ) return false; } // Ÿ·ÎÄ«µå üũ if ( IsInventoryCollect( number2 ) == true ) { TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory1->itemDefineIdx ); if ( itemDefine == NULL ) return false; if ( itemDefine->type == ITEM_CARD ) { if ( !(itemDefine->subType == ITEM_CARD_TAROT || itemDefine->subType == ITEM_CARD_TAROT_SILVER || itemDefine->subType == ITEM_CARD_TAROT_GOLD || itemDefine->subType == ITEM_CARD_TAROT_DIA) ) { return false; } TB_ITEM_TAROT* itemTarot = ITEMMANAGER->GetItemTarot( inventory1->itemDefineIdx ); if ( itemTarot == NULL ) return false; long tarotBegin = INVENTORY_TAROT_NORMAL_BEGIN; switch ( itemDefine->subType ) { case ITEM_CARD_TAROT: tarotBegin = INVENTORY_TAROT_NORMAL_BEGIN; break; case ITEM_CARD_TAROT_SILVER: tarotBegin = INVENTORY_TAROT_SILVER_BEGIN; break; case ITEM_CARD_TAROT_GOLD: tarotBegin = INVENTORY_TAROT_GOLD_BEGIN; break; case ITEM_CARD_TAROT_DIA: tarotBegin = INVENTORY_TAROT_DIA_BEGIN; break; } if ( (itemTarot->number + tarotBegin) != number2 ) return false; } else return false; } if ( IsInventoryEquip( number2 ) == false ) return true; /*-- ¾ÆÀÌÅÛ Âø¿ë °¡´É È®ÀÎ */ TB_ITEM_DEFINE* tbItemDefine = ITEMMANAGER->GetItemDefine( inventory1->itemDefineIdx ); if ( tbItemDefine == NULL ) return false; /*-- Item Limit Table(TB_ITEM_LIMIT) Àû¿ë --*/ if ( !IsItemLimit( inventory1->itemDefineIdx ) ) return false; /*-- ¹ÌÀÎÁõ ¾ÆÀÌÅÛ --*/ if ( IsInventorySeal( inventory1 ) == true ) return false; switch ( tbItemDefine->type ) { case ITEM_WEAPON: switch ( tbItemDefine->subType ) { case ITEM_WEAPON_SWORD: switch ( number2 ) { case INVENTORY_HAND_RIGHT1: { TB_INVENTORY* left1 = SelectInventory( INVENTORY_HAND_LEFT1 ); if ( IsInventory( left1 ) ) { if ( ITEMMANAGER->GetItemDefineSubType( left1->itemDefineIdx ) != ITEM_WEAPON_SHIELD ) (*except) = INVENTORY_HAND_LEFT1; } } return true; case INVENTORY_HAND_RIGHT2: { TB_INVENTORY* left2 = SelectInventory( INVENTORY_HAND_LEFT2 ); if ( IsInventory( left2 ) ) { if ( ITEMMANAGER->GetItemDefineSubType( left2->itemDefineIdx ) != ITEM_WEAPON_SHIELD ) (*except) = INVENTORY_HAND_LEFT2; } } return true; } break; // tbItemDefine->subType case ITEM_WEAPON_BLADE: case ITEM_WEAPON_DUAL: case ITEM_WEAPON_CUTTER: case ITEM_WEAPON_GUN: case ITEM_WEAPON_STAFF: switch ( number2 ) { case INVENTORY_HAND_LEFT1: if ( IsInventory( SelectInventory( INVENTORY_HAND_RIGHT1 ) ) ) (*except) = INVENTORY_HAND_RIGHT1; return true; case INVENTORY_HAND_RIGHT1: if ( IsInventory( SelectInventory( INVENTORY_HAND_LEFT1 ) ) ) (*except) = INVENTORY_HAND_LEFT1; return true; case INVENTORY_HAND_LEFT2: if ( IsInventory( SelectInventory( INVENTORY_HAND_RIGHT2 ) ) ) (*except) = INVENTORY_HAND_RIGHT2; return true; case INVENTORY_HAND_RIGHT2: if ( IsInventory( SelectInventory( INVENTORY_HAND_LEFT2 ) ) ) (*except) = INVENTORY_HAND_LEFT2; return true; } break; // tbItemDefine->subType case ITEM_WEAPON_SHIELD: switch ( number2 ) { case INVENTORY_HAND_LEFT1: { TB_INVENTORY* right1 = SelectInventory( INVENTORY_HAND_RIGHT1 ); if ( IsInventory( right1 ) ) { if ( ITEMMANAGER->GetItemDefineSubType( right1->itemDefineIdx ) != ITEM_WEAPON_SWORD ) (*except) = INVENTORY_HAND_RIGHT1; } } return true; case INVENTORY_HAND_LEFT2: { TB_INVENTORY* right2 = SelectInventory( INVENTORY_HAND_RIGHT2 ); if ( IsInventory( right2 ) ) { if ( ITEMMANAGER->GetItemDefineSubType( right2->itemDefineIdx ) != ITEM_WEAPON_SWORD ) (*except) = INVENTORY_HAND_RIGHT2; } } return true; } break; // tbItemDefine->subType } return false; // switch ( tbItemDefine->type ) case ITEM_WEAR: switch ( tbItemDefine->subType ) { case ITEM_WEAR_HEAD: return (number2 == INVENTORY_WEAR_HAT); case ITEM_WEAR_UPPER: return (number2 == INVENTORY_WEAR_BODY1); case ITEM_WEAR_LOWER: return (number2 == INVENTORY_WEAR_BODY2); case ITEM_WEAR_HANDS: return (number2 == INVENTORY_WEAR_HAND); case ITEM_WEAR_FEET: return (number2 == INVENTORY_WEAR_FOOT); case ITEM_WEAR_ONEPIECE: switch ( number2 ) { case INVENTORY_WEAR_BODY1: if ( IsInventory( SelectInventory( INVENTORY_WEAR_BODY2 ) ) ) (*except) = INVENTORY_WEAR_BODY2; return true; case INVENTORY_WEAR_BODY2: if ( IsInventory( SelectInventory( INVENTORY_WEAR_BODY1 ) ) ) (*except) = INVENTORY_WEAR_BODY1; return true; } break; case ITEM_WEAR_COS_ONEPIECE: if ( number2 == INVENTORY_COSTUME_BODY1 ) { if ( IsInventory( SelectInventory( INVENTORY_COSTUME_BODY2 ) ) ) { (*except) = INVENTORY_COSTUME_BODY2; except++; } if ( IsInventory( SelectInventory( INVENTORY_COSTUME_HAND ) ) ) { (*except) = INVENTORY_COSTUME_HAND; except++; } if ( IsInventory( SelectInventory( INVENTORY_COSTUME_FOOT ) ) ) { (*except) = INVENTORY_COSTUME_FOOT; except++; } return true; } return false; case ITEM_WEAR_COS_HEAD: return (number2 == INVENTORY_COSTUME_HAT); case ITEM_WEAR_COS_UPPER: return (number2 == INVENTORY_COSTUME_BODY1); case ITEM_WEAR_COS_LOWER: if ( number2 == INVENTORY_COSTUME_BODY2 ) { TB_INVENTORY* upper = SelectInventory( INVENTORY_COSTUME_BODY1 ); if ( IsInventory( upper ) ) { TB_ITEM_DEFINE* tempDefine = ITEMMANAGER->GetItemDefine( upper->itemDefineIdx ); if ( tempDefine->subType == ITEM_WEAR_COS_ONEPIECE ) (*except) = INVENTORY_COSTUME_BODY1; } return true; } return false; case ITEM_WEAR_COS_HANDS: if ( number2 == INVENTORY_COSTUME_HAND ) { TB_INVENTORY* upper = SelectInventory( INVENTORY_COSTUME_BODY1 ); if ( IsInventory( upper ) ) { TB_ITEM_DEFINE* tempDefine = ITEMMANAGER->GetItemDefine( upper->itemDefineIdx ); if ( tempDefine->subType == ITEM_WEAR_COS_ONEPIECE ) (*except) = INVENTORY_COSTUME_BODY1; } return true; } else return false; case ITEM_WEAR_COS_FEET: if ( number2 == INVENTORY_COSTUME_FOOT ) { TB_INVENTORY* upper = SelectInventory( INVENTORY_COSTUME_BODY1 ); if ( IsInventory( upper ) ) { TB_ITEM_DEFINE* tempDefine = ITEMMANAGER->GetItemDefine( upper->itemDefineIdx ); if ( tempDefine->subType == ITEM_WEAR_COS_ONEPIECE ) (*except) = INVENTORY_COSTUME_BODY1; } return true; } else return false; } return false; // switch ( tbItemDefine->type ) case ITEM_ACCESSORY: switch ( tbItemDefine->subType ) { case ITEM_ACCESSORY_EARRING: return (number2 == INVENTORY_WEAR_EARRING); case ITEM_ACCESSORY_NECKLACE: return (number2 == INVENTORY_WEAR_NECKLACE); case ITEM_ACCESSORY_BROOCH: return (number2 == INVENTORY_WEAR_BROOCH); case ITEM_ACCESSORY_BRACELET: return (number2 == INVENTORY_WEAR_BRACELET); case ITEM_ACCESSORY_RING: return (number2 == INVENTORY_WEAR_RING); case ITEM_ACCESSORY_COS_FACE: return (number2 == INVENTORY_COSTUME_FACE); case ITEM_ACCESSORY_COS_BACK: return (number2 == INVENTORY_COSTUME_BACK); } return false; // switch ( tbItemDefine->type ) case ITEM_CARD: if ( tbItemDefine->subType == ITEM_CARD_EQUIP_C ) { switch ( number2 ) { case INVENTORY_WEAR_CARD1: case INVENTORY_WEAR_CARD2: case INVENTORY_WEAR_CARD3: return true; } } return false; // switch ( tbItemDefine->type ) default: return false; // switch ( tbItemDefine->type ) } } /// IsInventoryMerge Method bool cPlayer::IsInventoryMerge(TB_ITEM_DEFINE* itemDefine, TB_INVENTORY* inventory1, TB_INVENTORY* inventory2) { if ( IsInventory( inventory1 ) && IsInventory( inventory2 ) ) { if ( inventory1->itemDefineIdx == inventory2->itemDefineIdx ) { if ( itemDefine == NULL ) return false; else if ( inventory1->cash > 0 || inventory2->cash > 0 ) return false; else return (itemDefine->capacity > 1 && itemDefine->licenseType != 1) ? true : false; } } return false; } /// IsInventorySeal Method bool cPlayer::IsInventorySeal( TB_ITEM_DEFINE* itemDefine, TB_INVENTORY* inventory ) { if( IsInventory( inventory ) ) { if ( itemDefine ) return ( itemDefine->licenseType == 1 && inventory->seal == 1); } return false; } /// IsInventorySeal Method bool cPlayer::IsInventorySeal(TB_INVENTORY* inventory) { TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if ( itemDefine != NULL ) { return IsInventorySeal( itemDefine, inventory ); } return false; } /// IsInventoryMegaphone Method bool cPlayer::IsInventoryMegaphone(long inventoryIdx) { TB_INVENTORY* inventory = SelectInventory( INVENTORY_BAG_BEGIN ); for ( unsigned short i = INVENTORY_BAG_BEGIN; i <= mHeroInfo.BagEnd; i++, inventory++ ) { if ( IsInventory( inventory ) == true ) { if ( inventory->idx == inventoryIdx ) { TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if ( itemDefine != NULL && inventory->seal == 0 ) { if ( (itemDefine->type == ITEM_ETC1 && itemDefine->subType == ITEM_ETC1_SHOUT) && (COOLTIMEPOOL->IsCooltime( &mCooltimeRoot, inventory->itemDefineIndex ) == false) ) { COOLTIMEPOOL->ApplyCooltime( &mCooltimeRoot, inventory ); return true; } } break; } } } return false; } /// SetInventorySize Method bool cPlayer::SetInvenLimit( TB_ITEM_DEFINE* itemDefine, CHARACTER_INVEN_SIZE* invenSize ) { if( itemDefine->subType == ITEM_INVENTORY_BAG ) { switch( mHeroInfo.BagEnd ) { case INVENTORY_BAG0_END: invenSize->bag = INVENTORY_BAG1_END; break; case INVENTORY_BAG1_END: invenSize->bag = INVENTORY_BAG2_END; break; case INVENTORY_BAG2_END: invenSize->bag = INVENTORY_BAG3_END; break; default: return false; break; } } else if( itemDefine->subType == ITEM_INVENTORY_CARD ) { switch( mHeroInfo.WearEnd ) { case INVENTORY_WEAR_RING : invenSize->wear = INVENTORY_WEAR_CARD1; break; case INVENTORY_WEAR_CARD1: invenSize->wear = INVENTORY_WEAR_CARD2; break; case INVENTORY_WEAR_CARD2: invenSize->wear = INVENTORY_WEAR_CARD3; break; default: return false; break; } } else if( itemDefine->subType == ITEM_INVENTORY_WAREHOUSE ) { switch( mHeroInfo.WareHouseEnd ) { case INVENTORY_WAREHOUSE0_END: invenSize->wareHouse = INVENTORY_WAREHOUSE1_END; break; case INVENTORY_WAREHOUSE1_END: invenSize->wareHouse = INVENTORY_WAREHOUSE2_END; break; case INVENTORY_WAREHOUSE2_END: invenSize->wareHouse = INVENTORY_WAREHOUSE3_END; break; default: return false; break; } } else if( itemDefine->subType == ITEM_INVENTORY_MAKESKILL ) { invenSize->makeSkill += 1; if( invenSize->makeSkill > MAX_MAKESKILL ) invenSize->makeSkill = MAX_MAKESKILL; } return true; } // GetEmptyBagNumber Method short cPlayer::GetEmptyBagNumber(short number) { TB_INVENTORY* inventory = SelectInventory( number ); for ( short i = number; i <= mHeroInfo.BagEnd; i++, inventory++ ) { if ( !IsInventory( inventory ) ) return i; } return INVENTORY_BAG_NONE; } // GetEmptyQuestNumber Method short cPlayer::GetEmptyQuestNumber(short number) { TB_INVENTORY* inventory = SelectInventory( number ); for ( short i = number; i <= INVENTORY_QUEST_END; i++, inventory++ ) { if ( !IsInventory( inventory ) ) return i; } return INVENTORY_QUEST_NONE; } /// InventorySwap Method void cPlayer::InventorySwap(unsigned short number1, unsigned short number2) { TB_INVENTORY* inventory1 = SelectInventory( number1 ); TB_INVENTORY* inventory2 = SelectInventory( number2 ); XCopyInventory( inventory1, inventory2, XCOPY_INVENTORY_SWAP ); } // InventoryMove Method void cPlayer::InventoryMove(unsigned short number1, unsigned short number2) { TB_INVENTORY* inventory1 = SelectInventory( number1 ); TB_INVENTORY* inventory2 = SelectInventory( number2 ); inventory1->number = number2; XCopyInventory( inventory2, inventory1, XCOPY_INVENTORY_ALL ); inventory1->number = number1; if ( IsInventoryCash( number1 ) == true ) { inventory1->count += -(inventory1->count); } RemoveInventory( inventory1 ); } // InventoryExcept Method void cPlayer::InventoryExcept(unsigned short number1, unsigned short number2) { TB_INVENTORY* inventory1 = SelectInventory( number1 ); TB_INVENTORY* inventory2 = SelectInventory( number2 ); inventory1->number = number2; XCopyInventory( inventory2, inventory1, XCOPY_INVENTORY_ALL ); inventory1->number = number1; RemoveInventory( inventory1 ); } // IsItemLimit Method. bool cPlayer::IsItemLimit(long itemDefineIdx) { TB_ITEM_LIMIT* itemLimit = ITEMMANAGER->GetItemLimit( itemDefineIdx ); if ( itemLimit != NULL ) { // Á¾Á·; TB_ITEM_LIMIT::charRace ¿Í sPlayerInfo::Race ´Â Á¤ÀÇ´Â ´Ù¸£³ª °°Àº °ªÀ» »ç¿ë. if ( itemLimit->charRace != ITEM_RACE_ALL ) { if ( itemLimit->charRace != mPlayerInfo.Race ) return false; } // ¼ºº°; TB_ITEM_LIMIT::charGender ¿Í sPlayerInfo::Gender ´Â Á¤ÀÇ´Â ´Ù¸£³ª °°Àº °ªÀ» »ç¿ë. if ( itemLimit->charGender != ITEM_GENDER_ALL ) { if ( itemLimit->charGender != mPlayerInfo.Gender ) return false; } // Á÷¾÷; TB_ITEM_LIMIT::charJob ¿Í sPlayerInfo::Job Àº Á¤ÀÇ´Â ´Ù¸£³ª °°Àº °ªÀ» »ç¿ë. if ( itemLimit->charJob1 != ITEM_JOB_ALL && itemLimit->charJob2 != ITEM_JOB_ALL ) { switch ( mPlayerInfo.Job ) { // ÆÄÀÌÅÍ(Àü»çÇü) ÀüÁ÷ Ŭ·¡½º - ÇÏÀ§ Á÷¾÷±º Æ÷ÇÔ. case ePLAYER_CRUSADER: if ( ePLAYER_CRUSADER == itemLimit->charJob1 || ePLAYER_CRUSADER == itemLimit->charJob2 ) break; case ePLAYER_KNIGHT: if ( ePLAYER_KNIGHT == itemLimit->charJob1 || ePLAYER_KNIGHT == itemLimit->charJob2 ) break; if ( ePLAYER_FIGHTER == itemLimit->charJob1 || ePLAYER_FIGHTER == itemLimit->charJob2 ) break; return false; case ePLAYER_TEMPLAR: if ( ePLAYER_TEMPLAR == itemLimit->charJob1 || ePLAYER_TEMPLAR == itemLimit->charJob2 ) break; case ePLAYER_GLADIATOR: if ( ePLAYER_GLADIATOR == itemLimit->charJob1 || ePLAYER_GLADIATOR == itemLimit->charJob2 ) break; if ( ePLAYER_FIGHTER == itemLimit->charJob1 || ePLAYER_FIGHTER == itemLimit->charJob2 ) break; return false; case ePLAYER_SOULBLADER: if ( ePLAYER_SOULBLADER == itemLimit->charJob1 || ePLAYER_SOULBLADER == itemLimit->charJob2 ) break; case ePLAYER_MERCENARY: if ( ePLAYER_MERCENARY == itemLimit->charJob1 || ePLAYER_MERCENARY == itemLimit->charJob2 ) break; if ( ePLAYER_FIGHTER == itemLimit->charJob1 || ePLAYER_FIGHTER == itemLimit->charJob2 ) break; return false; case ePLAYER_FIGHTER: if ( ePLAYER_FIGHTER == itemLimit->charJob1 || ePLAYER_FIGHTER == itemLimit->charJob2 ) break; return false; // ¸ÞÀÌÁö(¸¶¹ýÇü) ÀüÁ÷ Ŭ·¡½º - ÇÏÀ§ Á÷¾÷±º Æ÷ÇÔ. case ePLAYER_WIZARD: if ( ePLAYER_WIZARD == itemLimit->charJob1 || ePLAYER_WIZARD == itemLimit->charJob2 ) break; case ePLAYER_MAGICIAN: if ( ePLAYER_MAGICIAN == itemLimit->charJob1 || ePLAYER_MAGICIAN == itemLimit->charJob2 ) break; if ( ePLAYER_MAGE == itemLimit->charJob1 || ePLAYER_MAGE == itemLimit->charJob2 ) break; return false; case ePLAYER_HIGHPRIEST: if ( ePLAYER_HIGHPRIEST == itemLimit->charJob1 || ePLAYER_HIGHPRIEST == itemLimit->charJob2 ) break; case ePLAYER_PRIEST: if ( ePLAYER_PRIEST == itemLimit->charJob1 || ePLAYER_PRIEST == itemLimit->charJob2 ) break; if ( ePLAYER_MAGE == itemLimit->charJob1 || ePLAYER_MAGE == itemLimit->charJob2 ) break; return false; case ePLAYER_MAGE: if ( ePLAYER_MAGE == itemLimit->charJob1 || ePLAYER_MAGE == itemLimit->charJob2 ) break; return false; // ¿ø´õ·¯(¹ÎøÇü) ÀüÁ÷ Ŭ·¡½º - ÇÏÀ§ Á÷¾÷±º Æ÷ÇÔ. case ePLAYER_ASSASSIN: if ( ePLAYER_ASSASSIN == itemLimit->charJob1 || ePLAYER_ASSASSIN == itemLimit->charJob2 ) break; case ePLAYER_WINDWALKER: if ( ePLAYER_WINDWALKER == itemLimit->charJob1 || ePLAYER_WINDWALKER == itemLimit->charJob2 ) break; if ( ePLAYER_WANDERER == itemLimit->charJob1 || ePLAYER_WANDERER == itemLimit->charJob2 ) break; return false; case ePLAYER_SNIPER: if ( ePLAYER_SNIPER == itemLimit->charJob1 || ePLAYER_SNIPER == itemLimit->charJob2 ) break; case ePLAYER_SCOUT: if ( ePLAYER_SCOUT == itemLimit->charJob1 || ePLAYER_SCOUT == itemLimit->charJob2 ) break; if ( ePLAYER_WANDERER == itemLimit->charJob1 || ePLAYER_WANDERER == itemLimit->charJob2 ) break; return false; case ePLAYER_WANDERER: if ( ePLAYER_WANDERER == itemLimit->charJob1 || ePLAYER_WANDERER == itemLimit->charJob2 ) break; return false; // ¿ö·Ï(¸¶¹ýÇü) ÀüÁ÷ Ŭ·¡½º - ÇÏÀ§ Á÷¾÷±º Æ÷ÇÔ. case ePLAYER_SORCERER: if ( ePLAYER_SORCERER == itemLimit->charJob1 || ePLAYER_SORCERER == itemLimit->charJob2 ) break; case ePLAYER_SHAMAN: if ( ePLAYER_SHAMAN == itemLimit->charJob1 || ePLAYER_SHAMAN == itemLimit->charJob2 ) break; if ( ePLAYER_WARLOCK == itemLimit->charJob1 || ePLAYER_WARLOCK == itemLimit->charJob2 ) break; return false; case ePLAYER_MENTALIST: if ( ePLAYER_MENTALIST == itemLimit->charJob1 || ePLAYER_MENTALIST == itemLimit->charJob2 ) break; case ePLAYER_SAGE: if ( ePLAYER_SAGE == itemLimit->charJob1 || ePLAYER_SAGE == itemLimit->charJob2 ) break; if ( ePLAYER_WARLOCK == itemLimit->charJob1 || ePLAYER_WARLOCK == itemLimit->charJob2 ) break; return false; case ePLAYER_WARLOCK: if ( ePLAYER_WARLOCK == itemLimit->charJob1 || ePLAYER_WARLOCK == itemLimit->charJob2 ) break; return false; // ¾ÏÁî¸Ç(Àü»çÇü) ÀüÁ÷ Ŭ·¡½º - ÇÏÀ§ Á÷¾÷±º Æ÷ÇÔ. case ePLAYER_CHAMPION: if ( ePLAYER_CHAMPION == itemLimit->charJob1 || ePLAYER_CHAMPION == itemLimit->charJob2 ) break; case ePLAYER_VETERAN: if ( ePLAYER_VETERAN == itemLimit->charJob1 || ePLAYER_VETERAN == itemLimit->charJob2 ) break; if ( ePLAYER_ARMSMAN == itemLimit->charJob1 || ePLAYER_ARMSMAN == itemLimit->charJob2 ) break; return false; case ePLAYER_SLAYER: if ( ePLAYER_SLAYER == itemLimit->charJob1 || ePLAYER_SLAYER == itemLimit->charJob2 ) break; case ePLAYER_BERSERK: if ( ePLAYER_BERSERK == itemLimit->charJob1 || ePLAYER_BERSERK == itemLimit->charJob2 ) break; if ( ePLAYER_ARMSMAN == itemLimit->charJob1 || ePLAYER_ARMSMAN == itemLimit->charJob2 ) break; return false; case ePLAYER_HIGHLANDER: if ( ePLAYER_HIGHLANDER == itemLimit->charJob1 || ePLAYER_HIGHLANDER == itemLimit->charJob2 ) break; case ePLAYER_WARRIOR: if ( ePLAYER_WARRIOR == itemLimit->charJob1 || ePLAYER_WARRIOR == itemLimit->charJob2 ) break; if ( ePLAYER_ARMSMAN == itemLimit->charJob1 || ePLAYER_ARMSMAN == itemLimit->charJob2 ) break; return false; case ePLAYER_ARMSMAN: if ( ePLAYER_ARMSMAN == itemLimit->charJob1 || ePLAYER_ARMSMAN == itemLimit->charJob2 ) break; return false; // ·¹ÀÎÀú(¹ÎøÇü) ÀüÁ÷ Ŭ·¡½º - ÇÏÀ§ Á÷¾÷±º Æ÷ÇÔ. case ePLAYER_AVENGER: if ( ePLAYER_AVENGER == itemLimit->charJob1 || ePLAYER_AVENGER == itemLimit->charJob2 ) break; case ePLAYER_SHADOWWALKER: if ( ePLAYER_SHADOWWALKER == itemLimit->charJob1 || ePLAYER_SHADOWWALKER == itemLimit->charJob2 ) break; if ( ePLAYER_RANGER == itemLimit->charJob1 || ePLAYER_RANGER == itemLimit->charJob2 ) break; return false; case ePLAYER_SHARPSHOOTER: if ( ePLAYER_SHARPSHOOTER == itemLimit->charJob1 || ePLAYER_SHARPSHOOTER == itemLimit->charJob2 ) break; case ePLAYER_HUNTER: if ( ePLAYER_HUNTER == itemLimit->charJob1 || ePLAYER_HUNTER == itemLimit->charJob2 ) break; if ( ePLAYER_RANGER == itemLimit->charJob1 || ePLAYER_RANGER == itemLimit->charJob2 ) break; return false; case ePLAYER_RANGER: if ( ePLAYER_RANGER == itemLimit->charJob1 || ePLAYER_RANGER == itemLimit->charJob2 ) break; return false; } } // ·¹º§; ÀÌÇÏÀÏ °æ¿ì¸¸ Á¦¾î¸¦ ÇÑ´Ù. if ( mPlayerInfo.Level < itemLimit->charLevelMin || mPlayerInfo.Level > itemLimit->charLevelMax ) return false; // ¼­¹öºÐ·ù; 0 °ø¿ë / 1 ÀüÀåÀü¿ë / 2 Æ©Å丮¾óÀü¿ë / 3 ÇʵåÀü¿ë switch ( itemLimit->serverType ) { case ITEM_LIMIT_COMMON: // °ø¿ë break; case ITEM_LIMIT_PVP: // ÀüÀå Àü¿ë if ( NETWORK2->GetServerType( ) == _E_ST_ID_PVP_ ) break; return false; case ITEM_LIMIT_TUTORIAL: // Æ©Å丮¾ó Àü¿ë if ( NETWORK2->GetServerType( ) == _E_ST_ID_TUTORIAL_ ) break; return false; case ITEM_LIMIT_FIELD: if ( NETWORK2->GetServerType( ) == _E_ST_NORMAL_MAP_ ) break; return false; default: // ¾Ë¼ö¾ø´Â Á¤ÀÇ return false; } // ¼¼·Â; ¼¼·ÂÀü¿ë ¾ÆÀÌÅÛÀϰæ¿ì¸¸ »ç¿ë°¡´É. if ( (itemLimit->forceType != eFORCETYPE_NONE) && (itemLimit->forceType != mPlayerExrInfo.mForceType) ) return false; // º¸Á¶Á÷¾÷ && ¼÷·Ãµµ; º¸Á¶Á÷¾÷Àü¿ë ¾ÆÀÌÅÛÀϰæ¿ì¸¸ »ç¿ë°¡´É. if ( itemLimit->makeSkill != eMAKESKILL_NONE ) { if ( itemLimit->makeSkill == mHeroInfo.MakeSkill1.mIndex ) { if ( itemLimit->makeSkillExp > mHeroInfo.MakeSkill1.mExp ) return false; } else if ( itemLimit->makeSkill == mHeroInfo.MakeSkill2.mIndex ) { if ( itemLimit->makeSkillExp > mHeroInfo.MakeSkill2.mExp ) return false; } else return false; } } // ¼º°ø; »ç¿ë°¡´É. return true; } // IsItemExchange Method. bool cPlayer::IsItemExchange( TB_ITEM_DEFINE* itemDefine, TB_INVENTORY* inventory ) { if( itemDefine == NULL ) return false; /// ¹ÌÀÎÁõ ¾ÆÀÌÅÛ if( itemDefine->licenseType == 1 ) { /// ÀÎÁõ ¹ÞÀº ¾ÆÀÌÅÛÀº °Å·¡ ÇÒ ¼ö ¾øÀ½. if( inventory->seal == 0 ) return false; if( itemDefine->exchange == 2 ) return true; } /// ÀÏ¹Ý ¾ÆÀÌÅÛ else { if( itemDefine->exchange == 0 ) return true; } return false; } // IsMaxInventory Method. bool cPlayer::IsMaxInventory( TB_ITEM_DEFINE* itemDefine, long count ) { if( itemDefine == NULL ) return false; if( itemDefine->maxInventory == 0 ) return false; long sumCount = GetItemSumCount( itemDefine->index ) + count; if( itemDefine->maxInventory < sumCount ) return true; return false; } // IsMaxInventory Method. bool cPlayer::IsMaxInventory( sQuestItem* items, unsigned int rowCount ) { for( unsigned int i = 0; i < rowCount, i < QUEST_ITEM_MAX; i++, items++ ) { if( items ) { TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefineByIndex( items->itemIndex ); return IsMaxInventory( itemDefine, items->count ); } } return false; } // GetItemSumCount Method. long cPlayer::GetItemSumCount( long itemDefineIndex ) { PerItemCount* itemCount = ITEMCOUNTPOOL->SearchItemCount( &mItemCountRoot, itemDefineIndex ); if( itemCount != NULL ) return itemCount->sum; return 0; } // GetItemCount Method. short cPlayer::GetItemCount( long itemDefineIndex ) { PerItemCount* itemCount = ITEMCOUNTPOOL->SearchItemCount( &mItemCountRoot, itemDefineIndex ); if ( itemCount != NULL ) { return (short)itemCount->bag; } return 0; } // IsItem Method. bool cPlayer::IsItem(long itemDefineIndex) { PerItemCount* itemCount = ITEMCOUNTPOOL->SearchItemCount( &mItemCountRoot, itemDefineIndex ); if ( itemCount != NULL ) { return (itemCount->bag > 0) ? true : false; } return false; } // IsItem Method. bool cPlayer::IsItemIdx(long inventoryidx) { TB_INVENTORY* inventory = SelectInventory( INVENTORY_BAG_BEGIN ); for ( int i = INVENTORY_BAG_BEGIN; i <= mHeroInfo.BagEnd; i++, inventory++ ) { if ( inventory->idx == inventoryidx ) return true; } return false; } // IsItemUse Method. bool cPlayer::IsItemUse(long itemDefineIndex, unsigned short count) { // ÄðŸÀÓ °Ë»ç. if ( COOLTIMEPOOL->IsCooltime( &mCooltimeRoot, itemDefineIndex ) == true ) return false; PerItemCount* itemCount = ITEMCOUNTPOOL->SearchItemCount( &mItemCountRoot, itemDefineIndex ); if ( itemCount != NULL ) { return (itemCount->bag >= count) ? true : false; } return false; } // ItemUse Method. bool cPlayer::ItemUse(long itemDefineIndex, unsigned short count) { if ( IsItemUse( itemDefineIndex, count ) == true ) { TB_INVENTORY* inventory = SelectInventory( INVENTORY_BAG_BEGIN ); short remainCount = count; HANDLE handle = NULL; ITEM_USE* itemUse = (ITEM_USE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_USE ); long& rowCount = itemUse->rowCount; TB_INVENTORY* table = itemUse->table; long length = sizeof(ITEM_USE) - sizeof(itemUse->table); itemUse->characterIdx = mObject.index; for ( int i = INVENTORY_BAG_BEGIN; (i <= mHeroInfo.BagEnd) && (remainCount > 0); i++, inventory++ ) { if ( IsInventory( inventory ) == true ) { if ( itemDefineIndex == inventory->itemDefineIndex ) { short shortCount = (remainCount < inventory->count) ? remainCount : inventory->count; (*table) = (*inventory); table->count = shortCount; table++; rowCount++; // ÄðŸÀÓ Àû¿ë. COOLTIMEPOOL->ApplyCooltime( &mCooltimeRoot, inventory ); // °¡»óó¸®; Â÷°¨À» ¿Ï¼º ÇØ ³õ´Â´Ù. UpdateInventory( inventory, (-shortCount) ); // °¡»óó¸®; »ç¿ëµÈ ¾ÆÀÌÅÛ Á¤º¸¸¦ Àü¼ÛÇÑ´Ù. SendItemUse( inventory ); // °¡»óó¸®; »ç¿ëÀÌ ¿Ï·áµÈ Àκ¥Å丮 »èÁ¦. if ( inventory->count == 0 ) RemoveInventory( inventory ); // ³²Àº°¹¼ö Á¤»ê. remainCount = remainCount - shortCount; } } } length += sizeof(itemUse->table) * rowCount; return NETWORK2->SendSQL( handle, length ); } else return false; } // IsItemUseSkill Method. long cPlayer::IsItemMapChange(short number, long itemDefineIndex, bool isCash, long itemAbilityInfluence) { //if ( !IsInventoryRange( number ) ) // return 0; //if( IsAutoTrial() == true ) // return 0; //TB_INVENTORY* inventory = SelectInventory( number ); //if ( IsInventory( inventory ) == true ) //{ // if ( inventory->itemDefineIndex == itemDefineIndex ) // { // TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); // if ( itemDefine != NULL ) // { // if ( itemDefine->type == ITEM_MATERIAL && itemDefine->subType == ITEM_MATERIAL_MAP ) // { // if ( !IsItemLimit( inventory->itemDefineIdx ) ) // return 0; // // ¹ÌÀÎÁõ ¾ÆÀÌÅÛ // if ( IsInventorySeal( itemDefine, inventory ) == true ) // return 0; // TB_ITEM_ABILITY* itemAbility = ITEMMANAGER->GetItemAbility( inventory->itemDefineIdx ); // if ( itemAbility != NULL ) // { // if ( itemAbility->influence_idx == itemAbilityInfluence ) // { // // ÄðŸÀÓ °Ë»ç. // if ( COOLTIMEPOOL->IsCooltime( &mCooltimeRoot, itemDefineIndex ) != true ) // return inventory->idx; // else // return 0; // } // } // else // NETWORK2->PostServerEvent( "ERROR - cPlayer::IsItemUseMapChange:TB_ITEM_ABILITY::IDX(=%d)", itemDefine->idxAbility ); // } // } // else // NETWORK2->PostServerEvent( "ERROR - cPlayer::IsItemUseMapChange:TB_ITEM_DEFINE::IDX(=%d)", inventory->itemDefineIdx ); // } //} //return 0; if ( !IsInventoryRange( number ) ) return 0; if( IsAutoTrial() == true ) return 0; TB_INVENTORY* inventory = SelectInventory( number ); if ( IsInventory( inventory ) == false ) return 0; if ( inventory->itemDefineIndex != itemDefineIndex ) return 0; TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if ( itemDefine == NULL ) return 0; if( isCash == true ) { /// ij½ÃÅÛ Å¸ÀÔ È®ÀÎ if( itemDefine->type != ITEM_ETC1 || itemDefine->subType != ITEM_ETC1_FREE_MOVE ) return 0; } else { /// ¸ÊÀ̵¿ ÀÏ¹Ý ¾ÆÀÌÅÛ Å¸ÀÔ È®ÀÎ if( itemDefine->type != ITEM_MATERIAL || itemDefine->subType != ITEM_MATERIAL_MAP ) return 0; } if ( !IsItemLimit( inventory->itemDefineIdx ) ) return 0; // ¹ÌÀÎÁõ ¾ÆÀÌÅÛ if ( IsInventorySeal( itemDefine, inventory ) == true ) return 0; TB_ITEM_ABILITY* itemAbility = ITEMMANAGER->GetItemAbility( inventory->itemDefineIdx ); if ( itemAbility == NULL ) return 0; /// È¿°ú ¹øÈ£ È®ÀÎ if ( itemAbility->influence_idx != itemAbilityInfluence ) return 0; // ÄðŸÀÓ °Ë»ç. if ( COOLTIMEPOOL->IsCooltime( &mCooltimeRoot, itemDefineIndex ) != true ) return inventory->idx; else return 0; } // IsItemUseSkill Method. long cPlayer::IsItemVehicle(short number, long itemDefineIndex, long itemAbilityInfluence) { if ( !IsInventoryRange( number ) ) return 0; TB_INVENTORY* inventory = SelectInventory( number ); if ( IsInventory( inventory ) == true ) { if ( inventory->itemDefineIndex == itemDefineIndex ) { TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if ( itemDefine != NULL ) { if ( itemDefine->type == ITEM_MATERIAL && itemDefine->subType == ITEM_MATERIAL_VEHICLE ) { if ( !IsItemLimit( inventory->itemDefineIdx ) ) return 0; // ¹ÌÀÎÁõ ¾ÆÀÌÅÛ if ( IsInventorySeal( itemDefine, inventory ) == true ) return 0; TB_ITEM_ABILITY* itemAbility = ITEMMANAGER->GetItemAbility( inventory->itemDefineIdx ); if ( itemAbility != NULL ) { if ( itemAbility->influence_idx == itemAbilityInfluence ) { // ÄðŸÀÓ °Ë»ç. if ( COOLTIMEPOOL->IsCooltime( &mCooltimeRoot, itemDefineIndex ) != true ) return inventory->itemDefineIndex; else return 0; } } else NETWORK2->PostServerEvent( "ERROR - cPlayer::IsItemUseMapChange:TB_ITEM_ABILITY::IDX(=%d)", itemDefine->idxAbility ); } } else NETWORK2->PostServerEvent( "ERROR - cPlayer::IsItemUseMapChange:TB_ITEM_DEFINE::IDX(=%d)", inventory->itemDefineIdx ); } } return 0; } // ItemUseMapChange Method. bool cPlayer::ItemUseMapChange(long inventroyIdx) { TB_INVENTORY* inventory = SelectInventory( INVENTORY_BAG_BEGIN ); bool apply = false; HANDLE handle = NULL; ITEM_USE* itemUse = (ITEM_USE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_USE ); long& rowCount = itemUse->rowCount; TB_INVENTORY* table = itemUse->table; long length = sizeof(ITEM_USE)-sizeof(itemUse->table); itemUse->characterIdx = mObject.index; for ( int i = INVENTORY_BAG_BEGIN; (i <= mHeroInfo.BagEnd) && (apply == false); i++, inventory++ ) { if ( inventory->idx == inventroyIdx ) { (*table) = (*inventory); table->count = 1; table++; rowCount++; // ÄðŸÀÓ Àû¿ë. COOLTIMEPOOL->ApplyCooltime( &mCooltimeRoot, inventory ); // °¡»óó¸®; Â÷°¨À» ¿Ï¼º ÇØ ³õ´Â´Ù. UpdateInventory( inventory, (-1) ); // °¡»óó¸®; »ç¿ëµÈ ¾ÆÀÌÅÛ Á¤º¸¸¦ Àü¼ÛÇÑ´Ù. SendItemUse( inventory ); // °¡»óó¸®; »ç¿ëÀÌ ¿Ï·áµÈ Àκ¥Å丮 »èÁ¦. if ( inventory->count == 0 ) RemoveInventory( inventory ); // Àû¿ë¿Ï·á. apply = true; } } length += sizeof(itemUse->table) * rowCount; if ( apply == true ) { return NETWORK2->SendSQL( handle, length ); } else { NETWORK2->ReleaseSQL( handle, length ); return false; } } void cPlayer::ItemUseCashMapChange( long inventoryIdx ) { TB_INVENTORY* inventory = SelectInventory( INVENTORY_BAG_BEGIN ); bool apply = false; for ( int i = INVENTORY_BAG_BEGIN; (i <= mHeroInfo.BagEnd) && (apply == false); i++, inventory++ ) { if ( inventory->idx == inventoryIdx ) { // ÄðŸÀÓ Àû¿ë. COOLTIMEPOOL->ApplyCooltime( &mCooltimeRoot, inventory ); return; } } } // SendItemUse Method. bool cPlayer::SendItemUse(TB_INVENTORY* inventory) { HANDLE handle = NULL; MSG_RES_ITEM_USE* sendMsg = (MSG_RES_ITEM_USE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_ITEM, NM_ITEM_USE_RES ); if ( sendMsg != NULL ) { Inventory2sInventory( &sendMsg->inventory, inventory ); return NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_ITEM_USE) ); } return false; } // IsItemReward Method - ºÐÇØµÉ ¾ÆÀÌÅÛÀº ºñ¾îÀÖ´Â Àκ¥Å丮·Î °£ÁÖÇÑ´Ù. unsigned int cPlayer::IsItemReward(long inventoryIdx, eDisjointItem* items, int maxCount) { TB_ITEM_DEFINE* itemDefine = NULL; TB_INVENTORY* inventory = NULL; short inventoryCount; int emptyCount = 0; int applyCount = 0; // ³²Àº Àκ¥Å丮 ¼ö·® °ËÅä - ºÐÇØµÉ ¾ÆÀÌÅÛÀº ³²Àº Àκ¥Å丮·Î ó¸®. inventory = SelectInventory( INVENTORY_BAG_BEGIN ); for ( int i0 = INVENTORY_BAG_BEGIN; i0 <= mHeroInfo.BagEnd && emptyCount < maxCount; i0++, inventory++ ) { if ( (inventory->idx == 0) || (inventory->idx == inventoryIdx) ) emptyCount++; } // ³²Àº Àκ¥Å丮 ¼ö·®ÀÌ º¸»ó¹ÞÀ» ¾ÆÀÌÅÛ ¼ö·®º¸´Ù ÀûÀº °æ¿ì, °ãÄ¡±â °¡´É ¾ÆÀÌÅÛ °ËÅä. if ( emptyCount < maxCount ) { for ( int i0 = 0; i0 < maxCount; i0++, items++ ) { itemDefine = ITEMMANAGER->GetItemDefineByIndex( items->itemDefineIndex ); if ( itemDefine == NULL ) { return applyCount; } else if ( (!items->inventoryCount) || (itemDefine->capacity < items->inventoryCount) ) { return applyCount; } else if ( (emptyCount + applyCount) < maxCount ) { inventory = SelectInventory( INVENTORY_BAG_BEGIN ); inventoryCount = 0; for ( int i1 = INVENTORY_BAG_BEGIN; i1 <= mHeroInfo.BagEnd && inventoryCount < items->inventoryCount; i1++, inventory++ ) { // ºÐÇØµÉ ¾ÆÀÌÅÛÀº ¹«½Ã if ( inventory->idx == inventoryIdx ) continue; // ³²Àº ¼ö·® ´©Àû. if ( inventory->itemDefineIndex == (long)items->itemDefineIndex ) inventoryCount += (itemDefine->capacity - inventory->count); } // °ãÄ¡±â È®ÀÎÈÄ Àû¿ëÇà ¼ö Áõ°¡. if ( inventoryCount >= items->inventoryCount ) { applyCount++; } // °ãÄ¡±â ½ÇÆÐ½Ã ³²Àº Àκ¥Å丮 Â÷°¨ÈÄ Àû¿ëÇà ¼ö Áõ°¡. else if ( emptyCount > 0 ) { emptyCount--; applyCount++; } } else applyCount++; } } // ³²Àº Àκ¥Å丮 ¼ö·®ÀÌ º¸»ó¹ÞÀ» ¾ÆÀÌÅÛ ¼ö·®º¸´Ù Å« °æ¿ì, ¾ÆÀÌÅÛ Á¤ÀÇ Å×ÀÌºí¸¸ °ËÅä. else { for ( int i0 = 0; i0 < maxCount; i0++, items++ ) { itemDefine = ITEMMANAGER->GetItemDefineByIndex( items->itemDefineIndex ); if ( itemDefine == NULL ) { return applyCount; } else if ( (!items->inventoryCount) || (itemDefine->capacity < items->inventoryCount) ) { return applyCount; } else applyCount++; } } return applyCount; } // IsItemReward Method. unsigned int cPlayer::IsItemReward(sQuestItem* items, int maxCount, short slotBegin, short slotEnd ) { TB_ITEM_DEFINE* itemDefine = NULL; TB_INVENTORY* inventory = NULL; unsigned int inventoryCount; int emptyCount = 0; int applyCount = 0; // ³²Àº Àκ¥Å丮 ¼ö·® °ËÅä. inventory = SelectInventory( slotBegin ); for ( int i0 = slotBegin; i0 <= slotEnd && emptyCount < maxCount; i0++, inventory++ ) { if ( !inventory->idx ) emptyCount++; } // ³²Àº Àκ¥Å丮 ¼ö·®ÀÌ º¸»ó¹ÞÀ» ¾ÆÀÌÅÛ ¼ö·®º¸´Ù ÀûÀº °æ¿ì, °ãÄ¡±â °¡´É ¾ÆÀÌÅÛ °ËÅä. if ( emptyCount < maxCount ) { for ( int i0 = 0; i0 < maxCount; i0++, items++ ) { itemDefine = ITEMMANAGER->GetItemDefineByIndex( items->itemIndex ); if ( itemDefine == NULL ) { return applyCount; } else if ( (!items->count) || (itemDefine->capacity < (short)items->count) ) { return applyCount; } else if ( (emptyCount + applyCount) < maxCount ) { inventory = SelectInventory( slotBegin ); inventoryCount = 0; for ( int i1 = slotBegin; i1 <= slotEnd && inventoryCount < items->count; i1++, inventory++ ) { if ( inventory->itemDefineIndex == (long)items->itemIndex ) { inventoryCount += (itemDefine->capacity - inventory->count); } } // °ãÄ¡±â È®ÀÎÈÄ Àû¿ëÇà ¼ö Áõ°¡. if ( inventoryCount >= items->count ) { applyCount++; } // °ãÄ¡±â ½ÇÆÐ½Ã ³²Àº Àκ¥Å丮 Â÷°¨ÈÄ Àû¿ëÇà ¼ö Áõ°¡. else if ( emptyCount > 0 ) { emptyCount--; applyCount++; } } else applyCount++; } } // ³²Àº Àκ¥Å丮 ¼ö·®ÀÌ º¸»ó¹ÞÀ» ¾ÆÀÌÅÛ ¼ö·®º¸´Ù Å« °æ¿ì, ¾ÆÀÌÅÛ Á¤ÀÇ Å×ÀÌºí¸¸ °ËÅä. else { for ( int i0 = 0; i0 < maxCount; i0++, items++ ) { itemDefine = ITEMMANAGER->GetItemDefineByIndex( items->itemIndex ); if ( itemDefine == NULL ) { return applyCount; } else if ( (!items->count) || (itemDefine->capacity < (short)items->count) ) { return applyCount; } else applyCount++; } } return applyCount; //// ³²Àº Àκ¥Å丮 ¼ö·® °ËÅä. //inventory = SelectInventory( INVENTORY_BAG_BEGIN ); //for ( int i0 = INVENTORY_BAG_BEGIN; i0 <= mHeroInfo.BagEnd && emptyCount < maxCount; i0++, inventory++ ) //{ // if ( !inventory->idx ) // emptyCount++; //} //// ³²Àº Àκ¥Å丮 ¼ö·®ÀÌ º¸»ó¹ÞÀ» ¾ÆÀÌÅÛ ¼ö·®º¸´Ù ÀûÀº °æ¿ì, °ãÄ¡±â °¡´É ¾ÆÀÌÅÛ °ËÅä. //if ( emptyCount < maxCount ) //{ // for ( int i0 = 0; i0 < maxCount; i0++, items++ ) // { // itemDefine = ITEMMANAGER->GetItemDefineByIndex( items->itemIndex ); // if ( itemDefine == NULL ) // { // return applyCount; // } // else if ( (!items->count) || (itemDefine->capacity < (short)items->count) ) // { // return applyCount; // } // else if ( (emptyCount + applyCount) < maxCount ) // { // inventory = SelectInventory( INVENTORY_BAG_BEGIN ); // inventoryCount = 0; // for ( int i1 = INVENTORY_BAG_BEGIN; i1 <= mHeroInfo.BagEnd && inventoryCount < items->count; i1++, inventory++ ) // { // if ( inventory->itemDefineIndex == (long)items->itemIndex ) // { // inventoryCount += (itemDefine->capacity - inventory->count); // } // } // // °ãÄ¡±â È®ÀÎÈÄ Àû¿ëÇà ¼ö Áõ°¡. // if ( inventoryCount >= items->count ) // { // applyCount++; // } // // °ãÄ¡±â ½ÇÆÐ½Ã ³²Àº Àκ¥Å丮 Â÷°¨ÈÄ Àû¿ëÇà ¼ö Áõ°¡. // else if ( emptyCount > 0 ) // { // emptyCount--; // applyCount++; // } // } // else // applyCount++; // } //} //// ³²Àº Àκ¥Å丮 ¼ö·®ÀÌ º¸»ó¹ÞÀ» ¾ÆÀÌÅÛ ¼ö·®º¸´Ù Å« °æ¿ì, ¾ÆÀÌÅÛ Á¤ÀÇ Å×ÀÌºí¸¸ °ËÅä. //else //{ // for ( int i0 = 0; i0 < maxCount; i0++, items++ ) // { // itemDefine = ITEMMANAGER->GetItemDefineByIndex( items->itemIndex ); // if ( itemDefine == NULL ) // { // return applyCount; // } // else if ( (!items->count) || (itemDefine->capacity < (short)items->count) ) // { // return applyCount; // } // else // applyCount++; // } //} //return applyCount; } // IsItemTake Method. unsigned int cPlayer::IsItemTake(sQuestItem* items, int maxCount) { TB_INVENTORY* inventory = NULL; int remainCount; int applyCount = 0; for ( int i0 = 0; i0 < maxCount; i0++, items++ ) { inventory = SelectInventory( INVENTORY_BAG0_BEGIN ); remainCount = items->count; for ( int i1 = INVENTORY_BAG0_BEGIN; i1 <= INVENTORY_QUEST_END; i1++, inventory++ ) { if ( inventory->itemDefineIndex == (long)items->itemIndex ) { remainCount -= inventory->count; if ( !(remainCount > 0) ) { applyCount++; break; } } } } return applyCount; } /// ÇØ´ç Äù½ºÆ® ¾ÆÀÌÅÛ °Ë»ç unsigned int cPlayer::GetQuestItemCount( long itemDefineIndex, int maxCount ) { TB_INVENTORY* inventory = SelectInventory( INVENTORY_QUEST_BEGIN ); int totalCount = 0; for ( int i = INVENTORY_QUEST_BEGIN; i <= INVENTORY_QUEST_END; i++, inventory++ ) { if ( inventory->idx > 0 && inventory->count > 0 && inventory->itemDefineIndex == itemDefineIndex ) { totalCount += inventory->count; if ( totalCount >= maxCount ) return maxCount; } } return totalCount; } // EquipItems Method - Âø¿ë ¾ÆÀÌÅÛ. void cPlayer::EquipItems( ) { /// ¹ßµ¿ È¿°ú ÃʱâÈ­ ClearActInfluence(); short leftHand; short rightHand; // Ȱ¼º»óÅ °Ë»ç. if ( mItemActiveWeapon == ItemActiveFront ) { leftHand = INVENTORY_HAND_LEFT2; rightHand = INVENTORY_HAND_RIGHT2; } else { leftHand = INVENTORY_HAND_LEFT1; rightHand = INVENTORY_HAND_RIGHT1; } // ij¸¯ÅÍÀÇ ¹«±â »óÅ Á¤º¸ °»½Å. { int weaponState = eWEAPON_STATE_NONE; TB_INVENTORY* inventory; inventory = SelectInventory( leftHand ); for ( short i = leftHand; i <= rightHand; i++, inventory++ ) { if ( IsInventory( inventory ) && IsItemLimit( inventory->itemDefineIdx ) ) { if ( ITEMMANAGER->GetItemDefineType( inventory->itemDefineIdx ) == ITEM_WEAPON ) { switch ( ITEMMANAGER->GetItemDefineSubType( inventory->itemDefineIdx ) ) { case ITEM_WEAPON_SWORD: weaponState += eWEAPON_STATE_SWORD; break; case ITEM_WEAPON_BLADE: weaponState += eWEAPON_STATE_LONGSWORD; break; case ITEM_WEAPON_DUAL: weaponState += eWEAPON_STATE_DOUBLESWORD; break; case ITEM_WEAPON_CUTTER: weaponState += eWEAPON_STATE_SHORTSWORD; break; case ITEM_WEAPON_GUN: weaponState += eWEAPON_STATE_GUN; break; case ITEM_WEAPON_STAFF: weaponState += eWEAPON_STATE_STAFF; break; case ITEM_WEAPON_SHIELD: weaponState += eWEAPON_STATE_SHEILD; break; } } } } mPlayerWeaponState = (eWEAPON_STATE)weaponState; } // ij¸¯ÅÍÀÇ Âø¿ë ¾ÆÀÌÅÛ Á¤º¸ °»½Å. { // ¹æ¾î±¸ unsigned long wearHat = SelectInventory( INVENTORY_WEAR_HAT )->itemDefineIndex; unsigned long wearBody1 = SelectInventory( INVENTORY_WEAR_BODY1 )->itemDefineIndex; unsigned long wearBody2 = SelectInventory( INVENTORY_WEAR_BODY2 )->itemDefineIndex; unsigned long wearHand = SelectInventory( INVENTORY_WEAR_HAND )->itemDefineIndex; unsigned long wearFoot = SelectInventory( INVENTORY_WEAR_FOOT )->itemDefineIndex; SetWearInfoWithSendMsg( eWEAR_HAT, wearHat ); // ¸ðÀÚ SetWearInfoWithSendMsg( eWEAR_BODY1, wearBody1 ); // ¹Ùµð1 - »óÀÇ SetWearInfoWithSendMsg( eWEAR_BODY2, wearBody2 ); // ¹Ùµð2 - ÇÏÀÇ SetWearInfoWithSendMsg( eWEAR_HAND, wearHand ); // Àå°© SetWearInfoWithSendMsg( eWEAR_FOOT, wearFoot ); // ½Å¹ß // ¾×¼¼¼­¸® mPlayerWearInfo.Earring = SelectInventory( INVENTORY_WEAR_EARRING )->itemDefineIndex; mPlayerWearInfo.Necklace = SelectInventory( INVENTORY_WEAR_NECKLACE )->itemDefineIndex; mPlayerWearInfo.Brooch = SelectInventory( INVENTORY_WEAR_BROOCH )->itemDefineIndex; mPlayerWearInfo.Bracelet = SelectInventory( INVENTORY_WEAR_BRACELET )->itemDefineIndex; mPlayerWearInfo.Ring = SelectInventory( INVENTORY_WEAR_RING )->itemDefineIndex; // ¹«±â SetWeaponInfoWithSendMsg( SelectInventory( leftHand ), SelectInventory( rightHand ) ); // ÄÚ½ºÆ¬ ¾ÆÀÌÅÛ unsigned long cosBody1 = SelectInventory( INVENTORY_COSTUME_BODY1 )->itemDefineIndex; unsigned long cosBody2 = SelectInventory( INVENTORY_COSTUME_BODY2 )->itemDefineIndex; unsigned long cosHand = SelectInventory( INVENTORY_COSTUME_HAND )->itemDefineIndex; unsigned long cosFoot = SelectInventory( INVENTORY_COSTUME_FOOT )->itemDefineIndex; unsigned long cosHat = SelectInventory( INVENTORY_COSTUME_HAT )->itemDefineIndex; unsigned long cosFace = SelectInventory( INVENTORY_COSTUME_FACE )->itemDefineIndex; unsigned long cosBack = SelectInventory( INVENTORY_COSTUME_BACK )->itemDefineIndex; SetCosWearInfoWithSendMsg( eWEAR_BODY1, cosBody1 ); // ÄÚ½ºÆ¬ ¹Ùµð1 - »óÀÇ SetCosWearInfoWithSendMsg( eWEAR_BODY2, cosBody2 ); // ÄÚ½ºÆ¬ ¹Ùµð2 - ÇÏÀÇ SetCosWearInfoWithSendMsg( eWEAR_HAND, cosHand ); // ÄÚ½ºÆ¬ Àå°© SetCosWearInfoWithSendMsg( eWEAR_FOOT, cosFoot ); // ÄÚ½ºÆ¬ ½Å¹ß SetCosWearInfoWithSendMsg( eWEAR_HAT, cosHat ); // ÄÚ½ºÆ¬ ¸ðÀÚ SetCosAccInfoWithSendMsg( eCOSTUME_HEAD, cosFace ); // ÄÚ½ºÆ¬ Àå½Ä - ¾ó±¼ SetCosAccInfoWithSendMsg( eCOSTUME_BACK, cosBack ); // ÄÚ½ºÆ¬ Àå½Ä - ¸öÅë } // ij¸¯ÅÍÀÇ ¹æ¾î ¾ÆÀÌÅÛ ¼¼Æ® °»½Å. ResetArmorSets( ); // ij¸¯ÅÍÀÇ Âø¿ë ¾ÆÀÌÅÛ ¼Ó¼º °»½Å. { TB_INVENTORY* inventory; TB_ITEM_DEFINE* itemDefine; TB_ITEM_ABILITY* itemAbility; TB_ITEM_ENHANCED* itemEnhanced; memset( &mEquipAbility, 0, sizeof(mEquipAbility) ); tHashSet ItemSet; // ¾ÆÀÌÅÛ ´©Àû ¼Ó¼º - Âø¿ë ¹æ¾î±¸ & ¾×¼¼¼­¸® & Ä«µå. inventory = SelectInventory( INVENTORY_WEAR_BEGIN ); for ( int i = INVENTORY_WEAR_BEGIN; i <= mHeroInfo.WearEnd; i++, inventory++ ) { if ( IsInventory( inventory ) && IsItemLimit( inventory->itemDefineIdx ) && !IsInventorySeal( inventory ) ) { itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); /// set Á¤º¸ ÀÔ·Â if( itemDefine->setIndex != 0 ) ItemSet.NoneUniqueInsert( itemDefine->setIndex ); itemAbility = ITEMMANAGER->GetItemAbility( inventory->itemDefineIdx ); if ( itemAbility != NULL ) { AddEquipAbility( itemAbility ); if( itemAbility->active_index != 0 ) AddActInfluence( itemAbility->active_index ); } if ( !(inventory->enhanced < MIN_ITEM_ENHANCED || inventory->enhanced > MAX_ITEM_ENHANCED) ) { itemEnhanced = ITEMMANAGER->GetItemEnhanced( inventory->itemDefineIdx ); if ( itemEnhanced != NULL ) { AddEquipEnhanced( itemEnhanced, inventory->enhanced ); } } AddEquipCards( inventory ); } } // ¾ÆÀÌÅÛ ´©Àû ¼Ó¼º - ÄÚ½ºÆ¬ ¾ÆÀÌÅÛ inventory = SelectInventory( INVENTORY_COSTUME_HAT ); for ( int i = INVENTORY_COSTUME_HAT; i <= INVENTORY_COSTUME_BACK; i++, inventory++ ) { if ( IsInventory( inventory ) && IsItemLimit( inventory->itemDefineIdx ) && !IsInventorySeal( inventory ) ) { itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); /// set Á¤º¸ ÀÔ·Â if( itemDefine->setIndex != 0 ) ItemSet.NoneUniqueInsert( itemDefine->setIndex ); itemAbility = ITEMMANAGER->GetItemAbility( inventory->itemDefineIdx ); if ( itemAbility != NULL ) { AddEquipAbility( itemAbility ); if( itemAbility->active_index != 0 ) AddActInfluence( itemAbility->active_index ); } AddEquipCards( inventory ); } } // ¾ÆÀÌÅÛ ´©Àû ¼Ó¼º - Âø¿ë ¹«±â. inventory = SelectInventory( leftHand ); for ( int i = leftHand; i <= rightHand; i++, inventory++ ) { if ( IsInventory( inventory ) && IsItemLimit( inventory->itemDefineIdx ) && !IsInventorySeal( inventory ) ) { itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); /// set Á¤º¸ ÀÔ·Â if( itemDefine->setIndex != 0 ) ItemSet.NoneUniqueInsert( itemDefine->setIndex ); itemAbility = ITEMMANAGER->GetItemAbility( inventory->itemDefineIdx ); if ( itemAbility != NULL ) { AddEquipAbility( itemAbility ); if( itemAbility->active_index != 0 ) AddActInfluence( itemAbility->active_index ); } if ( !(inventory->enhanced < MIN_ITEM_ENHANCED || inventory->enhanced > MAX_ITEM_ENHANCED) ) { itemEnhanced = ITEMMANAGER->GetItemEnhanced( inventory->itemDefineIdx ); if ( itemEnhanced != NULL ) { AddEquipEnhanced( itemEnhanced, inventory->enhanced ); } } AddEquipCards( inventory ); } } // SET ¾ÆÀÌÅÛÀÇ OPT °ª Ãß°¡. /// ¼¼Æ® Á¤º¸ °»½Å tHashSet::cIterator b = ItemSet.Begin(); tHashSet::cIterator end = ItemSet.End(); for(; b != end; ) { /// ¼¼Æ® À妽º¿Í °¹¼ö unsigned long idx = (unsigned long)(*b); unsigned int checkCnt = ItemSet.GetCount(idx); cItemSetInfo* pInfo = ITEMMANAGER->GetItemSetInfo( idx ); if( pInfo ) { /// °¹¼ö¿¡ µû¸¥ ¼³Á¤ for( unsigned int c=1; c<=checkCnt; ++c ) { sSetAblityOption* opt = pInfo->GetItemOption(c); if( opt ) { if( opt->mOptType[0] != 0 ) AddEquipAbility( opt->mOptType[0], opt->mOptValue[0] ); if( opt->mOptType[1] != 0 ) AddEquipAbility( opt->mOptType[1], opt->mOptValue[1] ); /// ¹ßµ¿ Àû¿ë if( opt->mActIdx != 0 ) AddActInfluence( opt->mActIdx ); } } } /// reset ItemSet.Erase(idx); b = ItemSet.Begin(); end = ItemSet.End(); } } } // CalcItemWeight Method. void cPlayer::CalcItemWeight( ) { TB_INVENTORY* inventory; TB_ITEM_DEFINE* itemDefine; mItemWeight = 0; inventory = SelectInventory( INVENTORY_CHARACTER_BEGIN ); for ( int i = INVENTORY_CHARACTER_BEGIN; i <= INVENTORY_CHARACTER_END; ++i, ++inventory ) { itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if ( itemDefine != NULL ) { mItemWeight = mItemWeight + (itemDefine->weight * inventory->count); } } /// Äù½ºÆ® °»½Å UpdateDutyItem(); } void cPlayer::AddEquipAbility(short opt, short value) { #pragma warning( push ) #pragma warning( disable: 4244 ) switch ( opt ) { case ITEM_OPT_STR: mEquipAbility.mOptStr += value; // Èû break; case ITEM_OPT_DEX: mEquipAbility.mOptDex += value; // ¹Îø break; case ITEM_OPT_CON: mEquipAbility.mOptCon += value; // ü·Â break; case ITEM_OPT_INT: mEquipAbility.mOptInt += value; // Áö´É break; case ITEM_OPT_WIS: mEquipAbility.mOptWis += value; // ÁöÇý break; case ITEM_OPT_ALL: // ¸ðµÎ(Èû:¹Îø:ü·Â:Áö´É:ÁöÇý) mEquipAbility.mOptStr += value; mEquipAbility.mOptDex += value; mEquipAbility.mOptCon += value; mEquipAbility.mOptInt += value; mEquipAbility.mOptWis += value; break; // Option - Plus case ITEM_OPT_PLUS_PHYSIC_ATTACK: mEquipAbility.mOptPlusPhysicAttack += value; // ¹°¸®°ø°Ý·Â break; case ITEM_OPT_PLUS_MAGIC_ATTACK: mEquipAbility.mOptPlusMagicAttack += value; // ¸¶¹ý°ø°Ý·Â break; case ITEM_OPT_PLUS_PHYSIC_DEFENSE: mEquipAbility.mOptPlusPhysicDefense += value; // ¹°¸®¹æ¾î·Â break; case ITEM_OPT_PLUS_MAGIC_DEFENSE: mEquipAbility.mOptPlusMagicDefense += value; // ¸¶¹ý¹æ¾î·Â break; case ITEM_OPT_PLUS_PHYSIC_ATTACK_RATE: mEquipAbility.mOptPlusPhysicAttackRate += value; // ¹°¸®¸íÁß·ü break; case ITEM_OPT_PLUS_MAGIC_ATTACK_RATE: mEquipAbility.mOptPlusMagicAttackRate += value; // ¸¶¹ý¸íÁß·ü break; case ITEM_OPT_PLUS_PHYSIC_CRITICAL: mEquipAbility.mOptPlusPhysicCritical += value; // ¹°¸®Å©¸®Æ¼Äà break; case ITEM_OPT_PLUS_MAGIC_CRITICAL: mEquipAbility.mOptPlusMagicCritical += value; // ¸¶¹ýÅ©¸®Æ¼Äà break; case ITEM_OPT_PLUS_DOD: mEquipAbility.mOptPlusDod += value; // ȸÇÇ break; case ITEM_OPT_PLUS_WEI: mEquipAbility.mOptPlusWei += value; // ¹«°Ô break; case ITEM_OPT_PLUS_MAX_HP: mEquipAbility.mOptPlusMaxHp += value; // ÃÖ´ë·® HP break; case ITEM_OPT_PLUS_MAX_MP: mEquipAbility.mOptPlusMaxMp += value; // ÃÖ´ë·® MP break; case ITEM_OPT_PLUS_MOV: mEquipAbility.mOptPlusMov += value; // À̵¿ break; case ITEM_OPT_PLUS_HP: mEquipAbility.mOptPlusHp += value; // HP ȸº¹ break; case ITEM_OPT_PLUS_MP: mEquipAbility.mOptPlusMp += value; // MP ȸº¹ break; case ITEM_OPT_PLUS_ATTACK_SPEED: mEquipAbility.mOptPlusAttackSpeed += value; // ÀϹݰø°Ý¼Óµµ break; case ITEM_OPT_PLUS_SKILL_COOLTIME_SPEED: mEquipAbility.mOptPlusSkillCooltimeSpeed += value; // ½ºÅ³ÄðŸÀÓ¼Óµµ break; case ITEM_OPT_PLUS_SHORT_RANGE: mEquipAbility.mOptPlusShortRange += value; // ±Ù°Å¸®»çÁ¤°Å¸® break; case ITEM_OPT_PLUS_DISTANCE_RANGE: mEquipAbility.mOptPlusDistanceRange += value; // ¿ø°Å¸®»çÁ¤°Å¸® break; case ITEM_OPT_PLUS_HEAL: mEquipAbility.mOptPlusHeal += value; // Èú ȸº¹·® break; case ITEM_OPT_PLUS_HP_RECOVERTY: mEquipAbility.mOptPlusHpReceive += value; // HP ȸº¹½Ã Áõ°¡·® break; case ITEM_OPT_PLUS_ALL_ATTACK: mEquipAbility.mOptPlusPhysicAttack += value; // ¹°¸®°ø°Ý·Â mEquipAbility.mOptPlusMagicAttack += value; // ¸¶¹ý°ø°Ý·Â break; case ITEM_OPT_PLUS_ALL_DEFENSE: mEquipAbility.mOptPlusPhysicDefense += value; // ¹°¸®¹æ¾î·Â mEquipAbility.mOptPlusMagicDefense += value; // ¸¶¹ý¹æ¾î·Â break; case ITEM_OPT_PLUS_PHYSIC_CRITICAL_DEC: mEquipAbility.mOptPlusPhysicCriticalDec += value; // ¹°¸®Å©¸®Æ¼Äà °¨¼Ò break; case ITEM_OPT_PLUS_MAGIC_CRITICAL_DEC: mEquipAbility.mOptPlusMagicCriticalDec += value; // ¸¶¹ýÅ©¸®Æ¼Äà °¨¼Ò break; case ITEM_OPT_PLUS_RESISTANCE: mEquipAbility.mOptPlusResistance += value; // ÀúÇ×·Â break; // Option - Percent case ITEM_OPT_PERCENT_PHYSIC_ATTACK: mEquipAbility.mOptPercentPhysicAttack += value; // ¹°¸®°ø°Ý·Â break; case ITEM_OPT_PERCENT_MAGIC_ATTACK: mEquipAbility.mOptPercentMagicAttack += value; // ¸¶¹ý°ø°Ý·Â break; case ITEM_OPT_PERCENT_PHYSIC_DEFENSE: mEquipAbility.mOptPercentPhysicDefense += value; // ¹°¸®¹æ¾î·Â break; case ITEM_OPT_PERCENT_MAGIC_DEFENSE: mEquipAbility.mOptPercentMagicDefense += value; // ¸¶¹ý¹æ¾î·Â break; case ITEM_OPT_PERCENT_PHYSIC_ATTACK_RATE: mEquipAbility.mOptPercentPhysicAttackRate += value; // ¹°¸®¸íÁß·ü break; case ITEM_OPT_PERCENT_MAGIC_ATTACK_RATE: mEquipAbility.mOptPercentMagicAttackRate += value; // ¸¶¹ý¸íÁß·ü break; case ITEM_OPT_PERCENT_PHYSIC_CRITICAL: mEquipAbility.mOptPercentPhysicCritical += value; // ¹°¸®Å©¸®Æ¼Äà break; case ITEM_OPT_PERCENT_MAGIC_CRITICAL: mEquipAbility.mOptPercentMagicCritical += value; // ¸¶¹ýÅ©¸®Æ¼Äà break; case ITEM_OPT_PERCENT_DOD: mEquipAbility.mOptPercentDod += value; // ȸÇÇ break; case ITEM_OPT_PERCENT_WEI: mEquipAbility.mOptPercentWei += value; // ¹«°Ô break; case ITEM_OPT_PERCENT_MAX_HP: mEquipAbility.mOptPercentMaxHp += value; // ÃÖ´ë·® HP break; case ITEM_OPT_PERCENT_MAX_MP: mEquipAbility.mOptPercentMaxMp += value; // ÃÖ´ë·® MP break; case ITEM_OPT_PERCENT_MOV: mEquipAbility.mOptPercentMov += value; // À̵¿ break; case ITEM_OPT_PERCENT_HP: mEquipAbility.mOptPercentHp, value; // HP ȸº¹ break; case ITEM_OPT_PERCENT_MP: mEquipAbility.mOptPercentMp += value; // MP ȸº¹ break; case ITEM_OPT_PERCENT_ATTACK_SPEED: mEquipAbility.mOptPercentAttackSpeed += value; // ÀϹݰø°Ý¼Óµµ break; case ITEM_OPT_PERCENT_SKILL_COOLTIME_SPEED: mEquipAbility.mOptPercentSkillCooltimeSpeed += value; // ½ºÅ³ÄðŸÀÓ¼Óµµ break; case ITEM_OPT_PERCENT_SHORT_RANGE: mEquipAbility.mOptPercentShortRange += value; // ±Ù°Å¸®»çÁ¤°Å¸® break; case ITEM_OPT_PERCENT_DISTANCE_RANGE: mEquipAbility.mOptPercentDistanceRange += value; // ¿ø°Å¸®»çÁ¤°Å¸® break; case ITEM_OPT_PERCENT_HEAL: mEquipAbility.mOptPercentHeal += value; // Èú ȸº¹·® break; case ITEM_OPT_PERCENT_HP_RECOVERTY: mEquipAbility.mOptPercentHpReceive += value; // HP ȸº¹½Ã Áõ°¡·® break; case ITEM_OPT_PERCENT_ALL_ATTACK: mEquipAbility.mOptPercentPhysicAttack += value; // ¹°¸®°ø°Ý·Â mEquipAbility.mOptPercentMagicAttack += value; // ¸¶¹ý°ø°Ý·Â break; case ITEM_OPT_PERCENT_ALL_DEFENSE: mEquipAbility.mOptPercentPhysicDefense += value; // ¹°¸®¹æ¾î·Â mEquipAbility.mOptPercentMagicDefense += value; // ¸¶¹ý¹æ¾î·Â break; case ITEM_OPT_PERCENT_PHYSIC_CRITICAL_DEC: mEquipAbility.mOptPercentPhysicCriticalDec += value; // ¹°¸®Å©¸®Æ¼Äà °¨¼Ò break; case ITEM_OPT_PERCENT_MAGIC_CRITICAL_DEC: mEquipAbility.mOptPercentMagicCriticalDec += value; // ¸¶¹ýÅ©¸®Æ¼Äà °¨¼Ò break; case ITEM_OPT_PERCENT_RESISTANCE: mEquipAbility.mOptPercentResistance += value; // ÀúÇ×·Â break; // Option - Plus Etc case ITEM_OPT_PLUS_DRAIN_HP: mEquipAbility.mOptPlusDrainHp += value; // HP Èí¼ö break; case ITEM_OPT_PLUS_DRAIN_MP: mEquipAbility.mOptPlusDrainMp += value; // MP Èí¼ö break; case ITEM_OPT_PLUS_DAMAGE_DEC: mEquipAbility.mOptPlusDamageDec += value; // µ¥¹ÌÁö Èí¼ö/°¨¼Ò break; case ITEM_OPT_PLUS_DAMAGE_REF: mEquipAbility.mOptPlusDamageRef += value; // µ¥¹ÌÁö ¹Ý»ç break; // Option - Percent Etc case ITEM_OPT_PERCENT_DRAIN_HP: mEquipAbility.mOptPercentDrainHp += value; // HP Èí¼ö break; case ITEM_OPT_PERCENT_DRAIN_MP: mEquipAbility.mOptPercentDrainMp += value; // MP Èí¼ö break; case ITEM_OPT_PERCENT_DAMAGE_DEC: mEquipAbility.mOptPercentDamageDec += value; // µ¥¹ÌÁö Èí¼ö/°¨¼Ò break; case ITEM_OPT_PERCENT_DAMAGE_REF: mEquipAbility.mOptPercentDamageRef += value; // µ¥¹ÌÁö ¹Ý»ç break; } #pragma warning( pop ) } // AddEquipAbility Method. void cPlayer::AddEquipAbility(TB_ITEM_ABILITY* itemAbility) { // ±âº» °ª Àû¿ë. mEquipAbility.mPhysicDefense = mEquipAbility.mPhysicDefense + itemAbility->p_def; mEquipAbility.mMagicDefense = mEquipAbility.mMagicDefense + itemAbility->m_def; mEquipAbility.mAttackRange = mEquipAbility.mAttackRange + itemAbility->atk_range; mEquipAbility.mAttackSpeed = mEquipAbility.mAttackSpeed + itemAbility->atk_spd; mEquipAbility.mHealValue = mEquipAbility.mHealValue + itemAbility->heal; mEquipAbility.mPhysicMinAttack = mEquipAbility.mPhysicMinAttack + itemAbility->min_p_atk; mEquipAbility.mPhysicMaxAttack = mEquipAbility.mPhysicMaxAttack + itemAbility->max_p_atk; mEquipAbility.mMagicMinAttack = mEquipAbility.mMagicMinAttack + itemAbility->min_m_atk; mEquipAbility.mMagicMaxAttack = mEquipAbility.mMagicMaxAttack + itemAbility->max_m_atk; // ¿É¼Ç °ª Àû¿ë. AddEquipAbility( itemAbility->opt01_index, itemAbility->opt01_value ); AddEquipAbility( itemAbility->opt02_index, itemAbility->opt02_value ); AddEquipAbility( itemAbility->opt03_index, itemAbility->opt03_value ); AddEquipAbility( itemAbility->opt04_index, itemAbility->opt04_value ); AddEquipAbility( itemAbility->opt05_index, itemAbility->opt05_value ); } // AddEquipEnhanced Method - °­È­´Ü°è´Â MIN_ITEM_ENHANCED ¿¡¼­ MAX_ITEM_ENHANCED ±îÁö. void cPlayer::AddEquipEnhanced(TB_ITEM_ENHANCED* itemEnhanced, BYTE enhanced) { if ( MIN_ITEM_ENHANCED <= enhanced && enhanced <= MAX_ITEM_ENHANCED ) { for ( int i= 0; i < itemEnhanced->row; i++ ) { short value = itemEnhanced->value[ i ].value[ enhanced-MIN_ITEM_ENHANCED ]; switch ( itemEnhanced->value[ i ].type ) { case ITEM_ENHANCED_PHYSIC_ATTACK: mEquipAbility.mPhysicMinAttack = mEquipAbility.mPhysicMinAttack + value; mEquipAbility.mPhysicMaxAttack = mEquipAbility.mPhysicMaxAttack + value; break; case ITEM_ENHANCED_MAGIC_ATTACK: mEquipAbility.mMagicMinAttack = mEquipAbility.mMagicMinAttack + value; mEquipAbility.mMagicMaxAttack = mEquipAbility.mMagicMaxAttack + value; break; case ITEM_ENHANCED_PHYSIC_DEFENSE: mEquipAbility.mPhysicDefense = mEquipAbility.mPhysicDefense + value; break; case ITEM_ENHANCED_MAGIC_DEFENSE: mEquipAbility.mMagicDefense = mEquipAbility.mMagicDefense + value; break; case ITEM_ENHANCED_MAGIC_HEAL: mEquipAbility.mOptPlusHeal = mEquipAbility.mOptPlusHeal + value; break; } } } } // AddEquipCards Method. void cPlayer::AddEquipCards(TB_INVENTORY* inventory) { TB_ITEM_DEFINE* itemDefine; TB_ITEM_ABILITY* itemAbility; itemDefine = ITEMMANAGER->GetItemDefineByIndex( inventory->cardSlot1 ); if ( itemDefine != NULL ) { itemAbility = ITEMMANAGER->GetItemAbility( itemDefine->idx ); if ( itemAbility != NULL ) { AddEquipAbility( itemAbility ); } } itemDefine = ITEMMANAGER->GetItemDefineByIndex( inventory->cardSlot2 ); if ( itemDefine != NULL ) { itemAbility = ITEMMANAGER->GetItemAbility( itemDefine->idx ); if ( itemAbility != NULL ) { AddEquipAbility( itemAbility ); } } itemDefine = ITEMMANAGER->GetItemDefineByIndex( inventory->cardSlot3 ); if ( itemDefine != NULL ) { itemAbility = ITEMMANAGER->GetItemAbility( itemDefine->idx ); if ( itemAbility != NULL ) { AddEquipAbility( itemAbility ); } } itemDefine = ITEMMANAGER->GetItemDefineByIndex( inventory->cardSlot4 ); if ( itemDefine != NULL ) { itemAbility = ITEMMANAGER->GetItemAbility( itemDefine->idx ); if ( itemAbility != NULL ) { AddEquipAbility( itemAbility ); } } itemDefine = ITEMMANAGER->GetItemDefineByIndex( inventory->cardSlot5 ); if ( itemDefine != NULL ) { itemAbility = ITEMMANAGER->GetItemAbility( itemDefine->idx ); if ( itemAbility != NULL ) { AddEquipAbility( itemAbility ); } } } // ResetArmorSets Method. void cPlayer::ResetArmorSets( ) { TB_ITEM_DEFINE* itemDefine; TB_ITEM_ABILITY* itemAbility; TB_INVENTORY* inventory; // CLEAR - ARMOR SETS mArmorSets = ARMOR_SETS_NONE; // ARMOR SETS - HAT inventory = SelectInventory( INVENTORY_WEAR_HAT ); if ( IsItemLimit( inventory->itemDefineIdx ) ) { itemAbility = ITEMMANAGER->GetItemAbility( inventory->itemDefineIdx ); if ( itemAbility != NULL ) { switch ( itemAbility->def_class ) { case 1: mArmorSets = mArmorSets | ARMOR_SETS_ROBES; break; // õ case 2: mArmorSets = mArmorSets | ARMOR_SETS_LIGHT; break; // °¡Á× case 3: mArmorSets = mArmorSets | ARMOR_SETS_HEAVY; break; // ±Ý¼Ó } } } // ARMOR SETS - UPPER(BODY1) inventory = SelectInventory( INVENTORY_WEAR_BODY1 ); if ( IsItemLimit( inventory->itemDefineIdx ) ) { itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if ( itemDefine != NULL ) { if ( itemDefine->subType == ITEM_WEAR_ONEPIECE ) { itemAbility = ITEMMANAGER->GetItemAbility( inventory->itemDefineIdx ); switch ( itemAbility->def_class ) { case 1: mArmorSets = mArmorSets | ARMOR_SETS_ROBES; break; // õ case 2: mArmorSets = mArmorSets | ARMOR_SETS_LIGHT; break; // °¡Á× case 3: mArmorSets = mArmorSets | ARMOR_SETS_HEAVY; break; // ±Ý¼Ó } } else { itemAbility = ITEMMANAGER->GetItemAbility( inventory->itemDefineIdx ); if ( itemAbility != NULL ) { switch ( itemAbility->def_class ) { case 1: mArmorSets = mArmorSets | ARMOR_SETS_ROBES; break; // õ case 2: mArmorSets = mArmorSets | ARMOR_SETS_LIGHT; break; // °¡Á× case 3: mArmorSets = mArmorSets | ARMOR_SETS_HEAVY; break; // ±Ý¼Ó } } } } } // ARMOR SETS - LOWER(BODY2) inventory = SelectInventory( INVENTORY_WEAR_BODY2 ); if ( IsItemLimit( inventory->itemDefineIdx ) ) { itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if ( itemDefine != NULL ) { if ( itemDefine->subType == ITEM_WEAR_ONEPIECE ) { itemAbility = ITEMMANAGER->GetItemAbility( inventory->itemDefineIdx ); switch ( itemAbility->def_class ) { case 1: mArmorSets = mArmorSets | ARMOR_SETS_ROBES; break; // õ case 2: mArmorSets = mArmorSets | ARMOR_SETS_LIGHT; break; // °¡Á× case 3: mArmorSets = mArmorSets | ARMOR_SETS_HEAVY; break; // ±Ý¼Ó } } else { itemAbility = ITEMMANAGER->GetItemAbility( inventory->itemDefineIdx ); if ( itemAbility != NULL ) { switch ( itemAbility->def_class ) { case 1: mArmorSets = mArmorSets | ARMOR_SETS_ROBES; break; // õ case 2: mArmorSets = mArmorSets | ARMOR_SETS_LIGHT; break; // °¡Á× case 3: mArmorSets = mArmorSets | ARMOR_SETS_HEAVY; break; // ±Ý¼Ó } } } } } // ARMOR SETS - HANDS(HAND) inventory = SelectInventory( INVENTORY_WEAR_HAND ); if ( IsItemLimit( inventory->itemDefineIdx ) ) { itemAbility = ITEMMANAGER->GetItemAbility( inventory->itemDefineIdx ); if ( itemAbility != NULL ) { switch ( itemAbility->def_class ) { case 1: mArmorSets = mArmorSets | ARMOR_SETS_ROBES; break; // õ case 2: mArmorSets = mArmorSets | ARMOR_SETS_LIGHT; break; // °¡Á× case 3: mArmorSets = mArmorSets | ARMOR_SETS_HEAVY; break; // ±Ý¼Ó } } } // ARMOR SETS - FEET(HAND) inventory = SelectInventory( INVENTORY_WEAR_FOOT ); if ( IsItemLimit( inventory->itemDefineIdx ) ) { itemAbility = ITEMMANAGER->GetItemAbility( inventory->itemDefineIdx ); if ( itemAbility != NULL ) { switch ( itemAbility->def_class ) { case 1: mArmorSets = mArmorSets | ARMOR_SETS_ROBES; break; // õ case 2: mArmorSets = mArmorSets | ARMOR_SETS_LIGHT; break; // °¡Á× case 3: mArmorSets = mArmorSets | ARMOR_SETS_HEAVY; break; // ±Ý¼Ó } } } } // AddCooltime Method. void cPlayer::AddCooltime(TB_INVENTORY_COOLTIME* table) { PerCooltime* perCooltime = COOLTIMEPOOL->GetCooltime( &mCooltimeRoot, table->itemDefineIndex ); if ( perCooltime != NULL ) { time_t ltime; struct tm validThru; time( <ime ); validThru = *localtime( <ime ); validThru.tm_sec += (table->cooltime/1000); perCooltime->cooltime1 = table->cooltime1; perCooltime->cooltime2 = table->cooltime2; perCooltime->validThru = mktime( &validThru ); } } // AddItemBill Method. PerItemBill* cPlayer::AddItemBill(TB_ITEM_BILL* table) { PerItemBill* itemBill = ITEMBILLPOOL->GetItemBill( &mItemBillRoot, table->inventoryIdx ); struct tm result; if ( itemBill != NULL ) { itemBill->idx = table->idx; itemBill->type = table->type; itemBill->validDate = table->validDate; itemBill->validTime = table->validTime; itemBill->apply = table->apply; time( &itemBill->timeBegin ); itemBill->timeEnd = itemBill->timeBegin; result = *localtime( &itemBill->timeBegin ); switch ( itemBill->type ) { case ITEM_BILL_DATE: result.tm_sec += itemBill->validDate; itemBill->timeEnd = mktime( &result ); break; case ITEM_BILL_TIME: result.tm_sec += itemBill->validTime; itemBill->timeEnd = mktime( &result ); break; } } return itemBill; } // SaveItemBill Method. bool cPlayer::SaveItemBill(long itemBillIdx, long elapsed, long before, long after, long inventoryIdx) { HANDLE handle = NULL; ITEM_BILL_UPDATE* update = (ITEM_BILL_UPDATE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_BILL_UPDATE ); update->characterIdx = mObject.index; update->idx = itemBillIdx; update->elapsed = elapsed; update->inventoryIdx = inventoryIdx; update->before = before; update->after = after; return NETWORK2->SendSQL( mConnectionIdx, handle, sizeof(ITEM_BILL_UPDATE) ); } // CheckInventory Method. bool cPlayer::UpdateItemBill( ) { if ( mItemBillRoot.pool ) { PerItemBill* itemBill = (PerItemBill*)mItemBillRoot.pool; PerItemBill* nextBill; time_t current; long elapsed; long before; long after; time( ¤t ); while ( itemBill != NULL ) { nextBill = (PerItemBill*)itemBill->next; if ( itemBill->type == ITEM_BILL_TIME ) { elapsed = (long)difftime( current, itemBill->timeBegin ); before = itemBill->validTime; after = itemBill->validTime-elapsed; SaveItemBill( itemBill->idx, elapsed, before, after, itemBill->inventoryIdx ); } ITEMBILLPOOL->ReleaseItemBill( &mItemBillRoot, itemBill ); itemBill = nextBill; } } return false; } // StartItemBill Method. void cPlayer::StartItemBill( ) { mItemBillStart = true; if ( mItemBillRoot.pool != NULL ) { PerItemBill* itemBillPool = (PerItemBill*)mItemBillRoot.pool; struct tm result; HANDLE handle = NULL; MSG_SYN_ITEM_BILL* sendSyn = (MSG_SYN_ITEM_BILL*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_ITEM, NM_ITEM_BILL_SYN ); if ( sendSyn != NULL ) { long& rowCount = sendSyn->rowCount; sItemBill* itemBill = sendSyn->itemBill; long length = sizeof(MSG_SYN_ITEM_BILL)-sizeof(sendSyn->itemBill); rowCount = 0; while ( itemBillPool != NULL ) { // ½Ã°£Á¦¸¸ Á¤»ê. if ( itemBill->type == ITEM_BILL_TIME ) { time( &itemBillPool->timeBegin ); itemBillPool->timeEnd = itemBillPool->timeBegin; result = *localtime( &itemBillPool->timeBegin ); result.tm_sec += itemBillPool->validTime; itemBillPool->timeEnd = mktime( &result ); } itemBill->idx = itemBillPool->idx; itemBill->type = itemBillPool->type; itemBill->validDate = itemBillPool->timeEnd; itemBill->validTime = itemBillPool->validTime; itemBill->inventoryIdx = itemBillPool->inventoryIdx; rowCount++; itemBill++; itemBillPool = (PerItemBill*)itemBillPool->next; } length += (rowCount * sizeof(sendSyn->itemBill)); NETWORK2->SendMsgRoot( handle, length ); } } } // StopItemBill Method. void cPlayer::StopItemBill( ) { PerItemBill* itemBillPool = (PerItemBill*)mItemBillRoot.pool; time_t current; long elapsed; long before; long after; time( ¤t ); while ( itemBillPool != NULL ) { // ½Ã°£Á¦¸¸ Á¤»ê. if ( itemBillPool->type == ITEM_BILL_TIME ) { elapsed = (long)difftime( current, itemBillPool->timeBegin ); before = itemBillPool->validTime; after = itemBillPool->validTime-(before < elapsed ? before : elapsed); SaveItemBill( itemBillPool->idx, elapsed, before, after, itemBillPool->inventoryIdx ); itemBillPool->validTime = after; itemBillPool->timeBegin = current; } itemBillPool = (PerItemBill*)itemBillPool->next; } mItemBillStart = false; } // CheckInventory Method. bool cPlayer::CheckInventory(long itemDefineIndex, int itemCount) { TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefineByIndex( itemDefineIndex ); if ( itemDefine != NULL ) { TB_INVENTORY* inventory = SelectInventory( INVENTORY_BAG_BEGIN ); int remainCount = itemCount; for ( int i = INVENTORY_BAG_BEGIN; (i <= mHeroInfo.BagEnd) && (remainCount > 0); i++, inventory++ ) { if ( IsInventory( inventory ) == false ) { remainCount -= itemDefine->capacity; } else if ( inventory->itemDefineIndex == itemDefineIndex ) { remainCount -= (itemDefine->capacity - inventory->count); } } return (remainCount > 0) ? false : true; } return false; } // XCopyInventory Method. TB_INVENTORY* cPlayer::XCopyInventory(TB_INVENTORY* destination, TB_INVENTORY* source, XCOPY_INVENTORY_OPT opt) { size_t length = sizeof(TB_INVENTORY); TB_INVENTORY tempInv; short tempNum; switch ( opt ) { case XCOPY_INVENTORY_ALL: ITEMCOUNTPOOL->UpdateItemCount( &mItemCountRoot, source->itemDefineIndex, source->number, (source->count - destination->count) ); memcpy( destination, source, length ); break; case XCOPY_INVENTORY_COUNT: ITEMCOUNTPOOL->UpdateItemCount( &mItemCountRoot, source->itemDefineIndex, source->number, (source->count - destination->count) ); destination->count = source->count; break; case XCOPY_INVENTORY_SWAP: tempInv = (*destination); ITEMCOUNTPOOL->UpdateItemCount( &mItemCountRoot, source->itemDefineIndex, destination->number, source->count ); tempNum = destination->number; memcpy( destination, source, length ); destination->number = tempNum; ITEMCOUNTPOOL->UpdateItemCount( &mItemCountRoot, source->itemDefineIndex, source->number, (-source->count) ); ITEMCOUNTPOOL->UpdateItemCount( &mItemCountRoot, tempInv.itemDefineIndex, source->number, tempInv.count ); tempNum = source->number; memcpy( source, &tempInv, length ); source->number = tempNum; ITEMCOUNTPOOL->UpdateItemCount( &mItemCountRoot, tempInv.itemDefineIndex, tempInv.number, (-tempInv.count) ); break; } mItemChange = true; mXCopyComplete = true; return destination; } // XCopyInventory Method. TB_INVENTORY* cPlayer::XCopyInventory(TB_INVENTORY* source, XCOPY_INVENTORY_OPT opt) { TB_INVENTORY* destination = SelectInventory( source->number ); if ( destination != NULL ) { return XCopyInventory( destination, source, opt ); } return NULL; } TB_INVENTORY* cPlayer::SelectInventoryIdx(long idx, short begin, short end) { TB_INVENTORY* inventory = SelectInventory( begin ); for ( short i = begin; i <= end; i++, inventory++ ) { if ( inventory->idx == idx ) return inventory; } return NULL; } // FindFirstInventory Method(numberÀÇ °ªÀº ÀÚµ¿ ÃʱâÈ­µÊ). bool cPlayer::FindFirstInventory(TB_ITEM_DEFINE* itemDefine, short* number, short remainCount, short* pcvValue, bool overlap) { if ( itemDefine->type != ITEM_QUEST ) { (*number)=INVENTORY_BAG_BEGIN; return FindNextInventory( itemDefine, number, remainCount, pcvValue, overlap ); } else { (*number)=INVENTORY_QUEST_BEGIN; return FindNextInventory( itemDefine, number, remainCount, pcvValue, overlap ); } } // FindNextInventory Method(numberÀÇ °ªÀº ¼öµ¿ Áõ°¡ ÇØ¾ßµÊ). bool cPlayer::FindNextInventory(TB_ITEM_DEFINE* itemDefine, short* number, short remainCount, short* pcvValue, bool overlap) { if ( !(remainCount > 0) ) return false; if ( overlap == true ) { short begin = (*number); short end = (short)((itemDefine->type != ITEM_QUEST) ? mHeroInfo.BagEnd : INVENTORY_QUEST_END); TB_INVENTORY* inventory = SelectInventory( begin ); for ( short i = begin; i <= end; i++, inventory++ ) { if ( IsInventory( inventory ) == true && inventory->itemDefineIndex == itemDefine->index && inventory->count < itemDefine->capacity && inventory->cash == 0 ) { if ( (inventory->count + remainCount) > itemDefine->capacity ) (*pcvValue) = itemDefine->capacity - inventory->count; else (*pcvValue) = remainCount; (*number) = i; return true; } } } else { if ( itemDefine->type != ITEM_QUEST ) { (*number) = GetEmptyBagNumber( (*number) ); if ( (*number) != INVENTORY_BAG_NONE ) { (*pcvValue) = remainCount; return true; } } else { (*number) = GetEmptyQuestNumber( (*number) ); if ( (*number) != INVENTORY_QUEST_NONE ) { (*pcvValue) = remainCount; return true; } } } return false; } // CreateInventory Method. TB_INVENTORY* cPlayer::CreateInventory(TB_ITEM_DEFINE* itemDefine, short number, short count, short* pcbValue) { TB_INVENTORY* inventory = SelectInventory( number ); if ( inventory != NULL ) { if ( IsInventory( inventory ) == false ) { short shortCount = (count > itemDefine->capacity) ? itemDefine->capacity : count; ITEMCOUNTPOOL->UpdateItemCount( &mItemCountRoot, itemDefine->index, number, shortCount ); inventory->idx = LONG_MAX; inventory->itemDefineIdx = itemDefine->idx; inventory->itemDefineIndex = itemDefine->index; inventory->number = number; inventory->count = shortCount; inventory->enhanced = 0; inventory->seal = (itemDefine->licenseType == 1) ? 1 : 0; inventory->cash = 0; inventory->apply = InventoryApplyNone; (*pcbValue) = shortCount; mItemChange = true; return inventory; } } return NULL; } TB_INVENTORY* cPlayer::CreateInventory(long itemDefineIndex, short number, short count, short* pcbValue) { TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefineByIndex( itemDefineIndex ); return ( itemDefine != NULL ) ? CreateInventory( itemDefine, number, count, pcbValue ) : NULL; } // UpdateInventory Method. short cPlayer::UpdateInventory(TB_INVENTORY* inventory, short count) { short retvalue = 0; if ( inventory != NULL ) { if ( inventory->count > 0 ) { PerItemCount* itemCount = NULL; if ( count > 0 ) { TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if ( itemDefine != NULL ) { if ( (inventory->count + count) > itemDefine->capacity ) retvalue = itemDefine->capacity - inventory->count; else retvalue = count; itemCount =ITEMCOUNTPOOL->UpdateItemCount( &mItemCountRoot, inventory->itemDefineIndex, inventory->number, retvalue ); inventory->count = inventory->count + retvalue; } } else { if ( inventory->count <= abs( count ) ) retvalue = (-inventory->count); else retvalue = count; itemCount =ITEMCOUNTPOOL->UpdateItemCount( &mItemCountRoot, inventory->itemDefineIndex, inventory->number, retvalue ); inventory->count = inventory->count + retvalue; } mItemChange = true; } } return retvalue; } // UpdateInventory Method. short cPlayer::UpdateInventory(short number, short count) { return UpdateInventory( SelectInventory( number ), count ); } // RemoveInventory Method. bool cPlayer::RemoveInventory(TB_INVENTORY* inventory) { if ( inventory != NULL ) { int inventoryBagCount = 0; if ( inventory->count > 0 ) { PerItemCount* itemCount = ITEMCOUNTPOOL->UpdateItemCount( &mItemCountRoot, inventory->itemDefineIndex, inventory->number, (-inventory->count) ); if ( itemCount != NULL ) { inventoryBagCount = itemCount->bag; } } TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if ( itemDefine != NULL ) { if ( itemDefine->type == ITEM_MATERIAL && itemDefine->subType == ITEM_MATERIAL_VEHICLE ) { TB_ITEM_ABILITY* ability = ITEMMANAGER->GetItemAbility( inventory->itemDefineIdx ); if ( ability != NULL && !(inventoryBagCount > 0) ) { EndVehicleItem( ability->influence_idx ); } } } memset( inventory, 0, sizeof(TB_INVENTORY) ); mItemChange = true; return true; } return false; } // RemoveInventory Method. bool cPlayer::RemoveInventory(short number) { return RemoveInventory( SelectInventory( number ) ); } // ItemInsInventory Method. void cPlayer::ItemInsInventory(ULONG_PTR socketContext, MSG_REQ_CHEAT_MAKE* recvMsg) { if ( mInventoryDatabase ) throw ERROR_CHEAT_MAKE_NOTYET; TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefineByIndex( recvMsg->mItemIndex ); short remainCount = recvMsg->mCount; short shortCount; short number; if ( itemDefine!= NULL && recvMsg->mCount > 0 ) { // ġƮ ¾ÆÀÌÅÛ. »ý¼º °Ë»ç ¹× µî·Ï. if ( FindFirstInventory( itemDefine, &number, remainCount, &shortCount, false ) == false ) throw ERROR_CHEAT_MAKE_FAIL; HANDLE handle = NULL; INVENTORY_INSERT* inventoryInsert = (INVENTORY_INSERT*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_INVENTORY_INSERT ); TB_INVENTORY* table = inventoryInsert->table; long& rowCount = inventoryInsert->rowCount; long length = sizeof(INVENTORY_INSERT) - sizeof(inventoryInsert->table); inventoryInsert->characterIdx = mObject.index; // ġƮ ¾ÆÀÌÅÛ. »ý¼º °Ë»ç ¹× µî·Ï. do { CreateInventory( itemDefine, number, remainCount, &shortCount ); remainCount = remainCount - shortCount; table->idx = 0; table->itemDefineIdx = itemDefine->idx; table->itemDefineIndex = itemDefine->index; table->number = number; table->count = (+shortCount); table->enhanced = recvMsg->mEnhance; table->cardSlot1 = recvMsg->mCardSlot[0]; table->cardSlot2 = recvMsg->mCardSlot[1]; table->cardSlot3 = recvMsg->mCardSlot[2]; table->cardSlot4 = recvMsg->mCardSlot[3]; table->cardSlot5 = recvMsg->mCardSlot[4]; table->seal = ( itemDefine->licenseType == 1 ) ? 1 : 0; table++; rowCount++; } while ( FindNextInventory( itemDefine, &(++number), remainCount, &shortCount, false ) == true ); length += (sizeof(inventoryInsert->table) * inventoryInsert->rowCount); mInventoryDb.insert = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); if ( mInventoryDb.insert == false ) { NETWORK2->ReleaseSQL( handle, length ); throw ERROR_CHEAT_MAKE_FAIL; } } else throw ERROR_CHEAT_MAKE_FAIL; } // ItemInsInventory Method. void cPlayer::ItemInsInventory(ULONG_PTR socketContext, MSG_REQ_CHEAT_MAKE_ITEMS* recvMsg) { if ( mInventoryDatabase ) throw ERROR_CHEAT_MAKE_NOTYET; if( recvMsg->mCount < 1 ) throw ERROR_CHEAT_MAKE_FAIL; sCheat_Make_Item_Info* pItemInfo = recvMsg->mItemInfo; HANDLE handle = NULL; INVENTORY_INSERT* inventoryInsert = (INVENTORY_INSERT*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_INVENTORY_INSERT ); TB_INVENTORY* table = inventoryInsert->table; long& rowCount = inventoryInsert->rowCount; long length = sizeof(INVENTORY_INSERT) - sizeof(inventoryInsert->table); for( unsigned int cnt = 0; cnt < recvMsg->mCount; ++cnt, pItemInfo++ ) { TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefineByIndex( pItemInfo->mItemIndex ); short remainCount = pItemInfo->mCount; short shortCount; short number; if ( itemDefine!= NULL && pItemInfo->mCount > 0 ) { // ġƮ ¾ÆÀÌÅÛ. »ý¼º °Ë»ç ¹× µî·Ï. if ( FindFirstInventory( itemDefine, &number, remainCount, &shortCount, false ) == false ) { // ¸¸µé ¼ö ÀÖ´Â °¹¼ö ¸¸Å­ »ý¼ºÇϱâ. if( cnt != 0 ) { mInventoryDb.insert = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); if ( mInventoryDb.insert == false ) { NETWORK2->ReleaseSQL( handle, length ); throw ERROR_CHEAT_MAKE_FAIL; } return; } NETWORK2->ReleaseSQL( handle, length ); throw ERROR_CHEAT_MAKE_FAIL; } inventoryInsert->characterIdx = mObject.index; // ġƮ ¾ÆÀÌÅÛ. »ý¼º °Ë»ç ¹× µî·Ï. do { CreateInventory( itemDefine, number, remainCount, &shortCount ); remainCount = remainCount - shortCount; table->idx = 0; table->itemDefineIdx = itemDefine->idx; table->itemDefineIndex = itemDefine->index; table->number = number; table->count = (+shortCount); table->enhanced = pItemInfo->mEnhance; table->cardSlot1 = pItemInfo->mCardSlot[0]; table->cardSlot2 = pItemInfo->mCardSlot[1]; table->cardSlot3 = pItemInfo->mCardSlot[2]; table->cardSlot4 = pItemInfo->mCardSlot[3]; table->cardSlot5 = pItemInfo->mCardSlot[4]; table->seal = ( itemDefine->licenseType == 1 ) ? 1 : 0; table++; rowCount++; } while ( FindNextInventory( itemDefine, &(++number), remainCount, &shortCount, false ) == true ); length = (sizeof(inventoryInsert->table) * inventoryInsert->rowCount) + (sizeof(INVENTORY_INSERT) - sizeof(inventoryInsert->table)); } else { // ¸¸µé ¼ö ÀÖ´Â °¹¼ö ¸¸Å­ »ý¼ºÇϱâ. if( cnt != 0 ) { mInventoryDb.insert = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); if ( mInventoryDb.insert == false ) { NETWORK2->ReleaseSQL( handle, length ); throw ERROR_CHEAT_MAKE_FAIL; } return; } NETWORK2->ReleaseSQL( handle, length ); throw ERROR_CHEAT_MAKE_FAIL; } } mInventoryDb.insert = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); if ( mInventoryDb.insert == false ) { NETWORK2->ReleaseSQL( handle, length ); throw ERROR_CHEAT_MAKE_FAIL; } } // ItemMovInventory Method. void cPlayer::ItemMovInventory(ULONG_PTR socketContext, MSG_REQ_ITEM_MOV_INVENTORY* msg) { if ( mInventoryDatabase ) throw ERROR_ITEM_MOV_INVENTORY_NOTYET; if ( GetStateDie( ) ) throw ERROR_ITEM_MOV_INVENTORY_FAIL; if ( msg->number1 == msg->number2 ) throw ERROR_ITEM_MOV_INVENTORY_FAIL; TB_INVENTORY* inventory1 = SelectInventory( msg->number1 ); TB_INVENTORY* inventory2 = SelectInventory( msg->number2 ); TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory1->itemDefineIdx ); if ( IsInventoryCash( msg->number1 ) && IsInventoryRange( msg->number2 ) ) { if ( !IsInventoryBag( msg->number2 ) || IsInventory( inventory2 ) ) throw ERROR_ITEM_MOV_INVENTORY_FAIL; if ( IsMaxInventory( itemDefine, inventory1->count ) == true ) throw ERROR_ITEM_MOV_INVENTORY_MAX_ITEM; } else if ( !IsInventoryRange( msg->number1 ) || !IsInventoryRange( msg->number2 ) ) throw ERROR_ITEM_MOV_INVENTORY_FAIL; if ( IsInventoryEquip( msg->number1 ) && IsInventoryEquip( msg->number2 ) ) throw ERROR_ITEM_MOV_INVENTORY_FAIL; if ( IsInventoryQuest( msg->number1 ) != IsInventoryQuest( msg->number2 ) ) throw ERROR_ITEM_MOV_INVENTORY_FAIL; if ( IsInventoryWarehouse( msg->number1 ) != IsInventoryWarehouse( msg->number2 ) ) throw ERROR_ITEM_MOV_INVENTORY_FAIL; /// Ÿ·ÎÄ«µåÀÇ °æ¿ì if ( IsInventoryCollect( msg->number2 ) ) { if ( !IsInventoryBag( msg->number1 ) ) throw ERROR_ITEM_MOV_INVENTORY_FAIL; if ( GetStateStop() == eSTOP_SELFTAROT || GetStateStop() == eSTOP_OPENTAROT ) throw ERROR_ITEM_MOV_INVENTORY_STATE; } else if ( IsInventoryCollect( msg->number1 ) ) { if ( !IsInventoryBag( msg->number2 ) ) throw ERROR_ITEM_MOV_INVENTORY_FAIL; if ( GetStateStop() == eSTOP_SELFTAROT || GetStateStop() == eSTOP_OPENTAROT ) throw ERROR_ITEM_MOV_INVENTORY_STATE; } if ( inventory1->apply != InventoryApplyNone || inventory2->apply != InventoryApplyNone ) throw ERROR_ITEM_MOV_INVENTORY_FAIL; /*-- Àκ¥Å丮 À̵¿Áß, º´ÇÕ Ã³¸®. */ if ( IsInventoryMerge( itemDefine, inventory1, inventory2 ) == true ) { mInventoryDb.merge = NETWORK2->InventoryMerge( (PerSocketContext*)socketContext ,inventory1->idx ,inventory2->idx ,itemDefine->capacity ); throw ERROR_ITEM_MOV_INVENTORY_MERGE; } /*-- Àκ¥Å丮 À̵¿ ó¸®. */ int depth = 0; short except[3]; short number[3]; memset( except, 0, sizeof(except) ); memset( number, 0, sizeof(number) ); (*except) = msg->number2; if ( IsInventoryMove( msg->number1, msg->number2, except, depth ) == false ) throw ERROR_ITEM_MOV_INVENTORY_FAIL; // ¿¹¿Üó¸® °Ë»ç if ( (*except) != msg->number2 ) { short empty = INVENTORY_BAG_BEGIN; short* pExcept = except; short* pNumber = number; for ( int i = 0; i < 3 && (*pExcept) != 0; i++, pExcept++, pNumber++ ) { empty = GetEmptyBagNumber( empty ); if ( empty == INVENTORY_BAG_NONE ) throw ERROR_ITEM_MOV_INVENTORY_FAIL; (*pNumber) = empty; empty++; } } /*-- 'depth' °¡ 0 Àϰæ¿ì move, ¾Æ´Ò°æ¿ì swap ó¸® ÇÑ´Ù. 'swap' °ú 'move' ´Â ó¸® ¼ø¼­°¡ ¼­·Î ´Ù¸£¹Ç·Î ÁÖÀÇÇØ¾ß ÇÑ´Ù. */ if ( depth != 0 ) { // Except DB & SRV if ( (*except) != msg->number2 ) { long idx[3]; short* pExcept = except; short* pNumber = number; memset( idx, 0, sizeof(idx) ); for ( int i = 0; i < 3 && (*pExcept) != 0; i++, pExcept++, pNumber++ ) { idx[ i ] = SelectInventory( (*pExcept) )->idx; InventoryExcept( (*pExcept), (*pNumber) ); } mInventoryDb.except = NETWORK2->InventoryExcept( (PerSocketContext*)socketContext, idx, (short*)number ); } // Swap DB & SRV mInventoryDb.swap = NETWORK2->InventorySwap( (PerSocketContext*)socketContext ,inventory1->idx ,inventory1->number ,inventory2->idx ,inventory2->number ); if ( mInventoryDb.swap ) { InventorySwap( msg->number1, msg->number2 ); } throw ERROR_ITEM_MOV_INVENTORY_SUCCESS; } else { // Move DB & SRV mInventoryDb.move = NETWORK2->InventoryMove( (PerSocketContext*)socketContext ,inventory1->idx ,msg->number2 ,IsInventoryCash( msg->number1 ) ); if ( mInventoryDb.move ) { InventoryMove( msg->number1, msg->number2 ); } // Except DB & SRV if ( (*except) != msg->number2 ) { long idx[3]; short* pExcept = except; short* pNumber = number; memset( idx, 0, sizeof(idx) ); for ( int i = 0; i < 3 && (*pExcept) != 0; i++, pExcept++, pNumber++ ) { idx[ i ] = SelectInventory( (*pExcept) )->idx; InventoryExcept( (*pExcept), (*pNumber) ); } mInventoryDb.except = NETWORK2->InventoryExcept( (PerSocketContext*)socketContext, idx, (short*)number ); } throw ERROR_ITEM_MOV_INVENTORY_SUCCESS; } } // ItemUseInventory Method. void cPlayer::ItemUseInventory(ULONG_PTR socketContext, MSG_REQ_ITEM_USE_INVENTORY* msg) { /*-- ¾ÆÀÌÅÛ »ç¿ë½Ã °Ë»çÇÒ ³»¿ëµé. */ if ( mInventoryDatabase ) throw ERROR_ITEM_USE_INVENTORY_NOTYET; if ( GetStateDie( ) == true ) throw ERROR_ITEM_USE_INVENTORY_FAIL; if ( IsInventoryBag( msg->number ) == false ) throw ERROR_ITEM_USE_INVENTORY_FAIL; TB_INVENTORY* inventory = SelectInventory( msg->number ); if ( IsInventory( inventory ) == false ) throw ERROR_ITEM_USE_INVENTORY_FAIL; if ( inventory->apply != InventoryApplyNone ) throw ERROR_ITEM_USE_INVENTORY_FAIL; /*-- Item Define Table(TB_ITEM_DEFINE) Àû¿ë. */ TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); unsigned int getState; if ( itemDefine == NULL ) throw ERROR_ITEM_USE_INVENTORY_FAIL; if ( IsInventorySeal( itemDefine, inventory ) == true ) throw ERROR_ITEM_USE_INVENTORY_LICENSE; if ( !( (itemDefine->type == ITEM_ETC1) || (itemDefine->type == ITEM_CARD && itemDefine->subType == ITEM_CARD_COMMON ) || (itemDefine->type == ITEM_MONSTER) || (itemDefine->type == ITEM_INVENTORY) ) ) throw ERROR_ITEM_USE_INVENTORY_FAIL; /// ¿øº» //if ( itemDefine->type == ITEM_ETC1 && itemDefine->subType == ITEM_ETC1_QUEST ) //{ // throw ERROR_ITEM_USE_INVENTORY_FAIL; //} if ( itemDefine->type == ITEM_ETC1 ) { switch( itemDefine->subType ) { case ITEM_ETC1_QUEST: { throw ERROR_ITEM_USE_INVENTORY_FAIL; } break; case ITEM_ETC1_EXP_RESTORE: { if( mHeroInfo.mLoseExp == 0 ) throw ERROR_ITEM_USE_EXP_RECOVER; if( TIMER->DiffRealTime( mExpRecoverEndTime ) < 0 ) throw ERROR_ITEM_USE_EXP_RECOVER; } break; } } else if ( itemDefine->type == ITEM_CARD && itemDefine->subType == ITEM_CARD_COMMON ) { getState = GetState( ); if ( !( getState == eOBJECT_STATE_IDLE || getState == ePLAYER_STATE_ITEMPICK ) ) throw ERROR_ITEM_USE_INVENTORY_FAIL; } else if ( itemDefine->type == ITEM_MONSTER ) { getState = GetState( ); if ( !( getState == eOBJECT_STATE_IDLE || getState == ePLAYER_STATE_ITEMPICK ) ) throw ERROR_ITEM_USE_INVENTORY_FAIL; } /*-- Item Limit Table(TB_ITEM_LIMIT) Àû¿ë --*/ if ( !IsItemLimit( inventory->itemDefineIdx ) ) throw ERROR_ITEM_USE_INVENTORY_FAIL; /*-- »ç¿ëÇÒ È¿°ú Àû¿ë. --*/ TB_ITEM_ABILITY* itemAbility = ITEMMANAGER->GetItemAbility( inventory->itemDefineIdx ); cTitleDefine* titleDefine = TITLEMAN->GetTitleDefine( itemDefine->titleIndex ); /*-- Item Ability È¿°ú Àû¿ë°¡´É °Ë»ç */ if ( itemAbility != NULL ) { int apply = ERROR_ITEM_USE_INVENTORY_SUCCESS; if ( itemAbility->influence_idx > 0 ) { // ¿ì¼± °Ë»ç Á¶°Ç. if ( itemAbility->target_type == ITEM_TARGET_MYSELF ) { apply = SKILLMANAGER->ItemCheckAddInf( this, this, itemAbility->influence_idx ); } else if ( itemAbility->target_type == ITEM_TARGET_MONSTER ) { if ( msg->targetType == eOBJECTTYPE_MONSTER ) { cMonster* monster = OBJECTMANAGER->GetMonster( msg->targetIndex ); if ( monster != NULL ) { NiPoint3 monsterPos( monster->GetXPos( ), monster->GetYPos( ), monster->Height( ) ); NiPoint3 heroPos( mObjectPos.x, mObjectPos.y, Height() ); if ( mMapNumber == monster->GetMapNumber( ) && (short)(heroPos - monsterPos).Length( ) < itemAbility->use_range ) { apply = SKILLMANAGER->ItemCheckAddInf( this, monster, itemAbility->influence_idx ); } } } } // Â÷¼± °Ë»ç Á¶°Ç. else { if ( itemAbility->target_type & ITEM_TARGET_MYSELF ) { if ( msg->targetType == eOBJECTTYPE_HERO || msg->targetIndex == mObject.index ) { apply = SKILLMANAGER->ItemCheckAddInf( this, this, itemAbility->influence_idx ); } } if ( itemAbility->target_type & ITEM_TARGET_PLAYER ) { if ( msg->targetType == eOBJECTTYPE_PLAYER ) { cPlayer* player = OBJECTMANAGER->GetPlayer( msg->targetIndex ); if ( player != NULL ) { NiPoint3 playerPos( player->GetXPos( ), player->GetYPos( ), player->Height( ) ); NiPoint3 heroPos( mObjectPos.x, mObjectPos.y, Height() ); if ( mMapNumber == player->GetMapNumber( ) && (short)(heroPos - playerPos).Length( ) < itemAbility->use_range ) { apply = SKILLMANAGER->ItemCheckAddInf( this, player, itemAbility->influence_idx ); } } } } if ( itemAbility->target_type & ITEM_TARGET_PARTY ) { // ÆÄƼ °Ë»ç cParty* party = PARTYMAN->GetParty( mPlayerExrInfo.mPartyIndex ); if ( party != NULL ) { if ( party->IsUser( msg->targetIndex ) == true ) { cPlayer* player = OBJECTMANAGER->GetPlayer( msg->targetIndex ); if ( player != NULL ) { NiPoint3 playerPos( player->GetXPos( ), player->GetYPos( ), player->Height( ) ); NiPoint3 heroPos( mObjectPos.x, mObjectPos.y, Height() ); if ( mMapNumber == player->GetMapNumber( ) && (short)(heroPos - playerPos).Length( ) < itemAbility->use_range ) { apply = SKILLMANAGER->ItemCheckAddInf( this, player, itemAbility->influence_idx ); } } } } else { // ÆÄƼ ¿¬ÇÕ °Ë»ç cPartyUnion* partyUnion = PARTYUNIONMAN->GetUnion( mPlayerExrInfo.mPartyUnionIndex ); if( partyUnion != NULL ) { if ( partyUnion->IsUser( GetObjectID(), msg->targetIndex ) == true ) { cPlayer* player = OBJECTMANAGER->GetPlayer( msg->targetIndex ); if ( player != NULL ) { NiPoint3 playerPos( player->GetXPos( ), player->GetYPos( ), player->Height( ) ); NiPoint3 heroPos( mObjectPos.x, mObjectPos.y, Height() ); if ( mMapNumber == player->GetMapNumber( ) && (short)(heroPos - playerPos).Length( ) < itemAbility->use_range ) { apply = SKILLMANAGER->ItemCheckAddInf( this, player, itemAbility->influence_idx ); } } } } } } } } // ½ºÅ³ÀÇ È¿°ú Àû¿ë¿©ºÎ È®ÀÎ. if ( apply != ERROR_ITEM_USE_INVENTORY_SUCCESS ) { throw apply; } } /* Title Table È¿°ú Àû¿ë°¡´É °Ë»ç */ else if ( titleDefine != NULL ) { cHaveTitleSet::cIterator title = mHaveTitleSet.Find( itemDefine->titleIndex ); if ( title != mHaveTitleSet.End( ) ) throw ERROR_ITEM_USE_INVENTORY_TITLE; } /* È¿°ú ¾ø´Â ¾ÆÀÌÅÛ ±â´É Àû¿ë */ else if ( itemDefine->type == ITEM_INVENTORY ) { if( (itemDefine->subType == ITEM_INVENTORY_BAG && mHeroInfo.BagEnd == INVENTORY_BAG_END ) || (itemDefine->subType == ITEM_INVENTORY_CARD && mHeroInfo.WearEnd == INVENTORY_WEAR_END ) || (itemDefine->subType == ITEM_INVENTORY_WAREHOUSE && mHeroInfo.WareHouseEnd == INVENTORY_WAREHOUSE_END ) || (itemDefine->subType == ITEM_INVENTORY_MAKESKILL && mHeroInfo.MakeSkillEnd == MAX_MAKESKILL ) ) throw ERROR_ITEM_USE_INVENTORY_SLOT; HANDLE handle = NULL; CHARACTER_INVEN_SIZE* invenSize = (CHARACTER_INVEN_SIZE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_CHARACTER_INVEN_SIZE ); invenSize->idx = mObject.index; invenSize->bag = mHeroInfo.BagEnd; invenSize->wear = mHeroInfo.WearEnd; invenSize->wareHouse = mHeroInfo.WareHouseEnd; invenSize->makeSkill = mHeroInfo.MakeSkillEnd; if( SetInvenLimit( itemDefine, invenSize ) == false ) { NETWORK2->PostServerEvent( "ERROR INVENTORY_USE - (itemDefine->type == ITEM_INVENTORY), ItemIndex(=%d)", inventory->itemDefineIndex ); throw ERROR_ITEM_USE_INVENTORY_FAIL; } NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, sizeof(CHARACTER_INVEN_SIZE) ); } else if( itemDefine->type == ITEM_ETC1 && itemDefine->subType == ITEM_ETC1_EXP_RESTORE ) { } else throw ERROR_ITEM_USE_INVENTORY_FAIL; /*-- Item Ability Table - ÄðŸÀÓ °Ë»ç ¹× Àû¿ë. */ if ( COOLTIMEPOOL->IsCooltime( &mCooltimeRoot, inventory->itemDefineIndex ) == true ) throw ERROR_ITEM_USE_INVENTORY_COOLTIME; else COOLTIMEPOOL->ApplyCooltime( &mCooltimeRoot, inventory ); /*-- Item Ability Table - È¿°ú Àû¿ë. */ if ( itemAbility != NULL ) { bool apply = false; if( itemAbility->influence_idx == 0 ) { apply = true; } else if ( itemAbility->influence_idx > 0 ) { // ¿ì¼± °Ë»ç Á¶°Ç. if ( itemAbility->target_type == ITEM_TARGET_MYSELF ) { apply = SKILLMANAGER->AddInfluence( mObject, mObject, itemAbility->influence_idx, 0, true ); } else if ( itemAbility->target_type == ITEM_TARGET_MONSTER ) { cMonster* monster = OBJECTMANAGER->GetMonster( msg->targetIndex ); if ( monster != NULL ) apply = SKILLMANAGER->AddInfluence( mObject, monster->GetObject( ), itemAbility->influence_idx, 0, true ); } // Â÷¼± °Ë»ç Á¶°Ç. else { if ( msg->targetType == eOBJECTTYPE_HERO || msg->targetIndex == mObject.index ) { apply = SKILLMANAGER->AddInfluence( mObject, mObject, itemAbility->influence_idx, 0, true ); } if ( itemAbility->target_type & ITEM_TARGET_PLAYER ) { if ( msg->targetType == eOBJECTTYPE_PLAYER ) { cPlayer* player = OBJECTMANAGER->GetPlayer( msg->targetIndex ); if ( player != NULL ) apply = SKILLMANAGER->AddInfluence( mObject, player->GetObject( ), itemAbility->influence_idx, 0, true ); } } if ( itemAbility->target_type & ITEM_TARGET_PARTY ) { // ÆÄƼ °Ë»ç cParty* party = PARTYMAN->GetParty( GetPartyIndex( ) ); if ( party != NULL ) { if ( party->IsUser( msg->targetIndex ) == true ) { cPlayer* player = OBJECTMANAGER->GetPlayer( msg->targetIndex ); if ( player != NULL ) apply = SKILLMANAGER->AddInfluence( mObject, player->GetObject( ), itemAbility->influence_idx, 0, true ); } } else { // ÆÄƼ ¿¬ÇÕ °Ë»ç cPartyUnion* partyUnion = PARTYUNIONMAN->GetUnion( GetPartyUnionIndex() ); if( partyUnion != NULL ) { if ( partyUnion->IsUser( GetObjectID(), msg->targetIndex ) == true ) { cPlayer* player = OBJECTMANAGER->GetPlayer( msg->targetIndex ); if ( player != NULL ) apply = SKILLMANAGER->AddInfluence( mObject, player->GetObject( ), itemAbility->influence_idx, 0, true ); } } } } } } if ( apply == false ) { NETWORK2->PostServerEvent( "ERROR INVENTORY_USE, ItemIndex(=%d)", inventory->itemDefineIndex ); throw ERROR_ITEM_USE_INVENTORY_FAIL; } } else if ( titleDefine != NULL ) { HANDLE handle = NULL; TITLE_INSERT* titleInsert = (TITLE_INSERT*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_TITLE_INSERT ); titleInsert->characterIdx = mObject.index; titleInsert->titleIdx = itemDefine->titleIndex; NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, sizeof(TITLE_INSERT) ); } if ( itemDefine->type == ITEM_ETC1 ) { switch( itemDefine->subType ) { /// °æÇèÄ¡ º¹±¸ ¼öÄ¡ Àû¿ë case ITEM_ETC1_EXP_RESTORE: { AddExp( mHeroInfo.mLoseExp, false, true ); mHeroInfo.mLoseExp = 0; if( DBUpdate( false, PLAYER_DBUPDATE_EXPRECOVER ) == false ) mBatchSaveTime = 0; } break; case ITEM_ETC1_AUTODETECT: { // ·£´ý ¸ó½ºÅÍ ¼Òȯ if( AIMANAGER->AutoDetectSummonMonRegen( mMapNumber, mObjectPos.x, mObjectPos.y ) == false ) throw ERROR_ITEM_USE_INVENTORY_FAIL; } break; } } // ¾ÆÀÌÅÛ »ç¿ë ¼±Ã³¸®. UpdateInventory( inventory, (-1) ); // DATABASE - Àκ¥Å丮³» ¾ÆÀÌÅÛ »ç¿ë ¿äû. HANDLE handle = NULL; INVENTORY_USE* inventoryUse = (INVENTORY_USE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_INVENTORY_USE ); TB_INVENTORY* table = inventoryUse->table; (*table) = (*inventory); mInventoryDb.use = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, sizeof(INVENTORY_USE) ); if ( mInventoryDb.use == false ) throw ERROR_ITEM_USE_INVENTORY_FAIL; } // ItemDelInventory Method. void cPlayer::ItemDelInventory(ULONG_PTR socketContext, MSG_REQ_ITEM_DEL_INVENTORY* msg) { /*-- ¾ÆÀÌÅÛ »èÁ¦½Ã °Ë»çÇÒ ³»¿ëµé. */ if ( mInventoryDatabase ) throw ERROR_ITEM_DEL_INVENTORY_NOTYET; if ( GetStateDie( ) == true ) throw ERROR_ITEM_DEL_INVENTORY_FAIL; if ( IsInventoryRange(msg->number) == false ) throw ERROR_ITEM_DEL_INVENTORY_FAIL; TB_INVENTORY* inventory = SelectInventory( msg->number ); if ( IsInventory( inventory ) == false ) throw ERROR_ITEM_DEL_INVENTORY_FAIL; if ( inventory->apply != InventoryApplyNone ) throw ERROR_ITEM_DEL_INVENTORY_FAIL; // DATABASE - Àκ¥Å丮³» ¾ÆÀÌÅÛ »èÁ¦ ¿äû. HANDLE handle = NULL; INVENTORY_REMOVE* inventoryRemove = (INVENTORY_REMOVE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_INVENTORY_REMOVE ); inventoryRemove->idx = inventory->idx; inventoryRemove->number = inventory->number; mInventoryDb.remove = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, sizeof(INVENTORY_REMOVE) ); if ( mInventoryDb.remove == false ) throw ERROR_ITEM_DEL_INVENTORY_FAIL; } // ItemSwiInventory Method. void cPlayer::ItemSwiInventory(ULONG_PTR socketContext, MSG_REQ_ITEM_SWI_INVENTORY* /*msg*/) { /*-- ¾ÆÀÌÅÛ »èÁ¦½Ã °Ë»çÇÒ ³»¿ëµé. */ if ( GetStateDie( ) == true ) throw ERROR_ITEM_SWI_INVENTORY_FAIL; if ( GetState( ) == eOBJECT_STATE_ATTACK ) throw ERROR_ITEM_SWI_INVENTORY_FAIL; int activeWeapon = mItemActiveWeapon ^ ItemActiveSwitch; mItemActiveWeapon = (eItemActiveWeapon)activeWeapon; HANDLE handle = NULL; MSG_RES_ITEM_SWI_INVENTORY* sendMsg = (MSG_RES_ITEM_SWI_INVENTORY*)NETWORK2->GetMsgRoot( &handle, (PerSocketContext*)socketContext, NM_ITEM, NM_ITEM_SWI_INVENTORY_RES ); sendMsg->ErrorCode = ERROR_ITEM_SWI_INVENTORY_SUCCESS; sendMsg->activeWeapon = mItemActiveWeapon; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_ITEM_SWI_INVENTORY) ); } // ItemDivideInventory Method. void cPlayer::ItemDivideInventory(ULONG_PTR socketContext, MSG_REQ_ITEM_DIVIDE_INVENTORY* msg) { /*-- ¾ÆÀÌÅÛ ºÐȰ½Ã °Ë»çÇÒ ³»¿ëµé. */ if ( mInventoryDatabase ) throw ERROR_ITEM_DIVIDE_INVENTORY_NOTYET; if ( GetStateDie( ) == true ) throw ERROR_ITEM_DIVIDE_INVENTORY_FAIL; if ( msg->number1 == msg->number2 ) throw ERROR_ITEM_DIVIDE_INVENTORY_FAIL; if ( !IsInventoryRange( msg->number1 ) || !IsInventoryRange( msg->number2 ) ) throw ERROR_ITEM_DIVIDE_INVENTORY_FAIL; if ( IsInventoryEquip( msg->number1 ) || IsInventoryEquip( msg->number2 ) ) throw ERROR_ITEM_DIVIDE_INVENTORY_FAIL; if ( IsInventoryQuest( msg->number1 ) || IsInventoryQuest( msg->number2 ) ) throw ERROR_ITEM_DIVIDE_INVENTORY_FAIL; if ( IsInventoryWarehouse( msg->number1 ) != IsInventoryWarehouse( msg->number2 ) ) throw ERROR_ITEM_DIVIDE_INVENTORY_FAIL; TB_INVENTORY* inventory1 = SelectInventory( msg->number1 ); TB_INVENTORY* inventory2 = SelectInventory( msg->number2 ); if ( IsInventory( inventory1 ) == false || IsInventory( inventory2 ) == true ) throw ERROR_ITEM_DIVIDE_INVENTORY_FAIL; if ( inventory1->cash > 0 ) throw ERROR_ITEM_DIVIDE_INVENTORY_FAIL; if ( inventory1->apply != InventoryApplyNone ) throw ERROR_ITEM_DIVIDE_INVENTORY_FAIL; if ( (msg->divide < 1) || (msg->divide >= inventory1->count) ) throw ERROR_ITEM_DIVIDE_INVENTORY_FAIL; TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory1->itemDefineIdx ); if ( itemDefine == NULL ) throw ERROR_ITEM_DIVIDE_INVENTORY_FAIL; if ( itemDefine->licenseType == 1 ) throw ERROR_ITEM_DIVIDE_INVENTORY_FAIL; // DATABASE - Àκ¥Å丮³» ¾ÆÀÌÅÛ ºÐȰ ¿äû. HANDLE handle = NULL; INVENTORY_DIVIDE* inventoryDivide = (INVENTORY_DIVIDE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_INVENTORY_DIVIDE ); // Àκ¥Å丮 ºÐȰ. UpdateInventory( inventory1, (-msg->divide) ); // Àκ¥Å丮 »ý¼º. short shortCount=0; CreateInventory( itemDefine, msg->number2, msg->divide, &shortCount ); // DB °ª ÀÔ·Â. inventoryDivide->characterIdx = mObject.index; inventoryDivide->table[ 0 ] = (*inventory1); // Àκ¥Å丮 Á¤º¸ º¹»ç. inventoryDivide->table[ 1 ] = (*inventory2); // Àκ¥Å丮 Á¤º¸ º¹»ç. inventoryDivide->table[ 1 ].idx = 0; // Àӽà »ý¼º¹øÈ£ »èÁ¦. mInventoryDb.divide = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, sizeof(INVENTORY_DIVIDE) ); if ( mInventoryDb.divide == false ) throw ERROR_ITEM_DIVIDE_INVENTORY_FAIL; } // ItemMov2Inventory Method. void cPlayer::ItemMov2Inventory(ULONG_PTR socketContext, MSG_REQ_NPC_ITEM_MOV2_INVENTORY* msg) { /*-- ¾ÆÀÌÅÛ À̵¿½Ã(â°í & Àκ¥) °Ë»çÇÒ ³»¿ëµé. */ if ( mInventoryDatabase ) throw ERROR_ITEM_MOV2_INVENTORY_NOTYET; if ( GetStateDie( ) == true ) throw ERROR_ITEM_MOV2_INVENTORY_FAIL; if ( !IsInventoryRange( msg->number1 ) || !IsInventoryRange( msg->number2 ) ) throw ERROR_ITEM_MOV2_INVENTORY_FAIL; if ( IsInventoryEquip( msg->number1 ) || IsInventoryEquip( msg->number2 ) ) throw ERROR_ITEM_MOV2_INVENTORY_FAIL; if ( !IsInventoryWarehouse( msg->number1 ) && !IsInventoryWarehouse( msg->number2 ) ) throw ERROR_ITEM_MOV2_INVENTORY_FAIL; TB_INVENTORY* inventory1 = SelectInventory( msg->number1 ); TB_INVENTORY* inventory2 = SelectInventory( msg->number2 ); if ( inventory1->apply != InventoryApplyNone || inventory2->apply != InventoryApplyNone ) throw ERROR_ITEM_MOV2_INVENTORY_FAIL; if ( msg->count > inventory1->count ) throw ERROR_ITEM_MOV2_INVENTORY_FAIL; if ( msg->count == 0 ) msg->count = inventory1->count; TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory1->itemDefineIdx ); if ( itemDefine == NULL ) throw ERROR_ITEM_MOV2_INVENTORY_FAIL; /*-- Àκ¥Å丮 À̵¿Áß, º´ÇÕ Ã³¸®. */ if ( IsInventoryMerge( itemDefine, inventory1, inventory2 ) == true ) { mInventoryDb.merge = NETWORK2->InventoryMerge( (PerSocketContext*)socketContext ,inventory1->idx ,inventory2->idx ,itemDefine->capacity ); throw ERROR_ITEM_MOV2_INVENTORY_MERGE; } /*-- Àκ¥Å丮 À̵¿ ó¸®. */ int depth = 0; short except[3]; memset( except, 0, sizeof(except) ); (*except) = msg->number2; if ( IsInventoryMove( msg->number1, msg->number2, except, depth ) == false ) throw ERROR_ITEM_MOV2_INVENTORY_FAIL; /*-- 'depth' °¡ 0 Àϰæ¿ì move, ¾Æ´Ò°æ¿ì swap ó¸® ÇÑ´Ù. 'swap' °ú 'move' ´Â ó¸® ¼ø¼­°¡ ¼­·Î ´Ù¸£¹Ç·Î ÁÖÀÇÇØ¾ß ÇÑ´Ù. */ if ( depth != 0 ) { // Swap DB & SRV mInventoryDb.swap = NETWORK2->InventorySwap( (PerSocketContext*)socketContext ,inventory1->idx ,inventory1->number ,inventory2->idx ,inventory2->number ); if ( mInventoryDb.swap ) { InventorySwap( msg->number1, msg->number2 ); } throw ERROR_ITEM_MOV2_INVENTORY_SUCCESS; } else { // DATABASE - Àκ¥Å丮³» ¾ÆÀÌÅÛ À̵¿(â°í & Àκ¥) ¿äû. HANDLE handle = NULL; INVENTORY_MOVE2* inventoryMove2 = (INVENTORY_MOVE2*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_INVENTORY_MOVE2 ); unsigned long length = sizeof(INVENTORY_MOVE2) - sizeof(inventoryMove2->table); inventoryMove2->characterIdx = mObject.index; if ( msg->count == inventory1->count ) { InventoryMove( msg->number1, msg->number2 ); inventoryMove2->rowCount = 1; inventoryMove2->table[ 0 ] = (*inventory2); } else { // Àκ¥Å丮 ºÐȰ. UpdateInventory( inventory1, (-msg->count) ); // Àκ¥Å丮 »ý¼º. short shortCount=0; CreateInventory( itemDefine, msg->number2, msg->count, &shortCount ); // DB °ª ÀÔ·Â. inventoryMove2->rowCount = 2; inventoryMove2->table[ 0 ] = (*inventory1); // Àκ¥Å丮 Á¤º¸ º¹»ç. inventoryMove2->table[ 1 ] = (*inventory2); // Àκ¥Å丮 Á¤º¸ º¹»ç. inventoryMove2->table[ 1 ].idx = 0; // Àӽà »ý¼º¹øÈ£ »èÁ¦. } // Move DB & SRV length += (inventoryMove2->rowCount * sizeof(inventoryMove2->table)); mInventoryDb.move2 = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); if ( mInventoryDb.move2 == false ) throw ERROR_ITEM_MOV2_INVENTORY_FAIL; } } // ItemDisjointInventory Method. void cPlayer::ItemDisjointInventory(ULONG_PTR socketContext, MSG_REQ_ITEM_DISJOINT_INVENTORY* msg) { /*-- ¾ÆÀÌÅÛ ºÐÇØ½Ã °Ë»çÇÒ ³»¿ëµé. */ if ( mInventoryDatabase ) throw ERROR_ITEM_DISJOINT_INVENTORY_NOTYET; if ( GetStateDie( ) == true ) throw ERROR_ITEM_DISJOINT_INVENTORY_FAIL; if ( IsInventoryBag( msg->number ) == false ) throw ERROR_ITEM_DISJOINT_INVENTORY_FAIL; TB_INVENTORY* inventory = SelectInventory( msg->number ); if ( IsInventory( inventory ) == false ) throw ERROR_ITEM_DISJOINT_INVENTORY_FAIL; if ( inventory->apply != InventoryApplyNone ) throw ERROR_ITEM_DISJOINT_INVENTORY_FAIL; if( (int)mStatus2.mMaxWeight <= mItemWeight ) throw ERROR_ITEM_DISJOINT_INVENTORY_FAIL; TB_ITEM_DEFINE* disItemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if ( IsInventorySeal( disItemDefine, inventory ) == true ) throw ERROR_ITEM_DISJOINT_INVENTORY_LICENSE; TB_ITEM_DISJOINT* itemDisjoint = ITEMMANAGER->GetItemDisjoint( inventory->itemDefineIdx ); if ( itemDisjoint == NULL ) throw ERROR_ITEM_DISJOINT_INVENTORY_FAIL; // ºñ¿ëÈ®ÀÎ. if ( IsAddMoney( -(itemDisjoint->price) ) == false ) throw ERROR_ITEM_DISJOINT_INVENTORY_FAIL; // º¸»ó¾ÆÀÌÅÛ ¸ñ·Ï. eDisjointItem disjointItems[ MAX_DISJOINT_ITEM ]; unsigned int disjointItemsCount = 0; if ( itemDisjoint->itemDefineIndex1 > 0 ) { disjointItems[ disjointItemsCount ].itemDefineIndex = itemDisjoint->itemDefineIndex1; disjointItems[ disjointItemsCount ].inventoryCount = itemDisjoint->inventoryCount1; disjointItemsCount++; } if ( itemDisjoint->itemDefineIndex2 > 0 ) { disjointItems[ disjointItemsCount ].itemDefineIndex = itemDisjoint->itemDefineIndex2; disjointItems[ disjointItemsCount ].inventoryCount = itemDisjoint->inventoryCount2; disjointItemsCount++; } if ( itemDisjoint->itemDefineIndex3 > 0 ) { disjointItems[ disjointItemsCount ].itemDefineIndex = itemDisjoint->itemDefineIndex3; disjointItems[ disjointItemsCount ].inventoryCount = itemDisjoint->inventoryCount3; disjointItemsCount++; } if ( itemDisjoint->itemDefineIndex4 > 0 ) { disjointItems[ disjointItemsCount ].itemDefineIndex = itemDisjoint->itemDefineIndex4; disjointItems[ disjointItemsCount ].inventoryCount = itemDisjoint->inventoryCount4; disjointItemsCount++; } if ( itemDisjoint->itemDefineIndex5 > 0 ) { disjointItems[ disjointItemsCount ].itemDefineIndex = itemDisjoint->itemDefineIndex5; disjointItems[ disjointItemsCount ].inventoryCount = itemDisjoint->inventoryCount5; disjointItemsCount++; } if ( itemDisjoint->itemDefineIndex6 > 0 ) { disjointItems[ disjointItemsCount ].itemDefineIndex = itemDisjoint->itemDefineIndex6; disjointItems[ disjointItemsCount ].inventoryCount = itemDisjoint->inventoryCount6; disjointItemsCount++; } long itemDefineIndex = 0; long inventoryCount = 0; for( unsigned int i = 0; i < disjointItemsCount; i++ ) { itemDefineIndex = disjointItems[i].itemDefineIndex; inventoryCount = (long)disjointItems[i].inventoryCount; TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefineByIndex( itemDefineIndex ); if( IsMaxInventory( itemDefine, inventoryCount ) == true ) throw ERROR_ITEM_DISJOINT_INVENTORY_MAX_ITEM; } // º¸»ó¾ÆÀÌÅÛ °Ë»ç. if ( IsItemReward( inventory->idx, disjointItems, disjointItemsCount ) < disjointItemsCount ) throw ERROR_ITEM_DISJOINT_INVENTORY_FAIL; HANDLE handle = NULL; INVENTORY_DISJOINT* inventoryDisjoint = (INVENTORY_DISJOINT*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_INVENTORY_DISJOINT ); unsigned long length = sizeof(INVENTORY_DISJOINT) - sizeof(inventoryDisjoint->table); TB_INVENTORY* table = inventoryDisjoint->table; inventoryDisjoint->rowCount = 0; long& rowCount = inventoryDisjoint->rowCount; /*-- ij¸¯ÅÍ °íÀ¯¹øÈ£ */ inventoryDisjoint->characterIdx = mObject.index; /*-- ºÐÇØ ºñ¿ë */ inventoryDisjoint->characterMoney = -(itemDisjoint->price); /*-- ºÐÇØ ¾ÆÀÌÅÛ */ (*table) = (*inventory); table->count = (-inventory->count); table++; rowCount++; // ¾ÆÀÌÅÛ ¼± »èÁ¦ - º¸»ó ¾ÆÀÌÅÛ °ø°£ È®º¸ RemoveInventory( inventory ); /*-- º¸»ó ¾ÆÀÌÅÛ */ eDisjointItem* items = disjointItems; for ( unsigned int i0 = 0; i0 < disjointItemsCount; i0++, items++ ) { TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefineByIndex( items->itemDefineIndex ); u_short remainCount = (u_short)items->inventoryCount; if ( itemDefine != NULL && remainCount > 0 ) { TB_INVENTORY* inventory; short shortCount; short number; // ¾ÆÀÌÅÛ ºÐÇØ º¸»ó. °ãÄ¡±â °Ë»ç ¹× ó¸®. if ( FindFirstInventory( itemDefine, &number, remainCount, &shortCount, true ) == true ) { do { inventory = SelectInventory( number ); shortCount = UpdateInventory( inventory, remainCount ); remainCount = remainCount - shortCount; // INVENTORY_IDX, ITEM_DEFINE_INDEX, INVENTORY_NUMBER, INVENTORY_COUNT... (*table) = (*inventory); table->count = shortCount; table++; rowCount++; } while ( FindNextInventory( itemDefine, &(++number), remainCount, &shortCount, true ) == true ); } // ¾ÆÀÌÅÛ ºÐÇØ º¸»ó. »ý¼º °Ë»ç ¹× µî·Ï. if ( FindFirstInventory( itemDefine, &number, remainCount, &shortCount, false ) == true ) { do { CreateInventory( itemDefine, number, remainCount, &(shortCount=0) ); remainCount = remainCount - shortCount; // INVENTORY_IDX, ITEM_DEFINE_INDEX, INVENTORY_NUMBER, INVENTORY_COUNT... table->idx = 0; table->itemDefineIdx = itemDefine->idx; table->itemDefineIndex = itemDefine->index; table->number = number; table->count = shortCount; table++; rowCount++; } while ( FindNextInventory( itemDefine, &(++number), remainCount, &shortCount, false ) == true ); } } } length += (inventoryDisjoint->rowCount * sizeof(inventoryDisjoint->table)); mInventoryDb.disjoint = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); if ( mInventoryDb.disjoint == false ) throw ERROR_ITEM_DISJOINT_INVENTORY_FAIL; } // ItemPutCardInventory Method. void cPlayer::ItemPutCardInventory(ULONG_PTR socketContext, MSG_REQ_ITEM_PUT_CARD_INVENTORY* msg) { /*-- ¾ÆÀÌÅÛ Ä«µåÀåÂø½Ã °Ë»çÇÒ ³»¿ëµé. */ if ( mInventoryDatabase ) throw ERROR_ITEM_PUT_CARD_INVENTORY_NOTYET; if ( GetStateDie( ) == true ) throw ERROR_ITEM_PUT_CARD_INVENTORY_FAIL; if ( !IsInventoryBag( msg->number1 ) || !IsInventoryBag( msg->number2 ) ) throw ERROR_ITEM_PUT_CARD_INVENTORY_FAIL; TB_INVENTORY* inventory1 = SelectInventory( msg->number1 ); TB_INVENTORY* inventory2 = SelectInventory( msg->number2 ); if ( IsInventory( inventory1 ) == false || IsInventory( inventory2 ) == false ) throw ERROR_ITEM_PUT_CARD_INVENTORY_FAIL; if ( inventory1->apply != InventoryApplyNone || inventory2->apply != InventoryApplyNone ) throw ERROR_ITEM_PUT_CARD_INVENTORY_FAIL; if ( msg->cardSlot < MIN_CARD_SLOT || msg->cardSlot > MAX_CARD_SLOT ) throw ERROR_ITEM_PUT_CARD_INVENTORY_FAIL; // ÀåÂø½½·Ô °Ë»ç. TB_ITEM_DEFINE* itemDefine1 = ITEMMANAGER->GetItemDefine( inventory1->itemDefineIdx ); if ( IsInventorySeal( itemDefine1, inventory1 ) == true ) throw ERROR_ITEM_PUT_CARD_INVENTORY_LICENSE; TB_ITEM_CARD_SLOT* itemCardSlot = ITEMMANAGER->GetItemCardSlot( inventory1->itemDefineIdx ); if ( itemCardSlot == NULL ) throw ERROR_ITEM_PUT_CARD_INVENTORY_FAIL; // ÀåÂøÄ«µå °Ë»ç. TB_ITEM_DEFINE* itemDefine2 = ITEMMANAGER->GetItemDefine( inventory2->itemDefineIdx ); if ( itemDefine2 == NULL ) throw ERROR_ITEM_PUT_CARD_INVENTORY_FAIL; if ( itemDefine2->type != ITEM_CARD ) throw ERROR_ITEM_PUT_CARD_INVENTORY_FAIL; if ( IsInventorySeal( itemDefine2, inventory2 ) == true ) throw ERROR_ITEM_PUT_CARD_INVENTORY_LICENSE; if ( !IsItemLimit( inventory2->itemDefineIdx ) ) throw ERROR_ITEM_PUT_CARD_INVENTORY_FAIL; switch ( msg->cardSlot ) { case ITEM_CARD_SLOT_1: if ( !(ItemSlotType2Mtr( itemCardSlot->slot1 ) & ItemCardType2Mtr( itemDefine2->subType )) ) throw ERROR_ITEM_PUT_CARD_INVENTORY_FAIL; break; case ITEM_CARD_SLOT_2: if ( !(ItemSlotType2Mtr( itemCardSlot->slot2 ) & ItemCardType2Mtr( itemDefine2->subType )) ) throw ERROR_ITEM_PUT_CARD_INVENTORY_FAIL; break; case ITEM_CARD_SLOT_3: if ( !(ItemSlotType2Mtr( itemCardSlot->slot3 ) & ItemCardType2Mtr( itemDefine2->subType )) ) throw ERROR_ITEM_PUT_CARD_INVENTORY_FAIL; break; case ITEM_CARD_SLOT_4: if ( !(ItemSlotType2Mtr( itemCardSlot->slot4 ) & ItemCardType2Mtr( itemDefine2->subType )) ) throw ERROR_ITEM_PUT_CARD_INVENTORY_FAIL; break; case ITEM_CARD_SLOT_5: if ( !(ItemSlotType2Mtr( itemCardSlot->slot5 ) & ItemCardType2Mtr( itemDefine2->subType )) ) throw ERROR_ITEM_PUT_CARD_INVENTORY_FAIL; break; default: throw ERROR_ITEM_PUT_CARD_INVENTORY_FAIL; } HANDLE handle = NULL; INVENTORY_PUT_CARD* inventoryPutCard = (INVENTORY_PUT_CARD*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_INVENTORY_PUT_CARD ); inventoryPutCard->idx1 = inventory1->idx; inventoryPutCard->cardSlot = msg->cardSlot; inventoryPutCard->idx2 = inventory2->idx; inventoryPutCard->itemDefineIndex = inventory2->itemDefineIndex; mInventoryDb.putCard = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, sizeof(INVENTORY_PUT_CARD) ); if ( mInventoryDb.putCard == false ) throw ERROR_ITEM_PUT_CARD_INVENTORY_FAIL; } // ItemChangeInventory Method. void cPlayer::ItemChangeInventory(ULONG_PTR socketContext, MSG_REQ_ITEM_CHANGE_INVENTORY* msg) { /*-- ¾ÆÀÌÅÛ Ã¼ÀÎÁö °Ë»çÇÒ ³»¿ëµé. */ if ( mInventoryDatabase ) throw ERROR_ITEM_PUT_CARD_INVENTORY_NOTYET; if ( GetStateDie( ) == true ) throw ERROR_ITEM_CHANGE_INVENTORY_FAIL; if ( IsInventoryBag( msg->number ) == false ) throw ERROR_ITEM_CHANGE_INVENTORY_FAIL; TB_INVENTORY* inventory = SelectInventory( msg->number ); if ( IsInventory( inventory ) == false ) throw ERROR_ITEM_CHANGE_INVENTORY_FAIL; if ( inventory->apply != InventoryApplyNone ) throw ERROR_ITEM_CHANGE_INVENTORY_FAIL; TB_ITEM_DEFINE* itemBox = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if ( itemBox == NULL ) throw ERROR_ITEM_CHANGE_INVENTORY_FAIL; if ( IsInventorySeal( itemBox, inventory ) == true ) throw ERROR_ITEM_CHANGE_INVENTORY_LICENSE; /*-- Item Limit Table(TB_ITEM_LIMIT) Àû¿ë --*/ if ( !IsItemLimit( inventory->itemDefineIdx ) ) throw ERROR_ITEM_CHANGE_INVENTORY_FAIL; if( (int)mStatus2.mMaxWeight <= mItemWeight ) throw ERROR_ITEM_CHANGE_INVENTORY_FAIL; TB_ITEM_CHANGE* itemChange = ITEMMANAGER->GetItemChange( inventory->itemDefineIdx ); if ( itemChange == NULL ) throw ERROR_ITEM_CHANGE_INVENTORY_FAIL; long money = itemChange->maxMoney - itemChange->minMoney; long randomValue = (long)(RANDOMTABLE->Get( mItemChangeSeed ) * 1000000); if ( money > 0 ) money = itemChange->minMoney + (rand( ) % money) + 1; else money = itemChange->minMoney; // ÃÖ´ë º¸À¯±Ý¾×. if ( IsAddMoney( money ) == false ) throw ERROR_ITEM_CHANGE_INVENTORY_HAVE_MONEY; // üÀÎÁö È®·ü Àû¿ë. long* itemChangeIndex = itemChange->itemDefineIndex; short* itemChangeCount = itemChange->itemCount; long* changeRate = itemChange->changeRate; int itemChangeItems = 0; int itemChnageData[ MAX_ITEM_CHANGE_DATA ]; int* itemChangePtr = itemChnageData; for ( int i = 0; i < itemChange->row; i++ ) { if ( (*itemChangeIndex) != 0 && (*itemChangeCount) != 0 && randomValue <= (*changeRate) ) { (*itemChangePtr) = i; itemChangePtr++; itemChangeItems++; } itemChangeIndex++; itemChangeCount++; changeRate++; } // ·¥´ýÇÏ°Ô µÚ½â±â. for ( int i = 0, s, t; i < itemChangeItems; i++ ) { s = (int)(rand( ) % itemChangeItems); t = itemChnageData[ i ]; itemChnageData[ i ] = itemChnageData[ s ]; itemChnageData[ s ] = t; } // ÃÖ´ë¼ö·® º¸Á¤. if ( itemChangeItems > itemChange->rate ) { itemChangeItems = itemChange->rate; } // Àκ¥Å丮 ÃÖ´ë ¼ö·® °Ë»ç. long itemDefineIndex = 0; long inventoryCount = 0; for( long i = 0; i < itemChangeItems; i++ ) { itemDefineIndex = *(itemChange->itemDefineIndex + itemChnageData[ i ]); inventoryCount = (long)*(itemChange->itemCount + itemChnageData[ i ]); TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefineByIndex( itemDefineIndex ); if( IsMaxInventory( itemDefine, inventoryCount ) == true ) throw ERROR_ITEM_CHANGE_INVENTORY_MAX_ITEM; } HANDLE handle = NULL; INVENTORY_CHANGE* inventoryChange = (INVENTORY_CHANGE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_INVENTORY_CHANGE ); TB_INVENTORY* table = inventoryChange->table; unsigned long length = sizeof(INVENTORY_CHANGE) - sizeof(inventoryChange->table); inventoryChange->rowCount = 0; long& rowCount = inventoryChange->rowCount; /*-- ij¸¯ÅÍ °íÀ¯¹øÈ£ --*/ inventoryChange->characterIdx = mObject.index; /*-- ȹµæ ºñ¿ë -- */ inventoryChange->characterMoney = money; /*-- üÀÎÁö ¾ÆÀÌÅÛ --*/ (*table) = (*inventory); table->count = -1; inventory->count = inventory->count -1; table++; rowCount++; if ( inventory->count <= 0 ) { RemoveInventory( inventory ); } /*-- º¸»ó ¾ÆÀÌÅÛ */ for ( long i0 = 0; i0 < itemChangeItems; i0++ ) { long itemDefineIndex = *(itemChange->itemDefineIndex + itemChnageData[ i0 ]); short remainCount = *(itemChange->itemCount + itemChnageData[ i0 ]); TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefineByIndex( itemDefineIndex ); if ( itemDefine != NULL && remainCount > 0 ) { TB_INVENTORY* inventory; short shortCount; short number; // ¾ÆÀÌÅÛ º¯È¯ º¸»ó. °ãÄ¡±â °Ë»ç ¹× ó¸®. if ( FindFirstInventory( itemDefine, &number, remainCount, &shortCount, true ) == true ) { do { inventory = SelectInventory( number ); shortCount = UpdateInventory( inventory, remainCount ); remainCount = remainCount - shortCount; // INVENTORY_IDX, ITEM_DEFINE_INDEX, INVENTORY_NUMBER, INVENTORY_COUNT... (*table) = (*inventory); table->count = shortCount; table++; rowCount++; } while ( FindNextInventory( itemDefine, &(++number), remainCount, &shortCount, true ) == true ); } // ¾ÆÀÌÅÛ º¯È¯ º¸»ó. »ý¼º °Ë»ç ¹× µî·Ï. if ( FindFirstInventory( itemDefine, &number, remainCount, &shortCount, false ) == true ) { do { inventory = CreateInventory( itemDefine, number, remainCount, &(shortCount=0) ); remainCount = remainCount - shortCount; // INVENTORY_IDX, ITEM_DEFINE_INDEX, INVENTORY_NUMBER, INVENTORY_COUNT... (*table) = (*inventory); table->idx = 0; table->count = shortCount; table++; rowCount++; } while ( FindNextInventory( itemDefine, &(++number), remainCount, &shortCount, false ) == true ); } } } length += (sizeof(inventoryChange->table) * rowCount); mInventoryDb.change = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); if ( mInventoryDb.change == false ) throw ERROR_ITEM_CHANGE_INVENTORY_FAIL; } // ItemCashInventory Method. void cPlayer::ItemCashInventory( ULONG_PTR socketContext ) { if( mInventoryDatabase ) throw ERROR_ITEM_CASH_LIST_FAIL; HANDLE handle = NULL; INVENTORY_SELECT* inventorySelect = (INVENTORY_SELECT*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_INVENTORY_CASH_SELECT ); unsigned long length = sizeof(INVENTORY_SELECT) - sizeof(inventorySelect->table); inventorySelect->characterIdx = mObject.index; mInventoryDb.cash = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); if( mInventoryDb.cash == false ) throw ERROR_ITEM_CASH_LIST_FAIL; } // ItemSell Method. void cPlayer::ItemSell(ULONG_PTR socketContext, MSG_REQ_NPC_ITEM_SELL* msg) { /*-- ¾ÆÀÌÅÛ ÆÇ¸Å½Ã °Ë»çÇÒ ³»¿ëµé. */ if ( mInventoryDatabase ) throw ERROR_ITEM_SELL_NOTYET; if ( GetStateDie( ) == true ) throw ERROR_ITEM_SELL_FAIL; if ( IsInventoryBag( msg->inventoryNumber ) == false ) throw ERROR_ITEM_SELL_FAIL; // Àκ¥Å丮 ³»¿ë È®ÀÎ. TB_INVENTORY* inventory = SelectInventory( msg->inventoryNumber ); if ( IsInventory( inventory ) == false ) throw ERROR_ITEM_SELL_FAIL; if ( msg->count < 1 || msg->count > inventory->count ) throw ERROR_ITEM_SELL_FAIL; // ¾ÆÀÌÅÛ Á¤ÀÇ È®ÀÎ. TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); long sellType = ItemSellNone; long sellPrice = 0; if ( itemDefine == NULL ) throw ERROR_ITEM_SELL_FAIL; // ¹ÌÀÎÁõ ¾ÆÀÌÅÛÀº »óÁ¡°Å·¡°¡ ¹«Á¶°Ç ºÒ°¡´É if( itemDefine->licenseType == 1 ) throw ERROR_ITEM_SELL_EXCHANGE; if ( !(itemDefine->sellPrice > 0) ) throw ERROR_ITEM_SELL_FAIL; switch ( itemDefine->sellType ) { case ItemSellNone: throw ERROR_ITEM_SELL_FAIL; case ItemSellMoney: case ItemSellPvp: case ItemSellTarot: sellPrice = itemDefine->sellPrice * msg->count; if( IsAddMoney( sellPrice ) == false ) throw ERROR_ITEM_SELL_HAVE_MONEY; break; default: sellType = itemDefine->sellType; break; } // ¾ÆÀÌÅÛ - ¾ÆÀÌÅÛ ½Àµæ°Ë»ç(Ex: ÄÚÀÎ). if ( sellType != ItemSellNone ) { if ( CheckInventory( sellType, (itemDefine->sellPrice * msg->count) ) == false ) throw ERROR_ITEM_SELL_FAIL; // ÆÇ¸Å°¡´É ¼ö·® ¿À·ùÀϰæ¿ì. } // DATABASE - Àκ¥Å丮³» ¾ÆÀÌÅÛ ÆÇ¸Å ¿äû. HANDLE handle = NULL; ITEM_SELL* itemSell = (ITEM_SELL*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_SELL ); long& rowCount = itemSell->rowCount; TB_INVENTORY* table = itemSell->table; long length = sizeof(ITEM_SELL) - sizeof(itemSell->table); itemSell->characterIdx = mObject.index; itemSell->npcIdx = msg->npcIdx; itemSell->sellType = itemDefine->sellType; itemSell->sellPrice = (+sellPrice); rowCount = 1; (*table) = (*inventory); table->count = (-msg->count); table++; if ( inventory->count == msg->count ) RemoveInventory( inventory ); // ÆÇ¸Åº¸»ó ¾ÆÀÌÅÛ - ½ÀµæÃ³¸®. if ( sellType != ItemSellNone ) { TB_ITEM_DEFINE* tempDfn = ITEMMANAGER->GetItemDefine( sellType ); short remainCount = (short)(itemDefine->sellPrice * msg->count); short shortCount; short number; if ( tempDfn != NULL ) { // ¾ÆÀÌÅÛ ÆÇ¸Åº¸»ó ¾ÆÀÌÅÛ1. °ãÄ¡±â °Ë»ç ¹× ó¸®. if ( FindFirstInventory( tempDfn, &number, remainCount, &shortCount, true ) == true ) { TB_INVENTORY* tempInv; do { tempInv = SelectInventory( number ); shortCount = UpdateInventory( tempInv, remainCount ); remainCount = remainCount - shortCount; (*table) = (*tempInv); table->count = (+shortCount); table++; rowCount++; } while ( FindNextInventory( tempDfn, &(++number), remainCount, &shortCount, true ) == true ); } // ¾ÆÀÌÅÛ ÆÇ¸Åº¸»ó ¾ÆÀÌÅÛ2. »ý¼º °Ë»ç ¹× µî·Ï. if ( FindFirstInventory( tempDfn, &number, remainCount, &shortCount, false ) == true ) { do { CreateInventory( tempDfn, number, remainCount, &(shortCount=0) ); remainCount = remainCount - shortCount; table->idx = 0; table->itemDefineIdx = tempDfn->idx; table->itemDefineIndex = tempDfn->index; table->count = (+shortCount); table->number = number; table->seal = tempDfn->licenseType; table++; rowCount++; } while ( FindNextInventory( itemDefine, &(++number), remainCount, &shortCount, false ) == true ); } } } length += (rowCount * sizeof(itemSell->table)); mInventoryDb.sell = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); if ( mInventoryDb.sell == false ) throw ERROR_ITEM_SELL_FAIL; } // ItemBuy Method. void cPlayer::ItemBuy( ULONG_PTR socketContext, MSG_REQ_NPC_ITEM_BUY* msg) { /*-- ¾ÆÀÌÅÛ ±¸ÀԽà °Ë»çÇÒ ³»¿ëµé. */ if ( mInventoryDatabase ) throw ERROR_ITEM_BUY_NOTYET; // ij¸¯ÅÍ »óÅ °Ë»ç. if ( GetStateDie( ) == true ) throw ERROR_ITEM_BUY_FAIL; // Èñ¸ÁÇÏ´Â ±¸¸Å¼ö·® °Ë»ç. if ( !(msg->count > 0) ) throw ERROR_ITEM_BUY_FAIL; cNpc* pNpc = OBJECTMANAGER->GetNpc( msg->npcIdx ); if( !pNpc ) throw ERROR_QUEST_ADD_FAIL; unsigned int npcId = pNpc->GetRaceGender(); /// npc¿¡ ÇØ´çÇÏ´Â item È®ÀÎ cItemNpcStore* pItemStore = ITEMSCRIPT->GetItemNpcStore( npcId ); if( pItemStore == NULL ) throw ERROR_ITEM_BUY_NPC; if( pItemStore->IsItemIdx( msg->tabIdx, msg->itemDefineIndex ) == false ) throw ERROR_ITEM_BUY_NPC; /// npc »óÁ¡ tab Á¤º¸ sNpcItemData* itemStore = NULL; unsigned long priceRate = 0; /// ÆÇ¸Å ±Ý¾×/¼¼·ÂÆ÷ÀÎÆ® ºñÀ² unsigned char storeForce = 0; /// 0:Å׸£, 1/2/3/4:¼¼·Â itemStore = pItemStore->GetNpcItemData( msg->tabIdx ); if( itemStore == NULL ) throw ERROR_ITEM_BUY_NPC; priceRate = itemStore->mRate; storeForce = itemStore->mForce; // ¾ÆÀÌÅÛ Á¤ÀÇ Å×ÀÌºí °Ë»ç. TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefineByIndex( msg->itemDefineIndex ); long buyType = ItemBuyNone; long buyPrice = 0; bool payItem = false; PerItemCount* itemCount = NULL; if ( itemDefine == NULL ) throw ERROR_ITEM_BUY_FAIL; if ( !(itemDefine->buyPrice > 0) ) throw ERROR_ITEM_BUY_MONEY; if( IsMaxInventory( itemDefine, msg->count ) == true ) throw ERROR_ITEM_BUY_MAX_ITEM; buyPrice = (long)( itemDefine->buyPrice * ( priceRate * 0.01 ) ) * msg->count; switch ( itemDefine->buyType ) { case ItemBuyNone: throw ERROR_ITEM_BUY_FAIL; case ItemBuyMoney: if ( (ULONG)buyPrice > mMoney ) throw ERROR_ITEM_BUY_MONEY; break; case ItemBuyPvp: if ( (ULONG)buyPrice > GetPvPPoint( storeForce ) ) throw ERROR_ITEM_BUY_PVP_POINT; break; case ItemBuyTarot: if ( (ULONG)buyPrice > mMoney ) throw ERROR_ITEM_BUY_TAROT_POINT; break; default: buyType = itemDefine->buyType; itemCount = ITEMCOUNTPOOL->SearchItemCount( &mItemCountRoot, buyType ); if ( itemCount != NULL ) { if ( itemCount->bag < buyPrice ) throw ERROR_ITEM_BUY_FAIL; } else throw ERROR_ITEM_BUY_FAIL; payItem = true; break; } // ±¸ÀÔ°¡´É °Ë»ç. if ( CheckInventory( msg->itemDefineIndex, msg->count ) == false ) throw ERROR_ITEM_BUY_FAIL; // DATABASE - ¾ÆÀÌÅÛ ±¸¸Å ¿äû. HANDLE handle = NULL; ITEM_BUY* itemBuy = (ITEM_BUY*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_BUY ); TB_INVENTORY* table = itemBuy->table; u_long length = sizeof(ITEM_BUY) - sizeof(itemBuy->table); BYTE& rowCount = (BYTE&)itemBuy->rowCount; u_short remainCount = msg->count; itemBuy->characterIdx = mObject.index; itemBuy->npcIdx = msg->npcIdx; itemBuy->buyType = itemDefine->buyType; itemBuy->buyPrice = (-buyPrice); itemBuy->buyStore = storeForce; TB_INVENTORY* inventory; short number; short shortCount; // ¾ÆÀÌÅÛ ±¸¸Å. °ãÄ¡±â °Ë»ç ¹× ó¸®. if ( FindFirstInventory( itemDefine, &number, remainCount, &shortCount, true ) == true ) { do { inventory = SelectInventory( number ); shortCount = UpdateInventory( inventory, remainCount ); remainCount = remainCount - shortCount; (*table) = (*inventory); table->count = (+shortCount); table++; rowCount++; } while ( FindNextInventory( itemDefine, &(++number), remainCount, &shortCount, true ) == true ); } // ¾ÆÀÌÅÛ ±¸¸Å. »ý¼º °Ë»ç ¹× µî·Ï. if ( FindFirstInventory( itemDefine, &number, remainCount, &shortCount, false ) == true ) { do { CreateInventory( itemDefine, number, remainCount, &(shortCount=0) ); remainCount = remainCount - shortCount; table->idx = 0; table->itemDefineIdx = itemDefine->idx; table->itemDefineIndex = itemDefine->index; table->count = (+shortCount); table->number = number; table->seal = itemDefine->licenseType; table++; rowCount++; } while ( FindNextInventory( itemDefine, &(++number), remainCount, &shortCount, false ) == true ); } if ( payItem == true ) { TB_INVENTORY* tempInv; short remainCount; tempInv = SelectInventory( INVENTORY_BAG_BEGIN ); remainCount = (short)(itemDefine->buyPrice * msg->count); // ¾ÆÀÌÅÛ Â÷°¨(Ex: ÄÚÀÎ). for ( short i = INVENTORY_BAG_BEGIN; (i <= mHeroInfo.BagEnd) && (remainCount > 0); i++, tempInv++ ) { if ( buyType == tempInv->itemDefineIndex ) { short shortCount; shortCount = UpdateInventory( tempInv, (-remainCount) ); remainCount = remainCount + shortCount; (*table) = (*tempInv); table->count = shortCount; table++; rowCount++; } } } if ( itemBuy->rowCount > 0 ) { length += (itemBuy->rowCount * sizeof(itemBuy->table)); mInventoryDb.buy = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); if ( mInventoryDb.buy == false ) throw ERROR_ITEM_BUY_FAIL; } else { NETWORK2->ReleaseSQL( handle, length ); throw ERROR_ITEM_BUY_FAIL; } } // ItemCollect Method void cPlayer::ItemCollect(ULONG_PTR socketContext, MSG_REQ_ITEM_COLLECT* msg) { /*-- ¾ÆÀÌÅÛ ¼öÁý½Ã °Ë»çÇÒ ³»¿ëµé. */ if ( mInventoryDatabase ) throw ERROR_ITEM_COLLECT_NOTYET; if ( GetStateDie( ) == true ) throw ERROR_ITEM_COLLECT_FAIL; if ( GetStateStop() == eSTOP_SELFTAROT || GetStateStop() == eSTOP_OPENTAROT ) throw ERROR_ITEM_COLLECT_STATE; if ( IsInventoryBag( msg->number1 ) == false ) throw ERROR_ITEM_COLLECT_FAIL; if ( IsInventoryCollect( msg->number2 ) == false ) throw ERROR_ITEM_COLLECT_FAIL; // Àκ¥Å丮 ³»¿ë È®ÀÎ. TB_INVENTORY* inventory1 = SelectInventory( msg->number1 ); TB_INVENTORY* inventory2 = SelectInventory( msg->number2 ); if ( IsInventory( inventory1 ) == false ) throw ERROR_ITEM_COLLECT_FAIL; // ¾ÆÀÌÅÛ Å×À̺í È®ÀÎ. TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory1->itemDefineIdx ); if ( itemDefine == NULL ) throw ERROR_ITEM_COLLECT_FAIL; if ( IsInventorySeal( itemDefine, inventory1 ) == true ) throw ERROR_ITEM_COLLECT_LICENSE; /*-- Item Limit Table(TB_ITEM_LIMIT) Àû¿ë --*/ if ( !IsItemLimit( inventory1->itemDefineIdx ) ) throw ERROR_ITEM_COLLECT_FAIL; if ( itemDefine->type == ITEM_SPREAD ) { switch ( itemDefine->subType ) { case ITEM_SPREAD_NORMAL: if ( msg->number2 < INVENTORY_SPREAD_NORMAL_BEGIN || msg->number2 > INVENTORY_SPREAD_NORMAL_END ) throw ERROR_ITEM_COLLECT_FAIL; break; case ITEM_SPREAD_SILVER: if ( msg->number2 < INVENTORY_SPREAD_SILVER_BEGIN || msg->number2 > INVENTORY_SPREAD_SILVER_END ) throw ERROR_ITEM_COLLECT_FAIL; break; case ITEM_SPREAD_GOLD: if ( msg->number2 < INVENTORY_SPREAD_GOLD_BEGIN || msg->number2 > INVENTORY_SPREAD_GOLD_END ) throw ERROR_ITEM_COLLECT_FAIL; break; case ITEM_SPREAD_DIA: if ( msg->number2 < INVENTORY_SPREAD_DIA_BEGIN || msg->number2 > INVENTORY_SPREAD_DIA_END ) throw ERROR_ITEM_COLLECT_FAIL; break; default : throw ERROR_ITEM_COLLECT_FAIL; break; } } else throw ERROR_ITEM_COLLECT_FAIL; HANDLE handle = NULL; ITEM_COLLECT* itemCollect = (ITEM_COLLECT*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_COLLECT ); itemCollect->characterIdx = mObject.index; // itemCollect->table : [0:±âÁ¸Ä«µå/1:µî·ÏÄ«µå/2:»èÁ¦Ä«µå] if ( IsInventory( inventory2 ) == true ) { // ±âÁ¸ µî·ÏµÈ Ä«µå°¡ ÀÖÀ¸¸é »èÁ¦ itemCollect->table[ 2 ] = (*inventory2); RemoveInventory( inventory2 ); } if ( inventory1->count == 1 ) { itemCollect->table[ 0 ] = (*inventory1); itemCollect->table[ 0 ].count = 0; itemCollect->table[ 1 ] = (*inventory1); itemCollect->table[ 1 ].number = msg->number2; InventoryMove( msg->number1, msg->number2 ); } else { short shortCount = 0; TB_INVENTORY* inventory3 = CreateInventory( itemDefine, msg->number2, 1, &shortCount ); inventory3->idx = 0; UpdateInventory( inventory1, -1 ); itemCollect->table[ 0 ] = (*inventory1); itemCollect->table[ 1 ] = (*inventory3); } mInventoryDb.collect = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, sizeof(ITEM_COLLECT) ); if ( mInventoryDb.collect == false ) throw ERROR_ITEM_COLLECT_FAIL; } // ItemCollectChange Method void cPlayer::ItemCollectChange(ULONG_PTR socketContext, MSG_REQ_COLLECT_CARD_CHANGE* msg) { if ( mInventoryDatabase ) throw ERROR_ITEM_COLLECT_CARD_CHANGE_NOTYET; if ( GetStateDie( ) == true ) throw ERROR_ITEM_COLLECT_CARD_CHANGE_FAIL; if ( GetStateStop() == eSTOP_SELFTAROT || GetStateStop() == eSTOP_OPENTAROT ) throw ERROR_ITEM_COLLECT_CARD_CHANGE_FAIL; if( (int)mStatus2.mMaxWeight <= mItemWeight ) throw ERROR_ITEM_COLLECT_CARD_CHANGE_FAIL; short invenBegin = INVENTORY_TAROT_NORMAL_BEGIN; // Àκ¥Å丮 ´ë¿ª short invenEnd = INVENTORY_TAROT_NORMAL_END; // Àκ¥Å丮 ´ë¿ª long changeItem = -1; // üÀÎÁö ¾ÆÀÌÅÛ // µî±Þ¿¡ µû¸¥ Àκ¥Å丮 ´ë¿ª switch ( msg->tarotClass ) { case eTAROT_CLASS_NORMAL: invenBegin = INVENTORY_TAROT_NORMAL_BEGIN; invenEnd = INVENTORY_TAROT_NORMAL_END; changeItem = TAROT_CHANGE_ITEM_SILVER; break; case eTAROT_CLASS_SILVER: invenBegin = INVENTORY_TAROT_SILVER_BEGIN; invenEnd = INVENTORY_TAROT_SILVER_END; changeItem = TAROT_CHANGE_ITEM_GOLD; break; case eTAROT_CLASS_GOLD: invenBegin = INVENTORY_TAROT_GOLD_BEGIN; invenEnd = INVENTORY_TAROT_GOLD_END; changeItem = TAROT_CHANGE_ITEM_DIA; break; default : throw ERROR_ITEM_COLLECT_CARD_CHANGE_CLASS; break; } // Ÿ·ÎÄ«µå 22Àå üũ int tarotCount = 0; for ( short tarotNumber = invenBegin; tarotNumber <= invenEnd; tarotNumber++ ) { TB_INVENTORY* inventory = SelectInventory( tarotNumber ); if ( IsInventory( inventory ) ) { tarotCount++; } inventory++; } if ( tarotCount != MAX_TAROT_CARDS ) throw ERROR_ITEM_COLLECT_CARD_CHANGE_COUNT; // üÀÎÁö ¾ÆÀÌÅÛ »ý¼º TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefineByIndex( changeItem ); if ( itemDefine == NULL ) throw ERROR_ITEM_COLLECT_CARD_CHANGE_FAIL; if ( IsMaxInventory( itemDefine, 1 ) == true ) throw ERROR_ITEM_COLLECT_CARD_CHANGE_MAX_ITEM; HANDLE handle = NULL; ITEM_COLLECT_CHANGE* itemCollect = (ITEM_COLLECT_CHANGE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_COLLECT_CHANGE ); TB_INVENTORY* table = itemCollect->table; u_long length = sizeof(ITEM_COLLECT_CHANGE) - sizeof(itemCollect->table); itemCollect->rowCount = 0; long& rowCount = itemCollect->rowCount; // üÀÎÁö ¾ÆÀÌÅÛ »ý¼º TB_INVENTORY* inventory = NULL; long itemCount = 0; short remainCount = 1; short shortCount = 0; short itemNumber = 0; // ¾ÆÀÌÅÛ Áݱâ. °ãÄ¡±â °Ë»ç ¹× ó¸®. if ( FindFirstInventory( itemDefine, &itemNumber, remainCount, &shortCount, true ) == true ) { do { inventory = SelectInventory( itemNumber ); shortCount = UpdateInventory( inventory, remainCount ); remainCount = remainCount - shortCount; itemCollect->changeItem = (*inventory); itemCount++; } while ( FindNextInventory( itemDefine, &(++itemNumber), remainCount, &shortCount, true ) == true ); } // ¾ÆÀÌÅÛ Áݱâ. »ý¼º °Ë»ç ¹× µî·Ï. if ( FindFirstInventory( itemDefine, &itemNumber, remainCount, &shortCount, false ) == true ) { do { CreateInventory( itemDefine, itemNumber, remainCount, &(shortCount=0) ); remainCount = remainCount - shortCount; itemCollect->changeItem.idx = 0; itemCollect->changeItem.itemDefineIdx = itemDefine->idx; itemCollect->changeItem.itemDefineIndex = itemDefine->index; itemCollect->changeItem.number = itemNumber; itemCollect->changeItem.count = shortCount; itemCollect->changeItem.seal = itemDefine->licenseType; itemCount++; } while ( FindNextInventory( itemDefine, &(++itemNumber), remainCount, &shortCount, false ) == true ); } if ( itemCount != 1 ) throw ERROR_ITEM_COLLECT_CARD_CHANGE_FULL; // 22ÀåÀÇ Å¸·ÎÄ«µå »ç¿ë for ( short tarotNumber = invenBegin; tarotNumber <= invenEnd; tarotNumber++ ) { TB_INVENTORY* inventory = SelectInventory( tarotNumber ); if ( IsInventory( inventory ) ) { UpdateInventory( inventory, (-1) ); (*table) = (*inventory); table++; rowCount++; } } itemCollect->characterIdx = mObject.index; itemCollect->begin = invenBegin; itemCollect->end = invenEnd; length += (itemCollect->rowCount * sizeof(itemCollect->table)); mInventoryDb.collect = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); if ( mInventoryDb.collect == false ) throw ERROR_ITEM_COLLECT_CARD_CHANGE_FAIL; throw ERROR_ITEM_COLLECT_CARD_CHANGE_SUCCESS; } // ItemObtEvent Method void cPlayer::ItemObtEvent(ULONG_PTR socketContext, BYTE cbtUser, BYTE obtUser, BYTE fourGamer) { if ( mInventoryDatabase ) throw ERROR_NPC_OBT_EVENT_FAIL; if ( GetStateDie( ) == true ) throw ERROR_NPC_OBT_EVENT_FAIL; // ÀÌ¹Ì ¸ðµÎ Áö±Þ ¹ÞÀ½ if ( cbtUser == 2 && obtUser == 2 && fourGamer == 2 ) throw ERROR_NPC_OBT_EVENT_COMPLETE; // À̺¥Æ® ´ë»óÀÌ ¾Æ´Ô if ( cbtUser != 1 && obtUser != 1 && fourGamer != 1 ) throw ERROR_NPC_OBT_EVENT_NO_USER; HANDLE handle = NULL; ITEM_OBT_EVENT* itemEvent = (ITEM_OBT_EVENT*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_OBT_EVENT ); long length = sizeof(ITEM_OBT_EVENT) - sizeof(itemEvent->table); itemEvent->characterIdx = mObject.index; itemEvent->cbtUser = cbtUser; itemEvent->obtUser = obtUser; itemEvent->fourGamer = fourGamer; mInventoryDb.cash = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); if ( mInventoryDb.cash == false ) throw ERROR_NPC_OBT_EVENT_FAIL; } // IsItemEnhanced Method. int cPlayer::IsItemEnhanced( unsigned short equip, unsigned short card, unsigned short safeCard, int* rateType ) { /*-- ¾ÆÀÌÅÛ °­È­½Ã °Ë»çÇÒ ³»¿ëµé. */ // °­È­ Àåºñ °Ë»ç. TB_ITEM_DEFINE* itemDefine1 = NULL; TB_INVENTORY* inventory1 = NULL; inventory1 = SelectInventory( equip ); if ( IsInventory( inventory1 ) == false ) return ERROR_ITEM_ENHANCED_CHECK_FAIL; if ( inventory1->apply != InventoryApplyNone ) return ERROR_ITEM_ENHANCED_CHECK_FAIL; itemDefine1 = ITEMMANAGER->GetItemDefine( inventory1->itemDefineIdx ); if ( itemDefine1 == NULL ) return ERROR_ITEM_ENHANCED_CHECK_FAIL; if ( !(itemDefine1->type != ITEM_WEAPON || itemDefine1->type != ITEM_WEAR) ) return ERROR_ITEM_ENHANCED_CHECK_FAIL; if ( IsInventorySeal( itemDefine1, inventory1 ) == true ) return ERROR_ITEM_ENHANCED_CHECK_LICENSE; if ( !(inventory1->enhanced < MAX_ITEM_ENHANCED) ) return ERROR_ITEM_ENHANCED_CHECK_FAIL; // Àåºñ itemLimit TB_ITEM_LIMIT* equipLimit = ITEMMANAGER->GetItemLimit( inventory1->itemDefineIdx ); if ( equipLimit == NULL ) return ERROR_ITEM_ENHANCED_CHECK_FAIL; // °­È­ Ä«µå °Ë»ç. TB_ITEM_DEFINE* itemDefine2 = NULL; TB_INVENTORY* inventory2 = NULL; inventory2 = SelectInventory( card ); if ( IsInventory( inventory2 ) == false ) return ERROR_ITEM_ENHANCED_CHECK_FAIL; if ( inventory2->apply != InventoryApplyNone ) return ERROR_ITEM_ENHANCED_CHECK_FAIL; itemDefine2 = ITEMMANAGER->GetItemDefine( inventory2->itemDefineIdx ); if ( itemDefine2 == NULL ) return ERROR_ITEM_ENHANCED_CHECK_FAIL; if ( itemDefine2->type != ITEM_CARD ) return ERROR_ITEM_ENHANCED_CHECK_FAIL; // Àåºñ ·¹º§ üũ switch ( itemDefine2->subType ) { case ITEM_CARD_ENHANCE_WEAPON_LV1: case ITEM_CARD_ENHANCE_WEAPON_LV2: case ITEM_CARD_ENHANCE_WEAR_LV1: case ITEM_CARD_ENHANCE_WEAR_LV2: { if ( !(equipLimit->charLevelMin > 0 && equipLimit->charLevelMin <= 50) ) return ERROR_ITEM_ENHANCED_CHECK_EQUIP_LEVEL_BY_CARD; } break; case ITEM_CARD_ENHANCE_WEAPON_LV1_75: case ITEM_CARD_ENHANCE_WEAPON_LV2_75: case ITEM_CARD_ENHANCE_WEAR_LV1_75: case ITEM_CARD_ENHANCE_WEAR_LV2_75: { if ( !(equipLimit->charLevelMin > 50 && equipLimit->charLevelMin <= 75) ) return ERROR_ITEM_ENHANCED_CHECK_EQUIP_LEVEL_BY_CARD; } break; default: return ERROR_ITEM_ENHANCED_CHECK_FAIL; } if ( IsInventorySeal( itemDefine2, inventory2 ) == true ) return ERROR_ITEM_ENHANCED_CHECK_LICENSE; if ( !IsItemLimit( inventory2->itemDefineIdx ) ) return ERROR_ITEM_ENHANCED_CHECK_FAIL; // °­È­ º¸È£ Ä«µå °Ë»ç. if ( safeCard > 0 ) { TB_ITEM_DEFINE* itemDefine3 = NULL; TB_INVENTORY* inventory3 = NULL; inventory3 = SelectInventory( safeCard ); if ( IsInventory( inventory3 ) == false ) return ERROR_ITEM_ENHANCED_CHECK_FAIL; if ( inventory3->apply != InventoryApplyNone ) return ERROR_ITEM_ENHANCED_CHECK_FAIL; itemDefine3 = ITEMMANAGER->GetItemDefine( inventory3->itemDefineIdx ); if ( itemDefine3 == NULL ) return ERROR_ITEM_ENHANCED_CHECK_FAIL; /// Àåºñ ·¹º§ üũ if ( itemDefine3->type == ITEM_MATERIAL ) { if ( itemDefine3->subType == ITEM_MATERIAL_ENHANCED_DOWN_30 || itemDefine3->subType == ITEM_MATERIAL_ENHANCED_DESTROY_30 ) { if ( !(equipLimit->charLevelMin > 0 && equipLimit->charLevelMin <= 30) ) return ERROR_ITEM_ENHANCED_CHECK_EQUIP_LEVEL_BY_SAFE; } else if ( itemDefine3->subType == ITEM_MATERIAL_ENHANCED_DOWN_60 || itemDefine3->subType == ITEM_MATERIAL_ENHANCED_DESTROY_60 ) { if ( !(equipLimit->charLevelMin > 30 && equipLimit->charLevelMin <= 60) ) return ERROR_ITEM_ENHANCED_CHECK_EQUIP_LEVEL_BY_SAFE; } else return ERROR_ITEM_ENHANCED_CHECK_FAIL; } else { return ERROR_ITEM_ENHANCED_CHECK_FAIL; } if ( IsInventorySeal( itemDefine3, inventory3 ) == true ) return ERROR_ITEM_ENHANCED_CHECK_LICENSE; if ( !IsItemLimit( inventory3->itemDefineIdx ) ) return ERROR_ITEM_ENHANCED_CHECK_FAIL; } // °­È­Àåºñ & °­È­Ä«µå Á¶ÇÕ°Ë»ç. int rate = 0; switch ( itemDefine1->type ) { case ITEM_WEAPON: switch ( itemDefine2->subType ) { case ITEM_CARD_ENHANCE_WEAPON_LV1: case ITEM_CARD_ENHANCE_WEAPON_LV1_75: rate = 0; break; case ITEM_CARD_ENHANCE_WEAPON_LV2: case ITEM_CARD_ENHANCE_WEAPON_LV2_75: rate = 1; break; default: return ERROR_ITEM_ENHANCED_CHECK_FAIL; } break; case ITEM_WEAR: switch ( itemDefine2->subType ) { case ITEM_CARD_ENHANCE_WEAR_LV1: case ITEM_CARD_ENHANCE_WEAR_LV1_75: rate = 0; break; case ITEM_CARD_ENHANCE_WEAR_LV2: case ITEM_CARD_ENHANCE_WEAR_LV2_75: rate = 1; break; default: return ERROR_ITEM_ENHANCED_CHECK_FAIL; } break; default: return ERROR_ITEM_ENHANCED_CHECK_FAIL; } if ( rateType ) *rateType = rate; return 0; } // ItemEnhancedStart Method. void cPlayer::ItemEnhancedStart( MSG_REQ_ITEM_ENHANCED_START* msg ) { /// db »ç¿ëºÎ üũ if ( mInventoryDatabase ) throw ERROR_ITEM_ENHANCED_START_FAIL; if ( IsInventoryBag( msg->number1 ) == false ) throw ERROR_ITEM_ENHANCED_START_FAIL; if ( IsInventoryBag( msg->number2 ) == false ) throw ERROR_ITEM_ENHANCED_START_FAIL; if ( msg->number3 > 0 ) { if ( IsInventoryBag( msg->number3 ) == false ) throw ERROR_ITEM_ENHANCED_START_FAIL; } /// ¾ÆÀÌÅÛ °­È­ °Ë»ç int retval = IsItemEnhanced( msg->number1, msg->number2, msg->number3, 0 ); if ( retval != ERROR_ITEM_ENHANCED_CHECK_SUCCESS ) throw retval; /// °­È­ ºÒ°¡´É üũ if( mPlayerExrInfo.mIsDuelIdx ) throw ERROR_ITEM_ENHANCED_START_STATE; /// »óÅ º¯°æ if( ChangeState( eOBJECT_STATE_STOP ) == false ) throw ERROR_ITEM_ENHANCED_START_FAIL; SetStateStop( eSTOP_ENHANCED ); // ¿Ï·á ½Ã°£ ÀúÀå mItemEnhanceEndTime = NETWORK2->GetAccumTime() + ENHANCE_DELAYTIME; mEnhanceSlot1 = msg->number1; mEnhanceSlot2 = msg->number2; mEnhanceSlot3 = msg->number3; /// ¼º°ø½Ã ¸ðµÎ¿¡°Ô ¾Ë¸² MSG_SYN_ITEM_ENHANCED_START sync; sync.Category = NM_ITEM; sync.Protocol = NM_ITEM_ENHANCED_START_SYN; sync.characterIdx = mObject.index; NETWORK2->QuickSendExcept( this, (char*)&sync, sizeof( MSG_SYN_ITEM_ENHANCED_START ) ); throw ERROR_ITEM_ENHANCED_START_SUCCESS; } void cPlayer::ItemEnhancedEnd() { try { if( mEnhanceSlot1 == USHRT_MAX || mEnhanceSlot2 == USHRT_MAX || mEnhanceSlot3 == USHRT_MAX ) { NETWORK2->PostServerEvent( "ERROR ItemEnhancedEnd - CHARACTER_IDX(=%d) RETVALUE(=%d,%d,%d,%d)", mObject.index, GetStateStop(), mEnhanceSlot1, mEnhanceSlot2, mEnhanceSlot3 ); throw ERROR_ITEM_ENHANCED_END_FAIL; } if ( GetStateDie( ) == true ) throw ERROR_ITEM_ENHANCED_END_FAIL; /// ¾ÆÀÌÅÛ °­È­ °Ë»ç int rateType = 0; int retval = IsItemEnhanced( mEnhanceSlot1, mEnhanceSlot2, mEnhanceSlot3, &rateType ); if ( retval != ERROR_ITEM_ENHANCED_CHECK_SUCCESS ) throw retval; TB_INVENTORY* inventory1 = NULL; TB_INVENTORY* inventory2 = NULL; TB_INVENTORY* inventory3 = NULL; inventory1 = SelectInventory( mEnhanceSlot1 ); inventory2 = SelectInventory( mEnhanceSlot2 ); inventory3 = SelectInventory( mEnhanceSlot3 ); /*-- °­È­È®·ü Àû¿ë ¹æ¹ý. 0 1 = 0 ~ 1 »çÀÌÀÇ È®·ü (ÃÖ´ë 1/1000000) | SUCCESS | DOWN | DESTRUCT | FAIL | = ¼º°ø < ´Ù¿î < ÆÄ±« < º¯È­¾øÀ½ ¼øÀ¸·Î Àû¿ë. */ TB_ITEM_ENHANCED_RATE* itemEnhancedRate = ITEMMANAGER->GetItemEnhancedRate( inventory1->itemDefineIdx ); if ( itemEnhancedRate == NULL ) throw ERROR_ITEM_ENHANCED_END_FAIL; long success = *(itemEnhancedRate->value[ rateType ].success + inventory1->enhanced); long down = *(itemEnhancedRate->value[ rateType ].down + inventory1->enhanced) + success; long destruct = *(itemEnhancedRate->value[ rateType ].destruct + inventory1->enhanced) + down; // ¾ÆÀÌÅÛ °­È­È®·ü - °íÀ¯È®·ü Àû¿ë. long randomValue = (long)(RANDOMTABLE->Get( mItemEnhancedSeed ) * 1000000); // DATABASE - Àκ¥Å丮³» ¾ÆÀÌÅÛ À̵¿(â°í & Àκ¥) ¿äû. HANDLE handle = NULL; INVENTORY_ENHANCED* enhanced = (INVENTORY_ENHANCED*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_INVENTORY_ENHANCED ); char result = RESULT_INVENTORY_ENHANCED_SUCCESS; if ( randomValue <= success ) { result = RESULT_INVENTORY_ENHANCED_SUCCESS; } else if ( randomValue <= down && inventory1->enhanced > 0 ) { result = RESULT_INVENTORY_ENHANCED_DOWN; } else if ( randomValue <= destruct ) { result = RESULT_INVENTORY_ENHANCED_DESTROY; } else { result = RESULT_INVENTORY_ENHANCED_KEEP; } if ( result != RESULT_INVENTORY_ENHANCED_SUCCESS ) { if ( IsInventory( inventory3 ) == true ) { TB_ITEM_DEFINE* itemDefine3 = ITEMMANAGER->GetItemDefine( inventory3->itemDefineIdx ); if ( itemDefine3 != NULL ) { if ( itemDefine3->type == ITEM_MATERIAL ) { if ( result == RESULT_INVENTORY_ENHANCED_DOWN ) { if ( itemDefine3->subType == ITEM_MATERIAL_ENHANCED_DOWN_30 || itemDefine3->subType == ITEM_MATERIAL_ENHANCED_DOWN_60 ) { result = RESULT_INVENTORY_ENHANCED_KEEP; } } else result = RESULT_INVENTORY_ENHANCED_KEEP; } } } } enhanced->result = result; enhanced->table[ 0 ] = (*inventory1); enhanced->table[ 1 ] = (*inventory2); if ( mEnhanceSlot3 > 0 ) { enhanced->table[ 2 ] = (*inventory3); } mInventoryDb.enhanced = NETWORK2->SendSQL( mConnectionIdx, handle, sizeof(INVENTORY_ENHANCED) ); if ( mInventoryDb.enhanced == false ) throw ERROR_ITEM_ENHANCED_END_FAIL; mItemEnhanceEndTime = 0; mEnhanceSlot1 = USHRT_MAX; mEnhanceSlot2 = USHRT_MAX; mEnhanceSlot3 = USHRT_MAX; } catch ( int error ) { ChangeState( eOBJECT_STATE_IDLE ); SetStateStop( eSTOP_NONE ); NETWORK2->SendMsgError( mConnectionIdx, NM_ITEM, NM_ITEM_ENHANCED_END_SYN, error ); // ´Ù¸¥ À¯Àúµé¿¡°Ô °á°úÀü¼Û MSG_SYN_ITEM_ENHANCED_OTHEREND sync; sync.Category = NM_ITEM; sync.Protocol = NM_ITEM_ENHANCED_OTHEREND_SYN; sync.ErrorCode = ERROR_ITEM_ENHANCED_SYN_ENDFAIL; sync.characterIdx = mObject.index; NETWORK2->QuickSendExcept( this, (char*)&sync, sizeof(MSG_SYN_ITEM_ENHANCED_OTHEREND) ); } } // ItemEnhancedCancel Method. void cPlayer::ItemEnhancedCancel( ) { if( GetStateStop() == eSTOP_ENHANCED ) { /// »óÅ Ǯ¾îÁÜ if ( GetState() == eOBJECT_STATE_STOP && GetStateStop() == eSTOP_ENHANCED ) { ChangeState( eOBJECT_STATE_IDLE ); SetStateStop( eSTOP_NONE ); } mItemEnhanceEndTime = 0; mEnhanceSlot1 = USHRT_MAX; mEnhanceSlot2 = USHRT_MAX; mEnhanceSlot3 = USHRT_MAX; /// hero¿ÜÀÇ Ç÷¹À̾°Ô Ãë¼Ò È®ÀÎ ¸Þ¼¼Áö ¹ß¼Û MSG_SYN_ITEM_ENHANCED_CANCEL sync; sync.Category = NM_ITEM; sync.Protocol = NM_ITEM_ENHANCED_CANCEL_SYN; sync.characterIdx = mObject.index; NETWORK2->QuickSendExcept( this, (char*)&sync, sizeof( MSG_SYN_ITEM_ENHANCED_CANCEL ) ); /// db ó¸®ÁßÀÎ ³»¿ëÀÌ ÀÖÀ¸¸é Ŭ¶óÀÌ¾ðÆ®¿¡ ¾Ë¸² int retcode = ( mInventoryDb.enhanced == true ) ? ERROR_ITEM_ENHANCED_CANCEL_DBWORK : ERROR_ITEM_ENHANCED_CANCEL_SUCCESS; NETWORK2->SendMsgError( mConnectionIdx, NM_ITEM, NM_ITEM_ENHANCED_CANCEL_RES, retcode ); } else { NETWORK2->PostServerEvent( "ERROR ItemEnhancedCancel - CHARACTER_IDX(=%d) RETVALUE(=%d)", mObject.index, GetStateStop() ); } } // °­Á¦ Ãë¼Ò( »óÅÂÀÌ»óµî ) void cPlayer::ItemEnhancedForceCancel() { /// »óÅ Ǯ¾îÁÜ if ( GetState() == eOBJECT_STATE_STOP && GetStateStop() == eSTOP_ENHANCED ) { ChangeState( eOBJECT_STATE_IDLE ); SetStateStop( eSTOP_NONE ); } mItemEnhanceEndTime = 0; mEnhanceSlot1 = USHRT_MAX; mEnhanceSlot2 = USHRT_MAX; mEnhanceSlot3 = USHRT_MAX; /// hero ¿¡°Ô ¹ß¼Û MSG_SYN_ITEM_ENHANCED_CANCELFORCE msg; msg.Category = NM_ITEM; msg.Protocol = NM_ITEM_ENHANCED_CANCELFORCE_SYN; NETWORK2->QuickSend( this, (char*)&msg, sizeof( MSG_SYN_ITEM_ENHANCED_CANCELFORCE ) ); /// hero¿ÜÀÇ Ç÷¹À̾°Ô Ãë¼Ò È®ÀÎ ¸Þ¼¼Áö ¹ß¼Û MSG_SYN_ITEM_ENHANCED_CANCEL sync; sync.Category = NM_ITEM; sync.Protocol = NM_ITEM_ENHANCED_CANCEL_SYN; sync.characterIdx = mObject.index; NETWORK2->QuickSendExcept( this, (char*)&sync, sizeof( MSG_SYN_ITEM_ENHANCED_CANCEL ) ); } // ItemLicense Method. void cPlayer::ItemLicense( ULONG_PTR socketContext, MSG_REQ_ITEM_LICENSE* msg ) { if( !IsInventoryRange( msg->number ) ) throw ERROR_ITEM_LICENSE_FAIL; if( !IsInventoryBag( msg->number ) ) throw ERROR_ITEM_LICENSE_FAIL; TB_INVENTORY* inventory = SelectInventory( msg->number ); if( inventory == NULL ) throw ERROR_ITEM_LICENSE_FAIL; if ( inventory->seal == 0 ) throw ERROR_ITEM_LICENSE_ALREADY; if ( inventory->apply != InventoryApplyNone ) throw ERROR_ITEM_LICENSE_FAIL; TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if( itemDefine == NULL ) throw ERROR_ITEM_LICENSE_FAIL; // ¹ÌÀÎÁõ ¾ÆÀÌÅÛ if ( itemDefine->licenseType != 1 ) throw ERROR_ITEM_LICENSE_TYPE; // ÀÎÁõ¼³Á¤ inventory->seal = 0; HANDLE handle = NULL; INVENTORY_SEAL* inventorySeal = (INVENTORY_SEAL*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_INVENTORY_SEAL ); inventorySeal->characterIdx = mObject.index; inventorySeal->inventory = (*inventory); if ( itemDefine->licenseClass == 1 || itemDefine->licenseClass == 2 ) { inventorySeal->itemBill.type = itemDefine->licenseClass; inventorySeal->itemBill.validDate = itemDefine->licenseValidThru; inventorySeal->itemBill.validTime = itemDefine->licenseValidThru; inventorySeal->itemBill.inventoryIdx = inventory->idx; } mInventoryDb.seal = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, sizeof(INVENTORY_SEAL) ); } // ItemSummonPost Method. void cPlayer::ItemSummonPost( ULONG_PTR socketContext, MSG_REQ_TRADE_POST_SUMMON_OPEN* msg ) { if ( mInventoryDatabase ) throw ERROR_TRADE_POST_SUMMON_OPEN_FAIL; // Ç÷¹ÀÌ¾î »óÅ üũ if ( IsMapChange() == true ) throw ERROR_TRADE_POST_SUMMON_OPEN_FAIL; if ( GetStateDie() || GetStateStop() == eSTOP_SUMMON_PAPER ) throw ERROR_TRADE_POST_SUMMON_OPEN_FAIL; // Àκ¥Å丮 üũ if( !IsInventoryRange( msg->number ) ) throw ERROR_TRADE_POST_SUMMON_OPEN_FAIL; if( !IsInventoryBag( msg->number ) ) throw ERROR_TRADE_POST_SUMMON_OPEN_FAIL; TB_INVENTORY* inventory = SelectInventory( msg->number ); if( inventory == NULL ) throw ERROR_TRADE_POST_SUMMON_OPEN_FAIL; if ( inventory->apply != InventoryApplyNone ) throw ERROR_TRADE_POST_SUMMON_OPEN_FAIL; // ¾ÆÀÌÅÛ Ã¼Å© TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if( itemDefine == NULL ) throw ERROR_TRADE_POST_SUMMON_OPEN_FAIL; if ( itemDefine->type != ITEM_INVENTORY ) throw ERROR_TRADE_POST_SUMMON_OPEN_FAIL; if ( IsInventorySeal( itemDefine, inventory ) == true ) throw ERROR_TRADE_POST_SUMMON_OPEN_LICENSE; if ( IsChangeState( eOBJECT_STATE_STOP ) == false ) throw ERROR_TRADE_POST_SUMMON_OPEN_FAIL; if ( itemDefine->subType == ITEM_INVENTORY_POST_SUMMON ) { HANDLE handle = NULL; ITEM_SUMMON_POST* summonPost = (ITEM_SUMMON_POST*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_SUMMON_POST ); long length = sizeof(ITEM_SUMMON_POST) - sizeof(summonPost->post); // ¼Òȯ ÁÖ¹®¼­ UpdateInventory( inventory, -1 ); summonPost->inventory = (*inventory); // ¿ìÆí summonPost->characterIdx = mObject.index; summonPost->startPage = 1; mInventoryDb.use = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); if ( mInventoryDb.use == false ) throw ERROR_TRADE_POST_SUMMON_OPEN_FAIL; throw ERROR_TRADE_POST_SUMMON_OPEN_SUCCESS; } else if ( itemDefine->subType == ITEM_INVENTORY_USEFUL_PAPER ) { if ( PostOpen( (ULONG_PTR)socketContext ) == true ) { ChangeState( eOBJECT_STATE_STOP ); SetStateStop( eSTOP_SUMMON_PAPER ); throw ERROR_TRADE_POST_SUMMON_OPEN_USEFUL_SUCCESS; } } throw ERROR_TRADE_POST_SUMMON_OPEN_FAIL; } // ItemSummonAgent Method. void cPlayer::ItemSummonAgent( ULONG_PTR socketContext, MSG_REQ_TRADE_AGENT_SUMMON_OPEN* msg ) { if ( mInventoryDatabase ) throw ERROR_TRADE_AGENT_SUMMON_OPEN_FAIL; // Ç÷¹ÀÌ¾î »óÅ üũ if ( IsMapChange() == true ) throw ERROR_TRADE_AGENT_SUMMON_OPEN_FAIL; if ( GetStateDie() || GetStateStop() == eSTOP_SUMMON_PAPER ) throw ERROR_TRADE_AGENT_SUMMON_OPEN_FAIL; if( !IsInventoryRange( msg->number ) ) throw ERROR_TRADE_AGENT_SUMMON_OPEN_FAIL; if( !IsInventoryBag( msg->number ) ) throw ERROR_TRADE_AGENT_SUMMON_OPEN_FAIL; TB_INVENTORY* inventory = SelectInventory( msg->number ); if( inventory == NULL ) throw ERROR_TRADE_AGENT_SUMMON_OPEN_FAIL; if ( inventory->apply != InventoryApplyNone ) throw ERROR_TRADE_AGENT_SUMMON_OPEN_FAIL; TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if( itemDefine == NULL ) throw ERROR_TRADE_AGENT_SUMMON_OPEN_FAIL; if ( itemDefine->type != ITEM_INVENTORY ) throw ERROR_TRADE_AGENT_SUMMON_OPEN_FAIL; if ( IsInventorySeal( itemDefine, inventory ) == true ) throw ERROR_TRADE_AGENT_SUMMON_OPEN_LICENSE; // Ç÷¹ÀÌ¾î »óÅ üũ if( IsChangeState( eOBJECT_STATE_STOP ) == false ) throw ERROR_TRADE_AGENT_SUMMON_OPEN_FAIL; // ¼Ò¸ð¿ë ¼Òȯ ÁÖ¹®¼­ if ( itemDefine->subType == ITEM_INVENTORY_AGENT_SUMMON ) { HANDLE handle = NULL; ITEM_SUMMON_AGENT* summonAgent = (ITEM_SUMMON_AGENT*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_SUMMON_AGENT ); long length = sizeof(ITEM_SUMMON_AGENT) - sizeof(summonAgent->agent); // ¼Òȯ ÁÖ¹®¼­ UpdateInventory( inventory, -1 ); summonAgent->inventory = (*inventory); // ÆÇ¸Å ´ëÇà summonAgent->characterIdx = mObject.index; summonAgent->startPage = 1; mInventoryDb.use = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); if ( mInventoryDb.use == false ) throw ERROR_TRADE_AGENT_SUMMON_OPEN_FAIL; throw ERROR_TRADE_AGENT_SUMMON_OPEN_SUCCESS; } // ±â°£Á¦ ÆíÀDZâ´É ÁÖ¹®¼­ else if ( itemDefine->subType == ITEM_INVENTORY_USEFUL_PAPER ) { HANDLE handle = NULL; ITEM_AGENT_SELECT_OWNER* select = (ITEM_AGENT_SELECT_OWNER*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_AGENT_SELECT_OWNER ); long length = sizeof(ITEM_AGENT_SELECT_OWNER) - sizeof(select->table); select->characterIdx = mObject.index; select->startPage = 1; if ( NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ) == false ) throw ERROR_TRADE_AGENT_SUMMON_OPEN_FAIL; ChangeState( eOBJECT_STATE_STOP ); SetStateStop( eSTOP_SUMMON_PAPER ); throw ERROR_TRADE_AGENT_SUMMON_OPEN_USEFUL_SUCCESS; } throw ERROR_TRADE_AGENT_SUMMON_OPEN_FAIL; } // ItemSummonWareHouse Method. void cPlayer::ItemSummonWareHouse( ULONG_PTR socketContext, MSG_REQ_ITEM_WAREHOUSE_SUMMON_OPEN* msg ) { if ( mInventoryDatabase ) throw ERROR_ITEM_WAREHOUSE_SUMMON_OPEN_FAIL; // Ç÷¹ÀÌ¾î »óÅ üũ if ( IsMapChange() == true ) throw ERROR_ITEM_WAREHOUSE_SUMMON_OPEN_FAIL; if ( GetStateDie() || GetStateStop() == eSTOP_SUMMON_PAPER ) throw ERROR_ITEM_WAREHOUSE_SUMMON_OPEN_FAIL; // Àκ¥Å丮 üũ if( !IsInventoryRange( msg->number ) ) throw ERROR_ITEM_WAREHOUSE_SUMMON_OPEN_FAIL; if( !IsInventoryBag( msg->number ) ) throw ERROR_ITEM_WAREHOUSE_SUMMON_OPEN_FAIL; TB_INVENTORY* inventory = SelectInventory( msg->number ); if( inventory == NULL ) throw ERROR_ITEM_WAREHOUSE_SUMMON_OPEN_FAIL; if ( inventory->apply != InventoryApplyNone ) throw ERROR_ITEM_WAREHOUSE_SUMMON_OPEN_FAIL; // ¾ÆÀÌÅÛ Ã¼Å© TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if( itemDefine == NULL ) throw ERROR_ITEM_WAREHOUSE_SUMMON_OPEN_FAIL; if ( itemDefine->type != ITEM_INVENTORY ) throw ERROR_ITEM_WAREHOUSE_SUMMON_OPEN_FAIL; if ( IsInventorySeal( itemDefine, inventory ) == true ) throw ERROR_ITEM_WAREHOUSE_SUMMON_OPEN_LICENSE; if ( IsChangeState( eOBJECT_STATE_STOP ) == false ) throw ERROR_ITEM_WAREHOUSE_SUMMON_OPEN_FAIL; // ¼Ò¸ð¿ë ¼Òȯ ÁÖ¹®¼­ if ( itemDefine->subType == ITEM_INVENTORY_WAREHOUSE_SUMMON ) { HANDLE handle = NULL; ITEM_SUMMON_WAREHOUSE* summonWare = (ITEM_SUMMON_WAREHOUSE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_SUMMON_WAREHOUSE ); summonWare->characterIdx = mObject.index; UpdateInventory( inventory, -1 ); summonWare->inventory = (*inventory); mInventoryDb.use = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, sizeof(ITEM_SUMMON_WAREHOUSE) ); if ( mInventoryDb.use == false ) throw ERROR_ITEM_WAREHOUSE_SUMMON_OPEN_FAIL; throw ERROR_ITEM_WAREHOUSE_SUMMON_OPEN_SUCCESS; } // ±â°£Á¦ ÆíÀDZâ´É ÁÖ¹®¼­ else if ( itemDefine->subType == ITEM_INVENTORY_USEFUL_PAPER ) { ChangeState( eOBJECT_STATE_STOP ); SetStateStop( eSTOP_SUMMON_PAPER ); throw ERROR_ITEM_WAREHOUSE_SUMMON_OPEN_USEFUL_SUCCESS; } throw ERROR_ITEM_WAREHOUSE_SUMMON_OPEN_FAIL; } void cPlayer::ItemNpcEvent( ULONG_PTR socketContext, unsigned long eventIndex ) { if ( mInventoryDatabase ) throw ERROR_NPC_EVENT_ITEM_GIVE_FAIL; if ( GetStateDie( ) == true ) throw ERROR_NPC_EVENT_ITEM_GIVE_FAIL; if( !(eventIndex > NPC_EVENT_NONE && eventIndex < NPC_EVENT_MAX) ) throw ERROR_NPC_EVENT_ITEM_GIVE_FAIL; HANDLE handle = NULL; ITEM_NPC_EVENT* itemEvent = (ITEM_NPC_EVENT*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_NPC_EVENT ); long length = sizeof(ITEM_NPC_EVENT) - sizeof(itemEvent->table); itemEvent->characterIdx = mObject.index; itemEvent->userIdx = mConnectionIdx; itemEvent->eventType = eventIndex; itemEvent->retvalue = 0; mInventoryDb.cash = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); if ( mInventoryDb.cash == false ) throw ERROR_NPC_EVENT_ITEM_GIVE_FAIL; } // SendInventory Method. bool cPlayer::SendInventory(ULONG_PTR socketContext) { HANDLE handle = NULL; MSG_RES_INVENTORY* sendMsg = (MSG_RES_INVENTORY*)NETWORK2->GetMsgRoot( &handle, (PerSocketContext*)socketContext, NM_ITEM, NM_ITEM_INVENTORY_RES ); sInventory* sinventory = sendMsg->Inventory; TB_INVENTORY* inventory = SelectInventory( ); unsigned long length = sizeof(MSG_RES_INVENTORY) - sizeof(sendMsg->Inventory); int index = MIN_INVENTORY; sendMsg->activeWeapon = mItemActiveWeapon; sendMsg->RowCount = 0; while ( index <= MAX_VALID_INVENTORY ) { if ( IsInventory( inventory ) ) { Inventory2sInventory( sinventory, inventory ); sinventory++; sendMsg->RowCount++; } inventory++; index++; } length += (sendMsg->RowCount * sizeof(sendMsg->Inventory)); return NETWORK2->SendMsgRoot( handle, length ); } bool cPlayer::SendInventoryCash(ULONG_PTR socketContext) { HANDLE handle = NULL; MSG_RES_ITEM_CASH_LIST* sendMsg = (MSG_RES_ITEM_CASH_LIST*)NETWORK2->GetMsgRoot( &handle, (PerSocketContext*)socketContext, NM_ITEM, NM_ITEM_CASH_LIST_RES ); sCashInventory* sinventory = sendMsg->Inventory; TB_INVENTORY* inventory = SelectInventory( INVENTORY_CASH_ITEM_BEGIN ); int index = INVENTORY_CASH_ITEM_BEGIN; sendMsg->RowCount = 0; sendMsg->ErrorCode = ERROR_ITEM_CASH_LIST_SUCCESS; while ( index <= INVENTORY_CASH_ITEM_END ) { if ( IsInventory( inventory ) ) { sinventory->idx = inventory->idx; sinventory->ItemIndex = inventory->itemDefineIndex; sinventory->number = inventory->number; sinventory->count = inventory->count; sinventory->seal = inventory->seal; sinventory->cash = inventory->cash; sinventory++; sendMsg->RowCount++; } inventory++; index++; } return NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength() ); } // SendInventoryCooltime Method. bool cPlayer::SendInventoryCooltime(ULONG_PTR socketContext) { HANDLE handle = NULL; MSG_RES_INVENTORY_COOLTIME* sendMsg = (MSG_RES_INVENTORY_COOLTIME*)NETWORK2->GetMsgRoot( &handle, (PerSocketContext*)socketContext, NM_ITEM, NM_ITEM_INVENTORY_COOLTIME_RES ); unsigned long length = sizeof(MSG_RES_INVENTORY_COOLTIME) - sizeof(sendMsg->InventoryCooltime); PerCooltime* perCooltime = (PerCooltime*)mCooltimeRoot.pool; sInventoryCooltime* inventoryCooltime = sendMsg->InventoryCooltime; long remainCooltime; time_t ltime; time( <ime ); while ( perCooltime != NULL ) { remainCooltime = (long)difftime( perCooltime->validThru, ltime ); if ( remainCooltime > 0 ) { inventoryCooltime->ItemIndex = perCooltime->index; inventoryCooltime->cooltime2 = perCooltime->cooltime2; inventoryCooltime->cooltime = remainCooltime*1000; inventoryCooltime->cooltime1 = perCooltime->cooltime1; inventoryCooltime++; sendMsg->RowCount++; } perCooltime = (PerCooltime*)perCooltime->next; } length += (sendMsg->RowCount * sizeof(sendMsg->InventoryCooltime)); return NETWORK2->SendMsgRoot( handle, length ); } void cPlayer::SetInventoryEquip( sInventory* sInventory, unsigned long* count ) { TB_INVENTORY* inventory = NULL; for ( short number = INVENTORY_EQUIP_BEGIN; number <= INVENTORY_EQUIP_END; number++ ) { inventory = SelectInventory( number ); if ( IsInventory( inventory ) ) { Inventory2sInventory( sInventory, inventory ); sInventory++; (*count)++; } inventory++; } } // SetWearInfoWithSendMsg Method - PlayerÀÇ Âø¿ëÁ¤º¸(¹æ¾î±¸) ¼³Á¤°ú °ü·Ã ¸Þ½ÃÁö ó¸®. bool cPlayer::SetWearInfoWithSendMsg(eWEAR_TYPE type, unsigned long itemDefineIndex) { if ( type < eWEAR_MAX && mPlayerWearInfo.WearIdx[ type ] != itemDefineIndex ) { // Âø¿ëÁ¤º¸ ¹é¾÷. mPlayerWearInfo.WearIdx[ type ] = itemDefineIndex; // Âø¿ëÁ¤º¸ º¸³»±â-RES. HANDLE handle = NULL; MSG_RES_PLAYER_EQUIP_WEAR* msgRes = (MSG_RES_PLAYER_EQUIP_WEAR*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_EQUIP_WEAR_RES ); if ( msgRes != NULL ) { msgRes->mType = (unsigned char)type; msgRes->mWearInfo = itemDefineIndex; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_PLAYER_EQUIP_WEAR) ); } // Âø¿ëÁ¤º¸ º¸³»±â-SYN. MSG_SYN_PLAYER_EQUIP_WEAR msgSyn; memset( &msgSyn, 0, sizeof(MSG_SYN_PLAYER_EQUIP_WEAR) ); msgSyn.Category = NM_PLAYER; msgSyn.Protocol = NM_PLAYER_EQUIP_WEAR_SYN; msgSyn.mCharacterIdx = mObject.index; // mPlayerInfo.CharacterIdx ¿Í °°À½. msgSyn.mType = (unsigned char)type; msgSyn.mWearInfo = itemDefineIndex; NETWORK2->QuickSendExcept( this, (char*)&msgSyn, sizeof(msgSyn) ); return true; } return false; } // SetCosWearInfoWithSendMsg Method - PlayerÀÇ ÄÚ½ºÆ¬ Âø¿ëÁ¤º¸(¹æ¾î±¸) ¼³Á¤°ú °ü·Ã ¸Þ½ÃÁö ó¸®. bool cPlayer::SetCosWearInfoWithSendMsg( eWEAR_TYPE type, unsigned long itemDefineIndex ) { if ( type < eWEAR_MAX ) { unsigned long costumeIndex = mPlayerWearInfo.CostumeIdx[ type ]; if ( costumeIndex != itemDefineIndex ) { // Âø¿ëÁ¤º¸ ¹é¾÷. mPlayerWearInfo.CostumeIdx[ type ] = itemDefineIndex; // Âø¿ëÁ¤º¸. TB_ITEM_DEFINE* itemDefine = NULL; BYTE current = 0; BYTE changed = 0; itemDefine = ITEMMANAGER->GetItemDefineByIndex( costumeIndex ); if ( itemDefine != NULL ) { current = itemDefine->subType; } itemDefine = ITEMMANAGER->GetItemDefineByIndex( itemDefineIndex ); if ( itemDefine != NULL ) { changed = itemDefine->subType; } if ( current == ITEM_WEAR_COS_ONEPIECE && changed == ITEM_WEAR_COS_ONEPIECE ) { SendCosWearInfo( eWEAR_ONEPIECE, itemDefineIndex ); } else if ( current == ITEM_WEAR_COS_ONEPIECE ) { SendCosWearInfo( eWEAR_ONEPIECE, 0 ); if ( changed == ITEM_WEAR_COS_UPPER ) SendCosWearInfo( type, itemDefineIndex ); } else if ( changed == ITEM_WEAR_COS_ONEPIECE ) { SendCosWearInfo( eWEAR_ONEPIECE, itemDefineIndex ); mPlayerWearInfo.CostumeIdx[ eWEAR_BODY2 ] = 0; mPlayerWearInfo.CostumeIdx[ eWEAR_HAND ] = 0; mPlayerWearInfo.CostumeIdx[ eWEAR_FOOT ] = 0; } else { SendCosWearInfo( type, itemDefineIndex ); } return true; } } return false; } // SendCosWearInfo Method void cPlayer::SendCosWearInfo(eWEAR_TYPE type, unsigned long itemDefineIndex) { // Âø¿ëÁ¤º¸ º¸³»±â-RES. HANDLE handle = NULL; MSG_RES_PLAYER_COSTUME_WEAR* msgRes = (MSG_RES_PLAYER_COSTUME_WEAR*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_COSTUME_WEAR_RES ); if ( msgRes != NULL ) { msgRes->mType = (unsigned char)type; msgRes->mWearInfo = itemDefineIndex; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_PLAYER_COSTUME_WEAR) ); } // Âø¿ëÁ¤º¸ º¸³»±â-SYN. MSG_SYN_PLAYER_COSTUME_WEAR msgSyn; memset( &msgSyn, 0, sizeof(MSG_SYN_PLAYER_COSTUME_WEAR) ); msgSyn.Category = NM_PLAYER; msgSyn.Protocol = NM_PLAYER_COSTUME_WEAR_SYN; msgSyn.mCharacterIdx = mObject.index; // mPlayerInfo.CharacterIdx ¿Í °°À½. msgSyn.mType = (unsigned char)type; msgSyn.mWearInfo = itemDefineIndex; NETWORK2->QuickSendExcept( this, (char*)&msgSyn, sizeof(msgSyn) ); } // SetCosAccInfoWithSendMsg Method - PlayerÀÇ ÄÚ½ºÆ¬ Âø¿ëÁ¤º¸(¾Ç¼¼»ç¸®) ¼³Á¤°ú °ü·Ã ¸Þ½ÃÁö ó¸®. bool cPlayer::SetCosAccInfoWithSendMsg( eCOSTUME_LINK type, unsigned long itemDefineIndex ) { if ( type < eCOSTUME_MAX && mPlayerWearInfo.CostumeAccIdx[ type ] != itemDefineIndex ) { mPlayerWearInfo.CostumeAccIdx[ type ] = itemDefineIndex; HANDLE handle = NULL; MSG_RES_PLAYER_COSTUME_ACC* msgRes = (MSG_RES_PLAYER_COSTUME_ACC*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_COSTUME_ACC_RES ); if ( msgRes != NULL ) { msgRes->mType = (unsigned char)type; msgRes->mWearInfo = itemDefineIndex; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_PLAYER_COSTUME_ACC) ); } // Âø¿ëÁ¤º¸ º¸³»±â-SYN. MSG_SYN_PLAYER_COSTUME_ACC msgSyn; memset( &msgSyn, 0, sizeof(MSG_SYN_PLAYER_COSTUME_ACC) ); msgSyn.Category = NM_PLAYER; msgSyn.Protocol = NM_PLAYER_COSTUME_ACC_SYN; msgSyn.mCharacterIdx = mObject.index; msgSyn.mType = (unsigned char)type; msgSyn.mWearInfo = itemDefineIndex; NETWORK2->QuickSendExcept( this, (char*)&msgSyn, sizeof(msgSyn) ); return true; } return false; } // SetWeaponInfoWithSendMsg Method - PlayerÀÇ Âø¿ëÁ¤º¸(¹«±â) ¼³Á¤°ú °ü·Ã ¸Þ½ÃÁö ó¸®. void cPlayer::SetWeaponInfoWithSendMsg(TB_INVENTORY* left, TB_INVENTORY* right) { // Âø¿ëÁ¤º¸ ¹é¾÷. mPlayerWeaponInfo.WeaponIdx[ eHAND_LEFT ] = left->itemDefineIndex; mPlayerWeaponInfo.WeaponIdx[ eHAND_RIGHT ] = right->itemDefineIndex; mPlayerWeaponInfo.WeaponEnhanced[ eHAND_LEFT ] = left->enhanced; mPlayerWeaponInfo.WeaponEnhanced[ eHAND_RIGHT ] = right->enhanced; // Âø¿ëÁ¤º¸ º¸³»±â-RES. HANDLE handle = NULL; MSG_RES_PLAYER_EQUIP_WEAPON* msgRes = (MSG_RES_PLAYER_EQUIP_WEAPON*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_EQUIP_WEAPON_RES ); if ( msgRes != NULL ) { msgRes->mWeaponState = (unsigned char)mPlayerWeaponState; msgRes->mWeaponInfo = mPlayerWeaponInfo; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_PLAYER_EQUIP_WEAPON) ); } // Âø¿ëÁ¤º¸ º¸³»±â-SYN. MSG_SYN_PLAYER_EQUIP_WEAPON msgSyn; memset( &msgSyn, 0, sizeof(MSG_SYN_PLAYER_EQUIP_WEAPON) ); msgSyn.Category = NM_PLAYER; msgSyn.Protocol = NM_PLAYER_EQUIP_WEAPON_SYN; msgSyn.mCharacterIdx = mObject.index; msgSyn.mWeaponState = (unsigned char)mPlayerWeaponState; msgSyn.mWeaponInfo = mPlayerWeaponInfo; NETWORK2->QuickSendExcept( this, (char*)&msgSyn, sizeof(msgSyn) ); } // CbItemBillDel Method. bool cPlayer::CbItemBillDel(ULONG_PTR socketContext, ITEM_BILL_REMOVE* remove, u_long requestResult) { if ( mInventoryDb.itemBill == true ) mInventoryDb.itemBill = false; else return false; if ( requestResult != 0 ) throw requestResult; if ( remove->retvalue != 0 ) throw remove->retvalue; HANDLE handle = NULL; MSG_SYN_ITEM_BILL_DEL* sendSyn = (MSG_SYN_ITEM_BILL_DEL*)NETWORK2->GetMsgRoot( &handle, (PerSocketContext*)socketContext, NM_ITEM, NM_ITEM_BILL_DEL_SYN ); sendSyn->idx = remove->idx; return NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_ITEM_BILL_DEL) ); } // CbInventoryInsert Method. void cPlayer::CbInventoryInsert(ULONG_PTR socketContext, INVENTORY_INSERT* inventoryInsert, u_long requestResult) { if ( mInventoryDb.insert ) mInventoryDb.insert = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult == 0 ) { HANDLE handle = NULL; MSG_RES_CHEAT_MAKE* sendMsg = (MSG_RES_CHEAT_MAKE*)NETWORK2->GetMsgRoot( &handle, (PerSocketContext*)socketContext, NM_CHEAT, NM_CHEAT_MAKE_RES ); TB_INVENTORY* table = inventoryInsert->table; sInventory* sinventory = sendMsg->inventory; sendMsg->ErrorCode = ERROR_CHEAT_MAKE_SUCCESS; for ( long i = 0; i < inventoryInsert->rowCount; i++, table++ ) { if ( table->idx != 0 ) { XCopyInventory( table ); Inventory2sInventory( sinventory, table ); sinventory++; sendMsg->rowCount++; NETWORK2->PostInventoryEvent( EVENT_INVENTORY_CREATE, mObject.index, table, "INSERT-CHEAT" ); } } NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength( ) ); } else throw requestResult; } // CbInventoryRemove Method. void cPlayer::CbInventoryRemove(ULONG_PTR socketContext, INVENTORY_REMOVE* inventoryRemove, u_long requestResult) { if ( mInventoryDb.remove ) mInventoryDb.remove = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult == 0 ) { TB_INVENTORY* inventory = SelectInventory( inventoryRemove->number ); if ( inventoryRemove->idx == inventory->idx ) { // ¾ÆÀÌÅÛ ºô »èÁ¦. if ( inventory->idx > 0 ) { PerItemBill* itemBill = ITEMBILLPOOL->SearchItemBill( &mItemBillRoot, inventory->idx ); if ( itemBill != NULL ) { itemBill->apply = ItemBillApplyReserved; } } // ·Î±× Àü¼Û. NETWORK2->PostInventoryEvent( EVENT_INVENTORY_DELETE, mObject.index, inventory, "REMOVE" ); // »èÁ¦ ¿Ï·á. RemoveInventory( inventory ); // °á°ú Àü¼Û. NETWORK2->SendMsgError( (PerSocketContext*)socketContext, NM_ITEM, NM_ITEM_DEL_INVENTORY_RES, ERROR_ITEM_DEL_INVENTORY_SUCCESS ); } else throw inventory; } else throw requestResult; } // CbInventoryUse Method. void cPlayer::CbInventoryUse(ULONG_PTR socketContext, INVENTORY_USE* inventoryUse, u_long requestResult) { if ( mInventoryDb.use ) mInventoryDb.use = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult == 0 ) { TB_INVENTORY* table = inventoryUse->table; TB_INVENTORY* inventory = SelectInventory( table->number ); if ( table->idx != inventory->idx ) { throw table; } else if ( table->apply == InventoryApplyRemoved ) { // »èÁ¦ ¿Ï·á. RemoveInventory( inventory ); // ·Î±× Àü¼Û. NETWORK2->PostInventoryEvent( EVENT_INVENTORY_DELETE, mObject.index, table, "USE" ); } else { // °»½Å ¿Ï·á. XCopyInventory( inventory, table, XCOPY_INVENTORY_COUNT ); // ·Î±× Àü¼Û. NETWORK2->PostInventoryEvent( EVENT_INVENTORY_UPDATE, mObject.index, table, "USE" ); } // °á°ú Àü¼Û. NETWORK2->SendMsgError( (PerSocketContext*)socketContext, NM_ITEM, NM_ITEM_USE_INVENTORY_RES, ERROR_ITEM_USE_INVENTORY_SUCCESS ); } else throw requestResult; } // CbInventorySwap Method. void cPlayer::CbInventorySwap(ULONG_PTR /*socketContext*/, INVENTORY_SWAP* /*inventorySwap*/, u_long requestResult) { if ( mInventoryDb.swap ) mInventoryDb.swap = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult != 0 ) throw requestResult; } // CbInventoryMove Method. void cPlayer::CbInventoryMove(ULONG_PTR /*socketContext*/, INVENTORY_MOVE* inventoryMove, u_long requestResult) { if ( mInventoryDb.move ) mInventoryDb.move = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult == 0 ) { TB_INVENTORY* inventory = SelectInventory( inventoryMove->number ); if ( inventoryMove->cashBox ) NETWORK2->PostInventoryEvent( EVENT_INVENTORY_UPDATE, mObject.index, inventory, "CASH BOX" ); if ( inventory->idx != inventoryMove->idx || inventory->number != inventoryMove->number ) throw inventory; } else throw requestResult; } // CbInventoryExcept Method. void cPlayer::CbInventoryExcept(ULONG_PTR /*socketContext*/, INVENTORY_EXCEPT* inventoryExcept, u_long requestResult) { if ( mInventoryDb.except ) mInventoryDb.except = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult == 0 ) { TB_INVENTORY* inventory; for ( long i = 0; i < inventoryExcept->rowCount; i++ ) { inventory = SelectInventory( inventoryExcept->table[ i ].number ); if ( inventory->idx != inventoryExcept->table[ i ].idx ) throw inventory; } } else throw requestResult; } // CbInventoryMerge Method. void cPlayer::CbInventoryMerge(ULONG_PTR socketContext, INVENTORY_MERGE* inventoryMerge, u_long requestResult) { if ( mInventoryDb.merge ) mInventoryDb.merge = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult == 0 ) { TB_INVENTORY* table = inventoryMerge->table; TB_INVENTORY* inventory = NULL; for ( long i = 0; i < inventoryMerge->rowCount; i++, table++ ) { inventory = SelectInventory( table->number ); if ( inventory->idx == table->idx ) { if ( table->apply == InventoryApplyRemoved ) { // »èÁ¦ ¿Ï·á. RemoveInventory( inventory ); // ·Î±× Àü¼Û. NETWORK2->PostInventoryEvent( EVENT_INVENTORY_DELETE, mObject.index, table, "MERGE" ); } else { // °»½Å ¿Ï·á. XCopyInventory( inventory, table, XCOPY_INVENTORY_COUNT ); // ·Î±× Àü¼Û. NETWORK2->PostInventoryEvent( EVENT_INVENTORY_UPDATE, mObject.index, table, "MERGE" ); } } else throw table; } // °á°ú Àü¼Û. NETWORK2->SendMsgError( (PerSocketContext*)socketContext, NM_ITEM, NM_ITEM_MERGE_INVENTORY_RES, ERROR_ITEM_MERGE_INVENTORY_SUCCESS ); } else throw requestResult; } // CbInventoryDivide Method. void cPlayer::CbInventoryDivide(ULONG_PTR socketContext, INVENTORY_DIVIDE* inventoryDivide, u_long requestResult) { if ( mInventoryDb.divide ) mInventoryDb.divide = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult == 0 ) { TB_INVENTORY* table = inventoryDivide->table; TB_INVENTORY* inventory; for ( int i = 0; i < ROW_INVENTORY_DIVIDE; i++, table++ ) { inventory = SelectInventory( table->number ); // ·Î±× Àü¼Û. NETWORK2->PostInventoryEvent( inventory->idx == table->idx ? EVENT_INVENTORY_UPDATE : EVENT_INVENTORY_CREATE ,mObject.index ,table ,"DIVIDE" ); // °»½Å ¿Ï·á. XCopyInventory( table ); } // °á°ú Àü¼Û. HANDLE handle = NULL; MSG_RES_ITEM_DIVIDE_INVENTORY* sendMsg = (MSG_RES_ITEM_DIVIDE_INVENTORY*)NETWORK2->GetMsgRoot( &handle ,(PerSocketContext*)socketContext ,NM_ITEM ,NM_ITEM_DIVIDE_INVENTORY_RES ); sInventory* sinventory = sendMsg->Inventory; sendMsg->ErrorCode = ERROR_ITEM_DIVIDE_INVENTORY_SUCCESS; sendMsg->RowCount = ROW_INVENTORY_DIVIDE; table = inventoryDivide->table; for ( int i = 0; i < ROW_INVENTORY_DIVIDE; i++, table++, sinventory++ ) { Inventory2sInventory( sinventory, table ); } NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength( ) ); } else throw requestResult; } // CbInventoryMove2 Method. void cPlayer::CbInventoryMove2(ULONG_PTR socketContext, INVENTORY_MOVE2* inventoryMove2, u_long requestResult) { if ( mInventoryDb.move2 ) mInventoryDb.move2 = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult == 0 ) { TB_INVENTORY* table; TB_INVENTORY* inventory; table = inventoryMove2->table; for ( long i = 0; i < inventoryMove2->rowCount; i++, table++ ) { inventory = SelectInventory( table->number ); // ·Î±× Àü¼Û. NETWORK2->PostInventoryEvent( (inventory->idx == table->idx) ? EVENT_INVENTORY_UPDATE : EVENT_INVENTORY_CREATE ,mObject.index ,table ,"MOVE2" ); // °»½Å. XCopyInventory( inventory, table ); } // °á°ú Àü¼Û. HANDLE handle = NULL; MSG_RES_NPC_ITEM_MOV2_INVENTORY* sendMsg = (MSG_RES_NPC_ITEM_MOV2_INVENTORY*)NETWORK2->GetMsgRoot( &handle ,(PerSocketContext*)socketContext ,NM_NPC ,NM_NPC_ITEM_MOV2_INVENTORY_RES ); sInventory* sinventory = sendMsg->Inventory; sendMsg->ErrorCode = ERROR_ITEM_MOV2_INVENTORY_SUCCESS; sendMsg->RowCount = inventoryMove2->rowCount; table = inventoryMove2->table; for ( long i = 0; i < inventoryMove2->rowCount; i++, table++, sinventory++ ) { Inventory2sInventory( sinventory, table ); } NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength( ) ); } else throw requestResult; } // CbInventoryEnhanced Method. void cPlayer::CbInventoryEnhanced(ULONG_PTR socketContext, INVENTORY_ENHANCED* inventoryEnhanced, u_long requestResult) { if ( mInventoryDb.enhanced ) mInventoryDb.enhanced = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult == 0 ) { TB_INVENTORY* table = NULL; TB_INVENTORY* card = NULL; TB_INVENTORY* safeCard = NULL; // °­È­Àåºñ table = &inventoryEnhanced->table[ 0 ]; switch ( inventoryEnhanced->result ) { case RESULT_INVENTORY_ENHANCED_SUCCESS: { XCopyInventory( table ); NETWORK2->PostInventoryEvent( EVENT_INVENTORY_UPDATE, mObject.index, table, "ENHANCED SUCCESS" ); if ( table->enhanced > 8 ) { MSG_SYN_CHAT_SYSTEM sync; memset( &sync, 0, sizeof(sync) ); sync.Category = NM_CHAT; sync.Protocol = NM_CHAT_ENHANCED_SYN; Inventory2sInventory( &sync.inventory, table ); wcscpy( sync.characterName, mPlayerInfo.strName ); cSender* sender = g_gameSrv->GetSender( ); sender->PostEnhancedSync( NETWORK2->GetCID( ), sync.characterName, (char*)&sync.inventory, sizeof(sync.inventory) ); OBJECTMANAGER->SendNotice( (char*)&sync, sizeof(MSG_SYN_CHAT_SYSTEM) ); } } break; case RESULT_INVENTORY_ENHANCED_DOWN: XCopyInventory( table ); NETWORK2->PostInventoryEvent( EVENT_INVENTORY_UPDATE, mObject.index, table, "ENHANCED DOWN" ); break; case RESULT_INVENTORY_ENHANCED_DESTROY: if ( table->apply == InventoryApplyRemoved ) { RemoveInventory( table->number ); NETWORK2->PostInventoryEvent( EVENT_INVENTORY_DELETE, mObject.index, table, "ENHANCED DESTRUCT" ); if ( table->enhanced > 8 ) { MSG_SYN_CHAT_SYSTEM sync; memset( &sync, 0, sizeof(sync) ); sync.Category = NM_CHAT; sync.Protocol = NM_CHAT_ENHANCED_SYN; Inventory2sInventory( &sync.inventory, table ); cSender* sender = g_gameSrv->GetSender( ); sender->PostEnhancedSync( NETWORK2->GetCID( ), NULL, (char*)&sync.inventory, sizeof(sync.inventory) ); OBJECTMANAGER->SendNotice( (char*)&sync, sizeof(MSG_SYN_CHAT_SYSTEM) ); } } break; case RESULT_INVENTORY_ENHANCED_KEEP: NETWORK2->PostInventoryEvent( EVENT_INVENTORY_UPDATE, mObject.index, table, "ENHANCED FAIL" ); break; } // °­È­Ä«µå card = &inventoryEnhanced->table[ 1 ]; if ( card->apply == InventoryApplyRemoved ) { RemoveInventory( card->number ); NETWORK2->PostInventoryEvent( EVENT_INVENTORY_DELETE, mObject.index, card, "USED ENHANCED" ); } else { XCopyInventory( card ); NETWORK2->PostInventoryEvent( EVENT_INVENTORY_UPDATE, mObject.index, card, "USED ENHANCED" ); } // °­È­º¸È£Ä«µå safeCard = &inventoryEnhanced->table[ 2 ]; if ( safeCard->idx > 0 ) { if ( safeCard->apply == InventoryApplyRemoved ) { RemoveInventory( safeCard->number ); NETWORK2->PostInventoryEvent( EVENT_INVENTORY_DELETE, mObject.index, safeCard, "USED ENHANCED" ); } else { XCopyInventory( safeCard ); NETWORK2->PostInventoryEvent( EVENT_INVENTORY_UPDATE, mObject.index, safeCard, "USED ENHANCED" ); } } // °á°ú Àü¼Û // HERO¿¡ °á°úÀü¼Û HANDLE handle = NULL; MSG_SYN_ITEM_ENHANCED_END* sendMsg = (MSG_SYN_ITEM_ENHANCED_END*)NETWORK2->GetMsgRoot( &handle ,(PerSocketContext*)socketContext ,NM_ITEM ,NM_ITEM_ENHANCED_END_SYN ); sInventory* sinventory = sendMsg->Inventory; TB_INVENTORY* inventory = inventoryEnhanced->table; sendMsg->ErrorCode = ERROR_ITEM_ENHANCED_END_SUCCESS; sendMsg->RowCount = 0; for ( int i = 0; i < 3; i++, sinventory++, inventory++ ) { if ( inventory->idx > 0 ) { Inventory2sInventory( sinventory, inventory ); sendMsg->RowCount++; } } NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength() ); ChangeState( eOBJECT_STATE_IDLE ); SetStateStop( eSTOP_NONE ); // ´Ù¸¥ À¯Àúµé¿¡°Ô °á°úÀü¼Û MSG_SYN_ITEM_ENHANCED_OTHEREND sync; sync.Category = NM_ITEM; sync.Protocol = NM_ITEM_ENHANCED_OTHEREND_SYN; sync.ErrorCode = inventoryEnhanced->result; sync.characterIdx = mObject.index; NETWORK2->QuickSendExcept( this, (char*)&sync, sizeof(MSG_SYN_ITEM_ENHANCED_OTHEREND) ); // Æ©Å丮¾ó Äù½ºÆ® üũ if( IsTutorialMode() == true ) { UpdateDutyTutorial( eDUTY_ENHANCE ); } } else throw requestResult; } // CbInventoryDisjoint Method. void cPlayer::CbInventoryDisjoint(ULONG_PTR socketContext, INVENTORY_DISJOINT* inventoryDisjoint, u_long requestResult) { if ( mInventoryDb.disjoint ) mInventoryDb.disjoint = false; // DB; »ç¿ëÁ¾·á else return; if ( requestResult != 0 ) throw requestResult; if ( inventoryDisjoint->retvalue != 0 ) throw inventoryDisjoint->retvalue; // ºñ¿ë ó¸®. if ( inventoryDisjoint->characterMoney != 0 ) { unsigned long befor = GetMoney( ); long result = AddMoney( GetObject( ), inventoryDisjoint->characterMoney, false ); NETWORK2->PostMoneyEvent( inventoryDisjoint->characterIdx, befor, GetMoney( ), "INVENTORY_DISJOINT::Money(=%d)", inventoryDisjoint->characterMoney ); if ( result != inventoryDisjoint->characterMoney ) NETWORK2->PostServerEvent( "WARNING - SQL_GAME_PROCESS_INVENTORY_DISJOINT AddMoney(=%d) != ResultMoney(=%d).", inventoryDisjoint->characterMoney, result ); } // °á°ú Àü¼Û. HANDLE handle = NULL; MSG_RES_ITEM_DISJOINT_INVENTORY* sendMsg = (MSG_RES_ITEM_DISJOINT_INVENTORY*)NETWORK2->GetMsgRoot( &handle ,(PerSocketContext*)socketContext ,NM_ITEM ,NM_ITEM_DISJOINT_INVENTORY_RES ); sInventory* sinventory = sendMsg->Inventory; TB_INVENTORY* table = inventoryDisjoint->table; TB_INVENTORY* inventory = NULL; sendMsg->ErrorCode = ERROR_ITEM_DISJOINT_INVENTORY_SUCCESS; sendMsg->RowCount = 0; for ( long i = 0; i < inventoryDisjoint->rowCount; i++, table++ ) { if ( table->apply == InventoryApplyRemoved ) { NETWORK2->PostInventoryEvent( EVENT_INVENTORY_DELETE, mObject.index, table, "INVENTORY_DISJOINT" ); } else { inventory = SelectInventory( table->number ); NETWORK2->PostInventoryEvent( (inventory->idx == table->idx) ? EVENT_INVENTORY_UPDATE : EVENT_INVENTORY_CREATE ,mObject.index ,table ,"INVENTORY_DISJOINT" ); XCopyInventory( inventory, table ); Inventory2sInventory( sinventory, inventory ); sinventory++; sendMsg->RowCount++; } } NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength( ) ); } // CbInventoryPutCard Method. void cPlayer::CbInventoryPutCard(ULONG_PTR socketContext, INVENTORY_PUT_CARD* inventoryPutCard, u_long requestResult) { if ( mInventoryDb.putCard ) mInventoryDb.putCard = false; // DB; »ç¿ëÁ¾·á else return; if ( requestResult == 0 ) { TB_INVENTORY* table = inventoryPutCard->table; for ( int i = 0; i < 2; i++, table++ ) { if ( table->apply == 0 ) { // ÀåÂø ¾ÆÀÌÅÛ NETWORK2->PostInventoryEvent( EVENT_INVENTORY_UPDATE, mObject.index, table, "PUT_CARD" ); XCopyInventory( table ); HANDLE handle = NULL; MSG_RES_ITEM_PUT_CARD_INVENTORY* sendMsg = (MSG_RES_ITEM_PUT_CARD_INVENTORY*)NETWORK2->GetMsgRoot( &handle ,(PerSocketContext*)socketContext ,NM_ITEM ,NM_ITEM_PUT_CARD_INVENTORY_RES ); sendMsg->ErrorCode = ERROR_ITEM_PUT_CARD_INVENTORY_SUCCESS; Inventory2sInventory( &sendMsg->Inventory, table ); NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_ITEM_PUT_CARD_INVENTORY) ); } else { // Ä«µå ¾ÆÀÌÅÛ NETWORK2->PostInventoryEvent( EVENT_INVENTORY_DELETE, mObject.index, table, "PUT_CARD" ); RemoveInventory( table->number ); } } // Æ©Å丮¾ó Äù½ºÆ® üũ if( IsTutorialMode() == true ) { UpdateDutyTutorial( eDUTY_PUTCARD ); } } else throw requestResult; } // CbInventoryChange Method. void cPlayer::CbInventoryChange(ULONG_PTR socketContext, INVENTORY_CHANGE* inventoryChange, u_long requestResult) { if ( mInventoryDb.change ) mInventoryDb.change = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult != 0 ) throw requestResult; if ( inventoryChange->retvalue != 0 ) throw inventoryChange->retvalue; // ºñ¿ë ó¸®. if ( inventoryChange->characterMoney != 0 ) { unsigned long befor = GetMoney( ); long result = AddMoney( GetObject( ), inventoryChange->characterMoney, false ); NETWORK2->PostMoneyEvent( inventoryChange->characterIdx, befor, GetMoney( ), "INVENTORY_CHANGE::Money(=%d)", inventoryChange->characterMoney ); if ( result != inventoryChange->characterMoney ) NETWORK2->PostServerEvent( "WARNING - SQL_GAME_PROCESS_INVENTORY_CHANGE AddMoney(=%d) != ResultMoney(=%d).", inventoryChange->characterMoney, result ); } // °á°ú Àü¼Û. HANDLE handle = NULL; MSG_RES_ITEM_CHANGE_INVENTORY* sendMsg = (MSG_RES_ITEM_CHANGE_INVENTORY*)NETWORK2->GetMsgRoot( &handle ,(PerSocketContext*)socketContext ,NM_ITEM ,NM_ITEM_CHANGE_INVENTORY_RES ); sInventory* sinventory = sendMsg->Inventory; TB_INVENTORY* table = inventoryChange->table; TB_INVENTORY* inventory; sendMsg->ErrorCode = ERROR_ITEM_CHANGE_INVENTORY_SUCCESS; sendMsg->RowCount = 0; for ( long i = 0; i < inventoryChange->rowCount; i++, table++ ) { if ( table->apply == InventoryApplyRemoved ) { NETWORK2->PostInventoryEvent( EVENT_INVENTORY_DELETE, mObject.index, table, "INVENTORY_CHANGE" ); } else { inventory = SelectInventory( table->number ); NETWORK2->PostInventoryEvent( inventory->idx == table->idx ? EVENT_INVENTORY_UPDATE : EVENT_INVENTORY_CREATE ,mObject.index ,table ,"INVENTORY_CHANGE" ); XCopyInventory( table ); } Inventory2sInventory( sinventory, table ); sinventory++; sendMsg->RowCount++; } NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength( ) ); /// À¯´ÏÅ© ¾ÆÀÌÅÛ ½Àµæ SYNC TB_INVENTORY* syncTable = inventoryChange->table; TB_INVENTORY* syncInven = NULL; sInventory inven; memset( &inven, 0, sizeof(inven) ); for( long i = 0; i < inventoryChange->rowCount; i++, syncTable++ ) { syncInven = SelectInventory( syncTable->number ); if( IsInventory( syncInven ) ) { TB_ITEM_DEFINE* define = ITEMMANAGER->GetItemDefine( syncInven->itemDefineIdx ); if( define == NULL ) continue; // À¯´ÏÅ© if( define->rareLevel >= eTOOLTIP_UNIQUE && define->rareLevel <= eTOOLTIP_MAX ) { Inventory2sInventory( &inven, syncInven ); cSender* sender = g_gameSrv->GetSender( ); sender->PostUniqueItemSync( NETWORK2->GetCID( ), GetName(), (char*)&inven, sizeof(inven) ); } } } } // CbInventorySeal Method. void cPlayer::CbInventorySeal(ULONG_PTR socketContext, INVENTORY_SEAL* inventorySeal, u_long requestResult) { HANDLE handle = NULL; if ( mInventoryDb.seal ) mInventoryDb.seal = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult != 0 ) throw requestResult; if ( inventorySeal->retvalue != 0 ) throw inventorySeal->retvalue; // Àκ¥Å丮 ÀÎÁõ ¿Ï·á TB_INVENTORY* inventory = &inventorySeal->inventory; MSG_RES_ITEM_LICENSE* sendMsg = (MSG_RES_ITEM_LICENSE*)NETWORK2->GetMsgRoot( &handle, (PerSocketContext*)socketContext, NM_ITEM, NM_ITEM_LICENSE_RES ); if ( sendMsg != NULL ) { sendMsg->ErrorCode = ERROR_ITEM_LICENSE_SUCCESS; sendMsg->number = inventory->number; sendMsg->seal = inventory->seal; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_ITEM_LICENSE) ); } NETWORK2->PostInventoryEvent( EVENT_INVENTORY_UPDATE, mObject.index, inventory, "SEAL-INVENTORY" ); // ±â°£(½Ã°£) ¿Ï·á. TB_ITEM_BILL* table = &inventorySeal->itemBill; if ( table->idx != 0 ) { PerItemBill* itemBillPool = AddItemBill( table ); if ( itemBillPool != NULL ) { MSG_SYN_ITEM_BILL_ADD* sendSyn = (MSG_SYN_ITEM_BILL_ADD*)NETWORK2->GetMsgRoot( &handle, (PerSocketContext*)socketContext, NM_ITEM, NM_ITEM_BILL_ADD_SYN ); sItemBill& itemBill = sendSyn->itemBill; itemBill.idx = itemBillPool->idx; itemBill.type = itemBillPool->type; itemBill.validDate = itemBillPool->timeEnd; itemBill.validTime = itemBillPool->validTime; itemBill.inventoryIdx = itemBillPool->inventoryIdx; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_ITEM_BILL_ADD) ); } } } // CbInventoryCashSelect Method. void cPlayer::CbInventoryCashSelect( ULONG_PTR socketContext, INVENTORY_SELECT* inventorySelect, u_long requestResult ) { if ( mInventoryDb.cash ) mInventoryDb.cash = false; else return; if ( requestResult == 0 ) { TB_INVENTORY* inventory = SelectInventory( INVENTORY_CASH_ITEM_BEGIN ); TB_INVENTORY* table = &inventorySelect->table[0]; int rowCount = 0; for ( short number = INVENTORY_CASH_ITEM_BEGIN; number < INVENTORY_CASH_ITEM_END; number++, inventory++ ) { if ( rowCount < inventorySelect->rowCount ) { memcpy( inventory, table, sizeof(TB_INVENTORY) ); inventory->number = number; table++; rowCount++; } else if ( IsInventory( inventory ) == true ) { memset( inventory, 0, sizeof(TB_INVENTORY) ); } } SendInventoryCash( socketContext ); } else throw requestResult; } // CbItemSell Method. void cPlayer::CbItemSell(ULONG_PTR socketContext, ITEM_SELL* itemSell, u_long requestResult) { if ( mInventoryDb.sell ) mInventoryDb.sell = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult == 0 ) { TB_INVENTORY* table = itemSell->table; TB_INVENTORY* inventory; HANDLE handle = NULL; MSG_RES_NPC_ITEM_BUY* sendMsg = (MSG_RES_NPC_ITEM_BUY*)NETWORK2->GetMsgRoot( &handle ,(PerSocketContext*)socketContext ,NM_NPC ,NM_NPC_ITEM_SELL_RES ); sInventory* sinventory = sendMsg->inventory; sendMsg->ErrorCode = ERROR_ITEM_SELL_SUCCESS; sendMsg->rowCount = 0; for ( long i = 0; i < itemSell->rowCount; i++, table++, sinventory++ ) { inventory = SelectInventory( table->number ); if ( table->apply == InventoryApplyRemoved ) { NETWORK2->PostInventoryEvent( EVENT_INVENTORY_DELETE, mObject.index, table, "SELL-INVENTORY" ); RemoveInventory( inventory ); } else { NETWORK2->PostInventoryEvent( inventory->idx == table->idx ? EVENT_INVENTORY_UPDATE : EVENT_INVENTORY_CREATE ,mObject.index ,table ,"SELL-REWARD" ); XCopyInventory( table ); } Inventory2sInventory( sinventory, table ); sendMsg->rowCount++; } NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength( ) ); if ( itemSell->sellPrice > 0 ) { switch ( itemSell->sellType ) { case ItemSellMoney: { sObject object = { eOBJECTTYPE_NPC, itemSell->npcIdx }; long result = AddMoney( object, itemSell->sellPrice ); if ( result != itemSell->sellPrice ) NETWORK2->PostServerEvent( "WARNING - SQL_GAME_PROCESS_ITEM_SELL - CharacterIdx(%u) Money(%u)", mObject.index, GetMoney( ) ); } break; case ItemSellPvp: //Skip //AddPvPPoint( itemSell->sellPrice, eFORCETYPE_FIRE ); //AddPvPPoint( itemSell->sellPrice, eFORCETYPE_WATER ); //AddPvPPoint( itemSell->sellPrice, eFORCETYPE_WIND ); //AddPvPPoint( itemSell->sellPrice, eFORCETYPE_EARTH ); break; case ItemBuyTarot: AddTarotPoint( itemSell->sellPrice ); break; } } } else throw requestResult; } // CbItemBuy Method. void cPlayer::CbItemBuy(ULONG_PTR socketContext, ITEM_BUY* itemBuy, u_long requestResult) { if ( mInventoryDb.buy ) mInventoryDb.buy = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult == 0 ) { TB_INVENTORY* table = itemBuy->table; TB_INVENTORY* inventory; HANDLE handle = NULL; MSG_RES_NPC_ITEM_BUY* sendMsg = (MSG_RES_NPC_ITEM_BUY*)NETWORK2->GetMsgRoot( &handle ,(PerSocketContext*)socketContext ,NM_NPC ,NM_NPC_ITEM_BUY_RES ); sInventory* sinventory = sendMsg->inventory; sendMsg->ErrorCode = ERROR_ITEM_BUY_SUCCESS; sendMsg->rowCount = 0; for ( long i = 0; i < itemBuy->rowCount; i++, table++, sinventory++ ) { inventory = SelectInventory( table->number ); if ( table->apply == InventoryApplyRemoved ) { NETWORK2->PostInventoryEvent( EVENT_INVENTORY_DELETE, mObject.index, table, "BUY-INVENTORY" ); RemoveInventory( inventory ); } else { NETWORK2->PostInventoryEvent( inventory->idx == table->idx ? EVENT_INVENTORY_UPDATE : EVENT_INVENTORY_CREATE ,mObject.index ,table ,"BUY-REWARD" ); XCopyInventory( table ); } Inventory2sInventory( sinventory, table ); sendMsg->rowCount++; } NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength( ) ); if ( itemBuy->buyPrice != 0 ) { switch ( itemBuy->buyType ) { case ItemBuyMoney: { sObject object = { eOBJECTTYPE_NPC, itemBuy->npcIdx }; long result = AddMoney( object, itemBuy->buyPrice ); if ( result != itemBuy->buyPrice ) NETWORK2->PostServerEvent( "WARNING - SQL_GAME_PROCESS_ITEM_BUY - CharacterIdx(%u) Money(%u)", mObject.index, GetMoney( ) ); } break; case ItemBuyPvp: AddPvPPoint( itemBuy->buyPrice, itemBuy->buyStore ); break; case ItemBuyTarot: AddTarotPoint( itemBuy->buyPrice ); break; } } } else throw requestResult; } // CbItemCollect Method. void cPlayer::CbItemCollect(ULONG_PTR socketContext, ITEM_COLLECT* itemCollect, u_long requestResult) { if ( mInventoryDb.collect ) mInventoryDb.collect = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult != 0 ) throw requestResult; if ( itemCollect->retvalue != 0 ) throw itemCollect->retvalue; TB_INVENTORY* table = itemCollect->table; // °á°ú Àü¼Û. HANDLE handle = NULL; MSG_RES_ITEM_COLLECT* sendMsg = (MSG_RES_ITEM_COLLECT*)NETWORK2->GetMsgRoot( &handle ,(PerSocketContext*)socketContext ,NM_ITEM ,NM_ITEM_COLLECT_RES ); sendMsg->ErrorCode = ERROR_ITEM_COLLECT_SUCCESS; sendMsg->RowCount = 2; Inventory2sInventory( &sendMsg->Inventory[0], &table[0] ); // Àκ¥Å丮 Inventory2sInventory( &sendMsg->Inventory[1], &table[1] ); NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength( ) ); if ( table[2].apply == InventoryApplyRemoved ) { NETWORK2->PostInventoryEvent( EVENT_INVENTORY_DELETE, mObject.index, &table[2], "ITEM COLLECT" ); } if ( table[0].idx != table[1].idx ) { TB_INVENTORY* inventory = SelectInventory( table[1].number ); inventory->idx = table[1].idx; NETWORK2->PostInventoryEvent( EVENT_INVENTORY_UPDATE, mObject.index, &table[0], "ITEM COLLECT" ); NETWORK2->PostInventoryEvent( EVENT_INVENTORY_CREATE, mObject.index, &table[1], "ITEM COLLECT" ); } } // CbItemCollectChange Method. void cPlayer::CbItemCollectChange(ULONG_PTR socketContext, ITEM_COLLECT_CHANGE* itemCollect, u_long requestResult) { if ( mInventoryDb.collect ) mInventoryDb.collect = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult != 0 ) throw requestResult; if ( itemCollect->retvalue != 0 ) throw itemCollect->retvalue; TB_INVENTORY* changeItem = &itemCollect->changeItem; TB_INVENTORY* tarotCard = itemCollect->table; TB_INVENTORY* inventory = NULL; // °á°ú Àü¼Û. HANDLE handle = NULL; MSG_RES_COLLECT_CARD_CHANGE* sendMsg = (MSG_RES_COLLECT_CARD_CHANGE*)NETWORK2->GetMsgRoot( &handle ,(PerSocketContext*)socketContext ,NM_ITEM ,NM_ITEM_COLLECT_CARD_CHANGE_RES ); sInventory* sinventory = sendMsg->Inventory; sendMsg->ErrorCode = ERROR_ITEM_COLLECT_CARD_CHANGE_SUCCESS; // üÀÎÁö ¾ÆÀÌÅÛ inventory = SelectInventory( changeItem->number ); NETWORK2->PostInventoryEvent( (inventory->idx != changeItem->idx) ? EVENT_INVENTORY_CREATE : EVENT_INVENTORY_UPDATE, mObject.index, changeItem, "COLLECT-CHANGE" ); XCopyInventory( changeItem ); Inventory2sInventory( sinventory, changeItem ); sinventory++; sendMsg->RowCount++; // Ÿ·ÎÄ«µå 22Àå for ( long i = 0; i < itemCollect->rowCount; i++, sinventory++, tarotCard++ ) { Inventory2sInventory( sinventory, tarotCard ); sendMsg->RowCount++; inventory = SelectInventory( tarotCard->number ); if ( tarotCard->apply == InventoryApplyRemoved ) { NETWORK2->PostInventoryEvent( EVENT_INVENTORY_DELETE, mObject.index, tarotCard, "COLLECT-CHANGE" ); RemoveInventory( inventory ); } else { NETWORK2->PostInventoryEvent( EVENT_INVENTORY_UPDATE, mObject.index, tarotCard, "COLLECT-CHANGE" ); } } NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength( ) ); } // CbItemGet Method. void cPlayer::CbItemGet(ULONG_PTR socketContext, ITEM_GET* itemGet, u_long requestResult) { if ( mInventoryDb.get ) mInventoryDb.get = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult != 0 ) throw requestResult; HANDLE handle = NULL; MSG_RES_ITEM_GET* sendMsg = (MSG_RES_ITEM_GET*)NETWORK2->GetMsgRoot( &handle ,(PerSocketContext*)socketContext ,NM_ITEM ,NM_ITEM_GET_RES ); BYTE& rowCount = sendMsg->RowCount; sInventory* sinventory = sendMsg->Inventory; int error = ERROR_ITEM_GET_SUCCESS; TB_INVENTORY* table = itemGet->table; TB_INVENTORY* inventory; for ( long i = 0; i < itemGet->rowCount; i++, table++ ) { inventory = SelectInventory( table->number ); if ( inventory->apply == InventoryApplyGetAuto ) error = ERROR_ITEM_GET_AUTO; NETWORK2->PostInventoryEvent( (inventory->idx == table->idx) ? EVENT_INVENTORY_UPDATE : EVENT_INVENTORY_CREATE, mObject.index, table, "GET" ); XCopyInventory( inventory, table ); Inventory2sInventory( sinventory, table ); rowCount++; sinventory++; } sendMsg->ErrorCode = error; NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength( ) ); /// ÆÄƼ¿¡ send cParty* party = PARTYMAN->GetParty( mPlayerExrInfo.mPartyIndex ); if ( party != NULL ) { unsigned long* userArr = party->GetUserArr( ); unsigned int partyCount = party->GetCount( ); cPlayer* partyUser; for ( unsigned int i = 0; i < partyCount; ++i, ++userArr ) { if ( (*userArr) != mObject.index ) { partyUser = OBJECTMANAGER->GetPlayer( (*userArr) ); if ( partyUser != NULL ) { /// ȹµæ ¾ÆÀÌÅÛ µ¥ÀÌÅÍ ´ã±â MSG_SYN_PARTY_ITEMGET* partySend = (MSG_SYN_PARTY_ITEMGET*)NETWORK2->GetMsgRoot( &handle ,partyUser->GetConnectionIdx( ) ,NM_PARTY ,NM_PARTY_ITEMGET_SYN ); if ( partySend != NULL ) { unsigned long length = sizeof(MSG_SYN_PARTY_ITEMGET) - sizeof(partySend->ItemIndex); short& rowCount = partySend->RowCount; unsigned long* itemIndex = partySend->ItemIndex; partySend->UserIndex = mObject.index; rowCount = 0; table = itemGet->table; for ( long i = 0; i < itemGet->rowCount; ++i, ++table ) { (*itemIndex) = table->itemDefineIndex; rowCount++; itemIndex++; } length += (rowCount * sizeof(partySend->ItemIndex)); NETWORK2->SendMsgRoot( handle, length ); } } } } } // À¯´ÏÅ© ½Àµæ SYNC TB_INVENTORY* syncTable = itemGet->table; TB_INVENTORY* syncInven = NULL; sInventory inven; memset( &inven, 0, sizeof(inven) ); for( long i = 0; i < itemGet->rowCount; i++, syncTable++ ) { syncInven = SelectInventory( syncTable->number ); if( IsInventory( syncInven ) ) { TB_ITEM_DEFINE* define = ITEMMANAGER->GetItemDefine( syncInven->itemDefineIdx ); if( define == NULL ) continue; // À¯´ÏÅ© if( define->rareLevel >= eTOOLTIP_UNIQUE && define->rareLevel <= eTOOLTIP_MAX ) { Inventory2sInventory( &inven, syncInven ); cSender* sender = g_gameSrv->GetSender( ); sender->PostUniqueItemSync( NETWORK2->GetCID( ), GetName(), (char*)&inven, sizeof(inven) ); } } } } // CbItemGetQuest Method. void cPlayer::CbItemGetQuest(ULONG_PTR socketContext, ITEM_GET* itemGet, u_long requestResult) { if ( requestResult == 0 ) { HANDLE handle = NULL; MSG_RES_ITEM_GET_QUEST* sendMsg = (MSG_RES_ITEM_GET_QUEST*)NETWORK2->GetMsgRoot( &handle ,(PerSocketContext*)socketContext ,NM_ITEM ,NM_ITEM_GET_QUEST_RES ); BYTE& rowCount = sendMsg->RowCount; sInventory* sinventory = sendMsg->Inventory; TB_INVENTORY* table = itemGet->table; TB_INVENTORY* inventory; for ( long i = 0; i < itemGet->rowCount; i++, table++ ) { inventory = SelectInventory( table->number ); NETWORK2->PostInventoryEvent( (inventory->idx == table->idx) ? EVENT_INVENTORY_UPDATE : EVENT_INVENTORY_CREATE, mObject.index, table, "GET_QUEST" ); XCopyInventory( inventory, table ); Inventory2sInventory( sinventory, table ); rowCount++; sinventory++; } sendMsg->ErrorCode = ERROR_ITEM_GET_QUEST_SUCCESS; NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength( ) ); } else throw requestResult; } // CbItemPartyGive Method. void cPlayer::CbItemPartyGive(ULONG_PTR socketContext, ITEM_PARTY_GIVE* itemPartyGive, u_long requestResult) { if ( mInventoryDb.get ) mInventoryDb.get = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult != 0 ) throw requestResult; // ÆÄƼÀå¿¡ °á°ú Àü¼Û cPlayer* pGivePlayer = OBJECTMANAGER->GetPlayer( itemPartyGive->giveCharacterIdx ); if ( pGivePlayer ) { NETWORK2->SendMsgError( pGivePlayer->GetConnectionIdx(), NM_ITEM, NM_ITEM_PARTY_GIVE_RES, 0 ); } // ¾ÆÀÌÅÛ Áö±Þ Àü¼Û HANDLE handle = NULL; MSG_SYN_ITEM_PARTY_GIVE* sendMsg = (MSG_SYN_ITEM_PARTY_GIVE*)NETWORK2->GetMsgRoot( &handle ,(PerSocketContext*)socketContext ,NM_ITEM ,NM_ITEM_PARTY_GIVE_SYN ); sInventory* sinventory = sendMsg->inventory; TB_INVENTORY* table = itemPartyGive->table; TB_INVENTORY* inventory; for ( long i = 0; i < itemPartyGive->rowCount; i++, table++ ) { inventory = SelectInventory( table->number ); NETWORK2->PostInventoryEvent( (inventory->idx == table->idx) ? EVENT_INVENTORY_UPDATE : EVENT_INVENTORY_CREATE, mObject.index, table, "PARTY-GIVE" ); XCopyInventory( inventory, table ); Inventory2sInventory( sinventory, table ); sendMsg->rowCount++; sinventory++; } NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength( ) ); /// ÆÄƼ¿¡ send cParty* party = PARTYMAN->GetParty( mPlayerExrInfo.mPartyIndex ); if ( party != NULL ) { unsigned long* userArr = party->GetUserArr( ); unsigned int partyCount = party->GetCount( ); cPlayer* partyUser; for ( unsigned int i = 0; i < partyCount; ++i, ++userArr ) { if ( (*userArr) != mObject.index ) { partyUser = OBJECTMANAGER->GetPlayer( (*userArr) ); if ( partyUser != NULL ) { /// ȹµæ ¾ÆÀÌÅÛ µ¥ÀÌÅÍ ´ã±â MSG_SYN_PARTY_ITEMGET* partySend = (MSG_SYN_PARTY_ITEMGET*)NETWORK2->GetMsgRoot( &handle ,partyUser->GetConnectionIdx( ) ,NM_PARTY ,NM_PARTY_ITEMGET_SYN ); if ( partySend != NULL ) { unsigned long length = sizeof(MSG_SYN_PARTY_ITEMGET) - sizeof(partySend->ItemIndex); unsigned long* itemIndex = partySend->ItemIndex; partySend->UserIndex = mObject.index; table = itemPartyGive->table; for ( long i = 0; i < itemPartyGive->rowCount; ++i, ++table ) { (*itemIndex) = table->itemDefineIndex; itemIndex++; partySend->RowCount++; } length += (partySend->RowCount * sizeof(partySend->ItemIndex)); NETWORK2->SendMsgRoot( handle, length ); } } } } // for } // À¯´ÏÅ© ¾ÆÀÌÅÛ ½Àµæ SYNC TB_INVENTORY* syncTable = itemPartyGive->table; TB_INVENTORY* syncInven = NULL; sInventory inven; memset( &inven, 0, sizeof(inven) ); for( long i = 0; i < itemPartyGive->rowCount; i++, syncTable++ ) { syncInven = SelectInventory( syncTable->number ); if( IsInventory( syncInven ) ) { TB_ITEM_DEFINE* define = ITEMMANAGER->GetItemDefine( syncInven->itemDefineIdx ); if( define == NULL ) continue; // À¯´ÏÅ© if( define->rareLevel >= eTOOLTIP_UNIQUE && define->rareLevel <= eTOOLTIP_MAX ) { Inventory2sInventory( &inven, syncInven ); cSender* sender = g_gameSrv->GetSender( ); sender->PostUniqueItemSync( NETWORK2->GetCID( ), GetName(), (char*)&inven, sizeof(inven) ); } } } } // CbItemUse Method. void cPlayer::CbItemUse(ULONG_PTR socketContext, ITEM_USE* itemUse, u_long requestResult) { if ( requestResult == 0 ) { UNREFERENCED_PARAMETER(socketContext); UNREFERENCED_PARAMETER(itemUse); } else throw requestResult; } // CbItemSummonPost Method. void cPlayer::CbItemSummonPost(ULONG_PTR socketContext, ITEM_SUMMON_POST* summonPost, u_long requestResult) { if ( mInventoryDb.use ) mInventoryDb.use = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult != 0 ) throw requestResult; TB_INVENTORY* inventory = &(summonPost->inventory); if ( inventory->apply == InventoryApplyRemoved ) { NETWORK2->PostInventoryEvent( EVENT_INVENTORY_DELETE, mObject.index, inventory, "SUMMON POST" ); } else { NETWORK2->PostInventoryEvent( EVENT_INVENTORY_UPDATE, mObject.index, inventory, "SUMMON POST" ); } // »óÅ º¯°æ ChangeState( eOBJECT_STATE_STOP ); SetStateStop( eSTOP_SUMMON_PAPER ); // °á°ú Àü¼Û. HANDLE handle = NULL; MSG_RES_TRADE_POST_SUMMON_OPEN* sendMsg = (MSG_RES_TRADE_POST_SUMMON_OPEN*)NETWORK2->GetMsgRoot( &handle ,(PerSocketContext*)socketContext ,NM_TRADE ,NM_TRADE_POST_SUMMON_OPEN_RES ); sendMsg->ErrorCode = ERROR_TRADE_POST_SUMMON_OPEN_SUCCESS; Inventory2sInventory( &sendMsg->inventory, inventory ); NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_TRADE_POST_SUMMON_OPEN) ); // ¿ìÆí ¸®½ºÆ® Àü¼Û SendPostSelect( socketContext, summonPost->startPage, summonPost->endPage, summonPost->noneRead, summonPost->post, summonPost->postCount ); // ´Ù¸¥ Ç÷¹À̾îµé¿¡°Ôµµ ¾Ë¸² MSG_SYN_TRADE_POST_SUMMON_OPEN synMsg; synMsg.Category = NM_TRADE; synMsg.Protocol = NM_TRADE_POST_SUMMON_OPEN_SYN; synMsg.characterIdx = mObject.index; NETWORK2->QuickSendExcept( this, (char*)&synMsg, sizeof(synMsg) ); } // CbItemSummonAgent Method. void cPlayer::CbItemSummonAgent(ULONG_PTR socketContext, ITEM_SUMMON_AGENT* summonAgent, u_long requestResult) { if ( mInventoryDb.use ) mInventoryDb.use = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult != 0 ) throw requestResult; TB_INVENTORY* inventory = &(summonAgent->inventory); if ( inventory->apply == InventoryApplyRemoved ) { NETWORK2->PostInventoryEvent( EVENT_INVENTORY_DELETE, mObject.index, inventory, "SUMMON AGENT" ); } else { NETWORK2->PostInventoryEvent( EVENT_INVENTORY_UPDATE, mObject.index, inventory, "SUMMON AGENT" ); } // »óÅ º¯°æ ChangeState( eOBJECT_STATE_STOP ); SetStateStop( eSTOP_SUMMON_PAPER ); // °á°ú Àü¼Û. HANDLE handle = NULL; MSG_RES_TRADE_AGENT_SUMMON_OPEN* sendMsg = (MSG_RES_TRADE_AGENT_SUMMON_OPEN*)NETWORK2->GetMsgRoot( &handle ,(PerSocketContext*)socketContext ,NM_TRADE ,NM_TRADE_AGENT_SUMMON_OPEN_RES ); sendMsg->ErrorCode = ERROR_TRADE_AGENT_SUMMON_OPEN_SUCCESS; // ¼Òȯ ÁÖ¹®¼­ Inventory2sInventory( &sendMsg->inventory, inventory ); // ÆÇ¸Å ´ëÇà ITEM_AGENT_RESULT_OWNER* result = summonAgent->agent; NPC_ITEM_AGENT_OPEN_RESULT* sendResult = sendMsg->Agent; sendMsg->StartPage = summonAgent->startPage; sendMsg->EndPage = summonAgent->endPage; sendMsg->RowCount = summonAgent->rowCount; for ( long i = 0; i < summonAgent->rowCount; i++, result++, sendResult++ ) { sendResult->Idx = result->idx; sendResult->ValidThru = result->validThru; sendResult->Price = result->price; Inventory2sInventory( &sendResult->Inventory, &result->table ); } NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength() ); // ´Ù¸¥ Ç÷¹À̾îµé¿¡°Ôµµ ¾Ë¸² MSG_SYN_TRADE_AGENT_SUMMON_OPEN synMsg; synMsg.Category = NM_TRADE; synMsg.Protocol = NM_TRADE_AGENT_SUMMON_OPEN_SYN; synMsg.characterIdx = mObject.index; NETWORK2->QuickSendExcept( this, (char*)&synMsg, sizeof(synMsg) ); } // CbItemSummonWareHouse Method. void cPlayer::CbItemSummonWareHouse(ULONG_PTR socketContext, ITEM_SUMMON_WAREHOUSE* summonWare, u_long requestResult) { if ( mInventoryDb.use ) mInventoryDb.use = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult != 0 ) throw requestResult; TB_INVENTORY* inventory = &(summonWare->inventory); if ( inventory->apply == InventoryApplyRemoved ) { NETWORK2->PostInventoryEvent( EVENT_INVENTORY_DELETE, mObject.index, inventory, "SUMMON WAREHOUSE" ); } else { NETWORK2->PostInventoryEvent( EVENT_INVENTORY_UPDATE, mObject.index, inventory, "SUMMON WAREHOUSE" ); } // »óÅ º¯°æ ChangeState( eOBJECT_STATE_STOP ); SetStateStop( eSTOP_SUMMON_PAPER ); // °á°ú Àü¼Û. HANDLE handle = NULL; MSG_RES_ITEM_WAREHOUSE_SUMMON_OPEN* sendMsg = (MSG_RES_ITEM_WAREHOUSE_SUMMON_OPEN*)NETWORK2->GetMsgRoot( &handle ,(PerSocketContext*)socketContext ,NM_ITEM ,NM_ITEM_WAREHOUSE_SUMMON_OPEN_RES ); sendMsg->ErrorCode = ERROR_ITEM_WAREHOUSE_SUMMON_OPEN_SUCCESS; Inventory2sInventory( &sendMsg->inventory, inventory ); NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_ITEM_WAREHOUSE_SUMMON_OPEN) ); // ´Ù¸¥ Ç÷¹À̾îµé¿¡°Ôµµ ¾Ë¸² MSG_SYN_ITEM_WAREHOUSE_SUMMON_OPEN synMsg; synMsg.Category = NM_ITEM; synMsg.Protocol = NM_ITEM_WAREHOUSE_SUMMON_OPEN_SYN; synMsg.characterIdx = mObject.index; NETWORK2->QuickSendExcept( this, (char*)&synMsg, sizeof(synMsg) ); } // CbItemObtEvent Method. void cPlayer::CbItemObtEvent(ULONG_PTR socketContext, ITEM_OBT_EVENT* itemEvent, u_long requestResult) { if ( mInventoryDb.cash ) mInventoryDb.cash = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult != 0 ) throw requestResult; // ·Î±× ÀúÀå for ( int i = 0; i < itemEvent->rowCount; i++ ) { TB_INVENTORY* table = &(itemEvent->table[i]); if ( table ) { if ( table->apply == InventoryApplyRemoved ) { NETWORK2->PostInventoryEvent( EVENT_INVENTORY_DELETE, mObject.index, table, "OBT EVENT" ); } else { NETWORK2->PostInventoryEvent( EVENT_INVENTORY_CREATE, mObject.index, table, "OBT EVENT" ); } } } // °á°ú Àü¼Û. HANDLE handle = NULL; MSG_RES_NPC_OBT_EVENT* sendMsg = (MSG_RES_NPC_OBT_EVENT*)NETWORK2->GetMsgRoot( &handle ,(PerSocketContext*)socketContext ,NM_NPC ,NM_NPC_OBT_EVENT_RES ); if ( itemEvent->retvalue == 0 ) { sendMsg->ErrorCode = ERROR_NPC_OBT_EVENT_SUCCESS; // À̺¥Æ® ¿Ï·á ¼³Á¤ HANDLE handle = NULL; MEMBER_OBT_EVENT_COMPLETE* eventComplete = (MEMBER_OBT_EVENT_COMPLETE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_MEMBER_OBT_EVENT_COMPLETE ); eventComplete->memberIdx = mConnectionIdx; eventComplete->cbtUser = itemEvent->cbtUser; eventComplete->obtUser = itemEvent->obtUser; eventComplete->fourGamer = itemEvent->fourGamer; eventComplete->retvalue = 0; if ( NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, sizeof(MEMBER_OBT_EVENT_COMPLETE), COMMON_DB_MEMBER_OBT_EVENT_COMPLETE ) == false ) { NETWORK2->PostServerEvent("ERROR - COMMON_DB_MEMBER_OBT_EVENT_COMPLETE SendSQL FAIL [member:%d][cbtUser:%d,obtUser:%d,fourGamer:%d]", mConnectionIdx, itemEvent->cbtUser, itemEvent->obtUser, itemEvent->fourGamer); } } else { sendMsg->ErrorCode = ERROR_NPC_OBT_EVENT_FAIL; } NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_NPC_OBT_EVENT) ); } void cPlayer::CbItemNpcEvent( ULONG_PTR socketContext, ITEM_NPC_EVENT* npcEvent, u_long requestResult ) { if ( mInventoryDb.cash ) mInventoryDb.cash = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult != 0 ) throw requestResult; // ·Î±× ÀúÀå for ( int i = 0; i < npcEvent->rowCount; i++ ) { TB_INVENTORY* table = &(npcEvent->table[i]); if ( table ) { if ( table->apply == InventoryApplyRemoved ) { NETWORK2->PostInventoryEvent( EVENT_INVENTORY_DELETE, mObject.index, table, "NPC EVENT" ); } else { NETWORK2->PostInventoryEvent( EVENT_INVENTORY_CREATE, mObject.index, table, "NPC EVENT" ); } } } // °á°ú Àü¼Û. HANDLE handle = NULL; MSG_RES_NPC_EVENT_ITEM_GIVE* sendMsg = (MSG_RES_NPC_EVENT_ITEM_GIVE*)NETWORK2->GetMsgRoot( &handle ,(PerSocketContext*)socketContext ,NM_NPC ,NM_NPC_EVENT_ITEM_GIVE_RES ); sendMsg->ErrorCode = npcEvent->retvalue; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_NPC_EVENT_ITEM_GIVE) ); } // CbStallSellGet Method. void cPlayer::CbStallSellGet(ULONG_PTR socketContext, STALL_SELL_GET* stallSellGet, u_long requestResult) { if ( mInventoryDb.stallSellGet ) mInventoryDb.stallSellGet = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult == 0 ) { TB_INVENTORY* inventory; unsigned long befor = GetMoney( ); long result = AddMoney( stallSellGet->fObject, stallSellGet->tCharacterMoney, false ); unsigned long after = GetMoney( ); // ·Î±× Àü¼Û. NETWORK2->PostMoneyEvent( GetObjectID( ) ,befor ,after ,"STALL_SELL_GET(BUY)::Character(=%d):Money(=%d)" ,stallSellGet->fObject.index ,stallSellGet->tCharacterMoney ); NETWORK2->PostInventoryEvent( EVENT_INVENTORY_CREATE ,mObject.index ,&stallSellGet->tInventory ,"STALL SELL - BUY CHARACTER_IDX=%d INVENTORY_IDX=%d" ,stallSellGet->fObject.index ,stallSellGet->fInventory.idx ); // ¿À·ù °Ë»ç. if ( result != stallSellGet->tCharacterMoney ) NETWORK2->PostServerEvent( "Error - SQL_GAME_PROCESS_STALL_SELL_GET AddMoney(=%d) != ResultMoney(=%d).", stallSellGet->tCharacterMoney, result ); // °á°ú Àü¼Û. HANDLE handle = NULL; MSG_RES_ITEM_STALL_SELL_GET* sendMsg = (MSG_RES_ITEM_STALL_SELL_GET*)NETWORK2->GetMsgRoot( &handle ,(PerSocketContext*)socketContext ,NM_ITEM ,NM_ITEM_STALL_SELL_GET_RES ); sendMsg->ErrorCode = ERROR_ITEM_STALL_SELL_GET_SUCCESS; inventory = XCopyInventory( &stallSellGet->tInventory ); Inventory2sInventory( &sendMsg->Inventory, inventory ); NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_ITEM_STALL_SELL_GET) ); } else throw requestResult; } // CbCharacterSkillreset Method. void cPlayer::CbCharacterSkillreset(ULONG_PTR socketContext, CHARACTER_SKILL_RESET* characterSkillReset, u_long requestResult) { if ( mInventoryDb.skillReset ) { mInventoryDb.skillReset = false; // DB; »ç¿ëÁ¾·á. mIsDbUpdate = false; } else return; if ( requestResult == 0 ) { ChangeState( eOBJECT_STATE_IDLE ); SetStateStop( eSTOP_NONE ); if ( characterSkillReset->mRetvalue == ERROR_SKILLRESET_SUCCESS ) { /// ¼º°øÃ³¸® & ¸Þ¼¼Áö ¹ß¼Û SetSkillReset( characterSkillReset->mTable, characterSkillReset->mRowCount ); /// ¾ÆÀÌÅÛ Á¤º¸ °»½Å if ( characterSkillReset->mItem.idx != 0 ) { HANDLE handle = NULL; MSG_RES_ITEM_SKILLRESET* sendMsg = (MSG_RES_ITEM_SKILLRESET*)NETWORK2->GetMsgRoot( &handle ,(PerSocketContext*)socketContext ,NM_ITEM ,NM_ITEM_SKILLRESET_RES ); sInventory* sinventory = &sendMsg->inventory; TB_INVENTORY* table = &characterSkillReset->mItem; TB_INVENTORY* inventory; if ( table->apply == InventoryApplyRemoved ) { NETWORK2->PostInventoryEvent( EVENT_INVENTORY_DELETE, mObject.index, table, "SKILLRESET DELETE BY ITEM" ); table->count = 0; // Ŭ¶óÀÌ¾ðÆ® »èÁ¦ ¿äû¸¦ À§ÇØ 0À¸·Î ¼³Á¤. } else { inventory = SelectInventory( table->number ); if ( inventory->idx == table->idx ) NETWORK2->PostInventoryEvent( EVENT_INVENTORY_UPDATE, mObject.index, table, "SKILLRESET DELETE BY ITEM" ); else NETWORK2->PostInventoryEvent( EVENT_INVENTORY_CREATE, mObject.index, table, "SKILLRESET DELETE BY ITEM" ); inventory = XCopyInventory( inventory, table ); } Inventory2sInventory( sinventory, table ); sinventory++; NETWORK2->SendMsgRoot( handle, sizeof( MSG_RES_ITEM_SKILLRESET ) ); } NETWORK2->PostSkillEvent( mObject.index, true, 0, 0 ); } else { /// ó¸® ½ÇÆÐ ¸Þ¼¼Áö ¹ß¼Û NETWORK2->SendMsgError( (PerSocketContext*)socketContext, NM_PLAYER, NM_PLAYER_SKILLRESET_RES, characterSkillReset->mRetvalue ); NETWORK2->PostServerEvent(" SQL_GAME_PROCESS_CHARACTER_SKILLRESET [%d]", characterSkillReset->mRetvalue ); } // ij¸¯ÅÍ À̺¥Æ®. PostCharacterEvent( EVENT_CHARACTER_UPDATE, "Skill - Reset" ); } else throw requestResult; } // CbCharacterThemeReset Method. void cPlayer::CbCharacterThemeReset(ULONG_PTR socketContext, CHARACTER_THEME_RESET* characterThemeReset, u_long requestResult) { if ( mInventoryDb.themeReset ) mInventoryDb.themeReset = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult != 0 ) throw requestResult; ChangeState( eOBJECT_STATE_IDLE ); SetStateStop( eSTOP_NONE ); /// db°á°ú üũ switch( characterThemeReset->mRetvalue ) { case ERROR_SKILLRESET_SUCCESS: break; case 1: NETWORK2->SendMsgError( (PerSocketContext*)socketContext, NM_ITEM, NM_ITEM_THEMERESET_RES, ERROR_THEMERESET_READY ); break; default: /// ó¸® ½ÇÆÐ ¸Þ¼¼Áö ¹ß¼Û NETWORK2->SendMsgError( (PerSocketContext*)socketContext, NM_ITEM, NM_ITEM_THEMERESET_RES, ERROR_THEMERESET_DBERROR ); NETWORK2->PostServerEvent("cPlayer::CbCharacterThemeReset [%d]", characterThemeReset->mRetvalue ); return; } // ±âÁ¸ Å׸¶ Á¤º¸ »èÁ¦ PerThemeUser* perThemeUser = (PerThemeUser*)mThemeUserRoot.pool; while( perThemeUser != NULL ) { PerThemeUser* pDel = perThemeUser; perThemeUser = (PerThemeUser*)perThemeUser->next; THEMEUSERPOOL->ReleaseThemeUser( &mThemeUserRoot, pDel ); } /// Å׸¶ Á¤º¸ ±â·Ï THEME_USER* pTable = characterThemeReset->mTable; AddThemeUser( pTable, characterThemeReset->mRowCount ); /// ¸Þ¼¼Áö HANDLE handle = NULL; MSG_RES_ITEM_THEMERESET* sendMsg = (MSG_RES_ITEM_THEMERESET*)NETWORK2->GetMsgRoot( &handle ,(PerSocketContext*)socketContext ,NM_ITEM, NM_ITEM_THEMERESET_RES ); sInventory* sinventory = &sendMsg->mInventory; sendMsg->mThemeNum = characterThemeReset->mThemeIdx; sendMsg->mThemeMode = characterThemeReset->mThemeMode; /// ¾ÆÀÌÅÛ Á¤º¸ °»½Å if ( characterThemeReset->mItem.idx != 0 ) { TB_INVENTORY* table = &characterThemeReset->mItem; TB_INVENTORY* inventory; if ( table->apply == InventoryApplyRemoved ) { NETWORK2->PostInventoryEvent( EVENT_INVENTORY_DELETE, mObject.index, table, "THEMERESET DELETE BY ITEM" ); table->count = 0; // Ŭ¶óÀÌ¾ðÆ® »èÁ¦ ¿äû¸¦ À§ÇØ 0À¸·Î ¼³Á¤. } else { inventory = SelectInventory( table->number ); if ( inventory->idx == table->idx ) NETWORK2->PostInventoryEvent( EVENT_INVENTORY_UPDATE, mObject.index, table, "THEMERESET DELETE BY ITEM" ); else NETWORK2->PostInventoryEvent( EVENT_INVENTORY_CREATE, mObject.index, table, "THEMERESET DELETE BY ITEM" ); inventory = XCopyInventory( inventory, table ); } Inventory2sInventory( sinventory, table ); sinventory++; } else { sinventory->number = characterThemeReset->mSlotNum; NETWORK2->PostServerEvent(" SQL_GAME_PROCESS_CHARACTER_SKILLRESET characterThemeReset->mItem.idx == 0[%d]", characterThemeReset->mRetvalue ); } /// ¸Þ¼¼Áö ¹ß¼Û NETWORK2->SendMsgRoot( handle, sizeof( MSG_RES_ITEM_THEMERESET ) ); } void cPlayer::CbCharacterGMThemeReset( CHARACTER_GM_THEME_RESET* characterThemeReset ) { // ±âÁ¸ Å׸¶ Á¤º¸ »èÁ¦ PerThemeUser* perThemeUser = (PerThemeUser*)mThemeUserRoot.pool; while( perThemeUser != NULL ) { PerThemeUser* pDel = perThemeUser; perThemeUser = (PerThemeUser*)perThemeUser->next; THEMEUSERPOOL->ReleaseThemeUser( &mThemeUserRoot, pDel ); } /// Å׸¶ Á¤º¸ ±â·Ï THEME_USER* pTable = characterThemeReset->mTable; AddThemeUser( pTable, characterThemeReset->mRowCount ); /// ¸Þ¼¼Áö HANDLE handle = NULL; MSG_SYN_CHEAT_THEMERESET* sendMsg = (MSG_SYN_CHEAT_THEMERESET*)NETWORK2->GetMsgRoot( &handle ,mConnectionIdx, NM_CHEAT, NM_CHEAT_GM_THEME_RESET_SYN ); if( handle ) { sendMsg->mThemeNum = characterThemeReset->mThemeIdx; sendMsg->mThemeMode = characterThemeReset->mThemeMode; /// ¸Þ¼¼Áö ¹ß¼Û NETWORK2->SendMsgRoot( handle, sizeof( MSG_SYN_CHEAT_THEMERESET ) ); } } // CbInventoryReward Method. void cPlayer::CbInventoryReward( ) { mInventoryDb.reward = false; // DB; »ç¿ëÁ¾·á. } // CbInventoryTake Method. void cPlayer::CbInventoryTake( ) { mInventoryDb.take = false; // DB; »ç¿ëÁ¾·á. } bool cPlayer::CbInventoryItemMix( ) { mInventoryDb.itemMix = false; return false; } // ItemGetOpen Method. void cPlayer::ItemGetOpen(MSG_REQ_ITEM_GET_OPEN* msg) { if ( GetStateDie( ) == true ) throw ERROR_ITEM_GET_OPEN_FAIL; if ( IsChangeState( ePLAYER_STATE_ITEMPICK ) == false ) throw ERROR_ITEM_GET_OPEN_FAIL; if ( mItemGetOpen == true ) { cItem* item = OBJECTMANAGER->GetItem( mItemGetIdx ); if ( item != NULL ) { if ( item->IsOpen( this ) ) item->Close( ); } ItemGetClose( ); } cItem* item = OBJECTMANAGER->GetItem( msg->idx ); if ( item == NULL ) throw ERROR_ITEM_GET_OPEN_FAIL; item->Open( this ); mItemGetOpen = true; mItemGetIdx = item->GetObjectID( ); if ( ChangeState( ePLAYER_STATE_ITEMPICK ) == false ) throw ERROR_ITEM_GET_OPEN_FAIL; SendItemGetOpen( item ); } // ItemGetClose Method. void cPlayer::ItemGetClose(MSG_REQ_ITEM_GET_CLOSE* /*msg*/) { if ( mItemGetOpen == false ) throw ERROR_ITEM_GET_CLOSE_FAIL; cItem* item = OBJECTMANAGER->GetItem( mItemGetIdx ); if ( item == NULL ) throw ERROR_ITEM_GET_CLOSE_FAIL; if ( !item->IsOpen( this ) ) throw ERROR_ITEM_GET_CLOSE_FAIL; if ( !item->Close( ) ) throw ERROR_ITEM_GET_CLOSE_FAIL; ItemGetClose( ); } void cPlayer::ItemGetClose( ) { mItemGetIdx = 0; mItemGetOpen = false; if ( GetState( ) == ePLAYER_STATE_ITEMPICK ) ChangeState( eOBJECT_STATE_IDLE ); SendItemGetClose( ); } // ItemGet Method. void cPlayer::ItemGet(MSG_REQ_ITEM_GET* msg) { if ( mInventoryDatabase ) throw ERROR_ITEM_GET_FAIL; if ( GetStateDie( ) == true ) throw ERROR_ITEM_GET_FAIL; if ( mItemGetOpen == false ) throw ERROR_ITEM_GET_FAIL; cItem* item = OBJECTMANAGER->GetItem( mItemGetIdx ); if ( item == NULL ) throw ERROR_ITEM_GET_FAIL; if ( !item->IsOpen( this ) ) throw ERROR_ITEM_GET_FAIL; BYTE rowCount = 0; sItemData* itemData = item->GetItemData( rowCount ); if ( rowCount > 0 && itemData != NULL ) { HANDLE handle = NULL; ITEM_GET* itemGet = (ITEM_GET*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_GET ); u_long length = sizeof(ITEM_GET) - sizeof(itemGet->table); BYTE& count = (BYTE&)itemGet->rowCount; itemGet->characterIdx = mObject.index; for ( int i = 0; (i < MAX_ITEMS) && (rowCount > 0); i++, itemData++ ) { if ( itemData->itemDefineIndex > 0 && itemData->count > 0 ) { bool getBegin = false; bool getEnd = false; if ( msg->itemIndexOrInd == ITEM_GET_ALL ) { getBegin = true; } else if ( msg->itemIndexOrInd == itemData->itemDefineIndex ) { getBegin = true; getEnd = true; } if ( getBegin == true ) { TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefineByIndex( itemData->itemDefineIndex ); TB_INVENTORY* inventory; short remainCount = itemData->count; short shortCount; short number; if( IsMaxInventory( itemDefine, remainCount ) == true ) continue; // ¾ÆÀÌÅÛ Áݱâ. °ãÄ¡±â °Ë»ç ¹× ó¸®. if ( FindFirstInventory( itemDefine, &number, remainCount, &shortCount, true ) == true ) { do { inventory = SelectInventory( number ); shortCount = UpdateInventory( inventory, remainCount ); remainCount = remainCount - shortCount; itemGet->table[ count ].idx = inventory->idx; itemGet->table[ count ].itemDefineIdx = itemDefine->idx; itemGet->table[ count ].itemDefineIndex = itemDefine->index; itemGet->table[ count ].number = number; itemGet->table[ count ].count = shortCount; count++; item->PopItem( itemDefine->index, shortCount ); // ¾ÆÀÌÅÛ Â÷°¨. } while ( FindNextInventory( itemDefine, &(++number), remainCount, &shortCount, true ) == true ); } // ¾ÆÀÌÅÛ Áݱâ. »ý¼º °Ë»ç ¹× µî·Ï. if ( FindFirstInventory( itemDefine, &number, remainCount, &shortCount, false ) == true ) { do { CreateInventory( itemDefine, number, remainCount, &(shortCount=0) ); remainCount = remainCount - shortCount; itemGet->table[ count ].idx = 0; itemGet->table[ count ].itemDefineIdx = itemDefine->idx; itemGet->table[ count ].itemDefineIndex = itemDefine->index; itemGet->table[ count ].number = number; itemGet->table[ count ].count = shortCount; itemGet->table[ count ].seal = itemDefine->licenseType; count++; // ¾ÆÀÌÅÛ Â÷°¨. item->PopItem( itemDefine->index, shortCount ); } while ( FindNextInventory( itemDefine, &(++number), remainCount, &shortCount, false ) == true ); } rowCount--; } if ( getEnd == true ) break; // for ( ... ) } } if ( itemGet->rowCount > 0 ) { length += (itemGet->rowCount * sizeof(itemGet->table)); mInventoryDb.get = NETWORK2->SendSQL( mConnectionIdx, handle, length ); if ( mInventoryDb.get == false ) { NETWORK2->ReleaseSQL( handle, length ); throw ERROR_ITEM_GET_FAIL; } // ½ÀµæÈÄ ³²Àº ¾ÆÀÌÅÛ µ¿±âÈ­. SendItemGetLeave( item ); } else { NETWORK2->ReleaseSQL( handle, length ); throw ERROR_ITEM_GET_FAIL; } } else throw ERROR_ITEM_GET_FAIL; } // ItemPartyGive Method. int cPlayer::ItemPartyGive(MSG_REQ_ITEM_PARTY_GIVE* msg) { if ( GetStateDie( ) == true ) throw ERROR_ITEM_PARTY_GIVE_FAIL; if ( mItemGetOpen == false ) throw ERROR_ITEM_PARTY_GIVE_FAIL; // ÆÄƼÀå °Ë»ç cParty* party = PARTYMAN->GetParty( mPlayerExrInfo.mPartyIndex ); if ( party == NULL ) throw ERROR_ITEM_PARTY_GIVE_FAIL; if ( party->GetDivideType( ) != PARTY_DIVIDE_LEADER ) throw ERROR_ITEM_PARTY_GIVE_TYPE; // Áö±ÞÇÒ Ä³¸¯ÅÍ cPlayer* pTarget = OBJECTMANAGER->GetPlayer( msg->characterIdx ); if ( pTarget == NULL ) throw ERROR_ITEM_PARTY_GIVE_TARGET; if ( pTarget->GetStateDie() == true ) throw ERROR_ITEM_PARTY_GIVE_FAIL; if ( pTarget->InventoryDatabase() ) throw ERROR_ITEM_PARTY_GIVE_FAIL; if ( GetMapNumber() != pTarget->GetMapNumber() ) throw ERROR_ITEM_PARTY_GIVE_MAP; if ( party->IsUser( msg->characterIdx ) == false ) throw ERROR_ITEM_PARTY_GIVE_PARTY; // ¾ÆÀÌÅÛ cItem* item = OBJECTMANAGER->GetItem( mItemGetIdx ); if ( item == NULL ) throw ERROR_ITEM_PARTY_GIVE_TYPE; if ( !item->IsOpen( this ) ) throw ERROR_ITEM_PARTY_GIVE_OWNER; if ( item->IsParty( pTarget ) == false ) throw ERROR_ITEM_PARTY_GIVE_PARTY; sItemData* itemData = item->GetItemData( msg->itemDefineIndex ); if ( itemData == NULL ) throw ERROR_ITEM_PARTY_GIVE_FAIL; if ( !(itemData->count > 0) ) throw ERROR_ITEM_PARTY_GIVE_FAIL; TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefineByIndex( itemData->itemDefineIndex ); if ( itemDefine == NULL ) throw ERROR_ITEM_PARTY_GIVE_FAIL; // Áö±Þ int ret = pTarget->ItemPartyTake( itemDefine, itemData->count, mPlayerInfo.CharacterIdx ); if ( ret != 0 ) throw ret; item->PopItem( itemDefine->index, itemData->count ); // ¾ÆÀÌÅÛ Â÷°¨. // ½ÀµæÈÄ ³²Àº ¾ÆÀÌÅÛ µ¿±âÈ­. SendItemGetLeave( item ); throw ERROR_ITEM_PARTY_GIVE_SUCCESS; } // ItemPartyTake Method. int cPlayer::ItemPartyTake( TB_ITEM_DEFINE* takeItem, short count, unsigned long giveCharacterIdx ) { if( IsMaxInventory( takeItem, count ) == true ) return ERROR_ITEM_PARTY_GIVE_MAX_ITEM; float weight = (float)( mItemWeight + (takeItem->weight * count) ); if( mStatus2.mMaxWeight <= weight ) return ERROR_ITEM_PARTY_GIVE_WEIGHT; short remainCount = count; TB_INVENTORY* inventory = NULL; short shortCount = 0; short rowCount = 0; short number = 0; HANDLE handle = NULL; ITEM_PARTY_GIVE* itemPartyGive = (ITEM_PARTY_GIVE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_GET_PARTY_GIVE ); u_long length = sizeof(ITEM_PARTY_GIVE) - sizeof(itemPartyGive->table); itemPartyGive->giveCharacterIdx = giveCharacterIdx; itemPartyGive->takeCharacterIdx = mPlayerInfo.CharacterIdx; // ¾ÆÀÌÅÛ Áݱâ. °ãÄ¡±â °Ë»ç ¹× ó¸®. if ( FindFirstInventory( takeItem, &number, remainCount, &shortCount, true ) == true ) { do { inventory = SelectInventory( number ); shortCount = UpdateInventory( inventory, remainCount ); remainCount = remainCount - shortCount; itemPartyGive->table[ rowCount ].idx = inventory->idx; itemPartyGive->table[ rowCount ].itemDefineIdx = takeItem->idx; itemPartyGive->table[ rowCount ].itemDefineIndex = takeItem->index; itemPartyGive->table[ rowCount ].number = number; itemPartyGive->table[ rowCount ].count = shortCount; rowCount++; } while ( FindNextInventory( takeItem, &(++number), remainCount, &shortCount, true ) == true ); } // ¾ÆÀÌÅÛ Áݱâ. »ý¼º °Ë»ç ¹× µî·Ï. if ( FindFirstInventory( takeItem, &number, remainCount, &shortCount, false ) == true ) { do { CreateInventory( takeItem, number, remainCount, &(shortCount=0) ); remainCount = remainCount - shortCount; itemPartyGive->table[ rowCount ].idx = 0; itemPartyGive->table[ rowCount ].itemDefineIdx = takeItem->idx; itemPartyGive->table[ rowCount ].itemDefineIndex = takeItem->index; itemPartyGive->table[ rowCount ].number = number; itemPartyGive->table[ rowCount ].count = shortCount; itemPartyGive->table[ rowCount ].seal = takeItem->licenseType; rowCount++; } while ( FindNextInventory( takeItem, &(++number), remainCount, &shortCount, false ) == true ); } if ( !(rowCount > 0) ) return ERROR_ITEM_PARTY_GIVE_INVEN_FULL; itemPartyGive->rowCount = rowCount; length += (itemPartyGive->rowCount * sizeof(itemPartyGive->table)); mInventoryDb.get = NETWORK2->SendSQL( mConnectionIdx, handle, length ); if ( mInventoryDb.get == false ) return ERROR_ITEM_PARTY_GIVE_FAIL; return ERROR_ITEM_PARTY_GIVE_SUCCESS; } // ItemGetAutoPush Method. unsigned short cPlayer::ItemGetAutoPush(unsigned long itemDefineIndex, unsigned short count) { if ( mItemGetCount < MAX_ITEMS ) { TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefineByIndex( itemDefineIndex ); if ( itemDefine != NULL ) { if ( count > itemDefine->capacity ) count = itemDefine->capacity; mItemGetData[ mItemGetCount ].itemDefineIndex = itemDefineIndex; mItemGetData[ mItemGetCount ].count = count; mItemGetCount +=1; return count; } } return 0; } // ItemGetAutoEnd Method. bool cPlayer::ItemGetAutoEnd(bool apply) { sItemData* itemGetData = mItemGetData; int itemGetCount = mItemGetCount; // ÀÚµ¿½Àµæ ¼ö·® Á¤¸®. mItemGetCount = 0; if ( apply == true ) { if ( mItemGetOpen == true ) { cItem* item = OBJECTMANAGER->GetItem( mItemGetIdx ); if ( item != NULL ) { if ( item->IsOpen( this ) ) item->Close( ); } ItemGetClose( ); } unsigned itemIdx = ITEMMANAGER->MakeItemIdx( ); cItem* item = OBJECTMANAGER->AddItem( itemIdx, this, true ); if ( item != NULL ) { item->PushOwner( mObject.index ); for ( int i = 0; i < itemGetCount; ++i, ++itemGetData ) { unsigned short remainCount = itemGetData->count; unsigned short shortCount = 0; while ( remainCount > 0 ) { shortCount = item->PushItem( itemGetData->itemDefineIndex, remainCount ); remainCount = ( shortCount > 0 ) ? (remainCount - shortCount) : 0; } } item->Open( this ); mItemGetOpen = true; mItemGetIdx = itemIdx; if ( ChangeState( ePLAYER_STATE_ITEMPICK ) == false ) { OBJECTMANAGER->RemoveItem( itemIdx ); return false; } return SendItemGatheringOpen( item ); } } return false; } // ItemGetQuest Method. bool cPlayer::ItemGetQuest(unsigned long itemDefineIndex, unsigned short count) { TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefineByIndex( itemDefineIndex ); short remainCount = count; if ( itemDefine != NULL && count > 0 ) { TB_INVENTORY* inventory; short shortCount; short number; // ¾ÆÀÌÅÛ Äù½ºÆ® ÀÚµ¿½Àµæ. °ãÄ¡±â °Ë»ç ¹× ó¸®. if ( FindFirstInventory( itemDefine, &number, remainCount, &shortCount, true ) == true ) { do { inventory = SelectInventory( number ); shortCount = UpdateInventory( inventory, remainCount ); remainCount = remainCount - shortCount; PerItemGet* itemGet = ITEMGETPOOL->SearchItemGet( &mItemGetRoot, number ); if ( itemGet == NULL ) { itemGet = ITEMGETPOOL->GetItemGet( &mItemGetRoot, number ); itemGet->inventory = (*inventory); itemGet->inventory.count = 0; } itemGet->inventory.count = itemGet->inventory.count + shortCount; // °ãÄ¡±â ¿À·ù. if ( remainCount > 0 ) { NETWORK2->PostServerEvent( "Error - cPlayer::ItemGetQuest(=%d, =%d, =%d )", itemDefineIndex, remainCount, shortCount ); remainCount = 0; } } while ( FindNextInventory( itemDefine, &(++number), remainCount, &shortCount, true ) == true ); } // ¾ÆÀÌÅÛ Äù½ºÆ® ÀÚµ¿½Àµæ. »ý¼º °Ë»ç ¹× µî·Ï. if ( FindFirstInventory( itemDefine, &number, remainCount, &shortCount, false ) == true ) { do { CreateInventory( itemDefine, number, remainCount, &(shortCount=0) ); remainCount = remainCount - shortCount; PerItemGet* itemGet = ITEMGETPOOL->SearchItemGet( &mItemGetRoot, number ); if ( itemGet == NULL ) { itemGet = ITEMGETPOOL->GetItemGet( &mItemGetRoot, number ); itemGet->inventory.idx = 0; itemGet->inventory.itemDefineIdx = itemDefine->idx; itemGet->inventory.itemDefineIndex = itemDefine->index; itemGet->inventory.number = number; itemGet->inventory.seal = itemDefine->licenseType; } itemGet->inventory.count = itemGet->inventory.count + shortCount; // »ý¼º ¿À·ù. if ( remainCount > 0 ) { NETWORK2->PostServerEvent( "Error - cPlayer::ItemGetQuest(=%d, =%d, =%d )", itemDefineIndex, remainCount, shortCount ); remainCount = 0; } } while ( FindNextInventory( itemDefine, &(++number), remainCount, &shortCount, false ) == true ); } return true; } return false; } // SendItemGetOpen Method. bool cPlayer::SendItemGetOpen(cBaseObject* baseObject) { HANDLE handle = NULL; MSG_RES_ITEM_GET_OPEN* sendMsg = (MSG_RES_ITEM_GET_OPEN*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_ITEM, NM_ITEM_GET_OPEN_RES ); bool retvalue = false; if ( sendMsg != NULL ) { cItem* item = (cItem*)baseObject; sItemData* itemData = sendMsg->itemData; sendMsg->ErrorCode = ERROR_ITEM_GET_OPEN_SUCCESS; sendMsg->rowCount = item->GetItemData( itemData ); sendMsg->openItemIdx = mItemGetIdx; retvalue = NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength( ) ); } MSG_SYN_ITEM_GET_OPEN sendSyn; sendSyn.Category = NM_ITEM; sendSyn.Protocol = NM_ITEM_GET_OPEN_SYN; sendSyn.characterIdx = mObject.index; NETWORK2->QuickSendExcept( this, (char*)&sendSyn, sizeof(MSG_SYN_ITEM_GET_OPEN) ); return retvalue; } // SendItemGetClose Method. bool cPlayer::SendItemGetClose( ) { bool retvalue = NETWORK2->SendMsgError( mConnectionIdx, NM_ITEM, NM_ITEM_GET_CLOSE_RES, ERROR_ITEM_GET_CLOSE_SUCCESS ); MSG_SYN_ITEM_GET_CLOSE sendSyn; sendSyn.Category = NM_ITEM; sendSyn.Protocol = NM_ITEM_GET_CLOSE_SYN; sendSyn.characterIdx = mObject.index; NETWORK2->QuickSendExcept( this, (char*)&sendSyn, sizeof(MSG_SYN_ITEM_GET_CLOSE) ); return retvalue; } // SendItemGetLeave Method. bool cPlayer::SendItemGetLeave(cBaseObject* baseObject) { HANDLE handle = NULL; MSG_RES_ITEM_GET_LEAVE* sendMsg = (MSG_RES_ITEM_GET_LEAVE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_ITEM, NM_ITEM_GET_LEAVE_RES ); if ( sendMsg != NULL ) { cItem* item = (cItem*)baseObject; sItemData* itemData = sendMsg->itemData; sendMsg->rowCount = item->GetItemData( itemData ); return NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength( ) ); } return false; } // SendItemGatheringOpen Method. bool cPlayer::SendItemGatheringOpen(cBaseObject* baseObject) { HANDLE handle = NULL; MSG_RES_ITEM_GATHERING_OPEN* sendMsg = (MSG_RES_ITEM_GATHERING_OPEN*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_ITEM, NM_ITEM_GATHERING_OPEN_RES ); if ( sendMsg != NULL ) { cItem* item = (cItem*)baseObject; sItemData* itemData = sendMsg->itemData; sendMsg->ErrorCode = ERROR_ITEM_GET_OPEN_SUCCESS; sendMsg->rowCount = item->GetItemData( itemData ); return NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength( ) ); } return false; } // ExchangeAsk Method. void cPlayer::ExchangeAsk(MSG_REQ_ITEM_EXCHANGE_ASK* msg) { if ( GetCheatHideMode() == true ) throw ERROR_ITEM_EXCHANGE_ASK_ERROR; // ij¸¯ÅÍ »óÅ¿À·ù - hero °¡ hide on. // ÀÌ¹Ì °Å·¡Áß È®ÀÎ. if ( mExchangeStatus != ItemExchangeNone ) throw ERROR_ITEM_EXCHANGE_ASK_ERROR; if ( msg->mTarget.type != eOBJECTTYPE_PLAYER ) throw ERROR_ITEM_EXCHANGE_ASK_FAIL; if( IsChangeState( eOBJECT_STATE_MOVE ) == false ) throw ERROR_ITEM_EXCHANGE_ASK_ERROR; cPlayer* player = GRIDMANAGER->GetPlayer( msg->mTarget.index ); if ( player == NULL ) throw ERROR_ITEM_EXCHANGE_ASK_FAIL; sGameOption* toOption1 = GetOptionData(); if( toOption1->option1.rejectionTrade == true ) throw ERROR_ITEM_EXCHANGE_ASK_OPTIONREFUSE; // ¸Ê À§Ä¡ °Ë»ç. if ( mMapNumber != player->GetMapNumber( ) ) throw ERROR_ITEM_EXCHANGE_ASK_FAIL; // °Å¸® °Ë»ç. float tempRange = OBJECTMANAGER->ObjectSizeRange( this, player, ITEM_VALID_DISTANCE + SYNC_MOVE_RANGE ); if ( (mObjectPos - player->GetPos( )).Length( ) > tempRange ) throw ERROR_ITEM_EXCHANGE_ASK_DISTANCE; // °Å·¡ ÀÀ´ä ¿ä±¸. player->ExchangeAsk( mObject ); // °Å·¡Áß Ã³¸®¿Í ´ë»ó ÀúÀå. mExchangeStatus = ItemExchangeAsk; mExchangeTarget = player->GetObject( ); mExchangeItems = 0; mExchangeMoney = 0; SendMsgResExchange( NM_ITEM, NM_ITEM_EXCHANGE_ASK_RES, ERROR_ITEM_EXCHANGE_ASK_SUCCESS ); } void cPlayer::ExchangeAsk(sObject object) { if ( IsRequestRejection( ) == true ) throw ERROR_ITEM_EXCHANGE_ASK_TARGETERROR; // ij¸¯ÅÍ »óÅ¿À·ù. if ( GetStateDie( ) == true ) throw ERROR_ITEM_EXCHANGE_ASK_TARGETERROR; // ij¸¯ÅÍ »óÅ¿À·ù. if( IsChangeState( eOBJECT_STATE_MOVE ) == false ) throw ERROR_ITEM_EXCHANGE_ASK_TARGETERROR; if ( GetCheatHideMode() == true ) throw ERROR_ITEM_EXCHANGE_ASK_TARGETERROR; // ij¸¯ÅÍ »óÅ¿À·ù. sGameOption* toOption1 = GetOptionData(); if( toOption1->option1.rejectionTrade == true ) throw ERROR_ITEM_EXCHANGE_ASK_TARGETOPTIONREFUSE; // ÀÌ¹Ì °Å·¡Áß È®ÀÎ. if ( mExchangeStatus != ItemExchangeNone ) throw ERROR_ITEM_EXCHANGE_ASK_TARGETERROR; StartRequestRejection( eREQREJCT_EXCHANGE ); // ij¸¯ÅÍ »óꝰæ. // °Å·¡Áß Ã³¸®¿Í ´ë»ó ÀúÀå. mExchangeStatus = ItemExchangeAsk; mExchangeTarget = object; mExchangeItems = 0; mExchangeMoney = 0; HANDLE handle = NULL; MSG_RES_ITEM_EXCHANGE_ASK* sendMsg = (MSG_RES_ITEM_EXCHANGE_ASK*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_ITEM, NM_ITEM_EXCHANGE_ASK_RES ); if ( sendMsg != NULL ) { sendMsg->ErrorCode = ERROR_ITEM_EXCHANGE_ASK_REPLAY; sendMsg->characterIdx = object.index; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_ITEM_EXCHANGE_ASK) ); } } // ExchangeReply Method - ½Â¶ôÀÌ ¾Æ´Ò°æ¿ì, ¸ðµÎ °ÅÀýó¸®. void cPlayer::ExchangeReply(MSG_REQ_ITEM_EXCHANGE_REP* msg) { // ³» »óÅ üũ if( GetRequestRejection() != eREQREJCT_EXCHANGE ) throw ERROR_ITEM_EXCHANGE_REP_ERROR; // ij¸¯ÅÍ »óÅ ¿À·ù. EndRequestRejection( eREQREJCT_EXCHANGE ); // ij¸¯ÅÍ »óÅ º¯°æ. // ½ÅûÀÚ°¡ ¾øÀ¸¸é ÀÚ½ÅÀÇ »óÅ Ǭ´Ù cPlayer* player = OBJECTMANAGER->GetPlayer( mExchangeTarget.index ); if( player == NULL ) { if ( mExchangeStatus == ItemExchangeAsk ) mExchangeStatus = ItemExchangeNone; throw ERROR_ITEM_EXCHANGE_REP_NOTEXIST; } else { // Á¸ÀçÇϵÇ, ¸ÊÀ̵¿ÁßÀ̸é ÀڽŰú »ó´ë¹æÀÇ »óŸ¦ Ǭ´Ù if( player->IsMapChange() == true ) { player->ExchangeReplySyn( TYPE_ITEM_EXCHANGE_REP_REJECT, ERROR_ITEM_EXCHANGE_REP_TARGETERROR ); if ( mExchangeStatus == ItemExchangeAsk ) mExchangeStatus = ItemExchangeNone; throw ERROR_ITEM_EXCHANGE_REP_NOTEXIST; } } // if( msg->type == TYPE_ITEM_EXCHANGE_REP_ACCEPT ) { // °Å·¡ »óÅ üũ try { if ( GetCheatHideMode() == true ) throw ERROR_ITEM_EXCHANGE_REP_ERROR; // ij¸¯ÅÍ »óÅ¿À·ù - hero °¡ hide on if ( GetStateDie( ) == true ) throw ERROR_ITEM_EXCHANGE_REP_ERROR; // ij¸¯ÅÍ »óÅ¿À·ù. if( GetState() == eOBJECT_STATE_STOP ) throw ERROR_ITEM_EXCHANGE_REP_FAIL; sGameOption* myOption1 = GetOptionData(); if( myOption1->option1.rejectionTrade == true ) throw ERROR_ITEM_EXCHANGE_REP_OPTIONREFUSE; // ³»°¡ °ÅºÎ»óÅÂÀÓ // ÀÌ¹Ì °Å·¡Áß È®ÀÎ. if ( mExchangeStatus != ItemExchangeAsk ) throw ERROR_ITEM_EXCHANGE_REP_ERROR; // °Å·¡ ½ÅûÀÚ »óÅ üũ if( player->GetState() == eOBJECT_STATE_STOP || player->GetStateDie() ) throw ERROR_ITEM_EXCHANGE_REP_TARGETERROR; sGameOption* toOption1 = player->GetOptionData(); if( toOption1->option1.rejectionTrade == true ) throw ERROR_ITEM_EXCHANGE_REP_TARGETOPTIONREFUSE; if ( mMapNumber != player->GetMapNumber( ) ) throw ERROR_ITEM_EXCHANGE_REP_DISTANCE; // °Å¸® °Ë»ç. float tempRange = OBJECTMANAGER->ObjectSizeRange( this, player, ITEM_VALID_DISTANCE + SYNC_MOVE_RANGE ); if ( (mObjectPos - player->GetPos( )).Length( ) > tempRange ) throw ERROR_ITEM_EXCHANGE_REP_DISTANCE; } catch ( int error ) { // ¿À·ù°¡ ³ª¸é, ³» »óÅÂ¿Í »ó´ë¹æ»óŸ¦ ¸ðµÎ Ç®¾îÁØ´Ù player = OBJECTMANAGER->GetPlayer( mExchangeTarget.index ); // ¿äûÀÚ if ( player != NULL ) { player->ExchangeReplySyn( TYPE_ITEM_EXCHANGE_REP_REJECT, error ); } if ( mExchangeStatus == ItemExchangeAsk ) mExchangeStatus = ItemExchangeNone; throw error; } player->ExchangeReplySyn( msg->type, ERROR_ITEM_EXCHANGE_REP_SUCCESS ); ExchangeReply( msg->type ); } else if( msg->type == TYPE_ITEM_EXCHANGE_REP_REJECTTIME ) { player->ExchangeReplySyn( msg->type, ERROR_ITEM_EXCHANGE_REP_TIME ); ExchangeReply( msg->type ); } else { player->ExchangeReplySyn( msg->type, ERROR_ITEM_EXCHANGE_REP_TARGETREFUSE ); ExchangeReply( msg->type ); } } // ÀÚ±âÀڽſ¡°Ô º¸³¿ void cPlayer::ExchangeReply( BYTE type ) { if ( type == TYPE_ITEM_EXCHANGE_REP_ACCEPT ) { mExchangeStatus = ItemExchangeBegin; SendMsgResExchange( NM_ITEM, NM_ITEM_EXCHANGE_REP_RES, ERROR_ITEM_EXCHANGE_REP_SUCCESS ); } else if( type == TYPE_ITEM_EXCHANGE_REP_REJECTTIME ) { mExchangeStatus = ItemExchangeNone; SendMsgResExchange( NM_ITEM, NM_ITEM_EXCHANGE_REP_RES, ERROR_ITEM_EXCHANGE_REP_TIME ); } else { mExchangeStatus = ItemExchangeNone; SendMsgResExchange( NM_ITEM, NM_ITEM_EXCHANGE_REP_RES, ERROR_ITEM_EXCHANGE_REP_REFUSE ); } } // °Å·¡¿äûÀÚ¿¡°Ô º¸³¿ void cPlayer::ExchangeReplySyn( BYTE type, int error ) { if ( type == TYPE_ITEM_EXCHANGE_REP_ACCEPT ) { mExchangeStatus = ItemExchangeBegin; } else { mExchangeStatus = ItemExchangeNone; } SendMsgResExchange( NM_ITEM, NM_ITEM_EXCHANGE_REP_SYN, error ); } // ExchangeAdd Method. void cPlayer::ExchangeAdd(MSG_REQ_ITEM_EXCHANGE_ADD* msg) { if ( mExchangeStatus != ItemExchangeBegin ) throw ERROR_ITEM_EXCHANGE_ADD_FAIL; cPlayer* player = GRIDMANAGER->GetPlayer( mExchangeTarget.index ); // ½É°¢ÇÑ ¿À·ùÀ̹ǷÎ, ¹Ýµå½Ã ¿À·ùó¸® ÇØ¾ßµÊ. if ( player == NULL ) throw ERROR_ITEM_EXCHANGE_ADD_FAIL; switch ( msg->type ) { case TYPE_ITEM_EXCHANGE_ADD_ITEM: { if ( !(mExchangeItems < MAX_ITEM_EXCHANGE) ) throw ERROR_ITEM_EXCHANGE_ADD_FAIL; if( IsInventoryBag( msg->number ) == false ) throw ERROR_ITEM_EXCHANGE_ADD_FAIL; TB_INVENTORY* inventory = SelectInventory( msg->number ); if ( IsInventory( inventory ) == false ) throw ERROR_ITEM_EXCHANGE_ADD_FAIL; if ( inventory->apply != InventoryApplyNone ) throw ERROR_ITEM_EXCHANGE_ADD_FAIL; TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if ( itemDefine == NULL ) throw ERROR_ITEM_EXCHANGE_ADD_FAIL; if ( IsItemExchange( itemDefine, inventory ) == false ) throw ERROR_ITEM_EXCHANGE_ADD_EXCHANGE; inventory->apply = InventoryApplyExchange; mExchangeItems++; player->ExchangeAdd( inventory ); SendMsgResExchange( NM_ITEM, NM_ITEM_EXCHANGE_ADD_RES, ERROR_ITEM_EXCHANGE_ADD_SUCCESS ); } break; case TYPE_ITEM_EXCHANGE_ADD_MONEY: { if ( msg->money == 0 || msg->money > mMoney || msg->money > MAX_TRADE_MONEY ) throw ERROR_ITEM_EXCHANGE_ADD_TRADE_MONEY; mExchangeMoney = msg->money; player->ExchangeAdd( mExchangeMoney ); SendMsgResExchange( NM_ITEM, NM_ITEM_EXCHANGE_ADD_RES, ERROR_ITEM_EXCHANGE_ADD_SUCCESS ); } break; default: throw ERROR_ITEM_EXCHANGE_ADD_FAIL; } } void cPlayer::ExchangeAdd(TB_INVENTORY* inventory) { HANDLE handle = NULL; MSG_SYN_ITEM_EXCHANGE_ADD* sendMsg = (MSG_SYN_ITEM_EXCHANGE_ADD*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_ITEM, NM_ITEM_EXCHANGE_ADD_SYN ); if ( sendMsg != NULL ) { sendMsg->type = TYPE_ITEM_EXCHANGE_ADD_ITEM; Inventory2sInventory( &sendMsg->inventory, inventory ); NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_ITEM_EXCHANGE_ADD) ); } } void cPlayer::ExchangeAdd(unsigned long money) { HANDLE handle = NULL; MSG_SYN_ITEM_EXCHANGE_ADD* sendMsg = (MSG_SYN_ITEM_EXCHANGE_ADD*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_ITEM, NM_ITEM_EXCHANGE_ADD_SYN ); if ( sendMsg != NULL ) { sendMsg->type = TYPE_ITEM_EXCHANGE_ADD_MONEY; sendMsg->money = money; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_ITEM_EXCHANGE_ADD) ); } } // ExchangeDel Method. void cPlayer::ExchangeDel(MSG_REQ_ITEM_EXCHANGE_DEL* msg) { if ( mExchangeStatus != ItemExchangeBegin ) throw ERROR_ITEM_EXCHANGE_DEL_FAIL; cPlayer* player = GRIDMANAGER->GetPlayer( mExchangeTarget.index ); // ½É°¢ÇÑ ¿À·ùÀ̹ǷÎ, ¹Ýµå½Ã ¿À·ùó¸® ÇØ¾ßµÊ. if ( player == NULL ) throw ERROR_ITEM_EXCHANGE_DEL_FAIL; if ( !(mExchangeItems > 0) ) throw ERROR_ITEM_EXCHANGE_DEL_FAIL; TB_INVENTORY* inventory = SelectInventory( msg->number ); if ( IsInventory( inventory ) == false ) throw ERROR_ITEM_EXCHANGE_DEL_FAIL; if ( inventory->apply != InventoryApplyExchange ) throw ERROR_ITEM_EXCHANGE_DEL_FAIL; inventory->apply = InventoryApplyNone; mExchangeItems--; player->ExchangeDel( inventory ); SendMsgResExchange( NM_ITEM, NM_ITEM_EXCHANGE_DEL_RES, ERROR_ITEM_EXCHANGE_DEL_SUCCESS ); } void cPlayer::ExchangeDel(TB_INVENTORY* inventory) { HANDLE handle = NULL; MSG_SYN_ITEM_EXCHANGE_DEL* sendMsg = (MSG_SYN_ITEM_EXCHANGE_DEL*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_ITEM, NM_ITEM_EXCHANGE_DEL_SYN ); if ( sendMsg != NULL ) { Inventory2sInventory( &sendMsg->inventory, inventory ); NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_ITEM_EXCHANGE_DEL) ); } } // ExchangeOk Method. void cPlayer::ExchangeOk(MSG_REQ_ITEM_EXCHANGE_OK* /*msg*/) { if ( mExchangeStatus != ItemExchangeBegin ) throw ERROR_ITEM_EXCHANGE_OK_FAIL; cPlayer* player = GRIDMANAGER->GetPlayer( mExchangeTarget.index ); if ( player == NULL ) throw ERROR_ITEM_EXCHANGE_OK_FAIL; mExchangeStatus = ItemExchangeOk; player->SendMsgResExchange( NM_ITEM, NM_ITEM_EXCHANGE_OK_RES, ERROR_ITEM_EXCHANGE_OK_PLAYER ); SendMsgResExchange( NM_ITEM, NM_ITEM_EXCHANGE_OK_RES, ERROR_ITEM_EXCHANGE_OK_SUCCESS ); } // ExchangeRetry Method. void cPlayer::ExchangeRetry(MSG_REQ_ITEM_EXCHANGE_RETRY* /*msg*/) { if ( mExchangeStatus != ItemExchangeOk ) throw ERROR_ITEM_EXCHANGE_RETRY_FAIL; cPlayer* player = GRIDMANAGER->GetPlayer( mExchangeTarget.index ); if ( player == NULL ) throw ERROR_ITEM_EXCHANGE_RETRY_FAIL; mExchangeStatus = ItemExchangeBegin; player->ExchangeRetry( ); SendMsgResExchange( NM_ITEM, NM_ITEM_EXCHANGE_RETRY_RES, ERROR_ITEM_EXCHANGE_RETRY_SUCCESS ); } // ExchangeRetry Method. void cPlayer::ExchangeRetry( ) { // »ó´ë¹æÀÌ »óŰ¡ º¯°æµÇ¸é °°ÀÌ º¯°æ ó¸® mExchangeStatus = ItemExchangeBegin; SendMsgResExchange( NM_ITEM, NM_ITEM_EXCHANGE_RETRY_RES, ERROR_ITEM_EXCHANGE_RETRY_PLAYER ); } // ExchangeCancel Method. void cPlayer::ExchangeCancel(MSG_REQ_ITEM_EXCHANGE_CANCEL* /*msg*/) { if ( mExchangeStatus == ItemExchangeNone ) throw ERROR_ITEM_EXCHANGE_CANCEL_FAIL; cPlayer* player = GRIDMANAGER->GetPlayer( mExchangeTarget.index ); if ( player != NULL ) { player->SendMsgResExchange( NM_ITEM, NM_ITEM_EXCHANGE_CANCEL_RES, ERROR_ITEM_EXCHANGE_CANCEL_PLAYER ); player->ExchangeClear( ); } ExchangeClear( ); SendMsgResExchange( NM_ITEM, NM_ITEM_EXCHANGE_CANCEL_RES, ERROR_ITEM_EXCHANGE_CANCEL_SUCCESS ); } void cPlayer::ExchangeCancel( bool sendme ) { if( mExchangeStatus > ItemExchangeAsk ) { cPlayer* player = GRIDMANAGER->GetPlayer( mExchangeTarget.index ); if ( player != NULL ) { player->SendMsgResExchange( NM_ITEM, NM_ITEM_EXCHANGE_CANCEL_RES, ERROR_ITEM_EXCHANGE_CANCEL_PLAYER ); player->ExchangeClear( ); } ExchangeClear( ); // ÀÚ±âÀڽſ¡°Ô º¸³½´Ù if( sendme == true ) { SendMsgResExchange( NM_ITEM, NM_ITEM_EXCHANGE_CANCEL_RES, ERROR_ITEM_EXCHANGE_CANCEL_SUCCESS ); } } } void cPlayer::ExchangeClear( ) { // °Å·¡ »ó Å ÃʱâÈ­. mExchangeStatus = ItemExchangeNone; // °Å·¡ ¾ÆÀÌÅÛ ÃʱâÈ­. TB_INVENTORY* inventory = SelectInventory( INVENTORY_BAG_BEGIN ); for ( int i = INVENTORY_BAG_BEGIN; i <= mHeroInfo.BagEnd && mExchangeItems > 0; i++, inventory++ ) { if ( inventory->apply == InventoryApplyExchange ) { inventory->apply = InventoryApplyNone; mExchangeItems--; } } // °Å·¡ ±Ý ¾× ÃʱâÈ­. mExchangeMoney = 0; mExchangeTarget.index = 0; mExchangeTarget.type = eOBJECTTYPE_NONE; } // ExchangeEnd Method. void cPlayer::ExchangeEnd(MSG_REQ_ITEM_EXCHANGE_END* /*msg*/) { if ( mInventoryDatabase ) throw ERROR_ITEM_EXCHANGE_END_FAIL; if ( mExchangeStatus != ItemExchangeOk ) throw ERROR_ITEM_EXCHANGE_END_FAIL; cPlayer* player = GRIDMANAGER->GetPlayer( mExchangeTarget.index ); if ( player == NULL ) throw ERROR_ITEM_EXCHANGE_END_FAIL; if ( player->InventoryDatabase( ) ) throw ERROR_ITEM_EXCHANGE_END_FAIL; if ( player->GetExchangeStatus( ) < ItemExchangeOk ) throw ERROR_ITEM_EXCHANGE_END_FAIL; sHeroInfo* pTargetInfo = player->GetHeroInfo(); if( pTargetInfo == NULL ) throw ERROR_ITEM_EXCHANGE_END_FAIL; // »ó´ë¹æÀÇ º¸À¯ ±Ý¾×ÀÌ Çѵµ üũ unsigned long resultMoney = player->GetMoney() - player->GetExchangeMoney() + GetExchangeMoney(); if( resultMoney > MAX_HAVE_MONEY) throw ERROR_ITEM_EXCHANGE_END_THATMONEY_FAIL; // ³ªÀÇ º¸À¯ ±Ý¾×ÀÌ Çѵµ üũ resultMoney = GetMoney() - GetExchangeMoney() + player->GetExchangeMoney(); if( resultMoney > MAX_HAVE_MONEY ) throw ERROR_ITEM_EXCHANGE_END_MYMONEY_FAIL; // ±³È¯ ¼ö·®°Ë»ç. TB_INVENTORY* inventory; int exchangeCount; int remainCount; inventory = SelectInventory( INVENTORY_BAG_BEGIN ); exchangeCount = 0; remainCount = 0; for ( int i = INVENTORY_BAG_BEGIN; i <= mHeroInfo.BagEnd; i++, inventory++ ) { if ( IsInventory( inventory ) == true ) { if ( inventory->apply == InventoryApplyExchange ) exchangeCount++; } else remainCount++; } inventory = player->SelectInventory( INVENTORY_BAG_BEGIN ); for ( int i = INVENTORY_BAG_BEGIN; i <= pTargetInfo->BagEnd; i++, inventory++ ) { if ( IsInventory( inventory ) == true ) { if ( inventory->apply == InventoryApplyExchange ) remainCount--; } else exchangeCount--; } if ( exchangeCount > 0 || remainCount < 0 ) throw ERROR_ITEM_EXCHANGE_END_INVENTORY; // (³»°¡ ¿Ã¸° ¾ÆÀÌÅÛ)»ó´ë¹æÀÇ ÃÖ´ë º¸À¯°¹¼ö inventory = SelectInventory( INVENTORY_BAG_BEGIN ); for ( int i = INVENTORY_BAG_BEGIN; i <= mHeroInfo.BagEnd; i++, inventory++ ) { if ( inventory->apply == InventoryApplyExchange ) { TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if( player->IsMaxInventory( itemDefine, inventory->count ) == true ) throw ERROR_ITEM_EXCHANGE_END_THAT_MAX_ITEM; } } // (»ó´ë¹æÀÌ ¿Ã¸° ¾ÆÀÌÅÛ)³ªÀÇ ÃÖ´ë º¸À¯°¹¼ö inventory = player->SelectInventory( INVENTORY_BAG_BEGIN ); for ( int i = INVENTORY_BAG_BEGIN; i <= pTargetInfo->BagEnd; i++, inventory++ ) { if ( inventory->apply == InventoryApplyExchange ) { TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if( IsMaxInventory( itemDefine, inventory->count ) == true ) throw ERROR_ITEM_EXCHANGE_END_MY_MAX_ITEM; } } mExchangeStatus = ItemExchangeEnd; if ( player->GetExchangeStatus( ) != ItemExchangeEnd ) throw ERROR_ITEM_EXCHANGE_END_WAIT; // Database 󸮿äû. HANDLE handle = NULL; ITEM_EXCHANGE* itemExchange = (ITEM_EXCHANGE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_EXCHANGE ); TB_INVENTORY* table; // Àû¿ë Çà ¼ö itemExchange->rowCount = 2; // Player1 - Àκ¥Å丮 À̵¿(ij¸¯ÅÍ °íÀ¯¹øÈ£). itemExchange->table[ 0 ].characterIdx = mObject.index; itemExchange->table[ 0 ].characterMoney = player->GetExchangeMoney( ) - GetExchangeMoney( ); itemExchange->table[ 0 ].characterFrom = player->GetObjectID( ); itemExchange->table[ 0 ].characterBefor = mMoney; itemExchange->table[ 0 ].characterAfter = mMoney + itemExchange->table[ 0 ].characterMoney; inventory = SelectInventory( INVENTORY_BAG_BEGIN ); table = itemExchange->table[ 1 ].table; for ( int i = INVENTORY_BAG_BEGIN; i <= mHeroInfo.BagEnd && itemExchange->table[ 1 ].rowCount < MAX_ITEM_EXCHANGE; i++, inventory++ ) { if ( inventory->apply == InventoryApplyExchange ) { (*table) = (*inventory); RemoveInventory( inventory ); itemExchange->table[ 1 ].rowCount++; table++; } } // Player2 - Àκ¥Å丮 À̵¿(ij¸¯ÅÍ °íÀ¯¹øÈ£). itemExchange->table[ 1 ].characterIdx = player->GetObjectID( ); itemExchange->table[ 1 ].characterMoney = GetExchangeMoney( ) - player->GetExchangeMoney( ); itemExchange->table[ 1 ].characterFrom = mObject.index; itemExchange->table[ 1 ].characterBefor = player->GetMoney( ); itemExchange->table[ 1 ].characterAfter = player->GetMoney( ) + itemExchange->table[ 1 ].characterMoney; inventory = player->SelectInventory( INVENTORY_BAG_BEGIN ); table = itemExchange->table[ 0 ].table; for ( int i = INVENTORY_BAG_BEGIN; i <= pTargetInfo->BagEnd && itemExchange->table[ 0 ].rowCount < MAX_ITEM_EXCHANGE; i++, inventory++ ) { if ( inventory->apply == InventoryApplyExchange ) { (*table) = (*inventory); player->RemoveInventory( inventory ); itemExchange->table[ 0 ].rowCount++; table++; } } // Player1 - Àκ¥Å丮 ¹øÈ£Á¤¸®(½½·Ô). table = itemExchange->table[ 0 ].table; inventory = SelectInventory( INVENTORY_BAG_BEGIN ); for ( short i = INVENTORY_BAG_BEGIN, rowCount = 0; i <= mHeroInfo.BagEnd && rowCount < itemExchange->table[ 0 ].rowCount; i++, inventory++ ) { if ( IsInventory( inventory ) == false ) { table->number = i; XCopyInventory( table ); table++; rowCount++; } } if ( GetExchangeMoney( ) > 0 ) { long exchangeMoney = -GetExchangeMoney( ); long result = AddMoney( player->GetObject( ), exchangeMoney, false ); if ( result != exchangeMoney ) { NETWORK2->PostServerEvent( "Error - SQL_GAME_PROCESS_ITEM_EXCHANGE From(=%d) To(=%d) AddMoney(=%d) != ResultMoney(=%d).", GetObjectID( ), GetObjectID( ), exchangeMoney, result ); } } if ( player->GetExchangeMoney( ) > 0 ) { long exchangeMoney = +player->GetExchangeMoney( ); long result = AddMoney( player->GetObject( ), exchangeMoney, false ); if ( result != exchangeMoney ) { NETWORK2->PostServerEvent( "Error - SQL_GAME_PROCESS_ITEM_EXCHANGE From(=%d) To(=%d) AddMoney(=%d) != ResultMoney(=%d).", player->GetObjectID( ), GetObjectID( ), exchangeMoney, result ); } } // Player2 - Àκ¥Å丮 ¹øÈ£Á¤¸®(½½·Ô). table = itemExchange->table[ 1 ].table; inventory = player->SelectInventory( INVENTORY_BAG_BEGIN ); for ( short i = INVENTORY_BAG_BEGIN, rowCount = 0; i <= pTargetInfo->BagEnd && rowCount < itemExchange->table[ 1 ].rowCount; i++, inventory++ ) { if ( IsInventory( inventory ) == false ) { table->number = i; player->XCopyInventory( table ); table++; rowCount++; } } if ( player->GetExchangeMoney( ) > 0 ) { long exchangeMoney = -player->GetExchangeMoney( ); long result = player->AddMoney( GetObject( ), exchangeMoney, false ); if ( result != exchangeMoney ) { NETWORK2->PostServerEvent( "Error - SQL_GAME_PROCESS_ITEM_EXCHANGE From(=%d) To(=%d) AddMoney(=%d) != ResultMoney(=%d).", player->GetObjectID( ), player->GetObjectID( ), exchangeMoney, result ); } } if ( GetExchangeMoney( ) > 0 ) { long exchangeMoney = +GetExchangeMoney( ); long result = player->AddMoney( GetObject( ), exchangeMoney, false ); if ( result != exchangeMoney ) { NETWORK2->PostServerEvent( "Error - SQL_GAME_PROCESS_ITEM_EXCHANGE From(=%d) To(=%d) AddMoney(=%d) != ResultMoney(=%d).", GetObjectID( ), player->GetObjectID( ), exchangeMoney, result ); } } if ( NETWORK2->SendSQL( handle, sizeof(ITEM_EXCHANGE) ) == false ) { NETWORK2->CloseCID( player->GetConnectionIdx( ) ); NETWORK2->CloseCID( mConnectionIdx ); throw ERROR_ITEM_EXCHANGE_END_FAIL; } // Begin DB player->ExchangeEnd( ); ExchangeEnd( ); } void cPlayer::CbExchangeEnd(TB_INVENTORY* table, unsigned long rowCount, u_long requestResult) { if ( mInventoryDb.exchange ) mInventoryDb.exchange = false; // DB; »ç¿ëÁ¾·á. else return; if ( requestResult == 0 ) { TB_INVENTORY* inventory; SendMsgResExchangeEnd( table, rowCount ); while ( rowCount > 0 ) { inventory = SelectInventory( table->number ); if ( inventory->idx == table->idx ) { table->apply = InventoryApplyNone; XCopyInventory( inventory, table ); } else throw table; table++; rowCount--; } // °Å·¡Á¾·á & ÃʱâÈ­. mExchangeStatus = ItemExchangeNone; mExchangeItems = 0; mExchangeMoney = 0; mExchangeTarget.index = 0; mExchangeTarget.type = eOBJECTTYPE_NONE; } else throw requestResult; } // SendMsgResExchange Method. bool cPlayer::SendMsgResExchange(char category, char protocol, int error) { return NETWORK2->SendMsgError( mConnectionIdx, category, protocol, error ); } // SendMsgResExchangeEnd Method. bool cPlayer::SendMsgResExchangeEnd(TB_INVENTORY* table, unsigned long rowCount) { HANDLE handle = NULL; MSG_RES_ITEM_EXCHANGE_END* sendMsg = (MSG_RES_ITEM_EXCHANGE_END*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_ITEM, NM_ITEM_EXCHANGE_END_RES ); if ( sendMsg != NULL ) { sInventory* sinventory = sendMsg->Inventory; // °Å·¡¾ÆÀÌÅÛ while ( sendMsg->RowCount < rowCount ) { Inventory2sInventory( sinventory, table ); sinventory++; table++; sendMsg->RowCount++; } sendMsg->ErrorCode = ERROR_ITEM_EXCHANGE_END_SUCCESS; return NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength( ) ); } return false; } // StallSellOpen Method. void cPlayer::StallSellOpen(ULONG_PTR /*socketContext*/, MSG_REQ_ITEM_STALL_SELL_OPEN* msg) { // 1-1. ij¸¯ÅÍ »óÅ °Ë»ç. if ( IsChangeState( eOBJECT_STATE_STOP ) == false ) throw ERROR_ITEM_STALL_SELL_OPEN_FAIL; // ij¸¯ÅÍ »óÅ ¿À·ù - º¯°æºÒ°¡. if ( GetStateStop( ) != eSTOP_NONE ) throw ERROR_ITEM_STALL_SELL_OPEN_FAIL; // ij¸¯ÅÍ »óÅ ¿À·ù. if ( IsRequestRejection( ) == true ) throw ERROR_ITEM_STALL_SELL_OPEN_FAIL; // ij¸¯ÅÍ »óÅ¿À·ù. // 1-2. ³ëÁ¡ »óÅ °Ë»ç. if ( mStallSell == true ) throw ERROR_ITEM_STALL_SELL_OPEN_EXIST; // ³ë Á¡ »óÅ ¿À·ù - ÀÌ¹Ì ¿ÀÇÂÁß. // 2-1. ij¸¯ÅÍ »óÅ º¯°æ. ChangeState( eOBJECT_STATE_STOP ); // ij¸¯ÅÍ »óÅ - Á¤Áö. SetStateStop( eSTOP_OPENSTALL ); // Á¤ÁöÁß »óÅ - ³ëÁ¡¿ÀÇÂ. // 2-2. ³ëÁ¡ ÆÇ¸ÅÀÚ ¿­±â. mStallSell = true; // ³ë Á¡ »óÅ - ¿ÀÇÂ. // 2-3. ³ëÁ¡¸í µî·Ï. msg->title[ STALL_TITLE_LEN ] = 0; wcscpy( mStallSellTitle, msg->title ); // 3-1. ³ëÁ¡¿­±â ¼º°ø. SendMsgResStallSell( NM_ITEM, NM_ITEM_STALL_SELL_OPEN_RES, ERROR_ITEM_STALL_SELL_OPEN_SUCCESS ); // 3-2. ³ëÁ¡¿­±â µ¿±âÈ­. MSG_SYN_ITEM_STALL_SELL_OPEN sendMsg; memset( &sendMsg, 0, sizeof(MSG_SYN_ITEM_STALL_SELL_OPEN) ); sendMsg.Category = NM_ITEM; sendMsg.Protocol = NM_ITEM_STALL_SELL_OPEN_SYN; sendMsg.characterIdx = mObject.index; wcscpy( sendMsg.title, mStallSellTitle ); NETWORK2->QuickSendExcept( this, (char*)&sendMsg, sizeof(MSG_SYN_ITEM_STALL_SELL_OPEN) ); } // StallSellClose Method. void cPlayer::StallSellClose(ULONG_PTR /*socketContext*/, MSG_REQ_ITEM_STALL_SELL_CLOSE* /*msg*/) { // 1-1. ij¸¯ÅÍ »óÅ °Ë»ç. if ( IsChangeState( eOBJECT_STATE_IDLE ) == false ) throw ERROR_ITEM_STALL_SELL_CLOSE_FAIL; // ij¸¯ÅÍ »óÅ ¿À·ù - º¯°æºÒ°¡. if ( GetStateStop( ) != eSTOP_OPENSTALL ) throw ERROR_ITEM_STALL_SELL_CLOSE_FAIL; // ij¸¯ÅÍ »óÅ ¿À·ù. // 1-2. ³ëÁ¡ »óÅ °Ë»ç. if ( mStallSell != true ) throw ERROR_ITEM_STALL_SELL_CLOSE_FAIL; // 2-1. ij¸¯ÅÍ »óÅ º¯°æ. ChangeState( eOBJECT_STATE_IDLE ); SetStateStop( eSTOP_NONE ); // 2-2. ³ëÁ¡ ÆÇ¸ÅÀÚ ´Ý±â. ReleaseStallSellAllGuests( ); // °Ô½ºÆ®(GUEST)´Ý±â. ClearStallSellItem( ); // ³ë Á¡ ¾ÆÀÌÅÛ Á¤¸®. // 3-1. ³ëÁ¡´Ý±â ¼º°ø. SendMsgResStallSell( NM_ITEM, NM_ITEM_STALL_SELL_CLOSE_RES, ERROR_ITEM_STALL_SELL_CLOSE_SUCCESS ); // 3-2. ³ëÁ¡´Ý±â µ¿±âÈ­. MSG_SYN_ITEM_STALL_SELL_CLOSE sendMsg; memset( &sendMsg, 0, sizeof(MSG_SYN_ITEM_STALL_SELL_CLOSE) ); sendMsg.Category = NM_ITEM; sendMsg.Protocol = NM_ITEM_STALL_SELL_CLOSE_SYN; sendMsg.characterIdx = mObject.index; NETWORK2->QuickSendExcept( this, (char*)&sendMsg, sizeof(MSG_SYN_ITEM_STALL_SELL_CLOSE) ); } // StallSellOpenDie Method. void cPlayer::StallSellOpenDie( ) { ReleaseStallSellAllGuests( ); // °Ô½ºÆ® Á¤¸®. ClearStallSellItem( ); // ¾ÆÀÌÅÛ Á¤¸®. } // StallSellOpenShutdown Method. void cPlayer::StallSellOpenShutdown(bool /*shutdown*/) { ReleaseStallSellAllGuests( ); // °Ô½ºÆ® Á¤¸®. ClearStallSellItem( ); // ¾ÆÀÌÅÛ Á¤¸®. ChangeState( eOBJECT_STATE_STOP ); SetStateStop( eSTOP_GAMEFINISH ); } // StallSellUseDie Method. void cPlayer::StallSellUseDie( ) { cPlayer* player = GRIDMANAGER->GetPlayer( mStallSellOwner.index ); if ( player != NULL ) player->ReleaseStallSellGuest( mObject.index ); } // StallSellUseShutdown Method. void cPlayer::StallSellUseShutdown(bool /*shutdown*/) { cPlayer* player = GRIDMANAGER->GetPlayer( mStallSellOwner.index ); if ( player != NULL ) player->ReleaseStallSellGuest( mObject.index ); ChangeState( eOBJECT_STATE_STOP ); SetStateStop( eSTOP_GAMEFINISH ); } // GetStallSellItem Method - »ý¼º. StallSellItem* cPlayer::GetStallSellItem(TB_INVENTORY* inventory, long price) { if ( !(mStallSellItemOffset < MAX_STALL_ITEM) ) return NULL; StallSellItem* stallSellItem = mStallSellItems; for ( int i = 0; i < MAX_STALL_ITEM; i++, stallSellItem++ ) { if ( stallSellItem->status == StallSellItemNone ) { stallSellItem->status = StallSellItemStart; // ³ëÁ¡ ¾ÆÀÌÅÛ ÆÇ¸Å½ÃÀÛ. stallSellItem->inventory = inventory; // Àκ¥Å丮 Æ÷ÀÎÅÍ ÂüÁ¶. stallSellItem->price = price; // ³ëÁ¡ ¾ÆÀÌÅÛ°¡°Ý ¼³Á¤. mStallSellItemOffset++; return stallSellItem; } } return NULL; } // GetStallSellItem Method - °Ë»ö. StallSellItem* cPlayer::GetStallSellItem(TB_INVENTORY* inventory) { StallSellItem* stallSellItem = mStallSellItems; for ( int i = 0; i < MAX_STALL_ITEM; i++, stallSellItem++ ) { if ( stallSellItem->inventory == inventory ) return stallSellItem; } return NULL; } // ReleaseStallSellItem Method - ÇØÁ¦. bool cPlayer::ReleaseStallSellItem(StallSellItem* stallSellItem) { if ( !(mStallSellItemOffset > 0) ) return false; stallSellItem->status = StallSellItemNone; // ³ëÁ¡ ¾ÆÀÌÅÛ ÆÇ¸ÅÁßÁö. stallSellItem->inventory = NULL; // Àκ¥Å丮 Æ÷ÀÎÅÍ Ãʱâ. stallSellItem->price = 0; // ³ëÁ¡ ¾ÆÀÌÅÛ °¡°ÝÃʱâ. mStallSellItemOffset--; // ³ëÁ¡ ¾ÆÀÌÅÛ Á¤·Ä - µî·Ï ±âÁØÀ¸·Î ³»¸²Â÷¼ø. qsort( (void*)mStallSellItems, MAX_STALL_ITEM, sizeof(StallSellItem), StallSellItemCompare ); return true; } // ClearStallSellItem Method. void cPlayer::ClearStallSellItem( ) { StallSellItem* stallSellItem = mStallSellItems; for ( int i = 0; i < MAX_STALL_ITEM && mStallSellItemOffset > 0; i++, stallSellItem++ ) { if ( stallSellItem->status != StallSellItemNone ) { stallSellItem->inventory->apply = InventoryApplyNone; stallSellItem->status = StallSellItemNone; stallSellItem->inventory = NULL; stallSellItem->price = 0; mStallSellItemOffset--; } } mStallSell = false; // ³ëÁ¡Á¾·á. } // GetStallSellGuest Method bool cPlayer::GetStallSellGuest(unsigned long characterIdx) { if ( !(mStallSellGuestOffset < MAX_STALL_GUEST) ) return false; unsigned long* stallSellGuest = mStallSellGuests; for ( int i = 0; i < MAX_STALL_GUEST; i++, stallSellGuest++ ) { if ( (*stallSellGuest) == 0 ) { (*stallSellGuest) = characterIdx; mStallSellGuestOffset++; return true; } } return false; } // ReleaseStallSellGuest Method bool cPlayer::ReleaseStallSellGuest(unsigned long characterIdx) { unsigned long* stallSellGuest = mStallSellGuests; for ( int i = 0; i < MAX_STALL_GUEST && mStallSellGuestOffset > 0; i++, stallSellGuest++ ) { if ( (*stallSellGuest) == characterIdx ) { (*stallSellGuest) = 0; mStallSellGuestOffset--; return true; } } return false; } // ReleaseStallSellAllGuests Method - °Ô½ºÆ®(GUEST) ´Ý±â. void cPlayer::ReleaseStallSellAllGuests( ) { unsigned long* stallSellGuest = mStallSellGuests; for ( int i = 0; i < MAX_STALL_GUEST && mStallSellGuestOffset > 0; i++, stallSellGuest++ ) { if ( (*stallSellGuest) != 0 ) { cPlayer* player = OBJECTMANAGER->GetPlayer( (*stallSellGuest) ); if ( player != NULL ) { if ( player->GetState( ) == eOBJECT_STATE_STOP && player->GetStateStop( ) == eSTOP_USESTALL ) { player->ChangeState( eOBJECT_STATE_IDLE ); player->SetStateStop( eSTOP_NONE ); player->StallSellLeave( ERROR_ITEM_STALL_SELL_LEAVE_CLOSED ); } } (*stallSellGuest) = 0; mStallSellGuestOffset--; } } } // StallSellRename Method. void cPlayer::StallSellRename(ULONG_PTR /*socketContext*/, MSG_REQ_ITEM_STALL_SELL_RENAME* msg) { // ÀÌ¹Ì ¿ÀÇÂÁß °Ë»ç if ( mStallSell == false ) throw ERROR_ITEM_STALL_SELL_RENAME_FAIL; // ³ëÁ¡¸í º¯°æ. msg->title[ STALL_TITLE_LEN ] = 0; wcscpy( mStallSellTitle, msg->title ); SendMsgResStallSell( NM_ITEM, NM_ITEM_STALL_SELL_RENAME_RES, ERROR_ITEM_STALL_SELL_RENAME_SUCCESS ); MSG_SYN_ITEM_STALL_SELL_RENAME sendMsg; memset( &sendMsg, 0, sizeof(MSG_SYN_ITEM_STALL_SELL_RENAME) ); sendMsg.Category = NM_ITEM; sendMsg.Protocol = NM_ITEM_STALL_SELL_RENAME_SYN; sendMsg.characterIdx = mObject.index; wcscpy( sendMsg.title, mStallSellTitle ); NETWORK2->QuickSendExcept( this, (char*)&sendMsg, sizeof(MSG_SYN_ITEM_STALL_SELL_RENAME) ); } // StallSellAdd Method - ¸ñ·Ï¿¡ ¾ÆÀÌÅÛ µî·ÏÈÄ DB µ¿±âÈ­ ¿äû - µ¥ÀÌÅÍ Ã³¸®ÈÄ ¸Þ½ÃÁö Àü¼Û. void cPlayer::StallSellAdd(ULONG_PTR /*socketContext*/, MSG_REQ_ITEM_STALL_SELL_ADD* msg) { // ³ëÁ¡ »óŰ˻ç. if ( mStallSell == false ) throw ERROR_ITEM_STALL_SELL_ADD_FAIL; if ( IsInventoryBag( msg->number ) == false ) throw ERROR_ITEM_STALL_SELL_ADD_FAIL; StallSellItem* stallSellItem = NULL; TB_INVENTORY* inventory = SelectInventory( msg->number ); if ( IsInventory( inventory ) == false ) throw ERROR_ITEM_STALL_SELL_ADD_FAIL; TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ) ; if ( IsItemExchange( itemDefine, inventory ) == false ) throw ERROR_ITEM_STALL_SELL_ADD_EXCHANGE; __int64 totalPrice = (__int64)msg->price * (__int64)inventory->count; if( totalPrice > MAX_TRADE_MONEY ) throw ERROR_ITEM_STALL_SELL_ADD_TRADE_MONEY; // µ¥ÀÌÅÍ Ã³¸®. if ( inventory->apply == InventoryApplyNone ) { stallSellItem = GetStallSellItem( inventory, msg->price ); // ¾ÆÀÌÅÛ µî·Ï. if ( stallSellItem == NULL ) throw ERROR_ITEM_STALL_SELL_ADD_FAIL; inventory->apply = InventoryApplyStallSell; // Àκ¥Å丮 APPLY »óꝰæ. } else if ( inventory->apply == InventoryApplyStallSell ) { stallSellItem = GetStallSellItem( inventory ); // ¾ÆÀÌÅÛ °»½Å. if ( stallSellItem == NULL ) throw ERROR_ITEM_STALL_SELL_ADD_FAIL; if ( stallSellItem->status != StallSellItemPause ) throw ERROR_ITEM_STALL_SELL_ADD_FAIL; stallSellItem->status = StallSellItemStart; stallSellItem->price = msg->price; } else throw ERROR_ITEM_STALL_SELL_ADD_FAIL; // ¸Þ½ÃÁö Àü¼Û. SendMsgResStallSell( NM_ITEM, NM_ITEM_STALL_SELL_ADD_RES, ERROR_ITEM_STALL_SELL_ADD_SUCCESS ); SendMsgSynStallSell( NM_ITEM, NM_ITEM_STALL_SELL_ADD_SYN, stallSellItem->inventory, stallSellItem->price ); } // StallSellDel Method - ¸ñ·ÏÁß ¾ÆÀÌÅÛ »èÁ¦ÈÄ DBµ¿±âÈ­ ¿äû - ¸Þ½ÃÁö Àü¼ÛÈÄ µ¥ÀÌÅÍ Ã³¸®. void cPlayer::StallSellDel(ULONG_PTR /*socketContext*/, MSG_REQ_ITEM_STALL_SELL_DEL* msg) { // ³ëÁ¡ »óŰ˻ç. if ( mStallSell == false ) throw ERROR_ITEM_STALL_SELL_DEL_FAIL; TB_INVENTORY* inventory = SelectInventory( msg->number ); if ( IsInventory( inventory ) == false || inventory->apply != InventoryApplyStallSell ) throw ERROR_ITEM_STALL_SELL_DEL_FAIL; // ³ëÁ¡ ¾ÆÀÌÅÛ °Ë»ö. StallSellItem* stallSellItem = GetStallSellItem( inventory ); if ( stallSellItem == NULL ) throw ERROR_ITEM_STALL_SELL_DEL_FAIL; if ( stallSellItem->status == StallSellItemNone ) throw ERROR_ITEM_STALL_SELL_DEL_FAIL; // ¸Þ½ÃÁö Àü¼Û. SendMsgResStallSell( NM_ITEM, NM_ITEM_STALL_SELL_DEL_RES, ERROR_ITEM_STALL_SELL_DEL_SUCCESS ); SendMsgSynStallSell( NM_ITEM, NM_ITEM_STALL_SELL_DEL_SYN, stallSellItem->inventory, stallSellItem->price ); // µ¥ÀÌÅÍ Ã³¸®. inventory->apply = InventoryApplyNone; // Àκ¥Å丮 APPLY »óꝰæ. // ³ëÁ¡ ¾ÆÀÌÅÛ »èÁ¦ ReleaseStallSellItem( stallSellItem ); } // StallSellMod Method - »óŸ¸ º¯°æ. void cPlayer::StallSellMod(ULONG_PTR /*socketContext*/, MSG_REQ_ITEM_STALL_SELL_MOD* msg) { // ³ëÁ¡ »óŰ˻ç. if ( mStallSell == false ) throw ERROR_ITEM_STALL_SELL_MOD_FAIL; TB_INVENTORY* inventory = SelectInventory( msg->number ); if ( IsInventory( inventory ) == false || inventory->apply != InventoryApplyStallSell ) throw ERROR_ITEM_STALL_SELL_MOD_FAIL; if ( !(mStallSellItemOffset > 0) ) throw ERROR_ITEM_STALL_SELL_MOD_FAIL; // ³ëÁ¡ ¾ÆÀÌÅÛ °Ë»ö. StallSellItem* stallSellItem = GetStallSellItem( inventory ); if ( stallSellItem == NULL ) throw ERROR_ITEM_STALL_SELL_MOD_FAIL; if ( stallSellItem->status == StallSellItemNone ) throw ERROR_ITEM_STALL_SELL_MOD_FAIL; stallSellItem->status = StallSellItemPause; // ³ëÁ¡ ¾ÆÀÌÅÛ ÆÇ¸Å ÀϽÃÁßÁö. SendMsgResStallSell( NM_ITEM, NM_ITEM_STALL_SELL_MOD_RES, ERROR_ITEM_STALL_SELL_MOD_SUCCESS ); SendMsgSynStallSell( NM_ITEM, NM_ITEM_STALL_SELL_MOD_SYN, stallSellItem->inventory, stallSellItem->price ); } // StallSellJoin Method. void cPlayer::StallSellJoin(ULONG_PTR /*socketContext*/, MSG_REQ_ITEM_STALL_SELL_JOIN* msg) { if ( IsChangeState( eOBJECT_STATE_STOP ) == false ) throw ERROR_ITEM_STALL_SELL_JOIN_FAIL; // ij¸¯ÅÍ »óÅ ¿À·ù - º¯°æºÒ°¡. if ( GetStateStop( ) != eSTOP_NONE ) throw ERROR_ITEM_STALL_SELL_JOIN_FAIL; // ij¸¯ÅÍ »óÅ ¿À·ù. cPlayer* player = GRIDMANAGER->GetPlayer( msg->mTarget.index ); if ( player == NULL ) throw ERROR_ITEM_STALL_SELL_JOIN_FAIL; player->StallSellJoin( this ); mStallSellOwner = player->GetObject( ); ChangeState( eOBJECT_STATE_STOP ); SetStateStop( eSTOP_USESTALL ); } void cPlayer::StallSellJoin(cPlayer* player) { // ³ëÁ¡ »óŰ˻ç. if ( mStallSell == false ) throw ERROR_ITEM_STALL_SELL_JOIN_FAIL; if ( GetStallSellGuest( player->GetObjectID( ) ) == false ) throw ERROR_ITEM_STALL_SELL_JOIN_OVER; // ³ëÁ¡ ¾ÆÀÌÅÛ¸ñ·Ï Àü¼Û. HANDLE handle = NULL; MSG_RES_ITEM_STALL_SELL_JOIN* sendMsg = (MSG_RES_ITEM_STALL_SELL_JOIN*)NETWORK2->GetMsgRoot( &handle, player->GetConnectionIdx( ), NM_ITEM, NM_ITEM_STALL_SELL_JOIN_RES ); if ( sendMsg != NULL ) { StallSellItem* stallSellItem = mStallSellItems; sStallSellData* stallSellData = sendMsg->stallSellData; sendMsg->ErrorCode = ERROR_ITEM_STALL_SELL_JOIN_SUCCESS; // ¼º°ø. wcscpy( sendMsg->title, mStallSellTitle ); // ŸÀÌÆ² º¹»ç. for ( unsigned long i = 0; i < mStallSellItemOffset; i++, stallSellData++, stallSellItem++ ) { stallSellData->status = stallSellItem->status; Inventory2sInventory( &stallSellData->inventory, stallSellItem->inventory ); stallSellData->price = stallSellItem->price; sendMsg->rowCount++; } NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength( ) ); } } // StallSellLeave Method. void cPlayer::StallSellLeave(ULONG_PTR /*socketContext*/, MSG_REQ_ITEM_STALL_SELL_LEAVE* /*msg*/) { if ( GetState( ) != eOBJECT_STATE_STOP || GetStateStop( ) != eSTOP_USESTALL ) throw ERROR_ITEM_STALL_SELL_LEAVE_FAIL; // ij¸¯ÅÍ »óÅ ¿À·ù. if ( IsChangeState( eOBJECT_STATE_IDLE ) == false ) throw ERROR_ITEM_STALL_SELL_LEAVE_FAIL; // ij¸¯ÅÍ »óÅ ¿À·ù - º¯°æºÒ°¡. ChangeState( eOBJECT_STATE_IDLE ); SetStateStop( eSTOP_NONE ); cPlayer* player = GRIDMANAGER->GetPlayer( mStallSellOwner.index ); if ( player == NULL ) throw ERROR_ITEM_STALL_SELL_LEAVE_FAIL; if ( player->StallSellLeave( this ) == false ) throw ERROR_ITEM_STALL_SELL_LEAVE_FAIL; StallSellLeave( ERROR_ITEM_STALL_SELL_LEAVE_SUCCESS ); } bool cPlayer::StallSellLeave(cPlayer* player) { return ( mStallSell == true ) ? ReleaseStallSellGuest( player->GetObjectID( ) ) : false; } void cPlayer::StallSellLeave(int error) { SendMsgResStallSell( NM_ITEM, NM_ITEM_STALL_SELL_LEAVE_RES, error ); } // StallSellGet Method. void cPlayer::StallSellGet(ULONG_PTR socketContext, MSG_REQ_ITEM_STALL_SELL_GET* msg) { if ( GetState( ) != eOBJECT_STATE_STOP || GetStateStop( ) != eSTOP_USESTALL ) throw ERROR_ITEM_STALL_SELL_GET_FAIL; // ij¸¯ÅÍ »óÅ ¿À·ù. cPlayer* player = OBJECTMANAGER->GetPlayer( mStallSellOwner.index ); if ( player == NULL ) throw ERROR_ITEM_STALL_SELL_GET_FAIL; if ( player->IsStallSellOpen( ) == false ) throw ERROR_ITEM_STALL_SELL_GET_FAIL; if ( player->IsInventoryBag( msg->number ) == false ) throw ERROR_ITEM_STALL_SELL_GET_FAIL; TB_INVENTORY* inventory = player->SelectInventory( msg->number ); if ( IsInventory( inventory ) == false ) throw ERROR_ITEM_STALL_SELL_GET_FAIL; if ( inventory->apply != InventoryApplyStallSell ) throw ERROR_ITEM_STALL_SELL_GET_FAIL; if ( msg->count > inventory->count ) throw ERROR_ITEM_STALL_SELL_GET_FAIL; StallSellItem* stallSellItem = player->GetStallSellItem( inventory ); if ( stallSellItem == NULL ) throw ERROR_ITEM_STALL_SELL_GET_FAIL; if ( stallSellItem->status != StallSellItemStart ) throw ERROR_ITEM_STALL_SELL_GET_FAIL; if ( mMoney < (stallSellItem->price * msg->count) ) throw ERROR_ITEM_STALL_SELL_GET_FAIL; short inventoryNumber = GetEmptyBagNumber( ); if ( inventoryNumber == INVENTORY_BAG_NONE ) throw ERROR_ITEM_STALL_SELL_GET_FAIL; TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if( IsMaxInventory( itemDefine, msg->count ) == true ) throw ERROR_ITEM_STALL_SELL_LEAVE_MAX_ITEM; // º¸À¯°¡´É ±Ý¾× long totalPrice = (long)(stallSellItem->price * msg->count); if( player->IsAddMoney( totalPrice ) == false ) throw ERROR_ITEM_STALL_SELL_LEAVE_HAVE_MONEY; // ±¸¸Å½ÃÀÛ - ±¸¸ÅÀÚ ÈÄ ÀÀ´ä. HANDLE handle = NULL; STALL_SELL_GET* stallSellGet = (STALL_SELL_GET*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_STALL_SELL_GET ); stallSellGet->fObject = player->GetObject( ); stallSellGet->fCharacterMoney = (+totalPrice); stallSellGet->fInventory = *inventory; stallSellGet->tObject = GetObject( ); stallSellGet->tCharacterMoney = (-totalPrice); stallSellGet->tInventory = *inventory; stallSellGet->tInventory.idx = 0; stallSellGet->tInventory.number = inventoryNumber; stallSellGet->tInventory.count = msg->count; stallSellGet->tInventory.apply = InventoryApplyNone; mInventoryDb.stallSellGet = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, sizeof(STALL_SELL_GET) ); if ( mInventoryDb.stallSellGet == false ) throw ERROR_ITEM_STALL_SELL_GET_FAIL; // ±¸¸Å½ÃÀÛ - ÆÇ¸ÅÀÚ ¼± ÀÀ´ä. { // ÆÇ¸ÅÀÚ ¼± ÀÀ´ä - ÆÇ¸Å±Ý¾×. unsigned long befor = player->GetMoney( ); long result = player->AddMoney( GetObject( ), totalPrice, false ); unsigned long after = player->GetMoney( ); NETWORK2->PostMoneyEvent( player->GetObjectID( ), befor, after, "STALL_SELL_GET(SELL)::Character(=%d):Money(=%d)", GetObjectID( ), totalPrice ); if ( result != totalPrice ) NETWORK2->PostServerEvent( "Error - SQL_GAME_PROCESS_STALL_SELL_GET CharacterIdx(=%d), AddMoney(=%d) != ResultMoney(=%d).", player->GetObjectID( ), totalPrice, result ); // ÆÇ¸ÅÀÚ ¼± ÀÀ´ä - ¾ÆÀÌÅÛ. player->UpdateInventory( inventory, (-msg->count) ); HANDLE handle = NULL; MSG_RES_ITEM_STALL_SELL_COM* sendMsg = (MSG_RES_ITEM_STALL_SELL_COM*)NETWORK2->GetMsgRoot( &handle, player->GetConnectionIdx( ), NM_ITEM, NM_ITEM_STALL_SELL_COM_RES ); if ( sendMsg != NULL ) { wcscpy( sendMsg->characterName, GetName() ); Inventory2sInventory( &sendMsg->inventory, inventory ); NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_ITEM_STALL_SELL_COM) ); } if ( stallSellItem->inventory->count > 0 ) { NETWORK2->PostInventoryEvent( EVENT_INVENTORY_UPDATE ,player->GetObjectID( ) ,stallSellItem->inventory ,"STALL SELL - SELL CHARACTER_IDX=%d" ,mObject.index ); // ÆÇ¸ÅÈÄ °»½Å. stallSellItem->status = StallSellItemStart; player->SendMsgSynStallSell( NM_ITEM, NM_ITEM_STALL_SELL_ADD_SYN, stallSellItem->inventory, stallSellItem->price ); } else { NETWORK2->PostInventoryEvent( EVENT_INVENTORY_DELETE ,player->GetObjectID( ) ,stallSellItem->inventory ,"STALL SELL - SELL CHARACTER_IDX=%d" ,mObject.index ); // ÆÇ¸ÅÈÄ »èÁ¦. player->SendMsgSynStallSell( NM_ITEM, NM_ITEM_STALL_SELL_DEL_SYN, stallSellItem->inventory, stallSellItem->price ); player->RemoveInventory( stallSellItem->inventory->number ); player->ReleaseStallSellItem( stallSellItem ); } } } // SendMsgResStallSell Method. bool cPlayer::SendMsgResStallSell(char category, char protocol, int error) { return NETWORK2->SendMsgError( mConnectionIdx, category, protocol, error ); } // SendMsgSynStallSell Method. void cPlayer::SendMsgSynStallSell(char category, char protocol, TB_INVENTORY* inventory, long price) { unsigned long* stallSellGuest = mStallSellGuests; for ( int i = 0; i < MAX_STALL_GUEST; i++, stallSellGuest++ ) { if ( (*stallSellGuest) != 0 ) { cPlayer* player = OBJECTMANAGER->GetPlayer( (*stallSellGuest) ); if ( player != NULL ) { HANDLE handle = NULL; MSG_SYN_ITEM_STALL_SELL_DAT* synMsg = (MSG_SYN_ITEM_STALL_SELL_DAT*)NETWORK2->GetMsgRoot( &handle, player->GetConnectionIdx( ), category, protocol ); if ( synMsg != NULL ) { Inventory2sInventory( &synMsg->inventory, inventory ); synMsg->price = price; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_ITEM_STALL_SELL_DAT) ); } } else { ReleaseStallSellGuest( (*stallSellGuest) ); } } } } // SetItemAgentCheck Method. void cPlayer::SetItemAgentCheck(long nextCheck) { mItemAgentCheck = (nextCheck > 0) ? true : false; mItemAgentNextCheck = NETWORK2->GetAccumTime( ) + nextCheck; } // ItemAgentSearchOwner Method. bool cPlayer::ItemAgentPageOpen( ULONG_PTR socketContext, long startPage ) { // ij¸¯ÅÍ »óÅ °Ë»ç. if ( GetStateDie( ) == true ) throw ERROR_NPC_ITEM_AGENT_OPEN_PAGE_FAIL; if ( startPage <= 0 ) startPage= 1; HANDLE handle = NULL; ITEM_AGENT_SELECT_OWNER* select = (ITEM_AGENT_SELECT_OWNER*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_AGENT_SELECT_OWNER ); long length = sizeof(ITEM_AGENT_SELECT_OWNER) - sizeof(select->table); select->characterIdx = mObject.index; select->startPage = startPage; return NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); } // ItemAgentAdd Method. void cPlayer::ItemAgentAdd(ULONG_PTR socketContext, MSG_REQ_NPC_ITEM_AGENT_ADD* msg) { /*-- °Ë»çÇÒ ³»¿ëµé. --*/ if ( mInventoryDatabase ) throw ERROR_NPC_ITEM_AGENT_ADD_NOTYET; // ij¸¯ÅÍ »óÅ °Ë»ç. if ( GetStateDie( ) == true ) throw ERROR_NPC_ITEM_AGENT_ADD_FAIL; // Àκ¥Å丮 °Ë»ç. if( IsInventoryBag( msg->Number ) == false ) throw ERROR_NPC_ITEM_AGENT_ADD_FAIL; TB_INVENTORY* inventory = SelectInventory( msg->Number ); if ( IsInventory( inventory ) == false ) throw ERROR_NPC_ITEM_AGENT_ADD_FAIL; __int64 totalPrice = (__int64)msg->Price * (__int64)msg->Count; if( totalPrice > MAX_TRADE_MONEY ) throw ERROR_NPC_ITEM_AGENT_ADD_TRADE_MONEY; // µî·Ï¼ö¼ö·á °Ë»ç. switch ( msg->ValidThru ) { case NPC_ITEM_AGENT_TIME1: case NPC_ITEM_AGENT_TIME2: case NPC_ITEM_AGENT_TIME3: break; default: throw ERROR_NPC_ITEM_AGENT_ADD_FAIL; } u_long commission = (u_long)(msg->ValidThru / NPC_ITEM_AGENT_TIME1 * ITEM_AGENT_NPC_FEE); if ( commission > mMoney ) throw ERROR_NPC_ITEM_AGENT_ADD_FAIL; TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if ( itemDefine == NULL ) throw ERROR_NPC_ITEM_AGENT_ADD_FAIL; if ( IsItemExchange( itemDefine, inventory ) == false ) throw ERROR_NPC_ITEM_AGENT_ADD_EXCHANGE; if ( msg->StartPage <= 0 ) msg->StartPage = 1; HANDLE handle = NULL; ITEM_AGENT_INSERT* insert = (ITEM_AGENT_INSERT*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_AGENT_INSERT ); long length = sizeof(ITEM_AGENT_INSERT) - sizeof(insert->table); insert->inventory = (*inventory); insert->validThru = msg->ValidThru; insert->price = msg->Price; insert->characterIdx = mObject.index; insert->startPage = msg->StartPage; mInventoryDb.agentInsert = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); if ( mInventoryDb.agentInsert == false ) throw ERROR_NPC_ITEM_AGENT_ADD_FAIL; // µî·ÏÀü »èÁ¦. RemoveInventory( inventory ); } // ItemAgentDel Method. void cPlayer::ItemAgentDel(ULONG_PTR socketContext, MSG_REQ_NPC_ITEM_AGENT_DEL* msg) { /*-- °Ë»çÇÒ ³»¿ëµé. --*/ if ( mInventoryDatabase ) throw ERROR_NPC_ITEM_AGENT_DEL_NOTYET; // ij¸¯ÅÍ »óÅ °Ë»ç. if ( GetStateDie( ) == true ) throw ERROR_NPC_ITEM_AGENT_DEL_FAIL; short inventoryNumber = GetEmptyBagNumber( ); if ( inventoryNumber == INVENTORY_BAG_NONE ) throw ERROR_NPC_ITEM_AGENT_DEL_FAIL; if ( msg->StartPage <= 0 ) msg->StartPage = 1; HANDLE handle = NULL; ITEM_AGENT_DELETE* del = (ITEM_AGENT_DELETE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_AGENT_DELETE ); long length = sizeof(ITEM_AGENT_DELETE) - sizeof(del->table); del->idx = msg->Idx; del->characterIdx = mObject.index; del->inventoryNumber = inventoryNumber; del->startPage = msg->StartPage; mInventoryDb.agentDelete = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); if ( mInventoryDb.agentDelete == false ) throw ERROR_NPC_ITEM_AGENT_DEL_FAIL; } // ItemAgentGet Method. void cPlayer::ItemAgentGet(ULONG_PTR socketContext, MSG_REQ_NPC_ITEM_AGENT_GET* msg) { /*-- °Ë»çÇÒ ³»¿ëµé. --*/ // ij¸¯ÅÍ »óÅ °Ë»ç. if ( GetStateDie( ) == true ) throw ERROR_NPC_ITEM_AGENT_DEL_FAIL; if ( msg->startPage <= 0 ) msg->startPage = 1; msg->itemDefineName[ 50 ] = 0; HANDLE handle = NULL; ITEM_AGENT_UPDATE* update = (ITEM_AGENT_UPDATE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_AGENT_UPDATE ); unsigned long length = sizeof(ITEM_AGENT_UPDATE) - sizeof(update->table); update->characterIdx = mObject.index; update->idx = msg->Idx; update->count = msg->Count; update->startPage = msg->startPage; update->sort = msg->sortData; wcscpy_s( update->itemDefineName, 50, msg->itemDefineName ); update->itemDefineSearchType = msg->itemDefineSearchType; update->itemDefineSearchSubType = msg->itemDefineSearchSubType; update->itemDefineRareLevel = msg->itemDefineRareLevel; update->itemLimitLevelB = msg->itemLimitCharLevelB; update->itemLimitLevelE = msg->itemLimitCharLevelE; update->inventoryEnhanced = msg->inventoryEnhanced; mInventoryDb.agentUpdate = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); } // CbItemAgentCheck Method. void cPlayer::CbItemAgentCheck(ITEM_AGENT_CHECK* check) { if ( check->retvalue == 0 ) { // ¾ÆÀÌÅÛ ÆÇ¸Å´ëÇà Ãë¼Ò. if ( check->rowCount > 0 ) { NETWORK2->SendMsgRoot( mConnectionIdx, NM_CHAT ,NM_CHAT_POST_RECEIVED_SYN ); } // ¾ÆÀÌÅÛ ÆÇ¸Å´ëÇà °Ë»ç ¼³Á¤. if ( check->nextCheck > DELAY_ITEM_AGENT_CHECK ) { SetItemAgentCheck( check->nextCheck ); } else if ( check->nextCheck > 0 ) { SetItemAgentCheck( DELAY_ITEM_AGENT_CHECK ); } else SetItemAgentCheck( 0 ); } else { // ¿À·ùÀϰæ¿ì, 10ºÐÈÄ Àç½Ãµµ. SetItemAgentCheck( DELAY_ITEM_AGENT_CHECK ); } } // CbItemAgentAdd Method. void cPlayer::CbItemAgentAdd(ULONG_PTR socketContext, ITEM_AGENT_INSERT* insert, u_long requestResult) { if ( mInventoryDb.agentInsert ) mInventoryDb.agentInsert = false; else return; if ( requestResult != 0 ) throw requestResult; if ( insert->retvalue != 0 ) throw insert->retvalue; ITEM_AGENT_RESULT_OWNER* table = insert->table; HANDLE handle = NULL; MSG_RES_NPC_ITEM_AGENT_ADD* sendMsg = (MSG_RES_NPC_ITEM_AGENT_ADD*)NETWORK2->GetMsgRoot( &handle, (PerSocketContext*)socketContext, NM_NPC, NM_NPC_ITEM_AGENT_ADD_RES ); NPC_ITEM_AGENT_OPEN_RESULT* result = sendMsg->Result; sendMsg->ErrorCode = ERROR_NPC_ITEM_AGENT_ADD_SUCCESS; sendMsg->StartPage = insert->startPage; sendMsg->EndPage = insert->endPage; sendMsg->RowCount = insert->rowCount; for ( long i = 0; i < insert->rowCount; i++, table++, result++ ) { result->Idx = table->idx; result->ValidThru = table->validThru; result->Price = table->price; Inventory2sInventory( &result->Inventory, &table->table ); } // µî·Ï¼ö¼ö·á Â÷°¨. long commission = (long)(insert->validThru / NPC_ITEM_AGENT_TIME1 * ITEM_AGENT_NPC_FEE); AddMoney( mObject, -commission ); NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength() ); NETWORK2->PostInventoryEvent( EVENT_INVENTORY_UPDATE, mObject.index, &insert->inventory, "ITEM AGENT - ADD" ); // ´ÙÀ½ °Ë»ç½Ã°£ ¼³Á¤. mItemAgentCheck = true; mItemAgentNextCheck = insert->nextCheck; // ¾ÆÀÌÅÛ ÆÇ¸Å´ëÇà °Ë»ç ¼³Á¤. if ( insert->nextCheck > 0 ) { SetItemAgentCheck( insert->nextCheck ); } } // CbItemAgentDel Method. void cPlayer::CbItemAgentDel(ULONG_PTR socketContext, ITEM_AGENT_DELETE* del, u_long requestResult) { if ( mInventoryDb.agentDelete ) mInventoryDb.agentDelete = false; else return; if ( requestResult != 0 ) throw requestResult; if ( del->retvalue != 0 ) throw del->retvalue; HANDLE handle = NULL; MSG_RES_NPC_ITEM_AGENT_DEL* sendMsg = (MSG_RES_NPC_ITEM_AGENT_DEL*)NETWORK2->GetMsgRoot( &handle, (PerSocketContext*)socketContext, NM_NPC, NM_NPC_ITEM_AGENT_DEL_RES ); NPC_ITEM_AGENT_OPEN_RESULT* result = sendMsg->Result; ITEM_AGENT_RESULT_OWNER* table = del->table; sendMsg->ErrorCode = ERROR_NPC_ITEM_AGENT_DEL_SUCCESS; Inventory2sInventory( &sendMsg->Inventory, &del->result ); sendMsg->StartPage = del->startPage; sendMsg->EndPage = del->endPage; sendMsg->RowCount = del->rowCount; for ( long i = 0; i < del->rowCount; i++, table++, result++ ) { result->Idx = table->idx; result->ValidThru = table->validThru; result->Price = table->price; Inventory2sInventory( &result->Inventory, &table->table ); } NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength() ); XCopyInventory( &del->result ); NETWORK2->PostInventoryEvent( EVENT_INVENTORY_UPDATE, mObject.index, &del->result, "ITEM AGENT - DEL" ); } // CbItemAgentGet Method. void cPlayer::CbItemAgentGet(ULONG_PTR socketContext, ITEM_AGENT_UPDATE* update, u_long requestResult) { if ( mInventoryDb.agentUpdate ) mInventoryDb.agentUpdate = false; else return; if ( requestResult != 0 ) throw requestResult; if ( update->retvalue != 0 ) throw update->retvalue; HANDLE handle = NULL; MSG_RES_NPC_ITEM_AGENT_GET* sendMsg = (MSG_RES_NPC_ITEM_AGENT_GET*)NETWORK2->GetMsgRoot( &handle ,(PerSocketContext*)socketContext ,NM_NPC ,NM_NPC_ITEM_AGENT_GET_RES ); NPC_ITEM_AGENT_SEARCH_RESULT* result = sendMsg->Result; sendMsg->ErrorCode = update->retvalue; AddMoney( mObject, (-update->price) ); sendMsg->StartPage = update->startPage; sendMsg->EndPage = update->endPage; sendMsg->RowCount = update->rowCount; ITEM_AGENT_RESULT* table = update->table; for ( long i = 0; i < update->rowCount; i++, table++, result++ ) { result->Idx = table->idx; wcscpy_s( result->CharacterName, table->characterName ); result->ValidThru = table->validThru; result->Price = table->price; Inventory2sInventory( &result->Inventory, &table->table ); } /*-- ·Î±× --*/ NETWORK2->PostInventoryEvent( update->sciLog.apply ? EVENT_INVENTORY_DELETE : EVENT_INVENTORY_UPDATE ,update->sccIdx ,&update->sciLog ,"ITEM AGENT - GET (BUY::%d)", update->bciLog.idx ); // ÆÇ¸Å¿Ï·á(SELL COMPLETE ITEM) NETWORK2->PostInventoryEvent( EVENT_INVENTORY_CREATE ,mObject.index ,&update->bciLog ,"ITEM AGENT - GET (SELL::%d)", update->sciLog.idx ); // ±¸¸Å¿Ï·á(BUY COMPLETE ITEM) NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength( ) ); /*-- ¿ìÆíµ¿±âÈ­ --*/ NETWORK2->SendMsgRoot( (PerSocketContext*)socketContext, NM_CHAT, NM_CHAT_POST_RECEIVED_SYN ); cPlayer* player = GRIDMANAGER->GetPlayer( update->sccIdx ); if ( player != NULL ) { NETWORK2->SendMsgRoot( player->GetConnectionIdx ( ), NM_CHAT, NM_CHAT_POST_RECEIVED_SYN ); } else { NETWORK2->PostPostReceived( update->sccIdx ); } } //// ItemAgentSearch Method. //bool cPlayer::ItemAgentSearch(ULONG_PTR socketContext, MSG_REQ_NPC_ITEM_AGENT_SEARCH* msg) //{ // // ij¸¯ÅÍ »óÅ °Ë»ç. // if ( GetStateDie( ) == true ) // throw ERROR_NPC_ITEM_AGENT_SEARCH_FAIL; // // if ( msg->startPage <= 0 ) // msg->startPage = 1; // // HANDLE handle = NULL; // ITEM_AGENT_SELECT* select = (ITEM_AGENT_SELECT*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_AGENT_SELECT ); // long length = sizeof(ITEM_AGENT_SELECT) - sizeof(select->table); // // select->startPage = msg->startPage; // select->sort = msg->sortData; // select->itemDefineRareLevel = msg->itemDefineRareLevel; // select->itemLimitLevelB = msg->itemLimitCharLevelB; // select->itemLimitLevelE = msg->itemLimitCharLevelE; // select->inventoryEnhanced = msg->inventoryEnhanced; // // return NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); //} // ItemAgentSearchName Method. //bool cPlayer::ItemAgentSearchName(ULONG_PTR socketContext, MSG_REQ_NPC_ITEM_AGENT_SEARCH_NAME* msg) //{ // // ij¸¯ÅÍ »óÅ °Ë»ç. // if ( GetStateDie( ) == true ) // throw ERROR_NPC_ITEM_AGENT_SEARCH_FAIL; // // if ( msg->startPage <= 0 ) // msg->startPage = 1; // msg->itemDefineName[ 50 ] = 0; // // HANDLE handle = NULL; // ITEM_AGENT_SELECT_NAME* select = (ITEM_AGENT_SELECT_NAME*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_AGENT_SELECT_NAME ); // long length = sizeof(ITEM_AGENT_SELECT_NAME) - sizeof(select->table); // // select->startPage = msg->startPage; // select->sort = msg->sortData; // wcscpy_s( select->itemDefineName, 50, msg->itemDefineName ); // select->itemDefineRareLevel = msg->itemDefineRareLevel; // select->itemLimitLevelB = msg->itemLimitCharLevelB; // select->itemLimitLevelE = msg->itemLimitCharLevelE; // select->inventoryEnhanced = msg->inventoryEnhanced; // // return NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); //} // ItemAgentSearchType Method. bool cPlayer::ItemAgentSearchType(ULONG_PTR socketContext, MSG_REQ_NPC_ITEM_AGENT_SEARCH_TYPE* msg) { // ij¸¯ÅÍ »óÅ °Ë»ç. if ( GetStateDie( ) == true ) throw ERROR_NPC_ITEM_AGENT_SEARCH_FAIL; if ( msg->startPage <= 0 ) msg->startPage = 1; HANDLE handle = NULL; ITEM_AGENT_SELECT_TYPE* select = (ITEM_AGENT_SELECT_TYPE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_AGENT_SELECT_TYPE ); long length = sizeof(ITEM_AGENT_SELECT_TYPE) - sizeof(select->table); select->startPage = msg->startPage; select->sort = msg->sortData; select->itemDefineSearchType = msg->itemDefineSearchType; select->itemDefineSearchSubType = msg->itemDefineSearchSubType; select->itemDefineRareLevel = msg->itemDefineRareLevel; select->itemLimitLevelB = msg->itemLimitCharLevelB; select->itemLimitLevelE = msg->itemLimitCharLevelE; select->inventoryEnhanced = msg->inventoryEnhanced; return NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); } // ItemAgentSearchAll Method. bool cPlayer::ItemAgentSearchAll(ULONG_PTR socketContext, MSG_REQ_NPC_ITEM_AGENT_SEARCH_ALL* msg) { // ij¸¯ÅÍ »óÅ °Ë»ç. if ( GetStateDie( ) == true ) throw ERROR_NPC_ITEM_AGENT_SEARCH_FAIL; if ( msg->startPage <= 0 ) msg->startPage = 1; msg->itemDefineName[ 50 ] = 0; HANDLE handle = NULL; ITEM_AGENT_SELECT_ALL* select = (ITEM_AGENT_SELECT_ALL*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_AGENT_SELECT_ALL ); long length = sizeof(ITEM_AGENT_SELECT_ALL) - sizeof(select->table); select->startPage = msg->startPage; select->sort = msg->sortData; wcscpy_s( select->itemDefineName, 50, msg->itemDefineName ); select->itemDefineSearchType = msg->itemDefineSearchType; select->itemDefineSearchSubType = msg->itemDefineSearchSubType; select->itemDefineRareLevel = msg->itemDefineRareLevel; select->itemLimitLevelB = msg->itemLimitCharLevelB; select->itemLimitLevelE = msg->itemLimitCharLevelE; select->inventoryEnhanced = msg->inventoryEnhanced; return NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); } // SetPostCheck Method. void cPlayer::SetPostCheck(long nextCheck) { mPostCheck = (nextCheck > 0) ? true : false; mPostNextCheck = NETWORK2->GetAccumTime( ) + nextCheck; } // PostOpen Method. bool cPlayer::PostOpen(ULONG_PTR socketContext, long startPage) { // ij¸¯ÅÍ »óÅ °Ë»ç. if ( GetStateDie( ) == true ) throw false; if ( startPage <= 0 ) startPage = 1; HANDLE handle = NULL; POST_SELECT* select = (POST_SELECT*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_POST_SELECT ); long length = sizeof(POST_SELECT) - sizeof(select->table); select->characterIdx = mObject.index; select->startPage = startPage; return NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); } bool cPlayer::PostOpen(ULONG_PTR socketContext, MSG_REQ_CHAT_POST_OPEN* msg) { if ( PostOpen( socketContext, msg->startPage ) == false ) throw ERROR_CHAT_POST_OPEN_FAIL; return true; } // PostClose Method. void cPlayer::PostClose(ULONG_PTR socketContext, MSG_REQ_CHAT_POST_CLOSE* /*msg*/) { // ij¸¯ÅÍ »óÅ °Ë»ç. if ( GetStateDie( ) != true ) NETWORK2->SendMsgError( (PerSocketContext*)socketContext, NM_CHAT, NM_CHAT_POST_CLOSE_RES, ERROR_CHAT_POST_CLOSE_SUCCESS ); else throw ERROR_CHAT_POST_CLOSE_FAIL; } // PostRead Method. void cPlayer::PostRead(ULONG_PTR socketContext, MSG_REQ_CHAT_POST_READ* msg) { // ij¸¯ÅÍ »óÅ °Ë»ç. if ( GetStateDie( ) == true ) throw ERROR_CHAT_POST_READ_FAIL; HANDLE handle = NULL; POST_UPDATE_STATUS* status = (POST_UPDATE_STATUS*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_POST_UPDATE_STATUS ); status->characterIdx = mObject.index; status->idx = msg->idx; status->status = POST_STATUS_READ; NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, sizeof(POST_UPDATE_STATUS) ); } // PostWrite Method. void cPlayer::PostWrite(ULONG_PTR socketContext, MSG_REQ_CHAT_POST_WRITE* msg) { // ij¸¯ÅÍ »óÅ °Ë»ç. if ( GetStateDie( ) == true ) throw ERROR_CHAT_POST_WRITE_FAIL; if ( mInventoryDatabase ) throw ERROR_CHAT_POST_WRITE_FAIL; msg->name[ MAX_POST_NAME ]=0; msg->title[ MAX_POST_TITLE ]=0; msg->message[ MAX_POST_MESSAGE ]=0; if ( wcsicmp( msg->name, mPlayerInfo.strName ) == 0 ) throw ERROR_CHAT_POST_WRITE_FAIL; TB_INVENTORY* inventory1 = NULL; TB_INVENTORY* inventory2 = NULL; TB_INVENTORY* inventory3 = NULL; TB_ITEM_DEFINE* itemDefine = NULL; switch ( msg->rowCount ) { case 3: if ( IsInventoryBag( msg->inventoryNumber3 ) == false ) throw ERROR_CHAT_POST_WRITE_FAIL; if ( msg->inventoryNumber3 == msg->inventoryNumber2 ) throw ERROR_CHAT_POST_WRITE_FAIL; if ( msg->inventoryNumber3 == msg->inventoryNumber1 ) throw ERROR_CHAT_POST_WRITE_FAIL; inventory3 = SelectInventory( msg->inventoryNumber3 ); if ( IsInventory( inventory3 ) == false ) throw ERROR_CHAT_POST_WRITE_FAIL; itemDefine = ITEMMANAGER->GetItemDefine( inventory3->itemDefineIdx ); if ( itemDefine == NULL ) throw ERROR_CHAT_POST_WRITE_FAIL; if ( IsItemExchange( itemDefine, inventory3 ) == false ) throw ERROR_CHAT_POST_WRITE_EXCHANGE; case 2: if ( IsInventoryBag( msg->inventoryNumber2 ) == false ) throw ERROR_CHAT_POST_WRITE_FAIL; if ( msg->inventoryNumber2 == msg->inventoryNumber1 ) throw ERROR_CHAT_POST_WRITE_FAIL; inventory2 = SelectInventory( msg->inventoryNumber2 ); if ( IsInventory( inventory2 ) == false ) throw ERROR_CHAT_POST_WRITE_FAIL; itemDefine = ITEMMANAGER->GetItemDefine( inventory2->itemDefineIdx ); if ( itemDefine == NULL ) throw ERROR_CHAT_POST_WRITE_FAIL; if ( IsItemExchange( itemDefine, inventory2 ) == false ) throw ERROR_CHAT_POST_WRITE_EXCHANGE; case 1: if ( IsInventoryBag( msg->inventoryNumber1 ) == false ) throw ERROR_CHAT_POST_WRITE_FAIL; inventory1 = SelectInventory( msg->inventoryNumber1 ); if ( IsInventory( inventory1 ) == false ) throw ERROR_CHAT_POST_WRITE_FAIL; itemDefine = ITEMMANAGER->GetItemDefine( inventory1->itemDefineIdx ); if ( itemDefine == NULL ) throw ERROR_CHAT_POST_WRITE_FAIL; if ( IsItemExchange( itemDefine, inventory1 ) == false ) throw ERROR_CHAT_POST_WRITE_EXCHANGE; break; case 0: break; default: throw ERROR_CHAT_POST_WRITE_FAIL; } // ÃÖ´ë °Å·¡ °¡´É±Ý¾× if( msg->money > MAX_TRADE_MONEY ) throw ERROR_CHAT_POST_WRITE_TRADE_MONEY; long serviceCharge = MAIL_DEFAULT_CHARGE; // ±âº» ¼ö¼ö·á serviceCharge += (msg->rowCount * MAIL_ITEM_CHARGE); // ÷ºÎ ¾ÆÀÌÅÛ ¼ö¼ö·á if ( msg->money < 0 || (unsigned long)(msg->money + serviceCharge) > mMoney ) throw ERROR_CHAT_POST_WRITE_FAIL; HANDLE handle = NULL; POST_INSERT* insert = (POST_INSERT*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_POST_INSERT ); insert->toIdx = 0; wcscpy( insert->toName, msg->name ); insert->validThru = 14; insert->type = 0; // 0¿ìÆí insert->fromIdx = mObject.index; wcscpy( insert->fromName, mPlayerInfo.strName ); wcscpy( insert->contentTitle, msg->title ); wcscpy( insert->contentMessage, msg->message ); if ( inventory1 != NULL ) insert->inventory1 = (*inventory1); if ( inventory2 != NULL ) insert->inventory2 = (*inventory2); if ( inventory3 != NULL ) insert->inventory3 = (*inventory3); insert->money = msg->money; insert->serviceCharage = serviceCharge; mInventoryDb.postInsert = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, sizeof(POST_INSERT) ); if ( mInventoryDb.postInsert == 0 ) throw ERROR_CHAT_POST_WRITE_FAIL; } // PostDownload Method. void cPlayer::PostDownload(ULONG_PTR socketContext, MSG_REQ_CHAT_POST_DOWNLOAD* msg) { // ij¸¯ÅÍ »óÅ °Ë»ç. if ( GetStateDie( ) == true ) throw ERROR_CHAT_POST_DOWNLOAD_FAIL; if ( mInventoryDatabase ) throw ERROR_CHAT_POST_DOWNLOAD_FAIL; if ( msg->inventoryNumber1 != 0 ) { if ( (msg->inventoryNumber2 != 0 && msg->inventoryNumber1 == msg->inventoryNumber2) || (msg->inventoryNumber3 != 0 && msg->inventoryNumber1 == msg->inventoryNumber3) ) throw ERROR_CHAT_POST_DOWNLOAD_FAIL; } if ( msg->inventoryNumber2 != 0 ) { if ( (msg->inventoryNumber1 != 0 && msg->inventoryNumber2 == msg->inventoryNumber1) || (msg->inventoryNumber3 != 0 && msg->inventoryNumber2 == msg->inventoryNumber3) ) throw ERROR_CHAT_POST_DOWNLOAD_FAIL; } if ( msg->inventoryNumber3 != 0 ) { if ( (msg->inventoryNumber1 != 0 && msg->inventoryNumber3 == msg->inventoryNumber1) || (msg->inventoryNumber2 != 0 && msg->inventoryNumber3 == msg->inventoryNumber2) ) throw ERROR_CHAT_POST_DOWNLOAD_FAIL; } HANDLE handle = NULL; POST_UPDATE* update = (POST_UPDATE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_POST_UPDATE ); long length = sizeof(POST_UPDATE)-sizeof(update->table); TB_INVENTORY* inventory; update->characterIdx = mObject.index; update->idx = msg->idx; if ( msg->inventoryNumber1 != 0 ) { if ( IsInventoryBag( msg->inventoryNumber1 ) == false ) throw ERROR_CHAT_POST_DOWNLOAD_FAIL; inventory = SelectInventory( msg->inventoryNumber1 ); if ( IsInventory( inventory ) != true ) update->inventoryNumber1 = msg->inventoryNumber1; else throw ERROR_CHAT_POST_DOWNLOAD_FAIL; } if ( msg->inventoryNumber2 != 0 ) { if ( IsInventoryBag( msg->inventoryNumber2 ) == false ) throw ERROR_CHAT_POST_DOWNLOAD_FAIL; inventory = SelectInventory( msg->inventoryNumber2 ); if ( IsInventory( inventory ) != true ) update->inventoryNumber2 = msg->inventoryNumber2; else throw ERROR_CHAT_POST_DOWNLOAD_FAIL; } if ( msg->inventoryNumber3 != 0 ) { if ( IsInventoryBag( msg->inventoryNumber3 ) == false ) throw ERROR_CHAT_POST_DOWNLOAD_FAIL; inventory = SelectInventory( msg->inventoryNumber3 ); if ( IsInventory( inventory ) != true ) update->inventoryNumber3 = msg->inventoryNumber3; else throw ERROR_CHAT_POST_DOWNLOAD_FAIL; } update->money = (long)msg->money; mInventoryDb.postUpdate = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); if ( mInventoryDb.postUpdate == 0 ) throw ERROR_CHAT_POST_DOWNLOAD_FAIL; } // PostDelete Method. void cPlayer::PostDelete(ULONG_PTR socketContext, MSG_REQ_CHAT_POST_DELETE* msg) { // ij¸¯ÅÍ »óÅ °Ë»ç. if ( GetStateDie( ) == true ) throw ERROR_CHAT_POST_DELETE_FAIL; if ( msg->rowCount > MAX_POST_DELETE ) throw ERROR_CHAT_POST_DELETE_FAIL; if ( msg->startPage <= 0 ) msg->startPage = 1; HANDLE handle = NULL; POST_DELETE* del = (POST_DELETE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_POST_DELETE ); long length = sizeof(POST_DELETE)-sizeof(del->table); del->characterIdx = mObject.index; for ( BYTE i = 0; i < msg->rowCount; i++ ) { del->idx[i] = msg->idx[i]; } del->startPage = msg->startPage; NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); } // SendPostSelect Method. void cPlayer::SendPostSelect( ULONG_PTR socketContext, long startPage, long endPage, long noneRead, POST_RESULT* postResult, long postCount ) { // ¿ìÆí ¸®½ºÆ® Àü¼Û HANDLE handle = NULL; MSG_RES_CHAT_POST_OPEN* sendMsg = (MSG_RES_CHAT_POST_OPEN*)NETWORK2->GetMsgRoot( &handle, (PerSocketContext*)socketContext, NM_CHAT, NM_CHAT_POST_OPEN_RES ); POST_OPEN_RESULT* sendPost = sendMsg->Result; sendMsg->ErrorCode = ERROR_CHAT_POST_OPEN_SUCCESS; sendMsg->startPage = startPage; sendMsg->endPage = endPage; sendMsg->noneRead = noneRead; sendMsg->RowCount = postCount; for ( long i = 0; i < postCount; i++, postResult++, sendPost++ ) { sendPost->idx = postResult->idx; sendPost->registerDate.wYear = postResult->registerDate.year; sendPost->registerDate.wMonth = postResult->registerDate.month; sendPost->registerDate.wDay = postResult->registerDate.day; sendPost->registerDate.wHour = postResult->registerDate.hour; sendPost->registerDate.wMinute = postResult->registerDate.minute; sendPost->registerDate.wSecond = postResult->registerDate.second; sendPost->validThru = postResult->validThru; sendPost->type = postResult->type; sendPost->status = postResult->status; wcscpy( sendPost->fromName, postResult->fromName ); switch ( sendPost->type ) { case POST_TYPE_NORMAL: wcscpy( sendPost->content.title, postResult->contenTtitle ); wcscpy( sendPost->content.message, postResult->contentMessage ); break; case POST_TYPE_AGENT_CANCEL: break; case POST_TYPE_AGENT_SALE: sendPost->receipt.price = postResult->receiptPrice; sendPost->receipt.salesCharges = postResult->receiptSalesCharges; sendPost->receipt.inventory.count = postResult->receiptInventoryCount; Inventory2sInventory( &sendPost->receipt.inventory, &postResult->receiptInventory ); break; case POST_TYPE_AGENT_PURCHASE: Inventory2sInventory( &sendPost->receipt.inventory, &postResult->receiptInventory ); sendPost->receipt.inventory.count = postResult->receiptInventoryCount; break; } Inventory2sInventory( &sendPost->inventory1, &postResult->inventory1 ); Inventory2sInventory( &sendPost->inventory2, &postResult->inventory2 ); Inventory2sInventory( &sendPost->inventory3, &postResult->inventory3 ); sendPost->money = postResult->money; } NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength() ); } // CbPostCheck Method. void cPlayer::CbPostCheck(POST_CHECK* check) { if ( check->rowCount > 0 ) { NETWORK2->SendMsgRoot( mConnectionIdx, NM_CHAT, NM_CHAT_POST_RECEIVED_SYN ); } } // CbPostRead Method. void cPlayer::CbPostRead(POST_UPDATE_STATUS* status) { HANDLE handle = NULL; MSG_RES_CHAT_POST_READ* sendMsg = (MSG_RES_CHAT_POST_READ*)NETWORK2->GetMsgRoot( &handle ,mConnectionIdx ,NM_CHAT ,NM_CHAT_POST_READ_RES ); if ( sendMsg != NULL ) { sendMsg->ErrorCode = ERROR_CHAT_POST_READ_SUCCESS; sendMsg->noneRead = status->noneRead; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_CHAT_POST_READ) ); } } // CbPostWrite Method. void cPlayer::CbPostWrite(ULONG_PTR socketContext, POST_INSERT* insert) { if ( mInventoryDb.postInsert ) { mInventoryDb.postInsert = false; // DB »ç¿ëÁ¾·á. NETWORK2->SendMsgError( (PerSocketContext*)socketContext, NM_CHAT, NM_CHAT_POST_WRITE_RES, insert->retvalue ); if ( insert->retvalue == 0 ) { if ( IsInventory( &insert->inventory1 ) ) { RemoveInventory( insert->inventory1.number ); NETWORK2->PostInventoryEvent( EVENT_INVENTORY_UPDATE ,mObject.index ,&insert->inventory1 ,"Post Write - Items attached (TB_CHARACTER::IDX=%d)" ,insert->toIdx ); } if ( IsInventory( &insert->inventory2 ) ) { RemoveInventory( insert->inventory2.number ); NETWORK2->PostInventoryEvent( EVENT_INVENTORY_UPDATE ,mObject.index ,&insert->inventory2 ,"Post Write - Items attached (TB_CHARACTER::IDX=%d)" ,insert->toIdx ); } if ( IsInventory( &insert->inventory3 ) ) { RemoveInventory( insert->inventory3.number ); NETWORK2->PostInventoryEvent( EVENT_INVENTORY_UPDATE ,mObject.index ,&insert->inventory3 ,"Post Write - Items attached (TB_CHARACTER::IDX=%d)" , insert->toIdx ); } if ( insert->money > 0 ) { sObject object = { eOBJECTTYPE_PLAYER, insert->toIdx }; AddMoney( object, (-insert->money) ); } if ( insert->serviceCharage > 0 ) { AddMoney( mObject, (-insert->serviceCharage) ); } } /*-- ¿ìÆíµ¿±âÈ­ --*/ cPlayer* player = GRIDMANAGER->GetPlayer( insert->toIdx ); if ( player != NULL ) { NETWORK2->SendMsgRoot( player->GetConnectionIdx( ), NM_CHAT, NM_CHAT_POST_RECEIVED_SYN ); } else { NETWORK2->PostPostReceived( insert->toIdx ); } } } // CbPostDownload Method. void cPlayer::CbPostDownload(ULONG_PTR socketContext, POST_UPDATE* update) { if ( mInventoryDb.postUpdate ) { mInventoryDb.postUpdate = false; // DB »ç¿ëÁ¾·á. HANDLE handle = NULL; MSG_RES_CHAT_POST_DOWNLOAD* sendMsg = (MSG_RES_CHAT_POST_DOWNLOAD*)NETWORK2->GetMsgRoot( &handle ,(PerSocketContext*)socketContext ,NM_CHAT ,NM_CHAT_POST_DOWNLOAD_RES ); TB_INVENTORY* table = update->table; sInventory* sinventory = sendMsg->inventory; sendMsg->ErrorCode = update->retvalue; if ( sendMsg->ErrorCode == ERROR_CHAT_POST_DOWNLOAD_SUCCESS ) { for ( long i = 0; i < update->rowCount; i++, table++, sinventory++ ) { if ( ITEMMANAGER->GetItemDefine( table->itemDefineIdx ) != NULL ) { XCopyInventory( table ); Inventory2sInventory( sinventory, table ); NETWORK2->PostInventoryEvent( EVENT_INVENTORY_UPDATE ,mObject.index ,table ,"Post Download (TB_POST::IDX=%d)" ,update->idx ); sendMsg->rowCount++; } else { NETWORK2->PostServerEvent( "Error - cPlayer::CbPostDownload - TB_POST::IDX(%d).", update->idx ); } } sendMsg->money = (update->money != 0); if ( update->money != 0 ) { unsigned long befor = GetMoney( ); AddMoney( mObject, update->money, false ); NETWORK2->PostMoneyEvent( update->characterIdx ,befor ,GetMoney( ) ,"Post Download (TB_POST::IDX=%d, MONEY=%d)" ,update->idx ,update->money ); } } NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength( ) ); // ¿ìÆí ¼ö·É·Î±× long inventoryIdx1=0; long inventoryIdx2=0; long inventoryIdx3=0; switch ( update->rowCount ) { case 3: inventoryIdx3 = update->table[ 2 ].idx; case 2: inventoryIdx2 = update->table[ 1 ].idx; case 1: inventoryIdx1 = update->table[ 0 ].idx; break; } NETWORK2->PostPostEvent( update->idx, update->characterIdx, inventoryIdx1, inventoryIdx2, inventoryIdx3, update->money ); } } // IsTarotReaderClose Method. bool cPlayer::IsTarotReaderClose( ) { unsigned long* tarotGuest = mTarotGuests; int tarotGuestOffset = mTarotGuestOffset; for ( int i = 0; i < MAX_TAROT_GUEST && tarotGuestOffset > 0; i++, tarotGuest++ ) { if ( (*tarotGuest) > 0 ) { cPlayer* player = OBJECTMANAGER->GetPlayer( (*tarotGuest) ); if ( player != NULL ) { if ( player->GetStateStop( ) == eSTOP_USETAROT ) return false; } tarotGuestOffset--; } } return true; } // TarotReaderReady Method. void cPlayer::TarotReaderReady(ULONG_PTR /*socketContext*/, MSG_REQ_TAROT_READER_READY* /*msg*/) { /// 2Â÷»óÅ üũ if ( IsRequestRejection() == true ) throw ERROR_TAROT_READER_READY_FAIL; // ij¸¯ÅÍ »óÅÂ2¿À·ù. if ( IsChangeState( eOBJECT_STATE_STOP ) == false ) throw ERROR_TAROT_READER_READY_FAIL; // ij¸¯ÅÍ »óÅ ¿À·ù - »óź¯°æ ºÒ°¡. if ( GetStateStop( ) != eSTOP_NONE ) throw ERROR_TAROT_READER_READY_FAIL; // ij¸¯ÅÍ »óÅ ¿À·ù. /*-- ij¸¯ÅÍ »óÅ º¯°æ. */ if ( ChangeState( eOBJECT_STATE_STOP ) == false ) throw ERROR_TAROT_READER_READY_FAIL; // ij¸¯ÅÍ »óÅ ¿À·ù - º¯°æºÒ°¡. SetStateStop( eSTOP_READYTAROT ); // ij¸¯ÅÍ Á¤Áö»óÅ Áß Å¸·ÎÁغñ. /*-- Ÿ·Î °³¼³Á¤º¸ º¸³»±â [RES/SYN] ¸Þ½ÃÁö ¹ß¼Û. */ SendMsgResTarot( NM_TAROT, NM_TAROT_READER_READY_RES, ERROR_TAROT_READER_READY_SUCCESS ); MSG_SYN_TAROT_READER_READY msgSyn; memset( &msgSyn, 0, sizeof(MSG_SYN_TAROT_READER_READY) ); msgSyn.Category = NM_TAROT; msgSyn.Protocol = NM_TAROT_READER_READY_SYN; msgSyn.mCharacterIdx = mObject.index; NETWORK2->QuickSendExcept( this, (char*)&msgSyn, sizeof(msgSyn) ); } // TarotReaderOpen Method. void cPlayer::TarotReaderOpen(ULONG_PTR /*socketContext*/, MSG_REQ_TAROT_READER_OPEN* msg) { if ( GetState( ) != eOBJECT_STATE_STOP ) throw ERROR_TAROT_READER_OPEN_FAIL; // ij¸¯ÅÍ »óÅ ¿À·ù. if ( GetStateStop( ) != eSTOP_READYTAROT ) throw ERROR_TAROT_READER_OPEN_FAIL; // ij¸¯ÅÍ »óÅ ¿À·ù. /*-- Ÿ·ÎÄ«µå °Ë»ç - 22Àå(1¹ú)À» ¸ðµÎ °¡Áö°í ÀÖ´ÂÁö È®Àΰú °íÀ¯¹øÈ£ °Ë»ç. */ TB_INVENTORY* tarotCard = SelectInventory( INVENTORY_TAROT_NORMAL_BEGIN ); TB_ITEM_TAROT* itemTarot = NULL; long tarotNumber = 0; for ( int i = INVENTORY_TAROT_NORMAL_BEGIN; i <= INVENTORY_TAROT_NORMAL_END; i++, tarotCard++ ) { itemTarot = ITEMMANAGER->GetItemTarot( tarotCard->itemDefineIdx ); if ( itemTarot != NULL ) { if ( itemTarot->number != tarotNumber ) // Ÿ·ÎÄ«µå °íÀ¯¹øÈ£ °Ë»ç. throw ERROR_TAROT_READER_OPEN_CARD; // Ÿ·ÎÄ«µå °íÀ¯¹øÈ£ ¿À·ù. } else throw ERROR_TAROT_READER_OPEN_CARD; // Ÿ·ÎÄ«µå ¿À·ù. tarotNumber++; } /*-- ½ºÇÁ·¹µå °Ë»ç. */ TB_INVENTORY* spread = SelectInventory( INVENTORY_SPREAD_NORMAL_BEGIN ); long spreadCount = 0; for ( long i = INVENTORY_SPREAD_NORMAL_BEGIN; i <= INVENTORY_SPREAD_NORMAL_END; i++, spread++ ) { if ( ITEMMANAGER->IsItemDefineType( spread->itemDefineIdx, ITEM_SPREAD ) ) spreadCount++; } if ( !(spreadCount > 0) ) throw ERROR_TAROT_READER_OPEN_SPREAD; // ½ºÇÁ·¹µå ¿À·ù. // Àç·á ¾ÆÀÌÅÛ ¼ö·® È®ÀÎ. mTarotItemCount = GetItemCount( TAROT_MATERIAL_ITEM ); if ( !(mTarotItemCount > 0) ) throw ERROR_TAROT_READER_OPEN_ITEM; // Àç·á¾ÆÀÌÅÛ ¼ö·® ¿À·ù. if ( msg->Price > MAX_TRADE_MONEY ) throw ERROR_TAROT_READER_OPEN_TRADE_MONEY; if ( IsAddMoney( (long)msg->Price ) == false ) throw ERROR_TAROT_READER_OPEN_HAVE_MONEY; // Ÿ·Î»óÁ¡ °³¼³. SetStateStop( eSTOP_OPENTAROT ); // ij¸¯ÅÍ Á¤Áö»óÅ Áß Å¸·Î°³¼³. // Ÿ·Î»óÁ¡ °³¼³ Á¤º¸ ¹é¾÷. wcscpy( mTarotTitle, msg->strTitle ); // °³¼³¸í mTarotPrice = msg->Price; // °¡°Ý mTarotUserCount = 0; // »ç¿ë ij¸¯ÅÍ ¼ö - ÃʱâÈ­. mTarotCloseReserved = false; // ´Ý±â¿¹¾à - ÃʱâÈ­. /*-- Ÿ·Î °³¼³Á¤º¸ º¸³»±â [RES/SYN] ¸Þ½ÃÁö ¹ß¼Û. */ HANDLE handle = NULL; MSG_RES_TAROT_READER_OPEN* msgRes = (MSG_RES_TAROT_READER_OPEN*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_TAROT, NM_TAROT_READER_OPEN_RES ); if ( msgRes != NULL ) { msgRes->ErrorCode = ERROR_TAROT_READER_OPEN_SUCCESS; wcscpy( msgRes->strTitle, mTarotTitle ); msgRes->Price = mTarotPrice; msgRes->UserCount = mTarotUserCount; msgRes->Point = (unsigned short)mHeroInfo.TarotPoint; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_TAROT_READER_OPEN) ); } MSG_SYN_TAROT_READER_OPEN msgSyn; memset( &msgSyn, 0, sizeof(MSG_SYN_TAROT_READER_OPEN) ); msgSyn.Category = NM_TAROT; msgSyn.Protocol = NM_TAROT_READER_OPEN_SYN; msgSyn.mCharacterIdx = mObject.index; wcscpy( msgSyn.mTitle, mTarotTitle ); NETWORK2->QuickSendExcept( this, (char*)&msgSyn, sizeof(msgSyn) ); } // TarotReaderClose Method void cPlayer::TarotReaderClose(ULONG_PTR /*socketContext*/, MSG_REQ_TAROT_READER_CLOSE* /*msg*/) { eSTOPFLAG stopFlag = (eSTOPFLAG)GetStateStop( ); if ( !(stopFlag == eSTOP_READYTAROT || stopFlag == eSTOP_OPENTAROT) ) throw ERROR_TAROT_READER_CLOSE_FAIL; // ij¸¯ÅÍ »óÅ ¿À·ù. if ( IsChangeState( eOBJECT_STATE_IDLE ) == false ) throw ERROR_TAROT_READER_CLOSE_FAIL; // ij¸¯ÅÍ »óÅ ¿À·ù - »óź¯°æ ºÒ°¡. if ( IsTarotCloseReserved( ) == true ) { mTarotCloseReserved = false; throw ERROR_TAROT_READER_CLOSE_RESERVED_OFF; // Ÿ·Î»óÁ¡ ´Ý±â ¿¹¾àÇØÁö. } if ( IsTarotReaderClose( ) == false ) { mTarotCloseReserved = true; throw ERROR_TAROT_READER_CLOSE_RESERVED_ON; // Ÿ·Î»óÁ¡ ´Ý±â ¿¹¾à. } TarotReaderClose( ERROR_TAROT_READER_CLOSE_SUCCESS ); } void cPlayer::TarotReaderClose(int error) { // »óÅ º¯°æ ChangeState( eOBJECT_STATE_IDLE ); SetStateStop( eSTOP_NONE ); // ij¸¯ÅÍ Á¤Áö »óÅ - ¼¼ºÎ¼³Á¤ ¾øÀ½. // ¸ðµç °Ô½ºÆ® Á¾·á. ReleaseTarotAllGuests( ); /*-- Ÿ·ÎÁ¾·á Á¤º¸ º¸³»±â [RES/SYN] ¸Þ½ÃÁö ¹ß¼Û. */ SendMsgResTarot( NM_TAROT, NM_TAROT_READER_CLOSE_RES, error ); MSG_SYN_TAROT_READER_CLOSE msgSyn; memset( &msgSyn, 0, sizeof(MSG_SYN_TAROT_READER_CLOSE) ); msgSyn.Category = NM_TAROT; msgSyn.Protocol = NM_TAROT_READER_CLOSE_SYN; msgSyn.mCharacterIdx = mObject.index; NETWORK2->QuickSendExcept( this, (char*)&msgSyn, sizeof(msgSyn) ); } // GetTarotGuest Method. bool cPlayer::GetTarotGuest(unsigned long characterIdx) { if ( mTarotGuestOffset < MAX_TAROT_GUEST ) { unsigned long* tarotGuest = mTarotGuests; for ( int i = 0; i < MAX_STALL_GUEST; i++, tarotGuest++ ) { if ( (*tarotGuest) == 0 ) { (*tarotGuest) = characterIdx; mTarotGuestOffset++; return true; } } } return false; } // ReleaseTarotGuest Method. bool cPlayer::ReleaseTarotGuest(unsigned long characterIdx) { if ( mTarotGuestOffset > 0 ) { unsigned long* tarotGuest = mTarotGuests; for ( int i = 0; i < MAX_TAROT_GUEST; i++, tarotGuest++ ) { if ( (*tarotGuest) == characterIdx ) { (*tarotGuest) = 0; mTarotGuestOffset--; return true; } } } return false; } // ReleaseTarotAllGuests Method. void cPlayer::ReleaseTarotAllGuests( ) { unsigned long* tarotGuest = mTarotGuests; for ( int i = 0; i < MAX_TAROT_GUEST && mTarotGuestOffset > 0; i++, tarotGuest++ ) { if ( (*tarotGuest) > 0 ) { cPlayer* player = OBJECTMANAGER->GetPlayer( (*tarotGuest) ); if ( player != NULL ) { player->ChangeState( eOBJECT_STATE_IDLE ); player->SetStateStop( eSTOP_NONE ); player->SendMsgResTarot( NM_TAROT, NM_TAROT_SEEKER_CLOSE_RES, ERROR_TAROT_SEEKER_CLOSE_READER ); } (*tarotGuest) = 0; --mTarotGuestOffset; } } } // GetTarotCards Method - Ÿ·ÎÄ«µå Àκ¥Å丮 º¹»ç. bool cPlayer::GetTarotCards( TB_INVENTORY* inventory[], short begin ) { TB_INVENTORY* tarotCard = SelectInventory( begin ); TB_ITEM_TAROT* itemTarot = NULL; for ( int i = 0; i < MAX_TAROT_CARDS; i++, tarotCard++ ) { itemTarot = ITEMMANAGER->GetItemTarot( tarotCard->itemDefineIdx ); if ( itemTarot != NULL ) { if ( itemTarot->number == i ) // Ÿ·ÎÄ«µå °íÀ¯¹øÈ£ °Ë»ç. { inventory[ i ] = tarotCard; } else return false; } else return false; } return true; } // GetSpreads Method - ½ºÇÁ·¹µå Àκ¥Å丮 º¹»ç. void cPlayer::GetSpreads(TB_INVENTORY* inventory[], short begin, int& offset) { TB_INVENTORY* spread = SelectInventory( begin ); for ( long i = 0; i <= MAX_SPREAD; i++, spread++ ) { if ( ITEMMANAGER->IsItemDefineType( spread->itemDefineIdx, ITEM_SPREAD ) ) { inventory[ offset ] = spread; offset++; } } } // UseTarotCard Method. void cPlayer::UseTarotCard(sObject object, long price, long itemDefineIndex) { AddMoney( object, price ); ItemUse( itemDefineIndex ); mTarotItemCount = GetItemCount( TAROT_MATERIAL_ITEM ); } // TarotSeekerOpen Method - ¼ø¼­¿¡ ÁÖÀÇ!. void cPlayer::TarotSeekerOpen(ULONG_PTR /*socketContext*/, MSG_REQ_TAROT_SEEKER_OPEN* msg) { // 2Â÷»óÅ üũ if ( IsRequestRejection() == true ) throw ERROR_TAROT_SEEKER_OPEN_FAIL; // ij¸¯ÅÍ »óÅÂ2¿À·ù. // »óŰ˻ç. if ( IsChangeState( eOBJECT_STATE_STOP ) == false || GetStateStop( ) != eSTOP_NONE ) throw ERROR_TAROT_SEEKER_OPEN_FAIL; // ij¸¯ÅÍ »óÅ¿À·ù. // Ÿ·Î»óÁ¡ - ¸®´õ°Ë»ö. cPlayer* reader = OBJECTMANAGER->GetPlayer( msg->CharacterIdx ); if ( reader == NULL ) throw ERROR_TAROT_SEEKER_OPEN_READER; // Ÿ·Î»óÁ¡ ¿À·ù - ij¸¯ÅÍ °Ë»ö ¿À·ù. if ( reader->GetStateStop( ) != eSTOP_OPENTAROT && reader->IsTarotCloseReserved( ) == false ) throw ERROR_TAROT_SEEKER_OPEN_READER; // Ÿ·Î»óÁ¡ ¿À·ù - Ÿ·Î»óÁ¡ °³¼³ ¿À·ù. /// º¸À¯±Ý¾× ºñ±³Çؼ­ ´õÀÌ»ó ¾È¹Þ±â __int64 totalPrice = (__int64)reader->GetMoney() + (__int64)reader->GetTarotPrice(); if ( totalPrice > MAX_HAVE_MONEY ) throw ERROR_TAROT_SEEKER_OPEN_HAVE_MONEY; /// Á¡Áý ´Ý±â ¿¹¾à »óÅ °Ë»ç. if( reader->IsTarotCloseReserved( ) == true ) throw ERROR_TAROT_SEEKER_OPEN_RESERVED; // Ÿ·Î»óÁ¡ ´Ý±â ¿¹¾àÇØÁö. // Ÿ·Î»óÁ¡ - °Ô½ºÆ® µî·Ï. if ( reader->GetTarotGuest( mObject.index ) == false ) throw ERROR_TAROT_SEEKER_OPEN_OVER; // Ÿ·Î»óÁ¡ ¿À·ù - ÃÖ´ë °Ô½ºÆ® ¿À¹ö. if ( reader->GetTarotCards( mTarotCards, (short)INVENTORY_TAROT_NORMAL_BEGIN ) == false ) throw ERROR_TAROT_SEEKER_OPEN_FAIL; // Ÿ·Î»óÁ¡ ¿À·ù - Ÿ·ÎÄ«µå º¹»ç ½ÇÆÐ. reader->GetSpreads( mSpread, (short)INVENTORY_SPREAD_NORMAL_BEGIN, (mSpreadOffset=0) ); if ( !(mSpreadOffset > 0) ) throw ERROR_TAROT_SEEKER_OPEN_FAIL; // Ÿ·Î»óÁ¡ ¿À·ù - ½ºÇÁ·¹µå º¹»ç ½ÇÆÐ. // Ÿ·Î»óÁ¡, ¸®´õÀÇ Ä³¸¯ÅÍ °íÀ¯¹øÈ£ º¹»ç. mTarotReaderIdx = reader->GetObjectID( ); // Ÿ·Î»óÁ¡ ¹é¾÷ - ¸®´õÀÇ Ä³¸¯ÅÍ °íÀ¯¹øÈ£. // »óꝰæ. ChangeState( eOBJECT_STATE_STOP ); // ij¸¯ÅÍ »óꝰæ. SetStateStop( eSTOP_ENTERTAROT ); // ij¸¯ÅÍ »óꝰæ - ¼¼ºÎÇ׺¹. // Ÿ·Î °³¼³Á¤º¸ ¹ß¼Û. SendTarotStoreOpen( reader->GetName( ), reader->GetTarotTitle( ), reader->GetTarotPrice( ) ); } // TarotSeekerClose Method - ¼ø¼­¿¡ ÁÖÀÇ!. void cPlayer::TarotSeekerClose(ULONG_PTR /*socketContext*/, MSG_REQ_TAROT_SEEKER_CLOSE* /*msg*/) { // »óŰ˻ç. eSTOPFLAG stopFlag = (eSTOPFLAG)GetStateStop( ); if ( !(stopFlag == eSTOP_ENTERTAROT || stopFlag == eSTOP_USETAROT) ) throw ERROR_TAROT_SEEKER_CLOSE_FAIL; // ij¸¯ÅÍ »óÅ¿À·ù. if ( IsChangeState( eOBJECT_STATE_IDLE ) == false ) throw ERROR_TAROT_SEEKER_CLOSE_FAIL; // ij¸¯ÅÍ »óÅ¿À·ù - »óź¯°æ ºÒ°¡. // Ÿ·Î»óÁ¡ - ¸®´õó¸®. cPlayer* reader = OBJECTMANAGER->GetPlayer( mTarotReaderIdx ); if ( reader != NULL ) { if ( reader->GetStateStop( ) == eSTOP_OPENTAROT ) { reader->ReleaseTarotGuest( mObject.index ); // Ÿ·Î °Ô½ºÆ® Á¾·á. if ( stopFlag == eSTOP_USETAROT ) reader->SendTarotReaderLeave( mPlayerInfo.strName ); } } // Ÿ·Î»óÁ¡ ¹é¾÷ - Ŭ¸®¾î. mTarotReaderIdx = 0; // »óꝰæ. ChangeState( eOBJECT_STATE_IDLE ); SetStateStop( eSTOP_NONE ); // Ÿ·Î»óÁ¡ Âü¿©Á¾·á. SendMsgResTarot( NM_TAROT, NM_TAROT_SEEKER_CLOSE_RES, ERROR_TAROT_SEEKER_CLOSE_SUCCESS ); } // SendTarotStoreJoin Method. void cPlayer::TarotSeekerJoin(ULONG_PTR /*socketContext*/, MSG_REQ_TAROT_SEEKER_JOIN* /*msg*/) { // »óŰ˻ç. if ( GetState( ) != eOBJECT_STATE_STOP || GetStateStop( ) != eSTOP_ENTERTAROT ) throw ERROR_TAROT_SEEKER_JOIN_FAIL; // ij¸¯ÅÍ »óÅ¿À·ù. // ¸®´õ°Ë»ö cPlayer* reader = OBJECTMANAGER->GetPlayer( mTarotReaderIdx ); if ( reader == NULL ) throw ERROR_TAROT_SEEKER_JOIN_READER; // ¸®´õ°Ë»ö ¿À·ù - ÀÚµ¿À¸·Î Ÿ·Î»óÁ¡ ´Ý±â Ãß°¡ ÇØ¾ßµÊ. if ( reader->GetStateStop( ) != eSTOP_OPENTAROT ) throw ERROR_TAROT_SEEKER_JOIN_READER; // ¸®´õ°Ë»ö ¿À·ù - ¸®´õ¾Æ´Ô. if ( !(reader->GetItemCount( TAROT_MATERIAL_ITEM ) > 0) ) throw ERROR_TAROT_SEEKER_JOIN_ITEM; // ¸®´õ°Ë»ö ¿À·ù - Àç·áºÎÁ·. if ( mMoney < reader->GetTarotPrice( ) ) throw ERROR_TAROT_SEEKER_JOIN_MONEY; // ¼ÒÁö±Ý¾× ºÎÁ·. __int64 totalPrice = (__int64)reader->GetMoney() + (__int64)reader->GetTarotPrice(); if ( totalPrice > MAX_HAVE_MONEY ) throw ERROR_TAROT_SEEKER_JOIN_HAVE_MONEY; // Ÿ·Î»óÁ¡ °¡°Ý ¾ò¾î¿À±â. long tarotPrice = (long)reader->GetTarotPrice( ); // Ÿ·Î»óÁ¡ ÀÌ¿ë±Ý¾× -. AddMoney( reader->GetObject( ), -tarotPrice ); // Ÿ·Î»óÁ¡ ÀÌ¿ë±Ý¾× + & ¾ÆÀÌÅÛ »ç¿ë. reader->UseTarotCard( mObject, +tarotPrice, TAROT_MATERIAL_ITEM ); // »óꝰæ. SetStateStop( eSTOP_USETAROT ); // Âü¿© ¾¾Ä¿³×ÀÓ Àü¼Û. reader->SendTarotReaderJoin( mPlayerInfo.strName ); // Âü¿© Á¤º¸ Àü¼Û. SendTarotStoreJoin( reader->GetTarotTitle( ), reader->GetTarotPrice( ) ); } // TarotSeekerResult Method void cPlayer::TarotSeekerResult(ULONG_PTR socketContext, MSG_REQ_TAROT_SEEKER_RESULT* msg) { // »óŰ˻ç. if ( GetState( ) != eOBJECT_STATE_STOP || GetStateStop( ) != eSTOP_USETAROT ) throw ERROR_TAROT_SEEKER_RESULT_FAIL; // ij¸¯ÅÍ »óÅ¿À·ù. // ¸®´õ°Ë»ö cPlayer* reader = OBJECTMANAGER->GetPlayer( mTarotReaderIdx ); if ( reader == NULL ) throw ERROR_TAROT_SEEKER_RESULT_READER; // ¸®´õ°Ë»ö ¿À·ù. if ( reader->GetStateStop( ) != eSTOP_OPENTAROT ) throw ERROR_TAROT_SEEKER_RESULT_READER; // ¸®´õ°Ë»ö ¿À·ù - ¸®´õ¾Æ´Ô. // ½ºÇÁ·¹µå À妽º °Ë»ö. long spreadIndex = 0; bool exists = false; // Spread À妽º È®ÀÎ. for ( long i = 0; i < mSpreadOffset; i++ ) { if ( mSpread[ i ]->itemDefineIndex == (long)msg->SpreadIndex ) { TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( mSpread[ i ]->itemDefineIdx ); if ( itemDefine != NULL ) { spreadIndex = itemDefine->spreadIndex; exists = true; } } } if ( exists == false ) throw ERROR_TAROT_SEEKER_RESULT_FAIL; // ½ºÇÁ·¹µå À妽º ¿À·ù. // Database ó¸® ¿äû. HANDLE handle = NULL; ITEM_SPREAD_VALUE* itemSpreadValue = (ITEM_SPREAD_VALUE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_SPREAD_VALUE ); itemSpreadValue->itemDefineIndex = msg->SpreadIndex; itemSpreadValue->spreadIndex = spreadIndex; for ( long i = 0; i < MIN_TAROT_CARDS; i++ ) { TB_ITEM_TAROT* tbItemTarot = ITEMMANAGER->GetItemTarot( mTarotCards[ i ]->itemDefineIdx ); int dir = (rand( ) % 2); itemSpreadValue->values[ i ].itemDefineIndex = mTarotCards[ i ]->itemDefineIndex; itemSpreadValue->values[ i ].dir = (BYTE)(dir + 1); itemSpreadValue->values[ i ].tarot = (dir == 0) ? tbItemTarot->strValue : tbItemTarot->invValue; } if ( NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, sizeof(ITEM_SPREAD_VALUE) ) == false ) throw ERROR_TAROT_SEEKER_RESULT_FAIL; // SQL ¿À·ù. mTarotResultIndex = msg->SpreadIndex; } // TarotSeekerAccept Method void cPlayer::TarotSeekerAccept(ULONG_PTR socketContext, MSG_REQ_TAROT_SEEKER_ACCEPT* /*msg*/) { // »óŰ˻ç. if ( GetState( ) != eOBJECT_STATE_STOP || GetStateStop( ) != eSTOP_USETAROT ) throw ERROR_TAROT_SEEKER_ACCEPT_FAIL; // ij¸¯ÅÍ »óÅ¿À·ù. else if ( IsChangeState( eOBJECT_STATE_IDLE ) == false ) throw ERROR_TAROT_SEEKER_ACCEPT_FAIL; // ij¸¯ÅÍ »óÅ¿À·ù - »óź¯°æ ºÒ°¡. // »óꝰæ. ChangeState( eOBJECT_STATE_IDLE ); SetStateStop( eSTOP_NONE ); // ¸®´õ°Ë»ö. cPlayer* reader = OBJECTMANAGER->GetPlayer( mTarotReaderIdx ); if ( reader == NULL ) throw ERROR_TAROT_SEEKER_ACCEPT_READER; // ¸®´õ°Ë»ö ¿À·ù. if ( reader->GetStateStop( ) != eSTOP_OPENTAROT ) throw ERROR_TAROT_SEEKER_ACCEPT_READER; // ¸®´õ°Ë»ö ¿À·ù - ¸®´õ¾Æ´Ô. // Ÿ·Î»óÁ¡ - °Ô½ºÆ® Á¾·á. reader->ReleaseTarotGuest( mObject.index ); reader->SendTarotReaderLeave( mPlayerInfo.strName ); SendMsgResTarot( NM_TAROT, NM_TAROT_SEEKER_CLOSE_RES, ERROR_TAROT_SEEKER_CLOSE_SUCCESS ); // Database 󸮿äû HANDLE handle = NULL; ITEM_TAROT_RESULT* itemTarotResult = (ITEM_TAROT_RESULT*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_TAROT_RESULT ); itemTarotResult->itemDefineIndex = mTarotResultIndex; itemTarotResult->value = mTarotResultValue; if ( NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, sizeof(ITEM_TAROT_RESULT) ) == false ) throw ERROR_TAROT_SEEKER_ACCEPT_FAIL; // SQL ¿À·ù. } void cPlayer::TarotTutorialSeekerJoin() { if( GetMapDataNumber() != MAP_TUTORIAL ) throw ERROR_TAROT_TUTORIAL_SEEKER_JOIN_FAIL; // »óŰ˻ç. if ( !(GetState( ) == eOBJECT_STATE_STOP && GetStateStop( ) == eSTOP_NPCSPEECH) ) throw ERROR_TAROT_TUTORIAL_SEEKER_JOIN_FAIL; // ij¸¯ÅÍ »óÅ¿À·ù. cNpc* npc = OBJECTMANAGER->GetNpc( GetNpcIdx() ); if( npc == NULL ) throw ERROR_TAROT_TUTORIAL_SEEKER_JOIN_FAIL; // ij¸¯ÅÍ »óÅ¿À·ù. sNpcFuncData* funcData = NPCSCRIPT->GetNpcFuncData( npc->GetRaceGender() ); if( funcData == NULL ) throw ERROR_TAROT_TUTORIAL_SEEKER_JOIN_FAIL; // ij¸¯ÅÍ »óÅ¿À·ù. for ( int i = 0; i < MAX_TAROT_CARDS; i++ ) { mTempNpcTarotCards[i] = funcData->mTarotIndex[i]; } // ¼±Åà īµå Àü¼Û HANDLE handle = NULL; MSG_RES_TAROT_TUTORIAL_SEEKER_JOIN* sendMsg = (MSG_RES_TAROT_TUTORIAL_SEEKER_JOIN*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_TAROT, NM_TAROT_TUTORIAL_SEEKER_JOIN_RES ); if ( sendMsg != NULL ) { sendMsg->ErrorCode = ERROR_TAROT_TUTORIAL_SEEKER_JOIN_SUCCESS; /*-- Ä«µå¼¯ÀÌ(shuffle). */ unsigned long temp; int s; for ( int i = 0; i < MAX_TAROT_CARDS; i++ ) { s = (int)(rand( ) % MAX_TAROT_CARDS); // 0 ~ 21ÀÇ ·¥´ý ¼ö¸¦ »ý¼ºÇÑ´Ù. temp = mTempNpcTarotCards[ i ]; // ±³È¯À» À§ÇØ Àӽà ÀúÀå. mTempNpcTarotCards[ i ] = mTempNpcTarotCards[ s ]; // ±³È¯ ½ÃÀÛ. mTempNpcTarotCards[ s ] = temp; // ±³È¯ ¿Ï·á. } // Ä«µå¼±ÅÃ. for ( int i = 0; i < MIN_TAROT_CARDS; i++ ) { sendMsg->TarotCardIndex[ i ] = mTempNpcTarotCards[ i ]; } NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_TAROT_TUTORIAL_SEEKER_JOIN) ); } } void cPlayer::TarotTutorialSeekerResult( ULONG_PTR socketContext, MSG_REQ_TAROT_TUTORIAL_SEEKER_RESULT* msg ) { if( GetMapDataNumber() != MAP_TUTORIAL ) throw ERROR_TAROT_TUTORIAL_SEEKER_RESULT_FAIL; if ( !(GetState( ) == eOBJECT_STATE_STOP && GetStateStop( ) == eSTOP_NPCSPEECH) ) throw ERROR_TAROT_TUTORIAL_SEEKER_RESULT_FAIL; // ij¸¯ÅÍ »óÅ¿À·ù. cNpc* npc = OBJECTMANAGER->GetNpc( GetNpcIdx() ); if( npc == NULL ) throw ERROR_TAROT_TUTORIAL_SEEKER_RESULT_FAIL; // ij¸¯ÅÍ »óÅ¿À·ù. sNpcFuncData* funcData = NPCSCRIPT->GetNpcFuncData( npc->GetRaceGender() ); if( funcData == NULL ) throw ERROR_TAROT_TUTORIAL_SEEKER_RESULT_FAIL; // ij¸¯ÅÍ »óÅ¿À·ù. // ½ºÇÁ·¹µå À妽º °Ë»ö. long spreadIndex = 0; bool exists = false; // Spread À妽º È®ÀÎ. for ( unsigned int i = 0; i < funcData->mSpreadCount; i++ ) { // µ¿ÀÏÇÑ ¾ÆÀÌÅÛ À妽ºÀ̸é if ( funcData->mSpreadIndex[i] == msg->SpreadIndex ) { TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefineByIndex( funcData->mSpreadIndex[i] ); if ( itemDefine != NULL ) { spreadIndex = itemDefine->spreadIndex; exists = true; } } } if ( exists == false ) throw ERROR_TAROT_SEEKER_RESULT_FAIL; // ½ºÇÁ·¹µå À妽º ¿À·ù. // Database ó¸® ¿äû. HANDLE handle = NULL; ITEM_SPREAD_VALUE* itemSpreadValue = (ITEM_SPREAD_VALUE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_TUTORIALSPREAD_VALUE ); // µÎ°³ÀÇ À妽º´Â ´Ù¸¥ Á¾·ùÀÌ´Ù!! (Á¤ÀÇÀ妽º¿Í dbÀ妽º) itemSpreadValue->itemDefineIndex = msg->SpreadIndex; itemSpreadValue->spreadIndex = spreadIndex; for ( long i = 0; i < MIN_TAROT_CARDS; i++ ) { TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefineByIndex( mTempNpcTarotCards[ i ] ); TB_ITEM_TAROT* tbItemTarot = ITEMMANAGER->GetItemTarot( itemDefine->idx ); if( tbItemTarot ) { int dir = (rand( ) % 2); itemSpreadValue->values[ i ].itemDefineIndex = mTempNpcTarotCards[ i ]; itemSpreadValue->values[ i ].dir = (BYTE)(dir + 1); itemSpreadValue->values[ i ].tarot = (dir == 0) ? tbItemTarot->strValue : tbItemTarot->invValue; } else { NETWORK2->PostServerEvent( "Error(%d,%d): TarotTutorialSeekerResult", mTempNpcTarotCards[ i ], itemDefine->idx ); } } if ( NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, sizeof(ITEM_SPREAD_VALUE) ) == false ) throw ERROR_TAROT_TUTORIAL_SEEKER_RESULT_FAIL; // SQL ¿À·ù. mTarotResultIndex = msg->SpreadIndex; } void cPlayer::TarotTutorialSeekerAccept( ULONG_PTR socketContext ) { if( GetMapDataNumber() != MAP_TUTORIAL ) throw ERROR_TAROT_TUTORIAL_SEEKER_ACCEPT_FAIL; if ( !(GetState( ) == eOBJECT_STATE_STOP && GetStateStop( ) == eSTOP_NPCSPEECH) ) throw ERROR_TAROT_TUTORIAL_SEEKER_ACCEPT_FAIL; // ij¸¯ÅÍ »óÅ¿À·ù. if ( IsChangeState( eOBJECT_STATE_IDLE ) == false ) throw ERROR_TAROT_TUTORIAL_SEEKER_ACCEPT_FAIL; // ij¸¯ÅÍ »óÅ¿À·ù - »óź¯°æ ºÒ°¡. // »óꝰæ. ChangeState( eOBJECT_STATE_IDLE ); SetStateStop( eSTOP_NONE ); SendMsgResTarot( NM_TAROT, NM_TAROT_TUTORIAL_SEEKER_CLOSE_RES, ERROR_TAROT_TUTORIAL_SEEKER_CLOSE_SUCCESS ); // Database 󸮿äû HANDLE handle = NULL; ITEM_TAROT_RESULT* itemTarotResult = (ITEM_TAROT_RESULT*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_TUTORIALTAROT_RESULT ); itemTarotResult->itemDefineIndex = mTarotResultIndex; itemTarotResult->value = mTarotResultValue; if ( NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, sizeof(ITEM_TAROT_RESULT) ) == false ) throw ERROR_TAROT_TUTORIAL_SEEKER_ACCEPT_FAIL; // SQL ¿À·ù. } int cPlayer::TarotSelfJoin( ULONG_PTR /*socketContext*/, MSG_REQ_TAROT_SELF_JOIN* /*msg*/ ) { if ( IsRequestRejection() == true ) throw ERROR_TAROT_SELF_JOIN_FAIL; if ( GetState( ) != eOBJECT_STATE_STOP || GetStateStop( ) != eSTOP_SELFTAROT ) throw ERROR_TAROT_SELF_JOIN_FAIL; // Á¡±¥°³¼± Àû¿ë½Ã ¼öÁ¤ÇØ¾ß ÇÔ.... unsigned char tarotClass = eTAROT_CLASS_NORMAL; //if ( msg->tarotClass > eTAROT_CLASS_MAX ) if ( tarotClass > eTAROT_CLASS_MAX ) throw ERROR_TAROT_SELF_JOIN_FAIL; // µî±Þ¿¡ µû¸¥ Àç·á¾ÆÀÌÅÛ ¹× Àκ¥Å丮 long material = TAROT_MATERIAL_ITEM; short tarotBegin = INVENTORY_TAROT_NORMAL_BEGIN; short spreadBegin = INVENTORY_SPREAD_NORMAL_BEGIN; //switch ( msg->tarotClass ) switch ( tarotClass ) { case eTAROT_CLASS_NORMAL: material = TAROT_MATERIAL_ITEM; tarotBegin = INVENTORY_TAROT_NORMAL_BEGIN; spreadBegin = INVENTORY_SPREAD_NORMAL_BEGIN; break; case eTAROT_CLASS_SILVER: material = TAROT_MATERIAL_ITEM_SILVER; tarotBegin = INVENTORY_TAROT_SILVER_BEGIN; spreadBegin = INVENTORY_SPREAD_SILVER_BEGIN; break; case eTAROT_CLASS_GOLD: material = TAROT_MATERIAL_ITEM_GOLD; tarotBegin = INVENTORY_TAROT_GOLD_BEGIN; spreadBegin = INVENTORY_SPREAD_GOLD_BEGIN; break; case eTAROT_CLASS_DIA: material = TAROT_MATERIAL_ITEM_DIA; tarotBegin = INVENTORY_TAROT_DIA_BEGIN; spreadBegin = INVENTORY_SPREAD_DIA_BEGIN; break; default: throw ERROR_TAROT_SELF_JOIN_CLASS; break; } if ( !(GetItemCount( material ) > 0) ) throw ERROR_TAROT_SELF_JOIN_METARIAL; if ( GetTarotCards( mTarotCards, tarotBegin ) == false ) throw ERROR_TAROT_SELF_JOIN_FAIL; GetSpreads( mSpread, spreadBegin, (mSpreadOffset=0) ); if ( !(mSpreadOffset > 0) ) throw ERROR_TAROT_SELF_JOIN_SPREAD; HANDLE handle = NULL; MSG_RES_TAROT_SELF_JOIN* sendMsg = (MSG_RES_TAROT_SELF_JOIN*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_TAROT, NM_TAROT_SELF_JOIN_RES ); if ( sendMsg != NULL ) { sendMsg->ErrorCode = ERROR_TAROT_SELF_JOIN_SUCCESS; // Àç·á¼Ò¸ð ItemUse( material ); mTarotItemCount = GetItemCount( material ); /*-- Ä«µå¼¯ÀÌ(shuffle). */ TB_INVENTORY* temp; int s; for ( int i = 0; i < MAX_TAROT_CARDS; i++ ) { s = (int)(rand( ) % MAX_TAROT_CARDS); // 0 ~ 21ÀÇ ·¥´ý ¼ö¸¦ »ý¼ºÇÑ´Ù. temp = mTarotCards[ i ]; // ±³È¯À» À§ÇØ Àӽà ÀúÀå. mTarotCards[ i ] = mTarotCards[ s ]; // ±³È¯ ½ÃÀÛ. mTarotCards[ s ] = temp; // ±³È¯ ¿Ï·á. } // Ä«µå¼±ÅÃ. for ( int i = 0; i < MIN_TAROT_CARDS; i++ ) { sendMsg->TarotCardIndex[ i ] = mTarotCards[ i ]->itemDefineIndex; } NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_TAROT_SELF_JOIN) ); throw ERROR_TAROT_SELF_JOIN_SUCCESS; } throw ERROR_TAROT_SELF_JOIN_FAIL; } int cPlayer::TarotSelfResult( ULONG_PTR socketContext, MSG_REQ_TAROT_SELF_RESULT* msg ) { // »óŰ˻ç if ( GetState( ) != eOBJECT_STATE_STOP || GetStateStop( ) != eSTOP_SELFTAROT ) throw ERROR_TAROT_SELF_RESULT_FAIL; // ½ºÇÁ·¹µå À妽º °Ë»ö. long spreadIndex = 0; bool exists = false; // Spread À妽º È®ÀÎ. for ( long i = 0; i < mSpreadOffset; i++ ) { if ( mSpread[ i ]->itemDefineIndex == (long)msg->SpreadIndex ) { TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( mSpread[ i ]->itemDefineIdx ); if ( itemDefine != NULL ) { spreadIndex = itemDefine->spreadIndex; exists = true; } } } // ½ºÇÁ·¹µå À妽º ¿À·ù. if ( exists == false ) throw ERROR_TAROT_SELF_RESULT_FAIL; // Database ó¸® ¿äû. HANDLE handle = NULL; ITEM_SPREAD_VALUE* itemSpreadValue = (ITEM_SPREAD_VALUE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_SELF_SPREAD_VALUE ); itemSpreadValue->itemDefineIndex = msg->SpreadIndex; itemSpreadValue->spreadIndex = spreadIndex; for ( long i = 0; i < MIN_TAROT_CARDS; i++ ) { TB_ITEM_TAROT* tbItemTarot = ITEMMANAGER->GetItemTarot( mTarotCards[ i ]->itemDefineIdx ); int dir = (rand( ) % 2); itemSpreadValue->values[ i ].itemDefineIndex = mTarotCards[ i ]->itemDefineIndex; itemSpreadValue->values[ i ].dir = (BYTE)(dir + 1); itemSpreadValue->values[ i ].tarot = (dir == 0) ? tbItemTarot->strValue : tbItemTarot->invValue; } if ( NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, sizeof(ITEM_SPREAD_VALUE) ) == true ) { mTarotResultIndex = msg->SpreadIndex; throw ERROR_TAROT_SELF_RESULT_SUCCESS; } throw ERROR_TAROT_SELF_RESULT_FAIL; } int cPlayer::TarotSelfAccept( ULONG_PTR socketContext ) { // »óŰ˻ç if ( GetState( ) != eOBJECT_STATE_STOP || GetStateStop( ) != eSTOP_SELFTAROT ) throw ERROR_TAROT_SELF_ACCEPT_FAIL; if ( IsChangeState( eOBJECT_STATE_IDLE ) == false ) throw ERROR_TAROT_SELF_ACCEPT_FAIL; // »óꝰæ. ChangeState( eOBJECT_STATE_IDLE ); SetStateStop( eSTOP_NONE ); // Database 󸮿äû HANDLE handle = NULL; ITEM_TAROT_RESULT* itemTarotResult = (ITEM_TAROT_RESULT*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_ITEM_SELF_TAROT_RESULT ); itemTarotResult->itemDefineIndex = mTarotResultIndex; itemTarotResult->value = mTarotResultValue; if ( NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, sizeof(ITEM_TAROT_RESULT) ) == true ) throw ERROR_TAROT_SELF_ACCEPT_SUCCESS; throw ERROR_TAROT_SELF_ACCEPT_FAIL; } // TarotReaderDie Method void cPlayer::TarotReaderDie( ) { ReleaseTarotAllGuests( ); } // TarotSeekerDie Method void cPlayer::TarotSeekerDie( ) { cPlayer* player = OBJECTMANAGER->GetPlayer( mTarotReaderIdx ); if ( player != NULL ) player->ReleaseTarotGuest( mObject.index ); } // TarotReaderShutdown Method void cPlayer::TarotReaderShutdown(bool shutdown) { if ( mTarotCloseReserved == false ) mTarotCloseReserved = true; if ( IsTarotReaderClose( ) == true || shutdown == true ) { ReleaseTarotAllGuests( ); ChangeState( eOBJECT_STATE_STOP ); SetStateStop( eSTOP_GAMEFINISH ); } } // TarotSeekerShutdown Method void cPlayer::TarotSeekerShutdown(bool /*shutdown*/) { cPlayer* player = OBJECTMANAGER->GetPlayer( mTarotReaderIdx ); if ( player != NULL ) player->ReleaseTarotGuest( mObject.index ); ChangeState( eOBJECT_STATE_STOP ); SetStateStop( eSTOP_GAMEFINISH ); } // SendMsgResTarot Method bool cPlayer::SendMsgResTarot(char category, char protocol, int error) { return NETWORK2->SendMsgError( mConnectionIdx, category, protocol, error ); } // SendTarotStoreOpen Method. bool cPlayer::SendTarotStoreOpen(wchar_t* readerName, wchar_t* tarotTitle, unsigned long price) { HANDLE handle = NULL; MSG_RES_TAROT_SEEKER_OPEN* sendMsg = (MSG_RES_TAROT_SEEKER_OPEN*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_TAROT, NM_TAROT_SEEKER_OPEN_RES ); if ( sendMsg != NULL ) { sendMsg->ErrorCode = ERROR_TAROT_SEEKER_OPEN_SUCCESS; // Ÿ·ÎÄ«µå ÃÖ´ë 22Àå. unsigned long* tarotCardIndex = sendMsg->TarotCardIndex; for ( long i = 0; i < MAX_TAROT_CARDS; i++, tarotCardIndex++ ) { (*tarotCardIndex) = mTarotCards[ i ]->itemDefineIndex; } // ½ºÇÁ·¹µå ÃÖ´ë 5Àå. unsigned long* spreadIndex = sendMsg->SpreadIndex; for ( long i = 0; i < mSpreadOffset; i++, spreadIndex++ ) { (*spreadIndex) = mSpread[ i ]->itemDefineIndex; } wcscpy( sendMsg->Name, readerName ); wcscpy( sendMsg->Title, tarotTitle ); sendMsg->Price = price; return NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_TAROT_SEEKER_OPEN) ); } return false; } // SendTarotStoreOpen Method. bool cPlayer::SendTarotReaderJoin(wchar_t* seekerName) { HANDLE handle = NULL; MSG_RES_TAROT_READER_JOIN* sendMsg = (MSG_RES_TAROT_READER_JOIN*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_TAROT, NM_TAROT_READER_JOIN_RES ); if ( sendMsg != NULL ) { wcscpy( sendMsg->seekerName, seekerName ); sendMsg->userCount = (++mTarotUserCount); sendMsg->point = (unsigned short)(++mHeroInfo.TarotPoint); return NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_TAROT_READER_JOIN) ); } return false; } // SendTarotReaderLeave Method. bool cPlayer::SendTarotReaderLeave(wchar_t* seekerName) { HANDLE handle = NULL; MSG_RES_TAROT_READER_LEAVE* sendMsg = (MSG_RES_TAROT_READER_LEAVE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_TAROT, NM_TAROT_READER_LEAVE_RES ); if ( sendMsg != NULL ) { wcscpy( sendMsg->seekerName, seekerName ); return NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_TAROT_READER_LEAVE) ); } return false; } // SendTarotStoreJoin Method. bool cPlayer::SendTarotStoreJoin(wchar_t* tarotTitle, unsigned long price) { HANDLE handle = NULL; MSG_RES_TAROT_SEEKER_JOIN* sendMsg = (MSG_RES_TAROT_SEEKER_JOIN*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_TAROT, NM_TAROT_SEEKER_JOIN_RES ); if ( sendMsg != NULL ) { sendMsg->ErrorCode = ERROR_TAROT_SEEKER_JOIN_SUCCESS; /*-- Ä«µå¼¯ÀÌ(shuffle). */ TB_INVENTORY* temp; int s; for ( int i = 0; i < MAX_TAROT_CARDS; i++ ) { s = (int)(rand( ) % MAX_TAROT_CARDS); // 0 ~ 21ÀÇ ·¥´ý ¼ö¸¦ »ý¼ºÇÑ´Ù. temp = mTarotCards[ i ]; // ±³È¯À» À§ÇØ Àӽà ÀúÀå. mTarotCards[ i ] = mTarotCards[ s ]; // ±³È¯ ½ÃÀÛ. mTarotCards[ s ] = temp; // ±³È¯ ¿Ï·á. } // Ä«µå¼±ÅÃ. for ( int i = 0; i < MIN_TAROT_CARDS; i++ ) { sendMsg->TarotCardIndex[ i ] = mTarotCards[ i ]->itemDefineIndex; } wcscpy( sendMsg->strTitle, tarotTitle ); sendMsg->Price = price; return NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_TAROT_SEEKER_JOIN) ); } return false; } // ClearFriends Method. void cPlayer::ClearFriends( ) { memset( mFriends, 0, sizeof(mFriends) ); } // SelectFriend Method. TB_FRIEND* cPlayer::SelectFriend(short offset) { return (offset < MAX_FRIEND) ? (mFriends+offset) : NULL; } bool cPlayer::UpdateFriend( ) { TB_FRIEND* friends = SelectFriend( ); cPlayer* player = NULL; bool retcode = false; for ( long i = 0; i < MAX_FRIEND && friends->idx > 0; i++, friends++ ) { if ( friends->block == 0 ) { if ( friends->channelNum == 0 ) { // °ÔÀÓÁß Ä£±¸È®ÀÎ - ½Å±ÔÁ¢¼Ó °ËÅä. player = OBJECTMANAGER->GetPlayer( friends->characterIdx ); if ( player != NULL ) { friends->level = player->GetLevel( ); friends->job = (unsigned long)player->GetJob( ); friends->mapNum = player->GetMapDataNumber( ); friends->channelNum = NETWORK2->GetChannelNum(); } retcode = true; } else { // °ÔÀÓÁß Ä£±¸È®ÀÎ - º¯°æ³»¿ë °ËÅä. player = OBJECTMANAGER->GetPlayer( friends->characterIdx ); if ( player != NULL ) { if ( friends->level != player->GetLevel( ) ) { friends->level = player->GetLevel( ); retcode = true; } if ( friends->job != (unsigned long)player->GetJob( ) ) { friends->job = (unsigned long)player->GetJob( ); retcode = true; } if ( friends->mapNum != player->GetMapDataNumber( ) ) { friends->mapNum = player->GetMapDataNumber( ); retcode = true; } } else { retcode = true; } } } } return retcode; } // SendFriendList Method. void cPlayer::SendFriendList(ULONG_PTR socketContext) { HANDLE handle = NULL; MSG_RES_FRIEND_LIST* sendMsg = (MSG_RES_FRIEND_LIST*)NETWORK2->GetMsgRoot( &handle, (PerSocketContext*)socketContext, NM_CHAT, NM_CHAT_FRIEND_LIST_RES ); unsigned long length = sizeof(MSG_RES_FRIEND_LIST) - sizeof(sendMsg->table); TB_FRIEND* friends = SelectFriend( ); sendMsg->RowCount = 0; for ( long i = 0; i < 50 && friends->idx > 0; i++, friends++ ) { sendMsg->table[ i ].Idx = friends->idx; sendMsg->table[ i ].CharacterIdx = friends->characterIdx; wcscpy( sendMsg->table[ i ].CharacterName, friends->characterName ); sendMsg->table[ i ].Race = friends->race; sendMsg->table[ i ].Gender = friends->gender; sendMsg->table[ i ].Status = friends->status; sendMsg->table[ i ].Level = friends->level; sendMsg->table[ i ].Job = (unsigned short)friends->job; sendMsg->table[ i ].MapNum = (short)friends->mapNum; sendMsg->table[ i ].ChannelNum = friends->channelNum; sendMsg->table[ i ].Block = friends->block; sendMsg->RowCount++; } length += (sendMsg->RowCount * sizeof(sendMsg->table)); NETWORK2->SendMsgRoot( handle, length ); } // Á¢¼Ó °ü·Ã Á¤º¸ ¾Ë¸² void cPlayer::SendFriendConnect( BYTE connect ) { // ÀÚ½ÅÀÇ Ä£±¸¸ñ·Ï¿¡°Ô¸¸ Àü¼Û TB_FRIEND* friends = SelectFriend(); for( long i = 0; i < 50 && friends->idx > 0; ++i, ++friends ) { // Â÷´ÜÇÏÁö ¾ÊÀº À¯Àú¿¡°Ô¸¸ Àü¼Û if( friends->block == 0 ) { HANDLE handle = NULL; cPlayer* player = OBJECTMANAGER->GetPlayer( friends->characterIdx ); if( player != NULL ) { MSG_SYN_FRIEND_CONNECT* sendMsg = (MSG_SYN_FRIEND_CONNECT*)NETWORK2->GetMsgRoot( &handle, player->GetConnectionIdx(), NM_CHAT, NM_CHAT_FRIEND_CONNECT_SYN ) ; if( sendMsg != NULL ) { sendMsg->characterIndex = mObject.index; sendMsg->connect = connect; sendMsg->channelNum = (connect == 1) ? NETWORK2->GetChannelNum() : 0; sendMsg->mapNum = GetMapDataNumber(); sendMsg->level = GetLevel(); sendMsg->job = GetJob(); NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_FRIEND_CONNECT) ); } } } } } void cPlayer::SyncFriendConnect( long characterIdx, char level, unsigned long job, unsigned short mapnum, BYTE connect, DWORD channelNum ) { TB_FRIEND* friends = SelectFriend(); for( long i = 0; i < 50 && friends->idx > 0; ++i, ++friends ) { if( friends->characterIdx == characterIdx ) { friends->channelNum = ( connect == 1 ) ? channelNum : 0; friends->level = level; friends->job = job; friends->mapNum = mapnum; // HANDLE handle = NULL; MSG_SYN_FRIEND_CONNECT* sendMsg = (MSG_SYN_FRIEND_CONNECT*)NETWORK2->GetMsgRoot( &handle, GetConnectionIdx(), NM_CHAT, NM_CHAT_FRIEND_CONNECT_SYN ); if( sendMsg != NULL ) { sendMsg->characterIndex = characterIdx; sendMsg->connect = connect; sendMsg->channelNum = friends->channelNum; sendMsg->mapNum = friends->mapNum; sendMsg->level = friends->level; sendMsg->job = friends->job; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_FRIEND_CONNECT) ); } break; } } } void cPlayer::PostFriendConnect( BYTE connect ) { // ä³Î µ¿±âÈ­ cSender* sender = g_gameSrv->GetSender(); MSG_SYN_POSTFRIEND_CONNECT sync; memset( &sync, 0, sizeof(MSG_SYN_POSTFRIEND_CONNECT) ); sync.Category = NM_CHAT; sync.Protocol = NM_FRIENDPOST_CONNECT_SYN; sync.characterIdx = mObject.index; sync.connect = connect; sync.job = GetJob(); sync.level = GetLevel(); sync.mapNum = GetMapDataNumber(); long* list = sync.friendlist; TB_FRIEND* friends = SelectFriend(); for( long i = 0; i < 50 && friends->idx > 0; ++i, ++friends, ++list ) { // Â÷´ÜÇÏÁö ¾ÊÀº À¯Àú¸¸ Àü¼Û if( friends->block == 0 ) { *list = friends->characterIdx; } } sender->PostFriendSync( NETWORK2->GetCID(), (char*)&sync, sizeof(MSG_SYN_POSTFRIEND_CONNECT) ); } // TrialOpenReq Method int cPlayer::TrialOpenReq( ULONG_PTR socketContext, BYTE slevel, cPlayer* pTarget ) { if ( pTarget == NULL ) throw ERROR_PLAYER_TRIAL_OPEN_FAIL; if( GetLevel() < 10 ) throw ERROR_PLAYER_TRIAL_OPEN_LEVEL; //¸¶À», Å׸¶, ÀüÀå, Æ©Å丮¾ó¿¡¼­ »ç¿ë ºÒ°¡´É if ( !(mMapNumber > MAP_MIN && mMapNumber <= MAP_MAX) ) throw ERROR_PLAYER_TRIAL_OPEN_MAP; // GMÁ¦¿Ü üũ »çÇ× if ( slevel != 1 ) { // ½Å°í Àç»ç¿ë ½Ã°£ if ( mTrialTime > 0 ) { time_t current; time( ¤t ); if ( difftime( mTrialTime, current ) > 0 ) throw ERROR_PLAYER_TRIAL_OPEN_TIME; } } // »óÅ if( pTarget->GetState() == eOBJECT_STATE_DIE || pTarget->GetState() == eOBJECT_STATE_STOP ) throw ERROR_PLAYER_TRIAL_OPEN_FAIL; // ¸ÊÀ̵¿ if( pTarget->IsMapChange() == true ) throw ERROR_PLAYER_TRIAL_OPEN_FAIL; // °áÅõ Áß if( pTarget->GetDuelIdx() != 0 || GetDuelIdx() != 0 ) throw ERROR_PLAYER_TRIAL_OPEN_FAIL; // ½Å°í °ÅºÎ ½Ã°£ if ( pTarget->GetTrialRejectTime() > 0 ) { time_t current; time( ¤t ); if ( difftime( pTarget->GetTrialRejectTime(), current ) > 0 ) throw ERROR_PLAYER_TRIAL_OPEN_TRIAL_REJECT; } // »ó´ë ¶Ç´Â ³»°¡ ½Å°í´çÇÑ »óÅÂÀÌ¸é ½Å°í ºÒ°¡´É if( pTarget->IsAutoTrial() == true || IsAutoTrial() == true ) throw ERROR_PLAYER_TRIAL_OPEN_TRIAL; // ¸ó½ºÅÍ µ¥¹ÌÁö ÀÔÈùÁö 10ÃÊ ÀÌ»óÀÌ¸é ½Å°í ºÒ°¡´É unsigned long diffTime = NETWORK2->GetAccumTime() - pTarget->GetLastAttackTime(); if( diffTime > 10 * SECOND ) throw ERROR_PLAYER_TRIAL_OPEN_FAIL; // Àç»ç¿ë ½Å°í üũ HANDLE handle = NULL; MEMBER_TRIAL* trialCheck = (MEMBER_TRIAL*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_MEMBER_TRIAL_CHECK ); if ( trialCheck != NULL ) { sPlayerInfo* pTargetInfo = pTarget->GetPlayerInfo(); trialCheck->memberIdx = mConnectionIdx; trialCheck->autoCharacterIdx = (pTargetInfo->CharacterIdx > 0) ? pTargetInfo->CharacterIdx : 0; trialCheck->retvalue = 0; if ( NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, sizeof(MEMBER_TRIAL), COMMON_DB_MEMBER_TRIAL ) == false ) throw ERROR_PLAYER_TRIAL_OPEN_FAIL; } // ½Å°í »óÅ ¼³Á¤ pTarget->IsAutoTrial( true ); throw ERROR_PLAYER_TRIAL_OPEN_SUCCESS; } // SendTrialReqResult Method void cPlayer::SendTrialReqResult( ULONG_PTR socketContext, int error, cPlayer* pTarget ) { HANDLE handle = NULL; MSG_RES_PLAYER_TRIAL_OPEN* sendMsg = (MSG_RES_PLAYER_TRIAL_OPEN*)NETWORK2->GetMsgRoot( &handle, (PerSocketContext*)socketContext, NM_PLAYER, NM_PLAYER_TRIAL_OPEN_RES ); if ( sendMsg == NULL ) return; /// ½Å°íÀÚ Àç»ç¿ë ³²Àº ½Ã°£ if ( error == ERROR_PLAYER_TRIAL_OPEN_TIME ) { time_t current; time( ¤t ); sendMsg->remainTime = (long)difftime( mTrialTime, current ) * 1000; } /// ½Å°í °ÅºÎ ³²Àº ½Ã°£ else if ( error == ERROR_PLAYER_TRIAL_OPEN_TRIAL_REJECT ) { if ( pTarget ) { time_t current; time( ¤t ); sendMsg->remainTime = (long)difftime( pTarget->GetTrialRejectTime(), current ) * 1000; } else { NETWORK2->PostServerEvent( "Error(%d): cPlayer::SendTrialReqResult() - pTarget == NULL", error ); } } // ½Å°í ½ÇÆÐÀ̸é, ½ÉÆÇ »óŸ¦ º¯°æÇØ¾ß ÇÑ´Ù. if ( error != ERROR_PLAYER_TRIAL_OPEN_SUCCESS ) { if ( pTarget && pTarget->GetTrialMemberIdx() == 0 ) pTarget->IsAutoTrial( false ); } sendMsg->ErrorCode = error; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_PLAYER_TRIAL_OPEN) ); } // TrialAnswer Method int cPlayer::TrialAnswer( ULONG_PTR /*socketContext*/, wchar_t* answer ) { if( IsAutoTrial() == false ) return ERROR_PLAYER_TRIAL_ANSWER_FAIL; if( wcslen(answer) != MAX_TRIAL_ANSWER_LEN ) return ERROR_PLAYER_TRIAL_ANSWER_TEXTLEN; /// ½ÉÆÇ ½Ã°£ Ãʰú if( mTrialAnswerTime < NETWORK2->GetAccumTime() ) return ERROR_PLAYER_TRIAL_ANSWER_TIME_OVER; /// Á¤´ä if( wcscmp( answer, mCaptchaName ) == 0 ) { return ERROR_PLAYER_TRIAL_ANSWER_SUCCESS; } /// ¿À´ä else { mTrialAnswerCount--; /// 3¹ø ¸ðµÎ ½ÇÆÐ - ¿ÀÅä ÆÇÁ¤ if( mTrialAnswerCount == 0 ) mAutoPlayer = true; return ERROR_PLAYER_TRIAL_ANSWER_WRONG; } } // TrialStart Method void cPlayer::TrialStart( unsigned long trialPlayerIdx, wchar_t* answer ) { // Àç»ç¿ë ½Ã°£ 3ºÐ 15ÃÊ(Ŭ¶óÀÌ¾ðÆ®¿Í ÅÒÀ» 10ÃÊ ¿©À¯ Àû¿ë) mTrialAnswerTime = NETWORK2->GetAccumTime() + TRIAL_ANSWER_TIME + (10 * SECOND); mTrialAnswerCount = MAX_TRIAL_ANSWER_COUNT; mCaptchaCount = MAX_TRIAL_CAPTCHA_COUNT; mTrialMemberIdx = trialPlayerIdx; ::wcsncpy( mCaptchaName, answer, MAX_TRIAL_ANSWER_LEN ); IsAutoTrial( true ); } // TrialEnd Method void cPlayer::TrialEnd( bool bAuto ) { int result = ERROR_PLAYER_TRIAL_RESULT_AUTO; // ¿ÀÅä À¯Àú ÆÇÁ¤ if ( bAuto == true ) { // ·Î±×ÀÎ Á¦ÇÑ ¼³Á¤(DB) AutoLimit( ); result = ERROR_PLAYER_TRIAL_RESULT_AUTO; } // ¿ÀÅä À¯Àú ¾Æ´Ô else { result = ERROR_PLAYER_TRIAL_RESULT_NOT_AUTO; HANDLE handle = NULL; TRIAL_REJECT* trialReject = (TRIAL_REJECT*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_MEMBER_TRIAL_REJECT_UPDATE ); trialReject->memberIdx = mConnectionIdx; trialReject->rejectTime = 300; trialReject->retvalue = 0; NETWORK2->SendSQL( mConnectionIdx, handle, sizeof(CAPTCHA_SELECT), COMMON_DB_MEMBER_TRIAL ); } HANDLE handle = NULL; MSG_SYN_PLAYER_TRIAL_RESULT* sendMsg = (MSG_SYN_PLAYER_TRIAL_RESULT*)NETWORK2->GetMsgRoot( &handle, mTrialMemberIdx, NM_PLAYER, NM_PLAYER_TRIAL_RESULT_SYN ); if ( sendMsg != NULL ) { ::wcsncpy( sendMsg->name, GetName( ), MAX_NAME_BUFFER_SIZE ); sendMsg->ErrorCode = result; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_PLAYER_TRIAL_RESULT) ); } // ¿ÀÅä À¯Àú ¾Æ´Ô mAutoPlayer = false; mTrialAnswerTime = 0; mTrialAnswerCount = 0; mTrialMemberIdx = 0; mCaptchaCount = 0; memset( mCaptchaName, 0x00, sizeof(mCaptchaName) ); /// ½ÉÆÇ »óÅ Ǯ¾îÁÜ IsAutoTrial( false ); } void cPlayer::AutoLimit() { // ·Î±×ÀÎ Á¦ÇÑ ¼³Á¤(DB) HANDLE handle = NULL; LOGIN_LIMIT* loginLimit = (LOGIN_LIMIT*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_MEMBER_LOGIN_LIMIT ); loginLimit->memberIdx = mConnectionIdx; loginLimit->count = 1; // Á¦Àç Ä«¿îÆ® 1¾¿ Áõ°¡ loginLimit->retvalue = 0; NETWORK2->SendSQL( mConnectionIdx, handle, sizeof(LOGIN_LIMIT) ); //NETWORK2->SendSQL( mConnectionIdx, handle, sizeof(LOGIN_LIMIT), COMMON_DB_MEMBER_LOGIN_LIMIT ); } // SendPlayerInfo Method - [cGameProcess/CallbackComplete/SocketManager]¿¡¼­ È£Ãâ. bool cPlayer::SendPlayerInfo(char category, char protocol, ULONG_PTR perSocketContext, unsigned char inDunType ) { HANDLE handle = NULL; MSG_PLAYERINFO* sendMsg = (MSG_PLAYERINFO*)NETWORK2->GetMsgRoot( &handle, (PerSocketContext*)perSocketContext, category, protocol ); sendMsg->ErrorCode = 0; sendMsg->PlayerInfo = mPlayerInfo; sendMsg->WeaponInfo = mPlayerWeaponInfo; sendMsg->WearInfo = mPlayerWearInfo; sendMsg->Exrinfo = mPlayerExrInfo; sendMsg->MapNum = GetMapDataNumber(); sendMsg->MapMode = mThemeMode; sendMsg->XPos = mObjectPos.x; sendMsg->YPos = mObjectPos.y; sendMsg->RotAngle = mMapTargetPos.mRotAngle; sendMsg->IndunType = inDunType; return NETWORK2->SendMsgRoot( handle, sizeof(MSG_PLAYERINFO) ); } // SendSightIn Method - [cGridManager/SendPlayerGameIn/SendSightInPlayer]¿¡¼­ È£Ãâ. bool cPlayer::SendSightIn(char category, char protocol, unsigned long connectionIdx) { /// Ŭ¶óÀÌ¾ðÆ® Àü¼Û ¼öÄ¡ °è»ê mPlayerExrInfo.mMoveSpeed = GetMoveSpeed(); mPlayerExrInfo.mAttackSpeed = GetStatus2()->mAttackSpeed; /// Àåºñ°ü·Ã ½ºÅÝ °è»êÀüÀ̶ó db¿¡ ±â·ÏµÆ´ø °ªÀÌ ´õ Ŭ¼öÀÖ´Ù if( mPlayerExrInfo.MaxHP < mInitRestHP ) mPlayerExrInfo.MaxHP = mInitRestHP; if( mPlayerExrInfo.MaxMP < mInitRestMP ) mPlayerExrInfo.MaxMP = mInitRestMP; HANDLE handle = NULL; MSG_PLAYERINFO* sendMsg = (MSG_PLAYERINFO*)NETWORK2->GetMsgRoot( &handle, connectionIdx, category, protocol ); if ( sendMsg != NULL ) { sendMsg->ErrorCode = 0; sendMsg->PlayerInfo = mPlayerInfo; sendMsg->WeaponInfo = mPlayerWeaponInfo; sendMsg->WearInfo = mPlayerWearInfo; sendMsg->Exrinfo = mPlayerExrInfo; sendMsg->MapNum = GetMapDataNumber(); sendMsg->MapMode = mThemeMode; sendMsg->XPos = mObjectPos.x; sendMsg->YPos = mObjectPos.y; sendMsg->RotAngle = mDirection; NETWORK2->SendMsgRoot( handle, sizeof(MSG_PLAYERINFO) ); } SKILLMANAGER->SendAddSynMsgInfluenceToPlayer( connectionIdx, mPlayerInfo.CharacterIdx ); if ( mPlayerExrInfo.mState == eOBJECT_STATE_MOVE ) { HANDLE handle = NULL; MSG_SYN_MOVE* sendMsg = (MSG_SYN_MOVE*)NETWORK2->GetMsgRoot( &handle, connectionIdx, NM_PLAYER, NM_PLAYER_MOVE_SYN ); if ( sendMsg != NULL ) { sendMsg->characterIdx = mObject.index; sendMsg->destX = mGotoX; sendMsg->destY = mGotoY; sendMsg->moveSpeed = GetMoveSpeed(); NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_MOVE) ); } } else if ( mPlayerExrInfo.mState == eOBJECT_STATE_PUSHPULL ) { HANDLE handle = NULL; MSG_SYN_SKLL_PUSHPULL* sendMsg = (MSG_SYN_SKLL_PUSHPULL*)NETWORK2->GetMsgRoot( &handle, connectionIdx, NM_SKILL, NM_SKILL_PUSHPULL_SYN ); if ( sendMsg != NULL ) { sendMsg->mTarget = mObject; sendMsg->mPosX = mGotoX; sendMsg->mPosY = mGotoY; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_SKLL_PUSHPULL) ); } } if ( mPlayerExrInfo.mStateStop == eSTOP_OPENTAROT ) { HANDLE handle = NULL; MSG_SYN_TAROT_READER_OPEN* sendMsg = (MSG_SYN_TAROT_READER_OPEN*)NETWORK2->GetMsgRoot( &handle, connectionIdx, NM_TAROT, NM_TAROT_READER_OPEN_SYN ); if ( sendMsg != NULL ) { sendMsg->mCharacterIdx = mObject.index; wcscpy( sendMsg->mTitle, mTarotTitle ); NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_TAROT_READER_OPEN) ); } } if ( mPlayerExrInfo.mStateStop == eSTOP_OPENSTALL ) { HANDLE handle = NULL; MSG_SYN_ITEM_STALL_SELL_OPEN* sendMsg = (MSG_SYN_ITEM_STALL_SELL_OPEN*)NETWORK2->GetMsgRoot( &handle, connectionIdx, NM_ITEM, NM_ITEM_STALL_SELL_OPEN_SYN ); if ( sendMsg != NULL ) { sendMsg->characterIdx = mObject.index; wcscpy( sendMsg->title, mStallSellTitle ); NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_ITEM_STALL_SELL_OPEN) ); } } return false; } // SendSightOut Method - [cGridManager::SendPlayerGameOut/SendSightOutPlayer]¿¡¼­ È£Ãâ. bool cPlayer::SendSightOut(char category, char protocol, unsigned long connectionIdx) { HANDLE handle = NULL; MSG_CHARACTERIDX* sendMsg = (MSG_CHARACTERIDX*)NETWORK2->GetMsgRoot( &handle, connectionIdx, category, protocol ); if ( sendMsg != NULL ) { sendMsg->mCharacterIdx = mObject.index; NETWORK2->SendMsgRoot( handle, sizeof(MSG_CHARACTERIDX) ); } return false; } bool cPlayer::SendHeroInfo() { HANDLE handle = NULL; MSG_HEROINFO* sendMsg = (MSG_HEROINFO*)NETWORK2->NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_HEROINFO_RES ); if ( sendMsg != NULL ) { /// Àåºñ°ü·Ã ½ºÅÝ °è»êÀüÀ̶ó db¿¡ ±â·ÏµÆ´ø °ªÀÌ ´õ Ŭ¼öÀÖ´Ù if( mPlayerExrInfo.MaxHP < mInitRestHP ) mPlayerExrInfo.MaxHP = mInitRestHP; if( mPlayerExrInfo.MaxMP < mInitRestMP ) mPlayerExrInfo.MaxMP = mInitRestMP; sendMsg->mHeroInfo = mHeroInfo; sendMsg->mExrInfo = mPlayerExrInfo; sendMsg->mCanTMove = GetStateOddity( eODDITYTYPE_CANTMOVE ) != 0; sendMsg->mCanTSkillPhy = GetStateOddity( eODDITYTYPE_CANTSKILL_PHY ) != 0; sendMsg->mCanTSkillMag = GetStateOddity( eODDITYTYPE_CANTSKILL_MAG ) != 0; sendMsg->mSleep = GetStateOddity( eODDITYTYPE_SLEEP ) != 0; sendMsg->mStun = GetStateOddity( eODDITYTYPE_STUN ) != 0; sendMsg->mAvoidMonLook = GetStateOddity( eODDITYTYPE_AVOID_MON_LOOK ) != 0; sendMsg->mChgMonsterIdx = mPlayerExrInfo.mChgMonsterIdx; return NETWORK2->SendMsgRoot( handle, sizeof(MSG_HEROINFO) ); } return false; } /// ¹è¿­À妽º, DB °íÀ¯À妽º int cPlayer::IsKeepQuest( int arrIdx, unsigned long questIdx ) { if( arrIdx < 0 || arrIdx >= MAX_KEEPQUEST ) return -1; if( mQuest[arrIdx].questIdx == questIdx ) return mQuest[arrIdx].idx; return -1; } int cPlayer::IsKeepQuest( unsigned long questIdx ) { for( unsigned int i = 0; i < MAX_KEEPQUEST; ++i ) { if( mQuest[i].idx == 0 ) return -1; if( mQuest[i].questIdx == questIdx ) return i; } return -1; } /// ÇØ´ç Äù½ºÆ®¿Í µ¿ÀÏÇÑ ±×·ìÀÇ Äù½ºÆ®¸¦ º¸À¯ÁßÀÎÁö °Ë»ç int cPlayer::IsKeepGroupQuest( unsigned long questIdx ) { for( unsigned int i = 0; i < MAX_KEEPQUEST; ++i ) { if( mQuest[i].idx == 0 ) return -1; if( mQuest[i].questIdx == questIdx ) return i; /// µ¿ÀÏÇÑ ±×·ìÀÇ Äù½ºÆ® º¸À¯ÁßÀÌ¸é ¸®ÅÏ cQuestDefine* keepDefine = QUESTMAN->GetQuestDefine( mQuest[i].questIdx ); cQuestDefine* define = QUESTMAN->GetQuestDefine( questIdx ); if( keepDefine && define ) { if( define->mGroup > 0 && define->mGroup == keepDefine->mGroup ) return i; } } return -1; } /// Äù½ºÆ® ¸®½ºÆ® ºóÀÚ¸® ã±â int cPlayer::FindEmptyQuest() { for( unsigned int i = 0; i < MAX_KEEPQUEST; ++i ) { if( mQuest[i].idx == 0 && mQuest[i].questIdx == 0 ) return i; } return -1; } /// bool cPlayer::IsCompleteQuest( unsigned long questIdx, bool checkGroup ) { cCompleteQuestSet::cIterator i = mCompleteQuestSet.Find( questIdx ); if( i != mCompleteQuestSet.End() ) return true; if( checkGroup ) { /// µ¿ÀÏÇÑ ±×·ìÀÇ Äù½ºÆ®¸¦ ¿Ï·áÇÏ¿´´ÂÁö °Ë»ç cQuestDefine* define = QUESTMAN->GetQuestDefine( questIdx ); if( define ) { cCompleteGroupQuestSet::cIterator i = mCompleteGroupQuestSet.Find( define->mGroup ); if( i != mCompleteGroupQuestSet.End() ) return true; } } return false; } // bool cPlayer::AddCompleteQuest( unsigned long questIdx ) { cQuestDefine* define = QUESTMAN->GetQuestDefine( questIdx ); if( !define ) { //NETWORK2->PostServerEvent( "Error(%d): QUEST AddValidQuest() - failed to search questIdx", questIdx ); return false; } /// ¹Ýº¹Äùµµ ÀÖÀ¸¹Ç·Î ¿¡·¯Ã¼Å©ÇÏÁö ¾Ê´Â´Ù if( mCompleteQuestSet.Insert( questIdx ) == false ) return false; /// ¿Ï·á ±×·ìÁ¤º¸µµ ÀúÀå if( define->mGroup > 0 ) mCompleteGroupQuestSet.Insert( define->mGroup ); return true; } /// bool cPlayer::AddValidQuest( long questIdx, TIMESTAMP_STRUCT valid ) { cQuestDefine* define = QUESTMAN->GetQuestDefine( questIdx ); if( !define ) { //NETWORK2->PostServerEvent( "Error(%d): QUEST AddValidQuest() - failed to search questIdx", questIdx ); return false; } if( define->mEventType == eQUEST_TIMEEVENT && valid.year != 0 ) { if( mValidQuestMap.Insert( questIdx, valid ) == false ) return false; if( define->mGroup > 0 ) mValidGroupQuestSet.Insert( define->mGroup ); } return true; } bool cPlayer::IsValidEndQuest( long questIdx ) { cValidQuestMap::cIterator i = mValidQuestMap.Find( questIdx ); if( i != mValidQuestMap.End() ) { /// ¸¸±âÀϸñ·Ï¿¡ Á¸ÀçÇϸé, ½Ã°£ÀÌ µÇ¾ú´ÂÁö °Ë»ç TIMESTAMP_STRUCT valid = (*i).mSecond; long diff = TIMER->DiffRealTime( valid ); if( diff > 0 ) return false; /// ¸¸±âÀÏÀÌ ¿Ï·áµÈ Á¤º¸´Â »èÁ¦ ÇÑ´Ù mValidQuestMap.Erase( questIdx ); cQuestDefine* define = QUESTMAN->GetQuestDefine( questIdx ); if( define && define->mGroup > 0 ) mValidGroupQuestSet.Erase( define->mGroup ); } return true; } void cPlayer::DeleteQuest( int arrIdx ) { if( arrIdx < 0 || arrIdx >= MAX_KEEPQUEST ) { NETWORK2->PostServerEvent( "Error(%d,%d): QUEST DeleteQuest() ", mObject.index, arrIdx ); return; } TB_QUEST_PROGRESS* delQuest = mQuest + arrIdx; memset( delQuest, 0, sizeof(TB_QUEST_PROGRESS) ); /// À̵¿½Ã۱â TB_QUEST_PROGRESS* quest1 = mQuest + arrIdx; TB_QUEST_PROGRESS* quest2 = 0; for( int i = arrIdx; i < MAX_KEEPQUEST - 1; ++i, quest1++ ) { quest2 = quest1 + 1; *quest1 = *quest2; } TB_QUEST_PROGRESS* lastQuest = mQuest + MAX_KEEPQUEST - 1; memset( lastQuest, 0, sizeof(TB_QUEST_PROGRESS) ); } /// Äù½ºÆ® ¸ñ·Ï ¹ß¼Û bool cPlayer::SendQuest( ULONG_PTR socketContext ) { HANDLE handle = NULL; MSG_RES_QUEST_LIST* sendMsg = (MSG_RES_QUEST_LIST*)NETWORK2->GetMsgRoot( &handle, (PerSocketContext*)socketContext, NM_QUEST, NM_QUEST_LIST_RES ); sQuestList* questlist = sendMsg->table; unsigned long length = sizeof(MSG_RES_QUEST_LIST) - sizeof(sendMsg->table); TB_QUEST_PROGRESS* data = mQuest; sendMsg->rowCount = 0; for( int i = 0; i < MAX_KEEPQUEST; ++i ) { if( data->idx == 0 ) break; questlist->arrIdx = i; questlist->questIdx = data->questIdx; questlist->check = data->check; questlist->status = data->status; questlist->restTime = 0; /// ³²Àº½Ã°£ Àç°è»ê cQuestDefine* define = QUESTMAN->GetQuestDefine( data->questIdx ); if( define && define->mQuestLimit && define->mQuestLimit->mTimeType != eTIME_NONE ) { long accTime = NETWORK2->GetAccumTime(); long restTime = data->restTime - (accTime - data->startTime); questlist->restTime = ( restTime > 0 ) ? restTime : 0; } questlist++; sendMsg->rowCount++; data++; } length += (sendMsg->rowCount * sizeof(sendMsg->table)); return NETWORK2->SendMsgRoot( handle, length ); } /// DB¿¡ Äù½ºÆ® ÁøÇàÁ¤º¸ ÀúÀå bool cPlayer::SaveQuestProgress(ULONG_PTR /*socketContext*/) { HANDLE handle = NULL; QUEST_UPDATE* questUpdate = (QUEST_UPDATE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_QUEST_UPDATE ); if ( questUpdate != NULL ) { TB_QUEST_PROGRESS* table = questUpdate->table; int length = sizeof(QUEST_UPDATE) - sizeof(questUpdate->table); questUpdate->characterIdx = GetObjectID(); TB_QUEST_PROGRESS* quest = mQuest; for( long i = 0; i < MAX_KEEPQUEST; i++, quest++ ) { if( quest->idx > 0 ) { /// ÁøÇà »óÅÂÀΰ͸¸ ÀúÀåÇÑ´Ù if( quest->status != eQUEST_PLAYING ) continue; cQuestDefine* define = QUESTMAN->GetQuestDefine( quest->questIdx ); if( define ) { (*table) = (*quest); /// ½Ã°£ Á¦ÇÑÄù½ºÆ® - °ÔÀӽð£ ÀÏ °æ¿ì ½Ã°£ °Ë»ç /// °ÔÀӽð£ - ³²Àº½Ã°£ ÀúÀåÇϱâ cQuestLimit* limit = define->mQuestLimit; if( limit && limit->mTimeType == eTIME_GAME ) { long accTime = NETWORK2->GetAccumTime(); long restTime = table->restTime - (accTime - table->startTime); table->restTime = ( restTime > 0 ) ? restTime : 0; } table++; questUpdate->rowCount++; } } else break; } length += (questUpdate->rowCount * sizeof(questUpdate->table)); return NETWORK2->SendSQL( handle, length ); } return false; } int cPlayer::IsRegistQuest( eQUESTADD_TYPE type, unsigned long questIdx, unsigned long npcIdx ) { /// Äù½ºÆ®¹øÈ£ À¯È¿¼º °Ë»ç cQuestDefine* define = QUESTMAN->GetQuestDefine( questIdx ); if( !define ) return ERROR_QUEST_ADD_FAIL; /// NPC¿¡ ÀÇÇÑ Äù½ºÆ®Àϰæ¿ì, NPC °Ë»ç if( type == eQUESTADD_NPC ) { cNpc* pNpc = OBJECTMANAGER->GetNpc( npcIdx ); if( !pNpc ) return ERROR_QUEST_ADD_FAIL; unsigned int npcId = pNpc->GetRaceGender(); /// ½ÇÁ¦·Î npc°¡ ¼ÒÀ¯ÇÑ Äù½ºÆ®ÀÎÁö °Ë»ç if( !QUESTMAN->IsHaveQuest( questIdx, npcId ) ) return ERROR_QUEST_ADD_NPC; } /// ¿ÏÀü ¿Ï·áµÈ Äù½ºÆ®ÀÎÁö °Ë»ç (¹Ýº¹Äù Á¦¿Ü) if( define->mRepeatType != eQUEST_REPEAT ) { /// ÇØ´çÄù¿Í ±×·ìÄù°¡ ¿Ï·áµÇ¾ú´ÂÁö °Ë»ç (¹Ýº¹Äù Á¦¿Ü) if( IsCompleteQuest( questIdx ) ) return ERROR_QUEST_ADD_COMPLETE; } /// ÇØ´ç Äù¿Í ±×·ìÄù°¡ ¸¸±âÀÏÀÌ Áö³µ´ÂÁö °Ë»ç if( define->mEventType == eQUEST_TIMEEVENT ) { if( IsValidEndQuest( questIdx ) == false ) return ERROR_QUEST_ADD_TIME; } /// Äù½ºÆ® ¸ñ·Ï °¹¼ö °Ë»ç if( FindEmptyQuest() == -1 ) return ERROR_QUEST_ADD_MAX; /// °¡Áö°í ÀÖ´Â Äù½ºÆ®ÀÎÁö °Ë»ç. if( IsKeepGroupQuest( questIdx ) != -1 ) return ERROR_QUEST_ADD_EXIST; /// ÁöºÒÇÒ ±Ý¾×ÀÌ ÀÖÀ»½Ã ±Ý¾× °Ë»ç cQuestLimit* limit = define->mQuestLimit; if( limit ) { if( limit->mTakeMoney > 0 ) { if( GetMoney() < limit->mTakeMoney ) return ERROR_QUEST_ADD_MONEY; } if( limit->mTakeFire > 0 ) { if( mHeroInfo.mFirePoint < limit->mTakeFire ) return ERROR_QUEST_ADD_POINT; } if( limit->mTakeWater > 0 ) { if( mHeroInfo.mWaterPoint < limit->mTakeWater ) return ERROR_QUEST_ADD_POINT; } if( limit->mTakeWind > 0 ) { if( mHeroInfo.mWindPoint < limit->mTakeWind ) return ERROR_QUEST_ADD_POINT; } if( limit->mTakeEarth > 0 ) { if( mHeroInfo.mEarthPoint < limit->mTakeEarth ) return ERROR_QUEST_ADD_POINT; } } /// Æ®¸®°Å °Ë»ç( Á¶°Ç °Ë»ç ) if( !TRIGGERMAN->CheckTrigger( GetObjectID(), questIdx ) == eCHECK_TRIGGER_SUCCESS ) return ERROR_QUEST_ADD_TRIGGER; return ERROR_QUEST_ADD_SUCCESS; } // ÇöÀç ¸Ê¿¡¼­ ¹ß»ý°¡´ÉÇÑ ½Å±ÔÄù½ºÆ® ¸®½ºÆ®¸¸ º¸³½´Ù bool cPlayer::SendNewQuestList() { if( GetGameIn() == false ) return false; /// ÇØ´ç¸ÊÀÇ ÀÖ´Â npc·Î Àç ¼¼ÆÃ typedef tPointerHashMap cNpcMap; typedef tHashSet cQuestSet; cQuestSet nextLevelQuestList; HANDLE handle = NULL; MSG_SYN_NEWQUESTLIST* sendMsg = (MSG_SYN_NEWQUESTLIST*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_QUEST, NM_QUEST_NEWLIST_SYN ); if( sendMsg != NULL ) { unsigned long length = sizeof(MSG_SYN_NEWQUESTLIST) - sizeof(sendMsg->questIdxList); unsigned long* questlist = sendMsg->questIdxList; sendMsg->rowCount = 0; cNpcMap* npcMap = (cNpcMap*)OBJECTMANAGER->GetNpcMap(); if( npcMap != NULL ) { /// npc ¸ñ·ÏÁß µ¿ÀÏÇÑ ¸Ê¿¡ ÀÖ´Â npc¸¸ ó¸® cNpcMap::cIterator i = npcMap->Begin(); cNpcMap::cIterator end = npcMap->End(); for( ; i != end; ++i ) { cNpc* pNpc = (cNpc*)(i->mSecond); if( pNpc == NULL ) { NETWORK2->PostServerEvent( "Error(%d): QUEST SendNewQuestList() - not exist npc", GetMapNumber() ); continue; } if( pNpc->GetMapNumber() != mMapNumber ) continue; sNpcQuestList* list = QUESTMAN->GetNpcQuestMap( pNpc->GetRaceGender() ); if( list != NULL ) { cQuestSet::cIterator s = list->mQuestSet.Begin(); cQuestSet::cIterator send = list->mQuestSet.End(); for( ; s != send; ++s ) { unsigned long questIdx = (unsigned long)(*s); cQuestDefine* define = QUESTMAN->GetQuestDefine( questIdx ); if( !define ) { NETWORK2->PostServerEvent( "Error(%d): QUEST SendNewQuestList() - failed to search quest define", questIdx ); assert(0); continue; } /// ¹Ýº¹Äù½ºÆ®°¡ ¾Æ´Ñ°æ¿ì if( define->mRepeatType != eQUEST_REPEAT ) { /// ÇØ´çÄù¿Í ±×·ìÄù°¡ ¿Ï·áµÇ¾úÀ¸¸é skip if( IsCompleteQuest( questIdx ) ) continue; } /// ÇØ´ç Äù¿Í ±×·ìÄù°¡ ¸¸±âÀÏÀÌ Áö³µ´ÂÁö °Ë»ç if( define->mEventType == eQUEST_TIMEEVENT ) { if( IsValidEndQuest( questIdx ) == false ) continue; } /// 3. player °¡ º¸À¯ÁßÀÎ Äù½ºÆ®°Å³ª µ¿ÀÏÇÑ ±×·ìÀÇ Äù½ºÆ® º¸À¯ÁßÀ̸é skip if( IsKeepGroupQuest( questIdx ) != -1 ) continue; /// Æ®¸®°Å °Ë»ç ÈÄ °¡´ÉÇÏ¸é ½Å±Ô eCheckTriggerResult triggerRet = eCHECK_TRIGGER_ERROR; triggerRet = TRIGGERMAN->CheckTrigger( mObject.index, questIdx ); if( triggerRet == eCHECK_TRIGGER_SUCCESS ) { /// º¸³¾³»¿ë (*questlist) = questIdx; questlist++; sendMsg->rowCount++; } else if( triggerRet == eCHECK_TRIGGER_NEXT_LEVEL_QUEST ) { nextLevelQuestList.Insert( questIdx ); } } } } if( sendMsg->rowCount > 0 ) length += (sendMsg->rowCount * sizeof(sendMsg->questIdxList)); NETWORK2->SendMsgRoot( handle, length ); /// ÇöÀç ·¹º§ + NEXT_LEVEL_QUEST_GAP ·¦ ¶§ ÇÒ ¼ö ÀÖ´Â Äù½ºÆ® º¸³»ÁÖ±â if( nextLevelQuestList.GetSize() > 0 ) { HANDLE handle2 = NULL; MSG_SYN_NEXT_LEVEL_NEWQUESTLIST* sendMsg2 = (MSG_SYN_NEXT_LEVEL_NEWQUESTLIST*)NETWORK2->GetMsgRoot( &handle2, mConnectionIdx, NM_QUEST, NM_QUEST_NEXT_LEVEL_NEWLIST_SYN ); if( sendMsg2 != NULL ) { unsigned long len = sizeof(MSG_SYN_NEXT_LEVEL_NEWQUESTLIST) - sizeof(sendMsg2->questIdxList); unsigned long* questlist = sendMsg2->questIdxList; sendMsg2->rowCount = 0; cQuestSet::cIterator pos = nextLevelQuestList.Begin(); cQuestSet::cIterator end = nextLevelQuestList.End(); for ( ; pos != end; ++pos ) { (*questlist) = (*pos); questlist++; sendMsg2->rowCount++; } len += (sendMsg2->rowCount * sizeof(sendMsg2->questIdxList)); NETWORK2->SendMsgRoot( handle2, len ); } } } } return true; } // Äù½ºÆ®ÀÇ ÀÏÁ¤ »óȲ¿¡¸¸ °Ë»ç // Äù½ºÆ® ±âÁØÀ¸·Î NPC »óÅ üũ bool cPlayer::SendEventQuestList( short eventtype ) { typedef tPointerHashMap cNpcMap; typedef tHashSet cQuestSet; typedef tArray cArray; cQuestSet nextLevelQuestList; cArray* typeArr = QUESTMAN->GetQuestTypeArr( eventtype ); if( typeArr->GetSize() == 0 ) return true; HANDLE handle = NULL; MSG_SYN_NEWQUESTLIST* sendMsg = (MSG_SYN_NEWQUESTLIST*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_QUEST, NM_QUEST_NEWLISTEVENT_SYN ); if( sendMsg != NULL ) { unsigned long length = sizeof(MSG_SYN_NEWQUESTLIST) - sizeof(sendMsg->questIdxList); unsigned long* questlist = sendMsg->questIdxList; sendMsg->rowCount = 0; /// ÀÏÁ¤ »óȲ¿¡¼­¸¸ ¹ß»ýÇÏ´Â Äù½ºÆ® cArray::cIterator i = typeArr->Begin(); cArray::cIterator end = typeArr->End(); for( ; i != end; ++i ) { unsigned long questIndex = (unsigned long)(*i); cQuestDefine* define = QUESTMAN->GetQuestDefine( questIndex ); if( !define ) { NETWORK2->PostServerEvent( "Error(%d): QUEST SendEventQuestList() - failed to search questIdx", questIndex ); assert(0); continue; } cNpcMap* npcMap = (cNpcMap*)OBJECTMANAGER->GetNpcMap(); if( npcMap != NULL ) { /// npc ¸ñ·ÏÁß µ¿ÀÏÇÑ ¸Ê¿¡ ÀÖ´Â npc¸¸ ó¸® cNpcMap::cIterator ni = npcMap->Begin(); cNpcMap::cIterator nend = npcMap->End(); for( ; ni != nend; ++ni ) { cNpc* pNpc = (cNpc*)(ni->mSecond); if( pNpc == NULL ) { NETWORK2->PostServerEvent( "Error(%d): QUEST SendEventQuestList() - not exist npc", GetMapNumber() ); continue; } // µ¿ÀÏ¸Ê °Ë»ç if( pNpc->GetMapNumber() != mMapNumber ) continue; // À̺¥Æ® Äù¸¦ ¹ß»ýÇÏ´Â NPCÀÎÁö °Ë»ç if( pNpc->GetRaceGender() != define->mGiveNpcIndex ) continue; /// ¹Ýº¹Äù½ºÆ®°¡ ¾Æ´Ñ°æ¿ì if( define->mRepeatType != eQUEST_REPEAT ) { /// ÇØ´çÄù¿Í ±×·ìÄù°¡ ¿Ï·áµÇ¾úÀ¸¸é skip if( IsCompleteQuest( questIndex ) ) continue; } /// ÇØ´ç Äù¿Í ±×·ìÄù°¡ ¸¸±âÀÏÀÌ Áö³µ´ÂÁö °Ë»ç if( define->mEventType == eQUEST_TIMEEVENT ) { if( IsValidEndQuest( questIndex ) == false ) continue; } /// player °¡ º¸À¯ÁßÀÎ Äù½ºÆ®°Å³ª µ¿ÀÏÇÑ ±×·ìÀÇ Äù½ºÆ® º¸À¯ÁßÀ̸é skip if( IsKeepGroupQuest( questIndex ) != -1 ) continue; /// Æ®¸®°Å °Ë»ç ÈÄ °¡´ÉÇÏ¸é ½Å±Ô eCheckTriggerResult triggerRet = eCHECK_TRIGGER_ERROR; triggerRet = TRIGGERMAN->CheckTrigger( mObject.index, questIndex ); if( triggerRet == eCHECK_TRIGGER_SUCCESS ) { /// º¸³¾³»¿ë (*questlist) = questIndex; questlist++; sendMsg->rowCount++; } else if( triggerRet == eCHECK_TRIGGER_NEXT_LEVEL_QUEST ) { nextLevelQuestList.Insert( questIndex ); } } } } if( sendMsg->rowCount > 0 ) length += (sendMsg->rowCount * sizeof(sendMsg->questIdxList)); NETWORK2->SendMsgRoot( handle, length ); /// ÇöÀç ·¹º§ + NEXT_LEVEL_QUEST_GAP ·¦ ¶§ ÇÒ ¼ö ÀÖ´Â Äù½ºÆ® º¸³»ÁÖ±â if( nextLevelQuestList.GetSize() > 0 ) { HANDLE handle2 = NULL; MSG_SYN_NEXT_LEVEL_NEWQUESTLIST* sendMsg2 = (MSG_SYN_NEXT_LEVEL_NEWQUESTLIST*)NETWORK2->GetMsgRoot( &handle2, mConnectionIdx, NM_QUEST, NM_QUEST_NEXT_LEVEL_NEWLISTEVENT_SYN ); if( sendMsg2 != NULL ) { unsigned long len = sizeof(MSG_SYN_NEXT_LEVEL_NEWQUESTLIST) - sizeof(sendMsg2->questIdxList); unsigned long* questlist = sendMsg2->questIdxList; sendMsg2->rowCount = 0; cQuestSet::cIterator pos = nextLevelQuestList.Begin(); cQuestSet::cIterator end = nextLevelQuestList.End(); for ( ; pos != end; ++pos ) { (*questlist) = (*pos); questlist++; sendMsg2->rowCount++; } len += (sendMsg2->rowCount * sizeof(sendMsg2->questIdxList)); NETWORK2->SendMsgRoot( handle2, len ); } } } return true; } void cPlayer::UpdateDutyItem() { bool updateNpcStatus = false; bool addSend = false; HANDLE handle = NULL; MSG_RES_QUEST_UPDATE* sendMsg = (MSG_RES_QUEST_UPDATE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_QUEST, NM_QUEST_UPDATE_SYN ); if( sendMsg != NULL ) { sQuestList* questlist = sendMsg->table; unsigned long length = sizeof(MSG_RES_QUEST_UPDATE) - sizeof(sendMsg->table); sendMsg->rowCount = 0; TB_QUEST_PROGRESS* quest = mQuest; for( unsigned int arrIdx = 0; arrIdx < MAX_KEEPQUEST; ++arrIdx, ++quest ) { if( quest->idx == 0 ) break; cQuestDefine* define = QUESTMAN->GetQuestDefine( quest->questIdx ); if( !define ) { NETWORK2->PostServerEvent( "Error(%d): QUEST UpdateDutyItem() - failed to search questIdx", quest->questIdx ); assert(0); break; } if( quest->status != eQUEST_PLAYING ) continue; cQuestDuty* duty = define->mQuestDuty; if( !duty ) continue; /// ¼öÁý ¾ÆÀÌÅÛ °¹¼ö °»½Å for( int i = 0; i < MAX_DUTY; ++i ) { if( duty->mDuty[i].dutyType == eDUTY_NONE ) break; /// ¾ÆÀÌÅÛ ¼öÁý Àǹ« ã±â if( duty->mDuty[i].dutyType == eDUTY_COLLECT ) { PerItemCount* itemCount = ITEMCOUNTPOOL->SearchItemCount( &mItemCountRoot, duty->mDuty[i].targetIdx ); unsigned int count = ( itemCount != NULL ) ? itemCount->bag + itemCount->equip : 0; // max °Ë»ç if( count > duty->mDuty[i].count ) count = duty->mDuty[i].count; __int64 end = 0xFF << ( i * 8 ); __int64 cnt = count << ( i * 8 ); __int64 mask = (0xFFFFFFFFFFFFFFFF ^ end); __int64 update = ( quest->check & mask ) | cnt; if( quest->check != update ) { quest->check = update; /// ¿Ï·á°¡´É½Ã »óÅ °»½Å ¿äû if ( quest->check == define->mComplete ) updateNpcStatus = true; addSend = true; } } } /// Ŭ¶óÀÌ¾ðÆ® ½î±â if( addSend == true ) { questlist->arrIdx = arrIdx; questlist->questIdx = quest->questIdx; questlist->check = quest->check; questlist->status = quest->status; questlist++; sendMsg->rowCount++; addSend = false; } } /// ½î±â if( sendMsg->rowCount > 0 ) { length += (sendMsg->rowCount * sizeof(sendMsg->table)); NETWORK2->SendMsgRoot( handle, length ); } else NETWORK2->ReleaseMsgRoot( (PerIoContext*)handle, length ); /// Àǹ«Á¶°Ç ÃæÁ·¿¡ µû¸¥ npc »óÅ °»½Å ¿äû if( updateNpcStatus == true ) { SendNewQuestList(); } } } /// Äù½ºÆ® ÁøÇà»óȲ °»½Å ( playerIdx : ¸ó½ºÅ͸¦ ÀâÀº »ç¶÷ ) void cPlayer::UpdateDutyHunt( unsigned int classIdx, unsigned long playerIdx ) { bool checkStatus = false; /// Å׸¶ ¼­¹ö À̺¥Æ® ¹ß»ý if( NETWORK2->GetServerType() == _E_ST_ID_THEME_ ) SaveThemeUser( MAKETHEMECID( NETWORK2->GetInDunMapNum(), mThemeMode ) ); HANDLE handle = NULL; MSG_RES_QUEST_UPDATE* sendMsg = (MSG_RES_QUEST_UPDATE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_QUEST, NM_QUEST_UPDATE_SYN ); if( sendMsg != NULL ) { sQuestList* questlist = sendMsg->table; unsigned long length = sizeof(MSG_RES_QUEST_UPDATE) - sizeof(sendMsg->table); sendMsg->rowCount = 0; TB_QUEST_PROGRESS* quest = mQuest; for( unsigned int arrIdx = 0; arrIdx < MAX_KEEPQUEST; arrIdx++, quest++ ) { if( quest->idx == 0 ) break; cQuestDefine* define = QUESTMAN->GetQuestDefine( quest->questIdx ); if( !define ) { NETWORK2->PostServerEvent( "Error(%d): QUEST UpdateDuty() - failed to search questIdx", quest->questIdx ); assert(0); break; } if( quest->status != eQUEST_PLAYING ) continue; /// ÇØ´ç Àǹ«Á¶°ÇÀÌ ÀÖ´ÂÁö ã±â cQuestDuty* duty = define->mQuestDuty; if( !duty ) { NETWORK2->PostServerEvent( "Error(%d): not exist quest duty", quest->questIdx ); continue; } // »ç³É Àǹ« Á¶°Ç °Ë»ç int number = -1; for( unsigned int i = 0; i < MAX_DUTY; ++i, ++number ) { if( duty->mDuty[i].dutyType == eDUTY_HUNT ) { if( duty->mDuty[i].targetIdx == classIdx ) { number = i; break; } } } if( number == -1 ) continue; /// Äù½ºÆ® ¾ÆÀÌÅÛ Âø¿ë °Ë»ç if( IsEquipQuestItem( quest->questIdx ) == false ) continue; /// ÁøÇà½Ã ÇÊ¿äÇÑ Á¶°Ç ¸¸Á·ÇÏ´ÂÁö °Ë»ç if( TRIGGERMAN->CheckDuty( mObject.index, playerIdx, quest->questIdx ) == false ) continue; /// Äù½ºÆ® ¿Ï·áÀ̸é skip if( quest->check == define->mComplete ) continue; __int64 end = 0xFF; for( int i = 0; i < number; ++i ) end = end << 8; /// ºÎºÐ¿Ï·áÀΰæ¿ì skip /// ÇöÀç °ü·ÃµÈ ³»¿ëÀÌ ¿Ï·áÀÎÁö °Ë»çÇØ¼­ ¸ÂÀ¸¸é, ¿Ï·áµÈ Äù¹Ç·Î Ä«¿îÆ® ÇÏÁö ¾Ê´Â´Ù if( (quest->check & end) == (define->mComplete & end) ) continue; /// ÁøÇà»óȲ °»½Å __int64 cnt = 0x01; for( int i = 0; i < number; ++i ) cnt = cnt << 8; quest->check += cnt; /// ¿Ï·á°¡´É½Ã »óÅ °»½Å ¿äû if( quest->check == define->mComplete ) { checkStatus = true; } /// Ŭ¶óÀÌ¾ðÆ® ½î±â questlist->arrIdx = arrIdx; questlist->questIdx = quest->questIdx; questlist->check = quest->check; questlist->status = quest->status; questlist++; sendMsg->rowCount++; } /// ½î±â if( sendMsg->rowCount > 0 ) { length += (sendMsg->rowCount * sizeof(sendMsg->table)); NETWORK2->SendMsgRoot( handle, length ); } else NETWORK2->ReleaseMsgRoot( (PerIoContext*)handle, length ); /// Àǹ«Á¶°Ç ÃæÁ·¿¡ µû¸¥ npc »óÅ °»½Å ¿äû if( checkStatus == true ) { SendNewQuestList(); } } } // Æ©Å丮¾ó¸Ê¿¡¼­¸¸ »ç¿ëÇÏ´Â Äù½ºÆ® Á¶°Ç void cPlayer::UpdateDutyActiveSkill( unsigned int classIdx, unsigned long skillIndex ) { bool checkStatus = false; HANDLE handle = NULL; MSG_RES_QUEST_UPDATE* sendMsg = (MSG_RES_QUEST_UPDATE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_QUEST, NM_QUEST_UPDATE_SYN ); if( sendMsg != NULL ) { sQuestList* questlist = sendMsg->table; unsigned long length = sizeof(MSG_RES_QUEST_UPDATE) - sizeof(sendMsg->table); sendMsg->rowCount = 0; TB_QUEST_PROGRESS* quest = mQuest; for( unsigned int arrIdx = 0; arrIdx < MAX_KEEPQUEST; arrIdx++, quest++ ) { if( quest->idx == 0 ) break; cQuestDefine* define = QUESTMAN->GetQuestDefine( quest->questIdx ); if( !define ) { NETWORK2->PostServerEvent( "Error(%d): QUEST UpdateDutyActiveSkill() - failed to search questIdx", quest->questIdx ); assert(0); break; } if( quest->status != eQUEST_PLAYING ) continue; /// ÇØ´ç Àǹ«Á¶°ÇÀÌ ÀÖ´ÂÁö ã±â cQuestDuty* duty = define->mQuestDuty; if( !duty ) { NETWORK2->PostServerEvent( "Error(%d): QUEST UpdateDutyActiveSkill() - not exist quest duty", quest->questIdx ); continue; } // ½ºÅ³¹ßµ¿ Àǹ« Á¶°Ç °Ë»ç int number = -1; for( unsigned int i = 0; i < MAX_DUTY; ++i, ++number ) { if( duty->mDuty[i].dutyType == eDUTY_ACTIVESKILL && duty->mDuty[i].targetIdx == classIdx ) { // µ¿ÀϽºÅ³À̰ųª, ÀϹݰø°Ý ½ºÅ³Áß¿¡ ÇϳªÀÌ¸é ¼º°ø if( duty->mDuty[i].skillIndex == skillIndex || duty->mDuty[i].skillIndex == NORMAL_ATTACK_SKILL && skillIndex < NORMAL_ATTACK_SKILL_MAX ) { number = i; break; } } } if( number == -1 ) continue; /// Äù½ºÆ® ¾ÆÀÌÅÛ Âø¿ë °Ë»ç if( IsEquipQuestItem( quest->questIdx ) == false ) continue; /// ÁøÇà½Ã ÇÊ¿äÇÑ Á¶°Ç ¸¸Á·ÇÏ´ÂÁö °Ë»ç if( TRIGGERMAN->CheckDuty( mObject.index, mObject.index, quest->questIdx ) == false ) continue; /// Äù½ºÆ® ¿Ï·áÀ̸é skip if( quest->check == define->mComplete ) continue; __int64 end = 0xFF; for( int i = 0; i < number; ++i ) end = end << 8; /// ºÎºÐ¿Ï·áÀΰæ¿ì skip /// ÇöÀç °ü·ÃµÈ ³»¿ëÀÌ ¿Ï·áÀÎÁö °Ë»çÇØ¼­ ¸ÂÀ¸¸é, ¿Ï·áµÈ Äù¹Ç·Î Ä«¿îÆ® ÇÏÁö ¾Ê´Â´Ù if( (quest->check & end) == (define->mComplete & end) ) continue; /// ÁøÇà»óȲ °»½Å __int64 cnt = 0x01; for( int i = 0; i < number; ++i ) cnt = cnt << 8; quest->check += cnt; /// ¿Ï·á°¡´É½Ã »óÅ °»½Å ¿äû if( quest->check == define->mComplete ) { checkStatus = true; } /// Ŭ¶óÀÌ¾ðÆ® ½î±â questlist->arrIdx = arrIdx; questlist->questIdx = quest->questIdx; questlist->check = quest->check; questlist->status = quest->status; questlist++; sendMsg->rowCount++; } /// ½î±â if( sendMsg->rowCount > 0 ) { length += (sendMsg->rowCount * sizeof(sendMsg->table)); NETWORK2->SendMsgRoot( handle, length ); } else NETWORK2->ReleaseMsgRoot( (PerIoContext*)handle, length ); /// Àǹ«Á¶°Ç ÃæÁ·¿¡ µû¸¥ npc »óÅ °»½Å ¿äû if( checkStatus == true ) { SendNewQuestList(); } } } //ePVPDM_OBJECTTYPE void cPlayer::UpdateDutyPVP( unsigned char pvptype, bool win ) { bool checkStatus = false; HANDLE handle = NULL; MSG_RES_QUEST_UPDATE* sendMsg = (MSG_RES_QUEST_UPDATE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_QUEST, NM_QUEST_UPDATE_SYN ); if( sendMsg != NULL ) { sQuestList* questlist = sendMsg->table; unsigned long length = sizeof(MSG_RES_QUEST_UPDATE) - sizeof(sendMsg->table); sendMsg->rowCount = 0; TB_QUEST_PROGRESS* quest = mQuest; for( unsigned int arrIdx = 0; arrIdx < MAX_KEEPQUEST; arrIdx++, quest++ ) { if( quest->idx == 0 ) break; cQuestDefine* define = QUESTMAN->GetQuestDefine( quest->questIdx ); if( !define ) { NETWORK2->PostServerEvent( "Error(%d): QUEST UpdateDutyPVP() - failed to search questIdx", quest->questIdx ); assert(0); break; } if( quest->status != eQUEST_PLAYING ) continue; /// ÇØ´ç Àǹ«Á¶°ÇÀÌ ÀÖ´ÂÁö ã±â cQuestDuty* duty = define->mQuestDuty; if( !duty ) { NETWORK2->PostServerEvent( "Error(%d): QUEST UpdateDutyPVP() - not exist quest duty", quest->questIdx ); continue; } /// pvp Àǹ«Á¶°Ç °Ë»ç int number = -1; for( unsigned int i = 0; i < MAX_DUTY; ++i, ++number ) { // µ¿ÀÏ ÀüÀåÀ϶§ if( duty->mDuty[i].targetIdx == pvptype ) { if( duty->mDuty[i].dutyType == eDUTY_PVPJOIN ) { // Âü¿© number = i; break; } else if( duty->mDuty[i].dutyType == eDUTY_PVPWIN && win == true ) { // ½Â¸® number = i; break; } else if( duty->mDuty[i].dutyType == eDUTY_PVPLOSE && win == false ) { // ÆÐ¹è number = i; break; } } } if( number == -1 ) continue; /// Äù½ºÆ® ¾ÆÀÌÅÛ Âø¿ë °Ë»ç if( IsEquipQuestItem( quest->questIdx ) == false ) continue; /// ÁøÇà½Ã ÇÊ¿äÇÑ Á¶°Ç ¸¸Á·ÇÏ´ÂÁö °Ë»ç if( TRIGGERMAN->CheckDuty( mObject.index, mObject.index, quest->questIdx ) == false ) continue; /// Äù½ºÆ® ¿Ï·áÀ̸é skip if( quest->check == define->mComplete ) continue; __int64 end = 0xFF; for( int i = 0; i < number; ++i ) end = end << 8; /// ºÎºÐ¿Ï·áÀΰæ¿ì skip /// ÇöÀç °ü·ÃµÈ ³»¿ëÀÌ ¿Ï·áÀÎÁö °Ë»çÇØ¼­ ¸ÂÀ¸¸é, ¿Ï·áµÈ Äù¹Ç·Î Ä«¿îÆ® ÇÏÁö ¾Ê´Â´Ù if( (quest->check & end) == (define->mComplete & end) ) continue; /// ÁøÇà»óȲ °»½Å __int64 cnt = 0x01; for( int i = 0; i < number; ++i ) cnt = cnt << 8; quest->check += cnt; /// ¿Ï·á°¡´É½Ã »óÅ °»½Å ¿äû if( quest->check == define->mComplete ) { checkStatus = true; } /// Ŭ¶óÀÌ¾ðÆ® ½î±â questlist->arrIdx = arrIdx; questlist->questIdx = quest->questIdx; questlist->check = quest->check; questlist->status = quest->status; questlist++; sendMsg->rowCount++; } /// ½î±â if( sendMsg->rowCount > 0 ) { length += (sendMsg->rowCount * sizeof(sendMsg->table)); NETWORK2->SendMsgRoot( handle, length ); } else NETWORK2->ReleaseMsgRoot( (PerIoContext*)handle, length ); /// Àǹ«Á¶°Ç ÃæÁ·¿¡ µû¸¥ npc »óÅ °»½Å ¿äû if( checkStatus == true ) { SendNewQuestList(); } } } void cPlayer::UpdateDutyTutorial( eDutyType dutyType ) { bool checkStatus = false; HANDLE handle = NULL; MSG_RES_QUEST_UPDATE* sendMsg = (MSG_RES_QUEST_UPDATE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_QUEST, NM_QUEST_UPDATE_SYN ); if( sendMsg != NULL ) { sQuestList* questlist = sendMsg->table; unsigned long length = sizeof(MSG_RES_QUEST_UPDATE) - sizeof(sendMsg->table); sendMsg->rowCount = 0; TB_QUEST_PROGRESS* quest = mQuest; for( unsigned int arrIdx = 0; arrIdx < MAX_KEEPQUEST; arrIdx++, quest++ ) { if( quest->idx == 0 ) break; cQuestDefine* define = QUESTMAN->GetQuestDefine( quest->questIdx ); if( !define ) { NETWORK2->PostServerEvent( "Error(%d): QUEST UpdateDutyActiveSkill() - failed to search questIdx", quest->questIdx ); assert(0); break; } if( quest->status != eQUEST_PLAYING ) continue; /// ÇØ´ç Àǹ«Á¶°ÇÀÌ ÀÖ´ÂÁö ã±â cQuestDuty* duty = define->mQuestDuty; if( !duty ) { NETWORK2->PostServerEvent( "Error(%d): QUEST UpdateDutyActiveSkill() - not exist quest duty", quest->questIdx ); continue; } // ½ºÅ³¹ßµ¿ Àǹ« Á¶°Ç °Ë»ç int number = -1; for( unsigned int i = 0; i < MAX_DUTY; ++i, ++number ) { if( duty->mDuty[i].dutyType == dutyType ) { number = i; break; } } if( number == -1 ) continue; /// Äù½ºÆ® ¾ÆÀÌÅÛ Âø¿ë °Ë»ç if( IsEquipQuestItem( quest->questIdx ) == false ) continue; /// ÁøÇà½Ã ÇÊ¿äÇÑ Á¶°Ç ¸¸Á·ÇÏ´ÂÁö °Ë»ç if( TRIGGERMAN->CheckDuty( mObject.index, mObject.index, quest->questIdx ) == false ) continue; /// Äù½ºÆ® ¿Ï·áÀ̸é skip if( quest->check == define->mComplete ) continue; __int64 end = 0xFF; for( int i = 0; i < number; ++i ) end = end << 8; /// ºÎºÐ¿Ï·áÀΰæ¿ì skip /// ÇöÀç °ü·ÃµÈ ³»¿ëÀÌ ¿Ï·áÀÎÁö °Ë»çÇØ¼­ ¸ÂÀ¸¸é, ¿Ï·áµÈ Äù¹Ç·Î Ä«¿îÆ® ÇÏÁö ¾Ê´Â´Ù if( (quest->check & end) == (define->mComplete & end) ) continue; /// ÁøÇà»óȲ °»½Å __int64 cnt = 0x01; for( int i = 0; i < number; ++i ) cnt = cnt << 8; quest->check += cnt; /// ¿Ï·á°¡´É½Ã »óÅ °»½Å ¿äû if( quest->check == define->mComplete ) { checkStatus = true; } /// Ŭ¶óÀÌ¾ðÆ® ½î±â questlist->arrIdx = arrIdx; questlist->questIdx = quest->questIdx; questlist->check = quest->check; questlist->status = quest->status; questlist++; sendMsg->rowCount++; } /// ½î±â if( sendMsg->rowCount > 0 ) { length += (sendMsg->rowCount * sizeof(sendMsg->table)); NETWORK2->SendMsgRoot( handle, length ); } else NETWORK2->ReleaseMsgRoot( (PerIoContext*)handle, length ); /// Àǹ«Á¶°Ç ÃæÁ·¿¡ µû¸¥ npc »óÅ °»½Å ¿äû if( checkStatus == true ) { SendNewQuestList(); } } } /// Äù½ºÆ®ÁøÇà½Ã ¾ÆÀÌÅÛÂø¿ë ¿©ºÎ °Ë»ç bool cPlayer::IsEquipQuestItem( unsigned long questIdx ) { cQuestDefine* define = QUESTMAN->GetQuestDefine( questIdx ); if( !define ) { NETWORK2->PostServerEvent( "Error(%d): QUEST IsEquipQuestItem() - failed to search questIdx", questIdx ); assert(0); return false; } cQuestLimit* limit = define->mQuestLimit; if( limit != NULL ) { long* itemIndex = (long*)limit->mLimitEquipItem; for( int i = 0; i < QUEST_ITEM_MAX && (*itemIndex) != 0; ++i, ++itemIndex ) { TB_INVENTORY* inventory = 0; TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefineByIndex( (*itemIndex) ); if( itemDefine != NULL ) { switch( itemDefine->type ) { case ITEM_WEAPON: switch( itemDefine->subType ) { case ITEM_WEAPON_SWORD: // ÇÑ¼Õ°Ë case ITEM_WEAPON_BLADE: // ¾ç¼Õ°Ë case ITEM_WEAPON_DUAL: // À̵µ·ù case ITEM_WEAPON_CUTTER: // ´Ü °Ë case ITEM_WEAPON_GUN: // ÃÑ case ITEM_WEAPON_STAFF: // ÁöÆÎÀÌ inventory = SelectInventory( (short)((mItemActiveWeapon == ItemActiveFront) ? INVENTORY_HAND_RIGHT2 : INVENTORY_HAND_RIGHT1) ); break; case ITEM_WEAPON_SHIELD: // ¹æÆÐ inventory = SelectInventory( (short)((mItemActiveWeapon == ItemActiveFront) ? INVENTORY_HAND_LEFT2 : INVENTORY_HAND_LEFT1) ); break; default: NETWORK2->PostServerEvent( "Error(%d): QUEST IsEquipQuestItem() - error equip type", (*itemIndex) ); assert(0); break; } break; case ITEM_WEAR: switch( itemDefine->subType ) { case ITEM_WEAR_HEAD: inventory = SelectInventory( INVENTORY_WEAR_HAT ); break; // ¸ðÀÚ case ITEM_WEAR_UPPER: inventory = SelectInventory( INVENTORY_WEAR_BODY1 ); break; // »óÀÇ case ITEM_WEAR_LOWER: inventory = SelectInventory( INVENTORY_WEAR_BODY2 ); break; // ÇÏÀÇ case ITEM_WEAR_HANDS: inventory = SelectInventory( INVENTORY_WEAR_HAND ); break; // ¼Õ case ITEM_WEAR_FEET: inventory = SelectInventory( INVENTORY_WEAR_FOOT ); break; // ¹ß case ITEM_WEAR_ONEPIECE: inventory = SelectInventory( INVENTORY_WEAR_BODY1 ); break; // ¿øÇǽº case ITEM_WEAR_COS_HEAD: inventory = SelectInventory( INVENTORY_COSTUME_HAT ); break; // ÄÚ½ºÆ¬ ¸ðÀÚ case ITEM_WEAR_COS_UPPER: inventory = SelectInventory( INVENTORY_COSTUME_BODY1 ); break; // ÄÚ½ºÆ¬ »óÀÇ case ITEM_WEAR_COS_LOWER: inventory = SelectInventory( INVENTORY_COSTUME_BODY2 ); break; // ÄÚ½ºÆ¬ ÇÏÀÇ case ITEM_WEAR_COS_HANDS: inventory = SelectInventory( INVENTORY_COSTUME_HAND ); break; // ÄÚ½ºÆ¬ ¼Õ case ITEM_WEAR_COS_FEET: inventory = SelectInventory( INVENTORY_COSTUME_FOOT ); break; // ÄÚ½ºÆ¬ ¹ß case ITEM_WEAR_COS_ONEPIECE:inventory = SelectInventory( INVENTORY_COSTUME_BODY1 ); break; // ÄÚ½ºÆ¬ ¿øÇǽº default: NETWORK2->PostServerEvent( "Error(%d): QUEST IsEquipQuestItem() - error equip type", (*itemIndex) ); assert(0); break; } break; case ITEM_ACCESSORY: switch( itemDefine->subType ) { case ITEM_ACCESSORY_EARRING: inventory = SelectInventory( INVENTORY_WEAR_EARRING ); break; // ±Í°ÉÀÌ case ITEM_ACCESSORY_NECKLACE: inventory = SelectInventory( INVENTORY_WEAR_NECKLACE ); break; // ¸ñ°ÉÀÌ case ITEM_ACCESSORY_BROOCH: inventory = SelectInventory( INVENTORY_WEAR_BROOCH ); break; // ºê·ÎÄ¡ case ITEM_ACCESSORY_BRACELET: inventory = SelectInventory( INVENTORY_WEAR_BRACELET ); break; // ÆÈÂî case ITEM_ACCESSORY_RING: inventory = SelectInventory( INVENTORY_WEAR_RING ); break; // ¹ÝÁö case ITEM_ACCESSORY_COS_FACE: inventory = SelectInventory( INVENTORY_COSTUME_FACE ); break; // ÄÚ½ºÆ¬ Àå½Ä ¸Ó¸® case ITEM_ACCESSORY_COS_BACK: inventory = SelectInventory( INVENTORY_COSTUME_BACK ); break; // ÄÚ½ºÆ¬ Àå½Ä ¸öÅë default: NETWORK2->PostServerEvent( "Error(%d): QUEST IsEquipQuestItem() - error equip type", (*itemIndex) ); assert(0); break; } break; case ITEM_CARD: if( itemDefine->subType == ITEM_CARD_EQUIP_C ) { for( short i = INVENTORY_WEAR_CARD1; i <= INVENTORY_WEAR_CARD3; ++i ) { inventory = SelectInventory(i); if( inventory && inventory->itemDefineIndex == (*itemIndex) ) break; } } break; default: NETWORK2->PostServerEvent( "Error(%d): QUEST IsEquipQuestItem() - error equip type", (*itemIndex) ); assert(0); break; } // µ¿ÀÏÇÑÁö °Ë»ç if( inventory && inventory->itemDefineIndex != (*itemIndex) ) return false; } } } return true; } /// ÀÇ·Ú¾ÆÀÌÅÛ »ç¿ë °¡´É ¿©ºÎ üũ int cPlayer::IsUseQuestItem( unsigned int number, unsigned long& questIdx) { /*-- ¾ÆÀÌÅÛ »ç¿ë½Ã °Ë»çÇÒ ³»¿ëµé. */ if( GetStateDie() == true ) return ERROR_QUEST_ADD_ITEMFAIL; if ( IsInventoryBag( (unsigned short)number ) == false ) return ERROR_QUEST_ADD_ITEMFAIL; TB_INVENTORY* inventory = SelectInventory( (short)number ); if( IsInventory( inventory ) == false ) return ERROR_QUEST_ADD_ITEMFAIL; if( inventory->apply != InventoryApplyNone ) return ERROR_QUEST_ADD_ITEMFAIL; TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefine( inventory->itemDefineIdx ); if( itemDefine == NULL ) return ERROR_QUEST_ADD_ITEMFAIL; if ( IsInventorySeal( itemDefine, inventory ) == true ) return ERROR_QUEST_ADD_LICENSE; /*-- Item Limit Table(TB_ITEM_LIMIT) Àû¿ë --*/ if ( !IsItemLimit( inventory->itemDefineIdx ) ) return ERROR_QUEST_ADD_ITEMFAIL; /*unsigned int getState = GetState( ); if ( !( getState == eOBJECT_STATE_IDLE || getState == ePLAYER_STATE_ITEMPICK ) ) return ERROR_QUEST_ADDBYITEM_ITEMFAIL;*/ /*-- Item Limit Table(TB_ITEM_LIMIT) Àû¿ë --*/ if ( !IsItemLimit( inventory->itemDefineIdx ) ) return ERROR_QUEST_ADD_ITEMFAIL; /*-- ¾ÆÀÌÅÛ È¿°ú Àû¿ë - ½ºÅ³°ú ¿¬°áÇÏ¿© »ç¿ëÇÑ´Ù. */ TB_ITEM_ABILITY* itemAbility = ITEMMANAGER->GetItemAbility( inventory->itemDefineIdx ); if( itemAbility == NULL ) return ERROR_QUEST_ADD_ITEMFAIL; /// Äù½ºÆ® ÀÇ·Ú ¾ÆÀÌÅÛÀÎÁö È®ÀÎ if( !(itemAbility->influence_idx > 0 && (itemDefine->type == ITEM_ETC1 && itemDefine->subType == ITEM_ETC1_QUEST)) ) return ERROR_QUEST_ADD_ITEMFAIL; questIdx = itemAbility->influence_idx; // Äù½ºÆ® À妽º return ERROR_QUEST_ADD_SUCCESS; } /// äÁý °ü·Ã ¿Ï·á °Ë»ç bool cPlayer::IsCompleteGathering( unsigned long questIndex ) { cQuestDefine* define = QUESTMAN->GetQuestDefine( questIndex ); if( !define ) { NETWORK2->PostServerEvent( "Error(%d): QUEST IsCompleteGathering() - failed to search questIndex", questIndex ); assert(0); return true; } cQuestDuty* duty = define->mQuestDuty; if( !duty ) { NETWORK2->PostServerEvent( "Error: QUEST IsCompleteGathering() - failed to search duty" ); assert(0); return true; } int arrIdx = IsKeepQuest( questIndex ); if( arrIdx == -1 ) return true; /// Äù½ºÆ® ÀÚü°¡ ¿Ï·áµÇ¾úÀ¸¸é ¸®ÅÏ if( mQuest[arrIdx].check >= define->mComplete ) return true; /// äÁý °ü·ÃºÎºÐ ¿Ï·áµÇ¾ú´ÂÁö °Ë»ç __int64 mask = 0x00; for( unsigned int i = 0; i < MAX_DUTY; ++i ) { eDutyType type = duty->mDuty[i].dutyType; /// Àǹ«°¡ ¾ø´Â°Ô ³ª¿À¸é µÚ¿¡µµ ¾øÀ¸¹Ç·Î ³¡ if( type == eDUTY_NONE ) break; if( type == eDUTY_COLLECT ) { __int64 bit = 0xFF << ( i * 8 ); mask = mask | bit; } } /// ¸ðµç äÁý Á¶°ÇÀ» ¿Ï·áÇÏ¿´À¸¸é if( (mQuest[arrIdx].check & mask) >= (define->mComplete & mask) ) return true; return false; } /// ±âº» º¸»ó ó¸® bool cPlayer::SendDefaultReward( unsigned long questIdx, unsigned long* skillList, unsigned char skillListCnt ) { cQuestDefine* define = QUESTMAN->GetQuestDefine( questIdx ); if( !define ) { NETWORK2->PostServerEvent( "Error(%d): QUEST SendDefaultReward() - failed to search questIdx", questIdx ); assert(0); return false; } /// ±âº» º¸»ó ¾ø´Â Äù½ºÆ®µµ ÀÖ´Ù cQuestReward* reward = define->mDefaultReward; if( !reward ) return true; if( reward->mSkillPoint > 0 ) SkillPointPlus( (unsigned short)reward->mSkillPoint ); if( reward->mExp > 0 ) AddExp( reward->mExp, false, false ); if( reward->mSxp > 0 ) AddSxp( reward->mSxp, false ); /// º¸»ó ¹öÇÁ for( int i = 0; i < QUEST_BUFF_MAX; ++i ) { unsigned long buffIdx = reward->mRewardBuff[i]; SendRewardBuff( buffIdx ); } /// ÀüÁ÷ º¸»ó if( reward->mChangeJobIndex > 0 ) { SetJob( (ePLAYER_JOB)reward->mChangeJobIndex, skillList, skillListCnt ); NETWORK2->PostReservedEvent( EVENT_RESERVED_CHANGEJOB, mObject.index, mConnectionIdx ); } /// ¼¼·Â ¼¼ÆÃ if( reward->mForceType > eFORCETYPE_NONE && reward->mForceType < eFORCETYPE_MAX ) { SetForceType( reward->mForceType ); } /// ȣĪ º¸»ó if( reward->mGiveTitleIndex > 0 ) { /// ŸÀÌÆ²Àº ±âº» º¸»óÀ¸·Î ÁÖ¾îÁö±â ¶§¹®¿¡ µû·Î Äõ¸®¹®À» Àû¿ë½ÃŰÁö ¾Ê¾Ò´Ù! if( AddHaveTitle( reward->mGiveTitleIndex ) == true ) SendHaveTitle( reward->mGiveTitleIndex ); } /// ¸Ê üÀÎÁö if( reward->mMapChangeIndex > 0 ) { if( NETWORK2->GetServerType() != _E_ST_ID_TUTORIAL_ ) { if( QuestMapChange( reward->mMapChangeIndex ) == false ) { NETWORK2->PostServerEvent( "Error(%d,%d): SendDefaultReward MapChange", questIdx, reward->mMapChangeIndex ); assert(0); } } else { // ·Î±× NETWORK2->PostReservedEvent( EVENT_RESERVED_TUTORIAL, mObject.index, mConnectionIdx ); // ¸ÊÀ̵¿ °¡´É »óÅÂÀÎÁö üũ if( MapChangeByTutorial( reward->mMapChangeIndex ) == false ) { NETWORK2->PostServerEvent( "Error(%d,%d): SendDefaultReward MapChangeByTutorial MapChange", questIdx, reward->mMapChangeIndex ); assert(0); } } } return true; } /// º¸»ó ¹öÇÁ Ãß°¡ bool cPlayer::SendRewardBuff( unsigned long buffIdx ) { if( buffIdx > 0 ) { sInfluenceScript* info = SKILLSCRIPT->GetInfluenceInfo( buffIdx ); if( info ) { /// ¿À¶óŸÀÔ if( info->mContinuanceTime == -1 ) { int retvalue = SKILLMANAGER->AddInfSwitch( mObject, mObject, buffIdx, 0, true ); if( retvalue == 0 ) { NETWORK2->PostServerEvent( "Error(%d): SendRewardBuff mpSkillManager->AddInfSwitch", buffIdx ); assert(0); } } /// ±×¿Ü ŸÀÔ else { bool retvalue = SKILLMANAGER->AddInfluence( mObject, mObject, buffIdx, 0, true ); if( retvalue == false ) { NETWORK2->PostServerEvent( "Error(%d): SendRewardBuff mpSkillManager->AddInfluence", buffIdx ); assert(0); } } } else { NETWORK2->PostServerEvent( "Error(%d): SendRewardBuff mpSkillManager->GetInfluenceInfo", buffIdx ); assert(0); } } return true; } /// Äù½ºÆ® ¼ö¶ô¿¡ ÀÇÇÑ Á¦¾à Á¶°Ç °É±â bool cPlayer::SendLimitPenalty( unsigned long questIdx, bool gameIn ) { cQuestDefine* define = QUESTMAN->GetQuestDefine( questIdx ); if( !define ) { NETWORK2->PostServerEvent( "Error(%d): QUEST SendLimitPenalty() - failed to search questIdx", questIdx ); assert(0); return false; } cQuestLimit* limit = define->mQuestLimit; if( !limit ) return true; /// Á¦¾à ¹öÇÁ for( int i = 0; i < QUEST_BUFF_MAX; ++i ) { unsigned long buffIdx = limit->mLimitBuff[i]; if( buffIdx > 0 ) { sInfluenceScript* info = SKILLSCRIPT->GetInfluenceInfo( buffIdx ); if( info ) { /// ¿À¶óŸÀÔ if( info->mContinuanceTime == -1 ) { int retvalue = SKILLMANAGER->AddInfSwitch( mObject, mObject, buffIdx, 0, true ); if( retvalue == 0 ) { NETWORK2->PostServerEvent( "Error(%d): QUEST LIMIT PENALTY mpSkillManager->AddInfSwitch", buffIdx ); assert(0); return false; } } /// ±×¿Ü ŸÀÔ else { bool retvalue = SKILLMANAGER->AddInfluence( mObject, mObject, buffIdx, 0, true ); if( retvalue == false ) { NETWORK2->PostServerEvent( "Error(%d): QUEST LIMIT PENALTY mpSkillManager->AddInfluence", buffIdx ); assert(0); return false; } } } else { NETWORK2->PostServerEvent( "Error(%d): QUEST LIMIT PENALTY mpSkillManager->GetInfluenceInfo", buffIdx ); assert(0); } } } /// Á¦¾à µð¹öÇÁ for( int i = 0; i < QUEST_BUFF_MAX; ++i ) { unsigned long debuffIdx = limit->mLimitDeBuff[i]; if( debuffIdx > 0 ) { sInfluenceScript* info = SKILLSCRIPT->GetInfluenceInfo( debuffIdx ); if( info ) { /// ¿À¶óŸÀÔ if( info->mContinuanceTime == -1 ) { int retvalue = SKILLMANAGER->AddInfSwitch( mObject, mObject, debuffIdx, 0, true ); if( retvalue == 0 ) { NETWORK2->PostServerEvent( "Error(%d): QUEST LIMIT PENALTY mpSkillManager->AddInfSwitch debuff", debuffIdx ); assert(0); return false; } } /// ±×¿Ü ŸÀÔ else { bool retvalue = SKILLMANAGER->AddInfluence( mObject, mObject, debuffIdx, 0, true ); if( retvalue == false ) { NETWORK2->PostServerEvent( "Error(%d): QUEST LIMIT PENALTY mpSkillManager->AddInfluence debuff", debuffIdx ); assert(0); return false; } } } else { NETWORK2->PostServerEvent( "Error(%d): QUEST LIMIT PENALTY mpSkillManager->GetInfluenceInfo debuff", debuffIdx ); assert(0); return false; } } } /// gamein ½Ã¿¡´Â Àû¿ëÇÏÁö ¾Ê´Â´Ù if( gameIn == false ) { /// ¸Ê üÀÎÁö if( limit->mMapChangeIndex > 0 ) { if( QuestMapChange( limit->mMapChangeIndex ) == false ) { NETWORK2->PostServerEvent( "Error(%d,%d): QUEST LIMIT PENALTY MapChange", questIdx, limit->mMapChangeIndex ); return false; } } /// ¸ó½ºÅÍ ¼Òȯ if( limit->mMonsterClassIndex > 0 && limit->mMonsterCount > 0 ) { for( unsigned int i = 0; i < limit->mMonsterCount; ++i ) { unsigned long monsterIdx = AIMANAGER->QuestSummonMonRegen( mMapNumber, GetXPos(), GetYPos(), limit->mMonsterClassIndex, limit->mMonsterTime * 1000 ); if( monsterIdx > 0 ) { if( QUESTMAN->AddQuestMonster( mObject.index, questIdx, monsterIdx ) == false ) { NETWORK2->PostServerEvent( "Error(%d,%d,%d): QUEST LIMIT PENALTY AddQuestMonster", questIdx, limit->mMonsterClassIndex, monsterIdx ); return false; } } } } } return true; } /// ½ÇÆÐ·Î ÀÎÇÑ ÆÐ³ÎƼ ÁÖ±â bool cPlayer::SendFailPenalty( unsigned long questIdx ) { cQuestDefine* define = QUESTMAN->GetQuestDefine( questIdx ); if( !define ) { NETWORK2->PostServerEvent( "Error(%d): QUEST SendFailPenalty() - failed to search questIdx", questIdx ); assert(0); return false; } cQuestFail* fail = define->mQuestFail; if( !fail ) return true; /// ½ÇÆÐ¹öÇÁ for( int i = 0; i < QUEST_BUFF_MAX; ++i ) { unsigned long buffIdx = fail->mFailBuff[i]; if( buffIdx > 0 ) { sInfluenceScript* info = SKILLSCRIPT->GetInfluenceInfo( buffIdx ); if( info ) { /// ¿À¶óŸÀÔ if( info->mContinuanceTime == -1 ) { int retvalue = SKILLMANAGER->AddInfSwitch( mObject, mObject, buffIdx, 0, true ); if( retvalue == 0 ) { NETWORK2->PostServerEvent( "Error(%d): QUEST FAIL PENALTY mpSkillManager->AddInfSwitch", buffIdx ); assert(0); } } /// ±×¿Ü ŸÀÔ else { bool retvalue = SKILLMANAGER->AddInfluence( mObject, mObject, buffIdx, 0, true ); if( retvalue == false ) { NETWORK2->PostServerEvent( "Error(%d): QUEST FAIL PENALTY mpSkillManager->AddInfluence", buffIdx ); assert(0); } } } else { NETWORK2->PostServerEvent( "Error(%d): QUEST FAIL PENALTY mpSkillManager->GetInfluenceInfo", buffIdx ); assert(0); } } } /// ½ÇÆÐ µð¹öÇÁ for( int i = 0; i < QUEST_BUFF_MAX; ++i ) { unsigned long debuffIdx = fail->mFailDeBuff[i]; if( debuffIdx > 0 ) { sInfluenceScript* info = SKILLSCRIPT->GetInfluenceInfo( debuffIdx ); if( info ) { /// ¿À¶óŸÀÔ if( info->mContinuanceTime == -1 ) { int retvalue = SKILLMANAGER->AddInfSwitch( mObject, mObject, debuffIdx, 0, true ); if( retvalue == 0 ) { NETWORK2->PostServerEvent( "Error(%d): QUEST FAIL PENALTY mpSkillManager->AddInfSwitch debuff", debuffIdx ); assert(0); } } /// ±×¿Ü ŸÀÔ else { bool retvalue = SKILLMANAGER->AddInfluence( mObject, mObject, debuffIdx, 0, true ); if( retvalue == false ) { NETWORK2->PostServerEvent( "Error(%d): QUEST FAIL PENALTY mpSkillManager->AddInfluence debuff", debuffIdx ); assert(0); } } } else { NETWORK2->PostServerEvent( "Error(%d): QUEST FAIL PENALTY mpSkillManager->GetInfluenceInfo debuff", debuffIdx ); assert(0); } } } return true; } bool cPlayer::SendEndPenalty( unsigned long questIdx ) { cQuestDefine* define = QUESTMAN->GetQuestDefine( questIdx ); if( !define ) { NETWORK2->PostServerEvent( "Error(%d): QUEST SendEndPenalty() - failed to search questIdx", questIdx ); assert(0); return false; } cQuestEnd* end = define->mQuestEnd; if( !end ) return true; /// ¹öÇÁ, µð¹öÇÁ ÇØÁ¦ for( int i = 0; i < QUEST_BUFF_MAX; ++i ) { unsigned long buffIdx = end->mEndBuff[i]; if( buffIdx > 0 ) { SKILLMANAGER->InfluenceOff( mObject.index, buffIdx ); } } for( int i = 0; i < QUEST_BUFF_MAX; ++i ) { unsigned long debuffIdx = end->mEndDeBuff[i]; if( debuffIdx > 0 ) { SKILLMANAGER->InfluenceOff( mObject.index, debuffIdx ); } } /// ¸ó½ºÅÍ ¼ÒȯÁ¤º¸ »èÁ¦ cQuestLimit* limit = define->mQuestLimit; if( limit && limit->mMonsterClassIndex > 0 && limit->mMonsterCount > 0 ) { QUESTMAN->DeleteQuestMonster( mObject.index, questIdx ); } return true; } /// SaveQuestInsert Method. int cPlayer::SaveQuestInsert( ULONG_PTR socketContext, unsigned long characterIdx, unsigned long questIdx ) { cQuestDefine* define = QUESTMAN->GetQuestDefine( questIdx ); if( !define ) { NETWORK2->PostServerEvent( "Error(%d): QUEST SaveQuestInsert() - failed to search questIdx", questIdx ); assert(0); return ERROR_QUEST_ADD_FAIL; } /// Äù½ºÆ®½ÃÀ۽à Á¦°øÇÒ ¾ÆÀÌÅÛÀ» ¹ÞÀ»¼ö ÀÖ´ÂÁö üũ unsigned long total = 0; cQuestLimit* questIimit = define->mQuestLimit; if( questIimit ) { unsigned int bagCnt = 0; unsigned int questCnt = 0; sQuestItem bagItem[QUEST_ITEM_MAX]; sQuestItem questItem[QUEST_ITEM_MAX]; memset( bagItem, 0, sizeof(bagItem) ); memset( questItem, 0, sizeof(questItem) ); sQuestItem* item = questIimit->mGiveItem; for( int i = 0; i < QUEST_ITEM_MAX; ++i, ++item ) { if( item->itemIndex != 0 && item->count > 0 ) { TB_ITEM_DEFINE* p = ITEMMANAGER->GetItemDefineByIndex( item->itemIndex ); if( p ) { if( p->type == ITEM_QUEST ) { questItem[questCnt].itemIndex = item->itemIndex; questItem[questCnt].count = item->count; questCnt++; } else { bagItem[questCnt].itemIndex = item->itemIndex; bagItem[questCnt].count = item->count; bagCnt++; } // total++; } } } /// °¡¹æ °Ë»ç if( IsItemReward( bagItem, bagCnt, INVENTORY_BAG_BEGIN, mHeroInfo.BagEnd ) < bagCnt ) return ERROR_QUEST_ADD_ITEM; /// Äù½ºÆ® ÅÇ °Ë»ç if( IsItemReward( questItem, questCnt, INVENTORY_QUEST_BEGIN, INVENTORY_QUEST_END ) < questCnt ) return ERROR_QUEST_ADD_ITEM; /// °¡¹æ °Ë»ç - ÃÖ´ë º¸À¯°¹¼ö if( IsMaxInventory( bagItem, bagCnt ) == true ) return ERROR_QUEST_ADD_MAX_ITEM; /// Äù½ºÆ® ÅÇ °Ë»ç - ÃÖ´ë º¸À¯°¹¼ö if( IsMaxInventory( questItem, questCnt ) == true ) return ERROR_QUEST_ADD_MAX_ITEM; } /// Äù½ºÆ® »ðÀԽà ó¸® __int64 check = 0; cQuestDuty* duty = define->mQuestDuty; if( duty ) { for( int i = 0; i < MAX_DUTY; ++i ) { if( duty->mDuty[i].dutyType == eDUTY_MEET ) { /// °»½Å __int64 end = 0xFF; for( int e = 0; e < i; ++e ) end = end << 8; /// ÁøÇà»óȲ °»½Å __int64 cnt = 0x01; for( int c = 0; c < i; ++c ) cnt = cnt << 8; check += cnt; break; } } } else { NETWORK2->PostServerEvent( "Error(%d): QUEST SaveQuestInsert() - failed to search duty", questIdx ); return ERROR_QUEST_ADD_FAIL; } /// HANDLE handle = NULL; QUEST_INSERT* questInsert = (QUEST_INSERT*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_QUEST_INSERT ); long& rowCount = questInsert->rowCount; TB_INVENTORY* table = questInsert->inventory; unsigned long length = sizeof(QUEST_INSERT) - sizeof(questInsert->inventory); questInsert->characterIdx = characterIdx; questInsert->questIdx = questIdx; questInsert->timeType = eTIME_NONE; questInsert->restTime = 0; questInsert->takemoney = ( questIimit != NULL ) ? -((long)questIimit->mTakeMoney) : 0; questInsert->firepoint = ( questIimit != NULL ) ? -((long)questIimit->mTakeFire) : 0; questInsert->waterpoint = ( questIimit != NULL ) ? -((long)questIimit->mTakeWater) : 0; questInsert->windpoint = ( questIimit != NULL ) ? -((long)questIimit->mTakeWind) : 0; questInsert->earthpoint = ( questIimit != NULL ) ? -((long)questIimit->mTakeEarth) : 0; questInsert->tutorialindex = 0; if( define->mType == eQUEST_TYPE_TUTORIAL ) { questInsert->tutorialindex = ( questIimit != NULL ) ? questIimit->mTutorialModeIndex : 0; } questInsert->check = check; /// ³²Àº½Ã°£ ¼¼ÆÃ if( questIimit && questIimit->mTimeType != eTIME_NONE ) { questInsert->timeType = questIimit->mTimeType; questInsert->restTime = questIimit->mTime * 1000; } /*-- Á¦°ø ¾ÆÀÌÅÛ */ if( questIimit->mGiveItem ) { sQuestItem* items = questIimit->mGiveItem; for ( unsigned int i0 = 0; i0 < total; i0++, items++ ) { TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefineByIndex( items->itemIndex ); short remainCount = (short)items->count; TB_INVENTORY* inventory; short shortCount; short number; if ( itemDefine != NULL && remainCount > 0 ) { // ¾ÆÀÌÅÛ Äù½ºÆ® Á¦°ø ¾ÆÀÌÅÛ1. °ãÄ¡±â °Ë»ç ¹× ó¸®. if ( FindFirstInventory( itemDefine, &number, remainCount, &shortCount, true ) == true ) { do { inventory = SelectInventory( number ); shortCount = UpdateInventory( inventory, remainCount ); remainCount = remainCount - shortCount; (*table) = (*inventory); table->count = shortCount; table++; rowCount++; } while ( FindNextInventory( itemDefine, &(++number), remainCount, &shortCount, true ) == true ); } // ¾ÆÀÌÅÛ Äù½ºÆ® Á¦°ø ¾ÆÀÌÅÛ2. »ý¼º °Ë»ç ¹× µî·Ï. if ( FindFirstInventory( itemDefine, &number, remainCount, &shortCount, false ) == true ) { do { inventory = CreateInventory( itemDefine, number, remainCount, &(shortCount=0) ); remainCount = remainCount - shortCount; (*table) = (*inventory); table->idx = 0; table->count = shortCount; table++; rowCount++; } while ( FindNextInventory( itemDefine, &(++number), remainCount, &shortCount, false ) == true ); } } } } length += (sizeof(questInsert->inventory) * rowCount); mInventoryDb.reward = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); return ( mInventoryDb.reward ) ? ERROR_QUEST_ADD_SUCCESS : ERROR_QUEST_ADD_FAIL; } // SaveQuestInsertByItem - ÀÇ·Ú¾ÆÀÌÅÛÀ¸·Î Äù½ºÆ® ¹ß±Þ int cPlayer::SaveQuestInsertByItem( ULONG_PTR socketContext, unsigned long characterIdx, unsigned long questIndex, unsigned short number ) { /// 1. Äù½ºÆ® °Ë»ç cQuestDefine* define = QUESTMAN->GetQuestDefine( questIndex ); if( !define ) { NETWORK2->PostServerEvent( "Error(%d): QUEST SaveQuestInsertByItem() - failed to search questIdx", questIndex ); assert(0); return ERROR_QUEST_ADD_FAIL; } TB_INVENTORY* inventory = SelectInventory( number ); if ( IsInventory( inventory ) == false ) return ERROR_QUEST_ADD_ITEMFAIL; /// 2. ¾ÆÀÌÅÛ Á¦°ø üũ - Äù½ºÆ®½ÃÀ۽à Á¦°øÇÒ ¾ÆÀÌÅÛÀ» ¹ÞÀ»¼ö ÀÖ´ÂÁö üũ unsigned long total = 0; cQuestLimit* questIimit = define->mQuestLimit; if( questIimit ) { unsigned int bagCnt = 0; unsigned int questCnt = 0; sQuestItem bagItem[QUEST_ITEM_MAX]; sQuestItem questItem[QUEST_ITEM_MAX]; memset( bagItem, 0, sizeof(bagItem) ); memset( questItem, 0, sizeof(questItem) ); sQuestItem* item = questIimit->mGiveItem; for( int i = 0; i < QUEST_ITEM_MAX; ++i, ++item ) { if( item->itemIndex != 0 && item->count > 0 ) { TB_ITEM_DEFINE* p = ITEMMANAGER->GetItemDefineByIndex( item->itemIndex ); if( p ) { if( p->type == ITEM_QUEST ) { questItem[questCnt].itemIndex = item->itemIndex; questItem[questCnt].count = item->count; questCnt++; } else { bagItem[questCnt].itemIndex = item->itemIndex; bagItem[questCnt].count = item->count; bagCnt++; } // total++; } } } /// °¡¹æ °Ë»ç if( IsItemReward( bagItem, bagCnt, INVENTORY_BAG_BEGIN, mHeroInfo.BagEnd ) < bagCnt ) return ERROR_QUEST_ADD_ITEMFAIL; /// Äù½ºÆ® ÅÇ °Ë»ç if( IsItemReward( questItem, questCnt, INVENTORY_QUEST_BEGIN, INVENTORY_QUEST_END ) < questCnt ) return ERROR_QUEST_ADD_ITEMFAIL; /// °¡¹æ °Ë»ç - ÃÖ´ë º¸À¯°¹¼ö if( IsMaxInventory( bagItem, bagCnt ) == true ) return ERROR_QUEST_ADD_MAX_ITEM; /// Äù½ºÆ® ÅÇ °Ë»ç - ÃÖ´ë º¸À¯°¹¼ö if( IsMaxInventory( questItem, questCnt ) == true ) return ERROR_QUEST_ADD_MAX_ITEM; } /// Äù½ºÆ® »ðÀԽà ó¸® __int64 check = 0; cQuestDuty* duty = define->mQuestDuty; if( duty ) { for( int i = 0; i < MAX_DUTY; ++i ) { if( duty->mDuty[i].dutyType == eDUTY_MEET ) { /// °»½Å __int64 end = 0xFF; for( int e = 0; e < i; ++e ) end = end << 8; /// ÁøÇà»óȲ °»½Å __int64 cnt = 0x01; for( int c = 0; c < i; ++c ) cnt = cnt << 8; check += cnt; break; } } } else { NETWORK2->PostServerEvent( "Error(%d): QUEST SaveQuestInsertByItem() - failed to search duty", questIndex ); return ERROR_QUEST_ADD_FAIL; } /// 3. sql È£Ãâ HANDLE handle = NULL; QUEST_INSERT* questInsert = (QUEST_INSERT*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_QUEST_INSERTBYITEM ); long& rowCount = questInsert->rowCount; TB_INVENTORY* table = questInsert->inventory; unsigned long length = sizeof(QUEST_INSERT) - sizeof(questInsert->inventory); short shortCount; questInsert->characterIdx = characterIdx; questInsert->questIdx = questIndex; questInsert->check = check; questInsert->timeType = eTIME_NONE; questInsert->restTime = 0; questInsert->takemoney = ( questIimit != NULL ) ? -((long)questIimit->mTakeMoney) : 0; questInsert->firepoint = ( questIimit != NULL ) ? -((long)questIimit->mTakeFire) : 0; questInsert->waterpoint = ( questIimit != NULL ) ? -((long)questIimit->mTakeWater) : 0; questInsert->windpoint = ( questIimit != NULL ) ? -((long)questIimit->mTakeWind) : 0; questInsert->earthpoint = ( questIimit != NULL ) ? -((long)questIimit->mTakeEarth) : 0; questInsert->tutorialindex = 0; if( define->mType == eQUEST_TYPE_TUTORIAL ) { questInsert->tutorialindex = ( questIimit != NULL ) ? questIimit->mTutorialModeIndex : 0; } /// »ç¿ëÇÒ ¾ÆÀÌÅÛ shortCount = UpdateInventory( inventory, (-1) ); table->idx = inventory->idx; table->itemDefineIdx = inventory->itemDefineIdx; table->itemDefineIndex = inventory->itemDefineIndex; table->number = inventory->number; table->count = shortCount; table++; rowCount++; /// °¹¼ö°¡ 0°³ÀÌ¸é ¿ÏÀü »èÁ¦¹Ç·Î, ¼­¹öÁ¤º¸ ¹Ì¸® »èÁ¦ if( inventory->count == 0 ) RemoveInventory( inventory ); /*-- Á¦°ø ¾ÆÀÌÅÛ */ if( questIimit->mGiveItem ) { sQuestItem* items = questIimit->mGiveItem; for ( unsigned int i0 = 0; i0 < total; i0++, items++ ) { TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefineByIndex( items->itemIndex ); short remainCount = (short)items->count; if ( itemDefine != NULL && remainCount > 0 ) { TB_INVENTORY* inventory; short shortCount; short number; // ¾ÆÀÌÅÛ Äù½ºÆ® Á¦°ø ¾ÆÀÌÅÛ1. °ãÄ¡±â °Ë»ç ¹× ó¸®. if ( FindFirstInventory( itemDefine, &number, remainCount, &shortCount, true ) == true ) { do { inventory = SelectInventory( number ); shortCount = UpdateInventory( inventory, remainCount ); remainCount = remainCount - shortCount; (*table) = (*inventory); table->count = shortCount; table++; rowCount++; } while ( FindNextInventory( itemDefine, &(++number), remainCount, &shortCount, true ) == true ); } // ¾ÆÀÌÅÛ Äù½ºÆ® Á¦°ø ¾ÆÀÌÅÛ2. »ý¼º °Ë»ç ¹× µî·Ï. if ( FindFirstInventory( itemDefine, &number, remainCount, &shortCount, false ) == true ) { do { inventory = CreateInventory( itemDefine, number, remainCount, &(shortCount=0) ); remainCount = remainCount - shortCount; (*table) = (*inventory); table->idx = 0; table->count = shortCount; table++; rowCount++; } while ( FindNextInventory( itemDefine, &(++number), remainCount, &shortCount, false ) == true ); } } } } length += (sizeof(questInsert->inventory) * rowCount); mInventoryDb.reward = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); return ( mInventoryDb.reward ) ? ERROR_QUEST_ADD_SUCCESS : ERROR_QUEST_ADD_FAIL; } // SaveQuestDelete - Äù½ºÆ® ÀÚü¸¦ Æ÷±â ½ÃŲ´Ù bool cPlayer::SaveQuestDelete( ULONG_PTR socketContext, MSG_REQ_QUEST_DEL* msg, unsigned long dbIdx ) { /// Äù½ºÆ® À¯È¿¼º °Ë»ç cQuestDefine* define = QUESTMAN->GetQuestDefine( msg->questIndex ); if( !define ) { NETWORK2->PostServerEvent( "Error(%d): QUEST SaveQuestDelete() - failed to search questIdx", msg->questIndex ); assert(0); return false; } if( msg->arrayIdx < 0 || msg->arrayIdx >= MAX_KEEPQUEST ) return false; /// ÀÌ¹Ì ÁøÇà¿Ï·áµÈ Äù½ºÆ®ÀÎÁö °Ë»ç if( mQuest[msg->arrayIdx].status != eQUEST_PLAYING ) return false; /// ȸ¼öÇØ¾ßÇÒ ¾ÆÀÌÅÛ ¸ñ·Ï ¸¸µé±â - Äù½ºÆ® Æ÷±â·ÎÀÎÇÑ È¸¼ö // count = 0 : ÇÑ ½½·ÔÀÇ ÇØ´ç ¾ÆÀÌÅÛ Àüü »èÁ¦ // count = x : Àüü ¹üÀ§Áß x °³¸¸Å­ »èÁ¦ // Äù½ºÆ®¾ÆÀÌÅÛÀº ºÐ¸®°¡ ¾ÈµÇ°í, capacity °¡ ȹµæ°¹¼öº¸´Ù Å©´Ù´Â ÀüÁ¦ÇÏ¿¡, // count ¸¦ 0 À¸·Î ¼¼ÆÃÇØ¼­ ½½·Ô ÀÚü »èÁ¦¸¦ Çϵµ·Ï ÇÑ´Ù sQuestItem takeList[MAX_DUTY+QUEST_ITEM_MAX]; memset( takeList, 0, sizeof(takeList) ); unsigned int takeCnt = 0; cQuestDuty* duty = define->mQuestDuty; if( duty != NULL ) { for ( int i = 0; i < MAX_DUTY; ++i ) { if( duty->mDuty[i].dutyType == eDUTY_COLLECT ) { // ÀÏ¹Ý ¾ÆÀÌÅÛÀΰæ¿ì ȸ¼öÇÏÁö ¾Ê´Â´Ù TB_ITEM_DEFINE* define = ITEMMANAGER->GetItemDefineByIndex( duty->mDuty[i].targetIdx ); PerItemCount* itemCount = ITEMCOUNTPOOL->SearchItemCount( &mItemCountRoot, duty->mDuty[i].targetIdx ); if( define && define->type == ITEM_QUEST && itemCount != NULL ) { takeList[takeCnt].itemIndex = duty->mDuty[i].targetIdx; takeList[takeCnt].count = itemCount->bag; // Äù½ºÆ®¾ÆÀÌÅÛÀ¸·Î Àüü »èÁ¦ takeCnt++; } } } } /// Á¦°øÇÑ ¾ÆÀÌÅÛ È¸¼ö - Àִ¸¸Å­ ȸ¼ö if( define->mQuestEnd ) { cQuestEnd* questEnd = define->mQuestEnd; for( int i = 0; i < QUEST_ITEM_MAX; ++i ) { unsigned long itemIndex = questEnd->mTakeItem[i].itemIndex; unsigned long count = questEnd->mTakeItem[i].count; PerItemCount* itemCount = ITEMCOUNTPOOL->SearchItemCount( &mItemCountRoot, itemIndex ); if( itemIndex > 0 && count > 0 && itemCount != NULL ) { // ¾ÆÀÌÅÛÀÌ Á¸ÀçÇϸé ÀÖ´Â °¹¼ö¸¸Å­ ȸ¼ö takeList[takeCnt].itemIndex = itemIndex; takeList[takeCnt].count = ( (long)count > (itemCount->bag+itemCount->equip) ) ? (itemCount->bag+itemCount->equip) : count; takeCnt++; } } } /// HANDLE handle = NULL; QUEST_DELETE* questDelete = (QUEST_DELETE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_QUEST_DELETE ); long& rowCount = questDelete->rowCount; TB_INVENTORY* table = questDelete->table; unsigned long length = sizeof(QUEST_DELETE) - sizeof(questDelete->table); // Äù½ºÆ® Æ÷±â questDelete->idx = dbIdx; questDelete->arrIdx = msg->arrayIdx; questDelete->characterIdx = mObject.index; // ȸ¼ö ¾ÆÀÌÅÛ sQuestItem* items = takeList; TB_INVENTORY* tempInv; short remainCount; bool endLoop; for ( unsigned int i0 = 0; i0 < takeCnt; i0++, items++ ) { tempInv = SelectInventory( INVENTORY_BAG0_BEGIN ); remainCount = (short)items->count; endLoop = false; for ( int i1 = INVENTORY_BAG0_BEGIN; (i1 <= INVENTORY_QUEST_END) && (endLoop == false); i1++, tempInv++ ) { if ( tempInv->itemDefineIndex == (long)items->itemIndex ) { short shortCount; table->idx = tempInv->idx; table->itemDefineIdx = tempInv->itemDefineIdx; table->itemDefineIndex = tempInv->itemDefineIndex; table->number = tempInv->number; table->seal = tempInv->seal; if ( remainCount > 0 ) { shortCount = UpdateInventory( tempInv, (-remainCount) ); remainCount = remainCount + shortCount; if ( !(remainCount > 0) ) endLoop = true; } else { shortCount = UpdateInventory( tempInv, (-tempInv->count) ); endLoop = true; } table->count = shortCount; table++; rowCount++; } } } length += (sizeof(questDelete->table) * rowCount); mInventoryDb.take = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); return mInventoryDb.take; } bool cPlayer::SaveQuestDeleteAuto( ULONG_PTR socketContext, MSG_REQ_QUEST_DELAUTO* msg, unsigned long dbIdx ) { /// Äù½ºÆ® À¯È¿¼º °Ë»ç cQuestDefine* define = QUESTMAN->GetQuestDefine( msg->questIndex ); if( !define ) { NETWORK2->PostServerEvent( "Error(%d): QUEST SaveQuestDelete() - failed to search questIdx", msg->questIndex ); assert(0); return false; } if( msg->arrayIdx < 0 || msg->arrayIdx >= MAX_KEEPQUEST ) return false; /// ÀÌ¹Ì ÁøÇà¿Ï·áµÈ Äù½ºÆ®ÀÎÁö °Ë»ç if( mQuest[msg->arrayIdx].status != eQUEST_PLAYING ) return false; /// ¼öÁý ¾ÆÀÌÅÛ È¸¼ö sQuestItem takeList[MAX_DUTY+QUEST_ITEM_MAX]; memset( takeList, 0, sizeof(takeList) ); unsigned int takeCnt = 0; cQuestDuty* duty = define->mQuestDuty; if( duty != NULL ) { for ( int i = 0; i < MAX_DUTY; ++i ) { if( duty->mDuty[i].dutyType == eDUTY_COLLECT ) { // ÀÏ¹Ý ¾ÆÀÌÅÛÀΰæ¿ì ȸ¼öÇÏÁö ¾Ê´Â´Ù TB_ITEM_DEFINE* define = ITEMMANAGER->GetItemDefineByIndex( duty->mDuty[i].targetIdx ); PerItemCount* itemCount = ITEMCOUNTPOOL->SearchItemCount( &mItemCountRoot, duty->mDuty[i].targetIdx ); if( define && define->type == ITEM_QUEST && itemCount != NULL ) { takeList[takeCnt].itemIndex = duty->mDuty[i].targetIdx; takeList[takeCnt].count = itemCount->bag; // Äù½ºÆ®¾ÆÀÌÅÛÀ¸·Î Àüü »èÁ¦ takeCnt++; } } } } /// Á¦°øÇÑ ¾ÆÀÌÅÛ È¸¼ö - Àִ¸¸Å­ ȸ¼ö cQuestEnd* questEnd = define->mQuestEnd; if( questEnd ) { for( int i = 0; i < QUEST_ITEM_MAX; ++i ) { unsigned long itemIndex = questEnd->mTakeItem[i].itemIndex; unsigned long count = questEnd->mTakeItem[i].count; PerItemCount* itemCount = ITEMCOUNTPOOL->SearchItemCount( &mItemCountRoot, itemIndex ); if( itemIndex > 0 && count > 0 && itemCount != NULL ) { // ¾ÆÀÌÅÛÀÌ Á¸ÀçÇϸé ÀÖ´Â °¹¼ö¸¸Å­ ȸ¼ö takeList[takeCnt].itemIndex = itemIndex; takeList[takeCnt].count = ( (long)count > (itemCount->bag+itemCount->equip) ) ? (itemCount->bag+itemCount->equip) : count; takeCnt++; } } } /// HANDLE handle = NULL; QUEST_DELETE* questDelete = (QUEST_DELETE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_QUEST_DELETEAUTO ); long& rowCount = questDelete->rowCount; TB_INVENTORY* table = questDelete->table; unsigned long length = sizeof(QUEST_DELETE) - sizeof(questDelete->table); // Äù½ºÆ® Æ÷±â questDelete->idx = dbIdx; questDelete->arrIdx = msg->arrayIdx; questDelete->characterIdx = mObject.index; /*-- ȸ¼ö ¾ÆÀÌÅÛ */ sQuestItem* items = takeList; TB_INVENTORY* tempInv; short remainCount; bool endLoop; for ( unsigned int i0 = 0; i0 < takeCnt; i0++, items++ ) { tempInv = SelectInventory( INVENTORY_BAG0_BEGIN ); remainCount = (short)items->count; endLoop = false; for ( int i1 = INVENTORY_BAG0_BEGIN; (i1 <= INVENTORY_QUEST_END) && (endLoop == false); i1++, tempInv++ ) { if ( tempInv->itemDefineIndex == (long)items->itemIndex ) { short shortCount; table->idx = tempInv->idx; table->itemDefineIdx = tempInv->itemDefineIdx; table->itemDefineIndex = tempInv->itemDefineIndex; table->number = tempInv->number; table->seal = tempInv->seal; if ( remainCount > 0 ) { shortCount = UpdateInventory( tempInv, (-remainCount) ); remainCount = remainCount + shortCount; if ( !(remainCount > 0) ) endLoop = true; } else { shortCount = UpdateInventory( tempInv, (-tempInv->count) ); endLoop = true; } table->count = shortCount; table++; rowCount++; } } } length += (sizeof(questDelete->table) * rowCount); mInventoryDb.take = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); return mInventoryDb.take; } /// SaveQuestComplete Method. int cPlayer::SaveQuestComplete( ULONG_PTR socketContext, MSG_REQ_NPC_QUEST_COMPLETE* msg, unsigned long dbIdx ) { cQuestDefine* define = QUESTMAN->GetQuestDefine( msg->questIndex ); if( !define ) { NETWORK2->PostServerEvent( "Error(%d): QUEST SaveQuestComplete() - failed to search questIdx", msg->questIndex ); assert(0); return ERROR_QUEST_COMPLETE_FAIL; } if( msg->arrayIdx < 0 || msg->arrayIdx >= MAX_KEEPQUEST ) return ERROR_QUEST_COMPLETE_FAIL; /// ½Ã°£ Á¦ÇÑÄù½ºÆ®ÀÏ °æ¿ì ½Ã°£ °Ë»ç cQuestLimit* limit = define->mQuestLimit; if( limit && limit->mTimeType != eTIME_NONE ) { long startTime = mQuest[msg->arrayIdx].startTime; long restTime = mQuest[msg->arrayIdx].restTime; long accTime = NETWORK2->GetAccumTime(); /// Áö³­½Ã°£ > ³²Àº½Ã°£ : ½Ã°£¿À¹ö if( accTime - startTime > restTime ) return ERROR_QUEST_COMPLETE_TIME; } /// ÀÌ¹Ì ÁøÇà¿Ï·áµÈ Äù½ºÆ®ÀÎÁö °Ë»ç if( mQuest[msg->arrayIdx].status != eQUEST_PLAYING ) { if( mQuest[msg->arrayIdx].status == eQUEST_COMPLETE ) return ERROR_QUEST_COMPLETE_ALREADY; else return ERROR_QUEST_COMPLETE_FAIL; } /// ¼öÁý Àǹ« ¾ÆÀÌÅÛ È¸¼ö sQuestItem takeList[MAX_DUTY+QUEST_ITEM_MAX]; memset( takeList, 0, sizeof(takeList) ); unsigned int takeCnt = 0; cQuestDuty* duty = define->mQuestDuty; if ( duty != NULL ) { for ( int i = 0; i < MAX_DUTY; ++i ) { if ( duty->mDuty[i].dutyType == eDUTY_COLLECT ) { takeList[takeCnt].itemIndex = duty->mDuty[i].targetIdx; takeList[takeCnt].count = duty->mDuty[i].count; takeCnt++; } } } /// Á¦°øÇÑ ¾ÆÀÌÅÛ È¸¼ö cQuestEnd* questEnd = define->mQuestEnd; if( questEnd ) { for( int i = 0; i < QUEST_ITEM_MAX; ++i ) { unsigned long itemIndex = questEnd->mTakeItem[i].itemIndex; unsigned long count = questEnd->mTakeItem[i].count; if( itemIndex > 0 && count > 0 ) { takeList[takeCnt].itemIndex = itemIndex; takeList[takeCnt].count = count; takeCnt++; } } } // °Ë»ç - ȸ¼ö ¾ÆÀÌÅÛ. if ( IsItemTake( takeList, takeCnt ) < takeCnt ) return ERROR_QUEST_COMPLETE_TAKE; // DATABASE - Äù½ºÆ® ¿Ï·á ó¸®. HANDLE handle = NULL; QUEST_COMPLETE* questComplete = (QUEST_COMPLETE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_QUEST_COMPLETE ); long& rowCount = questComplete->rowCount; TB_INVENTORY* table = questComplete->table; unsigned long length = sizeof(QUEST_COMPLETE) - sizeof(questComplete->table); /*-- Äù½ºÆ® ¿Ï·á */ questComplete->idx = dbIdx; questComplete->arrIdx = msg->arrayIdx; questComplete->characterIdx = mObject.index; questComplete->repeatType = define->mRepeatType; questComplete->check = mQuest[msg->arrayIdx].check; questComplete->tutorialIndex = 0; // Æ©Å丮¾ó º¯°æÀ妽º if( define->mType == eQUEST_TYPE_TUTORIAL ) { questComplete->tutorialIndex = ( questEnd ) ? questEnd->mTutorialModeIndex : 0; } /*-- ȸ¼ö ¾ÆÀÌÅÛ */ sQuestItem* items = takeList; TB_INVENTORY* tempInv; int remainCount; bool endLoop; for ( unsigned int i0 = 0; i0 < takeCnt; i0++, items++ ) { tempInv = SelectInventory( INVENTORY_BAG0_BEGIN ); remainCount = items->count; endLoop = false; for ( int i1 = INVENTORY_BAG0_BEGIN; (i1 <= INVENTORY_QUEST_END) && (endLoop == false); i1++, tempInv++ ) { if ( tempInv->itemDefineIndex == (long)items->itemIndex ) { short shortCount; table->idx = tempInv->idx; table->itemDefineIdx = tempInv->itemDefineIdx; table->itemDefineIndex = tempInv->itemDefineIndex; table->number = tempInv->number; table->seal = tempInv->seal; if ( remainCount > 0 ) { shortCount = UpdateInventory( tempInv, (short)(-remainCount) ); remainCount = remainCount + shortCount; if ( !(remainCount > 0) ) endLoop = true; } else { shortCount = UpdateInventory( tempInv, (-tempInv->count) ); endLoop = true; } table->count = shortCount; table++; rowCount++; } } } length += (sizeof(questComplete->table) * rowCount); mInventoryDb.reward = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); return ( mInventoryDb.reward ) ? ERROR_QUEST_COMPLETE_SUCCESS : ERROR_QUEST_COMPLETE_FAIL; } /// SaveQuestReward Method. int cPlayer::SaveQuestReward( ULONG_PTR socketContext, MSG_REQ_NPC_QUEST_REWARD* msg, unsigned long dbIdx ) { cQuestDefine* define = QUESTMAN->GetQuestDefine( msg->questIndex ); if( !define ) { NETWORK2->PostServerEvent( "Error(%d): QUEST SaveQuestReward() - failed to search questIdx", msg->questIndex ); assert(0); return ERROR_QUEST_REWARD_FAIL; } if( msg->arrayIdx < 0 || msg->arrayIdx >= MAX_KEEPQUEST ) return ERROR_QUEST_REWARD_FAIL; /// ÁøÇà¿Ï·áµÈ Äù½ºÆ®ÀÎÁö °Ë»ç if( mQuest[msg->arrayIdx].status != eQUEST_COMPLETE ) return ERROR_QUEST_REWARD_COMPLETE; /// ¸¸±âÀÏ °è»ê /// ½Ã°£ ÁöÁ¤ Äù½ºÆ®ÀÎ °æ¿ì, TIMESTAMP_STRUCT validTime; memset( &validTime, 0, sizeof(validTime) ); if( define->mEventType == eQUEST_TIMEEVENT ) { validTime = TRIGGERMAN->GetValidTime( msg->questIndex ); } /// Á¦°ø ¾ÆÀÌÅÛ ÃÑ ¸ñ·Ï sQuestItem itemList[QUEST_ITEM_MAX]; unsigned int listCnt = 0; // ±âº»º¸»ó ¾ÆÀÌÅÛ ¸ñ·Ï cQuestReward* defaultReward = define->mDefaultReward; if ( defaultReward ) { sQuestItem* item = defaultReward->mRewardItem; for( int i = 0; i < QUEST_ITEM_MAX; ++i, ++item ) { if( item->itemIndex != 0 && item->count > 0 ) { itemList[ listCnt ].itemIndex = item->itemIndex; itemList[ listCnt ].count = item->count; listCnt++; } } } // ¼±Åà º¸»ó ó¸® if( define->mSelectReward && define->mSelectCount > 0 ) { /// °Ë»ç - ¼±Åà °¹¼ö °Ë»ç if( define->mSelectCount != msg->rowCount ) return ERROR_QUEST_REWARD_COUNT; for ( unsigned int i = 0; i < msg->rowCount; ++i ) { sRewardData& data = msg->table[i]; if( data.type != eREWARD_ITEM ) continue; /// ¼±Åú¸»ó ã±â int count = QUESTMAN->IsSelectRewardItem( msg->questIndex, data.index ); if( count == 0 ) continue; itemList[ listCnt ].itemIndex = data.index; itemList[ listCnt ].count = count; listCnt++; } } // if ( !(msg->rowCount < QUEST_BUFF_MAX) ) return ERROR_QUEST_REWARD_FAIL; // °Ë»ç - º¸»ó ±Ý ¾× . if( defaultReward ) { if ( IsAddMoney( defaultReward->mMoney ) == false ) return ERROR_QUEST_REWARD_MONEY; } // °Ë»ç - º¸»ó ¾ÆÀÌÅÛ. if ( IsItemReward( itemList, listCnt, INVENTORY_BAG_BEGIN, mHeroInfo.BagEnd ) < listCnt ) return ERROR_QUEST_REWARD_ITEM; // °Ë»ç - ÃÖ´ë º¸À¯°¹¼ö Á¦ÇÑ if( IsMaxInventory( itemList, listCnt ) == true ) return ERROR_QUEST_REWARD_MAX_ITEM; // DATABASE - Äù½ºÆ® º¸»ó ó¸®. HANDLE handle = NULL; QUEST_REWARD* questReward = (QUEST_REWARD*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_QUEST_REWARD ); long& itemRowCount = questReward->itemRowCount; TB_INVENTORY* table = questReward->table; unsigned long length = sizeof(QUEST_REWARD) - sizeof(questReward->skillClassIdx); /*-- Äù½ºÆ® ¿Ï·á --*/ questReward->idx = dbIdx; questReward->arrIdx = msg->arrayIdx; questReward->characterIdx = mObject.index; questReward->thru = validTime; /*-- º¸»ó ±Ý ¾× --*/ questReward->characterMoney = ( defaultReward ) ? defaultReward->mMoney : 0; /*-- º¸»ó Àü Á÷ ( ±âº» º¸»ó¸¸ °¡´É ) --*/ questReward->jobIdx = ( defaultReward ) ? defaultReward->mChangeJobIndex : 0; questReward->race = mPlayerInfo.Race; if( defaultReward && defaultReward->mChangeJobIndex != 0 ) questReward->jobStep = STATUSSCRIPT->GetJobStep( defaultReward->mChangeJobIndex ); else questReward->jobStep = 0; /*-- º¸»ó ½º ų ( ±âº» º¸»ó¸¸ °¡´É ) --*/ questReward->skillPoint = ( defaultReward ) ? defaultReward->mSkillPoint : 0; /*-- º¸»ó ¼¼ ·Â ( ±âº» º¸»ó¸¸ °¡´É ) --*/ questReward->forceType = ( defaultReward ) ? defaultReward->mForceType : 0; /*-- º¸»ó È£ Ī ( ±âº» º¸»ó¸¸ °¡´É ) --*/ questReward->titleIdx = ( defaultReward ) ? defaultReward->mGiveTitleIndex : 0; /*-- ¼±Åà º¸ »ó (¹ö ÇÁ) --*/ int buffCnt = 0; for( unsigned int i = 0; i < msg->rowCount; ++i ) { sRewardData& data = msg->table[i]; if( data.type != eREWARD_SKILL ) continue; bool ret = QUESTMAN->IsSelectRewardBuff( msg->questIndex, data.index ); if( ret == true ) { questReward->bufIndex[ buffCnt ] = data.index; buffCnt++; } } questReward->bufRowCount = buffCnt; /*-- º¸»ó ¾ÆÀÌÅÛ --*/ sQuestItem* items = itemList; for ( unsigned int i0 = 0; i0 < listCnt; i0++, items++ ) { TB_ITEM_DEFINE* itemDefine = ITEMMANAGER->GetItemDefineByIndex( items->itemIndex ); short remainCount = (short)items->count; TB_INVENTORY* tempInv; short shortCount; short number; if ( itemDefine != NULL && remainCount > 0 ) { // ¾ÆÀÌÅÛ Äù½ºÆ® º¸»ó. °ãÄ¡±â °Ë»ç ¹× ó¸®. if ( FindFirstInventory( itemDefine, &number, remainCount, &shortCount, true ) == true ) { do { tempInv = SelectInventory( number ); shortCount = UpdateInventory( tempInv, remainCount ); remainCount = remainCount - shortCount; (*table) = (*tempInv); table->count = shortCount; table++; itemRowCount++; } while ( FindNextInventory( itemDefine, &(++number), remainCount, &shortCount, true ) == true ); } // ¾ÆÀÌÅÛ Äù½ºÆ® º¸»ó. »ý¼º °Ë»ç ¹× µî·Ï. if ( FindFirstInventory( itemDefine, &number, remainCount, &shortCount, false ) == true ) { do { tempInv = CreateInventory( itemDefine, number, remainCount, &(shortCount=0) ); remainCount = remainCount - shortCount; (*table) = (*tempInv); table->idx = 0; table->count = shortCount; table++; itemRowCount++; } while ( FindNextInventory( itemDefine, &(++number), remainCount, &shortCount, false ) == true ); } } } mInventoryDb.reward = NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, length ); return ( mInventoryDb.reward ) ? ERROR_QUEST_REWARD_SUCCESS : ERROR_QUEST_REWARD_FAIL; } // Äù½ºÆ® °ü·Ã µå¶øÇؾßÇÒ ¾ÆÀÌÅÛ °¹¼ö ȹµæ unsigned int cPlayer::GetDropItemCount( unsigned int arrIdx, unsigned long itemIdx ) { if( arrIdx < 0 || arrIdx >= MAX_KEEPQUEST ) return 0; if( mQuest[arrIdx].idx == 0 ) return 0; cQuestDefine* define = QUESTMAN->GetQuestDefine( mQuest[arrIdx].questIdx ); if ( !define ) { NETWORK2->PostServerEvent( "Error(%d): QUEST GetDropItemCount() - failed to search questIdx", mQuest[arrIdx].questIdx ); assert(0); return 0; } /// ÇØ´ç Äù½ºÆ®ÀÇ Àǹ«Áß, ã´Â ¾ÆÀÌÅÛÀÌ ÀÖ´ÂÁö ã¾Æ¼­, ÀÖÀ¸¸é ÇÊ¿ä °¹¼ö¸¦ ¸®ÅÏÇÑ´Ù cQuestDuty* duty = define->mQuestDuty; if ( duty == NULL ) return 0; /// µ¿ÀÏÇÑ ¾ÆÀÌÅÛÀ» ã¾Æ °¹¼ö ¼¼ÆÃ unsigned int count = 0; int num = 0; for( int i = 0; i < MAX_DUTY; ++i ) { if( duty->mDuty[i].dutyType == eDUTY_COLLECT && duty->mDuty[i].targetIdx == itemIdx ) { count = duty->mDuty[i].count; num = i; break; } } /// Çʿ䰹¼ö°¡ 0 ÀÌ»óÀ̸é, ½ÇÁ¦ °¡Áö°íÀÖ´Â °¹¼ö¿Í ºñ±³ÇÑ´Ù if( count > 0 ) { TB_QUEST_PROGRESS* quest = mQuest + arrIdx; /// ÀÌ¹Ì ¿Ï·áµÈ Äù½ºÆ®À̸é Çʿ䰹¼ö 0 if( quest->check == define->mComplete ) return 0; __int64 end = 0xFF; for( int e = 0; e < num; ++e ) end = end << 8; /// ÇØ´ç Àǹ«°¡ ¿Ï·áÀ̸é Çʿ䰹¼ö 0 if( (quest->check & end) == (define->mComplete & end) ) return 0; /// ¹Ì¿Ï·áÀ̸é Çʿ䰹¼ö ºñ±³ °Ë»ç __int64 itemCount = (define->mComplete & end) - (quest->check & end); for( int c = 0; c < num; ++c ) itemCount = itemCount >> 8; count = (unsigned int)itemCount; } return count; } bool cPlayer::SetCheatHideMode( bool mode ) { if( mode == mCheatHideMode ) return false; if ( mode ) { GRIDMANAGER->SetHidePlayer( this, mode ); mCheatHideMode = mode; } else { mCheatHideMode = mode; GRIDMANAGER->SetHidePlayer( this, mode ); } return true; } void cPlayer::CheatRecover() { InitHP( GetMaxHP() ); InitMP( GetMaxMP() ); //if( ChangeState( eOBJECT_STATE_IDLE, true ) == false ) //{ // assert(NULL); // NETWORK2->PostServerEvent("Player[%d] CheatRebirth ChangeState( eOBJECT_STATE_IDLE, true ) == false", mObject.index ); //} //mSkillResurrectionHP = 0; //mSkillResurrectionMP = 0; //mIsSkillResurrection = false; } void cPlayer::CheatRebirth() { InitHP( GetMaxHP() ); InitMP( GetMaxMP() ); if( ChangeState( eOBJECT_STATE_IDLE, eCHANGESTATEOPTION_RESURRECTION ) == false ) { assert(NULL); NETWORK2->PostServerEvent("Player[%d] CheatRebirth ChangeState( eOBJECT_STATE_IDLE, true ) == false", mObject.index ); } mSkillResurrectionHP = 0; mSkillResurrectionMP = 0; mIsSkillResurrection = false; } void cPlayer::CheatStop( unsigned long duration ) { int error = ERROR_CHEAT_STOP_FAIL; /// Á¤Áö »óÅ º¯°æ if( ChangeState( eOBJECT_STATE_STOP ) == true ) { SetStateStop( eSTOP_CHEATSTOP ); error = ERROR_CHEAT_STOP_SUCCESS; mCheatStopDuration = NETWORK2->GetAccumTime() + duration; SetCheatUndeadMode( true ); } /// Á¤Áö ¸Þ¼¼Áö ¹ß¼Û NETWORK2->SendMsgError( mConnectionIdx, NM_CHEAT, NM_CHEAT_STOP_RES, error ); /// ¼º°ø½Ã ½ÌÅ© ¹ß¼Û if( error == ERROR_CHEAT_STOP_SUCCESS ) { /// µ¿±â MSG_SYN_CHEAT_STOP syn; syn.Category = NM_CHEAT; syn.Protocol = NM_CHEAT_STOP_SYN; syn.mObjIndex = mObject.index; NETWORK2->QuickSend( this, (char*)&syn, sizeof(syn) ); } } void cPlayer::CheatCancelStop() { int error = ERROR_CHEAT_STOP_FAIL; if( GetStateStop() == eSTOP_CHEATSTOP ) { /// Á¤Áö »óÅÂ ÇØÁ¦ if( ChangeState( eOBJECT_STATE_IDLE ) == false ) { assert(NULL); NETWORK2->PostServerEvent("cPlayer::CheatCancelStop[%d][%d,%d] State ERROR", mObject.index, GetState(), GetStateStop() ); } SetStateStop( eSTOP_NONE ); error = ERROR_CHEAT_STOP_SUCCESS; mCheatStopDuration = 0; SetCheatUndeadMode( false ); } else return; //error = ERROR_CHEAT_STOP_NOT; /// Á¤Áö ÇØÁ¦ ¸Þ¼¼Áö ¹ß¼Û NETWORK2->SendMsgError( mConnectionIdx, NM_CHEAT, NM_CHEAT_CANCEL_STOP_RES, error ); /// ¼º°ø½Ã ½ÌÅ© ¹ß¼Û if( error == ERROR_CHEAT_STOP_SUCCESS ) { /// µ¿±â MSG_SYN_CHEAT_CANCEL_STOP syn; syn.Category = NM_CHEAT; syn.Protocol = NM_CHEAT_CANCEL_STOP_SYN; syn.mObjIndex = mObject.index; NETWORK2->QuickSend( this, (char*)&syn, sizeof(syn) ); } } void cPlayer::SetCheatSpeedUp( unsigned long speedUp ) { if( speedUp >= eCHEATSPEEDUP_MAX ) return; mCheatSpeedUp = (eCHEAT_SPEEDUP)speedUp; STATUSCALC->CalcPlayerExtensionGlobal( mObject ); } void cPlayer::CalcCheatSpeedUp() { switch( mCheatSpeedUp ) { case eCHEATSPEEDUP_50UP: mStatus2.mMoveSpeed = mStatus2.mMoveSpeed * 1.5f; break; case eCHEATSPEEDUP_100UP: mStatus2.mMoveSpeed = mStatus2.mMoveSpeed * 2.0f; break; case eCHEATSPEEDUP_150UP: mStatus2.mMoveSpeed = mStatus2.mMoveSpeed * 2.5f; break; case eCHEATSPEEDUP_200UP: mStatus2.mMoveSpeed = mStatus2.mMoveSpeed * 3.0f; break; case eCHEATSPEEDUP_250UP: mStatus2.mMoveSpeed = mStatus2.mMoveSpeed * 3.5f; break; } } /// ȣΰü¸® void cPlayer::ClearHaveTitleList() { mHaveTitleSet.Clear(); } bool cPlayer::AddHaveTitle( unsigned long titleIdx ) { cTitleDefine* define = TITLEMAN->GetTitleDefine( titleIdx ); if( !define ) { assert(0); return false; } if( mHaveTitleSet.Insert( titleIdx ) == false ) { assert(0); return false; } return true; } bool cPlayer::IsHaveTitle( unsigned long titleIdx ) { return mHaveTitleSet.Find( titleIdx ) != mHaveTitleSet.End(); } /// Ŭ¶óÀÌ¾ðÆ®¿¡ º¸À¯È£Äª ¸ñ·Ï send bool cPlayer::SendHaveTitleList( ULONG_PTR socketContext ) { HANDLE handle = NULL; MSG_RES_PLAYER_TITLELIST* sendMsg = (MSG_RES_PLAYER_TITLELIST*)NETWORK2->GetMsgRoot( &handle, (PerSocketContext*)socketContext, NM_PLAYER, NM_PLAYER_TITLE_LIST_RES ); unsigned long length = sizeof(MSG_RES_PLAYER_TITLELIST) - sizeof(sendMsg->mTitleIndex); unsigned long* titleList = sendMsg->mTitleIndex; cHaveTitleSet::cIterator i = mHaveTitleSet.Begin(); cHaveTitleSet::cIterator end = mHaveTitleSet.End(); for( ; i != end; ++i, ++titleList ) { unsigned long idx = (unsigned long)(*i); *titleList = idx; sendMsg->rowCount++; } length += (sendMsg->rowCount * sizeof(sendMsg->mTitleIndex)); return NETWORK2->SendMsgRoot( handle, length ); } /// ÇØ´ç ȣĪ ½î±â void cPlayer::SendHaveTitle( unsigned long titleIdx ) { HANDLE handle = NULL; MSG_RES_PLAYER_TITLEADD* sendMsg = (MSG_RES_PLAYER_TITLEADD*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_TITLE_ADD_RES ); if ( sendMsg !=NULL ) { sendMsg->mTitleIndex = titleIdx; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_PLAYER_TITLEADD) ); } } bool cPlayer::InitTitle() { if( mPlayerExrInfo.mTitleIndex == 0 ) return true; cTitleDefine* define = TITLEMAN->GetTitleDefine( mPlayerExrInfo.mTitleIndex ); if ( !define ) { NETWORK2->PostServerEvent("ERROR InitTitle(%d,%d)", mObject.index, mPlayerExrInfo.mTitleIndex ); assert(0); return false; } if ( define->mInfluenceIndex > 0 ) { unsigned long uniqueIdx = SKILLMANAGER->AddInfSwitch( mObject, mObject, define->mInfluenceIndex, 0, false ); if ( uniqueIdx != 0 ) mTitleUniqIndex = uniqueIdx; else return false; } return true; } /// ÇöÀç ȣĪÀ¸·Î ¼³Á¤ bool cPlayer::ChangeTitle( unsigned long titleIdx ) { if ( mPlayerExrInfo.mTitleIndex == titleIdx ) return true; /// È¿°úÀû¿ë if ( titleIdx > 0 ) { cTitleDefine* define = TITLEMAN->GetTitleDefine( titleIdx ); if ( !define ) { NETWORK2->PostServerEvent("ERROR ChangeTitle(%d,%d)", mObject.index, titleIdx ); assert(0); return false; } unsigned long uniqueIdx = SKILLMANAGER->AddInfSwitch( mObject, mObject, define->mInfluenceIndex, 0, true ); if ( uniqueIdx == 0 ) return false; mTitleUniqIndex = uniqueIdx; } else { SKILLMANAGER->DeleteInfluence( mObject, mTitleUniqIndex ); mTitleUniqIndex = 0; } /// ¼³Á¤ mPlayerExrInfo.mTitleIndex = titleIdx; /// ´Ù¸¥ À¯Àú¿¡°Ô ½î±â MSG_SYN_PLAYER_TITLE_SET sendMsg; ::memset( &sendMsg, 0, sizeof(sendMsg) ); sendMsg.Category = NM_PLAYER; sendMsg.Protocol = NM_PLAYER_TITLE_SET_SYN; sendMsg.mCharacterIndex = GetObjectID(); sendMsg.mTitleIndex = titleIdx; NETWORK2->QuickSendExcept( this, (char*)&sendMsg, sizeof(MSG_SYN_PLAYER_TITLE_SET) ); SendEventQuestList( eQUEST_SETTITLE ); return true; } // Æ©Å丮¾ó ¸ðµå º¯°æ º¸³»±â void cPlayer::SetTutorialMode( int modeIndex, bool send ) { // Æ©Å丮¾ó ¸ÊÀÌ ¾Æ´Ï¸é ó¸®ÇÏÁö ¾Ê´Â´Ù if( NETWORK2->GetInDunMapNum() != MAP_TUTORIAL ) return; mTutorialModeIndex = modeIndex; if( send == true ) { HANDLE handle = NULL; MSG_SYN_TUTORIAL_CHANGEMODE* sendMsg = (MSG_SYN_TUTORIAL_CHANGEMODE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_TUTORIAL, NM_TUTORIAL_CHANGEMODE_SYN ); if ( sendMsg != NULL ) { sendMsg->mModeIndex = modeIndex; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_TUTORIAL_CHANGEMODE) ); } } } void cPlayer::SetPartyIndex( unsigned long idx ) { mPlayerExrInfo.mPartyIndex = idx; MSG_SYN_PLAYER_PARTY_SET sendMsg; ::memset( &sendMsg, 0, sizeof(sendMsg) ); sendMsg.Category = NM_PLAYER; sendMsg.Protocol = NM_PLAYER_PARTY_SET_SYN; sendMsg.mCharacterIndex = GetObjectID(); sendMsg.mPartyIndex = mPlayerExrInfo.mPartyIndex; NETWORK2->QuickSendExcept( this, (char*)&sendMsg, sizeof(MSG_SYN_PLAYER_PARTY_SET) ); } void cPlayer::GetPartyUserData(sPartyUserData* data) { data->userIndex = mObject.index; wcscpy( data->name, mPlayerInfo.strName ); data->job = (unsigned short)mPlayerInfo.Job; data->level = mPlayerInfo.Level; data->mapNum = GetMapDataNumber(); data->roomNum = GetRoomDataNumber(); data->channelNum = NETWORK2->GetChannelNum(); data->posX = mObjectPos.x; data->posY = mObjectPos.y; data->hp = mPlayerExrInfo.RestHP; data->maxhp = mPlayerExrInfo.MaxHP; data->mp = mPlayerExrInfo.RestMP; data->maxmp = mPlayerExrInfo.MaxMP; } void cPlayer::SendPartyDiceStart( ) { NETWORK2->SendMsgRoot( mConnectionIdx, NM_PARTY, NM_PARTY_DICE_START_SYN ); } void cPlayer::SendPartyAddoneSyn(sPartyUserData* userData) { HANDLE handle = NULL; MSG_SYN_PARTY_ADDONE* sendMsg = (MSG_SYN_PARTY_ADDONE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PARTY, NM_PARTY_ADDONE_SYN ); if ( sendMsg != NULL ) { sendMsg->mTable = (*userData); NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_PARTY_ADDONE) ); } } void cPlayer::SendPartyOutSyn(unsigned long playerIdx) { HANDLE handle = NULL; MSG_SYN_PARTY_OUT* sendMsg = (MSG_SYN_PARTY_OUT*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PARTY, NM_PARTY_OUT_SYN ); if ( sendMsg != NULL ) { sendMsg->UserIndex = playerIdx; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_PARTY_OUT) ); } } void cPlayer::SendPartyThrowSyn(unsigned long playerIdx) { HANDLE handle = NULL; MSG_SYN_PARTY_THROW* sendMsg = (MSG_SYN_PARTY_THROW*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PARTY, NM_PARTY_THROW_SYN ); if ( sendMsg != NULL ) { sendMsg->UserIndex = playerIdx; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_PARTY_THROW) ); } } void cPlayer::SendPartyLeaderSyn(unsigned long leaderIdx) { HANDLE handle = NULL; MSG_SYN_PARTY_CHANGELEADER* sendMsg = (MSG_SYN_PARTY_CHANGELEADER*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PARTY, NM_PARTY_CHANGELEADER_SYN ); if ( sendMsg != NULL ) { sendMsg->UserIndex = leaderIdx; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_PARTY_CHANGELEADER) ); } } void cPlayer::SendPartyDivideType(char type) { HANDLE handle = NULL; MSG_SYN_PARTY_CHANGEDIVDE* sendMsg = (MSG_SYN_PARTY_CHANGEDIVDE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PARTY, NM_PARTY_CHANGEDIVIDE_SYN ); if ( sendMsg != NULL ) { sendMsg->type = type; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_PARTY_CHANGEDIVDE) ); } } void cPlayer::SendPartyDataSyn(unsigned long connectionIdx) { HANDLE handle = NULL; MSG_SYN_PARTY_DATA* sendMsg = (MSG_SYN_PARTY_DATA*)NETWORK2->GetMsgRoot( &handle, connectionIdx, NM_PARTY, NM_PARTY_DATA_SYN ); if ( sendMsg != NULL ) { sendMsg->userIndex = mObject.index; sendMsg->level = mPlayerInfo.Level; sendMsg->maxHP = mPlayerExrInfo.MaxHP; sendMsg->hp = mPlayerExrInfo.RestHP; sendMsg->maxMP = mPlayerExrInfo.MaxMP; sendMsg->mp = mPlayerExrInfo.RestMP; sendMsg->posX = mObjectPos.x; sendMsg->posY = mObjectPos.y; sendMsg->RowCount = 0; // ¹öÇÁ¸®½ºÆ® ´ã±â cSkillInfluenceSet* influenceSet = GetInfluenceSet( ); if ( influenceSet && influenceSet->GetSize( ) > 0 ) { cSkillInfluenceSet::cIterator begin = influenceSet->Begin( ); cSkillInfluenceSet::cIterator end = influenceSet->End( ); short& rowCount = sendMsg->RowCount; sInfluenceClient* table = sendMsg->mTable; cInfluenceObject* object = 0; for ( ; begin != end; ++begin, ++table ) { object = SKILLMANAGER->GetInfluence( (unsigned long)(*begin) ); if ( object != NULL ) { table->mInfluenceClassIdx = object->GetInfluenceClassIdx(); table->mUniqueIdx = object->GetUniqueIdx(); table->mRestTime = 0; rowCount++; } else NETWORK2->PostServerEvent("cPartyManager::SendUpdateParty[%d, %d]", mObject.index, (unsigned long)(*begin) ); } } NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength( ) ); } } void cPlayer::SendPartyDataLevelSyn(unsigned long connectionIdx) { HANDLE handle = NULL; MSG_SYN_PARTYLEVEL_DATA* sendMsg = (MSG_SYN_PARTYLEVEL_DATA*)NETWORK2->GetMsgRoot( &handle, connectionIdx, NM_PARTY, NM_PARTY_DATA_LEVEL_SYN ); if ( sendMsg != NULL ) { sendMsg->userIndex = mObject.index; sendMsg->level = mPlayerInfo.Level; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_PARTYLEVEL_DATA) ); } } void cPlayer::SendPartyDataLevelSyn(unsigned long playerIdx, unsigned char level) { HANDLE handle = NULL; MSG_SYN_PARTYLEVEL_DATA* sendMsg = (MSG_SYN_PARTYLEVEL_DATA*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PARTY, NM_PARTY_DATA_LEVEL_SYN ); if ( sendMsg != NULL ) { sendMsg->userIndex = playerIdx; sendMsg->level = level; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_PARTYLEVEL_DATA) ); } } void cPlayer::SendPartyMapchangeSyn(unsigned long connectionIdx) { HANDLE handle = NULL; MSG_SYN_PARTY_MAPCHANGE* sendMsg = (MSG_SYN_PARTY_MAPCHANGE*)NETWORK2->GetMsgRoot( &handle, connectionIdx, NM_PARTY, NM_PARTY_MAPCHANGE_SYN ); if ( sendMsg != NULL ) { sendMsg->UserIndex = mObject.index; sendMsg->MapNum = GetMapDataNumber(); sendMsg->RoomNum = GetRoomDataNumber(); sendMsg->ChannelNum = NETWORK2->GetChannelNum(); NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_PARTY_MAPCHANGE) ); } } void cPlayer::SendPartyMapchangeSyn(unsigned long playerIdx, short map, short room, DWORD channelnum ) { HANDLE handle = NULL; MSG_SYN_PARTY_MAPCHANGE* sendMsg = (MSG_SYN_PARTY_MAPCHANGE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PARTY, NM_PARTY_MAPCHANGE_SYN ); if ( sendMsg != NULL ) { sendMsg->UserIndex = playerIdx; sendMsg->MapNum = map; sendMsg->RoomNum = room; sendMsg->ChannelNum = channelnum; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_PARTY_MAPCHANGE) ); } } void cPlayer::SendPartyDeleteSyn( ) { NETWORK2->SendMsgRoot( mConnectionIdx, NM_PARTY, NM_PARTY_DELETE_SYN ); } void cPlayer::SetPartyUnionIndex( unsigned long idx ) { mPlayerExrInfo.mPartyUnionIndex = idx; MSG_SYN_PLAYER_PARTYUNION_SET sendMsg; ::memset( &sendMsg, 0, sizeof(sendMsg) ); sendMsg.Category = NM_PLAYER; sendMsg.Protocol = NM_PLAYER_PARTYUNION_SET_SYN; sendMsg.mCharacterIndex = GetObjectID(); sendMsg.mPartyUnionIndex = mPlayerExrInfo.mPartyUnionIndex; NETWORK2->QuickSendExcept( this, (char*)&sendMsg, sizeof(MSG_SYN_PLAYER_PARTYUNION_SET) ); } bool cPlayer::ChangeGuild( unsigned long guildIndex, char position ) { mPlayerExrInfo.mGuildIndex = guildIndex; mPlayerExrInfo.mGuildPosition = position; struct tm initTm; memset( &initTm, 0, sizeof(initTm) ); initTm.tm_year = 1900; initTm.tm_mon = 1; initTm.tm_mday = 1; if( guildIndex == 0 ) { memset( &mPlayerExrInfo.mGuildName, 0, sizeof(mPlayerExrInfo.mGuildName) ); // mPlayerExrInfo.mGuildMarkDate = initTm; mPlayerExrInfo.mUseGuildMark = false; } else { // ±æµå¸í¼³Á¤ wchar_t* name = GUILDMAN->GetGuildName( guildIndex ); wcsncpy( mPlayerExrInfo.mGuildName, name, MAX_GUILDNAME_BUFFER_SIZE ); // ±æµå¸¶Å© ¼³Á¤ GUILDMAN->GetGuildMarkDate( guildIndex, mPlayerExrInfo.mGuildMarkDate, mPlayerExrInfo.mUseGuildMark ); } MSG_SYN_PLAYER_GUILD_SET sendMsg; ::memset( &sendMsg, 0, sizeof(sendMsg) ); sendMsg.Category = NM_PLAYER; sendMsg.Protocol = NM_PLAYER_GUILD_SET_SYN; sendMsg.mCharacterIndex = GetObjectID(); sendMsg.mGuildIndex = guildIndex; sendMsg.mPosition = position; sendMsg.mMarkRegistDate = mPlayerExrInfo.mGuildMarkDate; sendMsg.mUseGuildMark = mPlayerExrInfo.mUseGuildMark; int len = wcslen( mPlayerExrInfo.mGuildName ); if( len > 0 ) wcsncpy( sendMsg.mName, mPlayerExrInfo.mGuildName, MAX_GUILDNAME_BUFFER_SIZE ); NETWORK2->QuickSendExcept( this, (char*)&sendMsg, sizeof(MSG_SYN_PLAYER_GUILD_SET) ); return true; } void cPlayer::ChangeGuildMarkRegistDate() { if( mPlayerExrInfo.mGuildIndex == 0 ) { NETWORK2->PostServerEvent("ERROR ChangeGuildMarkRegistDate(%d), guildIndex == 0", mObject.index ); return; } // ±æµå¸¶Å© ¼³Á¤ GUILDMAN->GetGuildMarkDate( mPlayerExrInfo.mGuildIndex, mPlayerExrInfo.mGuildMarkDate, mPlayerExrInfo.mUseGuildMark ); MSG_SYN_PLAYER_GUILDMARK_CHANGE sendMsg; ::memset( &sendMsg, 0, sizeof(sendMsg) ); sendMsg.Category = NM_PLAYER; sendMsg.Protocol = NM_PLAYER_GUILDMARK_CHANGE_SYN; sendMsg.mCharacterIndex = GetObjectID(); sendMsg.mMarkRegistDate = mPlayerExrInfo.mGuildMarkDate; sendMsg.mUseGuildMark = mPlayerExrInfo.mUseGuildMark; NETWORK2->QuickSend( this, (char*)&sendMsg, sizeof(MSG_SYN_PLAYER_GUILDMARK_CHANGE) ); } void cPlayer::ChangeGuildPosition( char position ) { mPlayerExrInfo.mGuildPosition = position; } void cPlayer::SendGuildConnectSyn( unsigned long characterIdx, BYTE connect, DWORD channelNum ) { HANDLE handle = NULL; MSG_SYN_GUILDUSER_CONNECT* sendMsg = (MSG_SYN_GUILDUSER_CONNECT*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_GUILD, NM_GUILDUSER_CONNECT_SYN ); if( sendMsg != NULL ) { sendMsg->characterIndex = characterIdx; sendMsg->connect = connect; sendMsg->channelNum = channelNum; NETWORK2->SendMsgRoot ( handle, sizeof(MSG_SYN_GUILDUSER_CONNECT) ); } } void cPlayer::GetGuildUserData( sGuildConnect* data ) { data->characterIdx = mObject.index; data->job = (unsigned short)mPlayerInfo.Job; data->level = mPlayerInfo.Level; } unsigned short cPlayer::GetJobUsedSkillPoint( unsigned char jobstep ) { if( jobstep > mJobUsedSpArr.GetSize() ) { assert(0); return 0; } return mJobUsedSpArr[jobstep]; } void cPlayer::AddTargetingMonster( unsigned long monsterIdx ) { mTargetingMonsterSet.Insert( monsterIdx ); } void cPlayer::DelTargetingMonster( unsigned long monsterIdx ) { mTargetingMonsterSet.Erase( monsterIdx ); } void cPlayer::ClearTargetingMonster() { cTargetingMonsterSet::cIterator start = mTargetingMonsterSet.Begin(); cTargetingMonsterSet::cIterator end = mTargetingMonsterSet.End(); while( start != end ) { unsigned long monsterIdx = (*start++); if ( monsterIdx == 0 ) continue; cMonster* mon = GRIDMANAGER->GetMonster( monsterIdx ); //OBJECTMANAGER->GetMonster( monsterIdx ); if ( mon != NULL ) mon->DelTakeDamagePlayer( GetObjectID() ); } mTargetingMonsterSet.Clear(); } void cPlayer::DietargetingMonster() { cTargetingMonsterSet::cIterator start = mTargetingMonsterSet.Begin(); cTargetingMonsterSet::cIterator end = mTargetingMonsterSet.End(); while( start != end ) { unsigned long monsterIdx = (*start++); if ( monsterIdx == 0 ) continue; cMonster* mon = OBJECTMANAGER->GetMonster( monsterIdx ); if ( mon != NULL ) mon->ClearDistressPointPlayer( GetObjectID() ); } } void cPlayer::GetTargetingMonster( tHashSet& monsterSet ) { cTargetingMonsterSet::cIterator start = mTargetingMonsterSet.Begin(); cTargetingMonsterSet::cIterator end = mTargetingMonsterSet.End(); while( start != end ) { unsigned long monsterIdx = (*start++); if ( monsterIdx == 0 ) continue; cMonster* mon = OBJECTMANAGER->GetMonster( monsterIdx ); if ( mon != NULL ) { monsterSet.Insert( monsterIdx ); } } } void cPlayer::HealAttackToMonster( unsigned long healerIdx, unsigned long heal, long distressPoint, eTAKEDAMAGE_TYPE type ) { cTargetingMonsterSet::cIterator start = mTargetingMonsterSet.Begin(); cTargetingMonsterSet::cIterator end = mTargetingMonsterSet.End(); sObject healer = { eOBJECTTYPE_PLAYER, healerIdx }; while( start != end ) { unsigned long monsterIdx = (*start++); if ( monsterIdx == 0 ) continue; cMonster* mon = OBJECTMANAGER->GetMonster( monsterIdx ); if ( mon != NULL ) mon->AddTakeDamage( healer, heal, distressPoint, type ); } } /// DB¿¡ ÀúÀå bool cPlayer::SaveFortuneData(ULONG_PTR socketContext) { HANDLE handle = NULL; FORTUNE_UPDATE* fortuneUpdate = (FORTUNE_UPDATE*)NETWORK2->GetSQL( &handle, SQL_GAME_PROCESS_FORTUNE_UPDATE ); if ( fortuneUpdate != NULL ) { TIMESTAMP_STRUCT* validThru = fortuneUpdate->thru; TIMESTAMP_STRUCT* thru = mFortuneThru; /// Á¤º¸ ´ã±â for ( int i = 0; i < 5; ++i, ++validThru, ++thru ) (*validThru) = (*thru); fortuneUpdate->characterIdx = mObject.index; fortuneUpdate->color = mPlayerExrInfo.mTodayColor; ::wcsncpy( fortuneUpdate->word, mPlayerExrInfo.mTodayWord, MAX_TODAYWORD_BUFFER_SIZE ); } return NETWORK2->SendSQL( (PerSocketContext*)socketContext, handle, sizeof(FORTUNE_UPDATE)); } bool cPlayer::SendInitTodayWord() { if ( wcslen( mPlayerExrInfo.mTodayWord ) > 0 ) { HANDLE handle = NULL; MSG_RES_PLAYER_TODAYWORD_CHANGE* sendMsg = (MSG_RES_PLAYER_TODAYWORD_CHANGE*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx, NM_PLAYER, NM_PLAYER_TODAYWORD_CHANGE_RES ); if ( sendMsg != NULL ) { sendMsg->mWordColor = mPlayerExrInfo.mTodayColor; sendMsg->ErrorCode = ERROR_PLAYER_TODAYWORD_CHANGE_INIT; ::wcsncpy( sendMsg->mWord, mPlayerExrInfo.mTodayWord, MAX_TODAYWORD_BUFFER_SIZE ); NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_PLAYER_TODAYWORD_CHANGE) ); } } return true; } /// ¿À´ÃÀÇ ÇѸ¶µð º¯°æ bool cPlayer::ChangeTodayWord( ULONG_PTR socketContext, wchar_t* word, unsigned long color ) { mPlayerExrInfo.mTodayColor = color; if ( word == NULL ) memset( &mPlayerExrInfo.mTodayWord, 0, sizeof(mPlayerExrInfo.mTodayWord) ); else wcsncpy( mPlayerExrInfo.mTodayWord, word, MAX_TODAYWORD_BUFFER_SIZE ); /// HERO¿¡°Ô ½î±â HANDLE handle = NULL; MSG_RES_PLAYER_TODAYWORD_CHANGE* sendMsg = (MSG_RES_PLAYER_TODAYWORD_CHANGE*)NETWORK2->GetMsgRoot( &handle ,(PerSocketContext*)socketContext ,NM_PLAYER ,NM_PLAYER_TODAYWORD_CHANGE_RES ); sendMsg->ErrorCode = ERROR_PLAYER_TODAYWORD_CHANGE_SUCCESS; sendMsg->mWordColor = mPlayerExrInfo.mTodayColor; wcsncpy( sendMsg->mWord, mPlayerExrInfo.mTodayWord, MAX_TODAYWORD_BUFFER_SIZE ); NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_PLAYER_TODAYWORD_CHANGE) ); MSG_SYN_PLAYER_TODAYWORD_CHANGE synMsg; memset( &synMsg, 0, sizeof(synMsg) ); synMsg.Category = NM_PLAYER; synMsg.Protocol = NM_PLAYER_TODAYWORD_CHANGE_SYN; synMsg.mWordColor = mPlayerExrInfo.mTodayColor; synMsg.mCharacterIndex = mObject.index; if ( word != NULL ) wcsncpy( synMsg.mWord, word, MAX_TODAYWORD_BUFFER_SIZE ); NETWORK2->QuickSendExcept( this, (char*)&synMsg, sizeof(MSG_SYN_PLAYER_TODAYWORD_CHANGE) ); return true; } // Pg_Game_Start Method. void cPlayer::Pg_Game_Start(char* User_Status, char* Bill_Method, char* Bill_Expire, long Bill_Remain) { User_Status; Bill_Method; Bill_Expire; Bill_Remain; /// pc¹æ È¿°ú¸ñ·ÏÀ» °¡Áö°í¿Í¼­ È¿°ú¸¦ °É¾îº¸°í ºÒ°¡´ÉÇϸé ÁÖ±âÀûÀ¸·Î Àç½ÃµµÇÑ´Ù. cLongAry* pPcAry = SKILLSCRIPT->PcBangInfAry(); if( pPcAry != NULL && pPcAry->GetSize() != 0 ) { mPcBangNextCheckTime = 0; for( unsigned long i = 0 ; i < pPcAry->GetSize() ; ++i ) mReadyPcInfSet.Insert( (*pPcAry)[i] ); } } // Pg_User_Alert Method. void cPlayer::Pg_User_Alert(long Packet_Result, char* Bill_Method, long Bill_Remain) { Bill_Method; Bill_Remain; if( Packet_Result != 1 && Packet_Result != -3 ) { /// Àڽſ¡°Ô °É·ÁÀÕ´Â ¹öÇÁ¸¦ Á¦°ÅÇÑ´Ù. cLongAry* pPcAry = SKILLSCRIPT->PcBangInfAry(); if( pPcAry != NULL && pPcAry->GetSize() != 0 ) { mPcBangNextCheckTime = ULONG_MAX; for( unsigned long i = 0 ; i < pPcAry->GetSize() ; ++i ) SKILLMANAGER->DeleteInfluenceClassIdx( mObject, (*pPcAry)[i] ); } } } // Pg_Billing_Auth Method. void cPlayer::Pg_Billing_Auth(char* User_Status, char* Bill_Method, char* Bill_Expire, long Bill_Remain) { User_Status; Bill_Method; Bill_Expire; Bill_Remain; } // Pg_Client_Move Method. void cPlayer::Pg_Client_Move(char* User_Status) { User_Status; } // Pg_Close Method. void cPlayer::Pg_Close( ) { /// Àڽſ¡°Ô °É·ÁÀÕ´Â ¹öÇÁ¸¦ Á¦°ÅÇÑ´Ù. cLongAry* pPcAry = SKILLSCRIPT->PcBangInfAry(); if( pPcAry != NULL && pPcAry->GetSize() != 0 ) { mPcBangNextCheckTime = ULONG_MAX; for( unsigned long i = 0 ; i < pPcAry->GetSize() ; ++i ) SKILLMANAGER->DeleteInfluenceClassIdx( mObject, (*pPcAry)[i] ); } } // Pg_Game_Start Method. void cPlayer::BP_Start() { /// pc¹æ È¿°ú¸ñ·ÏÀ» °¡Áö°í¿Í¼­ È¿°ú¸¦ °É¾îº¸°í ºÒ°¡´ÉÇϸé ÁÖ±âÀûÀ¸·Î Àç½ÃµµÇÑ´Ù. cLongAry* pPcAry = SKILLSCRIPT->PcBangInfAry(); if( pPcAry != NULL && pPcAry->GetSize() != 0 ) { mPcBangNextCheckTime = 0; for( unsigned long i = 0 ; i < pPcAry->GetSize() ; ++i ) mReadyPcInfSet.Insert( (*pPcAry)[i] ); } } void cPlayer::BP_End() { /// Àڽſ¡°Ô °É·ÁÀÕ´Â ¹öÇÁ¸¦ Á¦°ÅÇÑ´Ù. cLongAry* pPcAry = SKILLSCRIPT->PcBangInfAry(); if( pPcAry != NULL && pPcAry->GetSize() != 0 ) { mPcBangNextCheckTime = ULONG_MAX; for( unsigned long i = 0 ; i < pPcAry->GetSize() ; ++i ) SKILLMANAGER->DeleteInfluenceClassIdx( mObject, (*pPcAry)[i] ); } } void cPlayer::BP_ItemGive() { /// HERO¿¡°Ô ½î±â HANDLE handle = NULL; MSGROOT* sendMsg = (MSGROOT*)NETWORK2->GetMsgRoot( &handle, mConnectionIdx ,NM_PLAYER ,NM_PLAYER_PCITEM_GIVE_SYN ); if( sendMsg != NULL ) NETWORK2->SendMsgRoot( handle, sizeof(MSGROOT) ); } // IsBlock Method. bool cPlayer::IsBlock( ) { if ( mBlockApply == true ) { time_t ltime; time( <ime ); if ( difftime( mBlockValidThru, ltime ) <= 0 ) mBlockApply = false; } return mBlockApply; } // SetBlock Method. bool cPlayer::SetBlock(bool apply, unsigned long second) { mBlockApply = apply; if ( mBlockApply == true ) { struct tm validThru; time_t ltime; time_t result; time( <ime ); validThru = *localtime( <ime ); validThru.tm_sec += second; result = mktime( &validThru ); if ( result != (time_t)-1 ) { mBlockValidThru = result; return true; } return false; } return true; } // PostCharacterEvent Method. bool cPlayer::PostCharacterEvent(char category, LPCTSTR format, ...) { LPVOID msgBuf = NULL; DWORD bufferLength; va_list args; va_start( args, format ); bufferLength = _vscprintf( format, args ) + 1; msgBuf = malloc( bufferLength ); vsprintf( (char*)msgBuf, format, args ); va_end( args ); bool retvalue = false; if ( msgBuf != NULL ) { retvalue = NETWORK2->PostCharacterEvent( category ,mConnectionIdx ,mObject.index ,mPlayerInfo.Level ,mHeroInfo.Exp ,mHeroInfo.SkillLevel ,mHeroInfo.SkillExp ,mHeroInfo.SkillPointTotal ,(char*)msgBuf ); free( msgBuf ); } return retvalue; } void cPlayer::AddAllGMEvent( ) { if( NETWORK2 ) { mReadyGMEventList.Clear(); time_t now; time( &now ); cGMEventList::cIterator i = mReadyGMEventList.Begin(); cGMEventList* eventArr = NETWORK2->GetGMEvent(); if( eventArr && eventArr->IsEmpty() == false ) { mGMEventNextCheckTime = 0; cGMEventList::cIterator pos = eventArr->Begin(); cGMEventList::cIterator end = eventArr->End(); for( ; pos != end; ++pos ) { sGMEventInfo& eventInfo = (*pos); /// ³¡³ª´Â ½Ã°£ÀÌ Áö³ªÁö ¾Ê´Â°Íµé¸¸ Ãß°¡ÇÑ´Ù. if( difftime( eventInfo.validThru, now ) > 0 ) mReadyGMEventList.PushBack( eventInfo ); } } } } void cPlayer::AddGMEvent( sGMEventInfo eventInfo ) { if( NETWORK2 ) { time_t now; time( &now ); mGMEventNextCheckTime = 0; /// ³¡³ª´Â ½Ã°£ÀÌ Áö³ªÁö ¾Ê´Â°Íµé¸¸ Ãß°¡ÇÑ´Ù. if( difftime( eventInfo.validThru, now ) > 0 ) mReadyGMEventList.PushBack( eventInfo ); } } void cPlayer::DelGMEvent( unsigned long DBIndex, unsigned long influenceIdx ) { if( NETWORK2 ) { ///»èÁ¦ÇÒ È¿°ú°¡ Ãß°¡ ´ë±â ¸®½ºÆ®¿¡ ÀÖ´Ù¸é »èÁ¦ÇÑ´Ù. cGMEventList::cIterator pos = mReadyGMEventList.Begin(); while( pos != mReadyGMEventList.End() ) { sGMEventInfo& eventInfo = (*pos); if( eventInfo.index == DBIndex && eventInfo.influenceIdx == influenceIdx ) { pos = mReadyGMEventList.Erase( pos ); continue; } ++pos; } mGMEventDelNextCheckTime = 0; ///»èÁ¦ÇÒ È¿°ú°¡ ÀÌ¹Ì »èÁ¦ ´ë±â ¸®½ºÆ®¿¡ ÀÖ´Ù¸é Á¤º¸¸¦ ¼öÁ¤ÇÑ´Ù. pos = mReadyDelGMEventList.Begin(); while( pos != mReadyDelGMEventList.End() ) { sGMEventInfo& eventInfo = (*pos); if( eventInfo.index == DBIndex && eventInfo.influenceIdx == influenceIdx ) { eventInfo.validThru = 0; break; } ++pos; } } } bool cPlayer::IsHaveApplyBuffType( unsigned short applyValueType ) { cApplyValueTypeMap::cIterator findPos = mBuffmap.Find( applyValueType ); if( findPos != mBuffmap.End() ) { /// ÀÌ¹Ì µé¾î°¡ ÀÖ´Â °æ¿ì cHashSet& influenceSet = (*findPos).mSecond; if( influenceSet.IsEmpty() == false ) { /// ÇØ´ç ½ºÅ³ÀÌ À¯È¿ÇÑÁö °Ë»ç´Â »ý·« Áß return true; } } return false; } bool cPlayer::IsHaveApplyDeBuffType( unsigned short applyValueType ) { cApplyValueTypeMap::cIterator findPos = mDeBuffmap.Find( applyValueType ); if( findPos != mDeBuffmap.End() ) { /// ÀÌ¹Ì µé¾î°¡ ÀÖ´Â °æ¿ì cHashSet& influenceSet = (*findPos).mSecond; if( influenceSet.IsEmpty() == false ) { /// ÇØ´ç ½ºÅ³ÀÌ À¯È¿ÇÑÁö °Ë»ç´Â »ý·« Áß return true; } } return false; } unsigned long cPlayer::CalcUseMPExt( unsigned long originUseMP ) { /// ¼Ò¸ð üũ float useMPPlus = mStatus2Plus[ePLAYER_STATUS_EXT_USE_MP]; float useMPPer = mStatus2Per[ePLAYER_STATUS_EXT_USE_MP]; float totalUseMP = (float)originUseMP; if( useMPPer != 0.0f ) { totalUseMP += ( (totalUseMP * useMPPer) / 100.0f ); } totalUseMP += useMPPlus; if( totalUseMP < 0.0f ) totalUseMP = 0.0f; return (unsigned long)totalUseMP; } unsigned long cPlayer::CalcCastingExt( unsigned long originCastingTime ) { /// ¼ø°£ ½ºÅ³ üũ if( originCastingTime == 0 ) return 0; /// ¼Ò¸ð üũ float useCastingPlus = mStatus2Plus[ePLAYER_STATUS_EXT_CASTING]; float useCastingPer = mStatus2Per[ePLAYER_STATUS_EXT_CASTING]; float totalCastingTime = (float)originCastingTime; if( useCastingPer != 0.0f ) { totalCastingTime += ( (totalCastingTime * useCastingPer) / 100.0f ); } totalCastingTime += useCastingPlus; if( totalCastingTime < 1.0f ) totalCastingTime = 1.0f; return (unsigned long)totalCastingTime; }