// 극단 해체 // 해체는 사람이 부족하여 자동으로 해체 // 단독적으로 해체할수 없음 BOOL CPartyMng::DeleteParty( u_long uPartyId ) { CParty* pParty = GetParty( uPartyId ); if( pParty ) { if( pParty->m_idDuelParty ) // 극단듀얼중일때 극단이 해체되었으면 { CParty *pDstParty = GetParty( pParty->m_idDuelParty ); // 상대 파티원들에게도 this파티가 해체되어 듀얼이해제됐다는걸 알림. if( pDstParty ) { pDstParty->DoDuelPartyCancel( pParty ); } else { Error( "CPartyMng::DeleteParty : 상대파티를 찾을 수 없음 %d", pParty->m_idDuelParty ); } #ifdef __WORLDSERVER g_DPCoreClient.SendSetPartyDuel( pParty->m_uPartyId, pParty->m_idDuelParty, FALSE ); #endif // __WORLDSERVER pParty->DoDuelPartyCancel( pDstParty ); // this파티원들에게도 듀얼해제됐다는걸 알림. } #ifdef __WORLDSERVER #if __VER >= 14 // __INSTANCE_DUNGEON CInstanceDungeonParty::GetInstance()->DestroyAllDungeonByDungeonID( uPartyId ); #endif // __INSTANCE_DUNGEON #endif // __WORLDSERVER safe_delete( pParty ); m_2PartyPtr.erase( uPartyId ); return TRUE; } return FALSE; }
void CPartyMng::AddConnection( CPlayer* pPlayer ) { CParty* pParty; CMclAutoLock Lock( m_AddRemoveLock ); pParty = GetParty( pPlayer->m_uPartyId ); if( pParty ) { int i = pParty->FindMember( pPlayer->uKey ); if( i < 0 ) { pPlayer->m_uPartyId = 0; return; } pParty->m_aMember[i].m_bRemove = FALSE; pParty->m_nReferens--; BEFORESENDDUAL( ar, PACKETTYPE_ADDPLAYERPARTY, DPID_UNKNOWN, DPID_UNKNOWN ); ar << pPlayer->m_uPartyId << pPlayer->uKey; SEND( ar, &g_dpCoreSrvr, DPID_ALLPLAYERS ); } else pPlayer->m_uPartyId = 0; }
int32 SetPlotFlag(int32 plotIndex, int64 nPlotFlag, int32 nPlotValue) { //update the actual Plot table in Party for (int32 j = 0; j < GetParty()->Plots[plotIndex].StatusList.Num(); j++) { if (GetParty()->Plots[plotIndex].StatusList[j].pNode.Flag == nPlotFlag) { GetParty()->Plots[plotIndex].StatusList[j].pValue = nPlotValue; return TRUE_; } } #ifdef DEBUG LogError("SetPlotFlag: plot not found with flag " + IntToString(nPlotFlag)); #endif // DEBUG return FALSE_; }
FString GetPlotResRef(int64 nPlotHash) { for (FPlot plot : GetParty()->Plots) { int64 _hash = GetNewHash(plot.GUID, TRUE_); if (nPlotHash == _hash) { return plot.ResRefName; } } return ""; }
bool Game_Enemy::IsActionValid(const RPG::EnemyAction& action) { if (action.kind == action.Kind_skill) { if (!IsSkillUsable(action.skill_id)) { return false; } } switch (action.condition_type) { case RPG::EnemyAction::ConditionType_always: return true; case RPG::EnemyAction::ConditionType_switch: return Game_Switches[action.switch_id]; case RPG::EnemyAction::ConditionType_turn: { int turns = Game_Battle::GetTurn(); return Game_Battle::CheckTurns(turns, action.condition_param2, action.condition_param1); } case RPG::EnemyAction::ConditionType_actors: { std::vector<Game_Battler*> battlers; GetParty().GetActiveBattlers(battlers); int count = (int)battlers.size(); return count >= action.condition_param1 && count <= action.condition_param2; } case RPG::EnemyAction::ConditionType_hp: { int hp_percent = GetHp() * 100 / GetMaxHp(); return hp_percent >= action.condition_param1 && hp_percent <= action.condition_param2; } case RPG::EnemyAction::ConditionType_sp: { int sp_percent = GetSp() * 100 / GetMaxSp(); return sp_percent >= action.condition_param1 && sp_percent <= action.condition_param2; } case RPG::EnemyAction::ConditionType_party_lvl: { int party_lvl = Main_Data::game_party->GetAverageLevel(); return party_lvl >= action.condition_param1 && party_lvl <= action.condition_param2; } case RPG::EnemyAction::ConditionType_party_fatigue: { int party_exh = Main_Data::game_party->GetFatigue(); return party_exh >= action.condition_param1 && party_exh <= action.condition_param2; } default: return true; } }
FString GetPlotFlagName(int64 nPlotHash, int32 nFlag) { for (FPlot plot : GetParty()->Plots) { int64 _hash = GetNewHash(plot.GUID, TRUE_); if (nPlotHash == _hash) { for (FPlotElement e : plot.StatusList) { if (e.pNode.Flag == nFlag) { return e.pNode.Name; } } } } return "";//error }
// 극단 생성 // uLeaderPlayerId : 단장, uPartyId : 1번째 단원 // 극단를 생설할때는 2명으로 생성함( 혼자서는 극단를 생성할수 없음 ) u_long CPartyMng::NewParty( u_long uLeaderId, LONG nLeaderLevel, LONG nLeaderJob, BYTE nLeaderSex, LPSTR szLeaderName, u_long uMemberId, LONG nMemberLevel, LONG nMemberJob, BYTE nMemberSex, LPSTR szMembername, u_long uPartyId ) { // locked if( 0 == uPartyId ) { m_id++; } else { m_id = uPartyId; } if( NULL == GetParty( m_id ) ) // NULL 이면 극단이 없으므로 만들어야 한다 { CParty* pParty = new CParty; // pParty->Lock(); pParty->SetPartyId( m_id ); #if __VER >= 11 // __SYS_PLAYER_DATA if( TRUE == pParty->NewMember( uLeaderId ) && TRUE == pParty->NewMember( uMemberId ) ) #else // __SYS_PLAYER_DATA if( TRUE == pParty->NewMember( uLeaderId, nLeaderLevel, nLeaderJob, nLeaderSex, szLeaderName ) && TRUE == pParty->NewMember( uMemberId, nMemberLevel, nMemberJob, nMemberSex, szMembername ) ) #endif // __SYS_PLAYER_DATA { // m_2Party.SetAt( m_id, pParty ); m_2PartyPtr.insert( C2PartyPtr::value_type( m_id, pParty ) ); pParty->m_nGetItemPlayerId = pParty->m_aMember[0].m_uPlayerId; // pParty->Unlock(); return m_id; } else // 극단에 소속되어 있다 { // pParty->Unlock(); safe_delete( pParty ); } } return 0; }
int32 GetPartyPlotFlag(int64 nPlotHash, int32 nFlag) { for (FPlot plot : GetParty()->Plots) { int64 _hash = GetNewHash(plot.GUID, TRUE_); if (nPlotHash == _hash) { for (FPlotElement e : plot.StatusList) { if (e.pNode.Flag == nFlag) { return e.pValue; } } } } #ifdef DEBUG LogError("plot_h: didn't find plot flag " + IntToString(nFlag) + " current value from hash " + IntToString(nPlotHash)); #endif // DEBUG return FALSE_;//error }
void CPartyMng::RemoveConnection( CPlayer* pPlayer ) { if( pPlayer->m_uPartyId == 0 ) return; CParty* pParty; CMclAutoLock Lock( m_AddRemoveLock ); pParty = GetParty( pPlayer->m_uPartyId ); if( pParty ) { int i = pParty->FindMember( pPlayer->uKey ); if( i < 0 ) return; pParty->m_aMember[i].m_tTime = CTime::GetCurrentTime(); pParty->m_aMember[i].m_bRemove = TRUE; pParty->m_nReferens++; BEFORESENDDUAL( ar, PACKETTYPE_REMOVEPLAYERPARTY, DPID_UNKNOWN, DPID_UNKNOWN ); ar << pPlayer->m_uPartyId << pPlayer->uKey; SEND( ar, &g_dpCoreSrvr, DPID_ALLPLAYERS ); #if __VER >= 12 // __PARSKILL1001 090917 mirchang - 파스킬 아이템 수정 if( pParty->m_nModeTime[PARTY_PARSKILL_MODE] ) g_dpCoreSrvr.SendSetPartyMode( pParty->m_uPartyId, PARTY_PARSKILL_MODE, FALSE ); #endif // __PARSKILL1001 090917 mirchang - 파스킬 아이템 수정 if( i == 0 ) { bool fRemoveParty = true; for( int j = 1; j < pParty->m_nSizeofMember; j++ ) { if( pParty->m_aMember[j].m_bRemove == FALSE ) { fRemoveParty = false; pParty->SwapPartyMember( 0, j ); break; } } #if __VER >= 12 // __PARSKILL1001 //12차 파스킬 아이템 수정 world,core,neuz for( int k = 0 ; k < MAX_PARTYMODE ; k++ ) { if( pParty->m_nModeTime[k] ) { if( k == PARTY_PARSKILL_MODE) continue; pParty->m_nModeTime[k] = 0; } } #endif //__PARSKILL1001 //12차 파스킬 아이템 수정 world,core,neuz if( fRemoveParty ) { CPlayer* pPlayer; for( j = 0; j < pParty->m_nSizeofMember; j++ ) { pPlayer = g_PlayerMng.GetPlayer( pParty->GetPlayerId( j ) ); if( pPlayer ) pPlayer->m_uPartyId = 0; } DeleteParty( pParty->m_uPartyId ); } } } }
bool CCharacter::AoeBuff( CSkills* skill ) { Position->destiny = Position->current; BEGINPACKET( pak, 0x7bb ); ADDWORD ( pak, clientid ); GServer->SendToVisible( &pak, (CCharacter*)this ); CMap* map = GServer->MapList.Index[Position->Map]; if(CharType != 2) //player || Summon || NPC. Anything that is not a monster { for(UINT i=0;i<map->PlayerList.size();i++) { CPlayer* player = map->PlayerList.at(i); if(player == NULL)continue; switch(skill->target) { case 1: //tPartyMember if(player->Party->party == GetParty()) { //Log(MSG_INFO,"Applying AOE buff as long as I can find a close enough party member"); if (player == this) //it is me so I had better cast it anyway ^-^ { UseBuffSkill( (CCharacter*)player, skill ); } else if(player->Party->party != NULL) // Don't cast the skill on players who are not in any party at all. { if(GServer->IsMonInCircle( Position->current,player->Position->current,(float)skill->aoeradius + 1)) UseBuffSkill( (CCharacter*)player, skill ); } } break; case 2: //tClanMember if (player->Clan == GetClan( ) && (player->Clan != 0 || player == this)) { //Log(MSG_INFO,"Applying AOE buff as long as I can find a close enough clan member"); if(GServer->IsMonInCircle( Position->current, player->Position->current, (float)skill->aoeradius + 1 ) ) UseBuffSkill( (CCharacter*)player, skill ); } break; case 3: //tAlly case 7: //tAllCharacters case 8: //tAllMembers. all characters { Log(MSG_INFO,"Applying AOE buff as long as I can find a close enough allied Player"); if(GServer->IsMonInCircle( Position->current,player->Position->current,(float)skill->aoeradius + 1)) UseBuffSkill( (CCharacter*)player, skill ); } break; case 5: //tHostileCharacter { if (CharType == 2) { //Log(MSG_INFO,"Applying AOE buff as long as I can find a close enough hostile Player"); if(GServer->IsMonInCircle( Position->current,player->Position->current,(float)skill->aoeradius + 1)) UseBuffSkill( (CCharacter*)player, skill ); } } break; } } } else if (CharType == 2) //monster { for(UINT i=0;i<map->MonsterList.size();i++) { CMonster* monster = map->MonsterList.at(i); if(monster == NULL)continue; switch(skill->target) { case tPartyMember: // party break; case 2: //tClanMember break; case 3: //tAlly case 7: //tAllCharacters case 8: //tAllMembers. all characters { //Log(MSG_INFO,"Applying AOE buff as long as I can find a close enough monster"); if(GServer->IsMonInCircle( Position->current,monster->Position->current,(float)skill->aoeradius + 1)) UseBuffSkill( (CCharacter*)monster, skill ); } break; case tHostileCharacter: break; } } } Stats->MP -= (skill->mp - (skill->mp * Stats->MPReduction / 100)); if(Stats->MP < 0) Stats->MP = 0; //Battle->atktarget = Battle->target; //Battle->bufftarget = 0; //Battle->skilltarget = 0; //Battle->skillid = 0; //Battle->atktype = NORMAL_ATTACK; ClearBattle( Battle ); Battle->lastAtkTime = clock( ); Battle->iscasting = 1; return true; }
//nPlotFlag comes from CONV file and is 0-512 range, so needs conversion when looking for plot int32 HandlePlotFlag(int32 nPlotEventType /*get/set*/, FString nPlotGUID, int64 nPlotFlag, int32 nPlotValue) { int32 handled = FALSE_; FPlot plot; int32 plotIndex = -1; //position in plot array, so we keep track in one place and don't search multiple times for (int32 i = 0; i < GetParty()->Plots.Num(); i++) { if (GetParty()->Plots[i].GUID == nPlotGUID) { plot = GetParty()->Plots[i]; plotIndex = i; break; } } if (plot.ResRefID == 0) return FALSE_;//not found //int32 convertedFlag = PlotFlagConversion(plot.ResRefID, nPlotFlag); nPlotFlag = PlotFlagConversion(plot.ResRefID, nPlotFlag); //not needed int64 _hash = GetNewHash(nPlotGUID, TRUE_); switch (_hash) { case PLT_DEMO000PL_MAIN: { switch (nPlotEventType) { case EVENT_TYPE_GET_PLOT://only defined flags { //plot less than but bigger than int64 lessThan = FCString::Atoi64(*(IntToString(plot.ResRefID) + TEXT("000") + IntToString(255))); int64 biggerThan = FCString::Atoi64(*(IntToString(plot.ResRefID) + TEXT("000") + IntToString(0))); if (nPlotFlag <= lessThan && nPlotFlag >= biggerThan) //starting main flag in our plot range { #ifdef DEBUG LogError("Get Flags need to be > 255 in their respective plot, got " + IntToString(nPlotFlag)); #endif return FALSE_; } switch (nPlotFlag) { case DEMO_DECLINED_QUEST: { //This is a "defined" plot flag. When the plot is checked //to see whether the flag is true or false, its status is //determined using the following code. if (WR_GetPlotFlag(PLT_DEMO000PL_MAIN, DEMO_TALKED_TO_BARKEEP) == TRUE_ && WR_GetPlotFlag(PLT_DEMO000PL_MAIN, DEMO_QUEST_ACCEPTED) == FALSE_) { return TRUE_; } else { return FALSE_; } break; } default: { #ifdef DEBUG LogError(Int64ToString(_hash) + " GET Unknown flag: " + IntToString(nPlotFlag)); #endif // DEBUG break; } } break; } case EVENT_TYPE_SET_PLOT: { switch (nPlotFlag) { case DEMO_TALKED_TO_BARKEEP: { if (nPlotValue == -1) return FALSE_; //error, needs to be 0/1 return SetPlotFlag(plotIndex, nPlotFlag, TRUE_); } case DEMO_QUEST_ACCEPTED: { //TODO UT_AddItemToInventory(DEMO_INKEEPER_KEY_R); LogWarning("DEMO_QUEST_ACCEPTED: UT_AddItemToInventory(DEMO_INKEEPER_KEY_R)"); if (nPlotValue == -1) return FALSE_; //error, needs to be 0/1 return SetPlotFlag(plotIndex, nPlotFlag, TRUE_); } case DEMO_BANDIT_HOSTILE: { //This causes all members of the bandit's "team" (the bandit and //the other bar patrons) to turn hostile. Since they're in the presence //of the player already, they'll immediately perceive him and initiate //combat. UT_TeamGoesHostile(BANDIT_TEAM); //During debug manually add the player to the bandits threat target // for (int32 nIndex = 0; nIndex < GetArraySize(arTeam); nIndex++) // { // GameObject _member = arTeam[nIndex]; // SetEnemy(_member, GetHero()); // } WR_SetGameMode(static_cast<uint8>(EGameMode::GM_COMBAT)); break; } default: { #ifdef DEBUG LogError(Int64ToString(_hash) + " SET Unknown flag: " + IntToString(nPlotFlag)); #endif // DEBUG break; } } break; } default: { #ifdef DEBUG LogError("Unknown plot event type!!!"); #endif break; } } break; } default: { LogError("Plot not found, needed " + Int64ToString(_hash)); break; } } return handled; }
FPlot ParsePlot(int32 nPlotID) { FString sValue; FString sPlot = FString::FromInt(nPlotID); FString aFullPath = FPaths::GameDevelopersDir(); aFullPath += "Source/JSON/PLO/"; aFullPath += *sPlot; aFullPath += ".json"; FString JsonStr; FFileHelper::LoadFileToString(JsonStr, *aFullPath); TSharedRef<TJsonReader<TCHAR>> JsonReader = TJsonReaderFactory<TCHAR>::Create(JsonStr); TSharedPtr<FJsonObject> JsonObject = MakeShareable(new FJsonObject()); FPlot plot; if (FJsonSerializer::Deserialize(JsonReader, JsonObject) && JsonObject.IsValid()) { plot.ResRefID = nPlotID; TMap<FString, TSharedPtr<FJsonValue>> JsonValuesMap = JsonObject->Values; TSharedPtr<FJsonValue> rootValues; JsonValuesMap.RemoveAndCopyValue("Resource", rootValues); TSharedPtr<FJsonObject> rootObject = rootValues->AsObject(); TMap<FString, TSharedPtr<FJsonValue>> rootValuesMap = rootObject->Values; TSharedPtr<FJsonValue> agentValues; rootValuesMap.RemoveAndCopyValue("Agent", agentValues); TSharedPtr<FJsonObject> agentObject = agentValues->AsObject(); TMap<FString, TSharedPtr<FJsonValue>> agentValuesMap = agentObject->Values; for (auto const& y : agentValuesMap) { if (y.Key == "ResRefName") { y.Value.Get()->TryGetString(sValue); plot.ResRefName = sValue; } if (y.Key == "LocalCopy") { y.Value.Get()->TryGetString(sValue); plot.LocalCopy = sValue == "False" ? false : true; } if (y.Key == "Name") { y.Value.Get()->TryGetString(sValue); plot.Name = sValue; } if (y.Key == "NameStringID") { y.Value.Get()->TryGetString(sValue); plot.NameStringID = FCString::Atoi(*sValue); } if (y.Key == "NameRequiresReTranslation") { y.Value.Get()->TryGetString(sValue); plot.NameRequiresReTranslation = sValue == "False" ? false : true; } if (y.Key == "GUID") { y.Value.Get()->TryGetString(sValue); plot.GUID = sValue; } if (y.Key == "ScriptURI") { y.Value.Get()->TryGetString(sValue); plot.ScriptURI = FCString::Atoi(*sValue); } if (y.Key == "Priority") { y.Value.Get()->TryGetString(sValue); plot.Priority = FCString::Atoi(*sValue); } if (y.Key == "JournalImage") { y.Value.Get()->TryGetString(sValue); plot.JournalImage = sValue; } if (y.Key == "ParentPlotURI") { y.Value.Get()->TryGetString(sValue); plot.ParentPlotURI = FCString::Atoi(*sValue); } if (y.Key == "EntryType") { y.Value.Get()->TryGetString(sValue); plot.EntryType = FCString::Atoi(*sValue); } if (y.Key == "AllowPausing") { y.Value.Get()->TryGetString(sValue); plot.AllowPausing = sValue == "False" ? false : true; } } TSharedPtr<FJsonValue> StatusListValues; agentValuesMap.RemoveAndCopyValue("StatusList", StatusListValues); TSharedPtr<FJsonObject> StatusListObject = StatusListValues->AsObject(); TArray<TSharedPtr<FJsonValue>> StatusArray = StatusListObject->GetArrayField("Agent"); FPlotNode statusNode; if (StatusArray.Num() > 0) { int32 counter = 0; do { TSharedPtr<FJsonValue> StatusValue = StatusArray[counter]; TSharedPtr<FJsonObject> StatusObject = StatusValue->AsObject(); TMap<FString, TSharedPtr<FJsonValue>> StatusValuesMap = StatusObject->Values; for (auto const& x : StatusValuesMap) { if (x.Key == "Flag") { x.Value.Get()->TryGetString(sValue); statusNode.Flag = FCString::Atoi64(*sValue); } if (x.Key == "Name") { x.Value.Get()->TryGetString(sValue); statusNode.Name = sValue; } if (x.Key == "Final") { x.Value.Get()->TryGetString(sValue); statusNode.Final = sValue == "False" ? false : true; } if (x.Key == "Repeatable") { x.Value.Get()->TryGetString(sValue); statusNode.Repeatable = sValue == "False" ? false : true; } if (x.Key == "JournalText") { x.Value.Get()->TryGetString(sValue); statusNode.JournalText = sValue; } if (x.Key == "JournalTextStringID") { x.Value.Get()->TryGetString(sValue); statusNode.JournalTextStringID = FCString::Atoi(*sValue); } if (x.Key == "JournalTextRequiresReTranslation") { x.Value.Get()->TryGetString(sValue); statusNode.JournalTextRequiresReTranslation = sValue == "False" ? false : true; } if (x.Key == "RewardID") { x.Value.Get()->TryGetString(sValue); statusNode.RewardID = FCString::Atoi(*sValue); } if (x.Key == "Comment") { x.Value.Get()->TryGetString(sValue); statusNode.Comment = sValue; } if (x.Key == "DefaultValue") { x.Value.Get()->TryGetString(sValue); statusNode.DefaultValue = FCString::Atoi(*sValue); } if (x.Key == "AreaLocationTag") { x.Value.Get()->TryGetString(sValue); statusNode.AreaLocationTag = sValue; } if (x.Key == "OfferID") { x.Value.Get()->TryGetString(sValue); statusNode.OfferID = FCString::Atoi(*sValue); } } //update Flag with pattern ResRefID+"000"+Flag statusNode.Flag = PlotFlagConversion(plot.ResRefID, statusNode.Flag); FPlotElement ePlot; ePlot.pNode = statusNode; ePlot.pValue = 0; //false by default plot.StatusList.Add(ePlot); counter++; } while (counter < StatusArray.Num()); } #ifdef DEBUG LogWarning("Plot " + IntToString(nPlotID) + " parsed!!"); #endif // DEBUG //TODO PlotAssistInfoList GetParty()->Plots.Add(plot); } else { #ifdef DEBUG LogError("Not Deserialized" + aFullPath); #endif } return plot; }