#include "stdafx.h" #include "gamesrv.h" #include "Party.h" #include "PartyManager.h" #include "RangeCheck.h" #include "ObjectManager.h" #include "Player.h" #include "Monster.h" #include "Drop.h" #include "DropScript.h" #include "RandomTable.h" #include "GridManager.h" cParty::cParty( ) : mIndex(0) , mDivideType( PARTY_DIVIDE_NONE ) , mCount(0) , mLeaderIndex(0) , mOwnUserNum(-1) , mDropMoney(0) , mDropExp(0) , mDropSxp(0) , mMonsterMaxHP(0) , mDamage(0) , mLastAccumTime(0) { /// À¯Àú À妽º ÃʱâÈ­ memset( mUserArr, 0, sizeof(mUserArr) ); memset( mUserDat, 0, sizeof(mUserDat) ); memset( mUserTsp, 0, sizeof(mUserTsp) ); DiceRelease( ); } cParty::~cParty( ) { DiceRelease( ); } // operator new - ÇÒ´ç void* cParty::operator new(size_t n) { if ( n == sizeof(cParty) ) return PARTYMAN->AllocParty( ); else assert(0); return NULL; } // operator delete - ÇØÁ¦ void cParty::operator delete(void* ptr, size_t n) { if ( ptr != NULL ) { if ( n == sizeof(cParty) ) PARTYMAN->FreeParty( static_cast(ptr) ); else assert(0); } else assert(0); } void cParty::Init(unsigned long index, unsigned long leaderIdx, PARTY_DIVIDE_TYPE type, unsigned long accumTime) { mIndex = index; mLeaderIndex = leaderIdx; mDivideType = type; mLastAccumTime = accumTime; } bool cParty::IsUser(unsigned long userIdx) { unsigned long* ptr = mUserArr; unsigned int cnt = mCount; while ( cnt > 0 ) { if ( (*ptr) == userIdx ) return true; cnt--; ptr++; } return false; } bool cParty::AddUser(unsigned long userIdx) { if ( mCount < MAX_PARTYUSER ) { mUserArr[ mCount ] = userIdx; /// »ðÀÔ mCount++; /// Áõ°¡ return true; /// ÆÄƼ·¹º§ ´Ù½Ã °»½ÅÇϱâ. } return false; } bool cParty::DeleteUser(unsigned long userIdx) { if ( mCount > 0 ) { int index = -1; for ( unsigned int i = 0; i < mCount; ++i ) { if ( mUserArr[ i ] == userIdx ) { index = i; break; } } if ( index > -1 ) { mCount--; /// °¨¼Ò for ( unsigned int i = index; i < mCount; ++i ) { mUserArr[ i ] = mUserArr[ i+1 ]; mUserDat[ i ] = mUserDat[ i+1 ]; mUserTsp[ i ] = mUserTsp[ i+1 ]; } mUserArr[ mCount ] = 0; memset( &mUserDat[ mCount ], 0, sizeof(sPartyUserData) ); mUserTsp[ mCount ] = 0; /// ÁÖ»çÀ§ ±¼¸®±â Âü¿©ÀÚ Æ÷±â ¼³Á¤ if ( mDiceEndTime > 0 ) SetDiceRoll( userIdx, 0 ); return true; } } return false; } bool cParty::SetUserData(sPartyUserData* userData, unsigned long tickCount) { unsigned long* ptr = mUserArr; for ( unsigned int i = 0; i < mCount; ++i, ++ptr ) { if ( (*ptr) == userData->userIndex ) { mUserDat[ i ] = (*userData); mUserTsp[ i ] = tickCount; return true; } } return false; } bool cParty::SetUserData(cPlayer* player, unsigned long tickCount) { unsigned long* ptr = mUserArr; unsigned long playerIdx = player->GetObjectID( ); for ( unsigned int i = 0; i < mCount; ++i, ++ptr ) { if ( (*ptr) == playerIdx ) { player->GetPartyUserData( &mUserDat[ i ] ); mUserTsp[ i ] = tickCount; return true; } } return false; } unsigned long cParty::NextLeader( ) { unsigned long* userArr = mUserArr; unsigned int index = 0; for ( unsigned int i = 0; i < mCount; ++i, ++userArr ) { if ( mLeaderIndex == (*userArr) ) { index = (i + 1) % mCount; // Àοø¼ö¸¦ ³Ñ¾î°¡¸é ù¹øÂ° À¯Àú·Î ¹Ù±À return mUserArr[ index ]; } } return 0; } unsigned long cParty::GetTurnUser(unsigned short mapNumber, float x, float y) { NiPoint2 monPos( x, y ); for ( unsigned int i = 0; i < mCount; ++i ) { /// ±×´ÙÀ½ À¯Àú·Î Áõ°¡ mOwnUserNum++; if ( mOwnUserNum >= (int)mCount ) mOwnUserNum = 0; /// ÇØ´çÀ¯Àú ã±â cPlayer* user = OBJECTMANAGER->GetPlayer( mUserArr[ mOwnUserNum ] ); if ( user != NULL ) { if ( mapNumber != user->GetMapNumber() ) continue; NiPoint2 playerPos = user->GetPos( ); // ( user->GetXPos(), user->GetYPos() ); cRangeCheck rangeCheck( PARTY_RANGE ); if ( rangeCheck.IsRange( monPos, playerPos ) == true ) { return mUserArr[ mOwnUserNum ]; } } } return 0; } unsigned long cParty::GetRandomUser(unsigned short mapNumber, float x, float y) { NiPoint2 monPos( x, y ); unsigned long tempArr[ MAX_PARTYUSER ] = {0,}; int count = 0; /// »çÁ¤°Å¸®¾È¿¡ ÀÖ´Â À¯Àú¸¸ µû·Î ¸ðÀº´Ù for ( unsigned int i = 0; i < mCount; ++i ) { cPlayer* user = OBJECTMANAGER->GetPlayer( mUserArr[ i ] ); if ( user != NULL ) { if ( mapNumber != user->GetMapNumber( ) ) continue; NiPoint2 playerPos = user->GetPos( ); // ( user->GetXPos(), user->GetYPos() ); cRangeCheck rangeCheck( PARTY_RANGE ); if ( rangeCheck.IsRange( monPos, playerPos ) == true ) { tempArr[ count ] = mUserArr[ i ]; count++; } } } if ( count == 0 ) { assert(0); return 0; } /// ·£´ýÀ¸·Î »Ì±â int random = rand() % count; mOwnUserNum = tempArr[ random ]; return mOwnUserNum; } void cParty::DivideDropValue(unsigned long monsterIdx, unsigned char monsterLevel) { unsigned long dropMoney = FloatToInt( mDropMoney ); unsigned long dropExp = FloatToInt( mDropExp ); unsigned long dropSxp = FloatToInt( mDropSxp ); unsigned long damage = mDamage; unsigned long monsterMaxHP = mMonsterMaxHP; mDropMoney = 0; mDropExp = 0; mDropSxp = 0; mMonsterMaxHP = 0; mDamage = 0; cMonster* pMonster = OBJECTMANAGER->GetMonster( monsterIdx ); if ( pMonster == NULL ) { assert(NULL); return; } /// ¸ó½ºÅÍ¿¡ ÆÄƼÀüü°¡ °ø°ÝÇÑ µ¥¹ÌÁö°¡ hpÀÇ 1%¹Ì¸¸ÀÌ¸é º¸»ó ¾øÀ½ if ( monsterMaxHP * 0.01f > damage ) return; unsigned short mapNumber = pMonster->GetMapNumber( ); NiPoint2 monPos = pMonster->GetPos( ); /// °æÇèÄ¡¸¦ ºÐ¹èÇØÁÙ ÆÄƼ¿ø ¸ñ·Ï unsigned long dropUserIdx[MAX_PARTYUSER] = { 0, }; unsigned char dropUserCnt = 0; /// µå¶ø À¯Àú ¼ö unsigned char calcUserCnt = 0; /// ÆÄƼ Áõ°¨Ä¡ °è»ê B½ÄÀÇ ÆÄƼ¿ø ¼ö unsigned char maxLevel = 0; /// ÆÄƼ ·¹º§ NiPoint2 playerPos = NiPoint2::ZERO; cRangeCheck rangeCheck( PARTY_RANGE ); /// ÆÄƼ ÃÖ°í ·¹º§ °Ë»ö cPlayer* pPlayer = NULL; for ( unsigned int i = 0; i < mCount; ++i ) { pPlayer = OBJECTMANAGER->GetPlayer( mUserArr[ i ] ); if ( pPlayer == NULL ) continue; playerPos = pPlayer->GetPos(); /// À§Ä¡ È®ÀÎ if ( mapNumber != pPlayer->GetMapNumber( ) || rangeCheck.IsRange( monPos, playerPos ) != true ) { /// À§Ä¡°¡ Ʋ¸®°í °ø°Ýµµ ¾ÈÇß´Ù¸é µå·Ó´ë»ó¿¡¼­ »©¹ö¸² if ( pMonster->GetTakeDamage( mUserArr[ i ] ) == 0 ) continue; } if ( maxLevel < pPlayer->GetLevel( ) ) maxLevel = pPlayer->GetLevel( ); } float totalValue = 0; float value104 = DROPSCRIPT->GetPartyCalcInfo( 104 ); /// Àüü ÆÄƼ¿ø °Ë»ö - À§Ä¡, ¸ó½ºÅÍ °ø°Ý ÇØ´ç ÆÄƼ¿ø ¸®½ºÆ®¸¸ Ãß·Á³¿ for ( unsigned int i = 0; i < mCount; ++i ) { pPlayer = OBJECTMANAGER->GetPlayer( mUserArr[ i ] ); if ( pPlayer == NULL ) continue; playerPos = pPlayer->GetPos(); /// À§Ä¡ È®ÀÎ if ( mapNumber != pPlayer->GetMapNumber( ) || rangeCheck.IsRange( monPos, playerPos ) != true ) { /// À§Ä¡°¡ Ʋ¸®°í °ø°Ýµµ ¾ÈÇß´Ù¸é µå·Ó´ë»ó¿¡¼­ »©¹ö¸² if ( pMonster->GetTakeDamage( mUserArr[ i ] ) == 0 ) continue; } /// 6·¹º§ ÀÌ»ó Â÷À̰¡ ³ª´Â À¯Àú´Â °è»êÇÏÁö ¾Ê´Â´Ù. if( (maxLevel - 6) < pPlayer->GetLevel() ) ++calcUserCnt; /// µå·Ó ÇØ´ç À¯Àú Ä«¿îÆ®¿Í ÆÄƼ ·¹º§ ¼³Á¤ dropUserIdx[ dropUserCnt ] = mUserArr[ i ]; ++dropUserCnt; /// °æÇèÄ¡ °è»ê¿¡ ¾µ ³»¿ë (ÆÄƼÀû¿ë¹üÀ§¿¡ ÀÖ´Â À¯Àú¸¸ üũ ) totalValue += pow( pPlayer->GetLevel( ), value104 ); } /// ¸ó½ºÅ͸¦ °ø°Ý Çß´ø ÆÄƼ°¡ ¸ó½ºÅͰ¡ Á×±âÀü¿¡ ´Ù ¶°³² if ( dropUserCnt == 0 ) return; if ( totalValue == 0 ) { assert( NULL ); return; } /// ·¹º§Â÷ Áõ°¨Ä¡ °è»ê float calcExp = DROP->MonsterDropExpIncrease( (float)dropExp, maxLevel, monsterLevel ); float calcSxp = DROP->MonsterDropExpIncrease( (float)dropSxp, maxLevel, monsterLevel ); /*------------------------------------------------------------------------------------*/ /// ÆÄƼ Áõ°¨Ä¡ °è»ê // A = [¸ó½ºÅÍ °æÇèÄ¡] // B = ( ([¸ó½ºÅÍ °æÇèÄ¡] / {NUM101} * {NUM102}) * (ÆÄƼ¿ø ¼ö - 1)) // C = ÀÚ½ÅÀÇ ·¹º§ ^ {NUM103} / (ÆÄƼ¿øÀÇ ·¹º§ ^ {NUM104} ÀÇ ÇÕ) // D = A * C (±âº» °æÇèÄ¡) // E = B * C (ÆÄƼÀοø¿¡ µû¸¥ Ãß°¡ °æÇèÄ¡) // F = D + E ÃÖ´ë A * 0.9 /*------------------------------------------------------------------------------------*/ float value101 = DROPSCRIPT->GetPartyCalcInfo( 101 ); float value102 = DROPSCRIPT->GetPartyCalcInfo( 102 ); float value103 = DROPSCRIPT->GetPartyCalcInfo( 103 ); /// ¼±Á¤µÈ Ç÷¹À̾°Ô µå·Ó for ( unsigned char i = 0 ; dropUserCnt > i ; ++i ) { pPlayer = OBJECTMANAGER->GetPlayer( dropUserIdx[ i ] ); if ( pPlayer == NULL || pPlayer->GetStateDie( ) == true ) continue; playerPos = pPlayer->GetPos( ); // { playerPos.x = pPlayer->GetXPos( ); playerPos.y = pPlayer->GetYPos( ); } /// µå·Ó ´ë»ó ÀÌÁö¸¸ µå·Ó ºÐ¹è ´ç½Ã ¸Ö¸® ÀÖÀ¸¸é ´ë»ó¿¡¼­ Á¦¿Ü if ( mapNumber != pPlayer->GetMapNumber( ) || rangeCheck.IsRange( monPos, playerPos ) != true ) continue; /// °³ÀÎ °æÇèÄ¡ °Ë»ç { float eachValue = pow( pPlayer->GetLevel(), value103 ); // B = ( ([¸ó½ºÅÍ °æÇèÄ¡] / {NUM101} * {NUM102}) * (ÆÄƼ¿ø ¼ö - 1)) float resultB = ( calcExp / value101 * value102 ) * (calcUserCnt - 1); // ½ÇÁ¦·Î Àû¿ë¹ÞÀ» Àοø¼ö float resultC = 1.0f; if ( dropUserCnt > 1 ) { // C = ÀÚ½ÅÀÇ ·¹º§ ^ {NUM103} / (ÆÄƼ¿øÀÇ ·¹º§ ^ {NUM104} ÀÇ ÇÕ) resultC = eachValue / totalValue; } float resultD = calcExp * resultC; float resultE = resultB * resultC; /// ÃÖ´ëÄ¡ ÁöÁ¤ if ( (resultD + resultE) > calcExp ) { resultD = (float)(resultD * 0.9); resultE = (float)(resultE * 0.9); } pPlayer->AddPartyExp( (unsigned long)(resultD + resultE), true, false, (unsigned long)resultD, (unsigned long)resultE ); } /// °³ÀÎ ½ºÅ³ °æÇèÄ¡ °Ë»ç { float eachValue = pow( pPlayer->GetLevel(), value103 ); float resultB = ( calcSxp / value101 * value102 ) * (calcUserCnt -1 ); // ½ÇÁ¦·Î Àû¿ë¹ÞÀ» Àοø¼ö float resultC = 1.0f; if ( dropUserCnt > 1 ) { resultC = eachValue / totalValue; } float resultD = calcSxp * resultC; float resultE = resultB * resultC; /// ÃÖ´ëÄ¡ ÁöÁ¤ if ( (resultD + resultE) > calcSxp ) { resultD = (float)(resultD * 0.9); resultE = (float)(resultE * 0.9); } pPlayer->AddPartySxp( (unsigned long)(resultD + resultE), true, (unsigned long)resultD, (unsigned long)resultE ); } /// money´Â ±Õµî ºÐ¹è unsigned long money = dropMoney / dropUserCnt; if ( money != 0 ) { float addMoneyPer = pPlayer->GetStatusEtc()->mMoneyAddPer; if( addMoneyPer < 0.0f ) { NETWORK2->PostServerEvent("cParty::DivideDropValue addMoneyPer < 0.0f[%f]", addMoneyPer ); pPlayer->AddMoney( pMonster->GetObject(), money ); } else { unsigned long addMoney = (unsigned long)(money + ( (float)money * addMoneyPer / 100.0f )); pPlayer->AddMoney( pMonster->GetObject(), addMoney ); } } } } void cParty::AddDropValue(unsigned long maxHP, unsigned long damage, float money, float exp, float sxp) { mDropMoney = mDropMoney + money; mDropExp = mDropExp + exp; mDropSxp = mDropSxp + sxp; mMonsterMaxHP = maxHP; mDamage = mDamage + damage; } void cParty::DiceRelease( ) { mDiceEndTime = 0; mDiceCount = 0; mDiceRollCnt = 0; memset( mDiceMember, 0, sizeof(mDiceMember) ); } bool cParty::DiceStart( ) { if ( mDiceEndTime > 0 ) { //NETWORK2->PostServerEvent("WARNNING cParty::DiceStart - already start"); return false; } for ( unsigned int i = 0; i < mCount; i++ ) { if ( mUserArr[i] > 0 ) { cPlayer* pPlayer = OBJECTMANAGER->GetPlayer( mUserArr[i] ); if ( pPlayer != NULL ) { pPlayer->SendPartyDiceStart( ); if ( mDiceCount < MAX_PARTYUSER ) { mDiceMember[mDiceCount].mUserIdx = mUserArr[i]; mDiceMember[mDiceCount].mRandom = 0; mDiceMember[mDiceCount].mRoll = false; wcscpy( mDiceMember[mDiceCount].mCharName, mUserDat[ i ].name ); ++mDiceCount; } } } } mDiceEndTime = NETWORK2->GetAccumTime( ) + PARTY_DICETIME; return true; } sDiceMember* cParty::GetDiceMember(unsigned long userIdx) { for ( unsigned int i = 0; i < mDiceCount; i++ ) { if ( mDiceMember[i].mUserIdx == userIdx ) return &mDiceMember[i]; } return NULL; } int cParty::DiceRollReq(unsigned long userIdx, unsigned short randVal) { /// ÁÖ»çÀ§ ±¼¸®±â ÁøÇà ¿©ºÎ if ( mDiceEndTime == 0 ) return ERROR_DICE_ROLL_NOT_START; sDiceMember* pMember = GetDiceMember( userIdx ); if ( pMember == NULL ) return ERROR_DICE_ROLL_MEMBER; /// ÀÌ¹Ì ¼±Åà Çß´ÂÁö if ( pMember->mRoll ) return ERROR_DICE_ROLL_ALREADY; /// ·£´ý°ª ÃßÃâ pMember->mRandom = randVal; pMember->mRoll = true; ++mDiceRollCnt; return ERROR_DICE_ROLL_SUCCESS; } void cParty::SetDiceRoll(unsigned long userIdx, unsigned short randVal) { sDiceMember* pMember = GetDiceMember( userIdx ); if ( pMember != NULL ) { if ( pMember->mRoll == false ) ++mDiceRollCnt; pMember->mRoll = true; pMember->mRandom = randVal; } } unsigned long cParty::GetLostPlayer(unsigned long tickCount) { unsigned long* userTsp = mUserTsp; for ( unsigned int i = 0; i < mCount; ++i, ++userTsp ) { if ( 0 < (*userTsp) && tickCount > (*userTsp) ) return mUserArr[ i ]; } return 0; } void cParty::SendPartyAddoneSyn(sPartyUserData* userData) { unsigned long* userArr = mUserArr; cPlayer* player; for ( unsigned int i = 0; i < mCount; ++i, ++userArr ) { player = OBJECTMANAGER->GetPlayer( (*userArr) ); if ( player != NULL ) player->SendPartyAddoneSyn( userData ); } } void cParty::SendPartyOutSyn(unsigned long playerIdx) { unsigned long* userArr = mUserArr; cPlayer* player; for ( unsigned int i = 0; i < mCount; ++i, ++userArr ) { player = OBJECTMANAGER->GetPlayer( (*userArr) ); if ( player != NULL ) player->SendPartyOutSyn( playerIdx ); } } void cParty::SendPartyThrowSyn(unsigned long playerIdx) { unsigned long* userArr = mUserArr; cPlayer* player; for ( unsigned int i = 0; i < mCount; ++i, ++userArr ) { player = OBJECTMANAGER->GetPlayer( (*userArr) ); if ( player != NULL ) player->SendPartyThrowSyn( playerIdx ); } } void cParty::SendPartyLeaderSyn(unsigned long leaderIdx) { unsigned long* userArr = mUserArr; cPlayer* player; for ( unsigned int i = 0; i < mCount; ++i, ++userArr ) { player = OBJECTMANAGER->GetPlayer( (*userArr) ); if ( player != NULL ) player->SendPartyLeaderSyn( leaderIdx ); } } void cParty::SendPartyDivideType(char type) { unsigned long* userArr = mUserArr; cPlayer* player; for ( unsigned int i = 0; i < mCount; ++i, ++userArr ) { player = OBJECTMANAGER->GetPlayer( (*userArr) ); if ( player != NULL ) player->SendPartyDivideType( type ); } } void cParty::SendPartyDataLevelSyn(unsigned long playerIdx, unsigned char level) { unsigned long* userArr = mUserArr; cPlayer* player; for ( unsigned int i = 0; i < mCount; ++i, ++userArr ) { player = OBJECTMANAGER->GetPlayer( (*userArr) ); if ( player != NULL ) player->SendPartyDataLevelSyn( playerIdx, level ); } } void cParty::SendPartyMapchangeSyn(unsigned long playerIdx, short map, short room, DWORD channelnum ) { unsigned long* userArr = mUserArr; cPlayer* player; for ( unsigned int i = 0; i < mCount; ++i, ++userArr ) { player = OBJECTMANAGER->GetPlayer( (*userArr) ); if ( player != NULL ) player->SendPartyMapchangeSyn( playerIdx, map, room, channelnum ); } } void cParty::SendPartyDeleteSyn( ) { unsigned long* userArr = mUserArr; cPlayer* player; for ( unsigned int i = 0; i < mCount; ++i, ++userArr ) { player = OBJECTMANAGER->GetPlayer( (*userArr) ); if ( player != NULL ) { player->SetPartyIndex( 0 ); player->SetPartyState( ePARTY_NONE ); player->SendPartyDeleteSyn( ); } } } void cParty::SendChat(sInventory* inventory, wchar_t* name, wchar_t* message, unsigned long characterIdx, unsigned short job ) { unsigned long* userArr = mUserArr; cPlayer* player; for ( unsigned int i = 0; i < mCount; ++i, ++userArr ) { player = OBJECTMANAGER->GetPlayer( (*userArr) ); if ( player != NULL ) { HANDLE handle = NULL; MSG_SYN_CHAT_PARTY* sendMsg = (MSG_SYN_CHAT_PARTY*)NETWORK2->GetMsgRoot( &handle, player->GetConnectionIdx( ), NM_CHAT, NM_CHAT_PARTY_SYN ); if ( sendMsg != NULL ) { sendMsg->playerIndex = characterIdx; sendMsg->job = job; sendMsg->inventory = (*inventory); memcpy( sendMsg->Name, name, sizeof(sendMsg->Name) ); memcpy( sendMsg->Message, message, sizeof(sendMsg->Message) ); NETWORK2->SendMsgRoot( handle, sendMsg->GetMsgLength( ) ); } } } } // SendUpdate Method - ÆÄƼÁ¤º¸ ¾÷µ¥ÀÌÆ® ¹× ä³Î µ¿±âÈ­ void cParty::SendUpdate( ) { cSender* sender = g_gameSrv->GetSender( ); cPlayer* player = NULL; cPlayer* others = NULL; unsigned long* rootPtr = &mUserArr[ 0 ]; unsigned int rootCnt = 0; unsigned int rootLen = mCount; while ( rootCnt < rootLen ) { player = OBJECTMANAGER->GetPlayer( (*rootPtr) ); ++rootPtr; ++rootCnt; if ( player != NULL ) { if ( rootCnt < rootLen ) { unsigned long* tailPtr = &mUserArr[ rootCnt ]; unsigned int tailCnt = rootCnt; unsigned int tailLen = mCount; while ( tailCnt < tailLen ) { others = OBJECTMANAGER->GetPlayer( (*tailPtr) ); ++tailPtr; ++tailCnt; if ( others != NULL ) { // 1. ¸ÊÀ§Ä¡ °Ë»ç - ÃÖ¼ÒÇÑÀÇ Á¤º¸¸¸ º¸³½´Ù if ( player->GetMapNumber() != others->GetMapNumber() ) { player->SendPartyDataLevelSyn( others->GetConnectionIdx( ) ); others->SendPartyDataLevelSyn( player->GetConnectionIdx( ) ); } // 2. ±×¸®µå °Ë»ç - ±ÙÁ¢ ±×¸®µå¾È¿¡ ¾ø´Â À¯Àú¿¡°Ô¸¸ ½îµµ·Ï ÇÑ´Ù else if ( GRIDMANAGER->IsSight( player, others ) == false ) { player->SendPartyDataSyn( others->GetConnectionIdx( ) ); others->SendPartyDataSyn( player->GetConnectionIdx( ) ); } } } } // ä³Îµ¿±âÈ­ PARTY_DATA_SYNC sync; memset( &sync, 0, sizeof(sync) ); sync.protocol = PSP_SYN_LEVEL_DATA; sync.synLevelData.partyIdx = mIndex; player->GetPartyUserData( &sync.synLevelData.player ); sender->PostPartySync( NETWORK2->GetCID( ), (char*)&sync, sync.SYNLEVELDATA( ) ); } } }