diff --git a/src/game/src/DragonLair.cpp b/src/game/src/DragonLair.cpp index d31a61f..1ec3659 100644 --- a/src/game/src/DragonLair.cpp +++ b/src/game/src/DragonLair.cpp @@ -237,7 +237,7 @@ void CDragonLairManager::OnDragonDead(LPCHARACTER pDragon, DWORD KillerGuildID) iter->second->OnDragonDead( pDragon ); - // ֵ ֱ + // 애들 다 집으로 보내고 맵 없애기 tag_DragonLair_Collapse_EventInfo* info; info = AllocEventInfo(); diff --git a/src/game/src/DragonSoul.cpp b/src/game/src/DragonSoul.cpp index f508546..104fd43 100644 --- a/src/game/src/DragonSoul.cpp +++ b/src/game/src/DragonSoul.cpp @@ -31,7 +31,7 @@ int Gamble(std::vector& vec_probs) return -1; } -// ġ ̺(prob_lst) ޾ random_set.size() index Ͽ random_set return +// 가중치 테이블(prob_lst)을 받아 random_set.size()개의 index를 선택하여 random_set을 return bool MakeDistinctRandomNumberSet(std::list prob_lst, OUT std::vector& random_set) { int size = prob_lst.size(); @@ -67,11 +67,11 @@ bool MakeDistinctRandomNumberSet(std::list prob_lst, OUT std::vectorGetApplyNumSettings(ds_type, grade_idx, basic_apply_num, add_min, add_max)) { @@ -315,7 +315,7 @@ int DSManager::GetDuration(const LPITEM pItem) const return pItem->GetDuration(); } -// ȥ ޾Ƽ ϴ Լ +// 용혼석을 받아서 용심을 추출하는 함수 bool DSManager::ExtractDragonHeart(LPCHARACTER ch, LPITEM pItem, LPITEM pExtractor) { if (NULL == ch || NULL == pItem) @@ -397,7 +397,7 @@ bool DSManager::ExtractDragonHeart(LPCHARACTER ch, LPITEM pItem, LPITEM pExtract } } -// Ư ȥ â θ ϰ, н λ깰 ִ Լ. +// 특정 용혼석을 장비창에서 제거할 때에 성공 여부를 결정하고, 실패시 부산물을 주는 함수. bool DSManager::PullOut(LPCHARACTER ch, TItemPos DestCell, LPITEM& pItem, LPITEM pExtractor) { if (NULL == ch || NULL == pItem) @@ -406,7 +406,7 @@ bool DSManager::PullOut(LPCHARACTER ch, TItemPos DestCell, LPITEM& pItem, LPITEM return false; } - // ǥ ġ valid ˻ , valid ʴٸ ã´. + // 목표 위치가 valid한지 검사 후, valid하지 않다면 임의의 빈 공간을 찾는다. if (!IsValidCellForThisItem(pItem, DestCell)) { int iEmptyCell = ch->GetEmptyDragonSoulInventory(pItem); @@ -430,14 +430,14 @@ bool DSManager::PullOut(LPCHARACTER ch, TItemPos DestCell, LPITEM& pItem, LPITEM int iBonus = 0; float fProb; float fDice; - // ȥ . + // 용혼석 추출 성공 여부 결정. { DWORD dwVnum = pItem->GetVnum(); BYTE ds_type, grade_idx, step_idx, strength_idx; GetDragonSoulInfo(pItem->GetVnum(), ds_type, grade_idx, step_idx, strength_idx); - // ٸ ϴ ϴ ̶ . + // 추출 정보가 없다면 일단 무조건 성공하는 것이라 생각하자. if (!m_pTable->GetDragonSoulExtValues(ds_type, grade_idx, fProb, dwByProduct)) { pItem->AddToCharacter(ch, DestCell); @@ -454,7 +454,7 @@ bool DSManager::PullOut(LPCHARACTER ch, TItemPos DestCell, LPITEM& pItem, LPITEM bSuccess = fDice <= (fProb * (100 + iBonus) / 100.f); } - // ij ȥ ߰ Ȥ . λ깰 . + // 캐릭터의 용혼석 추출 및 추가 혹은 제거. 부산물 제공. { char buf[128]; @@ -519,8 +519,8 @@ bool DSManager::DoRefineGrade(LPCHARACTER ch, TItemPos (&aItemPoses)[DRAGON_SOUL return false; } - // Ȥó ߺǴ item pointer ֱ ؼ set - // ̻ Ŷ , ߺ TItemPos ְ, ߸ TItemPos ִ. + // 혹시나 모를 중복되는 item pointer 없애기 위해서 set 사용 + // 이상한 패킷을 보낼 경우, 중복된 TItemPos가 있을 수도 있고, 잘못된 TItemPos가 있을 수도 있다. std::set set_items; for (int i = 0; i < DRAGON_SOUL_REFINE_GRID_SIZE; i++) { @@ -529,7 +529,7 @@ bool DSManager::DoRefineGrade(LPCHARACTER ch, TItemPos (&aItemPoses)[DRAGON_SOUL LPITEM pItem = ch->GetItem(aItemPoses[i]); if (NULL != pItem) { - // ȥ ƴ â . + // 용혼석이 아닌 아이템이 개량창에 있을 수 없다. if (!pItem->IsDragonSoul()) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB5\xEE\xB1\xDE \xB0\xB3\xB7\xAE\xBF\xA1 \xC7\xCA\xBF\xE4\xC7\xD1 \xC0\xE7\xB7\xE1\xB0\xA1 \xBE\xC6\xB4\xD5\xB4\xCF\xB4\xD9.")); @@ -557,7 +557,7 @@ bool DSManager::DoRefineGrade(LPCHARACTER ch, TItemPos (&aItemPoses)[DRAGON_SOUL BYTE ds_type, grade_idx, step_idx, strength_idx; int result_grade; - // ó ȭ ´. + // 가장 처음 것을 강화의 기준으로 삼는다. std::set ::iterator it = set_items.begin(); { LPITEM pItem = *it; @@ -576,8 +576,8 @@ bool DSManager::DoRefineGrade(LPCHARACTER ch, TItemPos (&aItemPoses)[DRAGON_SOUL { LPITEM pItem = *it; - // Ŭ ui â ø ұ , - // ˸ ó . + // 클라 ui에서 장착한 아이템은 개량창에 올릴 수 없도록 막았기 때문에, + // 별도의 알림 처리는 안함. if (pItem->IsEquipped()) { return false; @@ -592,7 +592,7 @@ bool DSManager::DoRefineGrade(LPCHARACTER ch, TItemPos (&aItemPoses)[DRAGON_SOUL } } - // Ŭ󿡼 ѹ üũ ϱ count != need_count invalid Ŭ ɼ ũ. + // 클라에서 한번 갯수 체크를 하기 때문에 count != need_count라면 invalid 클라일 가능성이 크다. if (count != need_count) { SPDLOG_ERROR("Possiblity of invalid client. Name {}", ch->GetName()); @@ -679,15 +679,15 @@ bool DSManager::DoRefineStep(LPCHARACTER ch, TItemPos (&aItemPoses)[DRAGON_SOUL_ return false; } - // Ȥó ߺǴ item pointer ֱ ؼ set - // ̻ Ŷ , ߺ TItemPos ְ, ߸ TItemPos ִ. + // 혹시나 모를 중복되는 item pointer 없애기 위해서 set 사용 + // 이상한 패킷을 보낼 경우, 중복된 TItemPos가 있을 수도 있고, 잘못된 TItemPos가 있을 수도 있다. std::set set_items; for (int i = 0; i < DRAGON_SOUL_REFINE_GRID_SIZE; i++) { LPITEM pItem = ch->GetItem(aItemPoses[i]); if (NULL != pItem) { - // ȥ ƴ â . + // 용혼석이 아닌 아이템이 개량창에 있을 수 없다. if (!pItem->IsDragonSoul()) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB4\xDC\xB0\xE8 \xB0\xB3\xB7\xAE\xBF\xA1 \xC7\xCA\xBF\xE4\xC7\xD1 \xC0\xE7\xB7\xE1\xB0\xA1 \xBE\xC6\xB4\xD5\xB4\xCF\xB4\xD9.")); @@ -713,7 +713,7 @@ bool DSManager::DoRefineStep(LPCHARACTER ch, TItemPos (&aItemPoses)[DRAGON_SOUL_ BYTE ds_type, grade_idx, step_idx, strength_idx; int result_step; - // ó ȭ ´. + // 가장 처음 것을 강화의 기준으로 삼는다. std::set ::iterator it = set_items.begin(); { LPITEM pItem = *it; @@ -730,8 +730,8 @@ bool DSManager::DoRefineStep(LPCHARACTER ch, TItemPos (&aItemPoses)[DRAGON_SOUL_ while(++it != set_items.end()) { LPITEM pItem = *it; - // Ŭ ui â ø ұ , - // ˸ ó . + // 클라 ui에서 장착한 아이템은 개량창에 올릴 수 없도록 막았기 때문에, + // 별도의 알림 처리는 안함. if (pItem->IsEquipped()) { return false; @@ -744,7 +744,7 @@ bool DSManager::DoRefineStep(LPCHARACTER ch, TItemPos (&aItemPoses)[DRAGON_SOUL_ } } - // Ŭ󿡼 ѹ üũ ϱ count != need_count invalid Ŭ ɼ ũ. + // 클라에서 한번 갯수 체크를 하기 때문에 count != need_count라면 invalid 클라일 가능성이 크다. if (count != need_count) { SPDLOG_ERROR("Possiblity of invalid client. Name {}", ch->GetName()); @@ -840,8 +840,8 @@ bool DSManager::DoRefineStrength(LPCHARACTER ch, TItemPos (&aItemPoses)[DRAGON_S return false; } - // Ȥó ߺǴ item pointer ֱ ؼ set - // ̻ Ŷ , ߺ TItemPos ְ, ߸ TItemPos ִ. + // 혹시나 모를 중복되는 item pointer 없애기 위해서 set 사용 + // 이상한 패킷을 보낼 경우, 중복된 TItemPos가 있을 수도 있고, 잘못된 TItemPos가 있을 수도 있다. std::set set_items; for (int i = 0; i < DRAGON_SOUL_REFINE_GRID_SIZE; i++) { @@ -863,15 +863,15 @@ bool DSManager::DoRefineStrength(LPCHARACTER ch, TItemPos (&aItemPoses)[DRAGON_S for (std::set ::iterator it = set_items.begin(); it != set_items.end(); it++) { LPITEM pItem = *it; - // Ŭ ui â ø ұ , - // ˸ ó . + // 클라 ui에서 장착한 아이템은 개량창에 올릴 수 없도록 막았기 때문에, + // 별도의 알림 처리는 안함. if (pItem->IsEquipped()) { return false; } - // ȥ ȭ â ִ. - // ׸ ϳ ־Ѵ. + // 용혼석과 강화석만이 개량창에 있을 수 있다. + // 그리고 하나씩만 있어야한다. if (pItem->IsDragonSoul()) { if (pDragonSoul != NULL) @@ -912,14 +912,14 @@ bool DSManager::DoRefineStrength(LPCHARACTER ch, TItemPos (&aItemPoses)[DRAGON_S GetDragonSoulInfo(pDragonSoul->GetVnum(), bType, bGrade, bStep, bStrength); float fWeight = 0.f; - // ġ ٸ ȭ ȥ + // 가중치 값이 없다면 강화할 수 없는 용혼석 if (!m_pTable->GetWeight(bType, bGrade, bStep, bStrength + 1, fWeight)) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB0\xAD\xC8\xAD\xC7\xD2 \xBC\xF6 \xBE\xF8\xB4\xC2 \xBF\xEB\xC8\xA5\xBC\xAE\xC0\xD4\xB4\xCF\xB4\xD9.")); SendRefineResultPacket(ch, DS_SUB_HEADER_REFINE_FAIL_MAX_REFINE, TItemPos(pDragonSoul->GetWindow(), pDragonSoul->GetCell())); return false; } - // ȭ ġ 0̶ ̻ ȭǼ ȵȴ. + // 강화했을 때 가중치가 0이라면 더 이상 강화되서는 안된다. if (fWeight < FLT_EPSILON) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB0\xAD\xC8\xAD\xC7\xD2 \xBC\xF6 \xBE\xF8\xB4\xC2 \xBF\xEB\xC8\xA5\xBC\xAE\xC0\xD4\xB4\xCF\xB4\xD9.")); @@ -988,7 +988,7 @@ bool DSManager::DoRefineStrength(LPCHARACTER ch, TItemPos (&aItemPoses)[DRAGON_S char buf[128]; sprintf(buf, "STRENGTH : %d -> %d", bStrength, bStrength - 1); - // strengthȭ н ־, α׸ . + // strength강화는 실패시 깨질 수도 있어, 원본 아이템을 바탕으로 로그를 남김. LogManager::instance().ItemLog(ch, pDragonSoul, "DS_STRENGTH_REFINE_FAIL", buf); ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB0\xAD\xC8\xAD\xBF\xA1 \xBD\xC7\xC6\xD0\xC7\xDF\xBD\xC0\xB4\xCF\xB4\xD9.")); @@ -1029,12 +1029,12 @@ int DSManager::LeftTime(LPITEM pItem) const if (pItem == NULL) return false; - // ϴ timer based on wear ȥ ð Ǿ . + // 일단은 timer based on wear인 용혼석만 시간 다 되어도 안 없어진다. if (pItem->GetProto()->cLimitTimerBasedOnWearIndex >= 0) { return pItem->GetSocket(ITEM_SOCKET_REMAIN_SEC); } - // ٸ limit type ȥ ð Ǹ ϴ ð Ҵٰ Ǵ. + // 다른 limit type인 용혼석들은 시간 되면 모두 사라지기 때문에 여기 들어온 아이템은 일단 시간이 남았다고 판단. else { return INT_MAX; @@ -1046,12 +1046,12 @@ bool DSManager::IsTimeLeftDragonSoul(LPITEM pItem) const if (pItem == NULL) return false; - // ϴ timer based on wear ȥ ð Ǿ . + // 일단은 timer based on wear인 용혼석만 시간 다 되어도 안 없어진다. if (pItem->GetProto()->cLimitTimerBasedOnWearIndex >= 0) { return pItem->GetSocket(ITEM_SOCKET_REMAIN_SEC) > 0; } - // ٸ limit type ȥ ð Ǹ ϴ ð Ҵٰ Ǵ. + // 다른 limit type인 용혼석들은 시간 되면 모두 사라지기 때문에 여기 들어온 아이템은 일단 시간이 남았다고 판단. else { return true; diff --git a/src/game/src/MarkConvert.cpp b/src/game/src/MarkConvert.cpp index 3ac11b0..06473b8 100644 --- a/src/game/src/MarkConvert.cpp +++ b/src/game/src/MarkConvert.cpp @@ -30,14 +30,14 @@ static Pixel * LoadOldGuildMarkImageFile() bool GuildMarkConvert(const std::vector & vecGuildID) { - // + // 폴더 생성 #ifndef __WIN32__ mkdir("mark", S_IRWXU); #else _mkdir("mark"); #endif - // ε ֳ? + // 인덱스 파일이 있나? #ifndef __WIN32__ if (0 != access(OLD_MARK_INDEX_FILENAME, F_OK)) #else @@ -45,13 +45,13 @@ bool GuildMarkConvert(const std::vector & vecGuildID) #endif return true; - // ε + // 인덱스 파일 열기 FILE* fp = fopen(OLD_MARK_INDEX_FILENAME, "r"); if (NULL == fp) return false; - // ̹ + // 이미지 파일 열기 Pixel * oldImagePtr = LoadOldGuildMarkImageFile(); if (NULL == oldImagePtr) @@ -61,8 +61,8 @@ bool GuildMarkConvert(const std::vector & vecGuildID) } /* - // guild_mark.tga targa ƴϰ, 512 * 512 * 4 ũ raw ̴. - // Ȯϱ targa Ϸ . + // guild_mark.tga가 실제 targa 파일이 아니고, 512 * 512 * 4 크기의 raw 파일이다. + // 눈으로 확인하기 위해 실제 targa 파일로 만든다. CGuildMarkImage * pkImage = new CGuildMarkImage; pkImage->Build("guild_mark_real.tga"); pkImage->Load("guild_mark_real.tga"); @@ -86,7 +86,7 @@ bool GuildMarkConvert(const std::vector & vecGuildID) continue; } - // mark id -> ̹ ġ ã + // mark id -> 이미지에서의 위치 찾기 uint row = mark_id / 32; uint col = mark_id % 32; @@ -102,7 +102,7 @@ bool GuildMarkConvert(const std::vector & vecGuildID) Pixel * src = oldImagePtr + sy * 512 + sx; Pixel * dst = mark; - // ̹ ũ Ѱ + // 옛날 이미지에서 마크 한개 복사 for (int y = 0; y != SGuildMark::HEIGHT; ++y) { for (int x = 0; x != SGuildMark::WIDTH; ++x) @@ -111,7 +111,7 @@ bool GuildMarkConvert(const std::vector & vecGuildID) src += 512; } - // ũ ýۿ ִ´. + // 새 길드 마크 시스템에 넣는다. CGuildMarkManager::instance().SaveMark(guild_id, (BYTE *) mark); line[0] = '\0'; } @@ -119,7 +119,7 @@ bool GuildMarkConvert(const std::vector & vecGuildID) free(oldImagePtr); fclose(fp); - // Ʈ ѹ ϸǹǷ Űش. + // 컨버트는 한번만 하면되므로 파일을 옮겨준다. #ifndef __WIN32__ system("mv -f guild_mark.idx guild_mark.idx.removable"); system("mv -f guild_mark.tga guild_mark.tga.removable"); diff --git a/src/game/src/MarkImage.cpp b/src/game/src/MarkImage.cpp index fe493c6..0b53e97 100644 --- a/src/game/src/MarkImage.cpp +++ b/src/game/src/MarkImage.cpp @@ -129,10 +129,10 @@ void CGuildMarkImage::GetData(UINT x, UINT y, UINT width, UINT height, void * da ilCopyPixels(x, y, 0, width, height, 1, IL_BGRA, IL_UNSIGNED_BYTE, data); } -// ̹ = 512x512 -// = ũ 4 x 4 -// ũ = 16 x 12 -// ̹ = 8 x 10 +// 이미지 = 512x512 +// 블럭 = 마크 4 x 4 +// 마크 = 16 x 12 +// 한 이미지의 블럭 = 8 x 10 // SERVER bool CGuildMarkImage::SaveMark(DWORD posMark, BYTE * pbImage) @@ -143,14 +143,14 @@ bool CGuildMarkImage::SaveMark(DWORD posMark, BYTE * pbImage) return false; } - // ũ ü ̹ ׸. + // 마크를 전체 이미지에 그린다. DWORD colMark = posMark % MARK_COL_COUNT; DWORD rowMark = posMark / MARK_COL_COUNT; printf("PutMark pos %u %ux%u\n", posMark, colMark * SGuildMark::WIDTH, rowMark * SGuildMark::HEIGHT); PutData(colMark * SGuildMark::WIDTH, rowMark * SGuildMark::HEIGHT, SGuildMark::WIDTH, SGuildMark::HEIGHT, pbImage); - // ׷ Ʈ + // 그려진 곳의 블럭을 업데이트 DWORD rowBlock = rowMark / SGuildMarkBlock::MARK_PER_BLOCK_HEIGHT; DWORD colBlock = colMark / SGuildMarkBlock::MARK_PER_BLOCK_WIDTH; @@ -197,7 +197,7 @@ bool CGuildMarkImage::SaveBlockFromCompressedData(DWORD posBlock, const BYTE * p return true; } -void CGuildMarkImage::BuildAllBlocks() // ̹ ü ȭ +void CGuildMarkImage::BuildAllBlocks() // 이미지 전체를 블럭화 { Pixel apxBuf[SGuildMarkBlock::SIZE]; SPDLOG_INFO("GuildMarkImage::BuildAllBlocks"); diff --git a/src/game/src/MarkManager.cpp b/src/game/src/MarkManager.cpp index 70b9088..3faa160 100644 --- a/src/game/src/MarkManager.cpp +++ b/src/game/src/MarkManager.cpp @@ -15,7 +15,7 @@ void CGuildMarkManager::__DeleteImage(CGuildMarkImage * pkImgDel) CGuildMarkManager::CGuildMarkManager() { - // mark id . () + // 남은 mark id 셋을 만든다. (서버용) for (DWORD i = 0; i < MAX_IMAGE_COUNT * CGuildMarkImage::MARK_TOTAL_COUNT; ++i) m_setFreeMarkID.insert(i); } @@ -44,7 +44,7 @@ void CGuildMarkManager::SetMarkPathPrefix(const char * prefix) m_pathPrefix = prefix; } -// ũ ε ҷ ( ) +// 마크 인덱스 불러오기 (서버에서만 사용) bool CGuildMarkManager::LoadMarkIndex() { char buf[64]; @@ -177,7 +177,7 @@ DWORD CGuildMarkManager::__AllocMarkID(DWORD guildID) DWORD markID = *it; DWORD imgIdx = markID / CGuildMarkImage::MARK_TOTAL_COUNT; - CGuildMarkImage * pkImage = __GetImage(imgIdx); // ̹ ٸ + CGuildMarkImage * pkImage = __GetImage(imgIdx); // 이미지가 없다면 만들기 위해 if (pkImage && AddMarkIDByGuildID(guildID, markID)) return markID; @@ -263,7 +263,7 @@ void CGuildMarkManager::GetDiffBlocks(DWORD imgIdx, const DWORD * crcList, std:: { mapDiffBlocks.clear(); - // Ŭ̾Ʈ ̹ û . + // 클라이언트에서 서버에 없는 이미지를 요청할 수는 없다. if (m_mapIdx_Image.end() == m_mapIdx_Image.find(imgIdx)) { SPDLOG_ERROR("invalid idx {}", imgIdx); @@ -290,7 +290,7 @@ bool CGuildMarkManager::SaveBlockFromCompressedData(DWORD imgIdx, DWORD posBlock // CLIENT bool CGuildMarkManager::GetBlockCRCList(DWORD imgIdx, DWORD * crcList) { - // Ŭ̾Ʈ ̹ û . + // 클라이언트에서 서버에 없는 이미지를 요청할 수는 없다. if (m_mapIdx_Image.end() == m_mapIdx_Image.find(imgIdx)) { SPDLOG_ERROR("invalid idx {}", imgIdx); diff --git a/src/game/src/OXEvent.cpp b/src/game/src/OXEvent.cpp index 24a0f95..7a45639 100644 --- a/src/game/src/OXEvent.cpp +++ b/src/game/src/OXEvent.cpp @@ -318,11 +318,11 @@ bool COXEventManager::CheckAnswer(bool answer) int len = snprintf(chatbuf, sizeof(chatbuf), "%s %u %u", Random::get(0, 1) == 1 ? "cheer1" : "cheer2", (DWORD)pkChar->GetVID(), 0); - // ϰ sizeof(chatbuf) ̻ truncateǾٴ .. + // 리턴값이 sizeof(chatbuf) 이상일 경우 truncate되었다는 뜻.. if (len < 0 || len >= (int) sizeof(chatbuf)) len = sizeof(chatbuf) - 1; - // \0 + // \0 문자 포함 ++len; TPacketGCChat pack_chat; diff --git a/src/game/src/PetSystem.cpp b/src/game/src/PetSystem.cpp index f801850..278eaa5 100644 --- a/src/game/src/PetSystem.cpp +++ b/src/game/src/PetSystem.cpp @@ -18,13 +18,13 @@ EVENTINFO(petsystem_event_info) CPetSystem* pPetSystem; }; -// PetSystem update ִ event. -// PetSystem CHRACTER_MANAGER FSM update ִ chracters ޸, -// Owner STATE update _UpdateFollowAI Լ update ش. -// ׷ owner state update CHRACTER_MANAGER ֱ , -// petsystem updateϴٰ pet unsummonϴ κп . -// (CHRACTER_MANAGER update ϸ chracter destroy pendingǾ, CPetSystem dangling ͸ ְ ȴ.) -// PetSystem Ʈ ִ event ߻Ŵ. +// PetSystem을 update 해주는 event. +// PetSystem은 CHRACTER_MANAGER에서 기존 FSM으로 update 해주는 기존 chracters와 달리, +// Owner의 STATE를 update 할 때 _UpdateFollowAI 함수로 update 해준다. +// 그런데 owner의 state를 update를 CHRACTER_MANAGER에서 해주기 때문에, +// petsystem을 update하다가 pet을 unsummon하는 부분에서 문제가 생겼다. +// (CHRACTER_MANAGER에서 update 하면 chracter destroy가 pending되어, CPetSystem에서는 dangling 포인터를 가지고 있게 된다.) +// 따라서 PetSystem만 업데이트 해주는 event를 발생시킴. EVENTFUNC(petsystem_update_event) { petsystem_event_info* info = dynamic_cast( event->info ); @@ -41,12 +41,12 @@ EVENTFUNC(petsystem_update_event) pPetSystem->Update(0); - // 0.25ʸ . + // 0.25초마다 갱신. return PASSES_PER_SEC(1) / 4; } -/// NOTE: 1ijͰ  ִ ... ij͸ ٸ ҰŶ ֵ... .. -/// ִ ÿ ȯ ִ Ʋ ִµ ̷ ȹ ϴ +/// NOTE: 1캐릭터가 몇개의 펫을 가질 수 있는지 제한... 캐릭터마다 개수를 다르게 할거라면 변수로 넣등가... 음.. +/// 가질 수 있는 개수와 동시에 소환할 수 있는 개수가 틀릴 수 있는데 이런건 기획 없으니 일단 무시 const float PET_COUNT_LIMIT = 3; /////////////////////////////////////////////////////////////////////////////////////// @@ -119,7 +119,7 @@ void CPetActor::Unsummon() { if (true == this->IsSummoned()) { - // + // 버프 삭제 this->ClearBuff(); this->SetSummonItem(NULL); if (NULL != m_pkOwner) @@ -175,14 +175,14 @@ DWORD CPetActor::Summon(const char* petName, LPITEM pSummonItem, bool bSpawnFar) // m_pkOwner->DetailLog(); // m_pkChar->DetailLog(); - // . + //펫의 국가를 주인의 국가로 설정함. m_pkChar->SetEmpire(m_pkOwner->GetEmpire()); m_dwVID = m_pkChar->GetVID(); this->SetName(petName); - // SetSummonItem(pSummonItem) θ Ŀ ComputePoints θ . + // SetSummonItem(pSummonItem)를 부른 후에 ComputePoints를 부르면 버프 적용됨. this->SetSummonItem(pSummonItem); m_pkOwner->ComputePoints(); m_pkChar->Show(m_pkOwner->GetMapIndex(), x, y, z); @@ -197,11 +197,11 @@ bool CPetActor::_UpdatAloneActionAI(float fMinDist, float fMaxDist) float dest_x = GetOwner()->GetX() + fDist * cos(r); float dest_y = GetOwner()->GetY() + fDist * sin(r); - //m_pkChar->SetRotation(Random::get(0, 359)); // + //m_pkChar->SetRotation(Random::get(0, 359)); // 방향은 랜덤으로 설정 //GetDeltaByDegree(m_pkChar->GetRotation(), fDist, &fx, &fy); - // Ӽ üũ; ġ ߰ ġ ٸ ʴ´. + // 느슨한 못감 속성 체크; 최종 위치와 중간 위치가 갈수없다면 가지 않는다. //if (!(SECTREE_MANAGER::instance().IsMovablePosition(m_pkChar->GetMapIndex(), m_pkChar->GetX() + (int) fx, m_pkChar->GetY() + (int) fy) // && SECTREE_MANAGER::instance().IsMovablePosition(m_pkChar->GetMapIndex(), m_pkChar->GetX() + (int) fx/2, m_pkChar->GetY() + (int) fy/2))) // return true; @@ -218,7 +218,7 @@ bool CPetActor::_UpdatAloneActionAI(float fMinDist, float fMaxDist) return true; } -// char_state.cpp StateHorseԼ ׳ C&P -_-; +// char_state.cpp StateHorse함수 그냥 C&P -_-; bool CPetActor::_UpdateFollowAI() { if (0 == m_pkChar->m_pkMobData) @@ -227,9 +227,9 @@ bool CPetActor::_UpdateFollowAI() return false; } - // NOTE: ij() ̵ ӵ ˾ƾ ϴµ, ش (m_pkChar->m_pkMobData->m_table.sMovingSpeed) ؼ ˾Ƴ - // m_pkChar->m_pkMobData invalid 찡 ߻. ð ľϰ ϴ m_pkChar->m_pkMobData ƿ ʵ . - // ⼭ Ź ˻ϴ ʱȭ 쵵 .. -_-;; ФФФФФФФФ + // NOTE: 캐릭터(펫)의 원래 이동 속도를 알아야 하는데, 해당 값(m_pkChar->m_pkMobData->m_table.sMovingSpeed)을 직접적으로 접근해서 알아낼 수도 있지만 + // m_pkChar->m_pkMobData 값이 invalid한 경우가 자주 발생함. 현재 시간관계상 원인은 다음에 파악하고 일단은 m_pkChar->m_pkMobData 값을 아예 사용하지 않도록 함. + // 여기서 매번 검사하는 이유는 최초 초기화 할 때 정상 값을 제대로 못얻어오는 경우도 있음.. -_-;; ㅠㅠㅠㅠㅠㅠㅠㅠㅠ if (0 == m_originalMoveSpeed) { const CMob* mobData = CMobManager::Instance().Get(m_dwVnum); @@ -237,14 +237,14 @@ bool CPetActor::_UpdateFollowAI() if (0 != mobData) m_originalMoveSpeed = mobData->m_table.sMovingSpeed; } - float START_FOLLOW_DISTANCE = 300.0f; // Ÿ ̻ Ѿư - float START_RUN_DISTANCE = 900.0f; // Ÿ ̻ پ Ѿư. + float START_FOLLOW_DISTANCE = 300.0f; // 이 거리 이상 떨어지면 쫓아가기 시작함 + float START_RUN_DISTANCE = 900.0f; // 이 거리 이상 떨어지면 뛰어서 쫓아감. - float RESPAWN_DISTANCE = 4500.f; // Ÿ ̻ ־ ȯ. - int APPROACH = 200; // Ÿ + float RESPAWN_DISTANCE = 4500.f; // 이 거리 이상 멀어지면 주인 옆으로 소환함. + int APPROACH = 200; // 접근 거리 - bool bDoMoveAlone = true; // ijͿ ȥ ϰ -_-; - bool bRun = false; // پ ϳ? + bool bDoMoveAlone = true; // 캐릭터와 가까이 있을 때 혼자 여기저기 움직일건지 여부 -_-; + bool bRun = false; // 뛰어야 하나? DWORD currentTime = get_dword_time(); @@ -272,7 +272,7 @@ bool CPetActor::_UpdateFollowAI() bRun = true; } - m_pkChar->SetNowWalking(!bRun); // NOTE: Լ ̸ ߴ° ˾Ҵµ SetNowWalking(false) ϸ ٴ°.. -_-; + m_pkChar->SetNowWalking(!bRun); // NOTE: 함수 이름보고 멈추는건줄 알았는데 SetNowWalking(false) 하면 뛰는거임.. -_-; Follow(APPROACH); @@ -288,7 +288,7 @@ bool CPetActor::_UpdateFollowAI() // m_dwLastActionTime = currentTime; // } //} - // Follow ΰ Ÿ ̳ ٸ + // Follow 중이지만 주인과 일정 거리 이내로 가까워졌다면 멈춤 else m_pkChar->SendMovePacket(FUNC_WAIT, 0, 0, 0, 0); //else if (currentTime - m_dwLastActionTime > Random::get(5000, 12000)) @@ -303,8 +303,8 @@ bool CPetActor::Update(DWORD deltaTime) { bool bResult = true; - // ׾ų, ȯ ° ̻ϴٸ . (NOTE: ̷ ȯ DEAD ¿ 찡 -_-;) - // ȯ ų, ° ƴ϶ . + // 펫 주인이 죽었거나, 소환된 펫의 상태가 이상하다면 펫을 없앰. (NOTE: 가끔가다 이런 저런 이유로 소환된 펫이 DEAD 상태에 빠지는 경우가 있음-_-;) + // 펫을 소환한 아이템이 없거나, 내가 가진 상태가 아니라면 펫을 없앰. if (m_pkOwner->IsDead() || (IsSummoned() && m_pkChar->IsDead()) || NULL == ITEM_MANAGER::instance().FindByVID(this->GetSummonItemVID()) || ITEM_MANAGER::instance().FindByVID(this->GetSummonItemVID())->GetOwner() != this->GetOwner() @@ -320,10 +320,10 @@ bool CPetActor::Update(DWORD deltaTime) return bResult; } -//NOTE : !!! MinDistance ũ ŭ ȭ follow ʴ´, +//NOTE : 주의!!! MinDistance를 크게 잡으면 그 변위만큼의 변화동안은 follow하지 않는다, bool CPetActor::Follow(float fMinDistance) { - // ġ ٶ Ѵ. + // 가려는 위치를 바라봐야 한다. if( !m_pkOwner || !m_pkChar) return false; @@ -367,7 +367,7 @@ void CPetActor::SetSummonItem (LPITEM pItem) void CPetActor::GiveBuff() { - // Ȳ ߻. + // 파황 펫 버프는 던전에서만 발생함. if (34004 == m_dwVnum || 34009 == m_dwVnum) { if (NULL == m_pkOwner->GetDungeon()) @@ -432,15 +432,15 @@ void CPetSystem::Destroy() m_petActorMap.clear(); } -/// ý Ʈ. ϵ AI ó . +/// 펫 시스템 업데이트. 등록된 펫들의 AI 처리 등을 함. bool CPetSystem::Update(DWORD deltaTime) { bool bResult = true; DWORD currentTime = get_dword_time(); - // CHARACTER_MANAGER ijͷ Update Ű ִ (Pulse Ǿִ) Ӱ ð ˾Ҵµ - // ٸ ̶-_-; ⿡ Է deltaTime ǹ̰ Ф + // CHARACTER_MANAGER에서 캐릭터류 Update할 때 매개변수로 주는 (Pulse라고 되어있는)값이 이전 프레임과의 시간차이인줄 알았는데 + // 전혀 다른 값이라서-_-; 여기에 입력으로 들어오는 deltaTime은 의미가 없음ㅠㅠ if (m_dwUpdatePeriod > currentTime - m_dwLastUpdateTime) return true; @@ -473,7 +473,7 @@ bool CPetSystem::Update(DWORD deltaTime) return bResult; } -/// Ͽ +/// 관리 목록에서 펫을 지움 void CPetSystem::DeletePet(DWORD mobVnum) { TPetActorMap::iterator iter = m_petActorMap.find(mobVnum); @@ -494,7 +494,7 @@ void CPetSystem::DeletePet(DWORD mobVnum) m_petActorMap.erase(iter); } -/// Ͽ +/// 관리 목록에서 펫을 지움 void CPetSystem::DeletePet(CPetActor* petActor) { for (TPetActorMap::iterator iter = m_petActorMap.begin(); iter != m_petActorMap.end(); ++iter) @@ -542,7 +542,7 @@ CPetActor* CPetSystem::Summon(DWORD mobVnum, LPITEM pSummonItem, const char* pet { CPetActor* petActor = this->GetByVnum(mobVnum); - // ϵ ƴ϶ Ͽ . + // 등록된 펫이 아니라면 새로 생성 후 관리 목록에 등록함. if (0 == petActor) { petActor = M2_NEW CPetActor(m_pkOwner, mobVnum, options); @@ -557,7 +557,7 @@ CPetActor* CPetSystem::Summon(DWORD mobVnum, LPITEM pSummonItem, const char* pet info->pPetSystem = this; - m_pkPetSystemUpdateEvent = event_create(petsystem_update_event, info, PASSES_PER_SEC(1) / 4); // 0.25 + m_pkPetSystemUpdateEvent = event_create(petsystem_update_event, info, PASSES_PER_SEC(1) / 4); // 0.25초 } return petActor; @@ -589,7 +589,7 @@ CPetActor* CPetSystem::GetByVID(DWORD vid) const return bFound ? petActor : 0; } -/// ߿ ־ VNUM ͸ ȯϴ Լ. +/// 등록 된 펫 중에서 주어진 몹 VNUM을 가진 액터를 반환하는 함수. CPetActor* CPetSystem::GetByVnum(DWORD vnum) const { CPetActor* petActor = 0; diff --git a/src/game/src/SpeedServer.cpp b/src/game/src/SpeedServer.cpp index bd8c503..962359b 100644 --- a/src/game/src/SpeedServer.cpp +++ b/src/game/src/SpeedServer.cpp @@ -3,7 +3,7 @@ #include "SpeedServer.h" #include "locale_service.h" -// 赵 ʽ ġ ý +// 쾌도 서버 보너스 경험치 시스템 // by rtsummit CSpeedServerManager::CSpeedServerManager() @@ -361,13 +361,13 @@ HME CSpeedServerEmpireExp::GetCurrentExpPriv(int &duration, bool &is_change) HME hme; - // ¥ holiday̸ holiday bonus Ѵ. + // 현재 날짜가 holiday이면 holiday bonus를 도입한다. if (holi_it != holiday_map.end()) { for (std::list ::iterator it = holi_it->second.begin(); it != wday_exp_table[datetime->tm_wday].end(); it++) { - // ð ð ȿ ԵǸ, + // 현재 시각이 시간 구간 안에 포함되면, if (total_sec < (it->hour * 3600 + it->min * 60 )) { hme = *it; @@ -380,7 +380,7 @@ HME CSpeedServerEmpireExp::GetCurrentExpPriv(int &duration, bool &is_change) for (std::list ::iterator it = wday_exp_table[datetime->tm_wday].begin(); it != wday_exp_table[datetime->tm_wday].end(); it++) { - // ð ð ȿ ԵǸ, + // 현재 시각이 시간 구간 안에 포함되면, if (total_sec < (it->hour * 3600 + it->min * 60 )) { hme = *it; diff --git a/src/game/src/ani.cpp b/src/game/src/ani.cpp index 7f2469d..d49599b 100644 --- a/src/game/src/ani.cpp +++ b/src/game/src/ani.cpp @@ -55,7 +55,7 @@ const char* FN_weapon_type(int weapon) class ANI { protected: - // [][Ϲ0Ż1][][޺] + // [종족][일반0탈것1][무기][콤보] DWORD m_speed[MAIN_RACE_MAX_NUM][2][WEAPON_NUM_TYPES][9]; public: @@ -126,14 +126,14 @@ ANI::ANI() bool ANI::load() { const char* dir_name[MAIN_RACE_MAX_NUM] = { - "data/pc/warrior", // () - "data/pc/assassin", // ڰ() - "data/pc/sura", // () - "data/pc/shaman", // () - "data/pc2/warrior", // () - "data/pc2/assassin", // ڰ() - "data/pc2/sura", // () - "data/pc2/shaman" // () + "data/pc/warrior", // 무사(남) + "data/pc/assassin", // 자객(여) + "data/pc/sura", // 수라(남) + "data/pc/shaman", // 무당(여) + "data/pc2/warrior", // 무사(여) + "data/pc2/assassin", // 자객(남) + "data/pc2/sura", // 수라(여) + "data/pc2/shaman" // 무당(남) }; for (int race = 0; race GetPoint(POINT_ATT_SPEED)); */ - /* ڵ ҵ ↓ݰ ¸ */ - /* Ѽհ ӵ */ + /* 투핸디드 소드의 경우 삼연참공격과 승마시 */ + /* 오류가 많아 한손검 속도로 생각하자 */ if (weapon == WEAPON_TWO_HANDED) weapon = WEAPON_SWORD; diff --git a/src/game/src/arena.cpp b/src/game/src/arena.cpp index 33068d4..ce3e994 100644 --- a/src/game/src/arena.cpp +++ b/src/game/src/arena.cpp @@ -290,7 +290,7 @@ EVENTFUNC(ready_to_start_event) duelStart.header = HEADER_GC_DUEL_START; duelStart.wSize = sizeof(TPacketGCDuelStart) + 4; - DWORD dwOppList[8]; // ִ Ƽ 8 ̹Ƿ.. + DWORD dwOppList[8]; // 최대 파티원 8명 이므로.. dwOppList[0] = (DWORD)chB->GetVID(); TEMP_BUFFER buf; @@ -339,7 +339,7 @@ EVENTFUNC(ready_to_start_event) TEMP_BUFFER buf; TEMP_BUFFER buf2; - DWORD dwOppList[8]; // ִ Ƽ 8 ̹Ƿ.. + DWORD dwOppList[8]; // 최대 파티원 8명 이므로.. TPacketGCDuelStart duelStart; duelStart.header = HEADER_GC_DUEL_START; duelStart.wSize = sizeof(TPacketGCDuelStart) + 4; @@ -678,7 +678,7 @@ bool CArenaMap::CanAttack(LPCHARACTER pCharAttacker, LPCHARACTER pCharVictim) bool CArena::CanAttack(DWORD dwPIDA, DWORD dwPIDB) { - // 1:1 ٴ ʿ + // 1:1 전용 다대다 할 경우 수정 필요 if (m_dwPIDA == dwPIDA && m_dwPIDB == dwPIDB) return true; if (m_dwPIDA == dwPIDB && m_dwPIDB == dwPIDA) return true; @@ -728,7 +728,7 @@ bool CArena::OnDead(DWORD dwPIDA, DWORD dwPIDB) if (pCharA == NULL && pCharB == NULL) { - // Ѵ ?! + // 둘다 접속이 끊어졌다 ?! SendChatPacketToObserver(CHAT_TYPE_NOTICE, LC_TEXT("\xB4\xEB\xB7\xC3\xC0\xDA \xB9\xAE\xC1\xA6\xB7\xCE \xC0\xCE\xC7\xCF\xBF\xA9 \xB4\xEB\xB7\xC3\xC0\xBB \xC1\xDF\xB4\xDC\xC7\xD5\xB4\xCF\xB4\xD9.")); restart = false; } @@ -811,7 +811,7 @@ bool CArena::OnDead(DWORD dwPIDA, DWORD dwPIDB) } else { - // ȵȴ ?! + // 오면 안된다 ?! } if (restart == false) diff --git a/src/game/src/auction_manager.cpp b/src/game/src/auction_manager.cpp index 12a405c..801a657 100644 --- a/src/game/src/auction_manager.cpp +++ b/src/game/src/auction_manager.cpp @@ -215,7 +215,7 @@ void AuctionBoard::YourItemInfoList (TItemInfoVec& vec, DWORD player_id, int sta } // 0~1, 2~3, 4~5, 6~7, 8~9 -// ¦ descending, Ȧ accending. +// 짝수면 descending, 홀수면 accending. struct FCheckGradeSatisfied { BYTE grade; @@ -796,7 +796,7 @@ void AuctionManager::YourBidItemInfoList (AuctionBoard::TItemInfoVec& vec, DWORD } else { - // expired ⼭ ־Ѵ. + // expired 만들고 여기서 넣어야한다. } } } @@ -975,7 +975,7 @@ void AuctionManager::bid (LPCHARACTER ch, DWORD item_id, int bid_price) } // fixme -// ݵ !!! +// 반드시 돈!!! void AuctionManager::immediate_purchase (LPCHARACTER ch, DWORD item_id) { TAuctionItemInfo* item_info = GetAuctionItemInfo (item_id); @@ -1005,7 +1005,7 @@ void AuctionManager::immediate_purchase (LPCHARACTER ch, DWORD item_id) db_clientdesc->DBPacket(HEADER_GD_COMMAND_AUCTION, ch->GetPlayerID(), &pack_impur, sizeof(TPacketGDCommnadAuction)); } -// +// 시작 void AuctionManager::get_auctioned_item (LPCHARACTER ch, DWORD item_id, DWORD item_num) { TItemTable* proto = ITEM_MANAGER::instance().GetTable(item_num); @@ -1120,7 +1120,7 @@ void AuctionManager::bid_cancel (LPCHARACTER ch, DWORD item_id) db_clientdesc->DBPacket(HEADER_GD_COMMAND_AUCTION, ch->GetPlayerID(), &pack_bc, sizeof(TPacketGDCommnadAuction)); } -// +// 끝 void AuctionManager::recv_result_auction (DWORD commander_id, TPacketDGResultAuction* cmd_result) { LPCHARACTER ch = CHARACTER_MANAGER::instance().FindByPID(commander_id); @@ -1354,7 +1354,7 @@ void AuctionManager::recv_result_auction (DWORD commander_id, TPacketDGResultAuc } else { - // insertϸ lock Ǯ. + // insert하면 lock이 풀린다. DWORD item_id = cmd_result->target; cmd_result++; TAuctionItemInfo* auction_info = (TAuctionItemInfo*)cmd_result; diff --git a/src/game/src/banword.cpp b/src/game/src/banword.cpp index 816b7c1..5fb782a 100644 --- a/src/game/src/banword.cpp +++ b/src/game/src/banword.cpp @@ -3,7 +3,7 @@ #include "banword.h" #include "config.h" -extern void SendLog(const char * c_pszBuf); // ڿԸ +extern void SendLog(const char * c_pszBuf); // 운영자에게만 공지 CBanwordManager::CBanwordManager() { diff --git a/src/game/src/battle.cpp b/src/game/src/battle.cpp index 8f9bf3a..b689003 100644 --- a/src/game/src/battle.cpp +++ b/src/game/src/battle.cpp @@ -46,7 +46,7 @@ bool timed_event_cancel(LPCHARACTER ch) } /* RECALL_DELAY - ȯ ̰ Ǿ ּ + 차후 전투로 인해 귀환부 딜레이가 취소 되어야 할 경우 주석 해제 if (ch->m_pk_RecallEvent) { event_cancel(&ch->m_pkRecallEvent); @@ -59,11 +59,11 @@ bool timed_event_cancel(LPCHARACTER ch) bool battle_is_attackable(LPCHARACTER ch, LPCHARACTER victim) { - // ׾ ߴѴ. + // 상대방이 죽었으면 중단한다. if (victim->IsDead()) return false; - // ߴ + // 안전지대면 중단 { SECTREE *sectree = NULL; @@ -77,7 +77,7 @@ bool battle_is_attackable(LPCHARACTER ch, LPCHARACTER victim) } - // ׾ ߴѴ. + // 내가 죽었으면 중단한다. if (ch->IsStun() || ch->IsDead()) return false; @@ -119,7 +119,7 @@ int battle_melee_attack(LPCHARACTER ch, LPCHARACTER victim) if (test_server&&ch->IsPC()) SPDLOG_TRACE("battle_melee_attack : [{}] attack to [{}]", ch->GetName(), victim->GetName()); - // Ÿ üũ + // 거리 체크 int distance = DISTANCE_APPROX(ch->GetX() - victim->GetX(), ch->GetY() - victim->GetY()); if (!victim->IsBuilding()) @@ -128,12 +128,12 @@ int battle_melee_attack(LPCHARACTER ch, LPCHARACTER victim) if (false == ch->IsPC()) { - // Ÿ + // 몬스터의 경우 몬스터 공격 거리를 사용 max = (int) (ch->GetMobAttackRange() * 1.15f); } else { - // PC 밡 melee Ÿ ִ Ÿ + // PC일 경우 상대가 melee 몹일 경우 몹의 공격 거리가 최대 공격 거리 if (false == victim->IsPC() && BATTLE_TYPE_MELEE == victim->GetMobBattleType()) max = std::max(300, (int) (victim->GetMobAttackRange() * 1.15f)); } @@ -161,7 +161,7 @@ int battle_melee_attack(LPCHARACTER ch, LPCHARACTER victim) return battle_hit(ch, victim); } -// GET_BATTLE_VICTIM NULL ̺Ʈ ĵ Ų. +// 실제 GET_BATTLE_VICTIM을 NULL로 만들고 이벤트를 캔슬 시킨다. void battle_end_ex(LPCHARACTER ch) { if (ch->IsPosition(POS_FIGHTING)) @@ -208,7 +208,7 @@ float CalcAttackRating(LPCHARACTER pkAttacker, LPCHARACTER pkVictim, bool bIgnor int iARSrc; int iERSrc; - if (LC_IsYMIR()) // õ + if (LC_IsYMIR()) // 천마 { iARSrc = std::min(90, pkAttacker->GetPolymorphPoint(POINT_DX)); iERSrc = std::min(90, pkVictim->GetPolymorphPoint(POINT_DX)); @@ -238,11 +238,11 @@ float CalcAttackRating(LPCHARACTER pkAttacker, LPCHARACTER pkVictim, bool bIgnor int CalcAttBonus(LPCHARACTER pkAttacker, LPCHARACTER pkVictim, int iAtk) { - // PvP + // PvP에는 적용하지않음 if (!pkVictim->IsPC()) iAtk += pkAttacker->GetMarriageBonus(UNIQUE_ITEM_MARRIAGE_ATTACK_BONUS); - // PvP + // PvP에는 적용하지않음 if (!pkAttacker->IsPC()) { int iReduceDamagePct = pkVictim->GetMarriageBonus(UNIQUE_ITEM_MARRIAGE_TRANSFER_DAMAGE); @@ -327,9 +327,9 @@ int CalcAttBonus(LPCHARACTER pkAttacker, LPCHARACTER pkVictim, int iAtk) } } - //[ mob -> PC ] Ӽ + //[ mob -> PC ] 원소 속성 방어 적용 //2013/01/17 - // Ӽ 30% شϴ ġ . + //몬스터 속성공격 데미지의 30%에 해당하는 수치에만 저항이 적용됨. if (pkAttacker->IsNPC() && pkVictim->IsPC()) { if (pkAttacker->IsRaceFlag(RACE_FLAG_ATT_ELEC)) @@ -553,7 +553,7 @@ int CalcArrowDamage(LPCHARACTER pkAttacker, LPCHARACTER pkVictim, LPITEM pkBow, if (!pkArrow) return 0; - // Ÿġ + // 타격치 계산부 int iDist = (int) (DISTANCE_SQRT(pkAttacker->GetX() - pkVictim->GetX(), pkAttacker->GetY() - pkVictim->GetY())); //int iGap = (iDist / 100) - 5 - pkBow->GetValue(5) - pkAttacker->GetPoint(POINT_BOW_DISTANCE); int iGap = (iDist / 100) - 5 - pkAttacker->GetPoint(POINT_BOW_DISTANCE); @@ -613,7 +613,7 @@ int CalcArrowDamage(LPCHARACTER pkAttacker, LPCHARACTER pkVictim, LPITEM pkBow, void NormalAttackAffect(LPCHARACTER pkAttacker, LPCHARACTER pkVictim) { - // ƯϹǷ Ư ó + // 독 공격은 특이하므로 특수 처리 if (pkAttacker->GetPoint(POINT_POISON_PCT) && !pkVictim->IsAffectFlag(AFF_POISON)) { if (Random::get(1, 100) <= pkAttacker->GetPoint(POINT_POISON_PCT)) @@ -637,7 +637,7 @@ int battle_hit(LPCHARACTER pkAttacker, LPCHARACTER pkVictim) NormalAttackAffect(pkAttacker, pkVictim); - // + // 데미지 계산 //iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST)) / 100; LPITEM pkWeapon = pkAttacker->GetWear(WEAR_WEAPON); @@ -670,7 +670,7 @@ int battle_hit(LPCHARACTER pkAttacker, LPCHARACTER pkVictim) } - // . (2011 2 հŹ̿Ը .) + //최종적인 데미지 보정. (2011년 2월 현재 대왕거미에게만 적용.) float attMul = pkAttacker->GetAttMul(); float tempIDam = iDam; iDam = attMul * tempIDam + 0.5f; @@ -691,19 +691,19 @@ DWORD GET_ATTACK_SPEED(LPCHARACTER ch) return 1000; LPITEM item = ch->GetWear(WEAR_WEAPON); - DWORD default_bonus = SPEEDHACK_LIMIT_BONUS * 3; // θ (⺻ 80) (Ϲ speed hack ɸ *3 ߰. 2013.09.11 CYH) + DWORD default_bonus = SPEEDHACK_LIMIT_BONUS * 3; // 유두리 공속(기본 80) (일반 유저가 speed hack 에 걸리는 것을 막기 위해 *3 추가. 2013.09.11 CYH) DWORD riding_bonus = 0; if (ch->IsRiding()) { - // ߰ 50 + // 뭔가를 탔으면 추가공속 50 riding_bonus = 50; } DWORD ani_speed = ani_attack_speed(ch); DWORD real_speed = (ani_speed * 100) / (default_bonus + ch->GetPoint(POINT_ATT_SPEED) + riding_bonus); - // ܰ 2 + // 단검의 경우 공속 2배 if (item && item->GetSubType() == WEAPON_DAGGER) real_speed /= 2; diff --git a/src/game/src/blend_item.cpp b/src/game/src/blend_item.cpp index d803ca5..71fe401 100644 --- a/src/game/src/blend_item.cpp +++ b/src/game/src/blend_item.cpp @@ -170,10 +170,10 @@ static int FN_random_index() return 0; } -// ȯ Ȯ ̺ -// blend.txt Ȯ ޵ ġ ϰ -// 󺰷 item proto ϹǷ, -// ȥ ־ ̷ ߰Ѵ. +// 충기환의 확률 테이블 +// blend.txt에서 확률도 받도록 고치면 깔끔하겠지만 +// 각 나라별로 item proto 등을 따로 관리하므로, +// 혼란이 올 수 있어 이렇게 추가한다. // by rtsummit static int FN_ECS_random_index() diff --git a/src/game/src/block_country.cpp b/src/game/src/block_country.cpp index 6a1b70a..38951d8 100644 --- a/src/game/src/block_country.cpp +++ b/src/game/src/block_country.cpp @@ -119,7 +119,7 @@ bool is_blocked_country_ip(const char *user_ip) #endif { SPDLOG_INFO("BLOCKED_COUNTRY_IP ({}) : YES", user_ip); - return true; // ǰ ϴ ϴ ó + return true; // 아이피가 괴상하니 일단 블럭처리 } ip_number = htonl(st_addr.s_addr); diff --git a/src/game/src/buff_on_attributes.cpp b/src/game/src/buff_on_attributes.cpp index 1a44446..4a91f8a 100644 --- a/src/game/src/buff_on_attributes.cpp +++ b/src/game/src/buff_on_attributes.cpp @@ -39,8 +39,8 @@ void CBuffOnAttributes::RemoveBuffFromItem(LPITEM pItem) { TPlayerItemAttribute attr = pItem->GetAttribute(j); TMapAttr::iterator it = m_map_additional_attrs.find(attr.bType); - // m_map_additional_attrs ش attribute type ϰ, - // (m_bBuffValue)%ŭ ȿ + // m_map_additional_attrs에서 해당 attribute type에 대한 값을 제거하고, + // 변경된 값의 (m_bBuffValue)%만큼의 버프 효과 감소 if (it != m_map_additional_attrs.end()) { int& sum_of_attr_value = it->second; @@ -76,15 +76,15 @@ void CBuffOnAttributes::AddBuffFromItem(LPITEM pItem) TPlayerItemAttribute attr = pItem->GetAttribute(j); TMapAttr::iterator it = m_map_additional_attrs.find(attr.bType); - // m_map_additional_attrs ش attribute type ٸ ߰. - // ߰ (m_bBuffValue)%ŭ ȿ ߰ + // m_map_additional_attrs에서 해당 attribute type에 대한 값이 없다면 추가. + // 추가된 값의 (m_bBuffValue)%만큼의 버프 효과 추가 if (it == m_map_additional_attrs.end()) { m_pBuffOwner->ApplyPoint(attr.bType, attr.sValue * m_bBuffValue / 100); m_map_additional_attrs.insert(TMapAttr::value_type(attr.bType, attr.sValue)); } - // m_map_additional_attrs ش attribute type ִٸ, Ű, - // (m_bBuffValue)%ŭ ȿ ߰ + // m_map_additional_attrs에서 해당 attribute type에 대한 값이 있다면, 그 값을 증가시키고, + // 변경된 값의 (m_bBuffValue)%만큼의 버프 효과 추가 else { int& sum_of_attr_value = it->second; @@ -105,8 +105,8 @@ void CBuffOnAttributes::ChangeBuffValue(BYTE bNewValue) Off(); else { - // , m_map_additional_attrs (m_bBuffValue)%ŭ  ־Ƿ, - // (bNewValue)%ŭ . + // 기존에, m_map_additional_attrs의 값의 (m_bBuffValue)%만큼이 버프로 들어가 있었으므로, + // (bNewValue)%만큼으로 값을 변경함. for (TMapAttr::iterator it = m_map_additional_attrs.begin(); it != m_map_additional_attrs.end(); it++) { int& sum_of_attr_value = it->second; diff --git a/src/game/src/building.cpp b/src/game/src/building.cpp index 509f518..9773964 100644 --- a/src/game/src/building.cpp +++ b/src/game/src/building.cpp @@ -112,7 +112,7 @@ void CObject::EncodeInsertPacket(LPENTITY entity) pack.z = GetZ(); pack.wRaceNum = m_data.dwVnum; - // ȸ (϶ ġ) ȯ + // 빌딩 회전 정보(벽일때는 문 위치)를 변환 pack.dwAffectFlag[0] = unsigned(m_data.xRot); pack.dwAffectFlag[1] = unsigned(m_data.yRot); @@ -298,7 +298,7 @@ void CObject::RegenNPC() m_chNPC->SetGuild(pGuild); - // 渶 س´ + // 힘의 신전일 경우 길드 레벨을 길마에게 저장해놓는다 if ( m_pProto->dwVnum == 14061 || m_pProto->dwVnum == 14062 || m_pProto->dwVnum == 14063 ) { quest::PC* pPC = quest::CQuestManager::instance().GetPC(pGuild->GetMasterPID()); @@ -690,10 +690,10 @@ TObjectProto * CManager::GetObjectProto(DWORD dwVnum) bool CManager::LoadLand(TLand * pTable) // from DB { - // MapAllow load ؾѴ. - // ǹ(object) 忡 ִ ˱ ؼ ǹ Ҽ ˾Ѵ. - // load ǹ 忡 Ҽӵ ؼ - // ǹ Ѵ. + // MapAllow에 없는 맵의 땅일지라도 load를 해야한다. + // 건물(object)이 어느 길드에 속해 있는지 알기 위해서는 건물이 세위진 땅이 어느 길드 소속인지 알아한다. + // 만약 땅을 load해 놓지 않으면 길드 건물이 어느 길드에 소속된 건지 알지 못해서 + // 길드 건물에 의한 길드 버프를 받지 못한다. //if (!map_allow_find(pTable->lMapIndex)) // return false; @@ -1098,7 +1098,7 @@ bool CLand::RequestCreateWall(int nMapIndex, float rot) int wall_half_w = 1000; int wall_half_h = 1362; - if (rot == 0.0f) // + if (rot == 0.0f) // 남쪽 문 { int door_x = wall_x; int door_y = wall_y + wall_half_h; @@ -1107,7 +1107,7 @@ bool CLand::RequestCreateWall(int nMapIndex, float rot) RequestCreateObject(WALL_LEFT_VNUM, nMapIndex, wall_x - wall_half_w, wall_y, door_x, door_y, 0.0f, WALL_ANOTHER_CHECKING_ENABLE); RequestCreateObject(WALL_RIGHT_VNUM, nMapIndex, wall_x + wall_half_w, wall_y, door_x, door_y, 0.0f, WALL_ANOTHER_CHECKING_ENABLE); } - else if (rot == 180.0f) // + else if (rot == 180.0f) // 북쪽 문 { int door_x = wall_x; int door_y = wall_y - wall_half_h; @@ -1116,7 +1116,7 @@ bool CLand::RequestCreateWall(int nMapIndex, float rot) RequestCreateObject(WALL_LEFT_VNUM, nMapIndex, wall_x - wall_half_w, wall_y, door_x, door_y, 0.0f, WALL_ANOTHER_CHECKING_ENABLE); RequestCreateObject(WALL_RIGHT_VNUM, nMapIndex, wall_x + wall_half_w, wall_y, door_x, door_y, 0.0f, WALL_ANOTHER_CHECKING_ENABLE); } - else if (rot == 90.0f) // + else if (rot == 90.0f) // 동쪽 문 { int door_x = wall_x + wall_half_h; int door_y = wall_y; @@ -1125,7 +1125,7 @@ bool CLand::RequestCreateWall(int nMapIndex, float rot) RequestCreateObject(WALL_LEFT_VNUM, nMapIndex, wall_x, wall_y - wall_half_w, door_x, door_y, 90.0f, WALL_ANOTHER_CHECKING_ENABLE); RequestCreateObject(WALL_RIGHT_VNUM, nMapIndex, wall_x, wall_y + wall_half_w, door_x, door_y, 90.0f, WALL_ANOTHER_CHECKING_ENABLE); } - else if (rot == 270.0f) // + else if (rot == 270.0f) // 서쪽 문 { int door_x = wall_x - wall_half_h; int door_y = wall_y; diff --git a/src/game/src/castle.cpp b/src/game/src/castle.cpp index ff6e96d..bd673e2 100644 --- a/src/game/src/castle.cpp +++ b/src/game/src/castle.cpp @@ -3,8 +3,8 @@ * file : castle.cpp * author : mhh * description : - * ȭ ȣ : 11506 - 11510 - * ƾ ȣ : 8012 - 8014, 8024-8027 + * 봉화 번호 : 11506 - 11510 + * 메틴석 번호 : 8012 - 8014, 8024-8027 */ #define _castle_cpp_ @@ -21,13 +21,13 @@ #include "char.h" #include "sectree_manager.h" -#define EMPIRE_NONE 0 // ƹ ƴ -#define EMPIRE_RED 1 // ż -#define EMPIRE_YELLOW 2 // õ -#define EMPIRE_BLUE 3 // +#define EMPIRE_NONE 0 // 아무국가 아님 +#define EMPIRE_RED 1 // 신수 +#define EMPIRE_YELLOW 2 // 천조 +#define EMPIRE_BLUE 3 // 진노 -#define SIEGE_EVENT_PULSE PASSES_PER_SEC(60*5) // 5 +#define SIEGE_EVENT_PULSE PASSES_PER_SEC(60*5) // 5분 #define GET_CAHR_MANAGER() CHARACTER_MANAGER::instance() @@ -171,7 +171,7 @@ static POSITION s_frog_pos[4][MAX_CASTLE_FROG] = { }; -/* 񱸿 */ +/* 경비병 경비구역 */ struct GUARD_REGION { int sx, sy, ex, ey; @@ -247,7 +247,7 @@ EVENTFUNC(castle_siege_event) info->pulse += SIEGE_EVENT_PULSE; - // 30 ̳ ȳ + // 공성 시작후 30분 이내라면 안내만 하자 if (info->pulse < PASSES_PER_SEC(30*60)) { snprintf(buf, sizeof(buf), LC_TEXT("%s\xBF\xA1\xBC\xAD \xBA\xC0\xC8\xAD\xB8\xA6 \xB5\xD1\xB7\xAF\xBD\xCE\xB0\xED \xC0\xFC\xC5\xF5\xB0\xA1 \xC1\xF8\xC7\xE0\xC1\xDF\xC0\xD4\xB4\xCF\xB4\xD9."), @@ -272,7 +272,7 @@ EVENTFUNC(castle_siege_event) GET_SIEGE_STATE() = CASTLE_SIEGE_END; - return PASSES_PER_SEC(60*30); // 30 + return PASSES_PER_SEC(60*30); // 30분 } break; case CASTLE_SIEGE_END: @@ -331,7 +331,7 @@ EVENTFUNC(castle_stone_event) if (NULL == sectree_map) return 0; - /* 15 2 ȯ */ + /* 15마리씩 2번 소환 */ const int SPAWN_COUNT = 15; if (info->spawn_count < (SPAWN_COUNT * 2)) @@ -351,7 +351,7 @@ EVENTFUNC(castle_stone_event) info->spawn_count += SPAWN_COUNT; if (info->spawn_count < (SPAWN_COUNT * 2)) - return PASSES_PER_SEC(30 * 60); // 30 + return PASSES_PER_SEC(30 * 60); // 30분 else return 0; } @@ -598,24 +598,24 @@ void castle_start_siege(int empire, int tower_count) castle_spawn_tower(empire, tower_count); - /* Ÿ̸ */ + /* 공성 타이머 시작 */ { castle_event_info* info = AllocEventInfo(); info->empire = empire; info->pulse = 0; - GET_SIEGE_EVENT(empire) = event_create(castle_siege_event, info, /*5*/SIEGE_EVENT_PULSE); + GET_SIEGE_EVENT(empire) = event_create(castle_siege_event, info, /*5분*/SIEGE_EVENT_PULSE); } - /* ƾ ȯ Ÿ̸ */ + /* 메틴석 소환 타이머 시작 */ { castle_stone_event_info* info = AllocEventInfo(); info->spawn_count = 0; info->empire = empire; - GET_STONE_EVENT(empire) = event_create(castle_stone_event, info, /* 1 */PASSES_PER_SEC(1)); + GET_STONE_EVENT(empire) = event_create(castle_stone_event, info, /* 1초 */PASSES_PER_SEC(1)); } } @@ -649,7 +649,7 @@ LPCHARACTER castle_spawn_frog(int empire) int dir = 1; int map_index = FN_castle_map_index(empire); - /* Ȳݵβ ȯ ֳ? */ + /* 황금두꺼비 소환할 곳이 있나? */ POSITION *empty_pos = FN_empty_frog_pos(empire); if (NULL == empty_pos) return NULL; @@ -667,7 +667,7 @@ LPCHARACTER castle_spawn_frog(int empire) { frog->SetEmpire(empire); int empty_index = FN_empty_frog_index(empire); - // + // 스폰성공 GET_FROG(empire, empty_index) = frog; return frog; } @@ -778,7 +778,7 @@ bool castle_spawn_tower(int empire, int tower_count) if (NULL == sectree_map) return false; - // ʱȭ + // 초기화 DO_ALL_TOWER(i) { if (GET_TOWER(empire, i)) @@ -786,7 +786,7 @@ bool castle_spawn_tower(int empire, int tower_count) GET_TOWER(empire, i) = NULL; } - int spawn_count = std::clamp(tower_count, MIN_CASTLE_TOWER, MAX_CASTLE_TOWER); // 5 ~ 10 + int spawn_count = std::clamp(tower_count, MIN_CASTLE_TOWER, MAX_CASTLE_TOWER); // 5 ~ 10마리 for (int j = 0; j < spawn_count; ++j) { @@ -802,7 +802,7 @@ bool castle_spawn_tower(int empire, int tower_count) return true; } -/* 񺴸 ܼϰ Ը . */ +/* 경비병리더가 죽으면 단순하게 슬롯만 비운다. */ void castle_guard_die(LPCHARACTER ch, LPCHARACTER killer) { int empire = ch->GetEmpire(); @@ -823,7 +823,7 @@ void castle_guard_die(LPCHARACTER ch, LPCHARACTER killer) } -/* Ȳ β killer 1õ */ +/* 황금 두꺼비가 죽으면 killer에게 1천만냥 */ void castle_frog_die(LPCHARACTER ch, LPCHARACTER killer) { if (NULL == ch || NULL == killer) @@ -837,15 +837,15 @@ void castle_frog_die(LPCHARACTER ch, LPCHARACTER killer) { GET_FROG(empire, i) = NULL; - killer->PointChange(POINT_GOLD, 10000000 /*1õ*/, true); - //CMonarch::instance().SendtoDBAddMoney(30000000/*3õ*/, killer->GetEmpire(), killer); + killer->PointChange(POINT_GOLD, 10000000 /*1천만*/, true); + //CMonarch::instance().SendtoDBAddMoney(30000000/*3천만*/, killer->GetEmpire(), killer); castle_save(); return; } } } -/* ȭ (?) */ +/* 봉화가 모두 죽으면(?) 공성전이 끝난다 */ void castle_tower_die(LPCHARACTER ch, LPCHARACTER killer) { char buf[1024] = {0}; @@ -929,27 +929,27 @@ bool castle_is_guard_vnum(DWORD vnum) { switch (vnum) { - /* â */ + /* 상급 창경비병 */ case 11112: case 11114: case 11116: - /* ߱ â */ + /* 중급 창경비병 */ case 11106: case 11108: case 11110: - /* ϱ â */ + /* 하급 창경비병 */ case 11100: case 11102: case 11104: - /* Ȱ */ + /* 상급 활경비병 */ case 11113: case 11115: case 11117: - /* ߱ Ȱ */ + /* 중급 활경비병 */ case 11107: case 11109: case 11111: - /* ϱ Ȱ */ + /* 하급 활경비병 */ case 11101: case 11103: case 11105: @@ -963,34 +963,34 @@ int castle_cost_of_hiring_guard(DWORD group_vnum) { switch (group_vnum) { - /* ϱ */ - case 9501: /* ż â */ - case 9511: /* â */ - case 9521: /* õ â */ + /* 하급 */ + case 9501: /* 신수 창경비 */ + case 9511: /* 진노 창경비 */ + case 9521: /* 천조 창경비 */ - case 9502: /* ż Ȱ */ - case 9512: /* Ȱ */ - case 9522: /* õ Ȱ */ + case 9502: /* 신수 활경비 */ + case 9512: /* 진노 활경비 */ + case 9522: /* 천조 활경비 */ return (100*10000); - /* ߱ */ - case 9503: /* ż â */ - case 9513: /* â */ - case 9523: /* õ â */ + /* 중급 */ + case 9503: /* 신수 창경비 */ + case 9513: /* 진노 창경비 */ + case 9523: /* 천조 창경비 */ - case 9504: /* ż Ȱ */ - case 9514: /* Ȱ */ - case 9524: /* õ Ȱ */ + case 9504: /* 신수 활경비 */ + case 9514: /* 진노 활경비 */ + case 9524: /* 천조 활경비 */ return (300*10000); - /* */ - case 9505: /* ż â */ - case 9515: /* â */ - case 9525: /* õ â */ + /* 상급 */ + case 9505: /* 신수 창경비 */ + case 9515: /* 진노 창경비 */ + case 9525: /* 천조 창경비 */ - case 9506: /* ż Ȱ */ - case 9516: /* Ȱ */ - case 9526: /* õ Ȱ */ + case 9506: /* 신수 활경비 */ + case 9516: /* 진노 활경비 */ + case 9526: /* 천조 활경비 */ return (1000*10000); } @@ -1010,7 +1010,7 @@ bool castle_can_attack(LPCHARACTER ch, LPCHARACTER victim) if (CASTLE_SIEGE_END == GET_SIEGE_STATE()) { - // ȭ ĥ + // 수성에 성공했을때 같은 제국만 봉화를 칠 수 있음 if (castle_is_tower_vnum(victim->GetRaceNum())) { if (ch->GetEmpire() == victim->GetEmpire()) @@ -1020,7 +1020,7 @@ bool castle_can_attack(LPCHARACTER ch, LPCHARACTER victim) } } - // ı Ұ + // 같은 제국은 파괴 불가 if (ch->GetEmpire() == victim->GetEmpire()) return false; @@ -1044,7 +1044,7 @@ bool castle_frog_to_empire_money(LPCHARACTER ch) if (false == CMonarch::instance().SendtoDBAddMoney(CASTLE_FROG_PRICE, empire, ch)) return false; - GET_FROG(empire, i) = NULL; // + GET_FROG(empire, i) = NULL; // 등록해제 npc->Dead(/*killer*/NULL, /*immediate_dead*/true); return true; } diff --git a/src/game/src/char.cpp b/src/game/src/char.cpp index 4218c31..d95176b 100644 --- a/src/game/src/char.cpp +++ b/src/game/src/char.cpp @@ -465,7 +465,7 @@ void CHARACTER::Destroy() party->Quit(GetVID()); } - SetParty(NULL); // ���ص� ������ �����ϰ�. + SetParty(NULL); // 안해도 되지만 안전하게. } if (m_pkMobInst) @@ -563,16 +563,16 @@ void CHARACTER::OpenMyShop(const char * c_pszSign, TShopItemTable * pTable, BYTE return; } - if (GetMyShop()) // �̹� ���� ���� ������ �ݴ´�. + if (GetMyShop()) // 이미 샵이 열려 있으면 닫는다. { CloseMyShop(); return; } - // �������� ����Ʈ�� ������ ������ �� �� ����. + // 진행중인 퀘스트가 있으면 상점을 열 수 없다. quest::PC * pPC = quest::CQuestManager::instance().GetPCForce(GetPlayerID()); - // GetPCForce�� NULL�� �� �����Ƿ� ���� Ȯ������ ���� + // GetPCForce는 NULL일 수 없으므로 따로 확인하지 않음 if (pPC->IsRunning()) return; @@ -613,7 +613,7 @@ void CHARACTER::OpenMyShop(const char * c_pszSign, TShopItemTable * pTable, BYTE } // MYSHOP_PRICE_LIST - std::map itemkind; // ������ ������ ����, first: vnum, second: ���� ���� ���� + std::map itemkind; // 아이템 종류별 가격, first: vnum, second: 단일 수량 가격 // END_OF_MYSHOP_PRICE_LIST std::set cont; @@ -659,11 +659,11 @@ void CHARACTER::OpenMyShop(const char * c_pszSign, TShopItemTable * pTable, BYTE } // MYSHOP_PRICE_LIST - // ������ ������ ���ҽ�Ų��. - if (CountSpecifyItem(71049)) { // ��� �������� ������ �ʰ� ���������� �����Ѵ�. + // 보따리 개수를 감소시킨다. + if (CountSpecifyItem(71049)) { // 비단 보따리는 없애지 않고 가격정보를 저장한다. // - // ������ ���������� �����ϱ� ���� ������ �������� ��Ŷ�� ����� DB ij�ÿ� ������. + // 아이템 가격정보를 저장하기 위해 아이템 가격정보 패킷을 만들어 DB 캐시에 보낸다. // TPacketMyshopPricelistHeader header; TItemPriceInfo info; @@ -688,7 +688,7 @@ void CHARACTER::OpenMyShop(const char * c_pszSign, TShopItemTable * pTable, BYTE else if (CountSpecifyItem(50200)) RemoveSpecifyItem(50200, 1); else - return; // �������� ������ �ߴ�. + return; // 보따리가 없으면 중단. if (m_pkExchange) m_pkExchange->Cancel(); @@ -712,8 +712,8 @@ void CHARACTER::OpenMyShop(const char * c_pszSign, TShopItemTable * pTable, BYTE { HorseSummon( false, true ); } - // new mount �̿� �߿�, ���� ���� ���� �ڵ� unmount - // StopRiding���� ������Ʈ���� ó���ϸ� ������ �� �׷��� ���س����� �� �� ����. + // new mount 이용 중에, 개인 상점 열면 자동 unmount + // StopRiding으로 뉴마운트까지 처리하면 좋은데 왜 그렇게 안해놨는지 알 수 없다. else if (GetMountVnum()) { RemoveAffect(AFFECT_MOUNT); @@ -796,7 +796,7 @@ void CHARACTER::RestartAtSamePos() } -// Entity�� ���� ��Ÿ���ٰ� ��Ŷ�� ������. +// Entity에 내가 나타났다고 패킷을 보낸다. void CHARACTER::EncodeInsertPacket(LPENTITY entity) { @@ -805,10 +805,10 @@ void CHARACTER::EncodeInsertPacket(LPENTITY entity) if (!(d = entity->GetDesc())) return; - // ����̸� ���� ���� �ڵ� + // 길드이름 버그 수정 코드 LPCHARACTER ch = (LPCHARACTER) entity; ch->SendGuildName(GetGuild()); - // ����̸� ���� ���� �ڵ� + // 길드이름 버그 수정 코드 TPacketGCCharacterAdd pack; @@ -1267,7 +1267,7 @@ void CHARACTER::SaveReal() void CHARACTER::FlushDelayedSaveItem() { - // ���� �ȵ� ����ǰ�� ���� �����Ų��. + // 저장 안된 소지품을 전부 저장시킨다. LPITEM item; for (int i = 0; i < INVENTORY_AND_EQUIP_SLOT_MAX; ++i) @@ -1335,7 +1335,7 @@ void CHARACTER::Disconnect(const char * c_pszReason) if (GetParty()) GetParty()->Unlink(this); - // �׾��� �� ���Ӳ����� ����ġ �ٰ� �ϱ� + // 죽었을 때 접속끊으면 경험치 줄게 하기 if (IsStun() || IsDead()) { DeathPenalty(0); @@ -1353,7 +1353,7 @@ void CHARACTER::Disconnect(const char * c_pszReason) SaveAffect(); m_bIsLoadedAffect = false; - m_bSkipSave = true; // �� ���Ŀ��� ���̻� �����ϸ� �ȵȴ�. + m_bSkipSave = true; // 이 이후에는 더이상 저장하면 안된다. quest::CQuestManager::instance().DisconnectPC(this); @@ -1783,7 +1783,7 @@ void CHARACTER::SetPlayerProto(const TPlayerTable * t) SetSP(t->sp); SetStamina(t->stamina); - //GM�϶� ��ȣ��� + //GM일때 보호모드 if (!test_server) { if (GetGMLevel() > GM_LOW_WIZARD) @@ -1816,7 +1816,7 @@ void CHARACTER::SetPlayerProto(const TPlayerTable * t) } #ifdef __PET_SYSTEM__ - // NOTE: �ϴ� ij���Ͱ� PC�� ��쿡�� PetSystem�� ������ ��. ���� �ӽŴ� �޸� ���������� NPC���� �ϱ� ��.. + // NOTE: 일단 캐릭터가 PC인 경우에만 PetSystem을 갖도록 함. 유럽 머신당 메모리 사용률때문에 NPC까지 하긴 좀.. if (m_petSystem) { m_petSystem->Destroy(); @@ -1903,9 +1903,9 @@ void CHARACTER::SetProto(const CMob * pkMob) else SetPoint(POINT_DEF_GRADE_BONUS, 15); - //��Ÿ�� + //산타용 //m_dwPlayStartTime = get_dword_time() + 10 * 60 * 1000; - //�ż��� ���� + //신선자 노해 m_dwPlayStartTime = get_dword_time() + 30 * 1000; if (test_server) m_dwPlayStartTime = get_dword_time() + 30 * 1000; @@ -1980,7 +1980,7 @@ float CHARACTER::GetMobDamageMultiply() const float fDamMultiply = GetMobTable().fDamMultiply; if (IsBerserk()) - fDamMultiply = fDamMultiply * 2.0f; // BALANCE: ����ȭ �� �ι� + fDamMultiply = fDamMultiply * 2.0f; // BALANCE: 광폭화 시 두배 return fDamMultiply; } @@ -2013,7 +2013,7 @@ DWORD CHARACTER::GetMonsterDrainSPPoint() const BYTE CHARACTER::GetMobRank() const { if (!m_pkMobData) - return MOB_RANK_KNIGHT; // PC�� ��� KNIGHT�� + return MOB_RANK_KNIGHT; // PC일 경우 KNIGHT급 return m_pkMobData->m_table.bRank; } @@ -2076,7 +2076,7 @@ void CHARACTER::ComputeBattlePoints() SetPoint(POINT_MAGIC_DEF_GRADE, GetPoint(POINT_DEF_GRADE)); // - // �⺻ ATK = 2lev + 2str, ������ ���� 2str�� �ٲ� �� ���� + // 기본 ATK = 2lev + 2str, 직업에 마다 2str은 바뀔 수 있음 // int iAtk = GetLevel() * 2; int iStatAtk = 0; @@ -2102,14 +2102,14 @@ void CHARACTER::ComputeBattlePoints() break; } - // ���� Ÿ�� �ְ�, �������� ���� ���ݷ��� ST*2 ���� ������ ST*2�� �Ѵ�. - // ������ �߸� ���� ��� ���ݷ��� �� ���� �ʰ� �ϱ� ���ؼ���. + // 말을 타고 있고, 스탯으로 인한 공격력이 ST*2 보다 낮으면 ST*2로 한다. + // 스탯을 잘못 찍은 사람 공격력이 더 낮지 않게 하기 위해서다. if (GetMountVnum() && iStatAtk < 2 * GetPoint(POINT_ST)) iStatAtk = (2 * GetPoint(POINT_ST)); iAtk += iStatAtk; - // �¸�(��) : �˼��� ������ ���� + // 승마(말) : 검수라 데미지 감소 if (GetMountVnum()) { if (GetJob() == JOB_SURA && GetSkillGroup() == 1) @@ -2130,7 +2130,7 @@ void CHARACTER::ComputeBattlePoints() PointChange(POINT_ATT_GRADE, iAtk); // DEF = LEV + CON + ARMOR - int iShowDef = GetLevel() + GetPoint(POINT_HT); // For Ymir(õ��) + int iShowDef = GetLevel() + GetPoint(POINT_HT); // For Ymir(천마) int iDef = GetLevel() + (int) (GetPoint(POINT_HT) / 1.25); // For Other int iArmor = 0; @@ -2146,7 +2146,7 @@ void CHARACTER::ComputeBattlePoints() } } - // �� Ÿ�� ���� �� ������ ���� ���� ���º��� ������ ���� �������� ���� + // 말 타고 있을 때 방어력이 말의 기준 방어력보다 낮으면 기준 방어력으로 설정 if( true == IsHorseRiding() ) { if (iArmor < GetHorseArmor()) @@ -2252,7 +2252,7 @@ void CHARACTER::ComputePoints() if (IsPC()) { - // �ִ� �����/���ŷ� + // 최대 생명력/정신력 iMaxHP = JobInitialPoints[GetJob()].max_hp + m_points.iRandomHP + GetPoint(POINT_HT) * JobInitialPoints[GetJob()].hp_per_ht; iMaxSP = JobInitialPoints[GetJob()].max_sp + m_points.iRandomSP + GetPoint(POINT_IQ) * JobInitialPoints[GetJob()].sp_per_iq; iMaxStamina = JobInitialPoints[GetJob()].max_stamina + GetPoint(POINT_HT) * JobInitialPoints[GetJob()].stamina_per_con; @@ -2268,7 +2268,7 @@ void CHARACTER::ComputePoints() } } - // �⺻ ���� + // 기본 값들 SetPoint(POINT_MOV_SPEED, 100); SetPoint(POINT_ATT_SPEED, 100); PointChange(POINT_ATT_SPEED, GetPoint(POINT_PARTY_HASTE_BONUS)); @@ -2287,9 +2287,9 @@ void CHARACTER::ComputePoints() if (IsPC()) { - // �� Ÿ�� ���� ���� �⺻ ������ ���� ���� ���Ⱥ��� ������ ���� �����. - // ���� ���� ���� ������ ���� �����̹Ƿ�, ����/������ ��ü ���� ���� - // ��ä������ �� �ö󰡰� �� ���̴�. + // 말 타고 있을 때는 기본 스탯이 말의 기준 스탯보다 낮으면 높게 만든다. + // 따라서 말의 기준 스탯이 무사 기준이므로, 수라/무당은 전체 스탯 합이 + // 대채적으로 더 올라가게 될 것이다. if (GetMountVnum()) { if (GetHorseST() > GetPoint(POINT_ST)) @@ -2309,17 +2309,17 @@ void CHARACTER::ComputePoints() ComputeBattlePoints(); - // �⺻ HP/SP ���� + // 기본 HP/SP 설정 if (iMaxHP != GetMaxHP()) { - SetRealPoint(POINT_MAX_HP, iMaxHP); // �⺻HP�� RealPoint�� ������ ���´�. + SetRealPoint(POINT_MAX_HP, iMaxHP); // 기본HP를 RealPoint에 저장해 놓는다. } PointChange(POINT_MAX_HP, 0); if (iMaxSP != GetMaxSP()) { - SetRealPoint(POINT_MAX_SP, iMaxSP); // �⺻SP�� RealPoint�� ������ ���´�. + SetRealPoint(POINT_MAX_SP, iMaxSP); // 기본SP를 RealPoint에 저장해 놓는다. } PointChange(POINT_MAX_SP, 0); @@ -2338,10 +2338,10 @@ void CHARACTER::ComputePoints() } } - // ��ȥ�� �ý��� - // ComputePoints������ �ɸ����� ��� �Ӽ����� �ʱ�ȭ�ϰ�, - // ������, ���� � ���õ� ��� �Ӽ����� �����ϱ� ������, - // ��ȥ�� �ý��۵� ActiveDeck�� �ִ� ��� ��ȥ���� �Ӽ����� �ٽ� ������Ѿ� �Ѵ�. + // 용혼석 시스템 + // ComputePoints에서는 케릭터의 모든 속성값을 초기화하고, + // 아이템, 버프 등에 관련된 모든 속성값을 재계산하기 때문에, + // 용혼석 시스템도 ActiveDeck에 있는 모든 용혼석의 속성값을 다시 적용시켜야 한다. if (DragonSoul_IsDeckActivated()) { for (int i = WEAR_MAX_NUM + DS_SLOT_MAX * DragonSoul_GetActiveDeck(); @@ -2379,9 +2379,9 @@ void CHARACTER::ComputePoints() UpdatePacket(); } -// m_dwPlayStartTime�� ������ milisecond��. �����ͺ��̽����� �д����� ����ϱ� -// ������ �÷��̽ð��� ����� �� / 60000 ���� ������ �ϴµ�, �� ������ ���� ���� -// �� �� ���⿡ dwTimeRemain���� �־ ����� ���ǵ��� ���־�� �Ѵ�. +// m_dwPlayStartTime의 단위는 milisecond다. 데이터베이스에는 분단위로 기록하기 +// 때문에 플레이시간을 계산할 때 / 60000 으로 나눠서 하는데, 그 나머지 값이 남았 +// 을 때 여기에 dwTimeRemain으로 넣어서 제대로 계산되도록 해주어야 한다. void CHARACTER::ResetPlayTime(DWORD dwTimeRemain) { m_dwPlayStartTime = get_dword_time() - dwTimeRemain; @@ -2407,7 +2407,7 @@ EVENTFUNC(recovery_event) if (!ch->IsPC()) { // - // ���� ȸ�� + // 몬스터 회복 // if (ch->IsAffectFlag(AFF_POISON)) return PASSES_PER_SEC(std::max(1, ch->GetMobTable().bRegenCycle)); @@ -2465,23 +2465,23 @@ EVENTFUNC(recovery_event) else { // - // PC ȸ�� + // PC 회복 // ch->CheckTarget(); - //ch->UpdateSectree(); // ���⼭ �̰� ������? + //ch->UpdateSectree(); // 여기서 이걸 왜하지? ch->UpdateKillerMode(); if (ch->IsAffectFlag(AFF_POISON) == true) { - // �ߵ��� ��� �ڵ�ȸ�� ���� - // �Ĺ����� ��� �ڵ�ȸ�� ���� + // 중독인 경우 자동회복 금지 + // 파법술인 경우 자동회복 금지 return 3; } int iSec = (get_dword_time() - ch->GetLastMoveTime()) / 3000; - // SP ȸ�� ��ƾ. - // �� �̰ɷ� �ؼ� �Լ��� �����°� ?! + // SP 회복 루틴. + // 왜 이걸로 해서 함수로 빼놨는가 ?! ch->DistributeSP(ch); if (ch->GetMaxHP() <= ch->GetHP()) @@ -2512,7 +2512,7 @@ void CHARACTER::StartRecoveryEvent() if (IsDead() || IsStun()) return; - if (IsNPC() && GetHP() >= GetMaxHP()) // ���ʹ� ü���� �� �������� ���� ���Ѵ�. + if (IsNPC() && GetHP() >= GetMaxHP()) // 몬스터는 체력이 다 차있으면 시작 안한다. return; char_event_info* info = AllocEventInfo(); @@ -2562,7 +2562,7 @@ void CHARACTER::SetRotation(float fRot) m_pointsInstant.fRot = fRot; } -// x, y �������� ���� ����. +// x, y 방향으로 보고 선다. void CHARACTER::SetRotationToXY(int x, int y) { SetRotation(GetDegreeFromPositionXY(GetX(), GetY(), x, y)); @@ -2578,10 +2578,10 @@ bool CHARACTER::CanMove() const if (CannotMoveByAffect()) return false; - if (GetMyShop()) // ���� �� ���¿����� ������ �� ���� + if (GetMyShop()) // 상점 연 상태에서는 움직일 수 없음 return false; - // 0.2�� ���̶�� ������ �� ����. + // 0.2초 전이라면 움직일 수 없다. /* if (get_float_time() - m_fSyncTime < 0.2f) return false; @@ -2589,7 +2589,7 @@ bool CHARACTER::CanMove() const return true; } -// ������ x, y ��ġ�� �̵� ��Ų��. +// 무조건 x, y 위치로 이동 시킨다. bool CHARACTER::Sync(int x, int y) { if (!GetSectree()) @@ -2618,7 +2618,7 @@ bool CHARACTER::Sync(int x, int y) if (GetDungeon()) { - // ������ �̺�Ʈ �Ӽ� ��ȭ + // 던젼용 이벤트 속성 변화 int iLastEventAttr = m_iEventAttr; m_iEventAttr = new_tree->GetEventAttribute(x, y); @@ -2669,8 +2669,8 @@ void CHARACTER::Stop() bool CHARACTER::Goto(int x, int y) { - // TODO �Ÿ�üũ �ʿ� - // ���� ��ġ�� �̵��� �ʿ� ���� (�ڵ� ����) + // TODO 거리체크 필요 + // 같은 위치면 이동할 필요 없음 (자동 성공) if (GetX() == x && GetY() == y) return false; @@ -2800,14 +2800,14 @@ void CHARACTER::CalculateMoveDuration() m_dwMoveStartTime = get_dword_time(); } -// x y ��ġ�� �̵� �Ѵ�. (�̵��� �� �ִ� �� ���� ���� Ȯ�� �ϰ� Sync �޼ҵ�� ���� �̵� �Ѵ�) -// ������ char�� x, y ���� �ٷ� �ٲ�����, -// Ŭ�󿡼��� ���� ��ġ���� �ٲ� x, y���� interpolation�Ѵ�. -// �Ȱų� �ٴ� ���� char�� m_bNowWalking�� �޷��ִ�. -// Warp�� �ǵ��� ���̶�� Show�� ����� ��. +// x y 위치로 이동 한다. (이동할 수 있는 가 없는 가를 확인 하고 Sync 메소드로 실제 이동 한다) +// 서버는 char의 x, y 값을 바로 바꾸지만, +// 클라에서는 이전 위치에서 바꾼 x, y까지 interpolation한다. +// 걷거나 뛰는 것은 char의 m_bNowWalking에 달려있다. +// Warp를 의도한 것이라면 Show를 사용할 것. bool CHARACTER::Move(int x, int y) { - // ���� ��ġ�� �̵��� �ʿ� ���� (�ڵ� ����) + // 같은 위치면 이동할 필요 없음 (자동 성공) if (GetX() == x && GetY() == y) return true; @@ -2969,7 +2969,7 @@ void CHARACTER::SetPoint(BYTE type, int val) m_pointsInstant.points[type] = val; - // ���� �̵��� �� �ȳ����ٸ� �̵� �ð� ����� �ٽ� �ؾ� �Ѵ�. + // 아직 이동이 다 안끝났다면 이동 시간 계산을 다시 해야 한다. if (type == POINT_MOV_SPEED && get_dword_time() < m_dwMoveStartTime + m_dwMoveDuration) { CalculateMoveDuration(); @@ -3035,7 +3035,7 @@ void CHARACTER::PointChange(BYTE type, int amount, bool bAmount, bool bBroadcast case POINT_NEXT_EXP: val = GetNextExp(); - bAmount = false; // ������ bAmount�� false ���� �Ѵ�. + bAmount = false; // 무조건 bAmount는 false 여야 한다. break; case POINT_EXP: @@ -3043,7 +3043,7 @@ void CHARACTER::PointChange(BYTE type, int amount, bool bAmount, bool bBroadcast DWORD exp = GetExp(); DWORD next_exp = GetNextExp(); - // û�ҳ⺸ȣ + // 청소년보호 if (LC_IsNewCIBN()) { if (IsOverTime(OT_NONE)) @@ -3062,7 +3062,7 @@ void CHARACTER::PointChange(BYTE type, int amount, bool bAmount, bool bBroadcast } } - // exp�� 0 ���Ϸ� ���� �ʵ��� �Ѵ� + // exp가 0 이하로 가지 않도록 한다 if (amount < 0 && exp < -amount) { SPDLOG_DEBUG("{} AMOUNT < 0 {}, CUR EXP: {}", GetName(), -amount, exp); @@ -3081,7 +3081,7 @@ void CHARACTER::PointChange(BYTE type, int amount, bool bAmount, bool bBroadcast DWORD iExpBalance = 0; - // ���� ��! + // 레벨 업! if (exp + amount >= next_exp) { iExpBalance = (exp + amount) - next_exp; @@ -3099,7 +3099,7 @@ void CHARACTER::PointChange(BYTE type, int amount, bool bAmount, bool bBroadcast DWORD q = DWORD(next_exp / 4.0f); int iLevStep = GetRealPoint(POINT_LEVEL_STEP); - // iLevStep�� 4 �̻��̸� ������ �ö���� �ϹǷ� ���⿡ �� �� ���� ���̴�. + // iLevStep이 4 이상이면 레벨이 올랐어야 하므로 여기에 올 수 없는 값이다. if (iLevStep >= 4) { SPDLOG_ERROR("{} LEVEL_STEP bigger than 4! ({})", GetName(), iLevStep); @@ -3239,16 +3239,16 @@ void CHARACTER::PointChange(BYTE type, int amount, bool bAmount, bool bBroadcast if (val == 0) { - // Stamina�� ������ ����! + // Stamina가 없으니 걷자! SetNowWalking(true); } else if (prev_val == 0) { - // ���� ���׹̳��� �������� ���� ��� ���� + // 없던 스테미나가 생겼으니 이전 모드 복귀 ResetWalking(); } - if (amount < 0 && val != 0) // ���Ҵ� �������ʴ´�. + if (amount < 0 && val != 0) // 감소는 보내지않는다. return; } break; @@ -3258,7 +3258,7 @@ void CHARACTER::PointChange(BYTE type, int amount, bool bAmount, bool bBroadcast SetPoint(type, GetPoint(type) + amount); //SetMaxHP(GetMaxHP() + amount); - // �ִ� ����� = (�⺻ �ִ� ����� + �߰�) * �ִ�����% + // 최대 생명력 = (기본 최대 생명력 + 추가) * 최대생명력% int hp = GetRealPoint(POINT_MAX_HP); int add_hp = std::min(3500, hp * GetPoint(POINT_MAX_HP_PCT) / 100); add_hp += GetPoint(POINT_MAX_HP); @@ -3275,7 +3275,7 @@ void CHARACTER::PointChange(BYTE type, int amount, bool bAmount, bool bBroadcast SetPoint(type, GetPoint(type) + amount); //SetMaxSP(GetMaxSP() + amount); - // �ִ� ���ŷ� = (�⺻ �ִ� ���ŷ� + �߰�) * �ִ����ŷ�% + // 최대 정신력 = (기본 최대 정신력 + 추가) * 최대정신력% int sp = GetRealPoint(POINT_MAX_SP); int add_sp = std::min(800, sp * GetPoint(POINT_MAX_SP_PCT) / 100); add_sp += GetPoint(POINT_MAX_SP); @@ -3317,7 +3317,7 @@ void CHARACTER::PointChange(BYTE type, int amount, bool bAmount, bool bBroadcast return; } - // û�ҳ⺸ȣ + // 청소년보호 if (LC_IsNewCIBN() && amount > 0) { if (IsOverTime(OT_NONE)) @@ -3380,12 +3380,12 @@ void CHARACTER::PointChange(BYTE type, int amount, bool bAmount, bool bBroadcast case POINT_HP_RECOVERY: case POINT_SP_RECOVERY: - case POINT_ATTBONUS_HUMAN: // 42 �ΰ����� ���� - case POINT_ATTBONUS_ANIMAL: // 43 �������� ������ % ���� - case POINT_ATTBONUS_ORC: // 44 ���Ϳ��� ������ % ���� - case POINT_ATTBONUS_MILGYO: // 45 �б����� ������ % ���� - case POINT_ATTBONUS_UNDEAD: // 46 ��ü���� ������ % ���� - case POINT_ATTBONUS_DEVIL: // 47 ����(�Ǹ�)���� ������ % ���� + case POINT_ATTBONUS_HUMAN: // 42 인간에게 강함 + case POINT_ATTBONUS_ANIMAL: // 43 동물에게 데미지 % 증가 + case POINT_ATTBONUS_ORC: // 44 웅귀에게 데미지 % 증가 + case POINT_ATTBONUS_MILGYO: // 45 밀교에게 데미지 % 증가 + case POINT_ATTBONUS_UNDEAD: // 46 시체에게 데미지 % 증가 + case POINT_ATTBONUS_DEVIL: // 47 마귀(악마)에게 데미지 % 증가 case POINT_ATTBONUS_MONSTER: case POINT_ATTBONUS_SURA: @@ -3406,11 +3406,11 @@ void CHARACTER::PointChange(BYTE type, int amount, bool bAmount, bool bBroadcast case POINT_RESIST_PENETRATE: case POINT_CURSE_PCT: - case POINT_STEAL_HP: // 48 ����� ��� - case POINT_STEAL_SP: // 49 ���ŷ� ��� + case POINT_STEAL_HP: // 48 생명력 흡수 + case POINT_STEAL_SP: // 49 정신력 흡수 - case POINT_MANA_BURN_PCT: // 50 ���� �� - case POINT_DAMAGE_SP_RECOVER: // 51 ���ݴ��� �� ���ŷ� ȸ�� Ȯ�� + case POINT_MANA_BURN_PCT: // 50 마나 번 + case POINT_DAMAGE_SP_RECOVER: // 51 공격당할 시 정신력 회복 확률 case POINT_RESIST_NORMAL_DAMAGE: case POINT_RESIST_SWORD: case POINT_RESIST_TWOHAND: @@ -3425,10 +3425,10 @@ void CHARACTER::PointChange(BYTE type, int amount, bool bAmount, bool bBroadcast case POINT_RESIST_ICE: case POINT_RESIST_EARTH: case POINT_RESIST_DARK: - case POINT_REFLECT_MELEE: // 67 ���� �ݻ� - case POINT_REFLECT_CURSE: // 68 ���� �ݻ� - case POINT_POISON_REDUCE: // 69 �������� ���� - case POINT_KILL_SP_RECOVER: // 70 �� �Ҹ�� MP ȸ�� + case POINT_REFLECT_MELEE: // 67 공격 반사 + case POINT_REFLECT_CURSE: // 68 저주 반사 + case POINT_POISON_REDUCE: // 69 독데미지 감소 + case POINT_KILL_SP_RECOVER: // 70 적 소멸시 MP 회복 case POINT_KILL_HP_RECOVERY: // 75 case POINT_HIT_HP_RECOVERY: case POINT_HIT_SP_RECOVERY: @@ -3656,7 +3656,7 @@ void CHARACTER::ApplyPoint(BYTE bApplyType, int iVal) case APPLY_SKILL: // SKILL_DAMAGE_BONUS { - // �ֻ��� ��Ʈ �������� 8��Ʈ vnum, 9��Ʈ add, 15��Ʈ change + // 최상위 비트 기준으로 8비트 vnum, 9비트 add, 15비트 change // 00000000 00000000 00000000 00000000 // ^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^ // vnum ^ add change @@ -3766,11 +3766,11 @@ void CHARACTER::ApplyPoint(BYTE bApplyType, int iVal) case APPLY_RESIST_ASSASSIN : case APPLY_RESIST_SURA : case APPLY_RESIST_SHAMAN : - case APPLY_ENERGY: // 82 ��� - case APPLY_DEF_GRADE: // 83 ����. DEF_GRADE_BONUS�� Ŭ�󿡼� �ι�� �������� �ǵ��� ����(...)�� �ִ�. - case APPLY_COSTUME_ATTR_BONUS: // 84 �ڽ�Ƭ �����ۿ� ���� �Ӽ�ġ ���ʽ� - case APPLY_MAGIC_ATTBONUS_PER: // 85 ���� ���ݷ� +x% - case APPLY_MELEE_MAGIC_ATTBONUS_PER: // 86 ���� + �и� ���ݷ� +x% + case APPLY_ENERGY: // 82 기력 + case APPLY_DEF_GRADE: // 83 방어력. DEF_GRADE_BONUS는 클라에서 두배로 보여지는 의도된 버그(...)가 있다. + case APPLY_COSTUME_ATTR_BONUS: // 84 코스튬 아이템에 붙은 속성치 보너스 + case APPLY_MAGIC_ATTBONUS_PER: // 85 마법 공격력 +x% + case APPLY_MELEE_MAGIC_ATTBONUS_PER: // 86 마법 + 밀리 공격력 +x% PointChange(aApplyInfo[bApplyType].bPointType, iVal); break; @@ -3855,7 +3855,7 @@ void CHARACTER::MonsterLog(const char* format, ...) else len += len2; - // \0 ���� ���� + // \0 문자 포함 ++len; va_end(args); @@ -3945,9 +3945,9 @@ void CHARACTER::mining(LPCHARACTER chLoad) return; } - int count = Random::get(5, 15); // ���� Ƚ��, �� ���۴� 2�� + int count = Random::get(5, 15); // 동작 횟수, 한 동작당 2초 - // ä�� ������ ������ + // 채광 동작을 보여줌 TPacketGCDigMotion p; p.header = HEADER_GC_DIG_MOTION; p.vid = GetVID(); @@ -3968,7 +3968,7 @@ void CHARACTER::fishing() return; } - // ���� �Ӽ����� ���ø� �õ��Ѵ�? + // 못감 속성에서 낚시를 시도한다? { LPSECTREE_MAP pkSectreeMap = SECTREE_MANAGER::instance().GetMap(GetMapIndex()); @@ -3987,7 +3987,7 @@ void CHARACTER::fishing() LPITEM rod = GetWear(WEAR_WEAPON); - // ���ô� ���� + // 낚시대 장착 if (!rod || rod->GetType() != ITEM_ROD) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xC3\xB4\xEB\xB8\xA6 \xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD \xEF\xBF\xBD\xCF\xBC\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD.")); @@ -4066,7 +4066,7 @@ void CHARACTER::SetNextStatePulse(int iNextPulse) } -// ij���� �ν��Ͻ� ������Ʈ �Լ�. +// 캐릭터 인스턴스 업데이트 함수. void CHARACTER::UpdateCharacter(DWORD dwPulse) { CFSM::Update(); @@ -4105,7 +4105,7 @@ WORD CHARACTER::GetOriginalPart(BYTE bPartPos) const switch (bPartPos) { case PART_MAIN: - if (!IsPC()) // PC�� �ƴ� ��� ���� ��Ʈ�� �״�� ���� + if (!IsPC()) // PC가 아닌 경우 현재 파트를 그대로 리턴 return GetPart(PART_MAIN); else return m_pointsInstant.bBasePart; @@ -4146,7 +4146,7 @@ bool CHARACTER::SetSyncOwner(LPCHARACTER ch, bool bRemoveFromList) if (m_pkChrSyncOwner) SPDLOG_DEBUG("SyncRelease {} {} from {}", GetName(), (void*) this, m_pkChrSyncOwner->GetName()); - // ����Ʈ���� �������� �ʴ��� �����ʹ� NULL�� ���õǾ�� �Ѵ�. + // 리스트에서 제거하지 않더라도 포인터는 NULL로 셋팅되어야 한다. m_pkChrSyncOwner = NULL; } else @@ -4154,12 +4154,12 @@ bool CHARACTER::SetSyncOwner(LPCHARACTER ch, bool bRemoveFromList) if (!IsSyncOwner(ch)) return false; - // �Ÿ��� 200 �̻��̸� SyncOwner�� �� �� ����. + // 거리가 200 이상이면 SyncOwner가 될 수 없다. if (DISTANCE_APPROX(GetX() - ch->GetX(), GetY() - ch->GetY()) > 250) { SPDLOG_DEBUG("SetSyncOwner distance over than 250 {} {}", GetName(), ch->GetName()); - // SyncOwner�� ��� Owner�� ǥ���Ѵ�. + // SyncOwner일 경우 Owner로 표시한다. if (m_pkChrSyncOwner == ch) return true; @@ -4177,7 +4177,7 @@ bool CHARACTER::SetSyncOwner(LPCHARACTER ch, bool bRemoveFromList) m_pkChrSyncOwner = ch; m_pkChrSyncOwner->m_kLst_pkChrSyncOwned.push_back(this); - // SyncOwner�� �ٲ�� LastSyncTime�� �ʱ�ȭ�Ѵ�. + // SyncOwner가 바뀌면 LastSyncTime을 초기화한다. static const timeval zero_tv = {0, 0}; SetLastSyncTime(zero_tv); @@ -4187,9 +4187,9 @@ bool CHARACTER::SetSyncOwner(LPCHARACTER ch, bool bRemoveFromList) m_fSyncTime = get_float_time(); } - // TODO: Sync Owner�� ������ ��� ��Ŷ�� ������ �����Ƿ�, - // ����ȭ �� �ð��� 3�� �̻� ������ �� Ǯ���ִ� ��Ŷ�� - // ������ ������� �ϸ� ��Ŷ�� ���� �� �ִ�. + // TODO: Sync Owner가 같더라도 계속 패킷을 보내고 있으므로, + // 동기화 된 시간이 3초 이상 지났을 때 풀어주는 패킷을 + // 보내는 방식으로 하면 패킷을 줄일 수 있다. TPacketGCOwnership pack; pack.bHeader = HEADER_GC_OWNERSHIP; @@ -4205,7 +4205,7 @@ struct FuncClearSync void operator () (LPCHARACTER ch) { assert(ch != NULL); - ch->SetSyncOwner(NULL, false); // false �÷��׷� �ؾ� for_each �� ����� ����. + ch->SetSyncOwner(NULL, false); // false 플래그로 해야 for_each 가 제대로 돈다. } }; @@ -4213,7 +4213,7 @@ void CHARACTER::ClearSync() { SetSyncOwner(NULL); - // �Ʒ� for_each���� ���� m_pkChrSyncOwner�� ���� �ڵ��� �����͸� NULL�� �Ѵ�. + // 아래 for_each에서 나를 m_pkChrSyncOwner로 가진 자들의 포인터를 NULL로 한다. std::for_each(m_kLst_pkChrSyncOwned.begin(), m_kLst_pkChrSyncOwned.end(), FuncClearSync()); m_kLst_pkChrSyncOwned.clear(); } @@ -4223,8 +4223,8 @@ bool CHARACTER::IsSyncOwner(LPCHARACTER ch) const if (m_pkChrSyncOwner == ch) return true; - // ���������� ����ȭ �� �ð��� 3�� �̻� �����ٸ� �������� �ƹ����Ե� - // ����. ���� �ƹ��� SyncOwner�̹Ƿ� true ���� + // 마지막으로 동기화 된 시간이 3초 이상 지났다면 소유권이 아무에게도 + // 없다. 따라서 아무나 SyncOwner이므로 true 리턴 if (get_float_time() - m_fSyncTime >= 3.0f) return true; @@ -4257,11 +4257,11 @@ void CHARACTER::SetParty(LPPARTY pkParty) } // PARTY_JOIN_BUG_FIX -/// ��Ƽ ���� event ���� +/// 파티 가입 event 정보 EVENTINFO(TPartyJoinEventInfo) { - DWORD dwGuestPID; ///< ��Ƽ�� ������ ij������ PID - DWORD dwLeaderPID; ///< ��Ƽ ������ PID + DWORD dwGuestPID; ///< 파티에 참여할 캐릭터의 PID + DWORD dwLeaderPID; ///< 파티 리더의 PID TPartyJoinEventInfo() : dwGuestPID( 0 ) @@ -4451,8 +4451,8 @@ void CHARACTER::AcceptToParty(LPCHARACTER member) } /** - * ��Ƽ �ʴ� event callback �Լ�. - * event �� �ߵ��ϸ� �ʴ� ������ ó���Ѵ�. + * 파티 초대 event callback 함수. + * event 가 발동하면 초대 거절로 처리한다. */ EVENTFUNC(party_invite_event) { @@ -4540,7 +4540,7 @@ void CHARACTER::PartyInvite(LPCHARACTER pchInvitee) return; // - // EventMap �� �̺�Ʈ �߰� + // EventMap 에 이벤트 추가 // TPartyJoinEventInfo* info = AllocEventInfo(); @@ -4550,7 +4550,7 @@ void CHARACTER::PartyInvite(LPCHARACTER pchInvitee) m_PartyInviteEventMap.insert(EventMap::value_type(pchInvitee->GetPlayerID(), event_create(party_invite_event, info, PASSES_PER_SEC(10)))); // - // �ʴ� �޴� character ���� �ʴ� ��Ŷ ���� + // 초대 받는 character 에게 초대 패킷 전송 // TPacketGCPartyInvite p; @@ -4624,7 +4624,7 @@ void CHARACTER::PartyInviteAccept(LPCHARACTER pchInvitee) } // - // ��Ƽ ���� ó�� + // 파티 가입 처리 // if (GetParty()) @@ -4837,9 +4837,9 @@ void CHARACTER::OnClick(LPCHARACTER pkChrCauser) DWORD vid = GetVID(); SPDLOG_DEBUG("OnClick {}[vnum {} ServerUniqueID {}, pid {}] by {}", GetName(), GetRaceNum(), vid, GetPlayerID(), pkChrCauser->GetName()); - // ������ �����·� ����Ʈ�� ������ �� ����. + // 상점을 연상태로 퀘스트를 진행할 수 없다. { - // ��, �ڽ��� �ڽ��� ������ Ŭ���� �� �ִ�. + // 단, 자신은 자신의 상점을 클릭할 수 있다. if (pkChrCauser->GetMyShop() && pkChrCauser != this) { SPDLOG_ERROR("OnClick Fail ({}->{}) - pc has shop", pkChrCauser->GetName(), GetName()); @@ -4847,7 +4847,7 @@ void CHARACTER::OnClick(LPCHARACTER pkChrCauser) } } - // ��ȯ���϶� ����Ʈ�� ������ �� ����. + // 교환중일때 퀘스트를 진행할 수 없다. { if (pkChrCauser->GetExchange()) { @@ -4858,16 +4858,16 @@ void CHARACTER::OnClick(LPCHARACTER pkChrCauser) if (IsPC()) { - // Ÿ������ ������ ���� PC�� ���� Ŭ���� ����Ʈ�� ó���ϵ��� �մϴ�. + // 타겟으로 설정된 경우는 PC에 의한 클릭도 퀘스트로 처리하도록 합니다. if (!CTargetManager::instance().GetTargetInfo(pkChrCauser->GetPlayerID(), TARGET_TYPE_VID, GetVID())) { - // 2005.03.17.myevan.Ÿ���� �ƴ� ���� ���� ���� ó�� ����� �۵���Ų��. + // 2005.03.17.myevan.타겟이 아닌 경우는 개인 상점 처리 기능을 작동시킨다. if (GetMyShop()) { if (pkChrCauser->IsDead() == true) return; //PREVENT_TRADE_WINDOW - if (pkChrCauser == this) // �ڱ�� ���� + if (pkChrCauser == this) // 자기는 가능 { if ((GetExchange() || IsOpenSafebox() || GetShopOwner()) || IsCubeOpen()) { @@ -4875,16 +4875,16 @@ void CHARACTER::OnClick(LPCHARACTER pkChrCauser) return; } } - else // �ٸ� ����� Ŭ�������� + else // 다른 사람이 클릭했을때 { - // Ŭ���� ����� ��ȯ/â��/���λ���/�����̿����̶�� �Ұ� + // 클릭한 사람이 교환/창고/개인상점/상점이용중이라면 불가 if ((pkChrCauser->GetExchange() || pkChrCauser->IsOpenSafebox() || pkChrCauser->GetMyShop() || pkChrCauser->GetShopOwner()) || pkChrCauser->IsCubeOpen() ) { pkChrCauser->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xEF\xBF\xBD\xD9\xB8\xEF\xBF\xBD \xEF\xBF\xBD\xC5\xB7\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD(\xC3\xA2\xEF\xBF\xBD\xEF\xBF\xBD,\xEF\xBF\xBD\xEF\xBF\xBD\xC8\xAF,\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD)\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD \xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xCE\xBB\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD \xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD \xEF\xBF\xBD\xEF\xBF\xBD \xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xCF\xB4\xEF\xBF\xBD.")); return; } - // Ŭ���� ����� ��ȯ/â��/�����̿����̶�� �Ұ� + // 클릭한 대상이 교환/창고/상점이용중이라면 불가 //if ((GetExchange() || IsOpenSafebox() || GetShopOwner())) if ((GetExchange() || IsOpenSafebox() || IsCubeOpen())) { @@ -4911,7 +4911,7 @@ void CHARACTER::OnClick(LPCHARACTER pkChrCauser) } } - // û�ҳ��� ����Ʈ ���� + // 청소년은 퀘스트 못함 if (LC_IsNewCIBN()) { if (pkChrCauser->IsOverTime(OT_3HOUR)) @@ -4935,12 +4935,12 @@ void CHARACTER::OnClick(LPCHARACTER pkChrCauser) } - // NPC ���� ��� ���� : ���� ���� �� + // NPC 전용 기능 수행 : 상점 열기 등 if (!IsPC()) { if (!m_triggerOnClick.pFunc) { - // NPC Ʈ���� �ý��� �α� ���� + // NPC 트리거 시스템 로그 보기 SPDLOG_ERROR("{}.OnClickFailure({}) : triggerOnClick.pFunc is EMPTY(pid={})", pkChrCauser->GetName(), GetName(), @@ -5005,7 +5005,7 @@ void CHARACTER::ClearStone() { if (!m_set_pkChrSpawnedBy.empty()) { - // ���� ������Ų ���͵��� ��� ���δ�. + // 내가 스폰시킨 몬스터들을 모두 죽인다. FuncDeadSpawnedByStone f; std::for_each(m_set_pkChrSpawnedBy.begin(), m_set_pkChrSpawnedBy.end(), f); m_set_pkChrSpawnedBy.clear(); @@ -5181,9 +5181,9 @@ void CHARACTER::ExitToSavedLocation() } // fixme -// ���ݱ��� privateMapIndex �� ���� �� �ε����� ������ üũ �ϴ� ���� �ܺο��� �ϰ�, -// �ٸ��� warpset�� �ҷ��µ� -// �̸� warpset ������ ����. +// 지금까진 privateMapIndex 가 현재 맵 인덱스와 같은지 체크 하는 것을 외부에서 하고, +// 다르면 warpset을 불렀는데 +// 이를 warpset 안으로 넣자. bool CHARACTER::WarpSet(int x, int y, int lPrivateMapIndex) { if (!IsPC()) @@ -5279,7 +5279,7 @@ void CHARACTER::WarpEnd() if (!map_allow_find(index)) { - // �� ������ ������ �� �����Ƿ� �����ϱ� �� ��ǥ�� �ǵ�����. + // 이 곳으로 워프할 수 없으므로 워프하기 전 좌표로 되돌리자. SPDLOG_ERROR("location {} {} not allowed to login this server", m_posWarp.x, m_posWarp.y); GetDesc()->SetPhase(PHASE_CLOSE); return; @@ -5352,14 +5352,14 @@ bool CHARACTER::Follow(LPCHARACTER pkChr, float fMinDistance) // TRENT_MONSTER if (IS_SET(m_pointsInstant.dwAIFlag, AIFLAG_NOMOVE)) { - if (pkChr->IsPC()) // �Ѿư��� ��밡 PC�� �� + if (pkChr->IsPC()) // 쫓아가는 상대가 PC일 때 { // If i'm in a party. I must obey party leader's AI. if (!GetParty() || !GetParty()->GetLeader() || GetParty()->GetLeader() == this) { - if (get_dword_time() - m_pkMobInst->m_dwLastAttackedTime >= 15000) // ���������� ���ݹ����� 15�ʰ� ������ + if (get_dword_time() - m_pkMobInst->m_dwLastAttackedTime >= 15000) // 마지막으로 공격받은지 15초가 지났고 { - // ������ ���� ������ ���� 50���� �̻� ���̳��� �����ϰ� ���ư���. + // 마지막 맞은 곳으로 부터 50미터 이상 차이나면 포기하고 돌아간다. if (m_pkMobData->m_table.wAttackRange < DISTANCE_APPROX(pkChr->GetX() - GetX(), pkChr->GetY() - GetY())) if (Return()) return true; @@ -5373,14 +5373,14 @@ bool CHARACTER::Follow(LPCHARACTER pkChr, float fMinDistance) int x = pkChr->GetX(); int y = pkChr->GetY(); - if (pkChr->IsPC()) // �Ѿư��� ��밡 PC�� �� + if (pkChr->IsPC()) // 쫓아가는 상대가 PC일 때 { // If i'm in a party. I must obey party leader's AI. if (!GetParty() || !GetParty()->GetLeader() || GetParty()->GetLeader() == this) { - if (get_dword_time() - m_pkMobInst->m_dwLastAttackedTime >= 15000) // ���������� ���ݹ����� 15�ʰ� ������ + if (get_dword_time() - m_pkMobInst->m_dwLastAttackedTime >= 15000) // 마지막으로 공격받은지 15초가 지났고 { - // ������ ���� ������ ���� 50���� �̻� ���̳��� �����ϰ� ���ư���. + // 마지막 맞은 곳으로 부터 50미터 이상 차이나면 포기하고 돌아간다. if (5000 < DISTANCE_APPROX(m_pkMobInst->m_posLastAttacked.x - GetX(), m_pkMobInst->m_posLastAttacked.y - GetY())) if (Return()) return true; @@ -5400,9 +5400,9 @@ bool CHARACTER::Follow(LPCHARACTER pkChr, float fMinDistance) GetMobBattleType() != BATTLE_TYPE_MAGIC && false == IsPet()) { - // ����� �̵����̸� ���� �̵��� �Ѵ� - // ���� ������ �ӵ����� �Ÿ��κ��� ���� �ð��� ������ �� - // ������ �� �ð����� �������� �̵��Ѵٰ� �����Ͽ� �ű�� �̵��Ѵ�. + // 대상이 이동중이면 예측 이동을 한다 + // 나와 상대방의 속도차와 거리로부터 만날 시간을 예상한 후 + // 상대방이 그 시간까지 직선으로 이동한다고 가정하여 거기로 이동한다. float rot = pkChr->GetRotation(); float rot_delta = GetDegreeDelta(rot, GetDegreeFromPositionXY(GetX(), GetY(), pkChr->GetX(), pkChr->GetY())); @@ -5434,7 +5434,7 @@ bool CHARACTER::Follow(LPCHARACTER pkChr, float fMinDistance) } } - // ������ ��ġ�� �ٶ���� �Ѵ�. + // 가려는 위치를 바라봐야 한다. SetRotationToXY(x, y); float fDist = DISTANCE_SQRT(x - GetX(), y - GetY()); @@ -5446,7 +5446,7 @@ bool CHARACTER::Follow(LPCHARACTER pkChr, float fMinDistance) if (IsChangeAttackPosition(pkChr) && GetMobRank() < MOB_RANK_BOSS) { - // ���� �ֺ� ������ ������ �̵� + // 상대방 주변 랜덤한 곳으로 이동 SetChangeAttackPositionTime(); int retry = 16; @@ -5477,7 +5477,7 @@ bool CHARACTER::Follow(LPCHARACTER pkChr, float fMinDistance) } else { - // ���� ���󰡱� + // 직선 따라가기 float fDistToGo = fDist - fMinDistance; GetDeltaByDegree(GetRotation(), fDistToGo, &fx, &fy); @@ -6150,11 +6150,11 @@ void CHARACTER::SetPolymorph(DWORD dwRaceNum, bool bMaintainStat) PointChange(POINT_HT, 0); } - // �������� ���¿��� �״� ���, ���������� Ǯ���� �Ǵµ� - // ���� ���� ���ķ� valid combo interval�� �ٸ��� ������ - // Combo �� �Ǵ� Hacker�� �ν��ϴ� ��찡 �ִ�. - // ���� ���������� Ǯ�ų� �������� �ϰ� �Ǹ�, - // valid combo interval�� reset�Ѵ�. + // 폴리모프 상태에서 죽는 경우, 폴리모프가 풀리게 되는데 + // 폴리 모프 전후로 valid combo interval이 다르기 때문에 + // Combo 핵 또는 Hacker로 인식하는 경우가 있다. + // 따라서 폴리모프를 풀거나 폴리모프 하게 되면, + // valid combo interval을 reset한다. SetValidComboInterval(0); SetComboSequence(0); @@ -6218,7 +6218,7 @@ void CHARACTER::DetermineDropMetinStone() else { iGradePct -= iLevelGradePortion; - m_dwDropMetinStone += 100; // �� +a -> +(a+1)�� �ɶ����� 100�� ���� + m_dwDropMetinStone += 100; // 돌 +a -> +(a+1)이 될때마다 100씩 증가 } } } @@ -6266,9 +6266,9 @@ void CHARACTER::MountVnum(DWORD vnum) if (m_bIsObserver) return; - //NOTE : Mount�Ѵٰ� �ؼ� Client Side�� ��ü�� �������� �ʴ´�. - //�׸��� ����Side���� ������ ��ġ �̵��� ���� �ʴ´�. �ֳ��ϸ� Client Side���� Coliision Adjust�� �Ҽ� �ִµ� - //��ü�� �Ҹ���״ٰ� ������ġ�� �̵���Ű�� �̶� collision check�� ������ �����Ƿ� ��濡 ���ų� �հ� ������ ������ �����Ѵ�. + //NOTE : Mount한다고 해서 Client Side의 객체를 삭제하진 않는다. + //그리고 서버Side에서 탔을때 위치 이동은 하지 않는다. 왜냐하면 Client Side에서 Coliision Adjust를 할수 있는데 + //객체를 소멸시켰다가 서버위치로 이동시키면 이때 collision check를 하지는 않으므로 배경에 끼거나 뚫고 나가는 문제가 존재한다. m_posDest.x = m_posStart.x = GetX(); m_posDest.y = m_posStart.y = GetY(); //EncodeRemovePacket(this); @@ -6280,7 +6280,7 @@ void CHARACTER::MountVnum(DWORD vnum) { LPENTITY entity = (it++)->first; - //Mount�Ѵٰ� �ؼ� Client Side�� ��ü�� �������� �ʴ´�. + //Mount한다고 해서 Client Side의 객체를 삭제하진 않는다. //EncodeRemovePacket(entity); //if (!m_bIsObserver) EncodeInsertPacket(entity); @@ -6526,10 +6526,10 @@ bool CHARACTER::WarpToPID(DWORD dwPID) } else { - // �ٸ� ������ �α��ε� ����� ���� -> �޽��� ���� ��ǥ�� �޾ƿ��� - // 1. A.pid, B.pid �� �Ѹ� - // 2. B.pid�� ���� ������ �Ѹ��������� A.pid, ��ǥ �� ���� - // 3. ���� + // 다른 서버에 로그인된 사람이 있음 -> 메시지 보내 좌표를 받아오자 + // 1. A.pid, B.pid 를 뿌림 + // 2. B.pid를 가진 서버가 뿌린서버에게 A.pid, 좌표 를 보냄 + // 3. 워프 CCI * pcci = P2P_MANAGER::instance().FindByPID(dwPID); if (!pcci) @@ -6590,7 +6590,7 @@ int CHARACTER::ComputeRefineFee(int iCost, int iMultiply) const if (pGuild == GetGuild()) return iCost * iMultiply * 9 / 10; - // �ٸ� ���� ����� �õ��ϴ� ��� �߰��� 3�� �� + // 다른 제국 사람이 시도하는 경우 추가로 3배 더 LPCHARACTER chRefineNPC = CHARACTER_MANAGER::instance().Find(m_dwRefineNPCVID); if (chRefineNPC && chRefineNPC->GetEmpire() != GetEmpire()) return iCost * iMultiply * 3; @@ -6610,7 +6610,7 @@ void CHARACTER::PayRefineFee(int iTotalMoney) if (pGuild) { - // �ڱ� ����̸� iTotalMoney�� �̹� 10%�� ���ܵǾ��ִ� + // 자기 길드이면 iTotalMoney에 이미 10%가 제외되어있다 if (pGuild != GetGuild()) { pGuild->RequestDepositMoney(this, iFee); @@ -6622,7 +6622,7 @@ void CHARACTER::PayRefineFee(int iTotalMoney) } // END_OF_ADD_REFINE_BUILDING -//Hack ������ ���� üũ. +//Hack 방지를 위한 체크. bool CHARACTER::IsHack(bool bSendMsg, bool bCheckShopOwner, int limittime) { const int iPulse = thecore_pulse(); @@ -6630,7 +6630,7 @@ bool CHARACTER::IsHack(bool bSendMsg, bool bCheckShopOwner, int limittime) if (test_server) bSendMsg = true; - //â�� ���� üũ + //창고 연후 체크 if (iPulse - GetSafeboxLoadTime() < PASSES_PER_SEC(limittime)) { if (bSendMsg) @@ -6641,7 +6641,7 @@ bool CHARACTER::IsHack(bool bSendMsg, bool bCheckShopOwner, int limittime) return true; } - //�ŷ����� â üũ + //거래관련 창 체크 if (bCheckShopOwner) { if (GetExchange() || GetMyShop() || GetShopOwner() || IsOpenSafebox() || IsCubeOpen()) @@ -6664,7 +6664,7 @@ bool CHARACTER::IsHack(bool bSendMsg, bool bCheckShopOwner, int limittime) } //PREVENT_PORTAL_AFTER_EXCHANGE - //��ȯ �� �ð�üũ + //교환 후 시간체크 if (iPulse - GetExchangeTime() < PASSES_PER_SEC(limittime)) { if (bSendMsg) @@ -7148,7 +7148,7 @@ BYTE CHARACTER::GetChatCounter() const return m_bChatCounter; } -// ���̳� �ٸ����� Ÿ�� �ֳ�? +// 말이나 다른것을 타고 있나? bool CHARACTER::IsRiding() const { return IsHorseRiding() || GetMountVnum(); @@ -7188,4 +7188,4 @@ DWORD CHARACTER::GetNextExp() const int CHARACTER::GetSkillPowerByLevel(int level, bool bMob) const { return CTableBySkill::instance().GetSkillPowerByLevelFromType(GetJob(), GetSkillGroup(), std::clamp(level, 0, SKILL_MAX_LEVEL), bMob); -} \ No newline at end of file +} diff --git a/src/game/src/char_affect.cpp b/src/game/src/char_affect.cpp index b9638e3..a82c41c 100644 --- a/src/game/src/char_affect.cpp +++ b/src/game/src/char_affect.cpp @@ -84,13 +84,13 @@ EVENTFUNC(affect_event) if (!ch->UpdateAffect()) return 0; else - return passes_per_sec; // 1 + return passes_per_sec; // 1초 } bool CHARACTER::UpdateAffect() { - // affect_event ó ƴ, 1¥ ̺Ʈ óϴ - // ̰ ̶ ⼭ ó Ѵ. + // affect_event 에서 처리할 일은 아니지만, 1초짜리 이벤트에서 처리하는 것이 + // 이것 뿐이라 여기서 물약 처리를 한다. if (GetPoint(POINT_HP_RECOVERY) > 0) { if (GetMaxHP() <= GetHP()) @@ -146,7 +146,7 @@ bool CHARACTER::UpdateAffect() AutoRecoveryItemProcess( AFFECT_AUTO_HP_RECOVERY ); AutoRecoveryItemProcess( AFFECT_AUTO_SP_RECOVERY ); - // ׹̳ ȸ + // 스테미나 회복 if (GetMaxStamina() > GetStamina()) { int iSec = (get_dword_time() - GetStopTime()) / 3000; @@ -155,7 +155,7 @@ bool CHARACTER::UpdateAffect() } - // ProcessAffect affect true Ѵ. + // ProcessAffect는 affect가 없으면 true를 리턴한다. if (ProcessAffect()) if (GetPoint(POINT_HP_RECOVERY) == 0 && GetPoint(POINT_SP_RECOVERY) == 0 && GetStamina() == GetMaxStamina()) { @@ -226,7 +226,7 @@ int CHARACTER::ProcessAffect() CAffect *pkAff = NULL; // - // ̾ ó + // 프리미엄 처리 // for (int i = 0; i <= PREMIUM_MAX_NUM; ++i) { @@ -300,8 +300,8 @@ int CHARACTER::ProcessAffect() } // AFFECT_DURATION_BUG_FIX - // ȿ ۵ ð δ. - // ð ſ ũ ̶ . + // 무한 효과 아이템도 시간을 줄인다. + // 시간을 매우 크게 잡기 때문에 상관 없을 것이라 생각됨. if ( --pkAff->lDuration <= 0 ) { bEnd = true; @@ -470,7 +470,7 @@ void CHARACTER::LoadAffect(DWORD dwCount, TPacketAffectElement * pElements) for (DWORD i = 0; i < dwCount; ++i, ++pElements) { - // εʴ´. + // 무영진은 로드하지않는다. if (pElements->dwType == SKILL_MUYEONG) continue; @@ -524,7 +524,7 @@ void CHARACTER::LoadAffect(DWORD dwCount, TPacketAffectElement * pElements) m_bIsLoadedAffect = true; - // ȥ ε ʱȭ + // 용혼석 셋팅 로드 및 초기화 DragonSoul_Initialize(); } @@ -562,10 +562,10 @@ bool CHARACTER::AddAffect(DWORD dwType, BYTE bApplyOn, int lApplyValue, DWORD dw } } - // ̹ ִ ȿ ó + // 이미 있는 효과를 덮어 쓰는 처리 if (pkAff && bOverride) { - ComputeAffect(pkAff, false); // ϴ ȿ ϰ + ComputeAffect(pkAff, false); // 일단 효과를 삭제하고 if (GetDesc()) SendAffectRemovePacket(GetDesc(), GetPlayerID(), pkAff->dwType, pkAff->bApplyOn); @@ -573,9 +573,9 @@ bool CHARACTER::AddAffect(DWORD dwType, BYTE bApplyOn, int lApplyValue, DWORD dw else { // - // 带 ߰ + // 새 에펙를 추가 // - // NOTE: type ε Ʈ ִ. + // NOTE: 따라서 같은 type 으로도 여러 에펙트를 붙을 수 있다. // pkAff = CAffect::Acquire(); m_list_pkAffect.push_back(pkAff); @@ -677,15 +677,15 @@ bool CHARACTER::RemoveAffect(CAffect * pkAff) ComputeAffect(pkAff, false); - // . - // ״ ų ->а-> (AFFECT_REVIVE_INVISIBLE) ٷ 쿡 ߻Ѵ. - // а ϴ , ų ȿ ϰ а ȿ ǰ Ǿִµ, - // ٷ ϸ RemoveAffect Ҹ ǰ, ComputePointsϸ鼭 а ȿ + ų ȿ ȴ. - // ComputePoints а ¸ ų ȿ ϸ DZ ϴµ, - // ComputePoints ϰ ǰ ־ ū ȭ ִ .( side effect ߻ ˱ .) - // AFFECT_REVIVE_INVISIBLE RemoveAffect Ǵ 츸 Ѵ. - // ð Ǿ ȿ Ǯ װ ߻ Ƿ ׿ Ȱ . - // (ProcessAffect ð Ǿ Affect Ǵ , ComputePoints θ ʴ´.) + // 백기 버그 수정. + // 백기 버그는 버프 스킬 시전->둔갑->백기 사용(AFFECT_REVIVE_INVISIBLE) 후 바로 공격 할 경우에 발생한다. + // 원인은 둔갑을 시전하는 시점에, 버프 스킬 효과를 무시하고 둔갑 효과만 적용되게 되어있는데, + // 백기 사용 후 바로 공격하면 RemoveAffect가 불리게 되고, ComputePoints하면서 둔갑 효과 + 버프 스킬 효과가 된다. + // ComputePoints에서 둔갑 상태면 버프 스킬 효과 안 먹히도록 하면 되긴 하는데, + // ComputePoints는 광범위하게 사용되고 있어서 큰 변화를 주는 것이 꺼려진다.(어떤 side effect가 발생할지 알기 힘들다.) + // 따라서 AFFECT_REVIVE_INVISIBLE가 RemoveAffect로 삭제되는 경우만 수정한다. + // 시간이 다 되어 백기 효과가 풀리는 경우는 버그가 발생하지 않으므로 그와 똑같이 함. + // (ProcessAffect를 보면 시간이 다 되어서 Affect가 삭제되는 경우, ComputePoints를 부르지 않는다.) if (AFFECT_REVIVE_INVISIBLE != pkAff->dwType) { ComputePoints(); @@ -795,41 +795,41 @@ bool CHARACTER::IsGoodAffect(BYTE bAffectType) const void CHARACTER::RemoveBadAffect() { SPDLOG_DEBUG("RemoveBadAffect {}", GetName()); - // + // 독 RemovePoison(); RemoveFire(); - // : Value% 5ʰ Ӹ ư. ( 1/2 Ȯ Ǯ) AFF_STUN + // 스턴 : Value%로 상대방을 5초간 머리 위에 별이 돌아간다. (때리면 1/2 확률로 풀림) AFF_STUN RemoveAffect(AFFECT_STUN); - // ο : Value% /̼ . õ ޶ 쿡 AFF_SLOW + // 슬로우 : Value%로 상대방의 공속/이속 모두 느려진다. 수련도에 따라 달라짐 기술로 사용 한 경우에 AFF_SLOW RemoveAffect(AFFECT_SLOW); - // Ӹ + // 투속마령 RemoveAffect(SKILL_TUSOK); - // + // 저주 //RemoveAffect(SKILL_CURSE); - // Ĺ + // 파법술 //RemoveAffect(SKILL_PABUP); - // : Value% Ų. 2 AFF_FAINT + // 기절 : Value%로 상대방을 기절시킨다. 2초 AFF_FAINT //RemoveAffect(AFFECT_FAINT); - // ٸ : Value% ̵ӵ Ʈ. 5ʰ -40 AFF_WEB + // 다리묶임 : Value%로 상대방의 이동속도를 떨어트린다. 5초간 -40 AFF_WEB //RemoveAffect(AFFECT_WEB); - // : Value% 10ʰ . ( Ǯ) AFF_SLEEP + // 잠들기 : Value%로 상대방을 10초간 잠재운다. (때리면 풀림) AFF_SLEEP //RemoveAffect(AFFECT_SLEEP); - // : Value% / Ʈ. õ ޶ 쿡 AFF_CURSE + // 저주 : Value%로 상대방의 공등/방등 모두 떨어트린다. 수련도에 따라 달라짐 기술로 사용 한 경우에 AFF_CURSE //RemoveAffect(AFFECT_CURSE); - // : Value% 4ʰ Ų. AFF_PARA + // 마비 : Value%로 상대방을 4초간 마비시킨다. AFF_PARA //RemoveAffect(AFFECT_PARALYZE); - // εں : + // 부동박부 : 무당 기술 //RemoveAffect(SKILL_BUDONG); } diff --git a/src/game/src/char_battle.cpp b/src/game/src/char_battle.cpp index d41103e..aef7aff 100644 --- a/src/game/src/char_battle.cpp +++ b/src/game/src/char_battle.cpp @@ -147,7 +147,7 @@ void CHARACTER::DistributeSP(LPCHARACTER pkKiller, int iMethod) else if (bMoving) iAmount = 3 + GetMaxSP() * 2 / 100; else - iAmount = 10 + GetMaxSP() * 3 / 100; // + iAmount = 10 + GetMaxSP() * 3 / 100; // 평상시 iAmount += (iAmount * pkKiller->GetPoint(POINT_SP_REGEN)) / 100; pkKiller->PointChange(POINT_SP, iAmount); @@ -162,11 +162,11 @@ void CHARACTER::DistributeSP(LPCHARACTER pkKiller, int iMethod) iAmount = 2 + pkKiller->GetMaxSP() / 100; else { - // + // 평상시 if (pkKiller->GetHP() < pkKiller->GetMaxHP()) - iAmount = 2 + (pkKiller->GetMaxSP() / 100); // á + iAmount = 2 + (pkKiller->GetMaxSP() / 100); // 피 다 안찼을때 else - iAmount = 9 + (pkKiller->GetMaxSP() / 100); // ⺻ + iAmount = 9 + (pkKiller->GetMaxSP() / 100); // 기본 } iAmount += (iAmount * pkKiller->GetPoint(POINT_SP_REGEN)) / 100; @@ -213,7 +213,7 @@ bool CHARACTER::Attack(LPCHARACTER pkVictim, BYTE bType) if (bType == 0) { // - // Ϲ + // 일반 공격 // switch (GetMobBattleType()) { @@ -302,7 +302,7 @@ void CHARACTER::DeathPenalty(BYTE bTown) REMOVE_BIT(m_pointsInstant.instant_flag, INSTANT_FLAG_DEATH_PENALTY); // NO_DEATH_PENALTY_BUG_FIX - if (LC_IsYMIR()) // õ ȣ üũѴ. + if (LC_IsYMIR()) // 천마 버전에서는 언제나 용신의 가호 아이템을 체크한다. { if (FindAffect(AFFECT_NO_DEATH_PENALTY)) { @@ -312,7 +312,7 @@ void CHARACTER::DeathPenalty(BYTE bTown) return; } } - else if (!bTown) // ڸ Ȱø ȣ Ѵ. ( ͽô ġ гƼ ) + else if (!bTown) // 국제 버전에서는 제자리 부활시만 용신의 가호를 사용한다. (마을 복귀시는 경험치 패널티 없음) { if (FindAffect(AFFECT_NO_DEATH_PENALTY)) { @@ -411,7 +411,7 @@ void CHARACTER::Stun() CloseMyShop(); - event_cancel(&m_pkRecoveryEvent); // ȸ ̺Ʈ δ. + event_cancel(&m_pkRecoveryEvent); // 회복 이벤트를 죽인다. TPacketGCStun pack; pack.header = HEADER_GC_STUN; @@ -535,7 +535,7 @@ void CHARACTER::RewardGold(LPCHARACTER pkAttacker) bool isAutoLoot = (pkAttacker->GetPremiumRemainSeconds(PREMIUM_AUTOLOOT) > 0 || pkAttacker->IsEquipUniqueGroup(UNIQUE_GROUP_AUTOLOOT)) - ? true : false; // 3 + ? true : false; // 제3의 손 // END_OF_ADD_PREMIUM PIXEL_POSITION pos; @@ -546,7 +546,7 @@ void CHARACTER::RewardGold(LPCHARACTER pkAttacker) int iTotalGold = 0; // - // --------- Ȯ ---------- + // --------- 돈 드롭 확률 계산 ---------- // int iGoldPercent = MobRankStats[GetMobRank()].iGoldPercent; @@ -580,35 +580,35 @@ void CHARACTER::RewardGold(LPCHARACTER pkAttacker) int iGoldMultipler = GetGoldMultipler(); - if (1 == Random::get(1, 50000)) // 1/50000 Ȯ 10 + if (1 == Random::get(1, 50000)) // 1/50000 확률로 돈이 10배 iGoldMultipler *= 10; - else if (1 == Random::get(1, 10000)) // 1/10000 Ȯ 5 + else if (1 == Random::get(1, 10000)) // 1/10000 확률로 돈이 5배 iGoldMultipler *= 5; - // + // 개인 적용 if (pkAttacker->GetPoint(POINT_GOLD_DOUBLE_BONUS)) if (Random::get(1, 100) <= pkAttacker->GetPoint(POINT_GOLD_DOUBLE_BONUS)) iGoldMultipler *= 2; // - // --------- ---------- + // --------- 돈 드롭 배수 결정 ---------- // if (test_server) pkAttacker->ChatPacket(CHAT_TYPE_PARTY, "gold_mul %d rate %d", iGoldMultipler, CHARACTER_MANAGER::instance().GetMobGoldAmountRate(pkAttacker)); // - // --------- ó ------------- + // --------- 실제 드롭 처리 ------------- // LPITEM item; int iGold10DropPct = 100; iGold10DropPct = (iGold10DropPct * 100) / (100 + CPrivManager::instance().GetPriv(pkAttacker, PRIV_GOLD10_DROP)); - // MOB_RANK BOSS ź + // MOB_RANK가 BOSS보다 높으면 무조건 돈폭탄 if (GetMobRank() >= MOB_RANK_BOSS && !IsStone() && GetMobTable().dwGoldMax != 0) { if (1 == Random::get(1, iGold10DropPct)) - iGoldMultipler *= 10; // 1% Ȯ 10 + iGoldMultipler *= 10; // 1% 확률로 돈 10배 int iSplitCount = Random::get(25, 35); @@ -627,7 +627,7 @@ void CHARACTER::RewardGold(LPCHARACTER pkAttacker) SPDLOG_TRACE("Drop Moeny MobGoldAmountRate {} {}", CHARACTER_MANAGER::instance().GetMobGoldAmountRate(pkAttacker), iGoldMultipler); SPDLOG_TRACE("Drop Money gold {} GoldMin {} GoldMax {}", iGold, GetMobTable().dwGoldMax, GetMobTable().dwGoldMax); - // NOTE: ź 3 ó + // NOTE: 돈 폭탄은 제 3의 손 처리를 하지 않음 if ((item = ITEM_MANAGER::instance().CreateItem(1, iGold))) { pos.x = GetX() + ((Random::get(-14, 14) + Random::get(-14, 14)) * 23); @@ -640,11 +640,11 @@ void CHARACTER::RewardGold(LPCHARACTER pkAttacker) } } } - // 1% Ȯ 10 ߸. (10 ) + // 1% 확률로 돈을 10개 떨어 뜨린다. (10배 드롭임) else if (1 == Random::get(1, iGold10DropPct)) { // - // ź + // 돈 폭탄식 드롭 // for (int i = 0; i < 10; ++i) { @@ -657,7 +657,7 @@ void CHARACTER::RewardGold(LPCHARACTER pkAttacker) continue; } - // NOTE: ź 3 ó + // NOTE: 돈 폭탄은 제 3의 손 처리를 하지 않음 if ((item = ITEM_MANAGER::instance().CreateItem(1, iGold))) { pos.x = GetX() + (Random::get(-7, 7) * 20); @@ -673,7 +673,7 @@ void CHARACTER::RewardGold(LPCHARACTER pkAttacker) else { // - // Ϲ + // 일반적인 방식의 돈 드롭 // int iGold = Random::get(GetMobTable().dwGoldMin, GetMobTable().dwGoldMax); iGold = iGold * CHARACTER_MANAGER::instance().GetMobGoldAmountRate(pkAttacker) / 100; @@ -720,7 +720,7 @@ void CHARACTER::RewardGold(LPCHARACTER pkAttacker) void CHARACTER::Reward(bool bItemDrop) { - if (GetRaceNum() == 5001) // ֱ + if (GetRaceNum() == 5001) // 왜구는 돈을 무조건 드롭 { PIXEL_POSITION pos; @@ -807,7 +807,7 @@ void CHARACTER::Reward(bool bItemDrop) return; // - // + // 돈 드롭 // //PROF_UNIT pu2("r2"); SPDLOG_TRACE("Drop money : Attacker {}", pkAttacker->GetName()); @@ -815,7 +815,7 @@ void CHARACTER::Reward(bool bItemDrop) //pu2.Pop(); // - // + // 아이템 드롭 // //PROF_UNIT pu3("r3"); LPITEM item; @@ -878,7 +878,7 @@ void CHARACTER::Reward(bool bItemDrop) if (v.empty()) { - // Ư + // 데미지를 특별히 많이 준 사람이 없으니 소유권 없음 while (iItemIdx >= 0) { item = s_vec_item[iItemIdx--]; @@ -890,7 +890,7 @@ void CHARACTER::Reward(bool bItemDrop) } item->AddToGround(GetMapIndex(), pos); - // 10% Ǿ + // 10% 이하 데미지 준 사람끼리는 소유권없음 //item->SetOwnership(pkAttacker); item->StartDestroyEvent(); @@ -904,7 +904,7 @@ void CHARACTER::Reward(bool bItemDrop) } else { - // + // 데미지 많이 준 사람들 끼리만 소유권 나눠가짐 std::vector::iterator it = v.begin(); while (iItemIdx >= 0) @@ -960,20 +960,20 @@ struct TItemDropPenalty TItemDropPenalty aItemDropPenalty_kor[9] = { - { 0, 0, 0, 0 }, // - { 0, 0, 0, 0 }, // - { 0, 0, 0, 0 }, // - { 0, 0, 0, 0 }, // - { 0, 0, 0, 0 }, // - { 25, 1, 5, 1 }, // - { 50, 2, 10, 1 }, // - { 75, 4, 15, 1 }, // - { 100, 8, 20, 1 }, // п + { 0, 0, 0, 0 }, // 선왕 + { 0, 0, 0, 0 }, // 영웅 + { 0, 0, 0, 0 }, // 성자 + { 0, 0, 0, 0 }, // 지인 + { 0, 0, 0, 0 }, // 양민 + { 25, 1, 5, 1 }, // 낭인 + { 50, 2, 10, 1 }, // 악인 + { 75, 4, 15, 1 }, // 마두 + { 100, 8, 20, 1 }, // 패왕 }; void CHARACTER::ItemDropPenalty(LPCHARACTER pkKiller) { - // λ ¿ ʴ´. + // 개인상점을 연 상태에서는 아이템을 드롭하지 않는다. if (GetMyShop()) return; @@ -1204,7 +1204,7 @@ void CHARACTER::Dead(LPCHARACTER pkKiller, bool bImmediateDead) if (!pkKiller && m_dwKillerPID) pkKiller = CHARACTER_MANAGER::instance().FindByPID(m_dwKillerPID); - m_dwKillerPID = 0; // ݵ ʱȭ ؾ DO NOT DELETE THIS LINE UNLESS YOU ARE 1000000% SURE + m_dwKillerPID = 0; // 반드시 초기화 해야함 DO NOT DELETE THIS LINE UNLESS YOU ARE 1000000% SURE bool isAgreedPVP = false; bool isUnderGuildWar = false; @@ -1304,7 +1304,7 @@ void CHARACTER::Dead(LPCHARACTER pkKiller, bool bImmediateDead) if (GetPoint(POINT_EMPIRE_POINT) < 10) { - // TODO : Ա ڵ带 ־ Ѵ. + // TODO : 입구로 날리는 코드를 넣어야 한다. } char buf[256]; @@ -1371,7 +1371,7 @@ void CHARACTER::Dead(LPCHARACTER pkKiller, bool bImmediateDead) ClearSync(); - event_cancel(&m_pkStunEvent); // ̺Ʈ δ. + event_cancel(&m_pkStunEvent); // 기절 이벤트는 죽인다. if (IsPC()) { @@ -1381,12 +1381,12 @@ void CHARACTER::Dead(LPCHARACTER pkKiller, bool bImmediateDead) } else { - // 忡 ݹ ʹ Ѵ. + // 가드에게 공격받은 몬스터는 보상이 없어야 한다. if (!IS_SET(m_pointsInstant.instant_flag, INSTANT_FLAG_NO_REWARD)) { if (!(pkKiller && pkKiller->IsPC() && pkKiller->GetGuild() && pkKiller->GetGuild()->UnderAnyWar(GUILD_WAR_TYPE_FIELD))) { - // Ȱϴ ʹ ʴ´. + // 부활하는 몬스터는 보상을 주지 않는다. if (GetMobTable().dwResurrectionVnum) { // DUNGEON_MONSTER_REBIRTH_BUG_FIX @@ -1438,10 +1438,10 @@ void CHARACTER::Dead(LPCHARACTER pkKiller, bool bImmediateDead) REMOVE_BIT(m_pointsInstant.instant_flag, INSTANT_FLAG_STUN); - // ÷̾ ij̸ + // 플레이어 캐릭터이면 if (GetDesc() != NULL) { // - // Ŭ̾Ʈ Ʈ Ŷ ٽ . + // 클라이언트에 에펙트 패킷을 다시 보낸다. // itertype(m_list_pkAffect) it = m_list_pkAffect.begin(); @@ -1450,11 +1450,11 @@ void CHARACTER::Dead(LPCHARACTER pkKiller, bool bImmediateDead) } // - // Dead ̺Ʈ , + // Dead 이벤트 생성, // - // Dead ̺Ʈ Ŀ Destroy ǵ ָ, - // PC 3 ִٰ ش. 3 κ - // , ⼭ ޴´. + // Dead 이벤트에서는 몬스터의 경우 몇초 후에 Destroy 되도록 해주며, + // PC의 경우 3분 있다가 마을에서 나오도록 해 준다. 3분 내에는 유저로부터 + // 마을에서 시작할 건지, 여기서 시작할 건지 결정을 받는다. if (isDuel == false) { if (m_pkDeadEvent) @@ -1578,12 +1578,12 @@ void CHARACTER::SendDamagePacket(LPCHARACTER pAttacker, int Damage, BYTE DamageF } // -// CHARACTER::Damage ޼ҵ this ԰ Ѵ. +// CHARACTER::Damage 메소드는 this가 데미지를 입게 한다. // // Arguments -// pAttacker : -// dam : -// EDamageType :  ΰ? +// pAttacker : 공격자 +// dam : 데미지 +// EDamageType : 어떤 형식의 공격인가? // // Return value // true : dead @@ -1656,7 +1656,7 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu } } - // Ÿ ƴ ó + // 평타가 아닐 때는 공포 처리 if (type != DAMAGE_TYPE_NORMAL && type != DAMAGE_TYPE_NORMAL_RANGE) { if (IsAffectFlag(AFF_TERROR)) @@ -1688,19 +1688,19 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu //PROF_UNIT puAttr("Attr"); // - // ų, ų(ڰ) ũƼð, Ѵ. - // ʾƾ ϴµ Nerf(ٿ뷱)ġ  ũƼð - // ʰ, /2 ̻Ͽ Ѵ. + // 마법형 스킬과, 레인지형 스킬은(궁자객) 크리티컬과, 관통공격 계산을 한다. + // 원래는 하지 않아야 하는데 Nerf(다운밸런스)패치를 할 수 없어서 크리티컬과 + // 관통공격의 원래 값을 쓰지 않고, /2 이상하여 적용한다. // - // ̾߱Ⱑ Ƽ и ų ߰ + // 무사 이야기가 많아서 밀리 스킬도 추가 // - // 20091109 : 簡 û г, 70% + // 20091109 : 무사가 결과적으로 엄청나게 강해진 것으로 결론남, 독일 기준 무사 비율 70% 육박 // if (type == DAMAGE_TYPE_MELEE || type == DAMAGE_TYPE_RANGE || type == DAMAGE_TYPE_MAGIC) { if (pAttacker) { - // ũƼ + // 크리티컬 int iCriticalPct = pAttacker->GetPoint(POINT_CRITICAL_PCT); if (!IsPC()) @@ -1708,12 +1708,12 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu if (iCriticalPct) { - if (iCriticalPct >= 10) // 10 ũ 5% + (4 1% ), ġ 50̸ 20% + if (iCriticalPct >= 10) // 10보다 크면 5% + (4마다 1%씩 증가), 따라서 수치가 50이면 20% iCriticalPct = 5 + (iCriticalPct - 10) / 4; - else // 10 ܼ , 10 = 5% + else // 10보다 작으면 단순히 반으로 깎음, 10 = 5% iCriticalPct /= 2; - //ũƼ . + //크리티컬 저항 값 적용. iCriticalPct -= GetPoint(POINT_RESIST_CRITICAL); if (Random::get(1, 100) <= iCriticalPct) @@ -1729,7 +1729,7 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu } } - // + // 관통공격 int iPenetratePct = pAttacker->GetPoint(POINT_PENETRATE_PCT); if (!IsPC()) @@ -1751,16 +1751,16 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu if (iPenetratePct >= 10) { - // 10 ũ 5% + (4 1% ), ġ 50̸ 20% + // 10보다 크면 5% + (4마다 1%씩 증가), 따라서 수치가 50이면 20% iPenetratePct = 5 + (iPenetratePct - 10) / 4; } else { - // 10 ܼ , 10 = 5% + // 10보다 작으면 단순히 반으로 깎음, 10 = 5% iPenetratePct /= 2; } - //Ÿ . + //관통타격 저항 값 적용. iPenetratePct -= GetPoint(POINT_RESIST_PENETRATE); if (Random::get(1, 100) <= iPenetratePct) @@ -1781,13 +1781,13 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu } } // - // ޺ , Ȱ , Ÿ Ӽ Ѵ. + // 콤보 공격, 활 공격, 즉 평타 일 때만 속성값들을 계산을 한다. // else if (type == DAMAGE_TYPE_NORMAL || type == DAMAGE_TYPE_NORMAL_RANGE) { if (type == DAMAGE_TYPE_NORMAL) { - // Ÿ + // 근접 평타일 경우 막을 수 있음 if (GetPoint(POINT_BLOCK) && Random::get(1, 100) <= GetPoint(POINT_BLOCK)) { if (test_server) @@ -1802,7 +1802,7 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu } else if (type == DAMAGE_TYPE_NORMAL_RANGE) { - // Ÿ Ÿ + // 원거리 평타의 경우 피할 수 있음 if (GetPoint(POINT_DODGE) && Random::get(1, 100) <= GetPoint(POINT_DODGE)) { if (test_server) @@ -1826,19 +1826,19 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu dam = dam * (100 - GetPoint(POINT_RESIST_NORMAL_DAMAGE)) / 100; // - // Ӽ + // 공격자 속성 적용 // if (pAttacker) { if (type == DAMAGE_TYPE_NORMAL) { - // ݻ + // 반사 if (GetPoint(POINT_REFLECT_MELEE)) { int reflectDamage = dam * GetPoint(POINT_REFLECT_MELEE) / 100; - // NOTE: ڰ IMMUNE_REFLECT Ӽ ִٸ ݻ縦 ϴ - // ƴ϶ 1/3 ؼ  ȹ û. + // NOTE: 공격자가 IMMUNE_REFLECT 속성을 갖고있다면 반사를 안 하는 게 + // 아니라 1/3 데미지로 고정해서 들어가도록 기획에서 요청. if (pAttacker->IsImmune(IMMUNE_REFLECT)) reflectDamage = int(reflectDamage / 3.0f + 0.5f); @@ -1846,7 +1846,7 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu } } - // ũƼ + // 크리티컬 int iCriticalPct = pAttacker->GetPoint(POINT_CRITICAL_PCT); if (!IsPC()) @@ -1854,7 +1854,7 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu if (iCriticalPct) { - //ũƼ . + //크리티컬 저항 값 적용. iCriticalPct -= GetPoint(POINT_RESIST_CRITICAL); if (Random::get(1, 100) <= iCriticalPct) @@ -1865,7 +1865,7 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu } } - // + // 관통공격 int iPenetratePct = pAttacker->GetPoint(POINT_PENETRATE_PCT); if (!IsPC()) @@ -1886,7 +1886,7 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu if (iPenetratePct) { - //Ÿ . + //관통타격 저항 값 적용. iPenetratePct -= GetPoint(POINT_RESIST_PENETRATE); if (Random::get(1, 100) <= iPenetratePct) @@ -1899,7 +1899,7 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu } } - // HP ƿ + // HP 스틸 if (pAttacker->GetPoint(POINT_STEAL_HP)) { int pct = 1; @@ -1917,7 +1917,7 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu } } - // SP ƿ + // SP 스틸 if (pAttacker->GetPoint(POINT_STEAL_SP)) { int pct = 1; @@ -1944,7 +1944,7 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu } } - // ƿ + // 돈 스틸 if (pAttacker->GetPoint(POINT_STEAL_GOLD)) { if (Random::get(1, 100) <= pAttacker->GetPoint(POINT_STEAL_GOLD)) @@ -1955,8 +1955,8 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu } } - // ĥ HPȸ - if (pAttacker->GetPoint(POINT_HIT_HP_RECOVERY) && Random::get(0, 4) > 0) // 80% Ȯ + // 칠 때마다 HP회복 + if (pAttacker->GetPoint(POINT_HIT_HP_RECOVERY) && Random::get(0, 4) > 0) // 80% 확률 { int i = std::min(dam, iCurHP) * pAttacker->GetPoint(POINT_HIT_HP_RECOVERY) / 100; @@ -1967,8 +1967,8 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu } } - // ĥ SPȸ - if (pAttacker->GetPoint(POINT_HIT_SP_RECOVERY) && Random::get(0, 4) > 0) // 80% Ȯ + // 칠 때마다 SP회복 + if (pAttacker->GetPoint(POINT_HIT_SP_RECOVERY) && Random::get(0, 4) > 0) // 80% 확률 { int i = std::min(dam, iCurHP) * pAttacker->GetPoint(POINT_HIT_SP_RECOVERY) / 100; @@ -1979,7 +1979,7 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu } } - // ش. + // 상대방의 마나를 없앤다. if (pAttacker->GetPoint(POINT_MANA_BURN_PCT)) { if (Random::get(1, 100) <= pAttacker->GetPoint(POINT_MANA_BURN_PCT)) @@ -1989,7 +1989,7 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu } // - // Ÿ Ǵ ų ʽ / + // 평타 또는 스킬로 인한 보너스 피해/방어 계산 // switch (type) { @@ -2020,16 +2020,16 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu } // - // (żȣ) + // 마나쉴드(흑신수호) // if (IsAffectFlag(AFF_MANASHIELD)) { - // POINT_MANASHIELD ۾ + // POINT_MANASHIELD 는 작아질수록 좋다 int iDamageSPPart = dam / 3; int iDamageToSP = iDamageSPPart * GetPoint(POINT_MANASHIELD) / 100; int iSP = GetSP(); - // SP + // SP가 있으면 무조건 데미지 절반 감소 if (iDamageToSP <= iSP) { PointChange(POINT_SP, -iDamageToSP); @@ -2037,14 +2037,14 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu } else { - // ŷ ڶ ǰ ←?? + // 정신력이 모자라서 피가 더 깍여야할?? PointChange(POINT_SP, -GetSP()); dam -= iSP * 100 / std::max(GetPoint(POINT_MANASHIELD), 1); } } // - // ü ( ) + // 전체 방어력 상승 (몰 아이템) // if (GetPoint(POINT_MALL_DEFBONUS) > 0) { @@ -2055,7 +2055,7 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu if (pAttacker) { // - // ü ݷ ( ) + // 전체 공격력 상승 (몰 아이템) // if (pAttacker->GetPoint(POINT_MALL_ATTBONUS) > 0) { @@ -2064,7 +2064,7 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu } // - // ʽ (ѱ õ ) + // 제국으로 인한 보너스 (한국 올드 버전만 적용) // int iEmpire = GetEmpire(); int lMapIndex = GetMapIndex(); @@ -2084,7 +2084,7 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu lMapIndex = pAttacker->GetMapIndex(); iMapEmpire = SECTREE_MANAGER::instance().GetEmpireFromMapIndex(lMapIndex); - // ٸ 10% + // 다른 제국 사람인 경우 데미지 10% 감소 if (iEmpire && iMapEmpire && iEmpire != iMapEmpire) { int percent = 10; @@ -2129,17 +2129,17 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu } // - // ݰ & + // 군주의 금강권 & 사자후 // if (pAttacker->IsPC() && CMonarch::instance().IsPowerUp(pAttacker->GetEmpire())) { - // 10% + // 10% 피해 증가 dam += dam / 10; } if (IsPC() && CMonarch::instance().IsDefenceUp(GetEmpire())) { - // 10% + // 10% 피해 감소 dam -= dam / 10; } } @@ -2155,7 +2155,7 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu else SetLastAttacked(get_dword_time()); - // : + // 몬스터 대사 : 맞을 때 MonsterChat(MONSTER_CHAT_ATTACKED); } @@ -2168,7 +2168,7 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu if (IsDead()) return true; - // ʵ . + // 독 공격으로 죽지 않도록 함. if (type == DAMAGE_TYPE_POISON) { if (GetHP() - dam <= 0) @@ -2178,7 +2178,7 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu } // ------------------------ - // ̾ + // 독일 프리미엄 모드 // ----------------------- if (LC_IsGermany() && pAttacker && pAttacker->IsPC()) { @@ -2186,7 +2186,7 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu dam = dam * iDmgPct / 100; } - // STONE SKIN : + // STONE SKIN : 피해 반으로 감소 if (IsMonster() && IsStoneSkinner()) { if (GetHPPct() < GetMobTable().bStoneSkinPoint) @@ -2196,7 +2196,7 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu //PROF_UNIT puRest1("Rest1"); if (pAttacker) { - // DEATH BLOW : Ȯ 4 (!? ̺Ʈ ͸ ) + // DEATH BLOW : 확률 적으로 4배 피해 (!? 현재 이벤트나 공성전용 몬스터만 사용함) if (pAttacker->IsMonster() && pAttacker->IsDeathBlower()) { if (pAttacker->IsDeathBlow()) @@ -2225,7 +2225,7 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu damageFlag |= DAMAGE_PENETRATE; - // + //최종 데미지 보정 float damMul = this->GetDamMul(); float tempDam = dam; dam = tempDam * damMul + 0.5f; @@ -2265,7 +2265,7 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu } // - // !!!!!!!!! HP ̴ κ !!!!!!!!! + // !!!!!!!!! 실제 HP를 줄이는 부분 !!!!!!!!! // if (!cannot_dead) { @@ -2292,7 +2292,7 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu //puRest20.Pop(); //PROF_UNIT puRest21("Rest21"); - StartRecoveryEvent(); // ʹ ȸ Ѵ. + StartRecoveryEvent(); // 몬스터는 데미지를 입으면 회복을 시작한다. //puRest21.Pop(); //PROF_UNIT puRest22("Rest22"); @@ -2317,40 +2317,40 @@ bool CHARACTER::Damage(LPCHARACTER pAttacker, int dam, EDamageType type) // retu void CHARACTER::DistributeHP(LPCHARACTER pkKiller) { - if (pkKiller->GetDungeon()) // ΰʴ´ + if (pkKiller->GetDungeon()) // 던젼내에선 만두가나오지않는다 return; } static void GiveExp(LPCHARACTER from, LPCHARACTER to, int iExp) { - // ġ + // 레벨차 경험치 가감비율 iExp = CALCULATE_VALUE_LVDELTA(to->GetLevel(), from->GetLevel(), iExp); - // ܺ ׽Ʈ ġ 3 ʽ + // 외부 테스트 서버 경험치 3배 보너스 if (distribution_test_server) iExp *= 3; int iBaseExp = iExp; - // , ȸ ġ ̺Ʈ + // 점술, 회사 경험치 이벤트 적용 iExp = iExp * (100 + CPrivManager::instance().GetPriv(to, PRIV_EXP_PCT)) / 100; - // ӳ ⺻ Ǵ ġ ʽ + // 게임내 기본 제공되는 경험치 보너스 { - // 뵿 ޴ + // 노동절 메달 if (to->IsEquipUniqueItem(UNIQUE_ITEM_LARBOR_MEDAL)) iExp += iExp * 20 /100; - // Ÿ ġ ʽ + // 사귀타워 경험치 보너스 if (to->GetMapIndex() >= 660000 && to->GetMapIndex() < 670000) - iExp += iExp * 20 / 100; // 1.2 (20%) + iExp += iExp * 20 / 100; // 1.2배 (20%) - // ġ ι Ӽ + // 아이템 경험치 두배 속성 if (to->GetPoint(POINT_EXP_DOUBLE_BONUS)) if (Random::get(1, 100) <= to->GetPoint(POINT_EXP_DOUBLE_BONUS)) - iExp += iExp * 30 / 100; // 1.3 (30%) + iExp += iExp * 30 / 100; // 1.3배 (30%) - // (2ð¥) + // 경험의 반지 (2시간짜리) if (to->IsEquipUniqueItem(UNIQUE_ITEM_DOUBLE_EXP)) iExp += iExp * 50 / 100; @@ -2374,16 +2374,16 @@ static void GiveExp(LPCHARACTER from, LPCHARACTER to, int iExp) case 20123: case 20124: case 20125: - // ġ ʽ + // 백사자 경험치 보너스 iExp += iExp * 30 / 100; break; } } - // Ǹ ġ ʽ + // 아이템 몰 판매 경험치 보너스 if (LC_IsHongKong() || LC_IsEurope() || LC_IsCanada()) { - // : ġ + // 아이템 몰: 경험치 결제 if (to->GetPremiumRemainSeconds(PREMIUM_EXP) > 0) { iExp += (iExp * 50 / 100); @@ -2394,19 +2394,19 @@ static void GiveExp(LPCHARACTER from, LPCHARACTER to, int iExp) iExp += (iExp * 50 / 100); } - // PC ġ ʽ + // PC방 아템 경치 보너스 if (to->GetPoint(POINT_PC_BANG_EXP_BONUS) > 0) { if (to->IsPCBang() == true) iExp += (iExp * to->GetPoint(POINT_PC_BANG_EXP_BONUS)/100); } - // ȥ ʽ + // 결혼 보너스 iExp += iExp * to->GetMarriageBonus(UNIQUE_ITEM_MARRIAGE_EXP_BONUS) / 100; } else if (/*LC_IsNewCIBN() || */LC_IsBrazil()) { - // : ġ + // 아이템 몰: 경험치 결제 if (to->GetPremiumRemainSeconds(PREMIUM_EXP) > 0) { iExp += iExp; @@ -2417,19 +2417,19 @@ static void GiveExp(LPCHARACTER from, LPCHARACTER to, int iExp) iExp += iExp; } - // PC ġ ʽ + // PC방 아템 경치 보너스 if (to->GetPoint(POINT_PC_BANG_EXP_BONUS) > 0) { if (to->IsPCBang() == true) iExp += (iExp * to->GetPoint(POINT_PC_BANG_EXP_BONUS)/100); } - // ȥ ʽ + // 결혼 보너스 iExp += iExp * to->GetMarriageBonus(UNIQUE_ITEM_MARRIAGE_EXP_BONUS) / 100; } else { - // : ġ + // 아이템 몰: 경험치 결제 if (to->GetPremiumRemainSeconds(PREMIUM_EXP) > 0) { iExp += (iExp * 20 / 100); @@ -2440,14 +2440,14 @@ static void GiveExp(LPCHARACTER from, LPCHARACTER to, int iExp) iExp += (iExp * 20 / 100); } - // PC ġ ʽ + // PC방 아템 경치 보너스 if (to->GetPoint(POINT_PC_BANG_EXP_BONUS) > 0) { if (to->IsPCBang() == true) iExp += (iExp * to->GetPoint(POINT_PC_BANG_EXP_BONUS)/100); } - // ȥ ʽ + // 결혼 보너스 iExp += iExp * to->GetMarriageBonus(UNIQUE_ITEM_MARRIAGE_EXP_BONUS) / 100; } @@ -2468,10 +2468,10 @@ static void GiveExp(LPCHARACTER from, LPCHARACTER to, int iExp) to->GetPoint(POINT_EXP) ); - // ȹ 2005.04.21 85% + // 기획측 조정값 2005.04.21 현재 85% iExp = iExp * CHARACTER_MANAGER::instance().GetMobExpRate(to) / 100; - // ġ ѹ ȹ淮 + // 경험치 한번 획득량 제한 iExp = std::min(to->GetNextExp() / 10, iExp); if (test_server) @@ -2487,10 +2487,10 @@ static void GiveExp(LPCHARACTER from, LPCHARACTER to, int iExp) { LPCHARACTER you = to->GetMarryPartner(); - // κΰ Ƽ̸ ݽ + // 부부가 서로 파티중이면 금슬이 오른다 if (you) { - // 1 100% + // 1억이 100% DWORD dwUpdatePoint = 2000*iExp/to->GetLevel()/to->GetLevel()/3; if (to->GetPremiumRemainSeconds(PREMIUM_MARRIAGE_FAST) > 0 || @@ -2609,7 +2609,7 @@ typedef struct SDamageInfo pParty->ChatPacketToAllMember(CHAT_TYPE_INFO, "exp party bonus %d%%", pParty->GetExpBonusPercent()); } - // ġ ֱ (Ƽ ȹ ġ 5% ) + // 경험치 몰아주기 (파티가 획득한 경험치를 5% 빼서 먼저 줌) if (pParty->GetExpCentralizeCharacter()) { LPCHARACTER tch = pParty->GetExpCentralizeCharacter(); @@ -2648,7 +2648,7 @@ LPCHARACTER CHARACTER::DistributeExp() TDamageMap::iterator it = m_map_kDamage.begin(); - // ϴ ɷ . (50m) + // 일단 주위에 없는 사람을 걸러 낸다. (50m) while (it != m_map_kDamage.end()) { const VID & c_VID = it->first; @@ -2658,7 +2658,7 @@ LPCHARACTER CHARACTER::DistributeExp() LPCHARACTER pAttacker = CHARACTER_MANAGER::instance().Find(c_VID); - // NPC ⵵ ϳ? -.-; + // NPC가 때리기도 하나? -.-; if (!pAttacker || pAttacker->IsNPC() || DISTANCE_APPROX(GetX()-pAttacker->GetX(), GetY()-pAttacker->GetY())>5000) continue; @@ -2705,10 +2705,10 @@ LPCHARACTER CHARACTER::DistributeExp() SetExp(0); //m_map_kDamage.clear(); - if (iTotalDam == 0) // ذ 0̸ + if (iTotalDam == 0) // 데미지 준게 0이면 리턴 return NULL; - if (m_pkChrStone) // ġ ѱ. + if (m_pkChrStone) // 돌이 있을 경우 경험치의 반을 돌에게 넘긴다. { int iExp = iExpToDistribute >> 1; m_pkChrStone->SetExp(m_pkChrStone->GetExp() + iExp); @@ -2721,11 +2721,11 @@ LPCHARACTER CHARACTER::DistributeExp() if (damage_info_table.empty()) return NULL; - // HP ȸ Ѵ. - DistributeHP(pkChrMostAttacked); // ý + // 제일 데미지를 많이 준 사람이 HP 회복을 한다. + DistributeHP(pkChrMostAttacked); // 만두 시스템 { - // ̳ Ƽ ġ 20% + ڱⰡ ŭ ġ Դ´. + // 제일 데미지를 많이 준 사람이나 파티가 총 경험치의 20% + 자기가 때린만큼의 경험치를 먹는다. TDamageInfoTable::iterator di = damage_info_table.begin(); { TDamageInfoTable::iterator it; @@ -2752,7 +2752,7 @@ LPCHARACTER CHARACTER::DistributeExp() di->Distribute(this, iExp); - // 100% Ծ Ѵ. + // 100% 다 먹었으면 리턴한다. if (fPercent == 1.0f) return pkChrMostAttacked; @@ -2760,7 +2760,7 @@ LPCHARACTER CHARACTER::DistributeExp() } { - // 80% ġ йѴ. + // 남은 80%의 경험치를 분배한다. TDamageInfoTable::iterator it; for (it = damage_info_table.begin(); it != damage_info_table.end(); ++it) @@ -2782,7 +2782,7 @@ LPCHARACTER CHARACTER::DistributeExp() return pkChrMostAttacked; } -// ȭ +// 화살 개수를 리턴해 줌 int CHARACTER::GetArrowAndBow(LPITEM * ppkBow, LPITEM * ppkArrow, int iArrowCount/* = 1 */) { LPITEM pkBow; @@ -2854,7 +2854,7 @@ class CFuncShoot if (!pkVictim) return; - // Ұ + // 공격 불가 if (!battle_is_attackable(m_me, pkVictim)) return; @@ -2868,7 +2868,7 @@ class CFuncShoot switch (m_bType) { - case 0: // ϹȰ + case 0: // 일반활 { int iDam = 0; @@ -2902,7 +2902,7 @@ class CFuncShoot NormalAttackAffect(m_me, pkVictim); - // + // 데미지 계산 iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST_BOW)) / 100; m_me->OnMove(true); @@ -2912,11 +2912,11 @@ class CFuncShoot pkVictim->BeginFight(m_me); pkVictim->Damage(m_me, iDam, DAMAGE_TYPE_NORMAL_RANGE); - // Ÿġ + // 타격치 계산부 끝 } break; - case 1: // Ϲ + case 1: // 일반 마법 { int iDam; @@ -2927,7 +2927,7 @@ class CFuncShoot NormalAttackAffect(m_me, pkVictim); - // + // 데미지 계산 iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST_MAGIC)) / 100; m_me->OnMove(true); @@ -2937,16 +2937,16 @@ class CFuncShoot pkVictim->BeginFight(m_me); pkVictim->Damage(m_me, iDam, DAMAGE_TYPE_MAGIC); - // Ÿġ + // 타격치 계산부 끝 } break; - case SKILL_YEONSA: // + case SKILL_YEONSA: // 연사 { //int iUseArrow = 2 + (m_me->GetSkillPower(SKILL_YEONSA) *6/100); int iUseArrow = 1; - // Ż ϴ° + // 토탈만 계산하는경우 { if (iUseArrow == m_me->GetArrowAndBow(&pkBow, &pkArrow, iUseArrow)) { @@ -3078,7 +3078,7 @@ class CFuncShoot SPDLOG_DEBUG("{} - Skill {} -> {}", m_me->GetName(), m_bType, pkVictim->GetName()); m_me->ComputeSkill(m_bType, pkVictim); - // TODO ϱ + // TODO 여러명에게 슉 슉 슉 하기 } break; @@ -3175,7 +3175,7 @@ LPCHARACTER CHARACTER::GetNearestVictim(LPCHARACTER pkChr) TDamageMap::iterator it = m_map_kDamage.begin(); - // ϴ ɷ . + // 일단 주위에 없는 사람을 걸러 낸다. while (it != m_map_kDamage.end()) { const VID & c_VID = it->first; @@ -3228,7 +3228,7 @@ LPCHARACTER CHARACTER::GetVictim() const return CHARACTER_MANAGER::instance().Find(m_kVIDVictim); } -LPCHARACTER CHARACTER::GetProtege() const // ȣؾ +LPCHARACTER CHARACTER::GetProtege() const // 보호해야 할 대상을 리턴 { if (m_pkChrStone) return m_pkChrStone; @@ -3381,7 +3381,7 @@ struct FuncAggregateMonster if (ch->GetVictim()) return; - if (Random::get(1, 100) <= 50) // ӽ÷ 50% Ȯ ´ + if (Random::get(1, 100) <= 50) // 임시로 50% 확률로 적을 끌어온다 if (DISTANCE_APPROX(ch->GetX() - m_ch->GetX(), ch->GetY() - m_ch->GetY()) < 5000) if (ch->CanBeginFight()) ch->BeginFight(m_ch); @@ -3509,7 +3509,7 @@ void CHARACTER::PullMonster() void CHARACTER::UpdateAggrPointEx(LPCHARACTER pAttacker, EDamageType type, int dam, CHARACTER::TBattleInfo & info) { - // Ư ŸԿ ö󰣴 + // 특정 공격타입에 따라 더 올라간다 switch (type) { case DAMAGE_TYPE_NORMAL_RANGE: @@ -3528,7 +3528,7 @@ void CHARACTER::UpdateAggrPointEx(LPCHARACTER pAttacker, EDamageType type, int d break; } - // ڰ ʽ ش. + // 공격자가 현재 대상인 경우 보너스를 준다. if (pAttacker == GetVictim()) dam = (int) (dam * 1.2f); @@ -3541,7 +3541,7 @@ void CHARACTER::UpdateAggrPointEx(LPCHARACTER pAttacker, EDamageType type, int d { LPPARTY pParty = GetParty(); - // ϴ + // 리더인 경우 영향력이 좀더 강하다 int iPartyAggroDist = dam; if (pParty->GetLeaderPID() == GetVID()) @@ -3573,7 +3573,7 @@ void CHARACTER::UpdateAggrPoint(LPCHARACTER pAttacker, EDamageType type, int dam void CHARACTER::ChangeVictimByAggro(int iNewAggro, LPCHARACTER pNewVictim) { - if (get_dword_time() - m_dwLastVictimSetTime < 3000) // 3ʴ ٷѴ + if (get_dword_time() - m_dwLastVictimSetTime < 3000) // 3초는 기다려야한다 return; if (pNewVictim == GetVictim()) @@ -3584,7 +3584,7 @@ void CHARACTER::ChangeVictimByAggro(int iNewAggro, LPCHARACTER pNewVictim) return; } - // Aggro + // Aggro가 감소한 경우 TDamageMap::iterator it; TDamageMap::iterator itFind = m_map_kDamage.end(); diff --git a/src/game/src/char_change_empire.cpp b/src/game/src/char_change_empire.cpp index 59d25c1..1d9bd3a 100644 --- a/src/game/src/char_change_empire.cpp +++ b/src/game/src/char_change_empire.cpp @@ -9,12 +9,12 @@ /* Return Value - 0 : or - 1 : ٲٷ - 2 : ijͰ - 3 : ȥ ijͰ + 0 : 알 수 없는 에러 or 쿼리 에러 + 1 : 동일한 제국으로 바꾸려고함 + 2 : 길드 가입한 캐릭터가 있음 + 3 : 결혼한 캐릭터가 있음 - 999 : ̵ + 999 : 제국 이동 성공 */ int CHARACTER::ChangeEmpire(BYTE empire) { @@ -27,7 +27,7 @@ int CHARACTER::ChangeEmpire(BYTE empire) memset(dwPID, 0, sizeof(dwPID)); { - // 1. pid ´ + // 1. 내 계정의 모든 pid를 얻어 온다 snprintf(szQuery, sizeof(szQuery), "SELECT id, pid1, pid2, pid3, pid4 FROM player_index%s WHERE pid1=%u OR pid2=%u OR pid3=%u OR pid4=%u AND empire=%u", get_table_postfix(), GetPlayerID(), GetPlayerID(), GetPlayerID(), GetPlayerID(), GetEmpire()); @@ -51,8 +51,8 @@ int CHARACTER::ChangeEmpire(BYTE empire) const int loop = 4; { - // 2. ij ´. - // ijͶ 忡 Ǿ ִٸ, ̵ . + // 2. 각 캐릭터의 길드 정보를 얻어온다. + // 한 캐릭터라도 길드에 가입 되어 있다면, 제국 이동을 할 수 없다. DWORD dwGuildID[4]; CGuild * pGuild[4]; SQLMsg * pMsg = NULL; @@ -91,8 +91,8 @@ int CHARACTER::ChangeEmpire(BYTE empire) } { - // 3. ij ȥ ´. - // ijͶ ȥ ¶ ̵ . + // 3. 각 캐릭터의 결혼 정보를 얻어온다. + // 한 캐릭터라도 결혼 상태라면 제국 이동을 할 수 없다. for (int i = 0; i < loop; ++i) { if (marriage::CManager::instance().IsEngagedOrMarried(dwPID[i]) == true) @@ -101,7 +101,7 @@ int CHARACTER::ChangeEmpire(BYTE empire) } { - // 4. db Ʈ Ѵ. + // 4. db의 제국 정보를 업데이트 한다. snprintf(szQuery, sizeof(szQuery), "UPDATE player_index%s SET empire=%u WHERE pid1=%u OR pid2=%u OR pid3=%u OR pid4=%u AND empire=%u", get_table_postfix(), empire, GetPlayerID(), GetPlayerID(), GetPlayerID(), GetPlayerID(), GetEmpire()); @@ -109,7 +109,7 @@ int CHARACTER::ChangeEmpire(BYTE empire) if (msg->Get()->uiAffectedRows > 0) { - // 5. ̷ ߰Ѵ. + // 5. 제국 변경 이력을 추가한다. SetChangeEmpireCount(); return 999; diff --git a/src/game/src/char_dragonsoul.cpp b/src/game/src/char_dragonsoul.cpp index 33f0996..7bf7b6b 100644 --- a/src/game/src/char_dragonsoul.cpp +++ b/src/game/src/char_dragonsoul.cpp @@ -5,14 +5,14 @@ #include "DragonSoul.h" #include "log.h" -// ȥ ʱȭ -// ȥ on/off Affect DZ , -// ȥ Affect ִٸ ִ ȥ activateؾѴ. -// ȥ ڰ QuestFlag ұ , -// Ʈ Flag ȥ ڰ о´. +// 용혼석 초기화 +// 용혼석 on/off는 Affect로 저장되기 때문에, +// 용혼석 Affect가 있다면 덱에 있는 용혼석을 activate해야한다. +// 또한 용혼석 사용 자격은 QuestFlag로 저장해 놓았기 때문에, +// 퀘스트 Flag에서 용혼석 사용 자격을 읽어온다. -// ij affect, quest load DZ DragonSoul_Initialize ȣϸ ȵȴ. -// affect εǾ LoadAffect ȣ. +// 캐릭터의 affect, quest가 load 되기 전에 DragonSoul_Initialize를 호출하면 안된다. +// affect가 가장 마지막에 로드되어 LoadAffect에서 호출함. void CHARACTER::DragonSoul_Initialize() { for (int i = INVENTORY_MAX_NUM + WEAR_MAX_NUM; i < DRAGON_SOUL_EQUIP_SLOT_END; i++) @@ -55,7 +55,7 @@ void CHARACTER::DragonSoul_GiveQualification() } AddAffect(AFFECT_DRAGON_SOUL_QUALIFIED, APPLY_NONE, 0, AFF_NONE, INFINITE_AFFECT_DURATION, 0, false, false); //SetQuestFlag("dragon_soul.is_qualified", 1); - //// ڰִٸ POINT_DRAGON_SOUL_IS_QUALIFIED 1 + //// 자격있다면 POINT_DRAGON_SOUL_IS_QUALIFIED는 무조건 1 //PointChange(POINT_DRAGON_SOUL_IS_QUALIFIED, 1 - GetPoint(POINT_DRAGON_SOUL_IS_QUALIFIED)); } diff --git a/src/game/src/char_horse.cpp b/src/game/src/char_horse.cpp index 136a1b7..e652621 100644 --- a/src/game/src/char_horse.cpp +++ b/src/game/src/char_horse.cpp @@ -27,7 +27,7 @@ bool CHARACTER::StartRiding() return false; } - // νõ Ÿ + // 턱시도 입은 상태의 말 타기 금지 LPITEM armor = GetWear(WEAR_BODY); if (armor && (armor->GetVnum() >= 11901 && armor->GetVnum() <= 11904)) @@ -57,7 +57,7 @@ bool CHARACTER::StartRiding() return false; } - // ȯ ְ + // 소환한 말 없애고 HorseSummon(false); MountVnum(dwMountVnum); @@ -78,7 +78,7 @@ bool CHARACTER::StopRiding() DWORD dwOldVnum = GetMountVnum(); MountVnum(0); - // [NOTE] ڱⰡ ȯϵ + // [NOTE] 말에서 내릴 땐 자기가 탔던걸 소환하도록 수정 HorseSummon(true, false, dwOldVnum); } else @@ -139,14 +139,14 @@ void CHARACTER::HorseSummon(bool bSummon, bool bFromFar, DWORD dwVnum, const cha { if ( bSummon ) { - //NOTE : summonߴµ ̹ horse ƹ͵ Ѵ. + //NOTE : summon했는데 이미 horse가 있으면 아무것도 안한다. if( m_chHorse != NULL ) return; if (GetHorseLevel() <= 0) return; - // 𰡸 Ÿ ִٸ + // 무언가를 타고 있다면 실패 if (IsRiding()) return; @@ -183,10 +183,10 @@ void CHARACTER::HorseSummon(bool bSummon, bool bFromFar, DWORD dwVnum, const cha if (GetHorseHealth() <= 0) { - // ó ְ ϴ ó + // 죽은거처럼 있게 하는 처리 m_chHorse->SetPosition(POS_DEAD); - // ðִ . + // 일정시간있다 사라지게 하자. char_event_info* info = AllocEventInfo(); info->ch = this; m_chHorse->m_pkDeadEvent = event_create(horse_dead_event, info, PASSES_PER_SEC(60)); @@ -239,7 +239,7 @@ void CHARACTER::HorseSummon(bool bSummon, bool bFromFar, DWORD dwVnum, const cha } else { - // ־鼭 ó ϱ + // 멀어지면서 사라지는 처리 하기 chHorse->SetNowWalking(false); float fx, fy; chHorse->SetRotation(GetDegreeFromPositionXY(chHorse->GetX(), chHorse->GetY(), GetX(), GetY())+180); @@ -310,7 +310,7 @@ void CHARACTER::SendHorseInfo() 3: 70% < ~ <= 100% 2: 30% < ~ <= 70% 1: 0% < ~ <= 30% -0: +0: 사망 STM @@ -343,8 +343,8 @@ STM { ChatPacket(CHAT_TYPE_COMMAND, "horse_state %d %d %d", GetHorseLevel(), iHealthGrade, iStaminaGrade); - // FIX : Ŭ̾Ʈ "\xB8\xBB \xBB\xF3\xC5\xC2 \xB9\xF6\xC7\xC1" ǥ Լ Կ returnν Ʒ ڵ带 Ѵٸ - // Ѵ ȯϴ ù װ .. Ȯ ľ غ . + // FIX : 클라이언트에 "\xB8\xBB \xBB\xF3\xC5\xC2 \xB9\xF6\xC7\xC1" 아이콘을 표시하지 않을 목적으로 함수 초입에 return함으로써 아래 코드를 무시한다면 + // 말을 무한대로 소환하는 무시무시한 버그가 생김.. 정확한 원인은 파악 안해봐서 모름. m_bSendHorseLevel = GetHorseLevel(); m_bSendHorseHealthGrade = iHealthGrade; m_bSendHorseStaminaGrade = iStaminaGrade; @@ -366,7 +366,7 @@ bool CHARACTER::CanUseHorseSkill() if (GetMountVnum() >= 20209 && GetMountVnum() <= 20212) return true; - //󸶴 渶 + //라마단 흑마 if (CMobVnumHelper::IsRamadanBlackHorse(GetMountVnum())) return true; } diff --git a/src/game/src/char_item.cpp b/src/game/src/char_item.cpp index cdae1d7..b2a5a63 100644 --- a/src/game/src/char_item.cpp +++ b/src/game/src/char_item.cpp @@ -77,7 +77,7 @@ struct FFindStone }; -//ȯ, ȯ, ȥ +//귀환부, 귀환기억부, 결혼반지 static bool IS_SUMMON_ITEM(int vnum) { switch (vnum) @@ -110,38 +110,38 @@ static bool IS_MONKEY_DUNGEON(int map_index) bool IS_SUMMONABLE_ZONE(int map_index) { - // Ű + // 몽키던전 if (IS_MONKEY_DUNGEON(map_index)) return false; - // + // 성 if (IS_CASTLE_MAP(map_index)) return false; switch (map_index) { - case 66 : // Ÿ - case 71 : // Ź 2 - case 72 : // õ - case 73 : // õ 2 - case 193 : // Ź 2-1 + case 66 : // 사귀타워 + case 71 : // 거미 던전 2층 + case 72 : // 천의 동굴 + case 73 : // 천의 동굴 2층 + case 193 : // 거미 던전 2-1층 #if 0 - case 184 : // õ (ż) - case 185 : // õ 2(ż) - case 186 : // õ (õ) - case 187 : // õ 2(õ) - case 188 : // õ () - case 189 : // õ 2() + case 184 : // 천의 동굴(신수) + case 185 : // 천의 동굴 2층(신수) + case 186 : // 천의 동굴(천조) + case 187 : // 천의 동굴 2층(천조) + case 188 : // 천의 동굴(진노) + case 189 : // 천의 동굴 2층(진노) #endif -// case 206 : // Ʊ͵ - case 216 : // Ʊ͵ - case 217 : // Ź 3 - case 208 : // õ () +// case 206 : // 아귀동굴 + case 216 : // 아귀동굴 + case 217 : // 거미 던전 3층 + case 208 : // 천의 동굴 (용방) return false; } if (CBattleArena::IsBattleArenaMap(map_index)) return false; - // private Ұ + // 모든 private 맵으론 워프 불가능 if (map_index > 10000) return false; return true; @@ -165,7 +165,7 @@ bool IS_BOTARYABLE_ZONE(int nMapIndex) return false; } -// item socket Ÿ԰ üũ -- by mhh +// item socket 이 프로토타입과 같은지 체크 -- by mhh static bool FN_check_item_socket(LPITEM item) { for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i) @@ -177,7 +177,7 @@ static bool FN_check_item_socket(LPITEM item) return true; } -// item socket -- by mhh +// item socket 복사 -- by mhh static void FN_copy_item_socket(LPITEM dest, LPITEM src) { for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i) @@ -187,13 +187,13 @@ static void FN_copy_item_socket(LPITEM dest, LPITEM src) } static bool FN_check_item_sex(LPCHARACTER ch, LPITEM item) { - // + // 남자 금지 if (IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_MALE)) { if (SEX_MALE==GET_SEX(ch)) return false; } - // ڱ + // 여자금지 if (IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_FEMALE)) { if (SEX_FEMALE==GET_SEX(ch)) @@ -279,7 +279,7 @@ void CHARACTER::SetItem(TItemPos Cell, LPITEM pItem) assert(!"GetOwner exist"); return; } - // ⺻ κ丮 + // 기본 인벤토리 switch(window_type) { case INVENTORY: @@ -325,8 +325,8 @@ void CHARACTER::SetItem(TItemPos Cell, LPITEM pItem) if (p >= INVENTORY_MAX_NUM) continue; - // wCell + 1 ϴ üũ - // óϱ + // wCell + 1 로 하는 것은 빈곳을 체크할 때 같은 + // 아이템은 예외처리하기 위함 m_pointsInstant.bItemGrid[p] = wCell + 1; } } @@ -337,7 +337,7 @@ void CHARACTER::SetItem(TItemPos Cell, LPITEM pItem) m_pointsInstant.pItems[wCell] = pItem; } break; - // ȥ κ丮 + // 용혼석 인벤토리 case DRAGON_SOUL_INVENTORY: { LPITEM pOld = m_pointsInstant.pDSItems[wCell]; @@ -380,8 +380,8 @@ void CHARACTER::SetItem(TItemPos Cell, LPITEM pItem) if (p >= DRAGON_SOUL_INVENTORY_MAX_NUM) continue; - // wCell + 1 ϴ üũ - // óϱ + // wCell + 1 로 하는 것은 빈곳을 체크할 때 같은 + // 아이템은 예외처리하기 위함 m_pointsInstant.wDSItemGrid[p] = wCell + 1; } } @@ -399,7 +399,7 @@ void CHARACTER::SetItem(TItemPos Cell, LPITEM pItem) if (GetDesc()) { - // Ȯ : ÷ + // 확장 아이템: 서버에서 아이템 플래그 정보를 보낸다 if (pItem) { TPacketGCItemSet pack; @@ -453,7 +453,7 @@ void CHARACTER::SetItem(TItemPos Cell, LPITEM pItem) LPITEM CHARACTER::GetWear(BYTE bCell) const { - // > WEAR_MAX_NUM : ȥ Ե. + // > WEAR_MAX_NUM : 용혼석 슬롯들. if (bCell >= WEAR_MAX_NUM + DRAGON_SOUL_DECK_MAX_NUM * DS_SLOT_MAX) { SPDLOG_ERROR("CHARACTER::GetWear: invalid wear cell {}", bCell); @@ -465,7 +465,7 @@ LPITEM CHARACTER::GetWear(BYTE bCell) const void CHARACTER::SetWear(BYTE bCell, LPITEM item) { - // > WEAR_MAX_NUM : ȥ Ե. + // > WEAR_MAX_NUM : 용혼석 슬롯들. if (bCell >= WEAR_MAX_NUM + DRAGON_SOUL_DECK_MAX_NUM * DS_SLOT_MAX) { SPDLOG_ERROR("CHARACTER::SetItem: invalid item cell {}", bCell); @@ -476,7 +476,7 @@ void CHARACTER::SetWear(BYTE bCell, LPITEM item) if (!item && bCell == WEAR_WEAPON) { - // Ͱ ̶ ȿ ־ Ѵ. + // 귀검 사용 시 벗는 것이라면 효과를 없애야 한다. if (IsAffectFlag(AFF_GWIGUM)) RemoveAffect(SKILL_GWIGEOM); @@ -524,8 +524,8 @@ bool CHARACTER::IsEmptyItemGrid(TItemPos Cell, BYTE bSize, int iExceptionCell) c { BYTE bCell = Cell.cell; - // bItemCell 0 false Ÿ + 1 ؼ óѴ. - // iExceptionCell 1 Ѵ. + // bItemCell은 0이 false임을 나타내기 위해 + 1 해서 처리한다. + // 따라서 iExceptionCell에 1을 더해 비교한다. ++iExceptionCell; if (Cell.IsBeltInventoryPosition()) @@ -585,7 +585,7 @@ bool CHARACTER::IsEmptyItemGrid(TItemPos Cell, BYTE bSize, int iExceptionCell) c return false; } - // ũⰡ 1̸ ĭ ϴ ̹Ƿ ׳ + // 크기가 1이면 한칸을 차지하는 것이므로 그냥 리턴 if (1 == bSize) return true; else @@ -619,8 +619,8 @@ bool CHARACTER::IsEmptyItemGrid(TItemPos Cell, BYTE bSize, int iExceptionCell) c if (wCell >= DRAGON_SOUL_INVENTORY_MAX_NUM) return false; - // bItemCell 0 false Ÿ + 1 ؼ óѴ. - // iExceptionCell 1 Ѵ. + // bItemCell은 0이 false임을 나타내기 위해 + 1 해서 처리한다. + // 따라서 iExceptionCell에 1을 더해 비교한다. iExceptionCell++; if (m_pointsInstant.wDSItemGrid[wCell]) @@ -651,7 +651,7 @@ bool CHARACTER::IsEmptyItemGrid(TItemPos Cell, BYTE bSize, int iExceptionCell) c return false; } - // ũⰡ 1̸ ĭ ϴ ̹Ƿ ׳ + // 크기가 1이면 한칸을 차지하는 것이므로 그냥 리턴 if (1 == bSize) return true; else @@ -681,8 +681,8 @@ bool CHARACTER::IsEmptyItemGrid(TItemPos Cell, BYTE bSize, int iExceptionCell) c int CHARACTER::GetEmptyInventory(BYTE size) const { - // NOTE: Լ , ȹ κ丮 ĭ ã ǰ ִµ, - // Ʈ κ丮 Ư κ丮̹Ƿ ˻ ʵ Ѵ. (⺻ κ丮: INVENTORY_MAX_NUM ˻) + // NOTE: 현재 이 함수는 아이템 지급, 획득 등의 행위를 할 때 인벤토리의 빈 칸을 찾기 위해 사용되고 있는데, + // 벨트 인벤토리는 특수 인벤토리이므로 검사하지 않도록 한다. (기본 인벤토리: INVENTORY_MAX_NUM 까지만 검사) for ( int i = 0; i < INVENTORY_MAX_NUM; ++i) if (IsEmptyItemGrid(TItemPos (INVENTORY, i), size)) return i; @@ -742,7 +742,7 @@ void TransformRefineItem(LPITEM pkOldItem, LPITEM pkNewItem) // END_OF_ACCESSORY_REFINE else { - // ⼭ ڵ û + // 여기서 깨진석이 자동적으로 청소 됨 for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i) { if (!pkOldItem->GetSocket(i)) @@ -751,7 +751,7 @@ void TransformRefineItem(LPITEM pkOldItem, LPITEM pkNewItem) pkNewItem->SetSocket(i, 1); } - // + // 소켓 설정 int slot = 0; for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i) @@ -764,7 +764,7 @@ void TransformRefineItem(LPITEM pkOldItem, LPITEM pkNewItem) } - // + // 매직 아이템 설정 pkOldItem->CopyAttributeTo(pkNewItem); } @@ -808,8 +808,8 @@ bool CHARACTER::DoRefine(LPITEM item, bool bMoneyOnly) return false; } - // ð : upgrade_refine_scroll.quest 5̳ Ϲ - //Ҽ + //개량 시간제한 : upgrade_refine_scroll.quest 에서 개량후 5분이내에 일반 개량을 + //진행할수 없음 if (quest::CQuestManager::instance().GetEventFlag("update_refine_time") != 0) { if (get_global_time() < quest::CQuestManager::instance().GetEventFlag("update_refine_time") + (60 * 5)) @@ -917,7 +917,7 @@ bool CHARACTER::DoRefine(LPITEM item, bool bMoneyOnly) if (prob <= prt->prob) { - // ! , Ӽ ٸ ȹ + // 성공! 모든 아이템이 사라지고, 같은 속성의 다른 아이템 획득 LPITEM pkNewItem = ITEM_MANAGER::instance().CreateItem(result_vnum, 1, 0, false); if (pkNewItem) @@ -946,7 +946,7 @@ bool CHARACTER::DoRefine(LPITEM item, bool bMoneyOnly) else { // DETAIL_REFINE_LOG - // -> з + // 아이템 생성에 실패 -> 개량 실패로 간주 SPDLOG_ERROR("cannot create item {}", result_vnum); NotifyRefineFail(this, item, IsRefineThroughGuild() ? "GUILD" : "POWER"); // END_OF_DETAIL_REFINE_LOG @@ -954,7 +954,7 @@ bool CHARACTER::DoRefine(LPITEM item, bool bMoneyOnly) } else { - // ! . + // 실패! 모든 아이템이 사라짐. DBManager::instance().SendMoneyLog(MONEY_LOG_REFINE, item->GetVnum(), -cost); NotifyRefineFail(this, item, IsRefineThroughGuild() ? "GUILD" : "POWER"); item->AttrLog(); @@ -970,7 +970,7 @@ bool CHARACTER::DoRefine(LPITEM item, bool bMoneyOnly) enum enum_RefineScrolls { CHUKBOK_SCROLL = 0, - HYUNIRON_CHN = 1, // ߱ + HYUNIRON_CHN = 1, // 중국에서만 사용 YONGSIN_SCROLL = 2, MUSIN_SCROLL = 3, YAGONG_SCROLL = 4, @@ -988,8 +988,8 @@ bool CHARACTER::DoRefineWithScroll(LPITEM item) ClearRefineMode(); - // ð : upgrade_refine_scroll.quest 5̳ Ϲ - //Ҽ + //개량 시간제한 : upgrade_refine_scroll.quest 에서 개량후 5분이내에 일반 개량을 + //진행할수 없음 if (quest::CQuestManager::instance().GetEventFlag("update_refine_time") != 0) { if (get_global_time() < quest::CQuestManager::instance().GetEventFlag("update_refine_time") + (60 * 5)) @@ -1006,7 +1006,7 @@ bool CHARACTER::DoRefineWithScroll(LPITEM item) LPITEM pkItemScroll; - // üũ + // 개량서 체크 if (m_iRefineAdditionalCell < 0) return false; @@ -1117,7 +1117,7 @@ bool CHARACTER::DoRefineWithScroll(LPITEM item) if (pkItemScroll->GetValue(0) == HYUNIRON_CHN || pkItemScroll->GetValue(0) == YONGSIN_SCROLL || - pkItemScroll->GetValue(0) == YAGONG_SCROLL) // ö, ູ, ߰ ó + pkItemScroll->GetValue(0) == YAGONG_SCROLL) // 현철, 용신의 축복서, 야공의 비전서 처리 { const char hyuniron_prob[9] = { 100, 75, 65, 55, 45, 40, 35, 25, 20 }; const char hyuniron_prob_euckr[9] = { 100, 75, 65, 55, 45, 40, 35, 30, 25 }; @@ -1148,7 +1148,7 @@ bool CHARACTER::DoRefineWithScroll(LPITEM item) { ChatPacket(CHAT_TYPE_INFO, "[Only Test] Success_Prob %d, RefineLevel %d ", success_prob, item->GetRefineLevel()); } - if (pkItemScroll->GetValue(0) == HYUNIRON_CHN) // ö μ Ѵ. + if (pkItemScroll->GetValue(0) == HYUNIRON_CHN) // 현철은 아이템이 부서져야 한다. bDestroyWhenFail = true; // DETAIL_REFINE_LOG @@ -1168,7 +1168,7 @@ bool CHARACTER::DoRefineWithScroll(LPITEM item) } // DETAIL_REFINE_LOG - if (pkItemScroll->GetValue(0) == MUSIN_SCROLL) // ູ 100% (+4) + if (pkItemScroll->GetValue(0) == MUSIN_SCROLL) // 무신의 축복서는 100% 성공 (+4까지만) { success_prob = 100; @@ -1190,7 +1190,7 @@ bool CHARACTER::DoRefineWithScroll(LPITEM item) if (prob <= success_prob) { - // ! , Ӽ ٸ ȹ + // 성공! 모든 아이템이 사라지고, 같은 속성의 다른 아이템 획득 LPITEM pkNewItem = ITEM_MANAGER::instance().CreateItem(result_vnum, 1, 0, false); if (pkNewItem) @@ -1212,14 +1212,14 @@ bool CHARACTER::DoRefineWithScroll(LPITEM item) } else { - // -> з + // 아이템 생성에 실패 -> 개량 실패로 간주 SPDLOG_ERROR("cannot create item {}", result_vnum); NotifyRefineFail(this, item, szRefineType); } } else if (!bDestroyWhenFail && result_fail_vnum) { - // ! , Ӽ ȹ + // 실패! 모든 아이템이 사라지고, 같은 속성의 낮은 등급의 아이템 획득 LPITEM pkNewItem = ITEM_MANAGER::instance().CreateItem(result_fail_vnum, 1, 0, false); if (pkNewItem) @@ -1243,14 +1243,14 @@ bool CHARACTER::DoRefineWithScroll(LPITEM item) } else { - // -> з + // 아이템 생성에 실패 -> 개량 실패로 간주 SPDLOG_ERROR("cannot create item {}", result_fail_vnum); NotifyRefineFail(this, item, szRefineType); } } else { - NotifyRefineFail(this, item, szRefineType); // + NotifyRefineFail(this, item, szRefineType); // 개량시 아이템 사라지지 않음 PayRefineFee(prt->cost); } @@ -1326,7 +1326,7 @@ bool CHARACTER::RefineInformation(BYTE bCell, BYTE bType, int iAdditionalCell) //MAIN_QUEST_LV7 if (GetQuestFlag("main_quest_lv7.refine_chance") > 0) { - // Ϻ + // 일본은 제외 if (!item->CheckItemUseLevel(20) || item->GetType() != ITEM_WEAPON) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB9\xAB\xB7\xE1 \xB0\xB3\xB7\xAE \xB1\xE2\xC8\xB8\xB4\xC2 20 \xC0\xCC\xC7\xCF\xC0\xC7 \xB9\xAB\xB1\xE2\xB8\xB8 \xB0\xA1\xB4\xC9\xC7\xD5\xB4\xCF\xB4\xD9")); @@ -1364,8 +1364,8 @@ bool CHARACTER::RefineItem(LPITEM pkItem, LPITEM pkTarget) if (pkItem->GetSubType() == USE_TUNING) { - // XXX , ϴ... - // XXX ɰ ູ Ǿ! + // XXX 성능, 소켓 개량서는 사라졌습니다... + // XXX 성능개량서는 축복의 서가 되었다! // MUSIN_SCROLL if (pkItem->GetValue(0) == MUSIN_SCROLL) RefineInformation(pkTarget->GetCell(), REFINE_TYPE_MUSIN, pkItem->GetCell()); @@ -1409,7 +1409,7 @@ bool CHARACTER::RefineItem(LPITEM pkItem, LPITEM pkTarget) AutoGiveItem(socket); //TItemTable* pTable = ITEM_MANAGER::instance().GetTable(pkTarget->GetSocket(i)); //pkTarget->SetSocket(i, pTable->alValues[2]); - // üش + // 깨진돌로 대체해준다 pkTarget->SetSocket(i, ITEM_BROKEN_METIN_VNUM); } } @@ -1476,12 +1476,12 @@ bool CHARACTER::GiveRecallItem(LPITEM item) int pos; - if (item->GetCount() == 1) // ϳ ׳ . + if (item->GetCount() == 1) // 아이템이 하나라면 그냥 셋팅. { item->SetSocket(0, GetX()); item->SetSocket(1, GetY()); } - else if ((pos = GetEmptyInventory(item->GetSize())) != -1) // ׷ ʴٸ ٸ κ丮 ã´. + else if ((pos = GetEmptyInventory(item->GetSize())) != -1) // 그렇지 않다면 다른 인벤토리 슬롯을 찾는다. { LPITEM item2 = ITEM_MANAGER::instance().CreateItem(item->GetVnum(), 1); @@ -1527,7 +1527,7 @@ void CHARACTER::ProcessRecallItem(LPITEM item) case 216: iEmpireByMapIndex = -1; break; - // Ƿ決 ϶ + // 악룡군도 일때 case 301: case 302: case 303: @@ -1581,14 +1581,14 @@ void CHARACTER::SendMyShopPriceListCmd(DWORD dwItemVnum, DWORD dwItemPrice) } // -// DB ij÷ Ʈ User ϰ Ŀǵ带 . +// DB 캐시로 부터 받은 리스트를 User 에게 전송하고 상점을 열라는 커맨드를 보낸다. // void CHARACTER::UseSilkBotaryReal(const TPacketMyshopPricelistHeader* p) { const TItemPriceInfo* pInfo = (const TItemPriceInfo*)(p + 1); if (!p->byCount) - // Ʈ . dummy ͸ Ŀǵ带 ش. + // 가격 리스트가 없다. dummy 데이터를 넣은 커맨드를 보내준다. SendMyShopPriceListCmd(1, 0); else { for (int idx = 0; idx < p->byCount; idx++) @@ -1599,8 +1599,8 @@ void CHARACTER::UseSilkBotaryReal(const TPacketMyshopPricelistHeader* p) } // -// ̹ ó Open ϴ Ʈ Load ϱ DB ijÿ Ʈ û Ŷ . -// ĺʹ ٷ . +// 이번 접속 후 처음 상점을 Open 하는 경우 리스트를 Load 하기 위해 DB 캐시에 가격정보 리스트 요청 패킷을 보낸다. +// 이후부터는 바로 상점을 열라는 응답을 보낸다. // void CHARACTER::UseSilkBotary(void) { @@ -1635,7 +1635,7 @@ int CalculateConsume(LPCHARACTER ch) consumeLife = needLife; - // CheckMinLifeForWarp: ؼ ȵǹǷ ּҷ ش + // CheckMinLifeForWarp: 독에 의해서 죽으면 안되므로 생명력 최소량는 남겨준다 const int minPercent = WARP_MIN_LIFE_PERCENT; const int minLife = ch->GetMaxHP() * minPercent / 100; if (curLife - needLife < minLife) @@ -1703,13 +1703,13 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) return false; } - // ĺʹ ʾƵ ð Ǵ ó. + // 아이템 최초 사용 이후부터는 사용하지 않아도 시간이 차감되는 방식 처리. if (-1 != iLimitRealtimeStartFirstUseFlagIndex) { - // ̶ δ Socket1 ǴѴ. (Socket1 Ƚ ) + // 한 번이라도 사용한 아이템인지 여부는 Socket1을 보고 판단한다. (Socket1에 사용횟수 기록) if (0 == item->GetSocket(1)) { - // 밡ɽð Default Limit Value ϵ, Socket0 ϵ Ѵ. ( ) + // 사용가능시간은 Default 값으로 Limit Value 값을 사용하되, Socket0에 값이 있으면 그 값을 사용하도록 한다. (단위는 초) int duration = (0 != item->GetSocket(0)) ? item->GetSocket(0) : item->GetProto()->aLimits[iLimitRealtimeStartFirstUseFlagIndex].lValue; if (0 == duration) @@ -1854,7 +1854,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) switch (item->GetVnum()) { - case 71049: // ܺ + case 71049: // 비단보따리 if (LC_IsYMIR() == true || LC_IsKorea() == true) { if (IS_BOTARYABLE_ZONE(GetMapIndex()) == true) @@ -1890,8 +1890,8 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) case ITEM_WEAPON: case ITEM_ARMOR: case ITEM_ROD: - case ITEM_RING: // ű - case ITEM_BELT: // ű Ʈ + case ITEM_RING: // 신규 반지 아이템 + case ITEM_BELT: // 신규 벨트 아이템 // MINING case ITEM_PICK: // END_OF_MINING @@ -1900,10 +1900,10 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) else UnequipItem(item); break; - // ȥ . - // Ŭ, ȥ Ͽ item use Ŷ . - // ȥ item move Ŷ Ѵ. - // ȥ Ѵ. + // 착용하지 않은 용혼석은 사용할 수 없다. + // 정상적인 클라라면, 용혼석에 관하여 item use 패킷을 보낼 수 없다. + // 용혼석 착용은 item move 패킷으로 한다. + // 착용한 용혼석은 추출한다. case ITEM_DS: { if (!item->IsEquipped()) @@ -2027,7 +2027,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) std::vector item_gets; int count = 0; - if (dwBoxVnum == 50033 && LC_IsYMIR()) // ˼ + if (dwBoxVnum == 50033 && LC_IsYMIR()) // 알수없는 상자 { if (GetLevel() < 15) { @@ -2036,7 +2036,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } } - if( (dwBoxVnum > 51500 && dwBoxVnum < 52000) || (dwBoxVnum >= 50255 && dwBoxVnum <= 50260) ) // ȥ + if( (dwBoxVnum > 51500 && dwBoxVnum < 52000) || (dwBoxVnum >= 50255 && dwBoxVnum <= 50260) ) // 용혼원석들 { if( !(this->DragonSoul_IsQualified()) ) { @@ -2129,7 +2129,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } else { - // ο ü value 0 ų ȣ Ƿ װ . + // 새로운 수련서는 value 0 에 스킬 번호가 있으므로 그것을 사용. dwVnum = item->GetValue(0); } @@ -2149,7 +2149,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) if (distribution_test_server) iReadDelay /= 3; - //ѱ 쿡 ð 24ð + //한국 본섭의 경우에는 시간을 24시간 고정 if (LC_IsKorea()) iReadDelay = 86400; @@ -2222,10 +2222,10 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) // PC_BANG_ITEM_ADD if (item->IsPCBangItem() == true) { - // PC üũؼ ó + // PC방인지 체크해서 처리 if (CPCBangManager::instance().IsPCBangIP(GetDesc()->GetHostName()) == false) { - // PC ƴ! + // PC방이 아님! ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC0\xCC \xBE\xC6\xC0\xCC\xC5\xDB\xC0\xBA PC\xB9\xE6\xBF\xA1\xBC\xAD\xB8\xB8 \xBB\xE7\xBF\xEB\xC7\xD2 \xBC\xF6 \xC0\xD6\xBD\xC0\xB4\xCF\xB4\xD9.")); return false; } @@ -2273,7 +2273,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) bool used = false; - if (item->GetValue(0) != 0) // HP 밪 ȸ + if (item->GetValue(0) != 0) // HP 절대값 회복 { if (GetHP() < GetMaxHP()) { @@ -2283,7 +2283,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } } - if (item->GetValue(1) != 0) // SP 밪 ȸ + if (item->GetValue(1) != 0) // SP 절대값 회복 { if (GetSP() < GetMaxSP()) { @@ -2293,7 +2293,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } } - if (item->GetValue(3) != 0) // HP % ȸ + if (item->GetValue(3) != 0) // HP % 회복 { if (GetHP() < GetMaxHP()) { @@ -2303,7 +2303,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } } - if (item->GetValue(4) != 0) // SP % ȸ + if (item->GetValue(4) != 0) // SP % 회복 { if (GetSP() < GetMaxSP()) { @@ -2361,7 +2361,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) { return false; } - // 켱 ȥ ؼ ϵ Ѵ. + // 우선 용혼석에 관해서만 하도록 한다. if (pDestItem->IsDragonSoul()) { int ret; @@ -2417,7 +2417,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) { return false; } - // 켱 ȥ ؼ ϵ Ѵ. + // 우선 용혼석에 관해서만 하도록 한다. if (pDestItem->IsDragonSoul()) { int ret = pDestItem->GiveMoreTime_Fix(item->GetValue(ITEM_VALUE_CHARGING_AMOUNT_IDX)); @@ -2446,15 +2446,15 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) switch (item->GetVnum()) { - //ũ + //크리스마스 란주 case ITEM_NOG_POCKET: { /* - ִɷġ : item_proto value ǹ - ̵ӵ value 1 - ݷ value 2 - ġ value 3 - ӽð value 0 ( ) + 란주능력치 : item_proto value 의미 + 이동속도 value 1 + 공격력 value 2 + 경험치 value 3 + 지속시간 value 0 (단위 초) */ if (FindAffect(AFFECT_NOG_ABILITY)) @@ -2473,15 +2473,15 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } break; - //󸶴ܿ + //라마단용 사탕 case ITEM_RAMADAN_CANDY: { /* - ɷġ : item_proto value ǹ - ̵ӵ value 1 - ݷ value 2 - ġ value 3 - ӽð value 0 ( ) + 사탕능력치 : item_proto value 의미 + 이동속도 value 1 + 공격력 value 2 + 경험치 value 3 + 지속시간 value 0 (단위 초) */ int time = item->GetValue(0); @@ -2531,9 +2531,9 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } break; - // + //기존 용기의 망토 case UNIQUE_ITEM_CAPE_OF_COURAGE: - //󸶴 + //라마단 보상용 용기의 망토 case 70057: case REWARD_BOX_UNIQUE_ITEM_CAPE_OF_COURAGE: AggregateMonster(); @@ -2552,7 +2552,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) case 30094: case 30095: case 30096: - // ָӴ + // 복주머니 { const int MAX_BAG_INFO = 26; static struct LuckyBagInfo @@ -2640,7 +2640,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) if (bi[i].vnum == 50300) { - // ųü Ưϰ ش. + // 스킬수련서는 특수하게 준다. GiveRandomSkillBook(); } else if (bi[i].vnum == 1) @@ -2655,7 +2655,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } break; - case 50004: // ̺Ʈ + case 50004: // 이벤트용 감지기 { if (item->GetSocket(0)) { @@ -2663,7 +2663,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } else { - // ó + // 처음 사용시 int iMapIndex = GetMapIndex(); PIXEL_POSITION pos; @@ -2686,10 +2686,10 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) if (distance < 1000.0f) { - // ߰! + // 발견! ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC0\xCC\xBA\xA5\xC6\xAE\xBF\xEB \xB0\xA8\xC1\xF6\xB1\xE2\xB0\xA1 \xBD\xC5\xBA\xF1\xB7\xCE\xBF\xEE \xBA\xFB\xC0\xBB \xB3\xBB\xB8\xE7 \xBB\xE7\xB6\xF3\xC1\xFD\xB4\xCF\xB4\xD9.")); - // Ƚ ִ ٸ Ѵ. + // 사용횟수에 따라 주는 아이템을 다르게 한다. struct TEventStoneInfo { DWORD dwVnum; @@ -2788,7 +2788,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) pdw[0] = info[i].dwVnum; pdw[1] = info[i].count; - // ÷ Ѵ + // 추첨서는 소켓을 설정한다 DBManager::instance().ReturnQuery(QID_LOTTO, GetPlayerID(), pdw, "INSERT INTO lotto_list VALUES(0, 'server%s', %u, NOW())", get_table_postfix(), GetPlayerID()); @@ -2808,7 +2808,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) if (len < 0 || len >= (int) sizeof(chatbuf)) len = sizeof(chatbuf) - 1; - ++len; // \0 ڱ + ++len; // \0 문자까지 보내기 TPacketGCChat pack_chat; pack_chat.header = HEADER_GC_CHAT; @@ -2834,7 +2834,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) else dist = 3; - // . + // 많이 사용했으면 사라진다. const int STONE_DETECT_MAX_TRY = 10; if (item->GetSocket(0) >= STONE_DETECT_MAX_TRY) { @@ -2854,7 +2854,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) if (len < 0 || len >= (int) sizeof(chatbuf)) len = sizeof(chatbuf) - 1; - ++len; // \0 ڱ + ++len; // \0 문자까지 보내기 TPacketGCChat pack_chat; pack_chat.header = HEADER_GC_CHAT; @@ -2874,8 +2874,8 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } break; - case 27989: // - case 76006: // + case 27989: // 영석감지기 + case 76006: // 선물용 영석감지기 { LPSECTREE_MAP pMap = SECTREE_MANAGER::instance().GetMap(GetMapIndex()); @@ -2937,13 +2937,13 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } break; - case 27996: // + case 27996: // 독병 item->SetCount(item->GetCount() - 1); /*if (GetSkillLevel(SKILL_CREATE_POISON)) AddAffect(AFFECT_ATT_GRADE, POINT_ATT_GRADE, 3, AFF_DRINK_POISON, 15*60, 0, true); else { - // ٷⰡ 50% 50% ݷ +2 + // 독다루기가 없으면 50% 즉사 50% 공격력 +2 if (Random::get(0, 1)) { if (GetHP() > 100) @@ -2956,12 +2956,12 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) }*/ break; - case 27987: // - // 50 47990 - // 30 - // 10 47992 - // 7 û 47993 - // 3 47994 + case 27987: // 조개 + // 50 돌조각 47990 + // 30 꽝 + // 10 백진주 47992 + // 7 청진주 47993 + // 3 피진주 47994 { item->SetCount(item->GetCount() - 1); @@ -3009,12 +3009,12 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } break; - case 71013: // + case 71013: // 축제용폭죽 CreateFly(Random::get(FLY_FIREWORK1, FLY_FIREWORK6), this); item->SetCount(item->GetCount() - 1); break; - case 50100: // + case 50100: // 폭죽 case 50101: case 50102: case 50103: @@ -3025,7 +3025,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) item->SetCount(item->GetCount() - 1); break; - case 50200: // + case 50200: // 보따리 if (LC_IsYMIR() == true || LC_IsKorea() == true) { if (IS_BOTARYABLE_ZONE(GetMapIndex()) == true) @@ -3048,7 +3048,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) item->SetCount(item->GetCount() - 1); break; - case 50301: // ַ ü + case 50301: // 통솔력 수련서 case 50302: case 50303: { @@ -3084,7 +3084,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } break; - case 50304: // ü + case 50304: // 연계기 수련서 case 50305: case 50306: { @@ -3125,7 +3125,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } } break; - case 50311: // ü + case 50311: // 언어 수련서 case 50312: case 50313: { @@ -3155,7 +3155,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } break; - case 50061 : // Ϻ ȯ ų ü + case 50061 : // 일본 말 소환 스킬 수련서 { if (IsPolymorphed()) { @@ -3184,9 +3184,9 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } break; - case 50314: case 50315: case 50316: // ü - case 50323: case 50324: // ü - case 50325: case 50326: // ö ü + case 50314: case 50315: case 50316: // 변신 수련서 + case 50323: case 50324: // 증혈 수련서 + case 50325: case 50326: // 철통 수련서 { if (IsPolymorphed() == true) { @@ -3352,7 +3352,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) { if (FindAffect(AFFECT_SKILL_NO_BOOK_DELAY)) { - // ־ȼ ߿ ð + // 주안술서 사용중에는 시간 제한 무시 RemoveAffect(AFFECT_SKILL_NO_BOOK_DELAY); ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC1\xD6\xBE\xC8\xBC\xFA\xBC\xAD\xB8\xA6 \xC5\xEB\xC7\xD8 \xC1\xD6\xC8\xAD\xC0\xD4\xB8\xB6\xBF\xA1\xBC\xAD \xBA\xFC\xC1\xAE\xB3\xAA\xBF\xD4\xBD\xC0\xB4\xCF\xB4\xD9.")); } @@ -3392,8 +3392,8 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } break; - case 70102: // - case 70103: // + case 70102: // 선두 + case 70103: // 선두 { if (GetAlignment() >= 0) return false; @@ -3413,7 +3413,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } break; - case 71107: // õ + case 71107: // 천도복숭아 { int val = item->GetValue(0); int interval = item->GetValue(1); @@ -3460,7 +3460,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } break; - case 71109: // Ż + case 71109: // 탈석서 case 72719: { LPITEM item2; @@ -3531,12 +3531,12 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } break; - case 70201: // Ż - case 70202: // () - case 70203: // (ݻ) - case 70204: // () - case 70205: // () - case 70206: // () + case 70201: // 탈색제 + case 70202: // 염색약(흰색) + case 70203: // 염색약(금색) + case 70204: // 염색약(빨간색) + case 70205: // 염색약(갈색) + case 70206: // 염색약(검은색) { // NEW_HAIR_STYLE_ADD if (GetPart(PART_HAIR) >= 1001) @@ -3610,7 +3610,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) if (item->GetVnum() == ITEM_VALENTINE_ROSE && SEX_MALE==GET_SEX(this) || item->GetVnum() == ITEM_VALENTINE_CHOCOLATE && SEX_FEMALE==GET_SEX(this)) { - // ʾ . + // 성별이 맞지않아 쓸 수 없다. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xBC\xBA\xBA\xB0\xC0\xCC \xB8\xC2\xC1\xF6\xBE\xCA\xBE\xC6 \xC0\xCC \xBE\xC6\xC0\xCC\xC5\xDB\xC0\xBB \xBF\xAD \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9.")); return false; } @@ -3634,7 +3634,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) if (item->GetVnum() == ITEM_WHITEDAY_CANDY && SEX_MALE==GET_SEX(this) || item->GetVnum() == ITEM_WHITEDAY_ROSE && SEX_FEMALE==GET_SEX(this)) { - // ʾ . + // 성별이 맞지않아 쓸 수 없다. ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xBC\xBA\xBA\xB0\xC0\xCC \xB8\xC2\xC1\xF6\xBE\xCA\xBE\xC6 \xC0\xCC \xBE\xC6\xC0\xCC\xC5\xDB\xC0\xBB \xBF\xAD \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9.")); return false; } @@ -3645,7 +3645,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } break; - case 50011: // + case 50011: // 월광보합 { DWORD dwBoxVnum = 50011; std::vector dwVnums; @@ -3726,7 +3726,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) case 50107: { EffectPacket(SE_CHINA_FIREWORK); - // ÷ش + // 스턴 공격을 올려준다 AddAffect(AFFECT_CHINA_FIREWORK, POINT_STUN_PCT, 30, AFF_CHINA_FIREWORK, 5*60, 0, true); item->SetCount(item->GetCount()-1); } @@ -3741,7 +3741,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } EffectPacket(SE_SPIN_TOP); - // ÷ش + // 스턴 공격을 올려준다 AddAffect(AFFECT_CHINA_FIREWORK, POINT_STUN_PCT, 30, AFF_CHINA_FIREWORK, 5*60, 0, true); item->SetCount(item->GetCount()-1); } @@ -3767,7 +3767,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) VCardUse(this, this, item); break; - case ITEM_ELK_VNUM: // ٷ + case ITEM_ELK_VNUM: // 돈꾸러미 { int iGold = item->GetSocket(0); ITEM_MANAGER::instance().RemoveItem(item); @@ -3776,7 +3776,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } break; - // ǥ + //군주의 증표 case 70021: { int HealPrice = quest::CQuestManager::instance().GetEventFlag("MonarchHealGold"); @@ -3799,7 +3799,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } break; - case 71092 : // ü ӽ + case 71092 : // 변신 해체부 임시 { if (m_pkChrTarget != NULL) { @@ -3820,9 +3820,9 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } break; - case 71051 : // 簡 + case 71051 : // 진재가 { - // , ̰, Ʈ 簡 + // 유럽, 싱가폴, 베트남 진재가 사용금지 if (LC_IsEurope() || LC_IsSingapore() || LC_IsVietnam()) return false; @@ -3867,9 +3867,9 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } break; - case 71052 : // + case 71052 : // 진재경 { - // , ̰, Ʈ 簡 + // 유럽, 싱가폴, 베트남 진재가 사용금지 if (LC_IsEurope() || LC_IsSingapore() || LC_IsVietnam()) return false; @@ -3910,8 +3910,8 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) case ITEM_AUTO_SP_RECOVERY_M: case ITEM_AUTO_SP_RECOVERY_L: case ITEM_AUTO_SP_RECOVERY_X: - // ù ϴ ġ ... - // ׷ ׳ ϵ ڵ. ڿ ڵ ۵. + // 무시무시하지만 이전에 하던 걸 고치기는 무섭고... + // 그래서 그냥 하드 코딩. 선물 상자용 자동물약 아이템들. case REWARD_BOX_ITEM_AUTO_SP_RECOVERY_XS: case REWARD_BOX_ITEM_AUTO_SP_RECOVERY_S: case REWARD_BOX_ITEM_AUTO_HP_RECOVERY_XS: @@ -4121,7 +4121,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) bool used = false; - if (item->GetValue(0) != 0) // HP 밪 ȸ + if (item->GetValue(0) != 0) // HP 절대값 회복 { if (GetHP() < GetMaxHP()) { @@ -4131,7 +4131,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } } - if (item->GetValue(1) != 0) // SP 밪 ȸ + if (item->GetValue(1) != 0) // SP 절대값 회복 { if (GetSP() < GetMaxSP()) { @@ -4141,7 +4141,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } } - if (item->GetValue(3) != 0) // HP % ȸ + if (item->GetValue(3) != 0) // HP % 회복 { if (GetHP() < GetMaxHP()) { @@ -4151,7 +4151,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) } } - if (item->GetValue(4) != 0) // SP % ȸ + if (item->GetValue(4) != 0) // SP % 회복 { if (GetSP() < GetMaxSP()) { @@ -4333,7 +4333,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) const int MEMORY_PORTAL = 2; - // gm_guild_build, oxevent ʿ ȯ ȯ ϰ + // gm_guild_build, oxevent 맵에서 귀환부 귀환기억부 를 사용못하게 막음 if (GetMapIndex() == 200 || GetMapIndex() == 113) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC7\xF6\xC0\xE7 \xC0\xA7\xC4\xA1\xBF\xA1\xBC\xAD \xBB\xE7\xBF\xEB\xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9.")); @@ -4359,7 +4359,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) return false; // END_OF_CONSUME_LIFE_WHEN_USE_WARP_ITEM - if (item->GetValue(0) == TOWN_PORTAL) // ȯ + if (item->GetValue(0) == TOWN_PORTAL) // 귀환부 { if (item->GetSocket(0) == 0) { @@ -4390,7 +4390,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) ProcessRecallItem(item); } } - else if (item->GetValue(0) == MEMORY_PORTAL) // ȯ + else if (item->GetValue(0) == MEMORY_PORTAL) // 귀환기억부 { if (item->GetSocket(0) == 0) { @@ -4427,15 +4427,15 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) if (item2->IsExchanging()) return false; - if (item2->GetVnum() >= 28330 && item2->GetVnum() <= 28343) // +3 + if (item2->GetVnum() >= 28330 && item2->GetVnum() <= 28343) // 영석+3 { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("+3 \xBF\xB5\xBC\xAE\xC0\xBA \xC0\xCC \xBE\xC6\xC0\xCC\xC5\xDB\xC0\xB8\xB7\xCE \xB0\xB3\xB7\xAE\xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9")); return false; } - if (item2->GetVnum() >= 28430 && item2->GetVnum() <= 28443) // +4 + if (item2->GetVnum() >= 28430 && item2->GetVnum() <= 28443) // 영석+4 { - if (item->GetVnum() == 71056) // ûǼ + if (item->GetVnum() == 71056) // 청룡의숨결 { RefineItem(item, item2); } @@ -4471,9 +4471,9 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) BuffOnAttr_RemoveBuffsFromItem(item2); } - // [NOTE] ڽƬ ۿ Ӽ οϵ, 簡 ƴ޶ û ־. - // ANTI_CHANGE_ATTRIBUTE Flag ߰Ͽ ȹ ϰ Ʈ ֵ ̾ - // ׵ ʿ ġ ش޷ ׳ ⼭ ... -_- + // [NOTE] 코스튬 아이템에는 아이템 최초 생성시 랜덤 속성을 부여하되, 재경재가 등등은 막아달라는 요청이 있었음. + // 원래 ANTI_CHANGE_ATTRIBUTE 같은 아이템 Flag를 추가하여 기획 레벨에서 유연하게 컨트롤 할 수 있도록 할 예정이었으나 + // 그딴거 필요없으니 닥치고 빨리 해달래서 그냥 여기서 막음... -_- if (ITEM_COSTUME == item2->GetType()) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xBC\xD3\xBC\xBA\xC0\xBB \xBA\xAF\xB0\xE6\xC7\xD2 \xBC\xF6 \xBE\xF8\xB4\xC2 \xBE\xC6\xC0\xCC\xC5\xDB\xC0\xD4\xB4\xCF\xB4\xD9.")); @@ -4541,8 +4541,8 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) if (GM_PLAYER == GetGMLevel() && false == test_server) { // - // Event Flag Ӽ ð ð 귶 ˻ϰ - // ð 귶ٸ Ӽ濡 ð ش. + // Event Flag 를 통해 이전에 아이템 속성 변경을 한 시간으로 부터 충분한 시간이 흘렀는지 검사하고 + // 시간이 충분히 흘렀다면 현재 속성변경에 대한 시간을 설정해 준다. // DWORD dwChangeItemAttrCycle = quest::CQuestManager::instance().GetEventFlag(msc_szChangeItemAttrCycleFlag); @@ -4589,8 +4589,8 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) else { - // Ưó - // 簡 ߰ ȵɰŶ Ͽ ϵ ڵ. + // 연재경 특수처리 + // 절대로 연재가 추가 안될거라 하여 하드 코딩함. if (item->GetVnum() == 71151 || item->GetVnum() == 76023) { if ((item2->GetType() == ITEM_WEAPON) @@ -4639,8 +4639,8 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) if (item2->GetAttributeCount() < 4) { - // 簡 Ưó - // 簡 ߰ ȵɰŶ Ͽ ϵ ڵ. + // 연재가 특수처리 + // 절대로 연재가 추가 안될거라 하여 하드 코딩함. if (item->GetVnum() == 71152 || item->GetVnum() == 76024) { if ((item2->GetType() == ITEM_WEAPON) @@ -4701,15 +4701,15 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) break; case USE_ADD_ATTRIBUTE2 : - // ູ - // 簡񼭸 Ӽ 4 ߰ Ų ۿ ؼ ϳ Ӽ ٿش. + // 축복의 구슬 + // 재가비서를 통해 속성을 4개 추가 시킨 아이템에 대해서 하나의 속성을 더 붙여준다. if (item2->GetAttributeSetIndex() == -1) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xBC\xD3\xBC\xBA\xC0\xBB \xBA\xAF\xB0\xE6\xC7\xD2 \xBC\xF6 \xBE\xF8\xB4\xC2 \xBE\xC6\xC0\xCC\xC5\xDB\xC0\xD4\xB4\xCF\xB4\xD9.")); return false; } - // Ӽ ̹ 4 ߰ Ǿ Ӽ ߰ ϴ. + // 속성이 이미 4개 추가 되었을 때만 속성을 추가 가능하다. if (item2->GetAttributeCount() == 4) { char buf[21]; @@ -4883,10 +4883,10 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) // PC_BANG_ITEM_ADD if (item->IsPCBangItem() == true) { - // PC üũؼ ó + // PC방인지 체크해서 처리 if (CPCBangManager::instance().IsPCBangIP(GetDesc()->GetHostName()) == false) { - // PC ƴ! + // PC방이 아님! ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC0\xCC \xBE\xC6\xC0\xCC\xC5\xDB\xC0\xBA PC\xB9\xE6\xBF\xA1\xBC\xAD\xB8\xB8 \xBB\xE7\xBF\xEB\xC7\xD2 \xBC\xF6 \xC0\xD6\xBD\xC0\xB4\xCF\xB4\xD9.")); return false; } @@ -4904,7 +4904,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) item->SetCount(item->GetCount() - 1); break; - // ų ó + // 물약 제조 스킬용 레시피 처리 case USE_RECIPE : { LPITEM pSource1 = FindSpecifyItem(item->GetValue(1)); @@ -5035,7 +5035,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) for (i = 0; i < ITEM_SOCKET_MAX_NUM; ++i) if (item2->GetSocket(i) >= 1 && item2->GetSocket(i) <= 2 && item2->GetSocket(i) >= item->GetValue(2)) { - // Ȯ + // 석 확률 if (Random::get(1, 100) <= 30) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB8\xDE\xC6\xBE\xBC\xAE \xBA\xCE\xC2\xF8\xBF\xA1 \xBC\xBA\xB0\xF8\xC7\xCF\xBF\xB4\xBD\xC0\xB4\xCF\xB4\xD9.")); @@ -5072,7 +5072,7 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell) break; case ITEM_BLEND: - // ο ʵ + // 새로운 약초들 SPDLOG_DEBUG("ITEM_BLEND!!"); if (Blend_Item_find(item->GetVnum())) { @@ -5188,9 +5188,9 @@ bool CHARACTER::UseItem(TItemPos Cell, TItemPos DestCell) return false; } - // ȥ SUMMONABLE_ZONE ִ° WarpToPC() üũ + // 경혼반지 사용지 상대방이 SUMMONABLE_ZONE에 있는가는 WarpToPC()에서 체크 - //Ÿ ʿ ȯθ ƹ. + //삼거리 관려 맵에서는 귀환부를 막아버린다. if (CThreeWayWar::instance().IsThreeWayWarMapIndex(GetMapIndex())) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xBB\xEF\xB0\xC5\xB8\xAE \xC0\xFC\xC5\xF5 \xC2\xFC\xB0\xA1\xC1\xDF\xBF\xA1\xB4\xC2 \xB1\xCD\xC8\xAF\xBA\xCE,\xB1\xCD\xC8\xAF\xB1\xE2\xBE\xEF\xBA\xCE\xB8\xA6 \xBB\xE7\xBF\xEB\xC7\xD2\xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9.")); @@ -5198,7 +5198,7 @@ bool CHARACTER::UseItem(TItemPos Cell, TItemPos DestCell) } int iPulse = thecore_pulse(); - //â üũ + //창고 연후 체크 if (iPulse - GetSafeboxLoadTime() < PASSES_PER_SEC(g_nPortalLimitTime)) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC3\xA2\xB0\xED\xB8\xA6 \xBF\xAC\xC8\xC4 %d\xC3\xCA \xC0\xCC\xB3\xBB\xBF\xA1\xB4\xC2 \xB1\xCD\xC8\xAF\xBA\xCE,\xB1\xCD\xC8\xAF\xB1\xE2\xBE\xEF\xBA\xCE\xB8\xA6 \xBB\xE7\xBF\xEB\xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."), g_nPortalLimitTime); @@ -5208,7 +5208,7 @@ bool CHARACTER::UseItem(TItemPos Cell, TItemPos DestCell) return false; } - //ŷ â üũ + //거래관련 창 체크 if (GetExchange() || GetMyShop() || GetShopOwner() || IsOpenSafebox() || IsCubeOpen()) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB0\xC5\xB7\xA1\xC3\xA2,\xC3\xA2\xB0\xED \xB5\xEE\xC0\xBB \xBF\xAC \xBB\xF3\xC5\xC2\xBF\xA1\xBC\xAD\xB4\xC2 \xB1\xCD\xC8\xAF\xBA\xCE,\xB1\xCD\xC8\xAF\xB1\xE2\xBE\xEF\xBA\xCE \xB8\xA6 \xBB\xE7\xBF\xEB\xC7\xD2\xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9.")); @@ -5216,7 +5216,7 @@ bool CHARACTER::UseItem(TItemPos Cell, TItemPos DestCell) } //PREVENT_REFINE_HACK - // ðüũ + //개량후 시간체크 { if (iPulse - GetRefineTime() < PASSES_PER_SEC(g_nPortalLimitTime)) { @@ -5239,7 +5239,7 @@ bool CHARACTER::UseItem(TItemPos Cell, TItemPos DestCell) //END_PREVENT_ITEM_COPY - //ȯ Ÿüũ + //귀환부 거리체크 if (item->GetVnum() != 70302) { PIXEL_POSITION posWarp; @@ -5249,13 +5249,13 @@ bool CHARACTER::UseItem(TItemPos Cell, TItemPos DestCell) double nDist = 0; const double nDistant = 5000.0; - //ȯ + //귀환기억부 if (item->GetVnum() == 22010) { x = item->GetSocket(0) - GetX(); y = item->GetSocket(1) - GetY(); } - //ȯ + //귀환부 else if (item->GetVnum() == 22000) { SECTREE_MANAGER::instance().GetRecallPositionByEmpire(GetMapIndex(), GetEmpire(), posWarp); @@ -5284,7 +5284,7 @@ bool CHARACTER::UseItem(TItemPos Cell, TItemPos DestCell) } //PREVENT_PORTAL_AFTER_EXCHANGE - //ȯ ðüũ + //교환 후 시간체크 if (iPulse - GetExchangeTime() < PASSES_PER_SEC(g_nPortalLimitTime)) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB0\xC5\xB7\xA1 \xC8\xC4 %d\xC3\xCA \xC0\xCC\xB3\xBB\xBF\xA1\xB4\xC2 \xB1\xCD\xC8\xAF\xBA\xCE,\xB1\xCD\xC8\xAF\xB1\xE2\xBE\xEF\xBA\xCE\xB5\xEE\xC0\xBB \xBB\xE7\xBF\xEB\xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."), g_nPortalLimitTime); @@ -5294,7 +5294,7 @@ bool CHARACTER::UseItem(TItemPos Cell, TItemPos DestCell) } - // ŷâ üũ + //보따리 비단 사용시 거래창 제한 체크 if (item->GetVnum() == 50200 | item->GetVnum() == 71049) { if (GetExchange() || GetMyShop() || GetShopOwner() || IsOpenSafebox() || IsCubeOpen()) @@ -5306,7 +5306,7 @@ bool CHARACTER::UseItem(TItemPos Cell, TItemPos DestCell) } //END_PREVENT_TRADE_WINDOW - if (IS_SET(item->GetFlag(), ITEM_FLAG_LOG)) // α׸ ó + if (IS_SET(item->GetFlag(), ITEM_FLAG_LOG)) // 사용 로그를 남기는 아이템 처리 { DWORD vid = item->GetVID(); DWORD oldCount = item->GetCount(); @@ -5320,7 +5320,7 @@ bool CHARACTER::UseItem(TItemPos Cell, TItemPos DestCell) bool ret = UseItemEx(item, DestCell); - if (NULL == ITEM_MANAGER::instance().FindByVID(vid)) // UseItemEx Ǿ. α׸ + if (NULL == ITEM_MANAGER::instance().FindByVID(vid)) // UseItemEx에서 아이템이 삭제 되었다. 삭제 로그를 남김 { LogManager::instance().ItemLog(this, vid, vnum, "REMOVE", hint); } @@ -5370,7 +5370,7 @@ bool CHARACTER::DropItem(TItemPos Cell, BYTE bCount) if (bCount == 0 || bCount > item->GetCount()) bCount = item->GetCount(); - SyncQuickslot(QUICKSLOT_TYPE_ITEM, Cell.cell, 255); // Quickslot + SyncQuickslot(QUICKSLOT_TYPE_ITEM, Cell.cell, 255); // Quickslot 에서 지움 LPITEM pkItemToDrop; @@ -5409,8 +5409,8 @@ bool CHARACTER::DropItem(TItemPos Cell, BYTE bCount) if (pkItemToDrop->AddToGround(GetMapIndex(), pxPos)) { - // ѱ ش޶ Ƽ - // ٴڿ Ӽα׸ . + // 한국에는 아이템을 버리고 복구해달라는 진상유저들이 많아서 + // 아이템을 바닥에 버릴 시 속성로그를 남긴다. if (LC_IsYMIR()) item->AttrLog(); @@ -5458,11 +5458,11 @@ bool CHARACTER::DropGold(int gold) //Motion(MOTION_PICKUP); PointChange(POINT_GOLD, -gold, true); - // ٴ װ ִµ, - // ó ߿ ϳ, - // ũγ, Ἥ 1000 带 0 , - // ٰ ûϴ ִ. - // ׷ 츦 ġ 忡 ؼ α׸ . + // 브라질에 돈이 없어진다는 버그가 있는데, + // 가능한 시나리오 중에 하나는, + // 메크로나, 핵을 써서 1000원 이하의 돈을 계속 버려 골드를 0으로 만들고, + // 돈이 없어졌다고 복구 신청하는 것일 수도 있다. + // 따라서 그런 경우를 잡기 위해 낮은 수치의 골드에 대해서도 로그를 남김. if (LC_IsBrazil() == true) { if (gold >= 213) @@ -5470,7 +5470,7 @@ bool CHARACTER::DropGold(int gold) } else { - if (gold > 1000) // õ ̻ Ѵ. + if (gold > 1000) // 천원 이상만 기록한다. LogManager::instance().CharLog(this, gold, "DROP_GOLD", ""); } @@ -5527,20 +5527,20 @@ bool CHARACTER::MoveItem(TItemPos Cell, TItemPos DestCell, BYTE count) return false; } - // ȹ û Ʈ κ丮 Ư Ÿ ۸ ִ. + // 기획자의 요청으로 벨트 인벤토리에는 특정 타입의 아이템만 넣을 수 있다. if (DestCell.IsBeltInventoryPosition() && false == CBeltInventoryHelper::CanMoveIntoBeltInventory(item)) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC0\xCC \xBE\xC6\xC0\xCC\xC5\xDB\xC0\xBA \xBA\xA7\xC6\xAE \xC0\xCE\xBA\xA5\xC5\xE4\xB8\xAE\xB7\xCE \xBF\xC5\xB1\xE6 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9.")); return false; } - // ̹ ٸ ű , 'å ' Ȯϰ ű + // 이미 착용중인 아이템을 다른 곳으로 옮기는 경우, '장책 해제' 가능한 지 확인하고 옮김 if (Cell.IsEquipPosition() && !CanUnequipNow(item)) return false; if (DestCell.IsEquipPosition()) { - if (GetItem(DestCell)) // ˻ص ȴ. + if (GetItem(DestCell)) // 장비일 경우 한 곳만 검사해도 된다. { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC0\xCC\xB9\xCC \xC0\xE5\xBA\xF1\xB8\xA6 \xC2\xF8\xBF\xEB\xC7\xCF\xB0\xED \xC0\xD6\xBD\xC0\xB4\xCF\xB4\xD9.")); @@ -5568,7 +5568,7 @@ bool CHARACTER::MoveItem(TItemPos Cell, TItemPos DestCell, BYTE count) return false; } } - // ȥ ƴ ȥ κ  . + // 용혼석이 아닌 아이템은 용혼석 인벤에 들어갈 수 없다. else if (DRAGON_SOUL_INVENTORY == DestCell.window_type) return false; @@ -5576,7 +5576,7 @@ bool CHARACTER::MoveItem(TItemPos Cell, TItemPos DestCell, BYTE count) if ((item2 = GetItem(DestCell)) && item != item2 && item2->IsStackable() && !IS_SET(item2->GetAntiFlag(), ITEM_ANTIFLAG_STACK) && - item2->GetVnum() == item->GetVnum()) // ĥ ִ + item2->GetVnum() == item->GetVnum()) // 합칠 수 있는 아이템의 경우 { for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i) if (item2->GetSocket(i) != item->GetSocket(i)) @@ -5695,7 +5695,7 @@ namespace NPartyPickupDistribute { ch->PointChange(POINT_GOLD, iMoney, true); - if (iMoney > 1000) // õ ̻ Ѵ. + if (iMoney > 1000) // 천원 이상만 기록한다. LogManager::instance().CharLog(ch, iMoney, "GET_GOLD", ""); } } @@ -5713,7 +5713,7 @@ void CHARACTER::GiveGold(int iAmount) { LPPARTY pParty = GetParty(); - // Ƽ ִ . + // 파티가 있는 경우 나누어 가진다. DWORD dwTotal = iAmount; DWORD dwMyAmount = dwTotal; @@ -5732,18 +5732,18 @@ void CHARACTER::GiveGold(int iAmount) PointChange(POINT_GOLD, dwMyAmount, true); - if (dwMyAmount > 1000) // õ ̻ Ѵ. + if (dwMyAmount > 1000) // 천원 이상만 기록한다. LogManager::instance().CharLog(this, dwMyAmount, "GET_GOLD", ""); } else { PointChange(POINT_GOLD, iAmount, true); - // ٴ װ ִµ, - // ó ߿ ϳ, - // ũγ, Ἥ 1000 带 0 , - // ٰ ûϴ ִ. - // ׷ 츦 ġ 忡 ؼ α׸ . + // 브라질에 돈이 없어진다는 버그가 있는데, + // 가능한 시나리오 중에 하나는, + // 메크로나, 핵을 써서 1000원 이하의 돈을 계속 버려 골드를 0으로 만들고, + // 돈이 없어졌다고 복구 신청하는 것일 수도 있다. + // 따라서 그런 경우를 잡기 위해 낮은 수치의 골드에 대해서도 로그를 남김. if (LC_IsBrazil() == true) { if (iAmount >= 213) @@ -5751,7 +5751,7 @@ void CHARACTER::GiveGold(int iAmount) } else { - if (iAmount > 1000) // õ ̻ Ѵ. + if (iAmount > 1000) // 천원 이상만 기록한다. LogManager::instance().CharLog(this, iAmount, "GET_GOLD", ""); } } @@ -5771,7 +5771,7 @@ bool CHARACTER::PickupItem(DWORD dwVID) { if (item->IsOwnership(this)) { - // ϴ ũ + // 만약 주으려 하는 아이템이 엘크라면 if (item->GetType() == ITEM_ELK) { GiveGold(item->GetCount()); @@ -5781,7 +5781,7 @@ bool CHARACTER::PickupItem(DWORD dwVID) Save(); } - // ̶ + // 평범한 아이템이라면 else { if (item->IsStackable() && !IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_STACK)) @@ -5866,7 +5866,7 @@ bool CHARACTER::PickupItem(DWORD dwVID) } else if (!IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_GIVE | ITEM_ANTIFLAG_DROP) && GetParty()) { - // ٸ Ƽ Ѵٸ + // 다른 파티원 소유권 아이템을 주으려고 한다면 NPartyPickupDistribute::FFindOwnership funcFindOwnership(item); GetParty()->ForEachOnlineMember(funcFindOwnership); @@ -5938,23 +5938,23 @@ bool CHARACTER::SwapItem(BYTE bCell, BYTE bDestCell) TItemPos srcCell(INVENTORY, bCell), destCell(INVENTORY, bDestCell); - // ùٸ Cell ˻ - // ȥ Swap Ƿ, ⼭ ɸ. + // 올바른 Cell 인지 검사 + // 용혼석은 Swap할 수 없으므로, 여기서 걸림. //if (bCell >= INVENTORY_MAX_NUM + WEAR_MAX_NUM || bDestCell >= INVENTORY_MAX_NUM + WEAR_MAX_NUM) if (srcCell.IsDragonSoulEquipPosition() || destCell.IsDragonSoulEquipPosition()) return false; - // CELL ˻ + // 같은 CELL 인지 검사 if (bCell == bDestCell) return false; - // â ġ Swap . + // 둘 다 장비창 위치면 Swap 할 수 없다. if (srcCell.IsEquipPosition() && destCell.IsEquipPosition()) return false; LPITEM item1, item2; - // item2 â ִ ǵ. + // item2가 장비창에 있는 것이 되도록. if (srcCell.IsEquipPosition()) { item1 = GetInventoryItem(bDestCell); @@ -5975,21 +5975,21 @@ bool CHARACTER::SwapItem(BYTE bCell, BYTE bDestCell) return false; } - // item2 bCellġ  ִ ȮѴ. + // item2가 bCell위치에 들어갈 수 있는지 확인한다. if (!IsEmptyItemGrid(TItemPos (INVENTORY, item1->GetCell()), item2->GetSize(), item1->GetCell())) return false; - // ٲ â + // 바꿀 아이템이 장비창에 있으면 if (TItemPos(EQUIPMENT, item2->GetCell()).IsEquipPosition()) { BYTE bEquipCell = item2->GetCell() - INVENTORY_MAX_NUM; BYTE bInvenCell = item1->GetCell(); - // ְ, ¿߸ + // 착용중인 아이템을 벗을 수 있고, 착용 예정 아이템이 착용 가능한 상태여야만 진행 if (false == CanUnequipNow(item2) || false == CanEquipNow(item1)) return false; - if (bEquipCell != item1->FindEquipCell(this)) // ġ϶ + if (bEquipCell != item1->FindEquipCell(this)) // 같은 위치일때만 허용 return false; item2->RemoveFromCharacter(); @@ -6044,7 +6044,7 @@ bool CHARACTER::UnequipItem(LPITEM item) } // -// @version 05/07/05 Bang2ni - Skill 1.5 ̳ +// @version 05/07/05 Bang2ni - Skill 사용후 1.5 초 이내에 장비 착용 금지 // bool CHARACTER::EquipItem(LPITEM item, int iCandidateCell) { @@ -6062,7 +6062,7 @@ bool CHARACTER::EquipItem(LPITEM item, int iCandidateCell) if (iWearCell < 0) return false; - // 𰡸 ź ¿ νõ Ա + // 무언가를 탄 상태에서 턱시도 입기 금지 if (iWearCell == WEAR_BODY && IsRiding() && (item->GetVnum() >= 11901 && item->GetVnum() <= 11904)) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB8\xBB\xC0\xBB \xC5\xBA \xBB\xF3\xC5\xC2\xBF\xA1\xBC\xAD \xBF\xB9\xBA\xB9\xC0\xBB \xC0\xD4\xC0\xBB \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9.")); @@ -6081,14 +6081,14 @@ bool CHARACTER::EquipItem(LPITEM item, int iCandidateCell) return false; } - //ű Ż 뿩 üũ + //신규 탈것 사용시 기존 말 사용여부 체크 if(item->IsRideItem() && IsRiding()) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC0\xCC\xB9\xCC \xC5\xBB\xB0\xCD\xC0\xBB \xC0\xCC\xBF\xEB\xC1\xDF\xC0\xD4\xB4\xCF\xB4\xD9.")); return false; } - // ȭ ̿ܿ ð Ǵ ų 1.5 Ŀ ü + // 화살 이외에는 마지막 공격 시간 또는 스킬 사용 1.5 후에 장비 교체가 가능 DWORD dwCurTime = get_dword_time(); if (iWearCell != WEAR_ARROW @@ -6098,11 +6098,11 @@ bool CHARACTER::EquipItem(LPITEM item, int iCandidateCell) return false; } - // ȥ Ư ó + // 용혼석 특수 처리 if (item->IsDragonSoul()) { - // Ÿ ȥ ̹  ִٸ . - // ȥ swap ϸ ȵ. + // 같은 타입의 용혼석이 이미 들어가 있다면 착용할 수 없다. + // 용혼석은 swap을 지원하면 안됨. if(GetInventoryItem(INVENTORY_MAX_NUM + iWearCell)) { ChatPacket(CHAT_TYPE_INFO, "\xC0\xCC\xB9\xCC \xB0\xB0\xC0\xBA \xC1\xBE\xB7\xF9\xC0\xC7 \xBF\xEB\xC8\xA5\xBC\xAE\xC0\xBB \xC2\xF8\xBF\xEB\xC7\xCF\xB0\xED \xC0\xD6\xBD\xC0\xB4\xCF\xB4\xD9."); @@ -6114,13 +6114,13 @@ bool CHARACTER::EquipItem(LPITEM item, int iCandidateCell) return false; } } - // ȥ ƴ. + // 용혼석이 아님. else { - // ִٸ, + // 착용할 곳에 아이템이 있다면, if (GetWear(iWearCell) && !IS_SET(GetWear(iWearCell)->GetFlag(), ITEM_FLAG_IRREMOVABLE)) { - // ѹ Ұ. swap Ұ + // 이 아이템은 한번 박히면 변경 불가. swap 역시 완전 불가 if (item->GetWearFlag() == WEARABLE_ABILITY) return false; @@ -6142,13 +6142,13 @@ bool CHARACTER::EquipItem(LPITEM item, int iCandidateCell) if (true == item->IsEquipped()) { - // ĺʹ ʾƵ ð Ǵ ó. + // 아이템 최초 사용 이후부터는 사용하지 않아도 시간이 차감되는 방식 처리. if (-1 != item->GetProto()->cLimitRealTimeFirstUseIndex) { - // ̶ δ Socket1 ǴѴ. (Socket1 Ƚ ) + // 한 번이라도 사용한 아이템인지 여부는 Socket1을 보고 판단한다. (Socket1에 사용횟수 기록) if (0 == item->GetSocket(1)) { - // 밡ɽð Default Limit Value ϵ, Socket0 ϵ Ѵ. ( ) + // 사용가능시간은 Default 값으로 Limit Value 값을 사용하되, Socket0에 값이 있으면 그 값을 사용하도록 한다. (단위는 초) int duration = (0 != item->GetSocket(0)) ? item->GetSocket(0) : item->GetProto()->aLimits[item->GetProto()->cLimitRealTimeFirstUseIndex].lValue; if (0 == duration) @@ -6166,27 +6166,27 @@ bool CHARACTER::EquipItem(LPITEM item, int iCandidateCell) const DWORD& dwVnum = item->GetVnum(); - // 󸶴 ̺Ʈ ʽ´ (71135) Ʈ ߵ + // 라마단 이벤트 초승달의 반지(71135) 착용시 이펙트 발동 if (true == CItemVnumHelper::IsRamadanMoonRing(dwVnum)) { this->EffectPacket(SE_EQUIP_RAMADAN_RING); } - // ҷ (71136) Ʈ ߵ + // 할로윈 사탕(71136) 착용시 이펙트 발동 else if (true == CItemVnumHelper::IsHalloweenCandy(dwVnum)) { this->EffectPacket(SE_EQUIP_HALLOWEEN_CANDY); } - // ູ (71143) Ʈ ߵ + // 행복의 반지(71143) 착용시 이펙트 발동 else if (true == CItemVnumHelper::IsHappinessRing(dwVnum)) { this->EffectPacket(SE_EQUIP_HAPPINESS_RING); } - // ҴƮ(71145) Ʈ ߵ + // 사랑의 팬던트(71145) 착용시 이펙트 발동 else if (true == CItemVnumHelper::IsLovePendant(dwVnum)) { this->EffectPacket(SE_EQUIP_LOVE_PENDANT); } - // ITEM_UNIQUE , SpecialItemGroup ǵǾ ְ, (item->GetSIGVnum() != NULL) + // ITEM_UNIQUE의 경우, SpecialItemGroup에 정의되어 있고, (item->GetSIGVnum() != NULL) // else if (ITEM_UNIQUE == item->GetType() && 0 != item->GetSIGVnum()) { @@ -6336,7 +6336,7 @@ int CHARACTER::CountSpecifyItem(DWORD vnum) const item = GetInventoryItem(i); if (NULL != item && item->GetVnum() == vnum) { - // ϵ ̸ Ѿ. + // 개인 상점에 등록된 물건이면 넘어간다. if (m_pkMyShop && m_pkMyShop->IsSellingItem(item->GetID())) { continue; @@ -6364,7 +6364,7 @@ void CHARACTER::RemoveSpecifyItem(DWORD vnum, DWORD count) if (GetInventoryItem(i)->GetVnum() != vnum) continue; - // ϵ ̸ Ѿ. ( Ǹŵɶ κ !) + //개인 상점에 등록된 물건이면 넘어간다. (개인 상점에서 판매될때 이 부분으로 들어올 경우 문제!) if(m_pkMyShop) { bool isItemSelling = m_pkMyShop->IsSellingItem(GetInventoryItem(i)->GetID()); @@ -6390,7 +6390,7 @@ void CHARACTER::RemoveSpecifyItem(DWORD vnum, DWORD count) } } - // ó ϴ. + // 예외처리가 약하다. if (count) SPDLOG_WARN("CHARACTER::RemoveSpecifyItem cannot remove enough item vnum {}, still remain {}", vnum, count); } @@ -6424,7 +6424,7 @@ void CHARACTER::RemoveSpecifyTypeItem(BYTE type, DWORD count) if (GetInventoryItem(i)->GetType() != type) continue; - // ϵ ̸ Ѿ. ( Ǹŵɶ κ !) + //개인 상점에 등록된 물건이면 넘어간다. (개인 상점에서 판매될때 이 부분으로 들어올 경우 문제!) if(m_pkMyShop) { bool isItemSelling = m_pkMyShop->IsSellingItem(GetInventoryItem(i)->GetID()); @@ -6617,9 +6617,9 @@ LPITEM CHARACTER::AutoGiveItem(DWORD dwItemVnum, BYTE bCount, int iRarePct, bool { item->AddToGround(GetMapIndex(), GetXYZ()); item->StartDestroyEvent(); - // Ƽ flag ɷִ , - // κ  ¿ Ʈ Ǹ, - // ownership (300) Ѵ. + // 안티 드랍 flag가 걸려있는 아이템의 경우, + // 인벤에 빈 공간이 없어서 어쩔 수 없이 떨어트리게 되면, + // ownership을 아이템이 사라질 때까지(300초) 유지한다. if (IS_SET(item->GetAntiFlag(), ITEM_ANTIFLAG_DROP)) item->SetOwnership(this, 300); else @@ -6731,7 +6731,7 @@ bool CHARACTER::CanReceiveItem(LPCHARACTER from, LPITEM item) const case 20101: case 20102: case 20103: - // ʱ + // 초급 말 if (item->GetVnum() == ITEM_REVIVE_HORSE_1) { if (!IsDead()) @@ -6758,7 +6758,7 @@ bool CHARACTER::CanReceiveItem(LPCHARACTER from, LPITEM item) const case 20104: case 20105: case 20106: - // ߱ + // 중급 말 if (item->GetVnum() == ITEM_REVIVE_HORSE_2) { if (!IsDead()) @@ -6785,7 +6785,7 @@ bool CHARACTER::CanReceiveItem(LPCHARACTER from, LPITEM item) const case 20107: case 20108: case 20109: - // + // 고급 말 if (item->GetVnum() == ITEM_REVIVE_HORSE_3) { if (!IsDead()) @@ -6922,7 +6922,7 @@ bool CHARACTER::IsEquipUniqueItem(DWORD dwItemVnum) const return true; } - // (ߺ) üũѴ. + // 언어반지인 경우 언어반지(견본) 인지도 체크한다. if (dwItemVnum == UNIQUE_ITEM_RING_OF_LANGUAGE) return IsEquipUniqueItem(UNIQUE_ITEM_RING_OF_LANGUAGE_SAMPLE); @@ -7083,7 +7083,7 @@ bool CHARACTER::ItemProcess_Hair(LPITEM item, int iDestCell) { if (item->CheckItemUseLevel(GetLevel()) == false) { - // ѿ ɸ + // 레벨 제한에 걸림 ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xBE\xC6\xC1\xF7 \xC0\xCC \xB8\xD3\xB8\xAE\xB8\xA6 \xBB\xE7\xBF\xEB\xC7\xD2 \xBC\xF6 \xBE\xF8\xB4\xC2 \xB7\xB9\xBA\xA7\xC0\xD4\xB4\xCF\xB4\xD9.")); return false; } @@ -7093,7 +7093,7 @@ bool CHARACTER::ItemProcess_Hair(LPITEM item, int iDestCell) switch (GetJob()) { case JOB_WARRIOR : - hair -= 72000; // 73001 - 72000 = 1001 ȣ + hair -= 72000; // 73001 - 72000 = 1001 부터 헤어 번호 시작 break; case JOB_ASSASSIN : @@ -7168,10 +7168,10 @@ bool CHARACTER::ItemProcess_Polymorph(LPITEM item) case 70107 : case 71093 : { - // а ó + // 둔갑구 처리 SPDLOG_DEBUG("USE_POLYMORPH_BALL PID({}) vnum({})", GetPlayerID(), dwVnum); - // üũ + // 레벨 제한 체크 int iPolymorphLevelLimit = std::max(0, 20 - GetLevel() * 3 / 10); if (pMob->m_table.bLevel >= GetLevel() + iPolymorphLevelLimit) { @@ -7202,11 +7202,11 @@ bool CHARACTER::ItemProcess_Polymorph(LPITEM item) case 50322: { - // + // 보류 - // а ó - // 0 1 2 - // а ȣ а + // 둔갑서 처리 + // 소켓0 소켓1 소켓2 + // 둔갑할 몬스터 번호 수련정도 둔갑서 레벨 SPDLOG_DEBUG("USE_POLYMORPH_BOOK: {}({}) vnum({})", GetName(), GetPlayerID(), dwVnum); if (CPolymorphUtils::instance().PolymorphCharacter(this, item, pMob) == true) @@ -7324,8 +7324,8 @@ void CHARACTER::AutoRecoveryItemProcess(const EAffectTypes type) const int pct_of_will_used = (amount_of_used + amount) * 100 / amount_of_full; bool bLog = false; - // 뷮 10% α׸ - // (뷮 %, ڸ ٲ α׸ .) + // 사용량의 10% 단위로 로그를 남김 + // (사용량의 %에서, 십의 자리가 바뀔 때마다 로그를 남김.) if ((pct_of_will_used / 10) - (pct_of_used / 10) >= 1) bLog = true; pItem->SetSocket(idx_of_amount_of_used, amount_of_used + amount, bLog); @@ -7397,7 +7397,7 @@ bool CHARACTER::IsValidItemPosition(TItemPos Pos) const } -// Ƽ ũ.. exp true msg ϰ return false ϴ ũ (Ϲ verify 뵵 return ణ ݴ ̸ 򰥸 ְڴ..) +// 귀찮아서 만든 매크로.. exp가 true면 msg를 출력하고 return false 하는 매크로 (일반적인 verify 용도랑은 return 때문에 약간 반대라 이름때문에 헷갈릴 수도 있겠다..) #define VERIFY_MSG(exp, msg) \ if (true == (exp)) { \ ChatPacket(CHAT_TYPE_INFO, LC_TEXT(msg)); \ @@ -7405,7 +7405,7 @@ bool CHARACTER::IsValidItemPosition(TItemPos Pos) const } -/// ij ¸ ־ item ִ Ȯϰ, Ұ ϴٸ ijͿ ˷ִ Լ +/// 현재 캐릭터의 상태를 바탕으로 주어진 item을 착용할 수 있는 지 확인하고, 불가능 하다면 캐릭터에게 이유를 알려주는 함수 bool CHARACTER::CanEquipNow(const LPITEM item, const TItemPos& srcCell, const TItemPos& destCell) /*const*/ { const TItemTable* itemTable = item->GetProto(); @@ -7503,18 +7503,18 @@ bool CHARACTER::CanEquipNow(const LPITEM item, const TItemPos& srcCell, const TI return true; } -/// ij ¸ item ִ Ȯϰ, Ұ ϴٸ ijͿ ˷ִ Լ +/// 현재 캐릭터의 상태를 바탕으로 착용 중인 item을 벗을 수 있는 지 확인하고, 불가능 하다면 캐릭터에게 이유를 알려주는 함수 bool CHARACTER::CanUnequipNow(const LPITEM item, const TItemPos& srcCell, const TItemPos& destCell) /*const*/ { if (ITEM_BELT == item->GetType()) VERIFY_MSG(CBeltInventoryHelper::IsExistItemInBeltInventory(this), "\xBA\xA7\xC6\xAE \xC0\xCE\xBA\xA5\xC5\xE4\xB8\xAE\xBF\xA1 \xBE\xC6\xC0\xCC\xC5\xDB\xC0\xCC \xC1\xB8\xC0\xE7\xC7\xCF\xB8\xE9 \xC7\xD8\xC1\xA6\xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."); - // + // 영원히 해제할 수 없는 아이템 if (IS_SET(item->GetFlag(), ITEM_FLAG_IRREMOVABLE)) return false; - // unequip κ丮 ű ڸ ִ Ȯ + // 아이템 unequip시 인벤토리로 옮길 때 빈 자리가 있는 지 확인 { int pos = -1; diff --git a/src/game/src/char_manager.cpp b/src/game/src/char_manager.cpp index 0b9d688..7724f2f 100644 --- a/src/game/src/char_manager.cpp +++ b/src/game/src/char_manager.cpp @@ -114,7 +114,7 @@ void CHARACTER_MANAGER::DestroyCharacter(LPCHARACTER ch, const char* file, size_ return; // prevent duplicated destrunction } - // Ҽӵ ʹ ϵ. + // 던전에 소속된 몬스터는 던전에서도 삭제하도록. if (ch->IsNPC() && !ch->IsPet() && ch->GetRider() == NULL) { if (ch->GetDungeon()) @@ -230,7 +230,7 @@ LPCHARACTER CHARACTER_MANAGER::FindPC(const char * name) LPCHARACTER CHARACTER_MANAGER::SpawnMobRandomPosition(DWORD dwVnum, int lMapIndex) { - // ֱ ְ + // 왜구 스폰할지말지를 결정할 수 있게함 { if (dwVnum == 5001 && !quest::CQuestManager::instance().GetEventFlag("japan_regen")) { @@ -239,7 +239,7 @@ LPCHARACTER CHARACTER_MANAGER::SpawnMobRandomPosition(DWORD dwVnum, int lMapInde } } - // ¸ ְ + // 해태를 스폰할지 말지를 결정할 수 있게 함 { if (dwVnum == 5002 && !quest::CQuestManager::instance().GetEventFlag("newyear_mob")) { @@ -248,7 +248,7 @@ LPCHARACTER CHARACTER_MANAGER::SpawnMobRandomPosition(DWORD dwVnum, int lMapInde } } - // ̺Ʈ + // 광복절 이벤트 { if (dwVnum == 5004 && !quest::CQuestManager::instance().GetEventFlag("independence_day")) { @@ -448,7 +448,7 @@ LPCHARACTER CHARACTER_MANAGER::SpawnMobRange(DWORD dwVnum, int lMapIndex, int sx if (!pkMob) return NULL; - if (pkMob->m_table.bType == CHAR_TYPE_STONE) // SPAWN ִ. + if (pkMob->m_table.bType == CHAR_TYPE_STONE) // 돌은 무조건 SPAWN 모션이 있다. bSpawnMotion = true; int i = 16; @@ -512,7 +512,7 @@ bool CHARACTER_MANAGER::SpawnMoveGroup(DWORD dwVnum, int lMapIndex, int sx, int if (!tch) { - if (i == 0) // Ͱ 쿡 ׳ + if (i == 0) // 못만든 몬스터가 대장일 경우에는 그냥 실패 return false; continue; @@ -596,7 +596,7 @@ LPCHARACTER CHARACTER_MANAGER::SpawnGroup(DWORD dwVnum, int lMapIndex, int sx, i if (!tch) { - if (i == 0) // Ͱ 쿡 ׳ + if (i == 0) // 못만든 몬스터가 대장일 경우에는 그냥 실패 return NULL; continue; @@ -652,11 +652,11 @@ void CHARACTER_MANAGER::Update(int iPulse) BeginPendingDestroy(); - // PC ij Ʈ + // PC 캐릭터 업데이트 { if (!m_map_pkPCChr.empty()) { - // ̳ + // 컨테이너 복사 CHARACTER_VECTOR v; v.reserve(m_map_pkPCChr.size()); #ifdef __GNUC__ @@ -680,7 +680,7 @@ void CHARACTER_MANAGER::Update(int iPulse) // for_each_pc(bind2nd(mem_fun(&CHARACTER::UpdateCharacter), iPulse)); } - // Ʈ + // 몬스터 업데이트 { if (!m_set_pkChrState.empty()) { @@ -695,7 +695,7 @@ void CHARACTER_MANAGER::Update(int iPulse) } } - // Ÿ Ʈ + // 산타 따로 업데이트 { CharacterVectorInteractor i; @@ -706,7 +706,7 @@ void CHARACTER_MANAGER::Update(int iPulse) } } - // 1ð ѹ + // 1시간에 한번씩 몹 사냥 개수 기록 if (0 == (iPulse % PASSES_PER_SEC(3600))) { for (itertype(m_map_dwMobKillCount) it = m_map_dwMobKillCount.begin(); it != m_map_dwMobKillCount.end(); ++it) @@ -715,11 +715,11 @@ void CHARACTER_MANAGER::Update(int iPulse) m_map_dwMobKillCount.clear(); } - // ׽Ʈ 60ʸ ij + // 테스트 서버에서는 60초마다 캐릭터 개수를 센다 if (test_server && 0 == (iPulse % PASSES_PER_SEC(60))) SPDLOG_TRACE("CHARACTER COUNT vid {} pid {}", m_map_pkChrByVID.size(), m_map_pkChrByPID.size()); - // DestroyCharacter ϱ + // 지연된 DestroyCharacter 하기 FlushPendingDestroy(); } @@ -835,7 +835,7 @@ void CHARACTER_MANAGER::RegisterRaceNumMap(LPCHARACTER ch) { DWORD dwVnum = ch->GetRaceNum(); - if (m_set_dwRegisteredRaceNum.find(dwVnum) != m_set_dwRegisteredRaceNum.end()) // ϵ ȣ ̸ + if (m_set_dwRegisteredRaceNum.find(dwVnum) != m_set_dwRegisteredRaceNum.end()) // 등록된 번호 이면 { SPDLOG_TRACE("RegisterRaceNumMap {} {}", ch->GetName(), dwVnum); m_map_pkChrByRaceNum[dwVnum].insert(ch); @@ -859,7 +859,7 @@ bool CHARACTER_MANAGER::GetCharactersByRaceNum(DWORD dwRaceNum, CharacterVectorI if (it == m_map_pkChrByRaceNum.end()) return false; - // ̳ + // 컨테이너 복사 i = it->second; return true; } @@ -1056,8 +1056,8 @@ void CHARACTER_MANAGER::SendScriptToMap(int lMapIndex, const std::string & s) bool CHARACTER_MANAGER::BeginPendingDestroy() { - // Begin Ŀ Begin ϴ 쿡 Flush ʴ - // ̹ ۵Ǿ false ó + // Begin 이 후에 Begin을 또 하는 경우에 Flush 하지 않는 기능 지원을 위해 + // 이미 시작되어있으면 false 리턴 처리 if (m_bUsePendingDestroy) return false; @@ -1069,7 +1069,7 @@ void CHARACTER_MANAGER::FlushPendingDestroy() { using namespace std; - m_bUsePendingDestroy = false; // ÷׸ ؾ Destroy ó + m_bUsePendingDestroy = false; // 플래그를 먼저 설정해야 실제 Destroy 처리가 됨 if (!m_set_pkChrPendingDestroy.empty()) { diff --git a/src/game/src/char_quickslot.cpp b/src/game/src/char_quickslot.cpp index 884cd3b..a9c087d 100644 --- a/src/game/src/char_quickslot.cpp +++ b/src/game/src/char_quickslot.cpp @@ -9,7 +9,7 @@ ///////////////////////////////////////////////////////////////////////////// // QUICKSLOT HANDLING ///////////////////////////////////////////////////////////////////////////// -void CHARACTER::SyncQuickslot(BYTE bType, BYTE bOldPos, BYTE bNewPos) // bNewPos == 255 DELETE +void CHARACTER::SyncQuickslot(BYTE bType, BYTE bOldPos, BYTE bNewPos) // bNewPos == 255 면 DELETE { if (bOldPos == bNewPos) return; @@ -121,7 +121,7 @@ bool CHARACTER::SwapQuickslot(BYTE a, BYTE b) if (a >= QUICKSLOT_MAX_NUM || b >= QUICKSLOT_MAX_NUM) return false; - // ڸ ٲ۴. + // 퀵 슬롯 자리를 서로 바꾼다. quickslot = m_quickslot[a]; m_quickslot[a] = m_quickslot[b]; diff --git a/src/game/src/char_resist.cpp b/src/game/src/char_resist.cpp index 115daee..4eb411e 100644 --- a/src/game/src/char_resist.cpp +++ b/src/game/src/char_resist.cpp @@ -6,7 +6,7 @@ #include "affect.h" #include "locale_service.h" -// +// 독 const int poison_damage_rate[MOB_RANK_MAX_NUM] = { 80, 50, 40, 30, 25, 1 @@ -135,7 +135,7 @@ EVENTFUNC(fire_event) /* - LEVEL .. + LEVEL에 의한.. +8 0% +7 5% @@ -184,7 +184,7 @@ void CHARACTER::AttackedByPoison(LPCHARACTER pkAttacker) if (m_pkPoisonEvent) return; - if (m_bHasPoisoned && !IsPC()) // ʹ ѹ ɸ. + if (m_bHasPoisoned && !IsPC()) // 몬스터는 독이 한번만 걸린다. return; if (pkAttacker && pkAttacker->GetLevel() < GetLevel()) @@ -201,7 +201,7 @@ void CHARACTER::AttackedByPoison(LPCHARACTER pkAttacker) /*if (IsImmune(IMMUNE_POISON)) return;*/ - // , ɷȴ! + // 독 내성 굴림 실패, 독에 걸렸다! m_bHasPoisoned = true; AddAffect(AFFECT_POISON, POINT_NONE, 0, AFF_POISON, POISON_LENGTH + 1, 0, true); diff --git a/src/game/src/char_skill.cpp b/src/game/src/char_skill.cpp index 77fbd5f..83b5bd3 100644 --- a/src/game/src/char_skill.cpp +++ b/src/game/src/char_skill.cpp @@ -62,7 +62,7 @@ void CHARACTER::SetSkillNextReadTime(DWORD dwVnum, time_t time) bool TSkillUseInfo::HitOnce(DWORD dwVnum) { - // ʾ Ѵ. + // 쓰지도않았으면 때리지도 못한다. if (!bUsed) return false; @@ -97,7 +97,7 @@ bool TSkillUseInfo::UseSkill(bool isGrandMaster, DWORD vid, DWORD dwCooltime, in this->isGrandMaster = isGrandMaster; DWORD dwCur = get_dword_time(); - // Ÿ ʾҴ. + // 아직 쿨타임이 끝나지 않았다. if (bUsed && dwNextSkillUsableTime > dwCur) { SPDLOG_DEBUG("cooltime is not over delta {}", dwNextSkillUsableTime - dwCur); @@ -280,7 +280,7 @@ bool CHARACTER::LearnGrandMasterSkill(DWORD dwSkillVnum) { if (FindAffect(AFFECT_SKILL_NO_BOOK_DELAY)) { - // ־ȼ ߿ ð + // 주안술서 사용중에는 시간 제한 무시 RemoveAffect(AFFECT_SKILL_NO_BOOK_DELAY); ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC1\xD6\xBE\xC8\xBC\xFA\xBC\xAD\xB8\xA6 \xC5\xEB\xC7\xD8 \xC1\xD6\xC8\xAD\xC0\xD4\xB8\xB6\xBF\xA1\xBC\xAD \xBA\xFC\xC1\xAE\xB3\xAA\xBF\xD4\xBD\xC0\xB4\xCF\xB4\xD9.")); } @@ -293,7 +293,7 @@ bool CHARACTER::LearnGrandMasterSkill(DWORD dwSkillVnum) } */ - // bType 0̸ ó å + // bType이 0이면 처음부터 책으로 수련 가능 if (pkSk->dwType == 0) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB1\xD7\xB7\xA3\xB5\xE5 \xB8\xB6\xBD\xBA\xC5\xCD \xBC\xF6\xB7\xC3\xC0\xBB \xC7\xD2 \xBC\xF6 \xBE\xF8\xB4\xC2 \xBD\xBA\xC5\xB3\xC0\xD4\xB4\xCF\xB4\xD9.")); @@ -316,7 +316,7 @@ bool CHARACTER::LearnGrandMasterSkill(DWORD dwSkillVnum) strTrainSkill = os.str(); } - // ⼭ Ȯ մϴ. + // 여기서 확률을 계산합니다. BYTE bLastLevel = GetSkillLevel(dwSkillVnum); int idx = std::min(9, GetSkillLevel(dwSkillVnum) - 30); @@ -438,7 +438,7 @@ bool CHARACTER::LearnSkillByBook(DWORD dwSkillVnum, BYTE bProb) } } - // bType 0̸ ó å + // bType이 0이면 처음부터 책으로 수련 가능 if (pkSk->dwType != 0) { if (GetSkillMasterType(dwSkillVnum) != SKILL_MASTER) @@ -457,7 +457,7 @@ bool CHARACTER::LearnSkillByBook(DWORD dwSkillVnum, BYTE bProb) { if (FindAffect(AFFECT_SKILL_NO_BOOK_DELAY)) { - // ־ȼ ߿ ð + // 주안술서 사용중에는 시간 제한 무시 RemoveAffect(AFFECT_SKILL_NO_BOOK_DELAY); ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC1\xD6\xBE\xC8\xBC\xFA\xBC\xAD\xB8\xA6 \xC5\xEB\xC7\xD8 \xC1\xD6\xC8\xAD\xC0\xD4\xB8\xB6\xBF\xA1\xBC\xAD \xBA\xFC\xC1\xAE\xB3\xAA\xBF\xD4\xBD\xC0\xB4\xCF\xB4\xD9.")); } @@ -469,7 +469,7 @@ bool CHARACTER::LearnSkillByBook(DWORD dwSkillVnum, BYTE bProb) } } - // ⼭ Ȯ մϴ. + // 여기서 확률을 계산합니다. BYTE bLastLevel = GetSkillLevel(dwSkillVnum); if (bProb != 0) @@ -527,7 +527,7 @@ bool CHARACTER::LearnSkillByBook(DWORD dwSkillVnum, BYTE bProb) if (Random::get(1, 100) > percent) { - // åб⿡ + // 책읽기에 성공 if (read_count >= need_bookcount) { SkillLevelUp(dwSkillVnum, SKILL_UP_BY_BOOK); @@ -564,7 +564,7 @@ bool CHARACTER::LearnSkillByBook(DWORD dwSkillVnum, BYTE bProb) } else { - // Ʈ ε + // 사용자의 퀘스트 정보 로드 실패 } } // INTERNATIONAL_VERSION @@ -721,7 +721,7 @@ void CHARACTER::SkillLevelUp(DWORD dwVnum, BYTE bMethod) if (!IsLearnableSkill(dwVnum)) return; - // ׷ ʹ Ʈθ డ + // 그랜드 마스터는 퀘스트로만 수행가능 if (pkSk->dwType != 0) { switch (GetSkillMasterType(pkSk->dwVnum)) @@ -738,7 +738,7 @@ void CHARACTER::SkillLevelUp(DWORD dwVnum, BYTE bMethod) if (bMethod == SKILL_UP_BY_POINT) { - // Ͱ ƴ ¿ ð + // 마스터가 아닌 상태에서만 수련가능 if (GetSkillMasterType(pkSk->dwVnum) != SKILL_NORMAL) return; @@ -747,7 +747,7 @@ void CHARACTER::SkillLevelUp(DWORD dwVnum, BYTE bMethod) } else if (bMethod == SKILL_UP_BY_BOOK) { - if (pkSk->dwType != 0) // ʾҰų Ʈ ø ų ó å ִ. + if (pkSk->dwType != 0) // 직업에 속하지 않았거나 포인트로 올릴수 없는 스킬은 처음부터 책으로 배울 수 있다. if (GetSkillMasterType(pkSk->dwVnum) != SKILL_MASTER) return; } @@ -801,11 +801,11 @@ void CHARACTER::SkillLevelUp(DWORD dwVnum, BYTE bMethod) if (pkSk->dwType != 0) { - // ڱ ׷̵ ϴ ڵ + // 갑자기 그레이드 업하는 코딩 switch (GetSkillMasterType(pkSk->dwVnum)) { case SKILL_NORMAL: - // ų ׷̵ 17~20 + // 번섭은 스킬 업그레이드 17~20 사이 랜덤 마스터 수련 if (GetSkillLevel(pkSk->dwVnum) >= 17) { if (GetQuestFlag("reset_scroll.force_to_master_skill") > 0) @@ -863,7 +863,7 @@ void CHARACTER::ResetSkill() if (NULL == m_pSkillLevels) return; - // ų ½Ű ʴ´ + // 보조 스킬은 리셋시키지 않는다 std::vector > vec; size_t count = sizeof(s_adwSubSkillVnums) / sizeof(s_adwSubSkillVnums[0]); @@ -994,7 +994,7 @@ EVENTFUNC(ChainLightningEvent) SPDLOG_DEBUG("chainlighting event {}", pkChr->GetName()); - if (pkChrVictim->GetParty()) // Ƽ + if (pkChrVictim->GetParty()) // 파티 먼저 { pkTarget = pkChrVictim->GetParty()->GetNextOwnership(NULL, pkChrVictim->GetX(), pkChrVictim->GetY()); if (pkTarget == pkChrVictim || !Random::get(0, 2) || pkChr->GetChainLightingExcept().find(pkTarget) != pkChr->GetChainLightingExcept().end()) @@ -1090,7 +1090,7 @@ struct FuncSplashDamage } if (m_pkChr->IsPC()) - // ų Ÿ ó ʴ´. + // 길드 스킬은 쿨타임 처리를 하지 않는다. if (!(m_pkSk->dwVnum >= GUILD_SKILL_START && m_pkSk->dwVnum <= GUILD_SKILL_END)) if (!m_bDisableCooltime && m_pInfo && !m_pInfo->HitOnce(m_pkSk->dwVnum) && m_pkSk->dwVnum != SKILL_MUYEONG) { @@ -1159,7 +1159,7 @@ struct FuncSplashDamage m_pkSk->SetPointVar("chain", m_pkChr->GetChainLightningIndex()); m_pkChr->IncChainLightningIndex(); - bool bUnderEunhyung = m_pkChr->GetAffectedEunhyung() > 0; // ̰ ⼭ ?? + bool bUnderEunhyung = m_pkChr->GetAffectedEunhyung() > 0; // 이건 왜 여기서 하지?? m_pkSk->SetPointVar("ek", m_pkChr->GetAffectedEunhyung()*1./100); //m_pkChr->ClearAffectedEunhyung(); @@ -1241,11 +1241,11 @@ struct FuncSplashDamage if (m_pkChr->IsPC() && m_pkChr->m_SkillUseInfo[m_pkSk->dwVnum].GetMainTargetVID() != (DWORD) pkChrVictim->GetVID()) { - // + // 데미지 감소 iDam = (int) (iDam * m_pkSk->kSplashAroundDamageAdjustPoly.Eval()); } - // TODO ų Ÿ ؾѴ. + // TODO 스킬에 따른 데미지 타입 기록해야한다. EDamageType dt = DAMAGE_TYPE_NONE; switch (m_pkSk->bSkillAttrType) @@ -1268,7 +1268,7 @@ struct FuncSplashDamage case WEAPON_TWO_HANDED: iDam = iDam * (100 - pkChrVictim->GetPoint(POINT_RESIST_TWOHAND)) / 100; - // հ Ƽ 10% + // 양손검 페널티 10% //iDam = iDam * 95 / 100; break; @@ -1293,8 +1293,8 @@ struct FuncSplashDamage case SKILL_ATTR_TYPE_RANGE: dt = DAMAGE_TYPE_RANGE; - // ƾƾƾ - // ߴ װ ־ ٽϸ + // 으아아아악 + // 예전에 적용안했던 버그가 있어서 방어력 계산을 다시하면 유저가 난리남 //iDam -= pkChrVictim->GetPoint(POINT_DEF_GRADE); iDam = iDam * (100 - pkChrVictim->GetPoint(POINT_RESIST_BOW)) / 100; break; @@ -1302,8 +1302,8 @@ struct FuncSplashDamage case SKILL_ATTR_TYPE_MAGIC: dt = DAMAGE_TYPE_MAGIC; iDam = CalcAttBonus(m_pkChr, pkChrVictim, iDam); - // ƾƾƾ - // ߴ װ ־ ٽϸ + // 으아아아악 + // 예전에 적용안했던 버그가 있어서 방어력 계산을 다시하면 유저가 난리남 //iDam -= pkChrVictim->GetPoint(POINT_MAGIC_DEF_GRADE); iDam = iDam * (100 - pkChrVictim->GetPoint(POINT_RESIST_MAGIC)) / 100; break; @@ -1314,13 +1314,13 @@ struct FuncSplashDamage } // - // 20091109 ų Ӽ û ۾ - // ų ̺ SKILL_FLAG_WIND, SKILL_FLAG_ELEC, SKILL_FLAG_FIRE ų - // Ƿ RESIST_WIND, RESIST_ELEC, RESIST_FIRE ʰ ־. + // 20091109 독일 스킬 속성 요청 작업 + // 기존 스킬 테이블에 SKILL_FLAG_WIND, SKILL_FLAG_ELEC, SKILL_FLAG_FIRE를 가진 스킬이 + // 전혀 없었으므로 몬스터의 RESIST_WIND, RESIST_ELEC, RESIST_FIRE도 사용되지 않고 있었다. // - // PvP PvE뷱 и ǵ NPC ϵ 뷱 - // ϱ mob_proto RESIST_MAGIC RESIST_WIND, RESIST_ELEC, RESIST_FIRE - // Ͽ. + // PvP와 PvE밸런스 분리를 위해 의도적으로 NPC만 적용하도록 했으며 기존 밸런스와 차이점을 + // 느끼지 못하기 위해 mob_proto의 RESIST_MAGIC을 RESIST_WIND, RESIST_ELEC, RESIST_FIRE로 + // 복사하였다. // if (pkChrVictim->IsNPC()) { @@ -1627,7 +1627,7 @@ EVENTFUNC(skill_gwihwan_event) { PIXEL_POSITION pos; - // + // 성공 if (SECTREE_MANAGER::instance().GetRecallPositionByEmpire(ch->GetMapIndex(), ch->GetEmpire(), pos)) { SPDLOG_DEBUG("Recall: {} {} {} -> {} {}", ch->GetName(), ch->GetX(), ch->GetY(), pos.x, pos.y); @@ -1641,7 +1641,7 @@ EVENTFUNC(skill_gwihwan_event) } else { - // + //실패 ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB1\xCD\xC8\xAF\xBF\xA1 \xBD\xC7\xC6\xD0\xC7\xCF\xBF\xB4\xBD\xC0\xB4\xCF\xB4\xD9.")); } return 0; @@ -1666,11 +1666,11 @@ int CHARACTER::ComputeSkillAtPosition(DWORD dwVnum, const PIXEL_POSITION& posTar SPDLOG_TRACE("ComputeSkillAtPosition {} vnum {} x {} y {} level {}", GetName(), dwVnum, posTarget.x, posTarget.y, bSkillLevel); - // ų ġ . + // 나에게 쓰는 스킬은 내 위치를 쓴다. //if (IS_SET(pkSk->dwFlag, SKILL_FLAG_SELFONLY)) // posTarget = GetXYZ(); - // ÷ ƴ ų ̸ ̻ϴ + // 스플래쉬가 아닌 스킬은 주위이면 이상하다 if (!IS_SET(pkSk->dwFlag, SKILL_FLAG_SPLASH)) return BATTLE_NONE; @@ -1769,7 +1769,7 @@ int CHARACTER::ComputeSkillAtPosition(DWORD dwVnum, const PIXEL_POSITION& posTar if (IS_SET(pkSk->dwFlag, SKILL_FLAG_ATTACK | SKILL_FLAG_USE_MELEE_DAMAGE | SKILL_FLAG_USE_MAGIC_DAMAGE)) { // - // ų + // 공격 스킬일 경우 // bool bAdded = false; @@ -1794,7 +1794,7 @@ int CHARACTER::ComputeSkillAtPosition(DWORD dwVnum, const PIXEL_POSITION& posTar int iDur = (int) pkSk->kDurationPoly.Eval(); if (IsPC()) - if (!(dwVnum >= GUILD_SKILL_START && dwVnum <= GUILD_SKILL_END)) // ų Ÿ ó ʴ´. + if (!(dwVnum >= GUILD_SKILL_START && dwVnum <= GUILD_SKILL_END)) // 길드 스킬은 쿨타임 처리를 하지 않는다. if (!m_bDisableCooltime && !m_SkillUseInfo[dwVnum].HitOnce(dwVnum) && dwVnum != SKILL_MUYEONG) { return BATTLE_NONE; @@ -1884,7 +1884,7 @@ int CHARACTER::ComputeSkillAtPosition(DWORD dwVnum, const PIXEL_POSITION& posTar if (iDur > 0) { iDur += GetPoint(POINT_PARTY_BUFFER_BONUS); - // AffectFlag ų, toggle ϴ ƴ϶.. + // AffectFlag가 없거나, toggle 하는 것이 아니라면.. pkSk->kDurationSPCostPoly.SetVar("k", k/*bSkillLevel*/); AddAffect(pkSk->dwVnum, @@ -1939,13 +1939,13 @@ int CHARACTER::ComputeSkillAtPosition(DWORD dwVnum, const PIXEL_POSITION& posTar } } -// bSkillLevel ڰ 0 ƴ 쿡 m_abSkillLevels ʰ -// bSkillLevel Ѵ. +// bSkillLevel 인자가 0이 아닐 경우에는 m_abSkillLevels를 사용하지 않고 강제로 +// bSkillLevel로 계산한다. int CHARACTER::ComputeSkill(DWORD dwVnum, LPCHARACTER pkVictim, BYTE bSkillLevel) { const bool bCanUseHorseSkill = CanUseHorseSkill(); - // Ÿ ų ¶ return + // 말을 타고있지만 스킬은 사용할 수 없는 상태라면 return if (false == bCanUseHorseSkill && true == IsRiding()) return BATTLE_NONE; @@ -1967,7 +1967,7 @@ int CHARACTER::ComputeSkill(DWORD dwVnum, LPCHARACTER pkVictim, BYTE bSkillLevel return BATTLE_NONE; - // 濡 ƴϸ Ѵ. + // 상대방에게 쓰는 것이 아니면 나에게 써야 한다. if (IS_SET(pkSk->dwFlag, SKILL_FLAG_SELFONLY)) pkVictim = this; @@ -2135,7 +2135,7 @@ int CHARACTER::ComputeSkill(DWORD dwVnum, LPCHARACTER pkVictim, BYTE bSkillLevel if (IsPC()) - if (!(dwVnum >= GUILD_SKILL_START && dwVnum <= GUILD_SKILL_END)) // ų Ÿ ó ʴ´. + if (!(dwVnum >= GUILD_SKILL_START && dwVnum <= GUILD_SKILL_END)) // 길드 스킬은 쿨타임 처리를 하지 않는다. if (!m_bDisableCooltime && !m_SkillUseInfo[dwVnum].HitOnce(dwVnum) && dwVnum != SKILL_MUYEONG) { return BATTLE_NONE; @@ -2248,7 +2248,7 @@ int CHARACTER::ComputeSkill(DWORD dwVnum, LPCHARACTER pkVictim, BYTE bSkillLevel if (iDur > 0) { iDur += GetPoint(POINT_PARTY_BUFFER_BONUS); - // AffectFlag ų, toggle ϴ ƴ϶.. + // AffectFlag가 없거나, toggle 하는 것이 아니라면.. pkSk->kDurationSPCostPoly.SetVar("k", k/*bSkillLevel*/); if (pkSk->bPointOn2 != POINT_NONE) @@ -2428,7 +2428,7 @@ bool CHARACTER::UseSkill(DWORD dwVnum, LPCHARACTER pkVictim, bool bUseGrandMaste return true; } - // Ÿ ų ¶ return false + // 말을 타고있지만 스킬은 사용할 수 없는 상태라면 return false if (false == bCanUseHorseSkill && true == IsRiding()) return false; @@ -2474,7 +2474,7 @@ bool CHARACTER::UseSkill(DWORD dwVnum, LPCHARACTER pkVictim, bool bUseGrandMaste } m_SkillUseInfo[dwVnum].SetMainTargetVID(pkVictim->GetVID()); - // DASH źȯ ݱ + // DASH 상태의 탄환격은 공격기술 ComputeSkill(dwVnum, pkVictim); RemoveAffect(dwVnum); return true; @@ -2492,7 +2492,7 @@ bool CHARACTER::UseSkill(DWORD dwVnum, LPCHARACTER pkVictim, bool bUseGrandMaste return true; } - // Toggle SP (SelfOnly ) + // Toggle 할 때는 SP를 쓰지 않음 (SelfOnly로 구분) if ((0 != pkSk->dwAffectFlag || pkSk->dwVnum == SKILL_MUYEONG) && (pkSk->dwFlag & SKILL_FLAG_TOGGLE) && RemoveAffect(pkSk->dwVnum)) { return true; @@ -2506,7 +2506,7 @@ bool CHARACTER::UseSkill(DWORD dwVnum, LPCHARACTER pkVictim, bool bUseGrandMaste pkSk->SetPointVar("k", k); pkSk->kSplashAroundDamageAdjustPoly.SetVar("k", k); - // Ÿ üũ + // 쿨타임 체크 pkSk->kCooldownPoly.SetVar("k", k); int iCooltime = (int) pkSk->kCooldownPoly.Eval(); int lMaxHit = pkSk->lMaxHit ? pkSk->lMaxHit : -1; @@ -2570,7 +2570,7 @@ bool CHARACTER::UseSkill(DWORD dwVnum, LPCHARACTER pkVictim, bool bUseGrandMaste if (pkSk->dwVnum == SKILL_MUYEONG || pkSk->IsChargeSkill() && !IsAffectFlag(AFF_TANHWAN_DASH) && !pkVictim) { - // ó ϴ ڽſ Affect δ. + // 처음 사용하는 무영진은 자신에게 Affect를 붙인다. pkVictim = this; } @@ -2643,7 +2643,7 @@ int CHARACTER::GetSkillMasterType(DWORD dwVnum) const int CHARACTER::GetSkillPower(DWORD dwVnum, BYTE bLevel) const { - // ξ + // 인어반지 아이템 if (dwVnum >= SKILL_LANGUAGE1 && dwVnum <= SKILL_LANGUAGE3 && IsEquipUniqueGroup(UNIQUE_GROUP_RING_OF_LANGUAGE)) { return 100; @@ -2748,16 +2748,16 @@ void CHARACTER::SkillLearnWaitMoreTimeMessage(DWORD ms) ChatPacket(CHAT_TYPE_TALKING, "%s", LC_TEXT("\xB8\xF6 \xBC\xD3\xC0\xCC \xB6\xDF\xB0\xCC\xB1\xBA. \xC7\xCF\xC1\xF6\xB8\xB8 \xBE\xC6\xC1\xD6 \xC6\xED\xBE\xC8\xC7\xD8. \xC0\xCC\xB4\xEB\xB7\xCE \xB1\xE2\xB8\xA6 \xBE\xC8\xC1\xA4\xBD\xC3\xC5\xB0\xC0\xDA.")); else if (ms < 5 * 60) ChatPacket(CHAT_TYPE_TALKING, "%s", LC_TEXT("\xB1\xD7\xB7\xA1, \xC3\xB5\xC3\xB5\xC8\xF7. \xC1\xBB\xB4\xF5 \xC3\xB5\xC3\xB5\xC8\xF7, \xB1\xD7\xB7\xAF\xB3\xAA \xB8\xB7\xC8\xFB \xBE\xF8\xC0\xCC \xBA\xFC\xB8\xA3\xB0\xD4!")); - else if (ms < 10 * 60) // 10 + else if (ms < 10 * 60) // 10분 ChatPacket(CHAT_TYPE_TALKING, "%s", LC_TEXT("\xB1\xD7\xB7\xA1, \xC0\xCC \xB4\xC0\xB3\xA6\xC0\xCC\xBE\xDF. \xC3\xBC\xB3\xBB\xBF\xA1 \xB1\xE2\xB0\xA1 \xBE\xC6\xC1\xD6 \xC3\xE6\xB8\xB8\xC7\xD8.")); - else if (ms < 30 * 60) // 30 + else if (ms < 30 * 60) // 30분 { ChatPacket(CHAT_TYPE_TALKING, "%s", LC_TEXT("\xB4\xD9 \xC0\xD0\xBE\xFA\xB4\xD9! \xC0\xCC\xC1\xA6 \xBA\xF1\xB1\xDE\xBF\xA1 \xC0\xFB\xC7\xF4\xC0\xD6\xB4\xC2 \xB4\xEB\xB7\xCE \xC0\xFC\xBD\xC5\xBF\xA1 \xB1\xE2\xB8\xA6 \xB5\xB9\xB8\xAE\xB1\xE2\xB8\xB8 \xC7\xCF\xB8\xE9,")); ChatPacket(CHAT_TYPE_TALKING, "%s", LC_TEXT("\xB1\xD7\xB0\xCD\xC0\xB8\xB7\xCE \xBC\xF6\xB7\xC3\xC0\xBA \xB3\xA1\xB3\xAD \xB0\xC5\xBE\xDF!")); } - else if (ms < 1 * 3600) // 1ð + else if (ms < 1 * 3600) // 1시간 ChatPacket(CHAT_TYPE_TALKING, "%s", LC_TEXT("\xC0\xCC\xC1\xA6 \xC3\xA5\xC0\xC7 \xB8\xB6\xC1\xF6\xB8\xB7 \xC0\xE5\xC0\xCC\xBE\xDF! \xBC\xF6\xB7\xC3\xC0\xC7 \xB3\xA1\xC0\xCC \xB4\xAB\xBF\xA1 \xBA\xB8\xC0\xCC\xB0\xED \xC0\xD6\xBE\xEE!")); - else if (ms < 2 * 3600) // 2ð + else if (ms < 2 * 3600) // 2시간 ChatPacket(CHAT_TYPE_TALKING, "%s", LC_TEXT("\xBE\xF3\xB8\xB6 \xBE\xC8 \xB3\xB2\xBE\xD2\xBE\xEE! \xC1\xB6\xB1\xDD\xB8\xB8 \xB4\xF5!")); else if (ms < 3 * 3600) ChatPacket(CHAT_TYPE_TALKING, "%s", LC_TEXT("\xC1\xC1\xBE\xD2\xBE\xEE! \xC1\xB6\xB1\xDD\xB8\xB8 \xB4\xF5 \xC0\xD0\xC0\xB8\xB8\xE9 \xB3\xA1\xC0\xCC\xB4\xD9!")); @@ -3138,10 +3138,10 @@ bool CHARACTER::IsUsableSkillMotion(DWORD dwMotionIndex) const static DWORD s_anMotion2SkillVnumList[MOTION_MAX_NUM][SKILL_LIST_MAX_COUNT] = { - // ų 罺ųID ڰųID ųID 罺ųID + // 스킬수 무사스킬ID 자객스킬ID 수라스킬ID 무당스킬ID { 0, 0, 0, 0, 0 }, // 0 - // 1 ⺻ ų + // 1번 직군 기본 스킬 { 4, 1, 31, 61, 91 }, // 1 { 4, 2, 32, 62, 92 }, // 2 { 4, 3, 33, 63, 93 }, // 3 @@ -3150,9 +3150,9 @@ bool CHARACTER::IsUsableSkillMotion(DWORD dwMotionIndex) const { 4, 6, 36, 66, 96 }, // 6 { 0, 0, 0, 0, 0 }, // 7 { 0, 0, 0, 0, 0 }, // 8 - // 1 ⺻ ų + // 1번 직군 기본 스킬 끝 - // + // 여유분 { 0, 0, 0, 0, 0 }, // 9 { 0, 0, 0, 0, 0 }, // 10 { 0, 0, 0, 0, 0 }, // 11 @@ -3160,9 +3160,9 @@ bool CHARACTER::IsUsableSkillMotion(DWORD dwMotionIndex) const { 0, 0, 0, 0, 0 }, // 13 { 0, 0, 0, 0, 0 }, // 14 { 0, 0, 0, 0, 0 }, // 15 - // + // 여유분 끝 - // 2 ⺻ ų + // 2번 직군 기본 스킬 { 4, 16, 46, 76, 106 }, // 16 { 4, 17, 47, 77, 107 }, // 17 { 4, 18, 48, 78, 108 }, // 18 @@ -3171,14 +3171,14 @@ bool CHARACTER::IsUsableSkillMotion(DWORD dwMotionIndex) const { 4, 21, 51, 81, 111 }, // 21 { 0, 0, 0, 0, 0 }, // 22 { 0, 0, 0, 0, 0 }, // 23 - // 2 ⺻ ų + // 2번 직군 기본 스킬 끝 - // + // 여유분 { 0, 0, 0, 0, 0 }, // 24 { 0, 0, 0, 0, 0 }, // 25 - // + // 여유분 끝 - // 1 ų + // 1번 직군 마스터 스킬 { 4, 1, 31, 61, 91 }, // 26 { 4, 2, 32, 62, 92 }, // 27 { 4, 3, 33, 63, 93 }, // 28 @@ -3187,9 +3187,9 @@ bool CHARACTER::IsUsableSkillMotion(DWORD dwMotionIndex) const { 4, 6, 36, 66, 96 }, // 31 { 0, 0, 0, 0, 0 }, // 32 { 0, 0, 0, 0, 0 }, // 33 - // 1 ų + // 1번 직군 마스터 스킬 끝 - // + // 여유분 { 0, 0, 0, 0, 0 }, // 34 { 0, 0, 0, 0, 0 }, // 35 { 0, 0, 0, 0, 0 }, // 36 @@ -3197,9 +3197,9 @@ bool CHARACTER::IsUsableSkillMotion(DWORD dwMotionIndex) const { 0, 0, 0, 0, 0 }, // 38 { 0, 0, 0, 0, 0 }, // 39 { 0, 0, 0, 0, 0 }, // 40 - // + // 여유분 끝 - // 2 ų + // 2번 직군 마스터 스킬 { 4, 16, 46, 76, 106 }, // 41 { 4, 17, 47, 77, 107 }, // 42 { 4, 18, 48, 78, 108 }, // 43 @@ -3208,14 +3208,14 @@ bool CHARACTER::IsUsableSkillMotion(DWORD dwMotionIndex) const { 4, 21, 51, 81, 111 }, // 46 { 0, 0, 0, 0, 0 }, // 47 { 0, 0, 0, 0, 0 }, // 48 - // 2 ų + // 2번 직군 마스터 스킬 끝 - // + // 여유분 { 0, 0, 0, 0, 0 }, // 49 { 0, 0, 0, 0, 0 }, // 50 - // + // 여유분 끝 - // 1 ׷ ų + // 1번 직군 그랜드 마스터 스킬 { 4, 1, 31, 61, 91 }, // 51 { 4, 2, 32, 62, 92 }, // 52 { 4, 3, 33, 63, 93 }, // 53 @@ -3224,9 +3224,9 @@ bool CHARACTER::IsUsableSkillMotion(DWORD dwMotionIndex) const { 4, 6, 36, 66, 96 }, // 56 { 0, 0, 0, 0, 0 }, // 57 { 0, 0, 0, 0, 0 }, // 58 - // 1 ׷ ų + // 1번 직군 그랜드 마스터 스킬 끝 - // + // 여유분 { 0, 0, 0, 0, 0 }, // 59 { 0, 0, 0, 0, 0 }, // 60 { 0, 0, 0, 0, 0 }, // 61 @@ -3234,9 +3234,9 @@ bool CHARACTER::IsUsableSkillMotion(DWORD dwMotionIndex) const { 0, 0, 0, 0, 0 }, // 63 { 0, 0, 0, 0, 0 }, // 64 { 0, 0, 0, 0, 0 }, // 65 - // + // 여유분 끝 - // 2 ׷ ų + // 2번 직군 그랜드 마스터 스킬 { 4, 16, 46, 76, 106 }, // 66 { 4, 17, 47, 77, 107 }, // 67 { 4, 18, 48, 78, 108 }, // 68 @@ -3245,14 +3245,14 @@ bool CHARACTER::IsUsableSkillMotion(DWORD dwMotionIndex) const { 4, 21, 51, 81, 111 }, // 71 { 0, 0, 0, 0, 0 }, // 72 { 0, 0, 0, 0, 0 }, // 73 - // 2 ׷ ų + // 2번 직군 그랜드 마스터 스킬 끝 - // + //여유분 { 0, 0, 0, 0, 0 }, // 74 { 0, 0, 0, 0, 0 }, // 75 - // + // 여유분 끝 - // 1 Ʈ ų + // 1번 직군 퍼펙트 마스터 스킬 { 4, 1, 31, 61, 91 }, // 76 { 4, 2, 32, 62, 92 }, // 77 { 4, 3, 33, 63, 93 }, // 78 @@ -3261,9 +3261,9 @@ bool CHARACTER::IsUsableSkillMotion(DWORD dwMotionIndex) const { 4, 6, 36, 66, 96 }, // 81 { 0, 0, 0, 0, 0 }, // 82 { 0, 0, 0, 0, 0 }, // 83 - // 1 Ʈ ų + // 1번 직군 퍼펙트 마스터 스킬 끝 - // + // 여유분 { 0, 0, 0, 0, 0 }, // 84 { 0, 0, 0, 0, 0 }, // 85 { 0, 0, 0, 0, 0 }, // 86 @@ -3271,9 +3271,9 @@ bool CHARACTER::IsUsableSkillMotion(DWORD dwMotionIndex) const { 0, 0, 0, 0, 0 }, // 88 { 0, 0, 0, 0, 0 }, // 89 { 0, 0, 0, 0, 0 }, // 90 - // + // 여유분 끝 - // 2 Ʈ ų + // 2번 직군 퍼펙트 마스터 스킬 { 4, 16, 46, 76, 106 }, // 91 { 4, 17, 47, 77, 107 }, // 92 { 4, 18, 48, 78, 108 }, // 93 @@ -3282,23 +3282,23 @@ bool CHARACTER::IsUsableSkillMotion(DWORD dwMotionIndex) const { 4, 21, 51, 81, 111 }, // 96 { 0, 0, 0, 0, 0 }, // 97 { 0, 0, 0, 0, 0 }, // 98 - // 2 Ʈ ų + // 2번 직군 퍼펙트 마스터 스킬 끝 - // + // 여유분 { 0, 0, 0, 0, 0 }, // 99 { 0, 0, 0, 0, 0 }, // 100 - // + // 여유분 끝 - // ų + // 길드 스킬 { 1, 152, 0, 0, 0}, // 101 { 1, 153, 0, 0, 0}, // 102 { 1, 154, 0, 0, 0}, // 103 { 1, 155, 0, 0, 0}, // 104 { 1, 156, 0, 0, 0}, // 105 { 1, 157, 0, 0, 0}, // 106 - // ų + // 길드 스킬 끝 - // + // 여유분 { 0, 0, 0, 0, 0}, // 107 { 0, 0, 0, 0, 0}, // 108 { 0, 0, 0, 0, 0}, // 109 @@ -3313,13 +3313,13 @@ bool CHARACTER::IsUsableSkillMotion(DWORD dwMotionIndex) const { 0, 0, 0, 0, 0}, // 118 { 0, 0, 0, 0, 0}, // 119 { 0, 0, 0, 0, 0}, // 120 - // + // 여유분 끝 - // ¸ ų + // 승마 스킬 { 2, 137, 140, 0, 0}, // 121 { 1, 138, 0, 0, 0}, // 122 { 1, 139, 0, 0, 0}, // 123 - // ¸ ų + // 승마 스킬 끝 }; if (dwMotionIndex >= MOTION_MAX_NUM) @@ -3473,7 +3473,7 @@ bool CHARACTER::CanUseSkill(DWORD dwSkillVnum) const if (true == IsRiding()) { - //Ʈ Ż ޸ ų 밡 + //마운트 탈것중 고급말만 스킬 사용가능 if(GetMountVnum()) { if( GetMountVnum() < 20209 && GetMountVnum() > 20212) diff --git a/src/game/src/char_state.cpp b/src/game/src/char_state.cpp index 915c17b..ccbffc6 100644 --- a/src/game/src/char_state.cpp +++ b/src/game/src/char_state.cpp @@ -63,7 +63,7 @@ namespace !pkChr->IsAffectFlag(AFF_WAR_FLAG2) && !pkChr->IsAffectFlag(AFF_WAR_FLAG3)) { - // 츮 + // 우리편 깃발일 경우 if ((DWORD) m_pkChr->GetPoint(POINT_STAT) == pkChr->GetGuild()->GetID()) { CWarMap * pMap = pkChr->GetWarMap(); @@ -72,8 +72,8 @@ namespace if (!pMap || !pMap->GetTeamIndex(pkChr->GetGuild()->GetID(), idx)) return; - // 츮 ̴´. ȱ׷ ִ - // ΰ Ƿ.. + // 우리편 기지에 깃발이 없을 때만 깃발을 뽑는다. 안그러면 기지에 있는 깃발을 + // 가만히 두고 싶은데도 뽑힐수가 있으므로.. if (!pMap->IsFlagOnBase(idx)) { m_pkChrFind = pkChr; @@ -82,7 +82,7 @@ namespace } else { - // ̴´. + // 상대편 깃발인 경우 무조건 뽑는다. m_pkChrFind = pkChr; m_iMinDistance = iDist; } @@ -186,7 +186,7 @@ namespace LPCHARACTER pkChr = (LPCHARACTER) ent; - // ϴ PC ݾ + // 일단 PC 공격안함 if (pkChr->IsPC()) return; @@ -202,7 +202,7 @@ namespace pkChr->IsAffectFlag(AFF_REVIVE_INVISIBLE)) return; - // ֱ н + // 왜구는 패스 if (pkChr->GetRaceNum() == 5001) return; @@ -285,7 +285,7 @@ void CHARACTER::CowardEscape() for (int iDistIdx = 2; iDistIdx >= 0; --iDistIdx) for (int iTryCount = 0; iTryCount < 8; ++iTryCount) { - SetRotation(Random::get(0, 359)); // + SetRotation(Random::get(0, 359)); // 방향은 랜덤으로 설정 float fx, fy; float fDist = Random::get(iDist[iDistIdx], iDist[iDistIdx+1]); @@ -367,7 +367,7 @@ void CHARACTER::StateIdle() } else if (IsWarp() || IsGoto()) { - // ̺Ʈ ó + // 워프는 이벤트로 처리 m_dwStateDuration = 60 * passes_per_sec; return; } @@ -375,7 +375,7 @@ void CHARACTER::StateIdle() if (IsPC()) return; - // NPC ó + // NPC 처리 if (!IsMonster()) { __StateIdle_NPC(); @@ -506,7 +506,7 @@ void CHARACTER::__StateIdle_NPC() MonsterChat(MONSTER_CHAT_WAIT); m_dwStateDuration = PASSES_PER_SEC(5); - // ý Idle ó ij͵ ؼ ϴ ¸ӽ ƴ CPetActor::Update ó. + // 펫 시스템의 Idle 처리는 기존 거의 모든 종류의 캐릭터들이 공유해서 사용하는 상태머신이 아닌 CPetActor::Update에서 처리함. if (IsPet()) return; else if (IsGuardNPC()) @@ -531,21 +531,21 @@ void CHARACTER::__StateIdle_NPC() } else { - if (GetRaceNum() == xmas::MOB_SANTA_VNUM) // Ÿ + if (GetRaceNum() == xmas::MOB_SANTA_VNUM) // 산타 { if (get_dword_time() > m_dwPlayStartTime) { - int next_warp_time = 2 * 1000; // 2 + int next_warp_time = 2 * 1000; // 2초 m_dwPlayStartTime = get_dword_time() + next_warp_time; - // ð Ѿ սô. + // 시간이 넘었으니 워프합시다. /* - * Ÿ + * 산타용 const int WARP_MAP_INDEX_NUM = 4; static const int c_lWarpMapIndexs[WARP_MAP_INDEX_NUM] = {61, 62, 63, 64}; */ - // ż ؿ + // 신선자 노해용 const int WARP_MAP_INDEX_NUM = 7; static const int c_lWarpMapIndexs[WARP_MAP_INDEX_NUM] = { 61, 62, 63, 64, 3, 23, 43 }; int lNextMapIndex; @@ -553,7 +553,7 @@ void CHARACTER::__StateIdle_NPC() if (map_allow_find(lNextMapIndex)) { - // ̰Դϴ. + // 이곳입니다. M2_DESTROY_CHARACTER(this); int iNextSpawnDelay = 0; if (LC_IsYMIR()) @@ -565,7 +565,7 @@ void CHARACTER::__StateIdle_NPC() } else { - // ٸ Դϴ. + // 다른 서버 입니다. TPacketGGXmasWarpSanta p; p.bHeader = HEADER_GG_XMAS_WARP_SANTA; p.bChannel = g_bChannel; @@ -579,7 +579,7 @@ void CHARACTER::__StateIdle_NPC() if (!IS_SET(m_pointsInstant.dwAIFlag, AIFLAG_NOMOVE)) { // - // ̵Ѵ. + // 이 곳 저 곳 이동한다. // LPCHARACTER pkChrProtege = GetProtege(); @@ -594,14 +594,14 @@ void CHARACTER::__StateIdle_NPC() if (!Random::get(0, 6)) { - SetRotation(Random::get(0, 359)); // + SetRotation(Random::get(0, 359)); // 방향은 랜덤으로 설정 float fx, fy; float fDist = Random::get(200, 400); GetDeltaByDegree(GetRotation(), fDist, &fx, &fy); - // Ӽ üũ; ġ ߰ ġ ٸ ʴ´. + // 느슨한 못감 속성 체크; 최종 위치와 중간 위치가 갈수없다면 가지 않는다. if (!(SECTREE_MANAGER::instance().IsMovablePosition(GetMapIndex(), GetX() + (int) fx, GetY() + (int) fy) && SECTREE_MANAGER::instance().IsMovablePosition(GetMapIndex(), GetX() + (int) fx / 2, GetY() + (int) fy / 2))) return; @@ -627,7 +627,7 @@ void CHARACTER::__StateIdle_Monster() if (IsCoward()) { - // ʹ ٴմϴ. + // 겁쟁이 몬스터는 도망만 다닙니다. if (!IsDead()) CowardEscape(); @@ -653,16 +653,16 @@ void CHARACTER::__StateIdle_Monster() if (!victim || victim->IsBuilding()) { - // ȣ ó + // 돌 보호 처리 if (m_pkChrStone) { victim = m_pkChrStone->GetNearestVictim(m_pkChrStone); } - // ó + // 선공 몬스터 처리 else if (!no_wander && IsAggressive()) { if (GetMapIndex() == 61 && quest::CQuestManager::instance().GetEventFlag("xmas_tree")); - // ѻ꿡 ʴ´. + // 서한산에서 나무가 있으면 선공하지않는다. else victim = FindVictim(this, m_pkMobData->m_table.wAggressiveSight); } @@ -683,7 +683,7 @@ void CHARACTER::__StateIdle_Monster() LPCHARACTER pkChrProtege = GetProtege(); - // ȣ (, Ƽ)Է ִٸ 󰣴. + // 보호할 것(돌, 파티장)에게로 부터 멀다면 따라간다. if (pkChrProtege) { if (DISTANCE_APPROX(GetX() - pkChrProtege->GetX(), GetY() - pkChrProtege->GetY()) > 1000) @@ -697,26 +697,26 @@ void CHARACTER::__StateIdle_Monster() } // - // ׳ Դٸ ٸ Ѵ. + // 그냥 왔다리 갔다리 한다. // if (!no_wander && !IS_SET(m_pointsInstant.dwAIFlag, AIFLAG_NOMOVE)) { if (!Random::get(0, 6)) { - SetRotation(Random::get(0, 359)); // + SetRotation(Random::get(0, 359)); // 방향은 랜덤으로 설정 float fx, fy; float fDist = Random::get(300, 700); GetDeltaByDegree(GetRotation(), fDist, &fx, &fy); - // Ӽ üũ; ġ ߰ ġ ٸ ʴ´. + // 느슨한 못감 속성 체크; 최종 위치와 중간 위치가 갈수없다면 가지 않는다. if (!(SECTREE_MANAGER::instance().IsMovablePosition(GetMapIndex(), GetX() + (int) fx, GetY() + (int) fy) && SECTREE_MANAGER::instance().IsMovablePosition(GetMapIndex(), GetX() + (int) fx/2, GetY() + (int) fy/2))) return; - // NOTE: Ͱ IDLE ¿ ֺ Ÿ , پ Ǿ . ( ) - // ׷ Ͱ ȴ ʹٰ ؼ ӽ÷ ƯȮ Ȱų ٰ . ( Ʋ ϴ ׽Ʈ 忡 ۵) + // NOTE: 몬스터가 IDLE 상태에서 주변을 서성거릴 때, 현재 무조건 뛰어가게 되어 있음. (절대로 걷지 않음) + // 그래픽 팀에서 몬스터가 걷는 모습도 보고싶다고 해서 임시로 특정확률로 걷거나 뛰게 함. (게임의 전반적인 느낌이 틀려지기 때문에 일단 테스트 모드에서만 작동) if (g_test_server) { if (Random::get(0, 100) < 60) @@ -745,13 +745,13 @@ bool __CHARACTER_GotoNearTarget(LPCHARACTER self, LPCHARACTER victim) { case BATTLE_TYPE_RANGE: case BATTLE_TYPE_MAGIC: - // 糪 ü Ÿ 80% Ѵ. + // 마법사나 궁수는 공격 거리의 80%까지 가서 공격을 시작한다. if (self->Follow(victim, self->GetMobAttackRange() * 8 / 10)) return true; break; default: - // 90%? + // 나머지는 90%? if (self->Follow(victim, self->GetMobAttackRange() * 9 / 10)) return true; } @@ -781,7 +781,7 @@ void CHARACTER::StateMove() LPCHARACTER victim = GetExchange()->GetCompany()->GetOwner(); int iDist = DISTANCE_APPROX(GetX() - victim->GetX(), GetY() - victim->GetY()); - // Ÿ üũ + // 거리 체크 if (iDist >= EXCHANGE_MAX_DISTANCE) { GetExchange()->Cancel(); @@ -789,17 +789,17 @@ void CHARACTER::StateMove() } } - // ׹̳ 0 ̻̾ Ѵ. + // 스테미나가 0 이상이어야 한다. if (IsPC()) { if (IsWalking() && GetStamina() < GetMaxStamina()) { - // 5 ׹̳ + // 5초 후 부터 스테미너 증가 if (get_dword_time() - GetWalkStartTime() > 5000) PointChange(POINT_STAMINA, GetMaxStamina() / 1); } - // ̸鼭 ٴ ̸ + // 전투 중이면서 뛰는 중이면 if (!IsWalking() && !IsRiding()) if ((get_dword_time() - GetLastAttackTime()) < 20000) { @@ -817,7 +817,7 @@ void CHARACTER::StateMove() if (GetStamina() <= 0) { - // ׹̳ ڶ ɾ + // 스테미나가 모자라 걸어야함 SetStamina(0); SetNowWalking(true); StopStaminaConsume(); @@ -838,7 +838,7 @@ void CHARACTER::StateMove() if (g_test_server) { - // Ͱ Ѿư ̸ پ. + // 몬스터가 적을 쫓아가는 것이면 무조건 뛰어간다. SetNowWalking(false); } } @@ -847,10 +847,10 @@ void CHARACTER::StateMove() { LPCHARACTER victim = GetVictim(); - // Ŵ ź + // 거대 거북 if (GetRaceNum() == 2191 && Random::get(1, 20) == 1 && get_dword_time() - m_pkMobInst->m_dwLastWarpTime > 1000) { - // ׽Ʈ + // 워프 테스트 float fx, fy; GetDeltaByDegree(victim->GetRotation(), 400, &fx, &fy); int new_x = victim->GetX() + (int)fx; @@ -864,7 +864,7 @@ void CHARACTER::StateMove() return; } - // TODO ȯ ؼ ٺ ! + // TODO 방향전환을 해서 덜 바보가 되자! if (Random::get(0, 3) == 0) { if (__CHARACTER_GotoNearTarget(this, victim)) @@ -1005,7 +1005,7 @@ void CHARACTER::StateBattle() { if (!GetParty()) { - // ؼ ä Ƽ Ӵϴ. + // 서몬해서 채워둘 파티를 만들어 둡니다. CPartyManager::instance().CreateParty(this); } @@ -1015,7 +1015,7 @@ void CHARACTER::StateBattle() if (bPct && pParty->CountMemberByVnum(GetSummonVnum()) < SUMMON_MONSTER_COUNT) { MonsterLog("\xBA\xCE\xC7\xCF \xB8\xF3\xBD\xBA\xC5\xCD \xBC\xD2\xC8\xAF!"); - // ڶ ༮ ҷ äô. + // 모자라는 녀석을 불러내 채웁시다. int sx = GetX() - 300; int sy = GetY() - 300; int ex = GetX() + 300; @@ -1035,12 +1035,12 @@ void CHARACTER::StateBattle() float fDist = DISTANCE_APPROX(GetX() - victim->GetX(), GetY() - victim->GetY()); - if (fDist >= 4000.0f) // 40 ̻ ־ + if (fDist >= 4000.0f) // 40미터 이상 멀어지면 포기 { MonsterLog("\xC5\xB8\xB0\xD9\xC0\xCC \xB8\xD6\xBE\xEE\xBC\xAD \xC6\xF7\xB1\xE2"); SetVictim(NULL); - // ȣ (, Ƽ) ֺ . + // 보호할 것(돌, 파티장) 주변으로 간다. if (pkChrProtege) if (DISTANCE_APPROX(GetX() - pkChrProtege->GetX(), GetY() - pkChrProtege->GetY()) > 1000) Follow(pkChrProtege, Random::get(150, 400)); @@ -1059,7 +1059,7 @@ void CHARACTER::StateBattle() if (2493 == m_pkMobData->m_table.dwVnum) { - // (2493) Ư ó + // 수룡(2493) 특수 처리 m_dwStateDuration = BlueDragon_StateBattle(this); return; } @@ -1067,7 +1067,7 @@ void CHARACTER::StateBattle() DWORD dwCurTime = get_dword_time(); DWORD dwDuration = CalculateDuration(GetLimitPoint(POINT_ATT_SPEED), 2000); - if ((dwCurTime - m_dwLastAttackTime) < dwDuration) // 2 ؾ Ѵ. + if ((dwCurTime - m_dwLastAttackTime) < dwDuration) // 2초 마다 공격해야 한다. { m_dwStateDuration = std::max(1, (passes_per_sec * (dwDuration - (dwCurTime - m_dwLastAttackTime)) / 1000)); return; @@ -1084,7 +1084,7 @@ void CHARACTER::StateBattle() SetGodSpeed(true); // - // ų ó + // 몹 스킬 처리 // if (HasMobSkill()) { @@ -1109,11 +1109,11 @@ void CHARACTER::StateBattle() } } - if (!Attack(victim)) // ж? ? TODO + if (!Attack(victim)) // 공격 실패라면? 왜 실패했지? TODO m_dwStateDuration = passes_per_sec / 2; else { - // ٶ󺸰 . + // 적을 바라보게 만든다. SetRotationToXY(victim->GetX(), victim->GetY()); SendMovePacket(FUNC_ATTACK, 0, GetX(), GetY(), 0, dwCurTime); @@ -1166,15 +1166,15 @@ void CHARACTER::StateFlagBase() void CHARACTER::StateHorse() { - float START_FOLLOW_DISTANCE = 400.0f; // Ÿ ̻ Ѿư - float START_RUN_DISTANCE = 700.0f; // Ÿ ̻ پ Ѿư. - int MIN_APPROACH = 150; // ּ Ÿ - int MAX_APPROACH = 300; // ִ Ÿ + float START_FOLLOW_DISTANCE = 400.0f; // 이 거리 이상 떨어지면 쫓아가기 시작함 + float START_RUN_DISTANCE = 700.0f; // 이 거리 이상 떨어지면 뛰어서 쫓아감. + int MIN_APPROACH = 150; // 최소 접근 거리 + int MAX_APPROACH = 300; // 최대 접근 거리 - DWORD STATE_DURATION = (DWORD)PASSES_PER_SEC(0.5); // ð + DWORD STATE_DURATION = (DWORD)PASSES_PER_SEC(0.5); // 상태 지속 시간 - bool bDoMoveAlone = true; // ijͿ ȥ ϰ -_-; - bool bRun = true; // پ ϳ? + bool bDoMoveAlone = true; // 캐릭터와 가까이 있을 때 혼자 여기저기 움직일건지 여부 -_-; + bool bRun = true; // 뛰어야 하나? if (IsDead()) return; @@ -1183,7 +1183,7 @@ void CHARACTER::StateHorse() LPCHARACTER victim = GetRider(); - // ! ƴ // ȯڰ Ŭ + // ! 아님 // 대상이 없는 경우 소환자가 직접 나를 클리어할 것임 if (!victim) { M2_DESTROY_CHARACTER(this); @@ -1197,7 +1197,7 @@ void CHARACTER::StateHorse() if (fDist >= START_FOLLOW_DISTANCE) { if (fDist > START_RUN_DISTANCE) - SetNowWalking(!bRun); // NOTE: Լ ̸ ߴ° ˾Ҵµ SetNowWalking(false) ϸ ٴ°.. -_-; + SetNowWalking(!bRun); // NOTE: 함수 이름보고 멈추는건줄 알았는데 SetNowWalking(false) 하면 뛰는거임.. -_-; Follow(victim, Random::get(MIN_APPROACH, MAX_APPROACH)); @@ -1208,14 +1208,14 @@ void CHARACTER::StateHorse() // wondering-.- m_dwLastAttackTime = get_dword_time() + Random::get(5000, 12000); - SetRotation(Random::get(0, 359)); // + SetRotation(Random::get(0, 359)); // 방향은 랜덤으로 설정 float fx, fy; float fDist = Random::get(200, 400); GetDeltaByDegree(GetRotation(), fDist, &fx, &fy); - // Ӽ üũ; ġ ߰ ġ ٸ ʴ´. + // 느슨한 못감 속성 체크; 최종 위치와 중간 위치가 갈수없다면 가지 않는다. if (!(SECTREE_MANAGER::instance().IsMovablePosition(GetMapIndex(), GetX() + (int) fx, GetY() + (int) fy) && SECTREE_MANAGER::instance().IsMovablePosition(GetMapIndex(), GetX() + (int) fx/2, GetY() + (int) fy/2))) return; diff --git a/src/game/src/cmd.cpp b/src/game/src/cmd.cpp index 341f5f1..3c632dc 100644 --- a/src/game/src/cmd.cpp +++ b/src/game/src/cmd.cpp @@ -187,7 +187,7 @@ ACMD(do_effect); ACMD(do_threeway_war_info ); ACMD(do_threeway_war_myinfo ); // -// +//군주 전용기능 ACMD(do_monarch_warpto); ACMD(do_monarch_transfer); ACMD(do_monarch_info); @@ -196,7 +196,7 @@ ACMD(do_monarch_tax); ACMD(do_monarch_mob); ACMD(do_monarch_notice); -// +//군주 관리 기능 ACMD(do_rmcandidacy); ACMD(do_setmonarch); ACMD(do_rmmonarch); @@ -204,10 +204,10 @@ ACMD(do_rmmonarch); ACMD(do_hair); //gift notify quest command ACMD(do_gift); -// ť +// 큐브관련 ACMD(do_inventory); ACMD(do_cube); -// +// 공성전 ACMD(do_siege); ACMD(do_temp); ACMD(do_frog); @@ -235,7 +235,7 @@ ACMD(do_ride); ACMD(do_get_item_id_list); ACMD(do_set_socket); #ifdef __AUCTION__ -// temp_auction ӽ +// temp_auction 임시 ACMD(do_get_auction_list); ACMD (do_get_my_auction_list); ACMD (do_get_my_purchase_list); @@ -255,21 +255,21 @@ ACMD (do_cancel_sale); ACMD (do_rebid); ACMD (do_bid_cancel); #endif -// ڽ º +// 코스츔 상태보기 및 벗기 ACMD(do_costume); ACMD(do_set_stat); -// +// 무적 ACMD (do_can_dead); ACMD (do_full_set); -// ְ +// 직군과 레벨에 따른 최고 아이템 ACMD (do_item_full_set); -// ְ ɼ Ӽ +// 직군에 따른 최고 옵션의 속성 셋팅 ACMD (do_attr_full_set); -// ų +// 모든 스킬 마스터 ACMD (do_all_skill_master); -// . icon Ŭ󿡼 Ȯ . +// 아이템 착용. icon이 없어 클라에서 확인 할 수 없는 아이템 착용을 위해 만듦. ACMD (do_use_item); ACMD (do_dragon_soul); ACMD (do_ds_list); @@ -277,7 +277,7 @@ ACMD (do_clear_affect); struct command_info cmd_info[] = { - { "!RESERVED!", NULL, 0, POS_DEAD, GM_IMPLEMENTOR }, /* ݵ ó̾ Ѵ. */ + { "!RESERVED!", NULL, 0, POS_DEAD, GM_IMPLEMENTOR }, /* 반드시 이 것이 처음이어야 한다. */ { "who", do_who, 0, POS_DEAD, GM_IMPLEMENTOR }, { "war", do_war, 0, POS_DEAD, GM_PLAYER }, { "warp", do_warp, 0, POS_DEAD, GM_LOW_WIZARD }, @@ -298,7 +298,7 @@ struct command_info cmd_info[] = { "item", do_item, 0, POS_DEAD, GM_GOD }, { "mob", do_mob, 0, POS_DEAD, GM_HIGH_WIZARD }, - { "mob_ld", do_mob_ld, 0, POS_DEAD, GM_HIGH_WIZARD }, /* ġ ȯ /mob_ld vnum x y dir */ + { "mob_ld", do_mob_ld, 0, POS_DEAD, GM_HIGH_WIZARD }, /* 몹의 위치와 방향을 설정해 소환 /mob_ld vnum x y dir */ { "ma", do_mob_aggresive, 0, POS_DEAD, GM_HIGH_WIZARD }, { "mc", do_mob_coward, 0, POS_DEAD, GM_HIGH_WIZARD }, { "mm", do_mob_map, 0, POS_DEAD, GM_HIGH_WIZARD }, @@ -546,7 +546,7 @@ struct command_info cmd_info[] = { "item_id_list", do_get_item_id_list, 0, POS_DEAD, GM_LOW_WIZARD }, { "set_socket", do_set_socket, 0, POS_DEAD, GM_LOW_WIZARD }, #ifdef __AUCTION__ - // auction ӽ + // auction 임시 { "auction_list", do_get_auction_list, 0, POS_DEAD, GM_PLAYER }, { "my_auction_list", do_get_my_auction_list, 0, POS_DEAD, GM_PLAYER }, { "my_purchase_list", do_get_my_purchase_list, 0, POS_DEAD, GM_PLAYER }, @@ -586,7 +586,7 @@ struct command_info cmd_info[] = { "ds_list", do_ds_list, 0, POS_DEAD, GM_PLAYER }, { "do_clear_affect", do_clear_affect, 0, POS_DEAD, GM_LOW_WIZARD}, - { "\n", NULL, 0, POS_DEAD, GM_IMPLEMENTOR } /* ݵ ̾ Ѵ. */ + { "\n", NULL, 0, POS_DEAD, GM_IMPLEMENTOR } /* 반드시 이 것이 마지막이어야 한다. */ }; void interpreter_set_privilege(const char *cmd, int lvl) @@ -609,7 +609,7 @@ void double_dollar(const char *src, size_t src_len, char *dest, size_t dest_len) const char * tmp = src; size_t cur_len = 0; - // \0 ڸ Ȯ + // \0 넣을 자리 확보 dest_len -= 1; while (src_len-- && *tmp) @@ -644,7 +644,7 @@ void interpret_command(LPCHARACTER ch, const char * argument, size_t len) return ; } - char cmd[128 + 1]; // buffer overflow ʵ Ϻη ̸ ª + char cmd[128 + 1]; // buffer overflow 문제가 생기지 않도록 일부러 길이를 짧게 잡음 char new_line[256 + 1]; const char * line; int icmd; @@ -661,7 +661,7 @@ void interpret_command(LPCHARACTER ch, const char * argument, size_t len) { if (cmd_info[icmd].command_pointer == do_cmd) { - if (!strcmp(cmd_info[icmd].command, cmd)) // do_cmd ɾ ľ ִ. + if (!strcmp(cmd_info[icmd].command, cmd)) // do_cmd는 모든 명령어를 쳐야 할 수 있다. break; } else if (!strncmp(cmd_info[icmd].command, cmd, cmdlen)) @@ -713,7 +713,7 @@ void interpret_command(LPCHARACTER ch, const char * argument, size_t len) return; } - if (strncmp("phase", cmd_info[icmd].command, 5) != 0) // ɾ ó + if (strncmp("phase", cmd_info[icmd].command, 5) != 0) // 히든 명령어 처리 SPDLOG_DEBUG("COMMAND: {}: {}", ch->GetName(), cmd_info[icmd].command); ((*cmd_info[icmd].command_pointer) (ch, line, icmd, cmd_info[icmd].subcmd)); diff --git a/src/game/src/cmd_emotion.cpp b/src/game/src/cmd_emotion.cpp index e9d8fec..e3d2d5e 100644 --- a/src/game/src/cmd_emotion.cpp +++ b/src/game/src/cmd_emotion.cpp @@ -108,11 +108,11 @@ ACMD(do_emotion_allow) bool CHARACTER_CanEmotion(CHARACTER& rch) { - // ��ȥ�� �ʿ����� ����� �� �ִ�. + // 결혼식 맵에서는 사용할 수 있다. if (marriage::WeddingManager::instance().IsWeddingMap(rch.GetMapIndex())) return true; - // ������ ���� ����� ����� �� �ִ�. + // 열정의 가면 착용시 사용할 수 있다. if (rch.IsEquipUniqueItem(UNIQUE_ITEM_EMOTION_MASK)) return true; @@ -246,7 +246,7 @@ ACMD(do_emotion) if (len < 0 || len >= (int) sizeof(chatbuf)) len = sizeof(chatbuf) - 1; - ++len; // \0 ���� ���� + ++len; // \0 문자 포함 TPacketGCChat pack_chat; pack_chat.header = HEADER_GC_CHAT; diff --git a/src/game/src/cmd_general.cpp b/src/game/src/cmd_general.cpp index e61158b..b6c6b52 100644 --- a/src/game/src/cmd_general.cpp +++ b/src/game/src/cmd_general.cpp @@ -46,7 +46,7 @@ ACMD(do_user_horse_ride) if (ch->IsHorseRiding() == false) { - // ƴ ٸŻ Ÿִ. + // 말이 아닌 다른탈것을 타고있다. if (ch->GetMountVnum()) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC0\xCC\xB9\xCC \xC5\xBB\xB0\xCD\xC0\xBB \xC0\xCC\xBF\xEB\xC1\xDF\xC0\xD4\xB4\xCF\xB4\xD9.")); @@ -86,7 +86,7 @@ ACMD(do_user_horse_back) ACMD(do_user_horse_feed) { - // λ ¿ ̸ . + // 개인상점을 연 상태에서는 말 먹이를 줄 수 없다. if (ch->GetMyShop()) return; @@ -397,7 +397,7 @@ ACMD(do_mount) char arg1[256]; struct action_mount_param param; - // ̹ Ÿ + // 이미 타고 있으면 if (ch->GetMountingChr()) { char arg2[256]; @@ -488,7 +488,7 @@ ACMD(do_restart) { if (ch->IsHack()) { - // ϰ쿡 üũ ʴ´. + //성지 맵일경우에는 체크 하지 않는다. if (false == CThreeWayWar::instance().IsSungZiMapIndex(ch->GetMapIndex())) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xBE\xC6\xC1\xF7 \xC0\xE7\xBD\xC3\xC0\xDB \xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9. (%d\xC3\xCA \xB3\xB2\xC0\xBD)"), iTimeToDead - (180 - g_nPortalLimitTime)); @@ -505,13 +505,13 @@ ACMD(do_restart) } //PREVENT_HACK - //DESC : â, ȯ â Ż ϴ ׿ ̿ɼ ־ - // Ÿ ߰ + //DESC : 창고, 교환 창 후 포탈을 사용하는 버그에 이용될수 있어서 + // 쿨타임을 추가 if (subcmd == SCMD_RESTART_TOWN) { if (ch->IsHack()) { - //, ʿ üũ ʴ´. + //길드맵, 성지맵에서는 체크 하지 않는다. if ((!ch->GetWarMap() || ch->GetWarMap()->GetType() == GUILD_WAR_TYPE_FLAG) || false == CThreeWayWar::instance().IsSungZiMapIndex(ch->GetMapIndex())) { @@ -535,7 +535,7 @@ ACMD(do_restart) ch->StartRecoveryEvent(); //FORKED_LOAD - //DESC: Ÿ Ȱ Ұ Ա ƴ Ÿ ̵ϰ ȴ. + //DESC: 삼거리 전투시 부활을 할경우 맵의 입구가 아닌 삼거리 전투의 시작지점으로 이동하게 된다. if (1 == quest::CQuestManager::instance().GetEventFlag("threeway_war")) { if (subcmd == SCMD_RESTART_TOWN || subcmd == SCMD_RESTART_HERE) @@ -552,7 +552,7 @@ ACMD(do_restart) return; } - // + //성지 if (true == CThreeWayWar::instance().IsSungZiMapIndex(ch->GetMapIndex())) { if (CThreeWayWar::instance().GetReviveTokenForPlayer(ch->GetPlayerID()) <= 0) @@ -867,7 +867,7 @@ ACMD(do_skillup) } // -// @version 05/06/20 Bang2ni - Ŀǵ ó Delegate to CHARACTER class +// @version 05/06/20 Bang2ni - 커맨드 처리 Delegate to CHARACTER class // ACMD(do_safebox_close) { @@ -875,7 +875,7 @@ ACMD(do_safebox_close) } // -// @version 05/06/20 Bang2ni - Ŀǵ ó Delegate to CHARACTER class +// @version 05/06/20 Bang2ni - 커맨드 처리 Delegate to CHARACTER class // ACMD(do_safebox_password) { @@ -946,7 +946,7 @@ ACMD(do_mall_password) return; } - if (iPulse - ch->GetMallLoadTime() < passes_per_sec * 10) // 10ʿ ѹ û + if (iPulse - ch->GetMallLoadTime() < passes_per_sec * 10) // 10초에 한번만 요청 가능 { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xC3\xA2\xB0\xED> \xC3\xA2\xB0\xED\xB8\xA6 \xB4\xDD\xC0\xBA\xC1\xF6 10\xC3\xCA \xBE\xC8\xBF\xA1\xB4\xC2 \xBF\xAD \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9.")); return; @@ -1028,20 +1028,20 @@ ACMD(do_set_run_mode) ACMD(do_war) { - // + //내 길드 정보를 얻어오고 CGuild * g = ch->GetGuild(); if (!g) return; - // üũѹ! + //전쟁중인지 체크한번! if (g->UnderAnyWar()) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xB1\xE6\xB5\xE5> \xC0\xCC\xB9\xCC \xB4\xD9\xB8\xA5 \xC0\xFC\xC0\xEF\xBF\xA1 \xC2\xFC\xC0\xFC \xC1\xDF \xC0\xD4\xB4\xCF\xB4\xD9.")); return; } - //Ķ͸ ι + //파라메터를 두배로 나누고 char arg1[256], arg2[256]; int type = GUILD_WAR_TYPE_FIELD; two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2)); @@ -1057,17 +1057,17 @@ ACMD(do_war) type = GUILD_WAR_TYPE_FIELD; } - // ̵ µ + //길드의 마스터 아이디를 얻어온뒤 DWORD gm_pid = g->GetMasterPID(); - // üũ( 常 ) + //마스터인지 체크(길전은 길드장만이 가능) if (gm_pid != ch->GetPlayerID()) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xB1\xE6\xB5\xE5> \xB1\xE6\xB5\xE5\xC0\xFC\xBF\xA1 \xB4\xEB\xC7\xD1 \xB1\xC7\xC7\xD1\xC0\xCC \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9.")); return; } - // 带 + //상대 길드를 얻어오고 CGuild * opp_g = CGuildManager::instance().FindGuildByName(arg1); if (!opp_g) @@ -1076,7 +1076,7 @@ ACMD(do_war) return; } - // üũ + //상대길드와의 상태 체크 switch (g->GetGuildWarState(opp_g->GetID())) { case GUILD_WAR_NONE: @@ -1139,7 +1139,7 @@ ACMD(do_war) if (!g->CanStartWar(type)) { - // ִ ʴ´. + // 길드전을 할 수 있는 조건을 만족하지않는다. if (g->GetLadderPoint() == 0) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xB1\xE6\xB5\xE5> \xB7\xB9\xB4\xF5 \xC1\xA1\xBC\xF6\xB0\xA1 \xB8\xF0\xC0\xDA\xB6\xF3\xBC\xAD \xB1\xE6\xB5\xE5\xC0\xFC\xC0\xBB \xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9.")); @@ -1157,7 +1157,7 @@ ACMD(do_war) return; } - // ʵ üũ ϰ üũ ³Ҷ Ѵ. + // 필드전 체크만 하고 세세한 체크는 상대방이 승낙할때 한다. if (!opp_g->CanStartWar(GUILD_WAR_TYPE_FIELD)) { if (opp_g->GetLadderPoint() == 0) @@ -1452,17 +1452,17 @@ ACMD(do_monarch_warpto) return; } - // Ÿ ˻ + //군주 쿨타임 검사 if (!ch->IsMCOK(CHARACTER::MI_WARP)) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d \xC3\xCA\xB0\xA3 \xC4\xF0\xC5\xB8\xC0\xD3\xC0\xCC \xC0\xFB\xBF\xEB\xC1\xDF\xC0\xD4\xB4\xCF\xB4\xD9."), ch->GetMCLTime(CHARACTER::MI_WARP)); return; } - // ȯ + //군주 몹 소환 비용 const int WarpPrice = 10000; - // ˻ + //군주 국고 검사 if (!CMonarch::instance().IsMoneyOk(WarpPrice, ch->GetEmpire())) { int NationMoney = CMonarch::instance().GetMoney(ch->GetEmpire()); @@ -1516,10 +1516,10 @@ ACMD(do_monarch_warpto) ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s \xBF\xA1\xB0\xD4\xB7\xCE \xC0\xCC\xB5\xBF\xC7\xD5\xB4\xCF\xB4\xD9"), arg1); ch->WarpSet(pos.x, pos.y); - // 谨 + //군주 돈 삭감 CMonarch::instance().SendtoDBDecMoney(WarpPrice, ch->GetEmpire(), ch); - //Ÿ ʱȭ + //쿨타임 초기화 ch->SetMC(CHARACTER::MI_WARP); } } @@ -1550,10 +1550,10 @@ ACMD(do_monarch_warpto) ch->WarpSet(x, y); ch->Stop(); - // 谨 + //군주 돈 삭감 CMonarch::instance().SendtoDBDecMoney(WarpPrice, ch->GetEmpire(), ch); - //Ÿ ʱȭ + //쿨타임 초기화 ch->SetMC(CHARACTER::MI_WARP); } @@ -1577,17 +1577,17 @@ ACMD(do_monarch_transfer) return; } - // Ÿ ˻ + //군주 쿨타임 검사 if (!ch->IsMCOK(CHARACTER::MI_TRANSFER)) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d \xC3\xCA\xB0\xA3 \xC4\xF0\xC5\xB8\xC0\xD3\xC0\xCC \xC0\xFB\xBF\xEB\xC1\xDF\xC0\xD4\xB4\xCF\xB4\xD9."), ch->GetMCLTime(CHARACTER::MI_TRANSFER)); return; } - // + //군주 워프 비용 const int WarpPrice = 10000; - // ˻ + //군주 국고 검사 if (!CMonarch::instance().IsMoneyOk(WarpPrice, ch->GetEmpire())) { int NationMoney = CMonarch::instance().GetMoney(ch->GetEmpire()); @@ -1635,9 +1635,9 @@ ACMD(do_monarch_transfer) P2P_MANAGER::instance().Send(&pgg, sizeof(TPacketGGTransfer)); ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s \xB4\xD4\xC0\xBB \xBC\xD2\xC8\xAF\xC7\xCF\xBF\xB4\xBD\xC0\xB4\xCF\xB4\xD9."), arg1); - // 谨 + //군주 돈 삭감 CMonarch::instance().SendtoDBDecMoney(WarpPrice, ch->GetEmpire(), ch); - //Ÿ ʱȭ + //쿨타임 초기화 ch->SetMC(CHARACTER::MI_TRANSFER); } else @@ -1674,9 +1674,9 @@ ACMD(do_monarch_transfer) //tch->Show(ch->GetMapIndex(), ch->GetX(), ch->GetY(), ch->GetZ()); tch->WarpSet(ch->GetX(), ch->GetY(), ch->GetMapIndex()); - // 谨 + //군주 돈 삭감 CMonarch::instance().SendtoDBDecMoney(WarpPrice, ch->GetEmpire(), ch); - //Ÿ ʱȭ + //쿨타임 초기화 ch->SetMC(CHARACTER::MI_TRANSFER); } @@ -1766,14 +1766,14 @@ ACMD(do_monarch_tax) return; } - // ˻ + // 군주 검사 if (!ch->IsMonarch()) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB1\xBA\xC1\xD6\xB8\xB8\xC0\xCC \xBB\xE7\xBF\xEB\xC7\xD2\xBC\xF6 \xC0\xD6\xB4\xC2 \xB1\xE2\xB4\xC9\xC0\xD4\xB4\xCF\xB4\xD9")); return; } - // ݼ + // 세금설정 int tax = 0; str_to_number(tax, arg1); @@ -1782,10 +1782,10 @@ ACMD(do_monarch_tax) quest::CQuestManager::instance().SetEventFlag("trade_tax", tax); - // ֿ ޼ ϳ + // 군주에게 메세지 하나 ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xBC\xBC\xB1\xDD\xC0\xCC %d %\xB7\xCE \xBC\xB3\xC1\xA4\xB5\xC7\xBE\xFA\xBD\xC0\xB4\xCF\xB4\xD9")); - // + // 공지 char szMsg[1024]; snprintf(szMsg, sizeof(szMsg), "\xB1\xBA\xC1\xD6\xC0\xC7 \xB8\xED\xC0\xB8\xB7\xCE \xBC\xBC\xB1\xDD\xC0\xCC %d %% \xB7\xCE \xBA\xAF\xB0\xE6\xB5\xC7\xBE\xFA\xBD\xC0\xB4\xCF\xB4\xD9", tax); @@ -1794,32 +1794,32 @@ ACMD(do_monarch_tax) snprintf(szMsg, sizeof(szMsg), "\xBE\xD5\xC0\xB8\xB7\xCE\xB4\xC2 \xB0\xC5\xB7\xA1 \xB1\xDD\xBE\xD7\xC0\xC7 %d %% \xB0\xA1 \xB1\xB9\xB0\xED\xB7\xCE \xB5\xE9\xBE\xEE\xB0\xA1\xB0\xD4\xB5\xCB\xB4\xCF\xB4\xD9.", tax); BroadcastNotice(szMsg); - // Ÿ ʱȭ + // 쿨타임 초기화 ch->SetMC(CHARACTER::MI_TAX); } static const DWORD cs_dwMonarchMobVnums[] = { - 191, // ߽ - 192, // - 193, // - 194, // ȣ - 391, // - 392, // - 393, // - 394, // - 491, // ȯ - 492, // - 493, // - 494, // - 591, // ܴ - 691, // - 791, // б - 1304, // - 1901, // ȣ - 2091, // հŹ - 2191, // Ŵ縷ź - 2206, // ȭi + 191, // 산견신 + 192, // 저신 + 193, // 웅신 + 194, // 호신 + 391, // 미정 + 392, // 은정 + 393, // 세랑 + 394, // 진희 + 491, // 맹환 + 492, // 보우 + 493, // 구패 + 494, // 추흔 + 591, // 비류단대장 + 691, // 웅귀 족장 + 791, // 밀교교주 + 1304, // 누렁범귀 + 1901, // 구미호 + 2091, // 여왕거미 + 2191, // 거대사막거북 + 2206, // 화염왕i 0, }; @@ -1854,17 +1854,17 @@ ACMD(do_monarch_mob) } } - // ȯ + // 군주 몹 소환 비용 const int SummonPrice = 5000000; - // Ÿ ˻ + // 군주 쿨타임 검사 if (!ch->IsMCOK(CHARACTER::MI_SUMMON)) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d \xC3\xCA\xB0\xA3 \xC4\xF0\xC5\xB8\xC0\xD3\xC0\xCC \xC0\xFB\xBF\xEB\xC1\xDF\xC0\xD4\xB4\xCF\xB4\xD9."), ch->GetMCLTime(CHARACTER::MI_SUMMON)); return; } - // ˻ + // 군주 국고 검사 if (!CMonarch::instance().IsMoneyOk(SummonPrice, ch->GetEmpire())) { int NationMoney = CMonarch::instance().GetMoney(ch->GetEmpire()); @@ -1892,7 +1892,7 @@ ACMD(do_monarch_mob) DWORD count; - // ȯ ˻ + // 소환 가능 몹 검사 for (count = 0; cs_dwMonarchMobVnums[count] != 0; ++count) if (cs_dwMonarchMobVnums[count] == vnum) break; @@ -1915,10 +1915,10 @@ ACMD(do_monarch_mob) if (tch) { - // 谨 + // 군주 돈 삭감 CMonarch::instance().SendtoDBDecMoney(SummonPrice, ch->GetEmpire(), ch); - // Ÿ ʱȭ + // 쿨타임 초기화 ch->SetMC(CHARACTER::MI_SUMMON); } } @@ -2185,11 +2185,11 @@ ACMD(do_cube) const std::string& strArg1 = std::string(arg1); // r_info (request information) - // /cube r_info ==> (Client -> Server) NPC ִ û + // /cube r_info ==> (Client -> Server) 현재 NPC가 만들 수 있는 레시피 요청 // (Server -> Client) /cube r_list npcVNUM resultCOUNT 123,1/125,1/128,1/130,5 // - // /cube r_info 3 ==> (Client -> Server) NPC ִ 3° ʿ û - // /cube r_info 3 5 ==> (Client -> Server) NPC ִ 3° ۺ 5 ʿ û + // /cube r_info 3 ==> (Client -> Server) 현재 NPC가 만들수 있는 레시피 중 3번째 아이템을 만드는 데 필요한 정보를 요청 + // /cube r_info 3 5 ==> (Client -> Server) 현재 NPC가 만들수 있는 레시피 중 3번째 아이템부터 이후 5개의 아이템을 만드는 데 필요한 재료 정보를 요청 // (Server -> Client) /cube m_info startIndex count 125,1|126,2|127,2|123,5&555,5&555,4/120000@125,1|126,2|127,2|123,5&555,5&555,4/120000 // if (strArg1 == "r_info") @@ -2278,7 +2278,7 @@ ACMD(do_in_game_mall) return; } - // _ 赵 ۸ URL ϵڵ ߰ + // ㅠ_ㅠ 쾌도서버 아이템몰 URL 하드코딩 추가 if (true == LC_IsWE_Korea()) { ch->ChatPacket(CHAT_TYPE_COMMAND, "mall http://metin2.co.kr/50_we_mall/mall/login.htm"); @@ -2354,7 +2354,7 @@ ACMD(do_in_game_mall) } } -// ֻ +// 주사위 ACMD(do_dice) { char arg1[256], arg2[256]; @@ -2395,7 +2395,7 @@ ACMD(do_ride) if (ch->IsDead() || ch->IsStun()) return; - // + // 내리기 { if (ch->IsHorseRiding()) { @@ -2412,7 +2412,7 @@ ACMD(do_ride) } } - // Ÿ + // 타기 { if (ch->GetHorse() != NULL) { @@ -2427,7 +2427,7 @@ ACMD(do_ride) if (NULL == item) continue; - // ũ Ż + // 유니크 탈것 아이템 if (item->IsRideItem()) { if (NULL==ch->GetWear(WEAR_UNIQUE1) || NULL==ch->GetWear(WEAR_UNIQUE2)) @@ -2439,20 +2439,20 @@ ACMD(do_ride) } } - // Ϲ Ż - // TODO : ŻͿ SubType ߰ + // 일반 탈것 아이템 + // TODO : 탈것용 SubType 추가 switch (item->GetVnum()) { - case 71114: // ̿ - case 71116: // ߽̿ - case 71118: // ̿ - case 71120: // ڿ̿ + case 71114: // 저신이용권 + case 71116: // 산견신이용권 + case 71118: // 투지범이용권 + case 71120: // 사자왕이용권 SPDLOG_TRACE("[DO_RIDE] USE QUEST ITEM"); ch->UseItem(TItemPos (INVENTORY, i)); return; } - // GF mantis #113524, 52001~52090 Ż + // GF mantis #113524, 52001~52090 번 탈것 if( (item->GetVnum() > 52000) && (item->GetVnum() < 52091) ) { SPDLOG_TRACE("[DO_RIDE] USE QUEST ITEM"); ch->UseItem(TItemPos (INVENTORY, i)); @@ -2462,7 +2462,7 @@ ACMD(do_ride) } - // Ÿų + // 타거나 내릴 수 없을때 ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB8\xBB\xC0\xBB \xB8\xD5\xC0\xFA \xBC\xD2\xC8\xAF\xC7\xD8\xC1\xD6\xBC\xBC\xBF\xE4.")); } @@ -2533,7 +2533,7 @@ ACMD(do_enroll_sale) } // temp_auction -// packet ϰ ϰ, ̰ ؾѴ. +// packet으로 통신하게 하고, 이건 삭제해야한다. ACMD(do_get_auction_list) { char arg1[256]; diff --git a/src/game/src/cmd_gm.cpp b/src/game/src/cmd_gm.cpp index 15fc569..ce6da5f 100644 --- a/src/game/src/cmd_gm.cpp +++ b/src/game/src/cmd_gm.cpp @@ -337,12 +337,12 @@ bool CHARACTER_GoToName(LPCHARACTER ch, BYTE empire, int mapIndex, const char* g { "Three|\xBD\xC2\xB7\xE6\xB0\xEE", 2, 64, 2704, 7399 }, { "Three|\xBD\xC2\xB7\xE6\xB0\xEE", 3, 64, 3213, 8080 }, -// б +// 밀교사원 { "Milgyo|\xB9\xD0\xB1\xB3\xBB\xE7\xBF\xF8", 1, 65, 5536, 1436 }, { "Milgyo|\xB9\xD0\xB1\xB3\xBB\xE7\xBF\xF8", 2, 65, 5536, 1436 }, { "Milgyo|\xB9\xD0\xB1\xB3\xBB\xE7\xBF\xF8", 3, 65, 5536, 1436 }, -// ŸԱ +// 사귀타워입구 { "\xBB\xE7\xB1\xCD\xC5\xB8\xBF\xF6\xC0\xD4\xB1\xB8", 1, 65, 5905, 1108 }, { "\xBB\xE7\xB1\xCD\xC5\xB8\xBF\xF6\xC0\xD4\xB1\xB8", 2, 65, 5905, 1108 }, { "\xBB\xE7\xB1\xCD\xC5\xB8\xBF\xF6\xC0\xD4\xB1\xB8", 3, 65, 5905, 1108 }, @@ -888,7 +888,7 @@ struct FuncPurge int iDist = DISTANCE_APPROX(pkChr->GetX() - m_pkGM->GetX(), pkChr->GetY() - m_pkGM->GetY()); - if (!m_bAll && iDist >= 1000) // 10 ̻ ִ ͵ purge ʴ´. + if (!m_bAll && iDist >= 1000) // 10미터 이상에 있는 것들은 purge 하지 않는다. return; SPDLOG_DEBUG("PURGE: {} {}", pkChr->GetName(), iDist); @@ -1812,7 +1812,7 @@ LPCHARACTER chHori, chForge, chLib, chTemple, chTraining, chTree, chPortal, chBa ACMD(do_b1) { - //ȣ 478 579 + //호리병 478 579 chHori = CHARACTER_MANAGER::instance().SpawnMobRange(14017, ch->GetMapIndex(), 304222, 742858, 304222, 742858, true, false); chHori->AddAffect(AFFECT_DUNGEON_UNIQUE, POINT_NONE, 0, AFF_BUILDING_CONSTRUCTION_SMALL, 65535, 0, true); chHori->AddAffect(AFFECT_DUNGEON_UNIQUE, POINT_NONE, 0, AFF_DUNGEON_UNIQUE, 65535, 0, true); @@ -1859,25 +1859,25 @@ ACMD(do_b2) ACMD(do_b3) { - // 492 547 + // 포지 492 547 chForge = CHARACTER_MANAGER::instance().SpawnMobRange(14003, ch->GetMapIndex(), 307500, 746300, 307500, 746300, true, false); chForge->AddAffect(AFFECT_DUNGEON_UNIQUE, POINT_NONE, 0, AFF_DUNGEON_UNIQUE, 65535, 0, true); - //ž 509 589 -> + //높은탑 509 589 -> 도서관 chLib = CHARACTER_MANAGER::instance().SpawnMobRange(14007, ch->GetMapIndex(), 307900, 744500, 307900, 744500, true, false); chLib->AddAffect(AFFECT_DUNGEON_UNIQUE, POINT_NONE, 0, AFF_DUNGEON_UNIQUE, 65535, 0, true); - // 513 606 -> ǽ + //욕조 513 606 -> 힘의신전 chTemple = CHARACTER_MANAGER::instance().SpawnMobRange(14004, ch->GetMapIndex(), 307700, 741600, 307700, 741600, true, false); chTemple->AddAffect(AFFECT_DUNGEON_UNIQUE, POINT_NONE, 0, AFF_DUNGEON_UNIQUE, 65535, 0, true); - // 490 625 + //권투장 490 625 chTraining= CHARACTER_MANAGER::instance().SpawnMobRange(14010, ch->GetMapIndex(), 307100, 739500, 307100, 739500, true, false); chTraining->AddAffect(AFFECT_DUNGEON_UNIQUE, POINT_NONE, 0, AFF_DUNGEON_UNIQUE, 65535, 0, true); - // 466 614 + //나무 466 614 chTree= CHARACTER_MANAGER::instance().SpawnMobRange(14013, ch->GetMapIndex(), 300800, 741600, 300800, 741600, true, false); chTree->AddAffect(AFFECT_DUNGEON_UNIQUE, POINT_NONE, 0, AFF_DUNGEON_UNIQUE, 65535, 0, true); - //Ż 439 615 + //포탈 439 615 chPortal= CHARACTER_MANAGER::instance().SpawnMobRange(14001, ch->GetMapIndex(), 300900, 744500, 300900, 744500, true, false); chPortal->AddAffect(AFFECT_DUNGEON_UNIQUE, POINT_NONE, 0, AFF_DUNGEON_UNIQUE, 65535, 0, true); - // 436 600 + // 구슬 436 600 chBall = CHARACTER_MANAGER::instance().SpawnMobRange(14012, ch->GetMapIndex(), 302500, 746600, 302500, 746600, true, false); chBall->AddAffect(AFFECT_DUNGEON_UNIQUE, POINT_NONE, 0, AFF_DUNGEON_UNIQUE, 65535, 0, true); } @@ -2121,7 +2121,7 @@ ACMD(do_reload) break; //END_RELOAD_ADMIN case 'c': // cube - // μ Ѵ. + // 로컬 프로세스만 갱산한다. Cube_init (); break; } @@ -2245,7 +2245,7 @@ struct FuncWeaken int iDist = DISTANCE_APPROX(pkChr->GetX() - m_pkGM->GetX(), pkChr->GetY() - m_pkGM->GetY()); - if (!m_bAll && iDist >= 1000) // 10 ̻ ִ ͵ purge ʴ´. + if (!m_bAll && iDist >= 1000) // 10미터 이상에 있는 것들은 purge 하지 않는다. return; if (pkChr->IsNPC()) @@ -2527,7 +2527,7 @@ ACMD(do_priv_empire) if (duration < 0) goto USAGE; - // ð + // 시간 단위로 변경 duration = duration * (60*60); SPDLOG_DEBUG("_give_empire_privileage(empire={}, type={}, value={}, duration={}) by command", @@ -2631,7 +2631,7 @@ ACMD(do_xmas) // BLOCK_CHAT ACMD(do_block_chat_list) { - // GM ƴϰų block_chat_privilege ɾ Ұ + // GM이 아니거나 block_chat_privilege가 없는 사람은 명령어 사용 불가 if (!ch || (ch->GetGMLevel() < GM_HIGH_WIZARD && ch->GetQuestFlag("chat_privilege.block") <= 0)) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB1\xD7\xB7\xB1 \xB8\xED\xB7\xC9\xBE\xEE\xB4\xC2 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9")); @@ -2697,7 +2697,7 @@ ACMD(do_vote_block_chat) ACMD(do_block_chat) { - // GM ƴϰų block_chat_privilege ɾ Ұ + // GM이 아니거나 block_chat_privilege가 없는 사람은 명령어 사용 불가 if (ch && (ch->GetGMLevel() < GM_HIGH_WIZARD && ch->GetQuestFlag("chat_privilege.block") <= 0)) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB1\xD7\xB7\xB1 \xB8\xED\xB7\xC9\xBE\xEE\xB4\xC2 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9")); @@ -2776,8 +2776,8 @@ ACMD(do_build) CLand * pkLand = CManager::instance().FindLand(ch->GetMapIndex(), ch->GetX(), ch->GetY()); - // NOTE: üũ Ŭ̾Ʈ Բ ϱ - // ޼ ʰ Ѵ. + // NOTE: 조건 체크들은 클라이언트와 서버가 함께 하기 때문에 문제가 있을 때는 + // 메세지를 전송하지 않고 에러를 출력한다. if (!pkLand) { SPDLOG_ERROR("{} trying to build on not buildable area.", ch->GetName()); @@ -2790,17 +2790,17 @@ ACMD(do_build) return; } - // Ǽ üũ + // 건설 권한 체크 if (GMLevel == GM_PLAYER) { - // ÷̾ Ȯؾ Ѵ. + // 플레이어가 집을 지을 때는 땅이 내껀지 확인해야 한다. if ((!ch->GetGuild() || ch->GetGuild()->GetID() != pkLand->GetOwner())) { SPDLOG_ERROR("{} trying to build on not owned land.", ch->GetName()); return; } - // 渶ΰ? + // 내가 길마인가? if (ch->GetGuild()->GetMasterPID() != ch->GetPlayerID()) { SPDLOG_ERROR("{} trying to build while not the guild master.", ch->GetName()); @@ -2846,13 +2846,13 @@ ACMD(do_build) } } - // ǹ Ӽ üũ ( ǹ ־) + // 건물 종속성 체크 (이 건물이 지어져 있어야함) if (t->dwDependOnGroupVnum) { // const TObjectProto * dependent = CManager::instance().GetObjectProto(dwVnum); // if (dependent) { - // ִ°? + // 지어져있는가? if (!pkLand->FindObjectByGroup(t->dwDependOnGroupVnum)) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB0\xC7\xBC\xB3\xBF\xA1 \xC7\xCA\xBF\xE4\xC7\xD1 \xB0\xC7\xB9\xB0\xC0\xCC \xC1\xF6\xBE\xEE\xC1\xAE \xC0\xD6\xC1\xF6 \xBE\xCA\xBD\xC0\xB4\xCF\xB4\xD9.")); @@ -2863,8 +2863,8 @@ ACMD(do_build) if (test_server || GMLevel == GM_PLAYER) { - // GM ƴҰ츸 (׼ GM Ҹ) - // Ǽ üũ + // GM이 아닐경우만 (테섭에서는 GM도 소모) + // 건설 비용 체크 if (t->dwPrice > BUILDING_MAX_PRICE) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB0\xC7\xB9\xB0 \xBA\xF1\xBF\xEB \xC1\xA4\xBA\xB8 \xC0\xCC\xBB\xF3\xC0\xB8\xB7\xCE \xB0\xC7\xBC\xB3 \xC0\xDB\xBE\xF7\xBF\xA1 \xBD\xC7\xC6\xD0\xC7\xDF\xBD\xC0\xB4\xCF\xB4\xD9.")); @@ -2877,7 +2877,7 @@ ACMD(do_build) return; } - // üũ + // 아이템 자재 개수 체크 int i; for (i = 0; i < OBJECT_MATERIAL_MAX_NUM; ++i) @@ -2899,7 +2899,7 @@ ACMD(do_build) float x_rot = atof(arg4); float y_rot = atof(arg5); float z_rot = atof(arg6); - // 20050811.myevan.ǹ ȸ + // 20050811.myevan.건물 회전 기능 봉인 해제 /* if (x_rot != 0.0f || y_rot != 0.0f || z_rot != 0.0f) { @@ -2929,12 +2929,12 @@ ACMD(do_build) } if (test_server || GMLevel == GM_PLAYER) - // Ǽ Ҹϱ (׼ GM Ҹ) + // 건설 재료 소모하기 (테섭에서는 GM도 소모) { - // Ǽ Ҹ + // 건설 비용 소모 ch->PointChange(POINT_GOLD, -t->dwPrice); - // ϱ + // 아이템 자재 사용하기 { int i; for (i = 0; i < OBJECT_MATERIAL_MAX_NUM; ++i) @@ -3013,8 +3013,8 @@ ACMD(do_build) break; case 'W' : - // - // build (w)all ȣ ũ 빮 빮 빮 빮 + // 담장 세우기 + // build (w)all 담장번호 담장크기 대문동 대문서 대문남 대문북 if (GMLevel > GM_PLAYER) { @@ -3048,8 +3048,8 @@ ACMD(do_build) break; case 'E' : - // - // build (e)rase ID + // 담장 지우기 + // build (e)rase 담장셋ID if (GMLevel > GM_PLAYER) { one_argument(line, arg1, sizeof(arg1)); @@ -3323,7 +3323,7 @@ ACMD(do_duel) if (!str_to_number(minute, szMinute)) { - // ijٴ ⺻ 10. + // 캐나다는 기본 10분. if (LC_IsCanada() == true) { minute = 10; @@ -3430,28 +3430,28 @@ ACMD(do_stat_plus_amount) switch (subcmd) { - case POINT_HT : // ü + case POINT_HT : // 체력 if (nPoint + ch->GetPoint(POINT_HT) > 90) { nPoint = 90 - ch->GetPoint(POINT_HT); } break; - case POINT_IQ : // + case POINT_IQ : // 지능 if (nPoint + ch->GetPoint(POINT_IQ) > 90) { nPoint = 90 - ch->GetPoint(POINT_IQ); } break; - case POINT_ST : // ٷ + case POINT_ST : // 근력 if (nPoint + ch->GetPoint(POINT_ST) > 90) { nPoint = 90 - ch->GetPoint(POINT_ST); } break; - case POINT_DX : // ø + case POINT_DX : // 민첩 if (nPoint + ch->GetPoint(POINT_DX) > 90) { nPoint = 90 - ch->GetPoint(POINT_DX); @@ -4208,8 +4208,8 @@ ACMD (do_attr_full_set) case JOB_SURA: case JOB_SHAMAN: { - // . - // ̰͸ ־ ӽ÷ ̷ Ӽ . + // 무사 몸빵 셋팅. + // 이것만 나와 있어서 임시로 모든 직군 다 이런 속성 따름. item = ch->GetWear(WEAR_HEAD); if (item != NULL) { diff --git a/src/game/src/config.cpp b/src/game/src/config.cpp index cfd83f6..bc8ac61 100644 --- a/src/game/src/config.cpp +++ b/src/game/src/config.cpp @@ -102,17 +102,17 @@ int SPEEDHACK_LIMIT_COUNT = 50; int SPEEDHACK_LIMIT_BONUS = 80; int g_iSyncHackLimitCount = 20; // 10 -> 20 2013 09 11 CYH -//�þ� = VIEW_RANGE + VIEW_BONUS_RANGE -//VIEW_BONUSE_RANGE : Ŭ���̾�Ʈ�� �þ� ó�������ʹ� �� ��������� ������ �߻��Ҽ��־� 500CM�� ������ �׻��ش�. +//시야 = VIEW_RANGE + VIEW_BONUS_RANGE +//VIEW_BONUSE_RANGE : 클라이언트와 시야 처리에서너무 딱 떨어질경우 문제가 발생할수있어 500CM의 여분을 항상준다. int VIEW_RANGE = 5000; int VIEW_BONUS_RANGE = 500; int g_server_id = 0; string g_strWebMallURL = "www.metin2.de"; -unsigned int g_uiSpamBlockDuration = 60 * 15; // �⺻ 15�� -unsigned int g_uiSpamBlockScore = 100; // �⺻ 100�� -unsigned int g_uiSpamReloadCycle = 60 * 10; // �⺻ 10�� +unsigned int g_uiSpamBlockDuration = 60 * 15; // 기본 15분 +unsigned int g_uiSpamBlockScore = 100; // 기본 100점 +unsigned int g_uiSpamReloadCycle = 60 * 10; // 기본 10분 bool g_bCheckMultiHack = true; @@ -121,8 +121,8 @@ int g_iSpamBlockMaxLevel = 10; void LoadStateUserCount(); void LoadValidCRCList(); bool LoadClientVersion(); -bool g_protectNormalPlayer = false; // �����ڰ� "��ȭ���" �� �Ϲ������� �������� ���� -bool g_noticeBattleZone = false; // �߸����뿡 �����ϸ� �ȳ��޼����� �˷��� +bool g_protectNormalPlayer = false; // 범법자가 "평화모드" 인 일반유저를 공격하지 못함 +bool g_noticeBattleZone = false; // 중립지대에 입장하면 안내메세지를 알려줌 int gPlayerMaxLevel = 99; @@ -318,7 +318,7 @@ void config_init(const string& st_localeServiceName) } char db_host[2][64], db_user[2][64], db_pwd[2][64], db_db[2][64]; - // ... ��... db_port�� �̹� �ִµ�... ���̹� �����ؾ���... + // ... 아... db_port는 이미 있는데... 네이밍 어찌해야함... int mysql_db_port[2]; for (int n = 0; n < 2; ++n) @@ -339,9 +339,9 @@ void config_init(const string& st_localeServiceName) *log_db = '\0'; - // DB���� ������������ �����ϱ����ؼ��� �ٸ� ���ð����� ����Ǿ - // DB������ �о�� ������ ������ ���� �ٸ� ������ ������Ѿ��Ѵ�. - // ������ �����ϰ��õ� �ʱ�ȭ ��ƾ�� ������ �����ϱ� ����. + // DB에서 로케일정보를 세팅하기위해서는 다른 세팅값보다 선행되어서 + // DB정보만 읽어와 로케일 세팅을 한후 다른 세팅을 적용시켜야한다. + // 이유는 로케일관련된 초기화 루틴이 곳곳에 존재하기 때문. bool isCommonSQL = false; bool isPlayerSQL = false; @@ -477,7 +477,7 @@ void config_init(const string& st_localeServiceName) } } - //ó���� �������� ������ ����. + //처리가 끝났으니 파일을 닫자. fclose(fpOnlyForDB); // CONFIG_SQL_INFO_ERROR @@ -503,7 +503,7 @@ void config_init(const string& st_localeServiceName) exit(EXIT_FAILURE); } - // Common DB �� Locale ������ ������ �ֱ� ������ ���� ���� �����ؾ� �Ѵ�. + // Common DB 가 Locale 정보를 가지고 있기 때문에 가장 먼저 접속해야 한다. AccountDB::instance().Connect(db_host[1], mysql_db_port[1], db_user[1], db_pwd[1], db_db[1]); if (false == AccountDB::instance().IsConnected()) @@ -514,8 +514,8 @@ void config_init(const string& st_localeServiceName) SPDLOG_INFO("CommonSQL connected"); - // ������ ������ �������� - // <���> �������� ���� ���ǹ�(WHERE) ���� ������. (�ٸ� �������� ������ ����� �ֽ��ϴ�) + // 로케일 정보를 가져오자 + // <경고> 쿼리문에 절대 조건문(WHERE) 달지 마세요. (다른 지역에서 문제가 생길수 있습니다) { char szQuery[512]; snprintf(szQuery, sizeof(szQuery), "SELECT mKey, mValue FROM locale"); @@ -532,7 +532,7 @@ void config_init(const string& st_localeServiceName) while (NULL != (row = mysql_fetch_row(pMsg->Get()->pSQLResult))) { - // ������ ���� + // 로케일 세팅 if (strcasecmp(row[0], "LOCALE") == 0) { if (LocaleService_Init(row[1]) == false) @@ -544,15 +544,15 @@ void config_init(const string& st_localeServiceName) } } - // ������ ������ COMMON SQL�� �������ش�. - // ������ g_stLocale ������ LocaleService_Init() ���ο��� ���õȴ�. + // 로케일 정보를 COMMON SQL에 세팅해준다. + // 참고로 g_stLocale 정보는 LocaleService_Init() 내부에서 세팅된다. SPDLOG_INFO("Setting DB to locale {}", g_stLocale.c_str()); AccountDB::instance().SetLocale(g_stLocale); AccountDB::instance().ConnectAsync(db_host[1], mysql_db_port[1], db_user[1], db_pwd[1], db_db[1], g_stLocale.c_str()); - // Player DB ���� + // Player DB 접속 DBManager::instance().Connect(db_host[0], mysql_db_port[0], db_user[0], db_pwd[0], db_db[0]); if (!DBManager::instance().IsConnected()) @@ -563,9 +563,9 @@ void config_init(const string& st_localeServiceName) SPDLOG_INFO("PlayerSQL connected"); - if (false == g_bAuthServer) // ���� ������ �ƴ� ��� + if (false == g_bAuthServer) // 인증 서버가 아닐 경우 { - // Log DB ���� + // Log DB 접속 LogManager::instance().Connect(log_host, log_port, log_user, log_pwd, log_db); if (!LogManager::instance().IsConnected()) @@ -580,8 +580,8 @@ void config_init(const string& st_localeServiceName) } // SKILL_POWER_BY_LEVEL - // ��Ʈ�� ���� ������ ���ؼ� AccountDB::instance().SetLocale(g_stLocale) �ĺ��� �Ѵ�. - // ���� ������ ���� ������ �ȵȴ�(�ؿܰ� ����) + // 스트링 비교의 문제로 인해서 AccountDB::instance().SetLocale(g_stLocale) 후부터 한다. + // 물론 국내는 별로 문제가 안된다(해외가 문제) { char szQuery[256]; snprintf(szQuery, sizeof(szQuery), "SELECT mValue FROM locale WHERE mKey='SKILL_POWER_BY_LEVEL'"); @@ -621,13 +621,13 @@ void config_init(const string& st_localeServiceName) } } - // ������ ��ų ���� + // 종족별 스킬 세팅 for (int job = 0; job < JOB_MAX_NUM * 2; ++job) { snprintf(szQuery, sizeof(szQuery), "SELECT mValue from locale where mKey='SKILL_POWER_BY_LEVEL_TYPE%d' ORDER BY CAST(mValue AS unsigned)", job); std::unique_ptr pMsg(AccountDB::instance().DirectQuery(szQuery)); - // ������ �ȵǾ������� �⺻���̺��� ����Ѵ�. + // 세팅이 안되어있으면 기본테이블을 사용한다. if (pMsg->Get()->uiNumRows == 0) { CTableBySkill::instance().SetSkillPowerByLevelFromType(job, aiBaseSkillPowerByLevelTable); @@ -1002,7 +1002,7 @@ void config_init(const string& st_localeServiceName) TOKEN("spam_block_reload_cycle") { str_to_number(g_uiSpamReloadCycle, value_string); - g_uiSpamReloadCycle = std::max(60, g_uiSpamReloadCycle); // �ּ� 1�� + g_uiSpamReloadCycle = std::max(60, g_uiSpamReloadCycle); // 최소 1분 } TOKEN("check_multihack") diff --git a/src/game/src/constants.cpp b/src/game/src/constants.cpp index fe44221..153892e 100644 --- a/src/game/src/constants.cpp +++ b/src/game/src/constants.cpp @@ -14,7 +14,7 @@ TJobInitialPoints JobInitialPoints[JOB_MAX_NUM] = } */ { - // str con dex int ʱHP ʱSP CON/HP INT/SP HP/lv MP/lv ʱstam stam/con stam/lv + // str con dex int 초기HP 초기SP CON/HP INT/SP HP랜덤/lv MP랜덤/lv 초기stam stam/con stam/lv { 6, 4, 3, 3, 600, 200, 40, 20, 36, 44, 18, 22, 800, 5, 1, 3 }, // JOB_WARRIOR 16 { 4, 3, 6, 3, 650, 200, 40, 20, 36, 44, 18, 22, 800, 5, 1, 3 }, // JOB_ASSASSIN 16 { 5, 3, 3, 5, 650, 200, 40, 20, 36, 44, 18, 22, 800, 5, 1, 3 }, // JOB_SURA 16 @@ -162,7 +162,7 @@ const DWORD exp_table_euckr[PLAYER_EXP_TABLE_MAX + 1] = 1676898443, 1844588288, 2029047116, - 2100000000, // 99 99 ʿġ (100 DZ ) + 2100000000, // 99 99레벨일 때 필요경험치 (100레벨이 되기 위한) 2100000000, // 100 2100000000, 2100000000, @@ -287,7 +287,7 @@ const DWORD exp_table_common[PLAYER_EXP_TABLE_MAX + 1] = 1676898443, 1844588288, 2029047116, - 2050000000, // 99 ʿġ (100 DZ ) + 2050000000, // 99레벨 일 때 필요경험치 (100레벨이 되기 위한) 2150000000, // 100 2210000000, 2250000000, @@ -412,7 +412,7 @@ const DWORD exp_table_newcibn[PLAYER_EXP_TABLE_MAX + 1 ] = 2000000000, 2000000000, 2000000000, - 2000000000, // 99 99 ʿġ (100 DZ ).. CIBN  ϰ ִ 𸣴 ű ̺ ʰ + 2000000000, // 99 99레벨일 때 필요경험치 (100레벨이 되기 위한).. 현재 CIBN이 어떻게 운영하고 있는 지 모르니 신규 테이블을 쓰지 않고 기존값 계속 연장 유지 2000000000, // 100 2000000000, 2000000000, @@ -439,8 +439,8 @@ const DWORD exp_table_newcibn[PLAYER_EXP_TABLE_MAX + 1 ] = const int * aiPercentByDeltaLev = NULL; const int * aiPercentByDeltaLevForBoss = NULL; -// ̿ 꿡 Ǵ ̺ -// MIN(MAX_EXP_DELTA_OF_LEV - 1, ( + 15) - )) +// 적과 나와의 레벨차이에 의한 계산에 사용되는 테이블 +// MIN(MAX_EXP_DELTA_OF_LEV - 1, (적렙 + 15) - 내렙)) const int aiPercentByDeltaLevForBoss_euckr[MAX_EXP_DELTA_OF_LEV] = { 1, // -15 0 @@ -720,7 +720,7 @@ const DWORD guild_exp_table[GUILD_MAX_LEVEL+1] = 42000000UL }; -// INTERNATIONAL_VERSION ġ +// INTERNATIONAL_VERSION 길드경험치 const DWORD guild_exp_table2[GUILD_MAX_LEVEL+1] = { 0, @@ -745,7 +745,7 @@ const DWORD guild_exp_table2[GUILD_MAX_LEVEL+1] = 4000000UL, 16800000UL }; -// END_OF_INTERNATIONAL_VERSION ġ +// END_OF_INTERNATIONAL_VERSION 길드경험치 const int aiMobEnchantApplyIdx[MOB_ENCHANTS_MAX_NUM] = { @@ -898,16 +898,16 @@ const TApplyInfo aApplyInfo[MAX_APPLY_NUM] = { POINT_PC_BANG_DROP_BONUS }, // 76 // END_PC_BANG_ITEM_ADD - { POINT_NONE, }, // 77 HP Ҹ APPLY_EXTRACT_HP_PCT + { POINT_NONE, }, // 77 사용시 HP 소모 APPLY_EXTRACT_HP_PCT - { POINT_RESIST_WARRIOR, }, // 78 翡 APPLY_RESIST_WARRIOR - { POINT_RESIST_ASSASSIN, }, // 79 ڰ APPLY_RESIST_ASSASSIN - { POINT_RESIST_SURA, }, // 80 󿡰 APPLY_RESIST_SURA - { POINT_RESIST_SHAMAN, }, // 81 翡 APPLY_RESIST_SHAMAN - { POINT_ENERGY }, // 82 - { POINT_DEF_GRADE }, // 83 . DEF_GRADE_BONUS Ŭ󿡼 ι ǵ (...) ִ. - { POINT_COSTUME_ATTR_BONUS }, // 84 ڽƬ Ӽ ؼ ʽ ִ - { POINT_MAGIC_ATT_BONUS_PER }, // 85 ݷ +x% + { POINT_RESIST_WARRIOR, }, // 78 무사에게 저항 APPLY_RESIST_WARRIOR + { POINT_RESIST_ASSASSIN, }, // 79 자객에게 저항 APPLY_RESIST_ASSASSIN + { POINT_RESIST_SURA, }, // 80 수라에게 저항 APPLY_RESIST_SURA + { POINT_RESIST_SHAMAN, }, // 81 무당에게 저항 APPLY_RESIST_SHAMAN + { POINT_ENERGY }, // 82 기력 + { POINT_DEF_GRADE }, // 83 방어력. DEF_GRADE_BONUS는 클라에서 두배로 보여지는 의도된 버그(...)가 있다. + { POINT_COSTUME_ATTR_BONUS }, // 84 코스튬에 붙은 속성에 대해서만 보너스를 주는 기력 + { POINT_MAGIC_ATT_BONUS_PER }, // 85 마법 공격력 +x% { POINT_MELEE_MAGIC_ATT_BONUS_PER }, // 86 APPLY_MELEE_MAGIC_ATTBONUS_PER { POINT_RESIST_ICE, }, // APPLY_RESIST_ICE, 87 { POINT_RESIST_EARTH, }, // APPLY_RESIST_EARTH, 88 @@ -1153,28 +1153,28 @@ TGuildWarInfo KOR_aGuildWarInfo[GUILD_WAR_TYPE_MAX_NUM] = }; // -// Ǽ Ͽ ġ +// 악세서리 소켓용 수치들 // -// ̾Ƹ ߰ Ȯ +// 다이아몬드로 소켓을 추가할 때 확률 const int aiAccessorySocketAddPct[ITEM_ACCESSORY_SOCKET_MAX_NUM] = { 50, 50, 50 }; -// Ǽ ġ %ŭ ߰ϴ +// 악세서리 수치 값의 몇%만큼의 성능을 추가하는지 const int aiAccessorySocketEffectivePct[ITEM_ACCESSORY_SOCKET_MAX_NUM + 1] = { 0, 10, 20, 40 }; -// ӽð 24, 12, 6 +// 소켓 지속시간 24, 12, 6 const int aiAccessorySocketDegradeTime[ITEM_ACCESSORY_SOCKET_MAX_NUM + 1] = { 0, 3600 * 24, 3600 * 12, 3600 * 6 }; -// +// 소켓 장착 성공률 const int aiAccessorySocketPutPct[ITEM_ACCESSORY_SOCKET_MAX_NUM + 1] = { 90, 80, 70, 0 @@ -1274,10 +1274,10 @@ TValueName c_aApplyTypeNames[] = { "RESIST_ASSASSIN", APPLY_RESIST_ASSASSIN}, { "RESIST_SURA", APPLY_RESIST_SURA}, { "RESIST_SHAMAN", APPLY_RESIST_SHAMAN}, - // by mhh game/affect.h ǵǾ. INFINITE_AFFECT_DURATION = 0x1FFFFFFF + // by mhh game/affect.h 정의되어있음. INFINITE_AFFECT_DURATION = 0x1FFFFFFF { "INFINITE_AFFECT_DURATION", 0x1FFFFFFF }, - { "ENERGY", APPLY_ENERGY }, // - { "COSTUME_ATTR_BONUS", APPLY_COSTUME_ATTR_BONUS }, // + { "ENERGY", APPLY_ENERGY }, // 기력 + { "COSTUME_ATTR_BONUS", APPLY_COSTUME_ATTR_BONUS }, // 기력 { "MAGIC_ATTBONUS_PER", APPLY_MAGIC_ATTBONUS_PER }, { "MELEE_MAGIC_ATTBONUS_PER", APPLY_MELEE_MAGIC_ATTBONUS_PER }, diff --git a/src/game/src/cube.cpp b/src/game/src/cube.cpp index 474bc71..adaf3b7 100644 --- a/src/game/src/cube.cpp +++ b/src/game/src/cube.cpp @@ -37,11 +37,11 @@ static bool s_isInitializedCubeMaterialInformation = false; /*--------------------------------------------------------*/ enum ECubeResultCategory { - CUBE_CATEGORY_POTION, // , .. ( Ư . ʰ Ÿ) - CUBE_CATEGORY_WEAPON, // - CUBE_CATEGORY_ARMOR, //  - CUBE_CATEGORY_ACCESSORY, // ű - CUBE_CATEGORY_ETC, // Ÿ ... + CUBE_CATEGORY_POTION, // 약초, 진액 등등.. (포션으로 특정할 수 없으니 사용 안 함. 약초같은건 다 걍 기타) + CUBE_CATEGORY_WEAPON, // 무기 + CUBE_CATEGORY_ARMOR, // 방어구 + CUBE_CATEGORY_ACCESSORY, // 장신구 + CUBE_CATEGORY_ETC, // 기타 등등... }; typedef std::vector TCubeValueVector; @@ -53,12 +53,12 @@ struct SCubeMaterialInfo bHaveComplicateMaterial = false; }; - CUBE_VALUE reward; // - TCubeValueVector material; // - DWORD gold; // 󸶵 - TCubeValueVector complicateMaterial; // -_- + CUBE_VALUE reward; // 보상이 뭐냐 + TCubeValueVector material; // 재료들은 뭐냐 + DWORD gold; // 돈은 얼마드냐 + TCubeValueVector complicateMaterial; // 복잡한-_- 재료들 - // .. Ŭ̾Ʈ Ḧ ֱ Ͽ + // .. 클라이언트에서 재료를 보여주기 위하여 약속한 포맷 // 72723,1&72724,2&72730,1 // 52001,1|52002,1|52003,1&72723,1&72724,5 // => ( 52001,1 or 52002,1 or 52003,1 ) and 72723,1 and 72724,5 @@ -75,13 +75,13 @@ struct SItemNameAndLevel }; -// ڷᱸ ̷ ΰ ... ȥ ¿ +// 자료구조나 이런거 병신인건 이해좀... 누구땜에 영혼이 없는 상태에서 만들었씀 typedef std::vector TCubeResultList; -typedef std::unordered_map TCubeMapByNPC; // NPC  ְ ᰡ ... -typedef std::unordered_map TCubeResultInfoTextByNPC; // NPC ִ +typedef std::unordered_map TCubeMapByNPC; // 각각의 NPC별로 어떤 걸 만들 수 있고 재료가 뭔지... +typedef std::unordered_map TCubeResultInfoTextByNPC; // 각각의 NPC별로 만들 수 있는 목록을 정해진 포맷으로 정리한 정보 TCubeMapByNPC cube_info_map; -TCubeResultInfoTextByNPC cube_result_info_map_by_npc; // ̹ Ű +TCubeResultInfoTextByNPC cube_result_info_map_by_npc; // 네이밍 존나 병신같다 ㅋㅋㅋ class CCubeMaterialInfoHelper { @@ -92,7 +92,7 @@ public: /*--------------------------------------------------------*/ /* STATIC FUNCTIONS */ /*--------------------------------------------------------*/ - // ʿ ִ°? + // 필요한 아이템 개수를 가지고있는가? static bool FN_check_item_count (LPITEM *items, DWORD item_vnum, int need_count) { int count = 0; @@ -111,7 +111,7 @@ static bool FN_check_item_count (LPITEM *items, DWORD item_vnum, int need_count) return (count>=need_count); } -// ť곻 Ḧ . +// 큐브내의 재료를 지운다. static void FN_remove_material (LPITEM *items, DWORD item_vnum, int need_count) { int count = 0; @@ -170,7 +170,7 @@ static bool FN_check_valid_npc( WORD vnum ) return false; } -// ť굥Ÿ ùٸ ʱȭ Ǿ üũѴ. +// 큐브데이타가 올바르게 초기화 되었는지 체크한다. static bool FN_check_cube_data (CUBE_DATA *cube_data) { DWORD i = 0; @@ -204,10 +204,10 @@ CUBE_DATA::CUBE_DATA() this->gold = 0; } -// ʿ ϴ üũѴ. +// 필요한 재료의 수량을 만족하는지 체크한다. bool CUBE_DATA::can_make_item (LPITEM *items, WORD npc_vnum) { - // ʿ , ϴ üũѴ. + // 필요한 재료, 수량을 만족하는지 체크한다. DWORD i, end_index; DWORD need_vnum; int need_count; @@ -235,7 +235,7 @@ bool CUBE_DATA::can_make_item (LPITEM *items, WORD npc_vnum) return true; } -// ť긦 +// 큐브를 돌렸을때 나오는 아이템의 종류를 결정함 CUBE_VALUE* CUBE_DATA::reward_value () { int end_index = 0; @@ -248,7 +248,7 @@ CUBE_VALUE* CUBE_DATA::reward_value () return &this->reward[reward_index]; } -// ť꿡 ִ Ḧ +// 큐브에 들어있는 재료를 지운다 void CUBE_DATA::remove_material (LPCHARACTER ch) { DWORD i, end_index; @@ -281,7 +281,7 @@ void Cube_clean_item (LPCHARACTER ch) } } -// ťâ +// 큐브창 열기 void Cube_open (LPCHARACTER ch) { if (false == s_isInitializedCubeMaterialInformation) @@ -331,7 +331,7 @@ void Cube_open (LPCHARACTER ch) ch->ChatPacket(CHAT_TYPE_COMMAND, "cube open %d", npc->GetRaceNum()); } -// ť ĵ +// 큐브 캔슬 void Cube_close (LPCHARACTER ch) { RETURN_IF_CUBE_IS_NOT_OPENED(ch); @@ -426,7 +426,7 @@ bool Cube_load (const char *file) } else TOKEN("gold") { - // ʿ ݾ + // 제조에 필요한 금액 cube_data->gold = value1; } else TOKEN("end") @@ -504,10 +504,10 @@ static bool FN_update_cube_status(LPCHARACTER ch) // return new item bool Cube_make (LPCHARACTER ch) { - // ־ ʿϴ ã´. (ť굥Ÿ Ī) - // ť Ÿ ִٸ Ḧ üũѴ. - // ο . - // ο + // 주어진 아이템을 필요로하는 조합을 찾는다. (큐브데이타로 칭함) + // 큐브 데이타가 있다면 아이템의 재료를 체크한다. + // 새로운 아이템을 만든다. + // 새로운 아이템 지급 LPCHARACTER npc; int percent_number = 0; @@ -538,23 +538,23 @@ bool Cube_make (LPCHARACTER ch) if (ch->GetGold() < cube_proto->gold) { - ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB5\xB7\xC0\xCC \xBA\xCE\xC1\xB7\xC7\xCF\xB0\xC5\xB3\xAA \xBE\xC6\xC0\xCC\xC5\xDB\xC0\xCC \xC1\xA6\xC0\xDA\xB8\xAE\xBF\xA1 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9.")); // ؽƮ ̹ θ ̴°Ŷ ߰ ʿ + ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB5\xB7\xC0\xCC \xBA\xCE\xC1\xB7\xC7\xCF\xB0\xC5\xB3\xAA \xBE\xC6\xC0\xCC\xC5\xDB\xC0\xCC \xC1\xA6\xC0\xDA\xB8\xAE\xBF\xA1 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9.")); // 이 텍스트는 이미 널리 쓰이는거라 추가번역 필요 없음 return false; } CUBE_VALUE *reward_value = cube_proto->reward_value(); - // Ǿ + // 사용되었던 재료아이템 삭제 cube_proto->remove_material (ch); - // ʿ + // 제조시 필요한 골드 차감 if (0 < cube_proto->gold) ch->PointChange(POINT_GOLD, -(cube_proto->gold), false); percent_number = Random::get(1,100); if ( percent_number<=cube_proto->percent) { - // + // 성공 ch->ChatPacket(CHAT_TYPE_COMMAND, "cube success %d %d", reward_value->vnum, reward_value->count); new_item = ch->AutoGiveItem(reward_value->vnum, reward_value->count); @@ -564,8 +564,8 @@ bool Cube_make (LPCHARACTER ch) } else { - // - ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC1\xA6\xC1\xB6\xBF\xA1 \xBD\xC7\xC6\xD0\xC7\xCF\xBF\xB4\xBD\xC0\xB4\xCF\xB4\xD9.")); // 2012.11.12 ߰ ޼ (locale_string.txt ߰ؾ ) + // 실패 + ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xC1\xA6\xC1\xB6\xBF\xA1 \xBD\xC7\xC6\xD0\xC7\xCF\xBF\xB4\xBD\xC0\xB4\xCF\xB4\xD9.")); // 2012.11.12 새로 추가된 메세지 (locale_string.txt 에 추가해야 함) ch->ChatPacket(CHAT_TYPE_COMMAND, "cube fail"); LogManager::instance().CubeLog(ch->GetPlayerID(), ch->GetX(), ch->GetY(), reward_value->vnum, 0, 0, 0); @@ -576,7 +576,7 @@ bool Cube_make (LPCHARACTER ch) } -// ť꿡 ִ ۵ ǥ +// 큐브에 있는 아이템들을 표시 void Cube_show_list (LPCHARACTER ch) { LPITEM *cube_item; @@ -597,13 +597,13 @@ void Cube_show_list (LPCHARACTER ch) } -// κ丮 ִ ť꿡 +// 인벤토리에 있는 아이템을 큐브에 등록 void Cube_add_item (LPCHARACTER ch, int cube_index, int inven_index) { - // ִ°? - // ť곻 ڸ ã - // ť꼼 - // ޽ + // 아이템이 있는가? + // 큐브내의 빈자리 찾기 + // 큐브세팅 + // 메시지 전송 LPITEM item; LPITEM *cube_item; @@ -620,7 +620,7 @@ void Cube_add_item (LPCHARACTER ch, int cube_index, int inven_index) cube_item = ch->GetCubeItem(); - // ̹ ٸġ ϵǾ ̸ indext + // 이미 다른위치에 등록되었던 아이템이면 기존 indext삭제 for (int i=0; iChatPacket(CHAT_TYPE_INFO, "cube[%d]: inventory[%d]: %s added", cube_index, inven_index, item->GetName()); - // ڿ ö ۵ ִ Ŭ̾Ʈ - // ϰ; ׳ ʿ 尡 + // 현재 상자에 올라온 아이템들로 무엇을 만들 수 있는지 클라이언트에 정보 전달 + // 을 하고싶었으나 그냥 필요한 골드가 얼마인지 전달 FN_update_cube_status(ch); return; } -// ť꿡ִ +// 큐브에있는 아이템을 제거 void Cube_delete_item (LPCHARACTER ch, int cube_index) { LPITEM item; @@ -664,14 +664,14 @@ void Cube_delete_item (LPCHARACTER ch, int cube_index) ch->ChatPacket(CHAT_TYPE_INFO, "cube[%d]: cube[%d]: %s deleted", cube_index, item->GetCell(), item->GetName()); - // ڿ ö ۵ ִ Ŭ̾Ʈ - // ϰ; ׳ ʿ 尡 + // 현재 상자에 올라온 아이템들로 무엇을 만들 수 있는지 클라이언트에 정보 전달 + // 을 하고싶었으나 그냥 필요한 골드가 얼마인지 전달 FN_update_cube_status(ch); return; } -// ̸ ؼ ̸ ȭ иϴ Լ (ְ+5 -> ְ, 5) +// 아이템 이름을 통해서 순수 이름과 강화레벨을 분리하는 함수 (무쌍검+5 -> 무쌍검, 5) SItemNameAndLevel SplitItemNameAndLevelFromName(const std::string& name) { int level = 0; @@ -705,7 +705,7 @@ bool FIsLessCubeValue(const CUBE_VALUE& a, const CUBE_VALUE& b) void Cube_MakeCubeInformationText() { - // ť Ŭ̾Ʈ ȯ. + // 이제 정리된 큐브 결과 및 재료들의 정보로 클라이언트에 보내 줄 정보로 변환함. for (TCubeMapByNPC::iterator iter = cube_info_map.begin(); cube_info_map.end() != iter; ++iter) { const DWORD& npcVNUM = iter->first; @@ -717,13 +717,13 @@ void Cube_MakeCubeInformationText() std::string& infoText = materialInfo.infoText; - // ̳ ۳̾ + // 이놈이 나쁜놈이야 if (0 < materialInfo.complicateMaterial.size()) { std::sort(materialInfo.complicateMaterial.begin(), materialInfo.complicateMaterial.end(), FIsLessCubeValue); std::sort(materialInfo.material.begin(), materialInfo.material.end(), FIsLessCubeValue); - //// ߺǴ + //// 중복되는 재료들을 지움 for (TCubeValueVector::iterator iter = materialInfo.complicateMaterial.begin(); materialInfo.complicateMaterial.end() != iter; ++iter) { for (TCubeValueVector::iterator targetIter = materialInfo.material.begin(); materialInfo.material.end() != targetIter; ++targetIter) @@ -735,7 +735,7 @@ void Cube_MakeCubeInformationText() } } - // 72723,1 or 72725,1 or ... ̷ ӵ Ű ؽƮ + // 72723,1 or 72725,1 or ... 이런 식의 약속된 포맷을 지키는 텍스트를 생성 for (TCubeValueVector::iterator iter = materialInfo.complicateMaterial.begin(); materialInfo.complicateMaterial.end() != iter; ++iter) { char tempBuffer[128]; @@ -750,7 +750,7 @@ void Cube_MakeCubeInformationText() infoText.push_back('&'); } - // ߺ ʴ Ϲ 鵵 + // 중복되지 않는 일반 재료들도 포맷 생성 for (TCubeValueVector::iterator iter = materialInfo.material.begin(); materialInfo.material.end() != iter; ++iter) { char tempBuffer[128]; @@ -760,7 +760,7 @@ void Cube_MakeCubeInformationText() infoText.erase(infoText.size() - 1); - // 尡 ʿϴٸ ߰ + // 만들 때 골드가 필요하다면 골드정보 추가 if (0 < materialInfo.gold) { char temp[128]; @@ -779,7 +779,7 @@ bool Cube_InformationInitialize() const std::vector& rewards = cubeData->reward; - // ϵڵ + // 하드코딩 ㅈㅅ if (1 != rewards.size()) { SPDLOG_ERROR("[CubeInfo] WARNING! Does not support multiple rewards (count: {})", rewards.size()); @@ -807,13 +807,13 @@ bool Cube_InformationInitialize() { SCubeMaterialInfo& existInfo = *iter; - // ̹ ߺǴ ϵǾ ִٸ ƿ ٸ , - // ε Ư κи Ʋ . - // Ư κи Ʋ ۵ Ʒó ϳ  ϳ ֱ : - // : - // ְ+5 ~ +9 x 1 - // Įڷ x1 - // x1 + // 이미 중복되는 보상이 등록되어 있다면 아예 다른 조합으로 만드는 것인지, + // 거의 같은 조합인데 특정 부분만 틀린 것인지 구분함. + // 예를들면 특정 부분만 틀린 아이템들은 아래처럼 하나로 묶어서 하나의 결과로 보여주기 위함임: + // 용신지검: + // 무쌍검+5 ~ +9 x 1 + // 붉은 칼자루 조각 x1 + // 녹색 검장식 조각 x1 if (reward.vnum == existInfo.reward.vnum) { for (TCubeValueVector::iterator existMaterialIter = existInfo.material.begin(); existInfo.material.end() != existMaterialIter; ++existMaterialIter) @@ -828,8 +828,8 @@ bool Cube_InformationInitialize() if (0 < existItemInfo.level) { - // ߰ϴ ť , ϵǾִ ť - // ߺǴ κ ִ ˻Ѵ + // 지금 추가하는 큐브 결과물의 재료와, 기존에 등록되어있던 큐브 결과물의 재료 중 + // 중복되는 부분이 있는지 검색한다 for (TCubeValueVector::iterator currentMaterialIter = materialInfo.material.begin(); materialInfo.material.end() != currentMaterialIter; ++currentMaterialIter) { TItemTable* currentMaterialProto = ITEM_MANAGER::Instance().GetTable(currentMaterialIter->vnum); @@ -845,7 +845,7 @@ bool Cube_InformationInitialize() //currentMaterialIter = materialInfo.material.erase(currentMaterialIter); - // TODO: ߺǴ ̻ ؾ + // TODO: 중복되는 아이템 두 개 이상 검출해야 될 수도 있음 break; } } // for currentMaterialIter @@ -865,7 +865,7 @@ bool Cube_InformationInitialize() return true; } -// Ŭ̾Ʈ : NPC ִ ۵ () û +// 클라이언트에서 서버로 : 현재 NPC가 만들 수 있는 아이템들의 정보(목록)를 요청 void Cube_request_result_list(LPCHARACTER ch) { RETURN_IF_CUBE_IS_NOT_OPENED(ch); @@ -879,7 +879,7 @@ void Cube_request_result_list(LPCHARACTER ch) std::string& resultText = cube_result_info_map_by_npc[npcVNUM]; - // ش NPC ִ ٸ ijø + // 해당 NPC가 만들 수 있는 목록이 정리된 게 없다면 캐시를 생성 if (resultText.length() == 0) { resultText.clear(); @@ -898,7 +898,7 @@ void Cube_request_result_list(LPCHARACTER ch) resultText.erase(resultText.size() - 1); - // ä Ŷ Ѱ踦 Ѿ ... ȹ е ش޶ ûϰų, ߿ ٸ ٲٰų... + // 채팅 패킷의 한계를 넘어가면 에러 남김... 기획자 분들 께 조정해달라고 요청하거나, 나중에 다른 방식으로 바꾸거나... if (resultText.size() - 20 >= CHAT_MAX_LEN) { SPDLOG_ERROR("[CubeInfo] Too long cube result list text. (NPC: {}, length: {})", npcVNUM, resultText.size()); @@ -908,7 +908,7 @@ void Cube_request_result_list(LPCHARACTER ch) } - // NPC ִ ۵ Ʒ Ѵ. + // 현재 NPC가 만들 수 있는 아이템들의 목록을 아래 포맷으로 전송한다. // (Server -> Client) /cube r_list npcVNUM resultCount vnum1,count1/vnum2,count2,/vnum3,count3/... // (Server -> Client) /cube r_list 20383 4 123,1/125,1/128,1/130,5 diff --git a/src/game/src/db.cpp b/src/game/src/db.cpp index d759690..79e06e1 100644 --- a/src/game/src/db.cpp +++ b/src/game/src/db.cpp @@ -399,7 +399,7 @@ void DBManager::FlushBilling(bool bForce) void DBManager::CheckBilling() { std::vector vec; - vec.push_back(0); // īƮ ̸ д. + vec.push_back(0); // 카운트를 위해 미리 비워둔다. itertype(m_map_pkLoginData) it = m_map_pkLoginData.begin(); @@ -414,7 +414,7 @@ void DBManager::CheckBilling() } } - vec[0] = vec.size() - 1; //  ִ´, ڽ ؾ ϹǷ -1 + vec[0] = vec.size() - 1; // 비워둔 곳에 사이즈를 넣는다, 사이즈 자신은 제외해야 하므로 -1 db_clientdesc->DBPacket(HEADER_GD_BILLING_CHECK, 0, &vec[0], sizeof(DWORD) * vec.size()); } @@ -632,7 +632,7 @@ void DBManager::AnalyzeReturnQuery(SQLMsg * pMsg) M2_DELETE(pinfo); break; } - //ġ - By SeMinZ + //위치 변경 - By SeMinZ d->SetLogin(pinfo->login); SPDLOG_DEBUG("QID_AUTH_LOGIN: START {} {}", qi->dwIdent, (void*) get_pointer(d)); @@ -758,7 +758,7 @@ void DBManager::AnalyzeReturnQuery(SQLMsg * pMsg) if (true == LC_IsBrazil()) { - nPasswordDiff = 0; // йȣ üũ ʴ´. + nPasswordDiff = 0; // 브라질 버전에서는 비밀번호 체크를 하지 않는다. } if (nPasswordDiff) @@ -789,7 +789,7 @@ void DBManager::AnalyzeReturnQuery(SQLMsg * pMsg) { if (LC_IsEurope()) { - //stBlockData >= 0 == ¥ BlockDate ̷ + //stBlockData >= 0 == 날짜가 BlockDate 보다 미래 if (strncmp(szCreateDate, g_stBlockDate.c_str(), 8) >= 0) { LoginFailure(d, "BLKLOGIN"); @@ -1315,7 +1315,7 @@ enum EAccountQID QID_SPAM_DB, }; -// 10и ε +// 10분마다 리로드 static LPEVENT s_pkReloadSpamEvent = NULL; EVENTINFO(reload_spam_event_info) diff --git a/src/game/src/desc.cpp b/src/game/src/desc.cpp index 5102f73..f11b90b 100644 --- a/src/game/src/desc.cpp +++ b/src/game/src/desc.cpp @@ -318,12 +318,12 @@ void DESC::Packet(const void * c_pvData, int iSize) { assert(iSize > 0); - if (m_iPhase == PHASE_CLOSE) // ¸ ʴ´. + if (m_iPhase == PHASE_CLOSE) // 끊는 상태면 보내지 않는다. return; if (m_stRelayName.length() != 0) { - // Relay Ŷ ȣȭ ʴ´. + // Relay 패킷은 암호화하지 않는다. TPacketGGRelay p; p.bHeader = HEADER_GG_RELAY; @@ -369,7 +369,7 @@ void DESC::SetPhase(int _phase) switch (m_iPhase) { case PHASE_CLOSE: - // ޽ ijʹ Ǹ鼭 + // 메신저가 캐릭터단위가 되면서 삭제 //MessengerManager::instance().Logout(GetAccountTable().login); m_pInputProcessor = &m_inputClose; break; @@ -379,8 +379,8 @@ void DESC::SetPhase(int _phase) break; case PHASE_SELECT: - // ޽ ijʹ Ǹ鼭 - //MessengerManager::instance().Logout(GetAccountTable().login); // ǵ break Ȱ + // 메신저가 캐릭터단위가 되면서 삭제 + //MessengerManager::instance().Logout(GetAccountTable().login); // 의도적으로 break 안검 case PHASE_LOGIN: case PHASE_LOADING: m_pInputProcessor = &m_inputLogin; diff --git a/src/game/src/desc_client.cpp b/src/game/src/desc_client.cpp index 59016bc..0edb14b 100644 --- a/src/game/src/desc_client.cpp +++ b/src/game/src/desc_client.cpp @@ -97,7 +97,7 @@ bool CLIENT_DESC::Connect(int iPhaseWhenSucceed) if (iPhaseWhenSucceed != 0) m_iPhaseWhenSucceed = iPhaseWhenSucceed; - if (get_global_time() - m_LastTryToConnectTime < 3) // 3 + if (get_global_time() - m_LastTryToConnectTime < 3) // 3초 return false; m_LastTryToConnectTime = get_global_time(); @@ -220,7 +220,7 @@ void CLIENT_DESC::SetPhase(int iPhase) SPDLOG_DEBUG("DB_SETUP current user {} size {}", p.dwLoginCount, buf.size()); - // Ƽ ó ְ . + // 파티를 처리할 수 있게 됨. CPartyManager::instance().EnablePCParty(); //CPartyManager::instance().SendPartyToDB(); } @@ -301,7 +301,7 @@ void CLIENT_DESC::Update(DWORD t) void CLIENT_DESC::UpdateChannelStatus(DWORD t, bool fForce) { enum { - CHANNELSTATUS_UPDATE_PERIOD = 5*60*1000, // 5и + CHANNELSTATUS_UPDATE_PERIOD = 5*60*1000, // 5분마다 }; if (fForce || m_tLastChannelStatusUpdateTime+CHANNELSTATUS_UPDATE_PERIOD < t) { int iTotal; diff --git a/src/game/src/desc_manager.cpp b/src/game/src/desc_manager.cpp index 30d11bb..ff91c05 100644 --- a/src/game/src/desc_manager.cpp +++ b/src/game/src/desc_manager.cpp @@ -53,7 +53,7 @@ int IsValidIP(struct valid_ip* ip_table, const char *host) DESC_MANAGER::DESC_MANAGER() : m_bDestroyed(false) { Initialize(); - //NOTE : Destroy Initialize θ° ̳..-_-; + //NOTE : Destroy 끝에서 Initialize 를 부르는건 또 무슨 짓이냐..-_-; 정말 m_pPackageCrypt = new CClientPackageCryptInfo; } @@ -146,7 +146,7 @@ RETRY: LPDESC DESC_MANAGER::AcceptDesc(evconnlistener* listener, evutil_socket_t fd, sockaddr* address) { - if (!IsValidIP(admin_ip, GetSocketHost(address).c_str())) // admin_ip ϵ IP ִ ֹ ʴ´. + if (!IsValidIP(admin_ip, GetSocketHost(address).c_str())) // admin_ip 에 등록된 IP 는 최대 사용자 수에 구애받지 않는다. { if (m_iSocketsConnected >= MAX_ALLOW_USER) { diff --git a/src/game/src/dragon_soul_table.cpp b/src/game/src/dragon_soul_table.cpp index e9909e3..2fd7510 100644 --- a/src/game/src/dragon_soul_table.cpp +++ b/src/game/src/dragon_soul_table.cpp @@ -172,7 +172,7 @@ bool DragonSoulTable::ReadBasicApplys() TVecApplys vecApplys; int n = pChild->GetRowCount(); - // BasicApply Group Key 1 . + // BasicApply Group은 Key가 1부터 시작함. for (int j = 1; j <= n; j++) { std::stringstream ss; @@ -655,7 +655,7 @@ bool DragonSoulTable::GetWeight(BYTE ds_type, BYTE grade_idx, BYTE step_index, B return true; } } - // default group 캽. + // default group을 살펴봄. pDragonSoulGroup = m_pWeightTableNode->GetChildNode("default"); if (NULL != pDragonSoulGroup) { diff --git a/src/game/src/dungeon.cpp b/src/game/src/dungeon.cpp index 00e2a79..c98c806 100644 --- a/src/game/src/dungeon.cpp +++ b/src/game/src/dungeon.cpp @@ -1122,7 +1122,7 @@ struct FExitDungeonToStartPosition { PIXEL_POSITION posWarp; - // ε ִ ƴ϶ ϴ ε ִ´. + // 현재 맵 인덱스를 넣는 것이 아니라 시작하는 맵 인덱스를 넣는다. if (SECTREE_MANAGER::instance().GetRecallPositionByEmpire(g_start_map[ch->GetEmpire()], ch->GetEmpire(), posWarp)) ch->WarpSet(posWarp.x, posWarp.y); else @@ -1272,7 +1272,7 @@ void CDungeon::JumpToEliminateLocation() } else { - // Ϲ + // 일반 맵으로 워프 LPSECTREE_MAP pMap = SECTREE_MANAGER::instance().GetMap(m_lMapIndex); if (!pMap) diff --git a/src/game/src/entity.cpp b/src/game/src/entity.cpp index 75af760..0e874e0 100644 --- a/src/game/src/entity.cpp +++ b/src/game/src/entity.cpp @@ -97,7 +97,7 @@ void CEntity::PacketView(const void * data, int bytes, LPENTITY except) FuncPacketView f(data, bytes, except); - // ¿ Ŷ ޴´. + // 옵저버 상태에선 내 패킷은 나만 받는다. if (!m_bIsObserver) for_each(m_map_view.begin(), m_map_view.end(), f); diff --git a/src/game/src/entity_view.cpp b/src/game/src/entity_view.cpp index 2e3a0fa..d366b57 100644 --- a/src/game/src/entity_view.cpp +++ b/src/game/src/entity_view.cpp @@ -98,21 +98,21 @@ class CFuncViewInsert void operator () (LPENTITY ent) { - // Ʈ ƴ Ÿ Ͽ Ÿ ָ ߰ ʴ´. + // 오브젝트가 아닌 것은 거리를 계산하여 거리가 멀면 추가하지 않는다. if (!ent->IsType(ENTITY_OBJECT)) if (DISTANCE_APPROX(ent->GetX() - m_me->GetX(), ent->GetY() - m_me->GetY()) > dwViewRange) return; - // ߰ + // 나를 대상에 추가 m_me->ViewInsert(ent); - // Ѵ ij͸ + // 둘다 캐릭터면 if (ent->IsType(ENTITY_CHARACTER) && m_me->IsType(ENTITY_CHARACTER)) { LPCHARACTER chMe = (LPCHARACTER) m_me; LPCHARACTER chEnt = (LPCHARACTER) ent; - // NPC StateMachine Ų. + // 대상이 NPC면 StateMachine을 킨다. if (chMe->IsPC() && !chEnt->IsPC() && !chEnt->IsWarp() && !chEnt->IsGoto()) chEnt->StartStateMachine(); } @@ -134,13 +134,13 @@ void CEntity::UpdateSectree() ++m_iViewAge; - CFuncViewInsert f(this); // Ʈ ִ 鿡 ߰ + CFuncViewInsert f(this); // 나를 섹트리에 있는 사람들에게 추가 GetSectree()->ForEachAround(f); ENTITY_MAP::iterator it, this_it; // - // m_map_view ʿ ༮ + // m_map_view에서 필요 없는 녀석들 지우기 // if (m_bObserverModeChange) { @@ -155,11 +155,11 @@ void CEntity::UpdateSectree() { LPENTITY ent = this_it->first; - // . + // 나로 부터 상대방을 지운다. ent->EncodeRemovePacket(this); m_map_view.erase(this_it); - // . + // 상대로 부터 나를 지운다. ent->ViewRemove(this, false); } else @@ -167,11 +167,11 @@ void CEntity::UpdateSectree() LPENTITY ent = this_it->first; - // . + // 나로 부터 상대방을 지운다. //ent->EncodeRemovePacket(this); //m_map_view.erase(this_it); - // . + // 상대로 부터 나를 지운다. //ent->ViewRemove(this, false); EncodeRemovePacket(ent); } @@ -189,11 +189,11 @@ void CEntity::UpdateSectree() { LPENTITY ent = this_it->first; - // . + // 나로 부터 상대방을 지운다. ent->EncodeRemovePacket(this); m_map_view.erase(this_it); - // . + // 상대로 부터 나를 지운다. ent->ViewRemove(this, false); } else @@ -223,11 +223,11 @@ void CEntity::UpdateSectree() { LPENTITY ent = this_it->first; - // . + // 나로 부터 상대방을 지운다. ent->EncodeRemovePacket(this); m_map_view.erase(this_it); - // . + // 상대로 부터 나를 지운다. ent->ViewRemove(this, false); } } diff --git a/src/game/src/event.cpp b/src/game/src/event.cpp index 880b4d5..9b08dd2 100644 --- a/src/game/src/event.cpp +++ b/src/game/src/event.cpp @@ -1,8 +1,8 @@ /* * Filename: event.c - * Description: ̺Ʈ (timed event) + * Description: 이벤트 관련 (timed event) * - * Author: (aka. , Cronan), ۿ (aka. myevan, ڷ) + * Author: 김한주 (aka. 비엽, Cronan), 송영진 (aka. myevan, 빗자루) */ #include "stdafx.h" @@ -18,12 +18,12 @@ static ObjectPool event_pool; static CEventQueue cxx_q; -/* ̺Ʈ ϰ Ѵ */ +/* 이벤트를 생성하고 리턴한다 */ LPEVENT event_create_ex(TEVENTFUNC func, event_info_data* info, int when) { LPEVENT new_event = NULL; - /* ݵ pulse ̻ ð Ŀ θ Ѵ. */ + /* 반드시 다음 pulse 이상의 시간이 지난 후에 부르도록 한다. */ if (when < 1) when = 1; @@ -44,7 +44,7 @@ LPEVENT event_create_ex(TEVENTFUNC func, event_info_data* info, int when) return (new_event); } -/* ý ̺Ʈ Ѵ */ +/* 시스템으로 부터 이벤트를 제거한다 */ void event_cancel(LPEVENT * ppevent) { LPEVENT event; @@ -69,7 +69,7 @@ void event_cancel(LPEVENT * ppevent) return; } - // ̹ Ǿ°? + // 이미 취소 되었는가? if (!event->q_el) { *ppevent = NULL; @@ -98,14 +98,14 @@ void event_reset_time(LPEVENT event, int when) } } -/* ̺Ʈ ð ̺Ʈ Ѵ */ +/* 이벤트를 실행할 시간에 도달한 이벤트들을 실행한다 */ int event_process(int pulse) { int new_time; int num_events = 0; - // event_q ̺Ʈ ť ð pulse - // ʰ ȴ. + // event_q 즉 이벤트 큐의 헤드의 시간보다 현재의 pulse 가 적으면 루프문이 + // 돌지 않게 된다. while (pulse >= cxx_q.GetTopKey()) { TQueueElement * pElem = cxx_q.Dequeue(); @@ -123,9 +123,9 @@ int event_process(int pulse) cxx_q.Delete(pElem); /* - * ο ð̸ 0 Ŭ ̺Ʈ ٽ ߰Ѵ. - * 0 ̻ event Ҵ ޸ ʵ - * Ѵ. + * 리턴 값은 새로운 시간이며 리턴 값이 0 보다 클 경우 이벤트를 다시 추가한다. + * 리턴 값을 0 이상으로 할 경우 event 에 할당된 메모리 정보를 삭제하지 않도록 + * 주의한다. */ the_event->is_processing = true; @@ -155,7 +155,7 @@ int event_process(int pulse) return num_events; } -/* ̺Ʈ ð pulse ش */ +/* 이벤트가 수행시간을 pulse 단위로 리턴해 준다 */ int event_processing_time(LPEVENT event) { int start_time; @@ -167,7 +167,7 @@ int event_processing_time(LPEVENT event) return (thecore_heart->pulse - start_time); } -/* ̺Ʈ ð pulse ش */ +/* 이벤트가 남은 시간을 pulse 단위로 리턴해 준다 */ int event_time(LPEVENT event) { int when; @@ -179,7 +179,7 @@ int event_time(LPEVENT event) return (when - thecore_heart->pulse); } -/* ̺Ʈ Ѵ */ +/* 모든 이벤트를 제거한다 */ void event_destroy(void) { TQueueElement * pElem; diff --git a/src/game/src/event_queue.cpp b/src/game/src/event_queue.cpp index e0f88eb..2f7a391 100644 --- a/src/game/src/event_queue.cpp +++ b/src/game/src/event_queue.cpp @@ -1,8 +1,8 @@ /* * Filename: queue.c - * Description: ť ó + * Description: 큐 처리 * - * Author: (aka. , Cronan), ۿ (aka. myevan, ڷ) + * Author: 김한주 (aka. 비엽, Cronan), 송영진 (aka. myevan, 빗자루) */ #include "stdafx.h" diff --git a/src/game/src/exchange.cpp b/src/game/src/exchange.cpp index 8fccdb0..6b5a2b7 100644 --- a/src/game/src/exchange.cpp +++ b/src/game/src/exchange.cpp @@ -16,7 +16,7 @@ void exchange_packet(LPCHARACTER ch, BYTE sub_header, bool is_me, DWORD arg1, TItemPos arg2, DWORD arg3, void * pvData = NULL); -// ȯ Ŷ +// 교환 패킷 void exchange_packet(LPCHARACTER ch, BYTE sub_header, bool is_me, DWORD arg1, TItemPos arg2, DWORD arg3, void * pvData) { if (!ch->GetDesc()) @@ -45,10 +45,10 @@ void exchange_packet(LPCHARACTER ch, BYTE sub_header, bool is_me, DWORD arg1, TI ch->GetDesc()->Packet(&pack_exchg, sizeof(pack_exchg)); } -// ȯ +// 교환을 시작 bool CHARACTER::ExchangeStart(LPCHARACTER victim) { - if (this == victim) // ڱ ڽŰ ȯ Ѵ. + if (this == victim) // 자기 자신과는 교환을 못한다. return false; if (IsObserverMode()) @@ -75,7 +75,7 @@ bool CHARACTER::ExchangeStart(LPCHARACTER victim) //END_PREVENT_TRADE_WINDOW int iDist = DISTANCE_APPROX(GetX() - victim->GetX(), GetY() - victim->GetY()); - // Ÿ üũ + // 거리 체크 if (iDist >= EXCHANGE_MAX_DISTANCE) return false; @@ -143,7 +143,7 @@ bool CExchange::AddItem(TItemPos item_pos, BYTE display_pos) if (!item_pos.IsValidItemPosition()) return false; - // ȯ + // 장비는 교환할 수 없음 if (item_pos.IsEquipPosition()) return false; @@ -163,7 +163,7 @@ bool CExchange::AddItem(TItemPos item_pos, BYTE display_pos) return false; } - // ̹ ȯâ ߰ ΰ? + // 이미 교환창에 추가된 아이템인가? if (item->IsExchanging()) { SPDLOG_DEBUG("EXCHANGE under exchanging"); @@ -212,7 +212,7 @@ bool CExchange::AddItem(TItemPos item_pos, BYTE display_pos) return true; } - // ߰ + // 추가할 공간이 없음 return false; } @@ -248,7 +248,7 @@ bool CExchange::AddGold(int gold) if (GetOwner()->GetGold() < gold) { - // ִ . + // 가지고 있는 돈이 부족. exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_LESS_GOLD, 0, 0, NPOS, 0); return false; } @@ -271,7 +271,7 @@ bool CExchange::AddGold(int gold) return true; } -// ִ, ȯϷ ִ Ȯ Ѵ. +// 돈이 충분히 있는지, 교환하려는 아이템이 실제로 있는지 확인 한다. bool CExchange::Check(int * piItemCount) { if (GetOwner()->GetGold() < m_lGold) @@ -325,10 +325,10 @@ bool CExchange::CheckSpace() s_grid2.Put(i - INVENTORY_MAX_NUM / 2, 1, item->GetSize()); } - // ... ... ȥ κ κ ߸̴ Ф + // 아... 뭔가 개병신 같지만... 용혼석 인벤을 노멀 인벤 보고 따라 만든 내 잘못이다 ㅠㅠ static std::vector s_vDSGrid(DRAGON_SOUL_INVENTORY_MAX_NUM); - // ϴ ȥ ȯ ɼ ũǷ, ȥ κ ȥ ϵ Ѵ. + // 일단 용혼석을 교환하지 않을 가능성이 크므로, 용혼석 인벤 복사는 용혼석이 있을 때 하도록 한다. bool bDSInitialized = false; for (i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i) @@ -411,7 +411,7 @@ bool CExchange::CheckSpace() return true; } -// ȯ (۰ ű) +// 교환 끝 (아이템과 돈 등을 실제로 옮긴다) bool CExchange::Done() { int empty_pos, i; @@ -493,7 +493,7 @@ bool CExchange::Done() return true; } -// ȯ +// 교환을 동의 bool CExchange::Accept(bool bAccept) { if (m_bAccept == bAccept) @@ -501,7 +501,7 @@ bool CExchange::Accept(bool bAccept) m_bAccept = bAccept; - // Ƿ ȯ + // 둘 다 동의 했으므로 교환 성립 if (m_bAccept && GetCompany()->m_bAccept) { int iItemCount; @@ -513,9 +513,9 @@ bool CExchange::Accept(bool bAccept) victim->SetExchangeTime(); //END_PREVENT_PORTAL_AFTER_EXCHANGE - // exchange_check ȯ ۵ ڸ ֳ Ȯϰ, - // ũ ֳ ȮѴ, ι° ڷ ȯ - // Ѵ. + // exchange_check 에서는 교환할 아이템들이 제자리에 있나 확인하고, + // 엘크도 충분히 있나 확인한다, 두번째 인자로 교환할 아이템 개수 + // 를 리턴한다. if (!Check(&iItemCount)) { GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB5\xB7\xC0\xCC \xBA\xCE\xC1\xB7\xC7\xCF\xB0\xC5\xB3\xAA \xBE\xC6\xC0\xCC\xC5\xDB\xC0\xCC \xC1\xA6\xC0\xDA\xB8\xAE\xBF\xA1 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9.")); @@ -523,7 +523,7 @@ bool CExchange::Accept(bool bAccept) goto EXCHANGE_END; } - // ǰ ڸ ֳ ȮѴ. + // 리턴 받은 아이템 개수로 상대방의 소지품에 남은 자리가 있나 확인한다. if (!CheckSpace()) { GetOwner()->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xBB\xF3\xB4\xEB\xB9\xE6\xC0\xC7 \xBC\xD2\xC1\xF6\xC7\xB0\xBF\xA1 \xBA\xF3 \xB0\xF8\xB0\xA3\xC0\xCC \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9.")); @@ -531,7 +531,7 @@ bool CExchange::Accept(bool bAccept) goto EXCHANGE_END; } - // 浵 .. + // 상대방도 마찬가지로.. if (!GetCompany()->Check(&iItemCount)) { victim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB5\xB7\xC0\xCC \xBA\xCE\xC1\xB7\xC7\xCF\xB0\xC5\xB3\xAA \xBE\xC6\xC0\xCC\xC5\xDB\xC0\xCC \xC1\xA6\xC0\xDA\xB8\xAE\xBF\xA1 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9.")); @@ -556,12 +556,12 @@ bool CExchange::Accept(bool bAccept) if (Done()) { - if (m_lGold) // ?? + if (m_lGold) // 돈이 있을 ??만 저장 GetOwner()->Save(); if (GetCompany()->Done()) { - if (GetCompany()->m_lGold) // + if (GetCompany()->m_lGold) // 돈이 있을 때만 저장 victim->Save(); // INTERNATIONAL_VERSION @@ -577,14 +577,14 @@ EXCHANGE_END: } else { - // ƴϸ accept Ŷ . + // 아니면 accept에 대한 패킷을 보내자. exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_ACCEPT, true, m_bAccept, NPOS, 0); exchange_packet(GetCompany()->GetOwner(), EXCHANGE_SUBHEADER_GC_ACCEPT, false, m_bAccept, NPOS, 0); return true; } } -// ȯ +// 교환 취소 void CExchange::Cancel() { exchange_packet(GetOwner(), EXCHANGE_SUBHEADER_GC_END, 0, 0, NPOS, 0); diff --git a/src/game/src/file_loader.cpp b/src/game/src/file_loader.cpp index 0e51cda..17fdde0 100644 --- a/src/game/src/file_loader.cpp +++ b/src/game/src/file_loader.cpp @@ -48,7 +48,7 @@ bool CMemoryTextFileLoader::SplitLine(DWORD dwLine, std::vector* ps pstTokenVector->push_back(c_rstLine.substr(beginPos, endPos - beginPos)); - // ߰ ڵ. ǵڿ ִ 츦 üũѴ. - [levites] + // 추가 코드. 맨뒤에 탭이 있는 경우를 체크한다. - [levites] if (int(c_rstLine.find_first_not_of(c_szDelimeter, basePos)) < 0) break; } while (basePos < c_rstLine.length()); diff --git a/src/game/src/fishing.cpp b/src/game/src/fishing.cpp index f636bc8..e266406 100644 --- a/src/game/src/fishing.cpp +++ b/src/game/src/fishing.cpp @@ -205,7 +205,7 @@ void Initialize() { SendLog("error! cannot open fishing.txt"); - // ̸ Ѵ. + // 백업에 이름이 있으면 리스토어 한다. if (*fish_info_bak[0].name) { memcpy(fish_info, fish_info_bak, sizeof(fish_info)); @@ -313,7 +313,7 @@ void Initialize() fish_info[i].length_range[2]); } - // Ȯ + // 확률 계산 for (int j = 0; j < MAX_PROB; ++j) { g_prob_accumulate[j][0] = fish_info[0].prob[j]; @@ -366,7 +366,7 @@ int DetermineFish(LPCHARACTER ch) // ADD_PREMIUM if (ch->GetPremiumRemainSeconds(PREMIUM_FISH_MIND) > 0 || - ch->IsEquipUniqueGroup(UNIQUE_GROUP_FISH_MIND)) // Ȯ + ch->IsEquipUniqueGroup(UNIQUE_GROUP_FISH_MIND)) // 월간어심 착용시 고급 물고기 확률 상승 { if (quest::CQuestManager::instance().GetEventFlag("manwoo") != 0) prob_idx = 3; @@ -394,7 +394,7 @@ int DetermineFish(LPCHARACTER ch) return 0; } - if (g_iUseLocale) // ߱ ݵ, ݿ, ʰ + if (g_iUseLocale) // 중국에서는 금덩어리, 금열쇠, 은열쇠 나오지 않게 함 { DWORD vnum = fish_info[fish_idx].vnum; @@ -437,7 +437,7 @@ void FishingPractice(LPCHARACTER ch) LPITEM rod = ch->GetWear(WEAR_WEAPON); if (rod && rod->GetType() == ITEM_ROD) { - // ִ õ ƴ ô + // 최대 수련도가 아닌 경우 낚시대 수련 if ( rod->GetRefinedVnum()>0 && rod->GetSocket(0) < rod->GetValue(2) && Random::get(1,rod->GetValue(1))==1 ) { rod->SetSocket(0, rod->GetSocket(0) + 1); @@ -449,14 +449,14 @@ void FishingPractice(LPCHARACTER ch) } } } - // ̳ + // 미끼를 뺀다 rod->SetSocket(2, 0); } bool PredictFish(LPCHARACTER ch) { // ADD_PREMIUM - // ȯ + // 어심환 if (ch->FindAffect(AFFECT_FISH_MIND_PILL) || ch->GetPremiumRemainSeconds(PREMIUM_FISH_MIND) > 0 || ch->IsEquipUniqueGroup(UNIQUE_GROUP_FISH_MIND)) @@ -491,7 +491,7 @@ EVENTFUNC(fishing_event) switch (info->step) { - case 0: // 鸮 Ǵ 丸 ư + case 0: // 흔들리기 또는 떡밥만 날아감 ++info->step; //info->ch->Motion(MOTION_FISHING_SIGN); @@ -600,7 +600,7 @@ int GetFishLength(int fish_id) void Take(fishing_event_info* info, LPCHARACTER ch) { - if (info->step == 1) // Ⱑ ɸ ¸.. + if (info->step == 1) // 고기가 걸린 상태면.. { int ms = (int) ((get_dword_time() - info->hang_time)); DWORD item_vnum = 0; @@ -611,9 +611,9 @@ void Take(fishing_event_info* info, LPCHARACTER ch) switch (ret) { - case -2: // - case -3: // ̵ - case -1: // ð Ȯ + case -2: // 잡히지 않은 경우 + case -3: // 난이도 때문에 실패 + case -1: // 시간 확률 때문에 실패 //ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB0\xED\xB1\xE2\xB0\xA1 \xB9\xCC\xB3\xA2\xB8\xB8 \xBB\xA9\xB8\xD4\xB0\xED \xC0\xEC\xBD\xCE\xB0\xD4 \xB5\xB5\xB8\xC1\xC4\xA8\xB4\xCF\xB4\xD9.")); { int map_idx = ch->GetMapIndex(); @@ -652,7 +652,7 @@ void Take(fishing_event_info* info, LPCHARACTER ch) if (quest::CQuestManager::instance().GetEventFlag("fishevent") > 0 && (info->fish_id == 5 || info->fish_id == 6)) { - // ̺Ʈ ̹Ƿ Ѵ. + // 이벤트 중이므로 기록한다. TPacketGDHighscore p; p.dwPID = ch->GetPlayerID(); @@ -758,7 +758,7 @@ void UseFish(LPCHARACTER ch, LPITEM item) { int idx = item->GetVnum() - fish_info[2].vnum+2; - // Ƕ Ұ, ִ° ƴѰ Ұ + // 피라미 사용불가, 살아있는게 아닌건 사용불가 if (idx<=1 || idx >= MAX_FISH) return; @@ -769,12 +769,12 @@ void UseFish(LPCHARACTER ch, LPITEM item) if (r >= 4001) { - // + // 죽은 물고기 ch->AutoGiveItem(fish_info[idx].dead_vnum); } else if (r >= 2001) { - // + // 생선뼈 ch->AutoGiveItem(FISH_BONE_VNUM); } else @@ -878,14 +878,14 @@ int RealRefineRod(LPCHARACTER ch, LPITEM item) if (pkNewItem) { BYTE bCell = rod->GetCell(); - // ô + // 낚시대 개량 성공 ITEM_MANAGER::instance().RemoveItem(rod, "REMOVE (REFINE FISH_ROD)"); pkNewItem->AddToCharacter(ch, TItemPos (INVENTORY, bCell)); LogManager::instance().ItemLog(ch, pkNewItem, "REFINE FISH_ROD SUCCESS", pkNewItem->GetName()); return 1; } - // ô + // 낚시대 개량 실패 return 2; } else @@ -896,14 +896,14 @@ int RealRefineRod(LPCHARACTER ch, LPITEM item) if (pkNewItem) { BYTE bCell = rod->GetCell(); - // ô + // 낚시대 개량에 성공 ITEM_MANAGER::instance().RemoveItem(rod, "REMOVE (REFINE FISH_ROD)"); pkNewItem->AddToCharacter(ch, TItemPos(INVENTORY, bCell)); LogManager::instance().ItemLog(ch, pkNewItem, "REFINE FISH_ROD FAIL", pkNewItem->GetName()); return 0; } - // ô + // 낚시대 개량 실패 return 2; } } diff --git a/src/game/src/gm.cpp b/src/game/src/gm.cpp index dea53b2..68d0499 100644 --- a/src/game/src/gm.cpp +++ b/src/game/src/gm.cpp @@ -65,7 +65,7 @@ BYTE gm_new_get_level( const char * name, const char * host, const char* account return GM_PLAYER; // GERMAN_GM_NOT_CHECK_HOST - // ȣƮ üũ ʴ´. + // 독일 버전은 호스트 체크를 하지 않는다. if ( LC_IsEurope() && !LC_IsTaiwan() || LC_IsSingapore() ) { if (account) diff --git a/src/game/src/group_text_parse_tree.cpp b/src/game/src/group_text_parse_tree.cpp index c55da8d..36c9a52 100644 --- a/src/game/src/group_text_parse_tree.cpp +++ b/src/game/src/group_text_parse_tree.cpp @@ -200,7 +200,7 @@ bool CGroupNode::GetRow(const std::string & c_rstrRowKey, OUT const CGroupNode:: return true; } -// , idx txt . +// 참고로, idx랑 txt에 쓰여진 순서랑 관계 없음. bool CGroupNode::GetRow(int idx, OUT const CGroupNode::CGroupNodeRow ** ppRow) const { if (idx >= m_map_rows.size()) @@ -223,7 +223,7 @@ bool CGroupNode::GetGroupRow(const std::string& stGroupName, const std::string& if (pChildGroup->GetRow(stRow, ppRow)) return true; } - // default group 캽. + // default group을 살펴봄. pChildGroup = GetChildNode("default"); if (NULL != pChildGroup) { diff --git a/src/game/src/guild.cpp b/src/game/src/guild.cpp index c08bf83..64d5afc 100644 --- a/src/game/src/guild.cpp +++ b/src/game/src/guild.cpp @@ -418,7 +418,7 @@ void CGuild::SendListPacket(LPCHARACTER ch) Count (byte) [ ... - name_flag 1 - ̸ Ⱥ + name_flag 1 - 이름을 보내느냐 안보내느냐 name CHARACTER_NAME_MAX_LEN+1 ] * Count @@ -560,7 +560,7 @@ void CGuild::LoadGuildMemberData(SQLMsg* pmsg) void CGuild::LoadGuildGradeData(SQLMsg* pmsg) { /* - // 15 ƴ ɼ + // 15개 아닐 가능성 존재 if (pmsg->Get()->iNumRows != 15) { SPDLOG_ERROR("Query failed: getting guild grade data. GuildID({})", GetID()); @@ -698,7 +698,7 @@ void CGuild::__P2PUpdateGrade(SQLMsg* pmsg) grade--; - // Ī ٸٸ Ʈ + // 등급 명칭이 현재와 다르다면 업데이트 if (0 != strcmp(m_data.grade_array[grade].grade_name, name)) { strlcpy(m_data.grade_array[grade].grade_name, name, sizeof(m_data.grade_array[grade].grade_name)); @@ -1084,7 +1084,7 @@ void CGuild::RefreshCommentForce(DWORD player_id) d->RawPacket(szName, sizeof(szName)); if (i == pmsg->Get()->uiNumRows - 1) - d->Packet(szContent, sizeof(szContent)); // ̸ + d->Packet(szContent, sizeof(szContent)); // 마지막 줄이면 보내기 else d->RawPacket(szContent, sizeof(szContent)); } @@ -1263,7 +1263,7 @@ void CGuild::UseSkill(DWORD dwVnum, LPCHARACTER ch, DWORD pid) if ((pkSk->dwFlag & SKILL_FLAG_SELFONLY)) { - // ̹ ɷ Ƿ . + // 이미 걸려 있으므로 사용하지 않음. if (ch->FindAffect(pkSk->dwVnum)) return; @@ -1315,7 +1315,7 @@ void CGuild::UseSkill(DWORD dwVnum, LPCHARACTER ch, DWORD pid) switch (dwVnum) { case GUILD_SKILL_TELEPORT: - // ִ õ. + // 현재 서버에 있는 사람을 먼저 시도. SendDBSkillUpdate(-iNeededSP); if ((victim = (CHARACTER_MANAGER::instance().FindByPID(pid)))) ch->WarpSet(victim->GetX(), victim->GetY()); @@ -1323,10 +1323,10 @@ void CGuild::UseSkill(DWORD dwVnum, LPCHARACTER ch, DWORD pid) { if (m_memberP2POnline.find(pid) != m_memberP2POnline.end()) { - // ٸ αε -> ޽ ǥ ޾ƿ - // 1. A.pid, B.pid Ѹ - // 2. B.pid Ѹ A.pid, ǥ - // 3. + // 다른 서버에 로그인된 사람이 있음 -> 메시지 보내 좌표를 받아오자 + // 1. A.pid, B.pid 를 뿌림 + // 2. B.pid를 가진 서버가 뿌린서버에게 A.pid, 좌표 를 보냄 + // 3. 워프 CCI * pcci = P2P_MANAGER::instance().FindByPID(pid); if (pcci->bChannel != g_bChannel) @@ -1897,11 +1897,11 @@ bool CGuild::HasLand() } // GUILD_JOIN_BUG_FIX -/// ʴ event +/// 길드 초대 event 정보 EVENTINFO(TInviteGuildEventInfo) { - DWORD dwInviteePID; ///< ʴ character PID - DWORD dwGuildID; ///< ʴ Guild ID + DWORD dwInviteePID; ///< 초대받은 character 의 PID + DWORD dwGuildID; ///< 초대한 Guild 의 ID TInviteGuildEventInfo() : dwInviteePID( 0 ) @@ -1911,8 +1911,8 @@ EVENTINFO(TInviteGuildEventInfo) }; /** - * ʴ event callback Լ. - * event ߵϸ ʴ óѴ. + * 길드 초대 event callback 함수. + * event 가 발동하면 초대 거절로 처리한다. */ EVENTFUNC( GuildInviteEvent ) { @@ -1989,7 +1989,7 @@ void CGuild::Invite( LPCHARACTER pchInviter, LPCHARACTER pchInvitee ) return; // - // ̺Ʈ + // 이벤트 생성 // TInviteGuildEventInfo* pInfo = AllocEventInfo(); pInfo->dwInviteePID = pchInvitee->GetPlayerID(); @@ -1998,7 +1998,7 @@ void CGuild::Invite( LPCHARACTER pchInviter, LPCHARACTER pchInvitee ) m_GuildInviteEventMap.insert(EventMap::value_type(pchInvitee->GetPlayerID(), event_create(GuildInviteEvent, pInfo, PASSES_PER_SEC(10)))); // - // ʴ ޴ character ʴ Ŷ + // 초대 받는 character 에게 초대 패킷 전송 // DWORD gid = GetID(); diff --git a/src/game/src/guild_manager.cpp b/src/game/src/guild_manager.cpp index ff38535..eceb7f2 100644 --- a/src/game/src/guild_manager.cpp +++ b/src/game/src/guild_manager.cpp @@ -504,7 +504,7 @@ void CGuildManager::RequestWarOver(DWORD dwGuild1, DWORD dwGuild2, DWORD dwGuild TPacketGuildWar p; p.bWar = GUILD_WAR_OVER; - // . + // 길드전이 끝나도 보상은 없다. //p.lWarPrice = lReward; p.lWarPrice = 0; p.bType = dwGuildWinner == 0 ? 1 : 0; // bType == 1 means draw for this packet. @@ -952,7 +952,7 @@ void CGuildManager::ChangeMaster(DWORD dwGID) iter->second->Load(dwGID); } - // Ʈ ֱ + // 업데이트된 정보 보내주기 DBManager::instance().FuncQuery(std::bind1st(std::mem_fun(&CGuild::SendGuildDataUpdateToAllMember), iter->second), "SELECT 1"); diff --git a/src/game/src/guild_war.cpp b/src/game/src/guild_war.cpp index 8cdcb9a..2a2c33c 100644 --- a/src/game/src/guild_war.cpp +++ b/src/game/src/guild_war.cpp @@ -140,12 +140,12 @@ DWORD CGuild::GetGuildWarMapIndex(DWORD dwOppGID) return git->second.map_index; } -bool CGuild::CanStartWar(BYTE bGuildWarType) // ŸԿ ٸ +bool CGuild::CanStartWar(BYTE bGuildWarType) // 타입에 따라 다른 조건이 생길 수도 있음 { if (bGuildWarType >= GUILD_WAR_TYPE_MAX_NUM) return false; - // ׽Ʈÿ ο Ȯ ʴ´. + // 테스트시에는 인원수를 확인하지 않는다. if (test_server || quest::CQuestManager::instance().GetEventFlag("guild_war_test") != 0) return GetLadderPoint() > 0; @@ -317,7 +317,7 @@ void CGuild::RequestDeclareWar(DWORD dwOppGID, BYTE type) return; } - // Ŷ to another server + // 패킷 보내기 to another server TPacketGuildWar p; p.bType = type; p.bWar = GUILD_WAR_SEND_DECLARE; @@ -336,7 +336,7 @@ void CGuild::RequestDeclareWar(DWORD dwOppGID, BYTE type) if (saved_type == GUILD_WAR_TYPE_FIELD) { - // Ѱ ޾Ƶ鿴. + // 선전포고 한것을 받아들였다. TPacketGuildWar p; p.bType = saved_type; p.bWar = GUILD_WAR_ON_WAR; @@ -441,14 +441,14 @@ void CGuild::StartWar(DWORD dwOppGID) bool CGuild::WaitStartWar(DWORD dwOppGID) { - //ڱڽ̸ + //자기자신이면 if (dwOppGID == GetID()) { SPDLOG_ERROR("GuildWar.WaitStartWar.DECLARE_WAR_SELF id({} -> {})", GetID(), dwOppGID); return false; } - // TGuildWar ´. + //상대방 길드 TGuildWar 를 얻어온다. itertype(m_EnemyGuild) it = m_EnemyGuild.find(dwOppGID); if (it == m_EnemyGuild.end()) { @@ -456,7 +456,7 @@ bool CGuild::WaitStartWar(DWORD dwOppGID) return false; } - //۷ ϰ + //레퍼런스에 등록하고 TGuildWar & gw(it->second); if (gw.state == GUILD_WAR_WAIT_START) @@ -465,10 +465,10 @@ bool CGuild::WaitStartWar(DWORD dwOppGID) return false; } - //¸ Ѵ. + //상태를 저장한다. gw.state = GUILD_WAR_WAIT_START; - // Ŭ ͸ + //상대편의 길드 클래스 포인터를 얻어오고 CGuild* g = CGuildManager::instance().FindGuild(dwOppGID); if (!g) { @@ -481,14 +481,14 @@ bool CGuild::WaitStartWar(DWORD dwOppGID) // END_OF_GUILDWAR_INFO - // ʵ̸ ʻ + // 필드형이면 맵생성 안함 if (gw.type == GUILD_WAR_TYPE_FIELD) { SPDLOG_DEBUG("GuildWar.WaitStartWar.FIELD_TYPE id({} -> {})", GetID(), dwOppGID); return true; } - // Ȯ + // 전쟁 서버 인지 확인 SPDLOG_DEBUG("GuildWar.WaitStartWar.CheckWarServer id({} -> {}), type({}), map({})", GetID(), dwOppGID, gw.type, rkGuildWarInfo.lMapIndex); @@ -505,7 +505,7 @@ bool CGuild::WaitStartWar(DWORD dwOppGID) if (id1 > id2) std::swap(id1, id2); - // + //워프 맵을 생성 DWORD lMapIndex = CWarMapManager::instance().CreateWarMap(rkGuildWarInfo, id1, id2); if (!lMapIndex) { @@ -516,10 +516,10 @@ bool CGuild::WaitStartWar(DWORD dwOppGID) SPDLOG_DEBUG("GuildWar.WaitStartWar.CreateMap id({} vs {}), type({}), map({}) -> map_inst({})", id1, id2, gw.type, rkGuildWarInfo.lMapIndex, lMapIndex); - // ε + //길드전 정보에 맵인덱스를 세팅 gw.map_index = lMapIndex; - //ʿ (?) + //양쪽에 등록(?) SetGuildWarMapIndex(dwOppGID, lMapIndex); g->SetGuildWarMapIndex(GetID(), lMapIndex); @@ -546,7 +546,7 @@ void CGuild::RequestRefuseWar(DWORD dwOppGID) if (it != m_EnemyGuild.end() && it->second.state == GUILD_WAR_RECV_DECLARE) { - // ߴ. + // 선전포고를 거절했다. TPacketGuildWar p; p.bWar = GUILD_WAR_REFUSE; p.dwGuildFrom = GetID(); diff --git a/src/game/src/horse_rider.cpp b/src/game/src/horse_rider.cpp index aa3a6c5..3eabab6 100644 --- a/src/game/src/horse_rider.cpp +++ b/src/game/src/horse_rider.cpp @@ -14,10 +14,10 @@ const int HORSE_STAMINA_REGEN_INTERVAL = 12 * 60; THorseStat c_aHorseStat[HORSE_MAX_LEVEL+1] = /* - int iMinLevel; // ž ִ ּ + int iMinLevel; // 탑승할 수 있는 최소 레벨 int iNPCRace; - int iMaxHealth; // ִ ü - int iMaxStamina; // ִ ׹̳ + int iMaxHealth; // 말의 최대 체력 + int iMaxStamina; // 말의 최대 스테미너 int iST; int iDX; int iHT; @@ -29,7 +29,7 @@ THorseStat c_aHorseStat[HORSE_MAX_LEVEL+1] = */ { { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, - { 25, 20101, 3, 4, 26, 35, 18, 9, 54, 43, 64, 32 }, // 1 (ʱ) + { 25, 20101, 3, 4, 26, 35, 18, 9, 54, 43, 64, 32 }, // 1 (초급) { 25, 20101, 4, 4, 27, 36, 18, 9, 55, 44, 66, 33 }, { 25, 20101, 5, 5, 28, 38, 19, 9, 56, 44, 67, 33 }, { 25, 20101, 7, 5, 29, 39, 19, 10, 57, 45, 68, 34 }, @@ -39,7 +39,7 @@ THorseStat c_aHorseStat[HORSE_MAX_LEVEL+1] = { 25, 20101, 12, 7, 33, 44, 22, 11, 61, 48, 73, 36 }, { 25, 20101, 13, 8, 34, 45, 22, 11, 62, 49, 74, 37 }, { 25, 20101, 15, 10, 35, 46, 23, 12, 63, 50, 75, 37 }, - { 35, 20104, 18, 30, 40, 53, 27, 13, 69, 55, 82, 41 }, // 11 (߱) + { 35, 20104, 18, 30, 40, 53, 27, 13, 69, 55, 82, 41 }, // 11 (중급) { 35, 20104, 19, 35, 41, 54, 27, 14, 70, 56, 84, 42 }, { 35, 20104, 21, 40, 42, 56, 28, 14, 71, 56, 85, 42 }, { 35, 20104, 22, 50, 43, 57, 28, 14, 72, 57, 86, 43 }, @@ -49,7 +49,7 @@ THorseStat c_aHorseStat[HORSE_MAX_LEVEL+1] = { 35, 20104, 28, 70, 46, 62, 31, 15, 76, 60, 91, 45 }, { 35, 20104, 30, 80, 47, 63, 31, 16, 77, 61, 92, 46 }, { 35, 20104, 32, 100, 48, 64, 32, 16, 78, 62, 93, 46 }, - { 50, 20107, 35, 120, 53, 71, 36, 18, 84, 67, 100, 50 }, // 21 () + { 50, 20107, 35, 120, 53, 71, 36, 18, 84, 67, 100, 50 }, // 21 (고급) { 50, 20107, 36, 125, 55, 74, 37, 18, 86, 68, 103, 51 }, { 50, 20107, 37, 130, 57, 76, 38, 19, 88, 70, 105, 52 }, { 50, 20107, 38, 135, 59, 78, 39, 20, 90, 72, 108, 54 }, @@ -117,7 +117,7 @@ bool CHorseRider::ReviveHorse() m_Horse.sHealth = c_aHorseStat[level].iMaxHealth; m_Horse.sStamina = c_aHorseStat[level].iMaxStamina; - // 2005.03.24.ipkn. 츰 ٽ ״ + // 2005.03.24.ipkn.말 살린후 다시 죽는 현상 수정 ResetHorseHealthDropTime(); StartStaminaRegenEvent(); @@ -138,11 +138,11 @@ short CHorseRider::GetHorseMaxStamina() void CHorseRider::FeedHorse() { - // + // 말을 가지고 살아있을때만 if (GetHorseLevel() > 0 && GetHorseHealth() > 0) { UpdateHorseHealth(+1); - // 20050324. ipkn Կ ü ̸ ø. + // 20050324. ipkn 말 먹였을때도 체력 감소 딜레이를 늘린다. ResetHorseHealthDropTime(); } } @@ -159,7 +159,7 @@ void CHorseRider::UpdateHorseDataByLogoff(DWORD dwLogoffTime) return; if (dwLogoffTime >= 12 * 60) - UpdateHorseStamina(dwLogoffTime / 12 / 60, false); // α׿ 12д 1 ȸ + UpdateHorseStamina(dwLogoffTime / 12 / 60, false); // 로그오프 12분당 1씩 회복 } void CHorseRider::UpdateHorseStamina(int iStamina, bool bSend) diff --git a/src/game/src/input.cpp b/src/game/src/input.cpp index 36329c6..06736c1 100644 --- a/src/game/src/input.cpp +++ b/src/game/src/input.cpp @@ -72,7 +72,7 @@ bool CInputProcessor::Process(LPDESC lpDesc, const void * c_pvOrig, int iBytes, BYTE bHeader = (BYTE) *(c_pData); const char * c_pszName; - if (bHeader == 0) // ȣȭ ó Ƿ 0 ŵѴ. + if (bHeader == 0) // 암호화 처리가 있으므로 0번 헤더는 스킵한다. iPacketLen = 1; else if (!m_pPacketInfo->Get(bHeader, &iPacketLen, &c_pszName)) { @@ -249,7 +249,7 @@ ACMD(do_block_chat); int CInputHandshake::Analyze(LPDESC d, BYTE bHeader, const char * c_pData) { - if (bHeader == 10) // ʹ + if (bHeader == 10) // 엔터는 무시 return 0; if (bHeader == HEADER_CG_TEXT) @@ -257,7 +257,7 @@ int CInputHandshake::Analyze(LPDESC d, BYTE bHeader, const char * c_pData) ++c_pData; const char * c_pSep; - if (!(c_pSep = strchr(c_pData, '\n'))) // \n ã´. + if (!(c_pSep = strchr(c_pData, '\n'))) // \n을 찾는다. return -1; if (*(c_pSep - 1) == '\r') @@ -356,7 +356,7 @@ int CInputHandshake::Analyze(LPDESC d, BYTE bHeader, const char * c_pData) else if (!stBuf.compare(0,15,"DELETE_AWARDID ")) { char szTmp[64]; - std::string msg = stBuf.substr(15,26); // item_award id? + std::string msg = stBuf.substr(15,26); // item_award의 id범위? TPacketDeleteAwardID p; p.dwID = (DWORD)(atoi(msg.c_str())); @@ -371,7 +371,7 @@ int CInputHandshake::Analyze(LPDESC d, BYTE bHeader, const char * c_pData) if (d->IsAdminMode()) { - // ɵ + // 어드민 명령들 if (!stBuf.compare(0, 7, "NOTICE ")) { std::string msg = stBuf.substr(7, 50); @@ -519,7 +519,7 @@ int CInputHandshake::Analyze(LPDESC d, BYTE bHeader, const char * c_pData) std::string strPrivEmpire; is >> strPrivEmpire >> empire >> type >> value >> duration; - // ִġ 10 + // 최대치 10배 value = std::clamp(value, 0, 1000); stResult = "PRIV_EMPIRE FAIL"; @@ -534,7 +534,7 @@ int CInputHandshake::Analyze(LPDESC d, BYTE bHeader, const char * c_pData) { stResult = "PRIV_EMPIRE SUCCEED"; - // ð + // 시간 단위로 변경 duration = duration * (60 * 60); SPDLOG_DEBUG("_give_empire_privileage(empire={}, type={}, value={}, duration={}) by web", @@ -569,13 +569,13 @@ int CInputHandshake::Analyze(LPDESC d, BYTE bHeader, const char * c_pData) { if (!guild_mark_server) { - // ! - ũ ƴѵ ũ ûϷ? + // 끊어버려! - 마크 서버가 아닌데 마크를 요청하려고? SPDLOG_ERROR("Guild Mark login requested but i'm not a mark server!"); d->SetPhase(PHASE_CLOSE); return 0; } - // --; + // 무조건 인증 --; SPDLOG_DEBUG("MARK_SERVER: Login"); d->SetPhase(PHASE_LOGIN); return 0; diff --git a/src/game/src/input_auth.cpp b/src/game/src/input_auth.cpp index aa7b5b7..31f7509 100644 --- a/src/game/src/input_auth.cpp +++ b/src/game/src/input_auth.cpp @@ -23,11 +23,11 @@ bool FN_IS_VALID_LOGIN_STRING(const char *str) for (tmp = str; *tmp; ++tmp) { - // ĺ ڸ + // 알파벳과 수자만 허용 if (isdigit(*tmp) || isalpha(*tmp)) continue; - // ijٴ Ư + // 캐나다는 몇몇 특수문자 허용 if (LC_IsCanada()) { switch (*tmp) @@ -111,7 +111,7 @@ void CInputAuth::Login(LPDESC d, const char * c_pData) return; } - // string Ἲ + // string 무결성을 위해 복사 char login[LOGIN_MAX_LEN + 1]; trim_and_lower(pinfo->login, login, sizeof(login)); diff --git a/src/game/src/input_db.cpp b/src/game/src/input_db.cpp index 1d4d125..47976f5 100644 --- a/src/game/src/input_db.cpp +++ b/src/game/src/input_db.cpp @@ -135,7 +135,7 @@ void CInputDB::LoginSuccess(DWORD dwHandle, const char *data) return; } - if (strcmp(pTab->status, "OK")) // OK ƴϸ + if (strcmp(pTab->status, "OK")) // OK가 아니면 { SPDLOG_DEBUG("CInputDB::LoginSuccess - status[{}] is not OK [{}]", pTab->status, pTab->login); @@ -158,7 +158,7 @@ void CInputDB::LoginSuccess(DWORD dwHandle, const char *data) d->BindAccountTable(pTab); - if (!bFound) // ijͰ .. -_- + if (!bFound) // 캐릭터가 없으면 랜덤한 제국으로 보낸다.. -_- { TPacketGCEmpire pe; pe.bHeader = HEADER_GC_EMPIRE; @@ -231,7 +231,7 @@ void CInputDB::PlayerCreateSuccess(LPDESC d, const char * data) d->Packet(&pack, sizeof(TPacketGCPlayerCreateSuccess)); - // ⺻ ȯθ + // 기본 무기와 귀환부를 지급 TPlayerItem t; memset(&t, 0, sizeof(t)); @@ -241,10 +241,10 @@ void CInputDB::PlayerCreateSuccess(LPDESC d, const char * data) t.count = 1; t.owner = r_Tab.players[pPacketDB->bAccountCharacterIndex].dwID; - //: ΰ+3,ö+3,Ź+3,+3,ݸ+3, ܱͰ+3, һ+3, +3, +3 - //ڰ+3,ȯΰ+3,Ź+3,ȵ+3,ȭȱ+3,+3, Ͱ+3, +3, +3 - //簩+3,+3,Ź+3,+3,ָ+3, ݱͰ+3, +3, +3 - //磺õ+3,+3,Ź+3,ڸ+3,ȭ+3,ָ+3, ݱͰ+3, +3, +3 + //무사: 자인갑+3,철편투구+3,금편신발+3,남만도+3,백금목걸이+3, 흑단귀걸이+3, 소산부+3, 오각패+3, 흑단팔찌+3 + //자객:영린+3,연환두건+3,금편신발+3,마안도+3,화안궁+3,옥목걸이+3, 옥귀걸이+3, 오각패+3, 흑단팔찌+3 + //수라:음양갑+3,애희투구+3,금편신발+3,남만도+3,진주목걸이+3, 백금귀걸이+3, 오각패+3, 흑단팔찌+3 + //무당:서천의+3,태을모+3,금편신발+3,자린선+3,매화령+3,진주목걸이+3, 백금귀걸이+3, 오각패+3, 흑단팔찌+3 struct SInitialItem { @@ -347,7 +347,7 @@ void CInputDB::PlayerLoad(LPDESC d, const char * data) { lMapIndex = SECTREE_MANAGER::instance().GetMapIndex(pTab->x, pTab->y); - if (lMapIndex == 0) // ǥ ã . + if (lMapIndex == 0) // 좌표를 찾을 수 없다. { lMapIndex = EMPIRE_START_MAP(d->GetAccountTable().bEmpire); pos.x = EMPIRE_START_X(d->GetAccountTable().bEmpire); @@ -361,11 +361,11 @@ void CInputDB::PlayerLoad(LPDESC d, const char * data) } pTab->lMapIndex = lMapIndex; - // Private ʿ ־µ, Private ¶ ⱸ ư Ѵ. + // Private 맵에 있었는데, Private 맵이 사라진 상태라면 출구로 돌아가야 한다. // ---- - // ٵ ⱸ ư Ѵٸ鼭... ⱸ ƴ϶ private map Ǵ pulic map ġ ãİ... - // 縦 𸣴... ϵڵ Ѵ. - // Ʊ͵̸, ⱸ... + // 근데 출구로 돌아가야 한다면서... 왜 출구가 아니라 private map 상에 대응되는 pulic map의 위치를 찾냐고... + // 역사를 모르니... 또 하드코딩 한다. + // 아귀동굴이면, 출구로... // by rtsummit if (!SECTREE_MANAGER::instance().GetValidLocation(pTab->lMapIndex, pTab->x, pTab->y, lMapIndex, pos, d->GetEmpire())) { @@ -479,11 +479,11 @@ void CInputDB::Boot(const char* data) { signal_timer_disable(); - // Ŷ üũ + // 패킷 사이즈 체크 DWORD dwPacketSize = decode_4bytes(data); data += 4; - // Ŷ üũ + // 패킷 버전 체크 BYTE bVersion = decode_byte(data); data += 1; @@ -802,7 +802,7 @@ void CInputDB::Boot(const char* data) data += size * sizeof(TItemIDRangeTable); //ADMIN_MANAGER - // + //관리자 등록 int ChunkSize = decode_2bytes(data ); data += 2; int HostSize = decode_2bytes(data ); @@ -1170,7 +1170,7 @@ void CInputDB::SafeboxLoad(LPDESC d, const char * c_pData) // END_OF_ADD_PREMIUM //if (d->GetCharacter()->IsEquipUniqueItem(UNIQUE_ITEM_SAFEBOX_EXPAND)) - //bSize = 3; // âȮ + //bSize = 3; // 창고확장권 //d->GetCharacter()->LoadSafebox(p->bSize * SAFEBOX_PAGE_SIZE, p->dwGold, p->wItemCount, (TPlayerItem *) (c_pData + sizeof(TSafeboxTable))); d->GetCharacter()->LoadSafebox(bSize * SAFEBOX_PAGE_SIZE, p->dwGold, p->wItemCount, (TPlayerItem *) (c_pData + sizeof(TSafeboxTable))); @@ -1190,7 +1190,7 @@ void CInputDB::SafeboxChangeSize(LPDESC d, const char * c_pData) } // -// @version 05/06/20 Bang2ni - ReqSafeboxLoad +// @version 05/06/20 Bang2ni - ReqSafeboxLoad 의 취소 // void CInputDB::SafeboxWrongPassword(LPDESC d) { @@ -1250,7 +1250,7 @@ void CInputDB::LoginAlready(LPDESC d, const char * c_pData) if (!d) return; - // INTERNATIONAL_VERSION ̹ ̸ + // INTERNATIONAL_VERSION 이미 접속중이면 접속 끊음 { TPacketDGLoginAlready * p = (TPacketDGLoginAlready *) c_pData; @@ -1730,11 +1730,11 @@ void CInputDB::AuthLogin(LPDESC d, const char * c_pData) if (bResult) { - // Panama ȣȭ ѿ ʿ Ű + // Panama 암호화 팩에 필요한 키 보내기 SendPanamaList(d); ptoc.dwLoginKey = d->GetLoginKey(); - //NOTE: AuthSucess ȱ׷ PHASE Close Ǽ ʴ´.-_- + //NOTE: AuthSucess보다 먼저 보내야지 안그러면 PHASE Close가 되서 보내지지 않는다.-_- //Send Client Package CryptKey { DESC_MANAGER::instance().SendClientPackageCryptKey(d); @@ -1762,7 +1762,7 @@ void CInputDB::ChangeEmpirePriv(const char* c_pData) } /** - * @version 05/06/08 Bang2ni - ӽð ߰ + * @version 05/06/08 Bang2ni - 지속시간 추가 */ void CInputDB::ChangeGuildPriv(const char* c_pData) { @@ -2101,7 +2101,7 @@ void CInputDB::ReloadAdmin(const char * c_pData ) //////////////////////////////////////////////////////////////////// // Analyze -// @version 05/06/10 Bang2ni - Ʈ Ŷ(HEADER_DG_MYSHOP_PRICELIST_RES) óƾ ߰. +// @version 05/06/10 Bang2ni - 아이템 가격정보 리스트 패킷(HEADER_DG_MYSHOP_PRICELIST_RES) 처리루틴 추가. //////////////////////////////////////////////////////////////////// int CInputDB::Analyze(LPDESC d, BYTE bHeader, const char * c_pData) { @@ -2450,7 +2450,7 @@ int CInputDB::Analyze(LPDESC d, BYTE bHeader, const char * c_pData) case HEADER_DG_NEED_LOGIN_LOG: DetailLog( (TPacketNeedLoginLogInfo*) c_pData ); break; - // ׽Ʈ + // 독일 선물 기능 테스트 case HEADER_DG_ITEMAWARD_INFORMER: ItemAwardInformer((TPacketItemAwardInfromer*) c_pData); break; @@ -2618,7 +2618,7 @@ void CInputDB::DetailLog(const TPacketNeedLoginLogInfo* info) void CInputDB::ItemAwardInformer(TPacketItemAwardInfromer *data) { - LPDESC d = DESC_MANAGER::instance().FindByLoginName(data->login); //login + LPDESC d = DESC_MANAGER::instance().FindByLoginName(data->login); //login정보 if(d == NULL) return; @@ -2627,12 +2627,12 @@ void CInputDB::ItemAwardInformer(TPacketItemAwardInfromer *data) if (d->GetCharacter()) { LPCHARACTER ch = d->GetCharacter(); - ch->SetItemAward_vnum(data->vnum); // ch ӽ سٰ QuestLoad Լ ó + ch->SetItemAward_vnum(data->vnum); // ch 에 임시 저장해놨다가 QuestLoad 함수에서 처리 ch->SetItemAward_cmd(data->command); - if(d->IsPhase(PHASE_GAME)) //϶ + if(d->IsPhase(PHASE_GAME)) //게임페이즈일때 { - quest::CQuestManager::instance().ItemInformer(ch->GetPlayerID(),ch->GetItemAward_vnum()); //questmanager ȣ + quest::CQuestManager::instance().ItemInformer(ch->GetPlayerID(),ch->GetItemAward_vnum()); //questmanager 호출 } } } diff --git a/src/game/src/input_login.cpp b/src/game/src/input_login.cpp index ea2e739..b80d509 100644 --- a/src/game/src/input_login.cpp +++ b/src/game/src/input_login.cpp @@ -68,13 +68,13 @@ static bool FN_is_battle_zone(LPCHARACTER ch) { switch (ch->GetMapIndex()) { - case 1: // ż 1 - case 2: // ż 2 - case 21: // õ 1 - case 23: // õ 2 - case 41: // 1 - case 43: // 2 - case 113: // OX + case 1: // 신수 1차 마을 + case 2: // 신수 2차 마을 + case 21: // 천조 1차 마을 + case 23: // 천조 2차 마을 + case 41: // 진노 1차 마을 + case 43: // 진노 2차 마을 + case 113: // OX 맵 return false; } @@ -373,7 +373,7 @@ bool RaceToJob(unsigned race, unsigned* ret_job) return true; } -// ű ij +// 신규 캐릭터 지원 bool NewPlayerTable2(TPlayerTable * table, const char * name, BYTE race, BYTE shape, BYTE bEmpire) { if (race >= MAIN_RACE_MAX_NUM) @@ -397,7 +397,7 @@ bool NewPlayerTable2(TPlayerTable * table, const char * name, BYTE race, BYTE sh strlcpy(table->name, name, sizeof(table->name)); table->level = 1; - table->job = race; // ִ´ + table->job = race; // 직업대신 종족을 넣는다 table->voice = 0; table->part_base = shape; @@ -443,7 +443,7 @@ void CInputLogin::CharacterCreate(LPDESC d, const char * data) return; } - // ̸̰ų, ߸ ̸ + // 사용할 수 없는 이름이거나, 잘못된 평상복이면 생설 실패 if (!check_name(pinfo->name) || pinfo->shape > 1) { if (LC_IsCanada() == true) @@ -573,7 +573,7 @@ void CInputLogin::Entergame(LPDESC d, const char * data) CGuildManager::instance().LoginMember(ch); - // ij͸ ʿ ߰ + // 캐릭터를 맵에 추가 ch->Show(ch->GetMapIndex(), pos.x, pos.y, pos.z); SECTREE_MANAGER::instance().SendNPCPosition(ch); @@ -581,8 +581,8 @@ void CInputLogin::Entergame(LPDESC d, const char * data) d->SetPhase(PHASE_GAME); - if(ch->GetItemAward_cmd()) //  - quest::CQuestManager::instance().ItemInformer(ch->GetPlayerID(),ch->GetItemAward_vnum()); //questmanager ȣ + if(ch->GetItemAward_cmd()) //게임페이즈 들어가면 + quest::CQuestManager::instance().ItemInformer(ch->GetPlayerID(),ch->GetItemAward_vnum()); //questmanager 호출 SPDLOG_DEBUG("ENTERGAME: {} {}x{}x{} {} map_index {}", ch->GetName(), ch->GetX(), ch->GetY(), ch->GetZ(), d->GetHostName(), ch->GetMapIndex()); @@ -592,10 +592,10 @@ void CInputLogin::Entergame(LPDESC d, const char * data) ch->EnterHorse(); } - // ÷̽ð ڵ + // 플레이시간 레코딩 시작 ch->ResetPlayTime(); - // ڵ ̺Ʈ ߰ + // 자동 저장 이벤트 추가 ch->StartSaveEvent(); ch->StartRecoveryEvent(); ch->StartCheckSpeedHackEvent(); @@ -751,10 +751,10 @@ void CInputLogin::Entergame(LPDESC d, const char * data) } else if (ch->GetMapIndex() == 113) { - // ox ̺Ʈ + // ox 이벤트 맵 if (COXEventManager::instance().Enter(ch) == false) { - // ox 㰡 . ÷̾ + // ox 맵 진입 허가가 나지 않음. 플레이어면 마을로 보내자 if (ch->GetGMLevel() == GM_PLAYER) ch->WarpSet(EMPIRE_START_X(ch->GetEmpire()), EMPIRE_START_Y(ch->GetEmpire())); } @@ -769,8 +769,8 @@ void CInputLogin::Entergame(LPDESC d, const char * data) } } - // ûҳ ȣ - if (g_TeenDesc) // RawPacket + // 청소년 보호 + if (g_TeenDesc) // RawPacket 사용 금지 { TPacketGTLogin p; @@ -790,7 +790,7 @@ void CInputLogin::Entergame(LPDESC d, const char * data) db_clientdesc->DBPacket(HEADER_GD_REQ_HORSE_NAME, 0, &pid, sizeof(DWORD)); } - // ߸ʿ  ȳϱ + // 중립맵에 들어갔을때 안내하기 if (g_noticeBattleZone) { if (FN_is_battle_zone(ch)) @@ -850,13 +850,13 @@ int CInputLogin::GuildSymbolUpload(LPDESC d, const char* c_pData, size_t uiBytes if (iSymbolSize <= 0 || iSymbolSize > 64 * 1024) { - // 64k ū ɺ ø - // + // 64k 보다 큰 길드 심볼은 올릴수없다 + // 접속을 끊고 무시 d->SetPhase(PHASE_CLOSE); return 0; } - // . + // 땅을 소유하지 않은 길드인 경우. if (!test_server) if (!building::CManager::instance().FindLandByGuild(p->guild_id)) { @@ -972,7 +972,7 @@ void CInputLogin::GuildMarkCRCList(LPDESC d, const char* c_pData) CGuildMarkManager::instance().GetDiffBlocks(pCG->imgIdx, pCG->crclist, mapDiffBlocks); DWORD blockCount = 0; - TEMP_BUFFER buf(1024 * 1024); // 1M + TEMP_BUFFER buf(1024 * 1024); // 1M 버퍼 for (itertype(mapDiffBlocks) it = mapDiffBlocks.begin(); it != mapDiffBlocks.end(); ++it) { diff --git a/src/game/src/input_main.cpp b/src/game/src/input_main.cpp index f94d866..69a72a1 100644 --- a/src/game/src/input_main.cpp +++ b/src/game/src/input_main.cpp @@ -45,7 +45,7 @@ extern int g_nPortalLimitTime; static int __deposit_limit() { - return (1000*10000); // 1õ + return (1000*10000); // 1천만 } void SendBlockChatInfo(LPCHARACTER ch, int sec) @@ -181,7 +181,7 @@ int GetTextTag(const char * src, int maxLen, int & tagLen, std::string & extraIn const char * cur = ++src; - if (*cur == '|') // || | ǥѴ. + if (*cur == '|') // ||는 |로 표시한다. { tagLen = 2; return TEXT_TAG_TAG; @@ -191,7 +191,7 @@ int GetTextTag(const char * src, int maxLen, int & tagLen, std::string & extraIn tagLen = 2; return TEXT_TAG_COLOR; } - else if (*cur == 'H') // hyperlink |Hitem:10000:0:0:0:0|h[̸]|h + else if (*cur == 'H') // hyperlink |Hitem:10000:0:0:0:0|h[이름]|h { tagLen = 2; return TEXT_TAG_HYPERLINK_START; @@ -229,12 +229,12 @@ void GetTextTagInfo(const char * src, int src_len, int & hyperlinks, bool & colo int ProcessTextTag(LPCHARACTER ch, const char * c_pszText, size_t len) { - //2012.05.17 - //0 : - //1 : ݰ - //2 : ݰ , λ - //3 : ȯ - //4 : + //2012.05.17 김용욱 + //0 : 정상적으로 사용 + //1 : 금강경 부족 + //2 : 금강경이 있으나, 개인상점에서 사용중 + //3 : 교환중 + //4 : 에러 int hyperlinks; bool colored; @@ -419,18 +419,18 @@ int CInputMain::Whisper(LPCHARACTER ch, const char * data, size_t uiBytes) if (g_bEmpireWhisper) if (!ch->IsEquipUniqueGroup(UNIQUE_GROUP_RING_OF_LANGUAGE)) if (!(pkChr && pkChr->IsEquipUniqueGroup(UNIQUE_GROUP_RING_OF_LANGUAGE))) - if (bOpponentEmpire != ch->GetEmpire() && ch->GetEmpire() && bOpponentEmpire // ٸ鼭 - && ch->GetGMLevel() == GM_PLAYER && gm_get_level(pinfo->szNameTo) == GM_PLAYER) // Ѵ Ϲ ÷̸̾ - // ̸ ۿ 𸣴 gm_get_level Լ + if (bOpponentEmpire != ch->GetEmpire() && ch->GetEmpire() && bOpponentEmpire // 서로 제국이 다르면서 + && ch->GetGMLevel() == GM_PLAYER && gm_get_level(pinfo->szNameTo) == GM_PLAYER) // 둘다 일반 플레이어이면 + // 이름 밖에 모르니 gm_get_level 함수를 사용 { if (!pkChr) { - // ٸ ǥø Ѵ. bType 4Ʈ Empireȣ Ѵ. + // 다른 서버에 있으니 제국 표시만 한다. bType의 상위 4비트를 Empire번호로 사용한다. bType = ch->GetEmpire() << 4; } else { - ConvertEmpireText(ch->GetEmpire(), buf, buflen, 10 + 2 * pkChr->GetSkillPower(SKILL_LANGUAGE1 + ch->GetEmpire() - 1)/*ȯȮ*/); + ConvertEmpireText(ch->GetEmpire(), buf, buflen, 10 + 2 * pkChr->GetSkillPower(SKILL_LANGUAGE1 + ch->GetEmpire() - 1)/*변환확률*/); } } @@ -445,7 +445,7 @@ int CInputMain::Whisper(LPCHARACTER ch, const char * data, size_t uiBytes) { char buf[128]; int len; - if (3==processReturn) //ȯ + if (3==processReturn) //교환중 len = snprintf(buf, sizeof(buf), LC_TEXT("\xB4\xD9\xB8\xA5 \xB0\xC5\xB7\xA1\xC1\xDF(\xC3\xA2\xB0\xED,\xB1\xB3\xC8\xAF,\xBB\xF3\xC1\xA1)\xBF\xA1\xB4\xC2 \xB0\xB3\xC0\xCE\xBB\xF3\xC1\xA1\xC0\xBB \xBB\xE7\xBF\xEB\xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."), pTable->szLocaleName); else len = snprintf(buf, sizeof(buf), LC_TEXT("%s\xC0\xCC \xC7\xCA\xBF\xE4\xC7\xD5\xB4\xCF\xB4\xD9."), pTable->szLocaleName); @@ -454,7 +454,7 @@ int CInputMain::Whisper(LPCHARACTER ch, const char * data, size_t uiBytes) if (len < 0 || len >= (int) sizeof(buf)) len = sizeof(buf) - 1; - ++len; // \0 + ++len; // \0 문자 포함 TPacketGCWhisper pack; @@ -470,7 +470,7 @@ int CInputMain::Whisper(LPCHARACTER ch, const char * data, size_t uiBytes) } } - // Ƿ ̸ Ǯش. + // 릴래이 상태일 수 있으므로 릴래이를 풀어준다. pkDesc->SetRelay(""); return (iExtraLen); } @@ -487,8 +487,8 @@ int CInputMain::Whisper(LPCHARACTER ch, const char * data, size_t uiBytes) pack.bType = bType; strlcpy(pack.szNameFrom, ch->GetName(), sizeof(pack.szNameFrom)); - // desc->BufferedPacket ʰ ۿ ϴ - // P2P relayǾ Ŷ ĸȭ ֱ ̴. + // desc->BufferedPacket을 하지 않고 버퍼에 써야하는 이유는 + // P2P relay되어 패킷이 캡슐화 될 수 있기 때문이다. TEMP_BUFFER tmpbuf; tmpbuf.write(&pack, sizeof(pack)); @@ -563,7 +563,7 @@ struct FEmpireChatPacket } else { - // ų ٸ Ź ؾմϴ + // 사람마다 스킬레벨이 다르니 매번 해야합니다 strlcpy(converted_msg, orig_msg, sizeof(converted_msg)); ConvertEmpireText(bEmpire, converted_msg + namelen, sizeof(converted_msg) - namelen, 10 + 2 * d->GetCharacter()->GetSkillPower(SKILL_LANGUAGE1 + bEmpire - 1)); @@ -595,17 +595,17 @@ struct FYmirChatPacket m_iMapIndex(iMapIndex), m_bEmpire(empire), m_ring(ring) { - m_len_orig_msg = snprintf(m_orig_msg, sizeof(m_orig_msg), "%s : %s", m_szName, m_szChat) + 1; // + m_len_orig_msg = snprintf(m_orig_msg, sizeof(m_orig_msg), "%s : %s", m_szName, m_szChat) + 1; // 널 문자 포함 if (m_len_orig_msg < 0 || m_len_orig_msg >= (int) sizeof(m_orig_msg)) m_len_orig_msg = sizeof(m_orig_msg) - 1; - m_len_conv_msg = snprintf(m_conv_msg, sizeof(m_conv_msg), "??? : %s", m_szChat) + 1; // + m_len_conv_msg = snprintf(m_conv_msg, sizeof(m_conv_msg), "??? : %s", m_szChat) + 1; // 널 문자 미포함 if (m_len_conv_msg < 0 || m_len_conv_msg >= (int) sizeof(m_conv_msg)) m_len_conv_msg = sizeof(m_conv_msg) - 1; - ConvertEmpireText(m_bEmpire, m_conv_msg + 6, m_len_conv_msg - 6, 10); // 6 "??? : " + ConvertEmpireText(m_bEmpire, m_conv_msg + 6, m_len_conv_msg - 6, 10); // 6은 "??? : "의 길이 } void operator() (LPDESC d) @@ -673,7 +673,7 @@ int CInputMain::Chat(LPCHARACTER ch, const char * data, size_t uiBytes) return iExtraLen; } - // ä Affect ó + // 채팅 금지 Affect 처리 const CAffect* pAffect = ch->FindAffect(AFFECT_BLOCK_CHAT); if (pAffect != NULL) @@ -710,7 +710,7 @@ int CInputMain::Chat(LPCHARACTER ch, const char * data, size_t uiBytes) if (NULL != pTable) { - if (3==processReturn) //ȯ + if (3==processReturn) //교환중 ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("\xB4\xD9\xB8\xA5 \xB0\xC5\xB7\xA1\xC1\xDF(\xC3\xA2\xB0\xED,\xB1\xB3\xC8\xAF,\xBB\xF3\xC1\xA1)\xBF\xA1\xB4\xC2 \xB0\xB3\xC0\xCE\xBB\xF3\xC1\xA1\xC0\xBB \xBB\xE7\xBF\xEB\xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9."), pTable->szLocaleName); else ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s\xC0\xCC \xC7\xCA\xBF\xE4\xC7\xD5\xB4\xCF\xB4\xD9."), pTable->szLocaleName); @@ -843,7 +843,7 @@ void CInputMain::ItemDrop(LPCHARACTER ch, const char * data) if (!ch) return; - // ũ 0 ũ ũ ̴. + // 엘크가 0보다 크면 엘크를 버리는 것 이다. if (pinfo->gold > 0) ch->DropGold(pinfo->gold); else @@ -859,7 +859,7 @@ void CInputMain::ItemDrop2(LPCHARACTER ch, const char * data) TPacketCGItemDrop2 * pinfo = (TPacketCGItemDrop2 *) data; - // ũ 0 ũ ũ ̴. + // 엘크가 0보다 크면 엘크를 버리는 것 이다. if (!ch) return; @@ -945,7 +945,7 @@ int CInputMain::Messenger(LPCHARACTER ch, const char* c_pData, size_t uiBytes) return sizeof(TPacketCGMessengerAddByVID); } - if (ch->GetDesc() == d) // ڽ ߰ . + if (ch->GetDesc() == d) // 자신은 추가할 수 없다. return sizeof(TPacketCGMessengerAddByVID); MessengerManager::instance().RequestToAdd(ch, ch_companion); @@ -973,7 +973,7 @@ int CInputMain::Messenger(LPCHARACTER ch, const char* c_pData, size_t uiBytes) ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s \xB4\xD4\xC0\xBA \xC1\xA2\xBC\xD3\xB5\xC7 \xC0\xD6\xC1\xF6 \xBE\xCA\xBD\xC0\xB4\xCF\xB4\xD9."), name); else { - if (tch == ch) // ڽ ߰ . + if (tch == ch) // 자신은 추가할 수 없다. return CHARACTER_NAME_MAX_LEN; if (tch->IsBlockMode(BLOCK_MESSENGER_INVITE) == true) @@ -982,7 +982,7 @@ int CInputMain::Messenger(LPCHARACTER ch, const char* c_pData, size_t uiBytes) } else { - // ޽ ijʹ Ǹ鼭 + // 메신저가 캐릭터단위가 되면서 변경 MessengerManager::instance().RequestToAdd(ch, tch); //MessengerManager::instance().AddToList(ch->GetName(), tch->GetName()); } @@ -1268,7 +1268,7 @@ static const int ComboSequenceBySkillLevel[3][8] = DWORD ClacValidComboInterval( LPCHARACTER ch, BYTE bArg ) { int nInterval = 300; - float fAdjustNum = 1.5f; // Ϲ speed hack ɸ . 2013.09.10 CYH + float fAdjustNum = 1.5f; // 일반 유저가 speed hack 에 걸리는 것을 막기 위해. 2013.09.10 CYH if( !ch ) { @@ -1299,17 +1299,17 @@ DWORD ClacValidComboInterval( LPCHARACTER ch, BYTE bArg ) bool CheckComboHack(LPCHARACTER ch, BYTE bArg, DWORD dwTime, bool CheckSpeedHack) { - // װų ¿ Ƿ, skipѴ. - // ̷ , CHRACTER::CanMove() + // 죽거나 기절 상태에서는 공격할 수 없으므로, skip한다. + // 이렇게 하지 말고, CHRACTER::CanMove()에 // if (IsStun() || IsDead()) return false; - // ߰ϴ° ´ٰ ϳ, - // ̹ ٸ κп CanMove() IsStun(), IsDead() - // üũϰ ֱ - // ּȭϱ ̷ ڵ带 ´. + // 를 추가하는게 맞다고 생각하나, + // 이미 다른 부분에서 CanMove()는 IsStun(), IsDead()과 + // 독립적으로 체크하고 있기 때문에 수정에 의한 영향을 + // 최소화하기 위해 이렇게 땜빵 코드를 써놓는다. if (ch->IsStun() || ch->IsDead()) return false; int ComboInterval = dwTime - ch->GetLastComboTime(); - int HackScalar = 0; // ⺻ Į 1 + int HackScalar = 0; // 기본 스칼라 단위 1 // [2013 09 11 CYH] debugging log /*SPDLOG_DEBUG("COMBO_TEST_LOG: {} arg:{} interval:{} valid:{} atkspd:{} riding:{}", @@ -1324,18 +1324,18 @@ bool CheckComboHack(LPCHARACTER ch, BYTE bArg, DWORD dwTime, bool CheckSpeedHack SPDLOG_DEBUG("COMBO: {} arg:{} seq:{} delta:{} checkspeedhack:{}", ch->GetName(), bArg, ch->GetComboSequence(), ComboInterval - ch->GetValidComboInterval(), CheckSpeedHack); #endif - // bArg 14 ~ 21 8޺ - // 1. ù ޺(14) ð Ŀ ݺ - // 2. 15 ~ 21 ݺ Ұ - // 3. ʴ Ѵ. + // bArg 14 ~ 21번 까지 총 8콤보 가능 + // 1. 첫 콤보(14)는 일정 시간 이후에 반복 가능 + // 2. 15 ~ 21번은 반복 불가능 + // 3. 차례대로 증가한다. if (bArg == 14) { if (CheckSpeedHack && ComboInterval > 0 && ComboInterval < ch->GetValidComboInterval() - COMBO_HACK_ALLOWABLE_MS) { - // FIXME ù° ޺ ̻ϰ ־ 300 -_-; - // ټ Ϳ ٿǴ Ȳ ϸ - // ù° ޺ ſ ͹ Ȳ ߻. - // ̷ ޺ ƨ 찡 ־ ڵ Ȱȭ. + // FIXME 첫번째 콤보는 이상하게 빨리 올 수가 있어서 300으로 나눔 -_-; + // 다수의 몬스터에 의해 다운되는 상황에서 공격을 하면 + // 첫번째 콤보가 매우 적은 인터벌로 들어오는 상황 발생. + // 이로 인해 콤보핵으로 튕기는 경우가 있어 다음 코드 비 활성화. //HackScalar = 1 + (ch->GetValidComboInterval() - ComboInterval) / 300; //SPDLOG_WARN("COMBO_HACK: 2 {} arg:{} interval:{} valid:{} atkspd:{} riding:{}", @@ -1357,13 +1357,13 @@ bool CheckComboHack(LPCHARACTER ch, BYTE bArg, DWORD dwTime, bool CheckSpeedHack { int idx = std::min(2, ch->GetComboIndex()); - if (ch->GetComboSequence() > 5) // 6޺ ̻ . + if (ch->GetComboSequence() > 5) // 현재 6콤보 이상은 없다. { HackScalar = 1; ch->SetValidComboInterval(300); SPDLOG_WARN("COMBO_HACK: 5 {} combo_seq:{}", ch->GetName(), ch->GetComboSequence()); } - // ڰ ּ ޺ ó + // 자객 쌍수 콤보 예외처리 else if (bArg == 21 && idx == 2 && ch->GetComboSequence() == 5 && @@ -1398,7 +1398,7 @@ bool CheckComboHack(LPCHARACTER ch, BYTE bArg, DWORD dwTime, bool CheckSpeedHack ch->IsRiding() ? "yes" : "no"); } - // 15 ~ 16 ݺѴ + // 말을 탔을 때는 15번 ~ 16번을 반복한다 //if (ch->IsHorseRiding()) if (ch->IsRiding()) ch->SetComboSequence(ch->GetComboSequence() == 1 ? 2 : 1); @@ -1411,13 +1411,13 @@ bool CheckComboHack(LPCHARACTER ch, BYTE bArg, DWORD dwTime, bool CheckSpeedHack ch->SetLastComboTime(dwTime); } } - else if (bArg == 13) // ⺻ (а(Polymorph) ´) + else if (bArg == 13) // 기본 공격 (둔갑(Polymorph)했을 때 온다) { if (CheckSpeedHack && ComboInterval > 0 && ComboInterval < ch->GetValidComboInterval() - COMBO_HACK_ALLOWABLE_MS) { - // ټ Ϳ ٿǴ Ȳ ϸ - // ù° ޺ ſ ͹ Ȳ ߻. - // ̷ ޺ ƨ 찡 ־ ڵ Ȱȭ. + // 다수의 몬스터에 의해 다운되는 상황에서 공격을 하면 + // 첫번째 콤보가 매우 적은 인터벌로 들어오는 상황 발생. + // 이로 인해 콤보핵으로 튕기는 경우가 있어 다음 코드 비 활성화. //HackScalar = 1 + (ch->GetValidComboInterval() - ComboInterval) / 100; //SPDLOG_WARN("COMBO_HACK: 6 {} arg:{} interval:{} valid:{} atkspd:{}", @@ -1440,8 +1440,8 @@ bool CheckComboHack(LPCHARACTER ch, BYTE bArg, DWORD dwTime, bool CheckSpeedHack SPDLOG_ERROR("cannot find motion by race {}", ch->GetRaceNum()); else { - // ̶ 1000.f ؾ Ŭ̾Ʈ ִϸ̼ ӵ 90% - // ִϸ̼ ϹǷ 900.f Ѵ. + // 정상적 계산이라면 1000.f를 곱해야 하지만 클라이언트가 애니메이션 속도의 90%에서 + // 다음 애니메이션 블렌딩을 허용하므로 900.f를 곱한다. int k = (int) (pkMotion->GetDuration() / ((float) ch->GetPoint(POINT_ATT_SPEED) / 100.f) * 900.f); ch->SetValidComboInterval(k); ch->SetLastComboTime(dwTime); @@ -1458,32 +1458,32 @@ bool CheckComboHack(LPCHARACTER ch, BYTE bArg, DWORD dwTime, bool CheckSpeedHack } else { - // ȵǴ ޺ Դ Ŀ ɼ? + // 말이 안되는 콤보가 왔다 해커일 가능성? //if (ch->GetDesc()->DelayedDisconnect(Random::get(2, 9))) //{ // LogManager::instance().HackLog("Hacker", ch); // SPDLOG_WARN("HACKER: {} arg {}", ch->GetName(), bArg); //} - // ڵ , Ǫ ߿ ϸ, - // νϴ 찡 ִ. + // 위 코드로 인해, 폴리모프를 푸는 중에 공격 하면, + // 가끔 핵으로 인식하는 경우가 있다. - // ڼ , - // poly 0 ó, - // Ŭ󿡼 Ŷ ޱ , . <- , ¿ . + // 자세히 말혀면, + // 서버에서 poly 0를 처리했지만, + // 클라에서 그 패킷을 받기 전에, 몹을 공격. <- 즉, 몹인 상태에서 공격. // - // ׷ Ŭ󿡼 · ߴٴ Ŀǵ带 (arg == 13) + // 그러면 클라에서는 서버에 몹 상태로 공격했다는 커맨드를 보내고 (arg == 13) // - // race ΰε ´ ̴! Ͽ üũ ߴ. + // 서버에서는 race는 인간인데 공격형태는 몹인 놈이다! 라고 하여 핵체크를 했다. - // Ͽ Ŭ̾Ʈ Ǵؼ ƴ϶, - // Ǵؾ ε... ̷ س... + // 사실 공격 패턴에 대한 것은 클라이언트에서 판단해서 보낼 것이 아니라, + // 서버에서 판단해야 할 것인데... 왜 이렇게 해놨을까... // by rtsummit } } else { - // ȵǴ ޺ Դ Ŀ ɼ? + // 말이 안되는 콤보가 왔다 해커일 가능성? if (ch->GetDesc()->DelayedDisconnect(Random::get(2, 9))) { LogManager::instance().HackLog("Hacker", ch); @@ -1496,7 +1496,7 @@ bool CheckComboHack(LPCHARACTER ch, BYTE bArg, DWORD dwTime, bool CheckSpeedHack if (HackScalar) { - // Ÿų 1.5ʰ ʵ ݷ ϴ ó + // 말에 타거나 내렸을 때 1.5초간 공격은 핵으로 간주하지 않되 공격력은 없게 하는 처리 if (get_dword_time() - ch->GetLastMountTime() > 1500) ch->IncreaseComboHackCount(1 + HackScalar); @@ -1531,9 +1531,9 @@ void CInputMain::Move(LPCHARACTER ch, const char * data) // FUNC_SKILL = 0x80, //}; - // ڷƮ üũ + // 텔레포트 핵 체크 -// if (!test_server) //2012.05.15 : ׼ (·) ټ ٿǸ鼭 ݽ ޺ ״ ־. +// if (!test_server) //2012.05.15 김용욱 : 테섭에서 (무적상태로) 다수 몬스터 상대로 다운되면서 공격시 콤보핵으로 죽는 문제가 있었다. { const float fDist = DISTANCE_SQRT((ch->GetX() - pinfo->lX) / 100, (ch->GetY() - pinfo->lY) / 100); @@ -1544,7 +1544,7 @@ void CInputMain::Move(LPCHARACTER ch, const char * data) const PIXEL_POSITION & warpPos = ch->GetWarpPosition(); if (warpPos.x == 0 && warpPos.y == 0) - LogManager::instance().HackLog("Teleport", ch); // Ȯ + LogManager::instance().HackLog("Teleport", ch); // 부정확할 수 있음 } SPDLOG_WARN("MOVE: {} trying to move too far (dist: {:.1f}m) Riding({})", ch->GetName(), fDist, ch->IsRiding()); @@ -1555,10 +1555,10 @@ void CInputMain::Move(LPCHARACTER ch, const char * data) } // - // ǵ(SPEEDHACK) Check + // 스피드핵(SPEEDHACK) Check // DWORD dwCurTime = get_dword_time(); - // ð Syncϰ 7 ˻Ѵ. (20090702 5ʿ) + // 시간을 Sync하고 7초 후 부터 검사한다. (20090702 이전엔 5초였음) bool CheckSpeedHack = (false == ch->GetDesc()->IsHandshaking() && dwCurTime - ch->GetDesc()->GetClientTime() > 7000); if (CheckSpeedHack) @@ -1568,13 +1568,13 @@ void CInputMain::Move(LPCHARACTER ch, const char * data) iDelta = (int) (dwCurTime - pinfo->dwTime); - // ð ʰ԰. ϴ α׸ صд. ¥ ̷ üũؾ. TODO + // 시간이 늦게간다. 일단 로그만 해둔다. 진짜 이런 사람들이 많은지 체크해야함. TODO if (iDelta >= 30000) { SPDLOG_WARN("SPEEDHACK: slow timer name {} delta {}", ch->GetName(), iDelta); ch->GetDesc()->DelayedDisconnect(3); } - // 1ʿ 20msec ° Ѵ. + // 1초에 20msec 빨리 가는거 까지는 이해한다. else if (iDelta < -(iServerDelta / 50)) { SPDLOG_WARN("SPEEDHACK: DETECTED! {} (delta {} {})", ch->GetName(), iDelta, iServerDelta); @@ -1583,11 +1583,11 @@ void CInputMain::Move(LPCHARACTER ch, const char * data) } // - // ޺ ǵ üũ + // 콤보핵 및 스피드핵 체크 // if (pinfo->bFunc == FUNC_COMBO && g_bCheckMultiHack) { - CheckComboHack(ch, pinfo->bArg, pinfo->dwTime, CheckSpeedHack); // ޺ üũ + CheckComboHack(ch, pinfo->bArg, pinfo->dwTime, CheckSpeedHack); // 콤보 체크 } } @@ -1596,7 +1596,7 @@ void CInputMain::Move(LPCHARACTER ch, const char * data) if (ch->GetLimitPoint(POINT_MOV_SPEED) == 0) return; - ch->SetRotation(pinfo->bRot * 5); // ߺ ڵ + ch->SetRotation(pinfo->bRot * 5); // 중복 코드 ch->ResetStopTime(); // "" ch->Goto(pinfo->lX, pinfo->lY); @@ -1635,7 +1635,7 @@ void CInputMain::Move(LPCHARACTER ch, const char * data) ch->OnMove(); } - ch->SetRotation(pinfo->bRot * 5); // ߺ ڵ + ch->SetRotation(pinfo->bRot * 5); // 중복 코드 ch->ResetStopTime(); // "" ch->Move(pinfo->lX, pinfo->lY); @@ -1657,13 +1657,13 @@ void CInputMain::Move(LPCHARACTER ch, const char * data) ch->PacketAround(&pack, sizeof(TPacketGCMove), ch); /* - if (pinfo->dwTime == 10653691) // ߰ + if (pinfo->dwTime == 10653691) // 디버거 발견 { if (ch->GetDesc()->DelayedDisconnect(Random::get(15, 30))) LogManager::instance().HackLog("Debugger", ch); } - else if (pinfo->dwTime == 10653971) // Softice ߰ + else if (pinfo->dwTime == 10653971) // Softice 발견 { if (ch->GetDesc()->DelayedDisconnect(Random::get(15, 30))) LogManager::instance().HackLog("Softice", ch); @@ -1839,20 +1839,20 @@ int CInputMain::SyncPosition(LPCHARACTER ch, const char * c_pcData, size_t uiByt continue; } - // ˻ + // 소유권 검사 if (!victim->SetSyncOwner(ch)) continue; const float fDistWithSyncOwner = DISTANCE_SQRT( (victim->GetX() - ch->GetX()) / 100, (victim->GetY() - ch->GetY()) / 100 ); static const float fLimitDistWithSyncOwner = 2500.f + 1000.f; - // victim Ÿ 2500 + a ̸̻ . - // Ÿ : Ŭ̾Ʈ __GetSkillTargetRange, __GetBowRange Լ - // 2500 : ų proto Ÿ ų Ÿ, Ǵ Ȱ Ÿ - // a = POINT_BOW_DISTANCE ... ε ϴ 𸣰. ̳ , ų, Ʈ µ... - // ׷ Ȥó ϴ ۷ ؼ 1000.f ... + // victim과의 거리가 2500 + a 이상이면 핵으로 간주. + // 거리 참조 : 클라이언트의 __GetSkillTargetRange, __GetBowRange 함수 + // 2500 : 스킬 proto에서 가장 사거리가 긴 스킬의 사거리, 또는 활의 사거리 + // a = POINT_BOW_DISTANCE 값... 인데 실제로 사용하는 값인지는 잘 모르겠음. 아이템이나 포션, 스킬, 퀘스트에는 없는데... + // 그래도 혹시나 하는 마음에 버퍼로 사용할 겸해서 1000.f 로 둠... if (fDistWithSyncOwner > fLimitDistWithSyncOwner) { - // g_iSyncHackLimitCount . + // g_iSyncHackLimitCount번 까지는 봐줌. if (ch->GetSyncHackCount() < g_iSyncHackLimitCount) { ch->SetSyncHackCount(ch->GetSyncHackCount() + 1); @@ -1877,11 +1877,11 @@ int CInputMain::SyncPosition(LPCHARACTER ch, const char * c_pcData, size_t uiByt const timeval &tvLastSyncTime = victim->GetLastSyncTime(); timeval *tvDiff = timediff(&tvCurTime, &tvLastSyncTime); - // SyncPosition ǿϿ Ÿ ̻ ϱ Ͽ, - // g_lValidSyncInterval ms ̳ ٽ SyncPositionϷ ϸ . + // SyncPosition을 악용하여 타유저를 이상한 곳으로 보내는 핵 방어하기 위하여, + // 같은 유저를 g_lValidSyncInterval ms 이내에 다시 SyncPosition하려고 하면 핵으로 간주. if (tvDiff->tv_sec == 0 && tvDiff->tv_usec < g_lValidSyncInterval) { - // g_iSyncHackLimitCount . + // g_iSyncHackLimitCount번 까지는 봐줌. if (ch->GetSyncHackCount() < g_iSyncHackLimitCount) { ch->SetSyncHackCount(ch->GetSyncHackCount() + 1); @@ -1968,11 +1968,11 @@ void CInputMain::ScriptAnswer(LPCHARACTER ch, const void* c_pData) TPacketCGScriptAnswer * p = (TPacketCGScriptAnswer *) c_pData; SPDLOG_DEBUG("QUEST ScriptAnswer pid {} answer {}", ch->GetPlayerID(), p->answer); - if (p->answer > 250) // ư Ŷ + if (p->answer > 250) // 다음 버튼에 대한 응답으로 온 패킷인 경우 { quest::CQuestManager::Instance().Resume(ch->GetPlayerID()); } - else // ư Ŷ + else // 선택 버튼을 골라서 온 패킷인 경우 { quest::CQuestManager::Instance().Select(ch->GetPlayerID(), p->answer); } @@ -2115,9 +2115,9 @@ void CInputMain::SafeboxCheckout(LPCHARACTER ch, const char * c_pData, bool bMal if (!ch->IsEmptyItemGrid(p->ItemPos, pkItem->GetSize())) return; - // κ ű κп ȥ Ư ó - // ( item_proto ǵȴ Ӽ ٱ , - // ȥ , ó Ӽ ϳ ʰ ȴ.) + // 아이템 몰에서 인벤으로 옮기는 부분에서 용혼석 특수 처리 + // (몰에서 만드는 아이템은 item_proto에 정의된대로 속성이 붙기 때문에, + // 용혼석의 경우, 이 처리를 하지 않으면 속성이 하나도 붙지 않게 된다.) if (pkItem->IsDragonSoul()) { if (bMall) @@ -2163,7 +2163,7 @@ void CInputMain::SafeboxCheckout(LPCHARACTER ch, const char * c_pData, bool bMal SPDLOG_ERROR("pkItem->GetProto() == NULL (id : {})",pkItem->GetID()); return ; } - // 100% Ȯ Ӽ پ ϴµ پִٸ . ............... + // 100% 확률로 속성이 붙어야 하는데 안 붙어있다면 새로 붙힌다. ............... if (100 == pkItem->GetProto()->bAlterToMagicItemPct && 0 == pkItem->GetAttributeCount()) { pkItem->AlterToMagicItem(); @@ -2232,7 +2232,7 @@ void CInputMain::PartyInviteAnswer(LPCHARACTER ch, const char * c_pData) LPCHARACTER pInviter = CHARACTER_MANAGER::instance().Find(p->leader_vid); - // pInviter ch Ƽ û ߾. + // pInviter 가 ch 에게 파티 요청을 했었다. if (!pInviter) ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<\xC6\xC4\xC6\xBC> \xC6\xC4\xC6\xBC\xBF\xE4\xC3\xBB\xC0\xBB \xC7\xD1 \xC4\xB3\xB8\xAF\xC5\xCD\xB8\xA6 \xC3\xA3\xC0\xBB\xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9.")); @@ -2554,7 +2554,7 @@ int CInputMain::Guild(LPCHARACTER ch, const char * data, size_t uiBytes) { case GUILD_SUBHEADER_CG_DEPOSIT_MONEY: { - // by mhh : ڱ а . + // by mhh : 길드자금은 당분간 넣을 수 없다. return SubPacketLen; const int gold = std::min(*reinterpret_cast(c_pData), __deposit_limit()); @@ -2577,7 +2577,7 @@ int CInputMain::Guild(LPCHARACTER ch, const char * data, size_t uiBytes) case GUILD_SUBHEADER_CG_WITHDRAW_MONEY: { - // by mhh : ڱ а . + // by mhh : 길드자금은 당분간 뺄 수 없다. return SubPacketLen; const int gold = std::min(*reinterpret_cast(c_pData), 500000); @@ -2773,7 +2773,7 @@ int CInputMain::Guild(LPCHARACTER ch, const char * data, size_t uiBytes) if (length > GUILD_COMMENT_MAX_LEN) { - // ߸ .. . + // 잘못된 길이.. 끊어주자. SPDLOG_ERROR("POST_COMMENT: {} comment too long (length: {})", ch->GetName(), length); ch->GetDesc()->SetPhase(PHASE_CLOSE); return -1; diff --git a/src/game/src/input_p2p.cpp b/src/game/src/input_p2p.cpp index b522058..efa9082 100644 --- a/src/game/src/input_p2p.cpp +++ b/src/game/src/input_p2p.cpp @@ -67,7 +67,7 @@ int CInputP2P::Relay(LPDESC d, const char * c_pData, size_t uiBytes) { if (pkChr->IsBlockMode(BLOCK_WHISPER)) { - // ӼӸ ź ¿ ӼӸ ź. + // 귓속말 거부 상태에서 귓속말 거부. return p->lSize; } @@ -75,12 +75,12 @@ int CInputP2P::Relay(LPDESC d, const char * c_pData, size_t uiBytes) memcpy(buf, c_pbData, std::min(p->lSize, sizeof(buf))); TPacketGCWhisper* p2 = (TPacketGCWhisper*) buf; - // bType 4Ʈ: Empire ȣ - // bType 4Ʈ: EWhisperType + // bType 상위 4비트: Empire 번호 + // bType 하위 4비트: EWhisperType BYTE bToEmpire = (p2->bType >> 4); p2->bType = p2->bType & 0x0F; if(p2->bType == 0x0F) { - // ý ޼ ӼӸ bType Ʈ . + // 시스템 메세지 귓속말은 bType의 상위비트까지 모두 사용함. p2->bType = WHISPER_TYPE_SYSTEM; } else { if (!pkChr->IsEquipUniqueGroup(UNIQUE_GROUP_RING_OF_LANGUAGE)) @@ -338,7 +338,7 @@ void CInputP2P::XmasWarpSanta(const char * c_pData) else iNextSpawnDelay = 50 * 60; - xmas::SpawnSanta(p->lMapIndex, iNextSpawnDelay); // 50ִٰ ο Ÿ Ÿ (ѱ 20) + xmas::SpawnSanta(p->lMapIndex, iNextSpawnDelay); // 50분있다가 새로운 산타가 나타남 (한국은 20분) TPacketGGXmasWarpSantaReply pack_reply; pack_reply.bHeader = HEADER_GG_XMAS_WARP_SANTA_REPLY; diff --git a/src/game/src/item.cpp b/src/game/src/item.cpp index 481f9ba..4c38efa 100644 --- a/src/game/src/item.cpp +++ b/src/game/src/item.cpp @@ -294,7 +294,7 @@ LPITEM CItem::RemoveFromCharacter() LPCHARACTER pOwner = m_pOwner; - if (m_bEquipped) // Ǿ°? + if (m_bEquipped) // 장착되었는가? { Unequip(); //pOwner->UpdatePacket(); @@ -318,7 +318,7 @@ LPITEM CItem::RemoveFromCharacter() { TItemPos cell(INVENTORY, m_wCell); - if (false == cell.IsDefaultInventoryPosition() && false == cell.IsBeltInventoryPosition()) // ƴϸ ǰ? + if (false == cell.IsDefaultInventoryPosition() && false == cell.IsBeltInventoryPosition()) // 아니면 소지품에? SPDLOG_ERROR("CItem::RemoveFromCharacter: Invalid Item Position"); else { @@ -470,16 +470,16 @@ bool CItem::CanUsedBy(LPCHARACTER ch) int CItem::FindEquipCell(LPCHARACTER ch, int iCandidateCell) { - // ڽ (ITEM_COSTUME) WearFlag  . (sub type ġ . wear flag ʿ䰡 ֳ..) - // ȥ(ITEM_DS, ITEM_SPECIAL_DS) SUB_TYPE . ű , Ʈ ITEM_TYPE -_- + // 코스츔 아이템(ITEM_COSTUME)은 WearFlag 없어도 됨. (sub type으로 착용위치 구분. 귀찮게 또 wear flag 줄 필요가 있나..) + // 용혼석(ITEM_DS, ITEM_SPECIAL_DS)도 SUB_TYPE으로 구분. 신규 반지, 벨트는 ITEM_TYPE으로 구분 -_- if ((0 == GetWearFlag() || ITEM_TOTEM == GetType()) && ITEM_COSTUME != GetType() && ITEM_DS != GetType() && ITEM_SPECIAL_DS != GetType() && ITEM_RING != GetType() && ITEM_BELT != GetType()) return -1; - // ȥ WEAR ó (WEAR ִ 32 ѵ ȥ ߰ϸ 32 Ѵ´.) - // κ丮 Ư ġ((INVENTORY_MAX_NUM + WEAR_MAX_NUM) (INVENTORY_MAX_NUM + WEAR_MAX_NUM + DRAGON_SOUL_DECK_MAX_NUM * DS_SLOT_MAX - 1)) - // ȥ . - // return , INVENTORY_MAX_NUM , - // WearCell INVENTORY_MAX_NUM return ϱ . + // 용혼석 슬롯을 WEAR로 처리할 수가 없어서(WEAR는 최대 32개까지 가능한데 용혼석을 추가하면 32가 넘는다.) + // 인벤토리의 특정 위치((INVENTORY_MAX_NUM + WEAR_MAX_NUM)부터 (INVENTORY_MAX_NUM + WEAR_MAX_NUM + DRAGON_SOUL_DECK_MAX_NUM * DS_SLOT_MAX - 1)까지)를 + // 용혼석 슬롯으로 정함. + // return 할 때에, INVENTORY_MAX_NUM을 뺀 이유는, + // 본래 WearCell이 INVENTORY_MAX_NUM를 빼고 return 하기 때문. if (GetType() == ITEM_DS || GetType() == ITEM_SPECIAL_DS) { if (iCandidateCell < 0) @@ -540,7 +540,7 @@ int CItem::FindEquipCell(LPCHARACTER ch, int iCandidateCell) return WEAR_UNIQUE1; } - // Ʈ ° ѹ ?E . + // 수집 퀘스트를 위한 아이템이 박히는곳으로 한번 박히면 절대 ?E수 없다. else if (GetWearFlag() & WEARABLE_ABILITY) { if (!ch->GetWear(WEAR_ABILITY1)) @@ -587,12 +587,12 @@ void CItem::ModifyPoints(bool bAdd) { int accessoryGrade; - // ʸ Ų. + // 무기와 갑옷만 소켓을 적용시킨다. if (false == IsAccessoryForSocket()) { if (m_pProto->bType == ITEM_WEAPON || m_pProto->bType == ITEM_ARMOR) { - // Ӽȭ Ǵ ʴ´ (ARMOR_WRIST ARMOR_NECK ARMOR_EAR) + // 소켓이 속성강화에 사용되는 경우 적용하지 않는다 (ARMOR_WRIST ARMOR_NECK ARMOR_EAR) for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i) { DWORD dwVnum; @@ -651,12 +651,12 @@ void CItem::ModifyPoints(bool bAdd) m_pOwner->ApplyPoint(m_pProto->aApplies[i].bType, bAdd ? value : -value); } } - // ʽ´ , ҷ , ູ , Ʈ - // ϵ ڵ Ӽ ο, - // κ ϰ special item group ̺ Ӽ οϵ Ͽ. - // ϵ ڵǾ ־ Ưó س´. - // ۵ , ؿ ITEM_UNIQUE ó Ӽ οDZ , - // ۿ ִ attribute ʰ Ѿ. + // 초승달의 반지, 할로윈 사탕, 행복의 반지, 영원한 사랑의 펜던트의 경우 + // 기존의 하드 코딩으로 강제로 속성을 부여했지만, + // 그 부분을 제거하고 special item group 테이블에서 속성을 부여하도록 변경하였다. + // 하지만 하드 코딩되어있을 때 생성된 아이템이 남아있을 수도 있어서 특수처리 해놓는다. + // 이 아이템들의 경우, 밑에 ITEM_UNIQUE일 때의 처리로 속성이 부여되기 때문에, + // 아이템에 박혀있는 attribute는 적용하지 않고 넘어간다. if (true == CItemVnumHelper::IsRamadanMoonRing(GetVnum()) || true == CItemVnumHelper::IsHalloweenCandy(GetVnum()) || true == CItemVnumHelper::IsHappinessRing(GetVnum()) || true == CItemVnumHelper::IsLovePendant(GetVnum())) { @@ -713,7 +713,7 @@ void CItem::ModifyPoints(bool bAdd) case ITEM_ARMOR: { - // ڽ body ԰ִٸ armor Դ ־ ָ . + // 코스츔 body를 입고있다면 armor는 벗던 입던 상관 없이 비주얼에 영향을 주면 안 됨. if (0 != m_pOwner->GetWear(WEAR_COSTUME_BODY)) break; @@ -733,33 +733,33 @@ void CItem::ModifyPoints(bool bAdd) } break; - // ڽ Ծ ij parts . Ÿϴ ߰.. + // 코스츔 아이템 입었을 때 캐릭터 parts 정보 세팅. 기존 스타일대로 추가함.. case ITEM_COSTUME: { DWORD toSetValue = this->GetVnum(); EParts toSetPart = PART_MAX_NUM; - // ڽ + // 갑옷 코스츔 if (GetSubType() == COSTUME_BODY) { toSetPart = PART_MAIN; if (false == bAdd) { - // ڽ ԰ ־ٸ look , ʾҴٸ default look + // 코스츔 갑옷을 벗었을 때 원래 갑옷을 입고 있었다면 그 갑옷으로 look 세팅, 입지 않았다면 default look const CItem* pArmor = m_pOwner->GetWear(WEAR_BODY); toSetValue = (NULL != pArmor) ? pArmor->GetVnum() : m_pOwner->GetOriginalPart(PART_MAIN); } } - // ڽ + // 헤어 코스츔 else if (GetSubType() == COSTUME_HAIR) { toSetPart = PART_HAIR; - // ڽ shape item proto value3 ϵ . Ư (ARMOR_BODY) shape value3 ־  value3 . - // [NOTE] vnum shape(value3) .. ý ׷ Ǿ... + // 코스츔 헤어는 shape값을 item proto의 value3에 세팅하도록 함. 특별한 이유는 없고 기존 갑옷(ARMOR_BODY)의 shape값이 프로토의 value3에 있어서 헤어도 같이 value3으로 함. + // [NOTE] 갑옷은 아이템 vnum을 보내고 헤어는 shape(value3)값을 보내는 이유는.. 기존 시스템이 그렇게 되어있음... toSetValue = (true == bAdd) ? this->GetValue(3) : 0; } @@ -820,7 +820,7 @@ bool CItem::EquipTo(LPCHARACTER ch, BYTE bWearCell) return false; } - // ȥ index WEAR_MAX_NUM ŭ. + // 용혼석 슬롯 index는 WEAR_MAX_NUM 보다 큼. if (IsDragonSoul()) { if (bWearCell < WEAR_MAX_NUM || bWearCell >= WEAR_MAX_NUM + DRAGON_SOUL_DECK_MAX_NUM * DS_SLOT_MAX) @@ -847,7 +847,7 @@ bool CItem::EquipTo(LPCHARACTER ch, BYTE bWearCell) if (GetOwner()) RemoveFromCharacter(); - ch->SetWear(bWearCell, this); // ⼭ Ŷ + ch->SetWear(bWearCell, this); // 여기서 패킷 나감 m_pOwner = ch; m_bEquipped = true; @@ -905,7 +905,7 @@ bool CItem::Unequip() return false; } - //ű Ž ó + //신규 말 아이템 제거시 처리 if (IsRideItem()) ClearMountAttributeAndAffect(); @@ -1209,7 +1209,7 @@ void CItem::AlterToMagicItem() } } - // 100% Ȯ Ӽ ϳ + // 100% 확률로 좋은 속성 하나 PutAttribute(aiItemMagicAttributePercentHigh); if (Random::get(1, 100) <= iSecondPct) @@ -1295,8 +1295,8 @@ EVENTFUNC(unique_expire_event) } else { - // ð ۵ ϰ ʴ װ ־ - // + // 게임 내에 시간제 아이템들이 빠릿빠릿하게 사라지지 않는 버그가 있어 + // 수정 // by rtsummit if (pkItem->GetSocket(ITEM_SOCKET_UNIQUE_REMAIN_TIME) - cur < 600) return PASSES_PER_SEC(pkItem->GetSocket(ITEM_SOCKET_UNIQUE_REMAIN_TIME) - cur); @@ -1306,9 +1306,9 @@ EVENTFUNC(unique_expire_event) } } -// ð ĺ -// timer ð ϴ ƴ϶, -// timer ȭ timer ð ŭ ð Ѵ. +// 시간 후불제 +// timer를 시작할 때에 시간 차감하는 것이 아니라, +// timer가 발화할 때에 timer가 동작한 시간 만큼 시간 차감을 한다. EVENTFUNC(timer_based_on_wear_expire_event) { item_event_info* info = dynamic_cast( event->info ); @@ -1327,7 +1327,7 @@ EVENTFUNC(timer_based_on_wear_expire_event) pkItem->SetTimerBasedOnWearExpireEvent(NULL); pkItem->SetSocket(ITEM_SOCKET_REMAIN_SEC, 0); - // ϴ timer based on wear ȥ ð Ǿٰ ʴ´. + // 일단 timer based on wear 용혼석은 시간 다 되었다고 없애지 않는다. if (pkItem->IsDragonSoul()) { DSManager::instance().DeactivateDragonSoul(pkItem); @@ -1419,7 +1419,7 @@ void CItem::StartUniqueExpireEvent() if (m_pkUniqueExpireEvent) return; - //Ⱓ ð ʴ´ + //기간제 아이템일 경우 시간제 아이템은 동작하지 않는다 if (IsRealTimeItem()) return; @@ -1442,14 +1442,14 @@ void CItem::StartUniqueExpireEvent() SetUniqueExpireEvent(event_create(unique_expire_event, info, PASSES_PER_SEC(iSec))); } -// ð ĺ -// timer_based_on_wear_expire_event +// 시간 후불제 +// timer_based_on_wear_expire_event 설명 참조 void CItem::StartTimerBasedOnWearExpireEvent() { if (m_pkTimerBasedOnWearExpireEvent) return; - //Ⱓ ð ʴ´ + //기간제 아이템일 경우 시간제 아이템은 동작하지 않는다 if (IsRealTimeItem()) return; @@ -1458,7 +1458,7 @@ void CItem::StartTimerBasedOnWearExpireEvent() int iSec = GetSocket(0); - // ð д ... + // 남은 시간을 분단위로 끊기 위해... if (0 != iSec) { iSec %= 60; @@ -1477,7 +1477,7 @@ void CItem::StopUniqueExpireEvent() if (!m_pkUniqueExpireEvent) return; - if (GetValue(2) != 0) // ӽð ̿ UniqueExpireEvent ߴ . + if (GetValue(2) != 0) // 게임시간제 이외의 아이템은 UniqueExpireEvent를 중단할 수 없다. return; // HARD CODING @@ -1514,12 +1514,12 @@ int CItem::GetSpecialGroup() const } // -// Ǽ ó. +// 악세서리 소켓 처리. // bool CItem::IsAccessoryForSocket() { return (m_pProto->bType == ITEM_ARMOR && (m_pProto->bSubType == ARMOR_WRIST || m_pProto->bSubType == ARMOR_NECK || m_pProto->bSubType == ARMOR_EAR)) || - (m_pProto->bType == ITEM_BELT); // 2013 2 ߰ 'Ʈ' ȹ Ǽ ý ״ ̿ڰ . + (m_pProto->bType == ITEM_BELT); // 2013년 2월 새로 추가된 '벨트' 아이템의 경우 기획팀에서 악세서리 소켓 시스템을 그대로 이용하자고 함. } void CItem::SetAccessorySocketGrade(int iGrade) @@ -1664,7 +1664,7 @@ void CItem::ClearMountAttributeAndAffect() } // fixme -// ̰ Ⱦ... ٵ Ȥó ; ܵ. +// 이거 지금은 안쓴데... 근데 혹시나 싶어서 남겨둠. // by rtsummit bool CItem::IsNewMountItem() { @@ -1711,7 +1711,7 @@ void CItem::AccessorySocketDegrade() } } -// ring item ִ θ üũؼ +// ring에 item을 박을 수 있는지 여부를 체크해서 리턴 static const bool CanPutIntoRing(LPITEM ring, LPITEM item) { const DWORD vnum = item->GetVnum(); @@ -1932,10 +1932,10 @@ int CItem::GetLevelLimit() bool CItem::OnAfterCreatedItem() { - // ̶ ߴٸ, Ŀ ʾƵ ð Ǵ + // 아이템을 한 번이라도 사용했다면, 그 이후엔 사용 중이지 않아도 시간이 차감되는 방식 if (-1 != this->GetProto()->cLimitRealTimeFirstUseIndex) { - // Socket1 Ƚ ϵǾ , ̶ Ÿ̸Ӹ Ѵ. + // Socket1에 아이템의 사용 횟수가 기록되어 있으니, 한 번이라도 사용한 아이템은 타이머를 시작한다. if (0 != GetSocket(1)) { StartRealTimeExpireEvent(); @@ -1948,8 +1948,8 @@ bool CItem::OnAfterCreatedItem() #ifdef __AUCTION__ -// -// window Ѵ. +// 경매장 +// window를 경매장으로 한다. bool CItem::MoveToAuction() { @@ -2016,7 +2016,7 @@ int CItem::GiveMoreTime_Per(float fPercent) return given_time; } } - // 켱 ȥ ؼ ϵ Ѵ. + // 우선 용혼석에 관해서만 하도록 한다. else return 0; } @@ -2040,7 +2040,7 @@ int CItem::GiveMoreTime_Fix(DWORD dwTime) return dwTime; } } - // 켱 ȥ ؼ ϵ Ѵ. + // 우선 용혼석에 관해서만 하도록 한다. else return 0; } @@ -2065,7 +2065,7 @@ int CItem::GetDuration() bool CItem::IsSameSpecialGroup(const LPITEM item) const { - // VNUM ٸ ׷ + // 서로 VNUM이 같다면 같은 그룹인 것으로 간주 if (this->GetVnum() == item->GetVnum()) return true; diff --git a/src/game/src/item_addon.cpp b/src/game/src/item_addon.cpp index 5e66ff4..9dc5317 100644 --- a/src/game/src/item_addon.cpp +++ b/src/game/src/item_addon.cpp @@ -20,7 +20,7 @@ void CItemAddonManager::ApplyAddonTo(int iAddonType, LPITEM pItem) return; } - // TODO ϴ ϵڵ Ÿ ų ġ 游 츸 ްѴ. + // TODO 일단 하드코딩으로 평타 스킬 수치 변경만 경우만 적용받게한다. int iSkillBonus = std::clamp((int) (Random::get>(0, 5) + 0.5f), -30, 30); int iNormalHitBonus = 0; diff --git a/src/game/src/item_attribute.cpp b/src/game/src/item_attribute.cpp index 095b1cc..3b00128 100644 --- a/src/game/src/item_attribute.cpp +++ b/src/game/src/item_attribute.cpp @@ -24,7 +24,7 @@ int CItem::GetAttributeSetIndex() switch (GetSubType()) { case ARMOR_BODY: -// case COSTUME_BODY: // ڽ Ϲ ʰ Attribute Set ̿Ͽ Ӽ (ARMOR_BODY == COSTUME_BODY) +// case COSTUME_BODY: // 코스츔 갑옷은 일반 갑옷과 동일한 Attribute Set을 이용하여 랜덤속성 붙음 (ARMOR_BODY == COSTUME_BODY) return ATTRIBUTE_SET_BODY; case ARMOR_WRIST: @@ -37,7 +37,7 @@ int CItem::GetAttributeSetIndex() return ATTRIBUTE_SET_NECK; case ARMOR_HEAD: -// case COSTUME_HAIR: // ڽ Ϲ ۰ Attribute Set ̿Ͽ Ӽ (ARMOR_HEAD == COSTUME_HAIR) +// case COSTUME_HAIR: // 코스츔 헤어는 일반 투구 아이템과 동일한 Attribute Set을 이용하여 랜덤속성 붙음 (ARMOR_HEAD == COSTUME_HAIR) return ATTRIBUTE_SET_HEAD; case ARMOR_SHIELD: @@ -125,7 +125,7 @@ void CItem::PutAttributeWithLevel(BYTE bLevel) int total = 0; - // ִ Ӽ 迭 + // 붙일 수 있는 속성 배열을 구축 for (int i = 0; i < MAX_APPLY_NUM; ++i) { const TItemAttrTable & r = g_map_itemAttr[i]; @@ -137,7 +137,7 @@ void CItem::PutAttributeWithLevel(BYTE bLevel) } } - // 迭 Ȯ Ӽ + // 구축된 배열로 확률 계산을 통해 붙일 속성 선정 unsigned int prob = Random::get(1, total); int attr_idx = APPLY_NONE; @@ -162,7 +162,7 @@ void CItem::PutAttributeWithLevel(BYTE bLevel) const TItemAttrTable & r = g_map_itemAttr[attr_idx]; - // Ӽ ִ밪 + // 종류별 속성 레벨 최대값 제한 if (bLevel > r.bMaxLevelBySet[iAttributeSet]) bLevel = r.bMaxLevelBySet[iAttributeSet]; diff --git a/src/game/src/item_manager.cpp b/src/game/src/item_manager.cpp index a11c2a1..48def27 100644 --- a/src/game/src/item_manager.cpp +++ b/src/game/src/item_manager.cpp @@ -80,7 +80,7 @@ bool ITEM_MANAGER::Initialize(TItemTable * table, int size) if (m_vec_prototype[i].dwRefinedVnum) m_map_ItemRefineFrom.insert(std::make_pair(m_vec_prototype[i].dwRefinedVnum, m_vec_prototype[i].dwVnum)); - // NOTE : QUEST_GIVE ÷״ npc ̺Ʈ ߻. + // NOTE : QUEST_GIVE 플래그는 npc 이벤트로 발생. if (m_vec_prototype[i].bType == ITEM_QUEST || IS_SET(m_vec_prototype[i].dwFlags, ITEM_FLAG_QUEST_USE | ITEM_FLAG_QUEST_USE_MULTIPLE)) quest::CQuestManager::instance().RegisterNPCVnum(m_vec_prototype[i].dwVnum); @@ -155,7 +155,7 @@ LPITEM ITEM_MANAGER::CreateItem(DWORD vnum, DWORD count, DWORD id, bool bTryMagi { if (vnum == 50300 && bTryMagic) { - // ü ȣ ٸ ش. + // 수련서를 아이템 번호를 다르게 만들어 준다. DWORD dwSkillVnum; do @@ -181,7 +181,7 @@ LPITEM ITEM_MANAGER::CreateItem(DWORD vnum, DWORD count, DWORD id, bool bTryMagi LPITEM item = NULL; - //id ˻ؼ Ѵٸ -- ! + //id로 검사해서 존재한다면 -- 리턴! if (m_map_pkItemByID.find(id) != m_map_pkItemByID.end()) { item = m_map_pkItemByID[id]; @@ -190,7 +190,7 @@ LPITEM ITEM_MANAGER::CreateItem(DWORD vnum, DWORD count, DWORD id, bool bTryMagi return NULL; } - // ϳ Ҵϰ + //아이템 하나 할당하고 #ifdef M2_USE_POOL item = pool_.Construct(); #else @@ -199,15 +199,15 @@ LPITEM ITEM_MANAGER::CreateItem(DWORD vnum, DWORD count, DWORD id, bool bTryMagi bool bIsNewItem = (0 == id); - //ʱȭ ϰ. ̺ ϰ + //초기화 하고. 테이블 셋하고 item->Initialize(); item->SetProto(table); item->SetMaskVnum(dwMaskVnum); - if (item->GetType() == ITEM_ELK) // ID ʿ 嵵 ʿ. + if (item->GetType() == ITEM_ELK) // 돈은 ID가 필요없고 저장도 필요없다. item->SetSkipSave(true); - // Unique ID + // Unique ID를 세팅하자 else if (!bIsNewItem) { item->SetID(id); @@ -217,16 +217,16 @@ LPITEM ITEM_MANAGER::CreateItem(DWORD vnum, DWORD count, DWORD id, bool bTryMagi { item->SetID(GetNewID()); - if (item->GetType() == ITEM_UNIQUE) // ũ ÿ Ͽ ð Ѵ. + if (item->GetType() == ITEM_UNIQUE) // 유니크 아이템은 생성시에 소켓에 남은시간을 기록한다. { if (item->GetValue(2) == 0) - item->SetSocket(ITEM_SOCKET_UNIQUE_REMAIN_TIME, item->GetValue(0)); // ð ũ + item->SetSocket(ITEM_SOCKET_UNIQUE_REMAIN_TIME, item->GetValue(0)); // 게임 시간 유니크 else { //int globalTime = get_global_time(); //int lastTime = item->GetValue(0); //int endTime = get_global_time() + item->GetValue(0); - item->SetSocket(ITEM_SOCKET_UNIQUE_REMAIN_TIME, get_global_time() + item->GetValue(0)); // ǽð ũ + item->SetSocket(ITEM_SOCKET_UNIQUE_REMAIN_TIME, get_global_time() + item->GetValue(0)); // 실시간 유니크 } } } @@ -255,9 +255,9 @@ LPITEM ITEM_MANAGER::CreateItem(DWORD vnum, DWORD count, DWORD id, bool bTryMagi break; } - if (item->GetType() == ITEM_ELK) // ƹ ó ʿ + if (item->GetType() == ITEM_ELK) // 돈은 아무 처리가 필요하지 않음 ; - else if (item->IsStackable()) // ĥ ִ + else if (item->IsStackable()) // 합칠 수 있는 아이템의 경우 { count = std::clamp(count, 1, ITEM_MAX_COUNT); @@ -285,7 +285,7 @@ LPITEM ITEM_MANAGER::CreateItem(DWORD vnum, DWORD count, DWORD id, bool bTryMagi for (int i=0 ; i < ITEM_LIMIT_MAX_NUM ; i++) { - // ʾƵ ð Ǵ + // 아이템 생성 시점부터 사용하지 않아도 시간이 차감되는 방식 if (LIMIT_REAL_TIME == item->GetLimitType(i)) { if (item->GetLimitValue(i)) @@ -300,11 +300,11 @@ LPITEM ITEM_MANAGER::CreateItem(DWORD vnum, DWORD count, DWORD id, bool bTryMagi item->StartRealTimeExpireEvent(); } - // ũ ó ÿ 밡 ð Ǵ + // 기존 유니크 아이템처럼 착용시에만 사용가능 시간이 차감되는 방식 else if (LIMIT_TIMER_BASED_ON_WEAR == item->GetLimitType(i)) { - // ̹ ̸ Ÿ̸Ӹ ϰ, ð ش. ( - // ۸ ϴ 쿡 Socket0 Ǿ ־ Ѵ. + // 이미 착용중인 아이템이면 타이머를 시작하고, 새로 만드는 아이템은 사용 가능 시간을 세팅해준다. ( + // 아이템몰로 지급하는 경우에는 이 로직에 들어오기 전에 Socket0 값이 세팅이 되어 있어야 한다. if (true == item->IsEquipped()) { item->StartTimerBasedOnWearExpireEvent(); @@ -316,16 +316,16 @@ LPITEM ITEM_MANAGER::CreateItem(DWORD vnum, DWORD count, DWORD id, bool bTryMagi duration = item->GetLimitValue(i); if (0 == duration) - duration = 60 * 60 * 10; // ƹ͵ Ʈ 10ð + duration = 60 * 60 * 10; // 정보가 아무것도 없으면 디폴트로 10시간 세팅 item->SetSocket(0, duration); } } } - if (id == 0) // ó + if (id == 0) // 새로 만드는 아이템일 때만 처리 { - // ߰Ǵ ʵϰ ٸó + // 새로추가되는 약초들일경우 성능을 다르게처리 if (ITEM_BLEND==item->GetType()) { if (Blend_Item_find(item->GetVnum())) @@ -352,7 +352,7 @@ LPITEM ITEM_MANAGER::CreateItem(DWORD vnum, DWORD count, DWORD id, bool bTryMagi if (table->bGainSocketPct) item->AlterToSocketItem(table->bGainSocketPct); - // 50300 == ü + // 50300 == 기술 수련서 if (vnum == 50300 || vnum == ITEM_SKILLFORGET_VNUM) { DWORD dwSkillVnum; @@ -404,7 +404,7 @@ LPITEM ITEM_MANAGER::CreateItem(DWORD vnum, DWORD count, DWORD id, bool bTryMagi } } - // Ǵ ȥ ó. + // 새로 생성되는 용혼석 처리. if (item->IsDragonSoul() && 0 == id) { DSManager::instance().DragonSoulItemInitialize(item); @@ -473,7 +473,7 @@ void ITEM_MANAGER::Update() this_it = it++; LPITEM item = *this_it; - // SLOW_QUERY ÷װ ִ ÿ Ѵ. + // SLOW_QUERY 플래그가 있는 것은 종료시에만 저장한다. if (item->GetOwner() && IS_SET(item->GetFlag(), ITEM_FLAG_SLOW_QUERY)) continue; @@ -496,7 +496,7 @@ void ITEM_MANAGER::RemoveItem(LPITEM item, const char * c_pszReason) // SAFEBOX_TIME_LIMIT_ITEM_BUG_FIX if (item->GetWindow() == MALL || item->GetWindow() == SAFEBOX) { - // 20050613.ipkn.ð ð ٿȴ. + // 20050613.ipkn.시간제 아이템이 상점에 있을 경우 시간만료시 서버가 다운된다. CSafebox* pSafebox = item->GetWindow() == MALL ? o->GetMall() : o->GetSafebox(); if (pSafebox) { @@ -760,8 +760,8 @@ class CItemDropInfo extern std::vector g_vec_pkCommonDropItem[MOB_RANK_MAX_NUM]; // 20050503.ipkn. -// iMinimum iDefault (, iMinimum 0 Ŀ) -// 1, 0 ON/OFF Ǵ ϱ +// iMinimum 보다 작으면 iDefault 세팅 (단, iMinimum은 0보다 커야함) +// 1, 0 식으로 ON/OFF 되는 방식을 지원하기 위해 존재 int GetDropPerKillPct(int iMinimum, int iDefault, int iDeltaPercent, const char * c_pszFlag) { int iVal = 0; @@ -781,8 +781,8 @@ int GetDropPerKillPct(int iMinimum, int iDefault, int iDeltaPercent, const char if (iVal == 0) return 0; - // ⺻ ϶ (iDeltaPercent=100) - // 40000 iVal ϳ ֱ + // 기본 세팅일때 (iDeltaPercent=100) + // 40000 iVal 마리당 하나 느낌을 주기 위한 상수임 return (40000 * iDeltaPercent / iVal); } @@ -930,7 +930,7 @@ bool ITEM_MANAGER::CreateDropItem(LPCHARACTER pkChr, LPCHARACTER pkKiller, std:: CMobItemGroup* pGroup = it->second; // MOB_DROP_ITEM_BUG_FIX - // 20050805.myevan.MobDropItem CMobItemGroup::GetOne() ٽ ߻ + // 20050805.myevan.MobDropItem 에 아이템이 없을 경우 CMobItemGroup::GetOne() 접근시 문제 발생 수정 if (pGroup && !pGroup->IsEmpty()) { int iPercent = 40000 * iDeltaPercent / pGroup->GetKillPerDrop(); @@ -997,7 +997,7 @@ bool ITEM_MANAGER::CreateDropItem(LPCHARACTER pkChr, LPCHARACTER pkKiller, std:: } } - // + // 잡템 if (pkChr->GetMobDropItemVnum()) { itertype(m_map_dwEtcItemDropProb) it = m_map_dwEtcItemDropProb.find(pkChr->GetMobDropItemVnum()); @@ -1046,14 +1046,14 @@ bool ITEM_MANAGER::CreateDropItem(LPCHARACTER pkChr, LPCHARACTER pkKiller, std:: pdw[1] = 1; pdw[2] = quest::CQuestManager::instance().GetEventFlag("lotto_round"); - // Ѵ + // 행운의 서는 소켓을 설정한다 DBManager::instance().ReturnQuery(QID_LOTTO, pkKiller->GetPlayerID(), pdw, "INSERT INTO lotto_list VALUES(0, 'server%s', %u, NOW())", get_table_postfix(), pkKiller->GetPlayerID()); } // - // + // 스페셜 드롭 아이템 // CreateQuestDropItem(pkChr, pkKiller, vec_item, iDeltaPercent, iRandRange); @@ -1064,7 +1064,7 @@ bool ITEM_MANAGER::CreateDropItem(LPCHARACTER pkChr, LPCHARACTER pkKiller, std:: } // - // · õǵ 2 + // 승룡곡 천의동굴 2층에서만 수룡방 입장권 // if (LC_IsYMIR() || LC_IsKorea()) { @@ -1081,21 +1081,21 @@ bool ITEM_MANAGER::CreateDropItem(LPCHARACTER pkChr, LPCHARACTER pkKiller, std:: } // - // · 1, 2 7,8 ųԹ + // 승룡곡 1층, 2층에서만 7,8 스킬입문서 드롭 // if (LC_IsYMIR() || LC_IsKorea()) { switch (pkKiller->GetMapIndex()) { - case 72: // õǵ 1 - case 73: // õǵ 2 + case 72: // 천의동굴 1층 + case 73: // 천의동굴 2층 { int vnum = 0; - if (2403 == pkChr->GetRaceNum()) // õǹ - vnum = 69200; // 7ų Թ - else if (2411 == pkChr->GetRaceNum()) // õǺ - vnum = 69201; // 8ų Թ + if (2403 == pkChr->GetRaceNum()) // 천의법사 + vnum = 69200; // 7스킬 입문서 + else if (2411 == pkChr->GetRaceNum()) // 진천의병사 + vnum = 69201; // 8스킬 입문서 else break; @@ -1250,11 +1250,11 @@ bool DropEvent_CharStone_SetValue(const std::string& name, int value) // END_OF_DROPEVENT_CHARSTONE // fixme -// Ͱ Բ quest . -// ̰ ʹ ݾ... -// ??.. ϵڵ ȴ ̤ -// 跮 . -// by rtsummit ġ ¥ +// 위의 것과 함께 quest로 뺄것 빼보자. +// 이거 너무 더럽잖아... +// ??.. 하드코딩 싫다 ㅜㅠ +// 계량 아이템 보상 시작. +// by rtsummit 고치자 진짜 static struct DropEvent_RefineBox { int percent_low; @@ -1371,7 +1371,7 @@ bool DropEvent_RefineBox_SetValue(const std::string& name, int value) return true; } -// . +// 개량 아이템 보상 끝. void ITEM_MANAGER::CreateQuestDropItem(LPCHARACTER pkChr, LPCHARACTER pkKiller, std::vector & vec_item, int iDeltaPercent, int iRandRange) @@ -1391,7 +1391,7 @@ void ITEM_MANAGER::CreateQuestDropItem(LPCHARACTER pkChr, LPCHARACTER pkKiller, // END_OF_DROPEVENT_CHARSTONE __DropEvent_RefineBox_DropItem(*pkKiller, *pkChr, *this, vec_item); - // ũ 縻 + // 크리스마스 양말 if (quest::CQuestManager::instance().GetEventFlag("xmas_sock")) { //const DWORD SOCK_ITEM_VNUM = 50010; @@ -1433,7 +1433,7 @@ void ITEM_MANAGER::CreateQuestDropItem(LPCHARACTER pkChr, LPCHARACTER pkKiller, } } - // + // 월광 보합 if (quest::CQuestManager::instance().GetEventFlag("drop_moon")) { const DWORD ITEM_VNUM = 50011; @@ -1479,7 +1479,7 @@ void ITEM_MANAGER::CreateQuestDropItem(LPCHARACTER pkChr, LPCHARACTER pkKiller, } } - // + //육각보합 if (GetDropPerKillPct(100, g_iUseLocale ? 2000 : 800, iDeltaPercent, "2006_drop") >= Random::get(1, iRandRange)) { SPDLOG_DEBUG("\xC0\xB0\xB0\xA2\xBA\xB8\xC7\xD5 DROP EVENT "); @@ -1491,7 +1491,7 @@ void ITEM_MANAGER::CreateQuestDropItem(LPCHARACTER pkChr, LPCHARACTER pkKiller, } - //+ + //육각보합+ if (GetDropPerKillPct(100, g_iUseLocale ? 2000 : 800, iDeltaPercent, "2007_drop") >= Random::get(1, iRandRange)) { SPDLOG_DEBUG("\xC0\xB0\xB0\xA2\xBA\xB8\xC7\xD5 DROP EVENT "); @@ -1502,17 +1502,17 @@ void ITEM_MANAGER::CreateQuestDropItem(LPCHARACTER pkChr, LPCHARACTER pkKiller, vec_item.push_back(item); } - // ̺Ʈ + // 새해 폭죽 이벤트 if (GetDropPerKillPct(/* minimum */ 100, /* default */ 1000, iDeltaPercent, "newyear_fire") >= Random::get(1, iRandRange)) { - // ߱ , ѱ + // 중국은 폭죽, 한국 팽이 const DWORD ITEM_VNUM_FIRE = g_iUseLocale ? 50107 : 50108; if ((item = CreateItem(ITEM_VNUM_FIRE, 1, 0, true))) vec_item.push_back(item); } - // 뺸 ̺Ʈ + // 새해 대보름 원소 이벤트 if (GetDropPerKillPct(100, 500, iDeltaPercent, "newyear_moon") >= Random::get(1, iRandRange)) { SPDLOG_DEBUG("EVENT NEWYEAR_MOON DROP"); @@ -1524,7 +1524,7 @@ void ITEM_MANAGER::CreateQuestDropItem(LPCHARACTER pkChr, LPCHARACTER pkKiller, vec_item.push_back(item); } - // ߷Ÿ ̺Ʈ. OGE 䱸 event ּҰ 1 .(ٸ ̺Ʈ ϴ ״ .) + // 발렌타인 데이 이벤트. OGE의 요구에 따라 event 최소값을 1로 변경.(다른 이벤트는 일단 그대로 둠.) if (GetDropPerKillPct(1, g_iUseLocale ? 2000 : 800, iDeltaPercent, "valentine_drop") >= Random::get(1, iRandRange)) { SPDLOG_DEBUG("EVENT VALENTINE_DROP"); @@ -1536,7 +1536,7 @@ void ITEM_MANAGER::CreateQuestDropItem(LPCHARACTER pkChr, LPCHARACTER pkKiller, vec_item.push_back(item); } - // ̽ũ ̺Ʈ + // 아이스크림 이벤트 if (GetDropPerKillPct(100, g_iUseLocale ? 2000 : 800, iDeltaPercent, "icecream_drop") >= Random::get(1, iRandRange)) { const static DWORD icecream = 50123; @@ -1545,8 +1545,8 @@ void ITEM_MANAGER::CreateQuestDropItem(LPCHARACTER pkChr, LPCHARACTER pkKiller, vec_item.push_back(item); } - // new ũ ̺Ʈ - // 53002 : Ʊ ȯ + // new 크리스마스 이벤트 + // 53002 : 아기 순록 소환권 if ((pkKiller->CountSpecifyItem(53002) > 0) && (GetDropPerKillPct(50, 100, iDeltaPercent, "new_xmas_event") >= Random::get(1, iRandRange))) { const static DWORD xmas_sock = 50010; @@ -1590,7 +1590,7 @@ void ITEM_MANAGER::CreateQuestDropItem(LPCHARACTER pkChr, LPCHARACTER pkKiller, vec_item.push_back(item); } - // ̺Ʈ + // 월드컵 이벤트 if ( GetDropPerKillPct(100, g_iUseLocale ? 2000 : 800, iDeltaPercent, "football_drop") >= Random::get(1, iRandRange) ) { const static DWORD football_item = 50096; @@ -1599,7 +1599,7 @@ void ITEM_MANAGER::CreateQuestDropItem(LPCHARACTER pkChr, LPCHARACTER pkKiller, vec_item.push_back(item); } - // ȭƮ ̺Ʈ + // 화이트 데이 이벤트 if (GetDropPerKillPct(100, g_iUseLocale ? 2000 : 800, iDeltaPercent, "whiteday_drop") >= Random::get(1, iRandRange)) { SPDLOG_DEBUG("EVENT WHITEDAY_DROP"); @@ -1610,7 +1610,7 @@ void ITEM_MANAGER::CreateQuestDropItem(LPCHARACTER pkChr, LPCHARACTER pkKiller, vec_item.push_back(item); } - // ̳ ̺Ʈ + // 어린이날 수수께끼 상자 이벤트 if (pkKiller->GetLevel()>=50) { if (GetDropPerKillPct(100, 1000, iDeltaPercent, "kids_day_drop_high") >= Random::get(1, iRandRange)) @@ -1632,7 +1632,7 @@ void ITEM_MANAGER::CreateQuestDropItem(LPCHARACTER pkChr, LPCHARACTER pkKiller, } } - // ø ̺Ʈ + // 올림픽 드롭 이벤트 if (pkChr->GetLevel() >= 30 && GetDropPerKillPct(50, 100, iDeltaPercent, "medal_part_drop") >= Random::get(1, iRandRange)) { const static DWORD drop_items[] = { 30265, 30266, 30267, 30268, 30269 }; @@ -1643,7 +1643,7 @@ void ITEM_MANAGER::CreateQuestDropItem(LPCHARACTER pkChr, LPCHARACTER pkKiller, } // ADD_GRANDMASTER_SKILL - // ȥ + // 혼석 아이템 드롭 if (pkChr->GetLevel() >= 40 && pkChr->GetMobRank() >= MOB_RANK_BOSS && GetDropPerKillPct(/* minimum */ 1, /* default */ 1000, iDeltaPercent, "three_skill_item") / GetThreeSkillLevelAdjust(pkChr->GetLevel()) >= Random::get(1, iRandRange)) { const DWORD ITEM_VNUM = 50513; @@ -1654,7 +1654,7 @@ void ITEM_MANAGER::CreateQuestDropItem(LPCHARACTER pkChr, LPCHARACTER pkKiller, // END_OF_ADD_GRANDMASTER_SKILL // - // drop + // 종자 아이템 drop // if (GetDropPerKillPct(100, 1000, iDeltaPercent, "dragon_boat_festival_drop") >= Random::get(1, iRandRange)) { @@ -1664,7 +1664,7 @@ void ITEM_MANAGER::CreateQuestDropItem(LPCHARACTER pkChr, LPCHARACTER pkKiller, vec_item.push_back(item); } - // ູ ö drop + // 무신의 축복서용 만년한철 drop if (pkKiller->GetLevel() >= 15 && quest::CQuestManager::instance().GetEventFlag("mars_drop")) { const DWORD ITEM_HANIRON = 70035; @@ -1726,8 +1726,8 @@ DWORD ITEM_MANAGER::GetMaskVnum(DWORD dwVnum) return 0; } -// pkNewItem Ӽ ϴ Լ. -// char_item.cpp Ͽ ִ Լ TransformRefineItem ״ +// pkNewItem으로 모든 속성과 소켓 값들을 목사하는 함수. +// 기존에 char_item.cpp 파일에 있던 로컬함수인 TransformRefineItem 그대로 복사함 void ITEM_MANAGER::CopyAllAttrTo(LPITEM pkOldItem, LPITEM pkNewItem) { // ACCESSORY_REFINE @@ -1742,7 +1742,7 @@ void ITEM_MANAGER::CopyAllAttrTo(LPITEM pkOldItem, LPITEM pkNewItem) // END_OF_ACCESSORY_REFINE else { - // ⼭ ڵ û + // 여기서 깨진석이 자동적으로 청소 됨 for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i) { if (!pkOldItem->GetSocket(i)) @@ -1751,19 +1751,19 @@ void ITEM_MANAGER::CopyAllAttrTo(LPITEM pkOldItem, LPITEM pkNewItem) pkNewItem->SetSocket(i, 1); } - // + // 소켓 설정 int slot = 0; for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i) { int socket = pkOldItem->GetSocket(i); - const int ITEM_BROKEN_METIN_VNUM = 28960; // ̰ Ȱ 3 ֳ... ϳ سФФ н ȫ Ҳ + const int ITEM_BROKEN_METIN_VNUM = 28960; // 이건 뭐 똑같은 상수가 3군데나 있냐... 하나로 해놓지ㅠㅠㅠ 나는 패스 홍이 할꺼임 if (socket > 2 && socket != ITEM_BROKEN_METIN_VNUM) pkNewItem->SetSocket(slot++, socket); } } - // + // 매직 아이템 설정 pkOldItem->CopyAttributeTo(pkNewItem); } diff --git a/src/game/src/item_manager_read_tables.cpp b/src/game/src/item_manager_read_tables.cpp index 7c97ad9..a059bac 100644 --- a/src/game/src/item_manager_read_tables.cpp +++ b/src/game/src/item_manager_read_tables.cpp @@ -78,7 +78,7 @@ bool ITEM_MANAGER::ReadCommonDropItemFile(const char * c_pszFileName) if (!ITEM_MANAGER::instance().GetVnumByOriginalName(d[i].szItemName, dwItemVnum)) { - // �̸����� ��ã���� ��ȣ�� �˻� + // 이름으로 못찾으면 번호로 검색 str_to_number(dwItemVnum, d[i].szItemName); if (!ITEM_MANAGER::instance().GetTable(dwItemVnum)) { @@ -405,7 +405,7 @@ bool ITEM_MANAGER::ConvSpecialDropItemFile() str_to_number(iRarePct, pTok->at(3).c_str()); } - // 1 "��� ���ü�" 1 100 + // 1 "기술 수련서" 1 100 if (0 == dwVnum) fprintf(fp, " %d %s %d %d\n", k, name.c_str(), iCount, iProb); else diff --git a/src/game/src/locale.cpp b/src/game/src/locale.cpp index 74397a7..8477317 100644 --- a/src/game/src/locale.cpp +++ b/src/game/src/locale.cpp @@ -48,7 +48,7 @@ const char *quote_find_end(const char *string) { if (quote && *tmp == '\\' && *(tmp + 1)) { - // \ ڰ " ŵѴ. + // \ 다음 문자가 " 면 스킵한다. switch (*(tmp + 1)) { case '"': diff --git a/src/game/src/locale_service.cpp b/src/game/src/locale_service.cpp index 4b3b7cf..fde3eb7 100644 --- a/src/game/src/locale_service.cpp +++ b/src/game/src/locale_service.cpp @@ -79,7 +79,7 @@ int check_name_independent(const char * str) if (CBanwordManager::instance().CheckString(str, strlen(str))) return 0; - // ̸δ . + // 몬스터 이름으로는 만들 수 없다. char szTmp[256]; str_lower(str, szTmp, sizeof(szTmp)); @@ -120,12 +120,12 @@ int check_name_gb2312(const char * str) b1 = str[i++]; b2 = str[i++]; - // ߱ ü ù° Ʈ b0 -> f7 - // ι° Ʈ a1 -> fe . + // 중국 간체는 첫번째 바이트 범위가 b0 -> f7 까지고 + // 두번째 바이트 범위가 a1 -> fe 다. if (b1 < 0xb0 || b1 > 0xf7 || b2 < 0xa1 || b2 > 0xfe) return 0; - // ܰ ִ. + // 예외가 있다. for (j = 0; j < 5; j++) if (b1 == exceptions[j][0] && b2 == exceptions[j][1]) return 0; @@ -172,8 +172,8 @@ int check_name_big5(const char * str ) b[0] = b2; b[1] = b1; - // ߱ ü ( big5 : ȫ ) - // . + // 중국 번체 ( big5 : 홍콩 ) + // 범위는 다음과 같다. // big5: 0xA140--0xF9D5 // extended big5: 0x40--0x7E and 0xA1--0xFE @@ -230,15 +230,15 @@ int check_name_latin1(const char * str) for (tmp = str; *tmp; ++tmp) { - // ѱ ƴϰ ĭ̸ ߸ + // 한글이 아니고 빈칸이면 잘못된 것 if (isspace(*tmp)) return 0; - // ѱ ƴϰ ڶ ϴ. + // 한글이 아니고 숫자라면 적합하다. if (isdigit(*tmp)) continue; - // ѱ ƴϰ ̶ ϴ. + // 한글이 아니고 영문이라면 적합하다. if (isalpha(*tmp)) continue; @@ -275,7 +275,7 @@ int check_name_alphabet(const char * str) for (tmp = str; *tmp; ++tmp) { - // ĺ ڸ + // 알파벳과 수자만 허용 if (isdigit(*tmp) || isalpha(*tmp)) continue; else @@ -324,7 +324,7 @@ int check_name_sjis(const char *str) const char *p = str; const char *e = str + strlen(str); // NULL position - // Ϻ ij ̸ 16byte + // 일본은 캐릭터 이름길이 16byte 까지 if ( strlen(str) < 2 || strlen(str) > 16 ) return 0; @@ -337,7 +337,7 @@ int check_name_sjis(const char *str) return false; // END_OF_DISABLE_SPECIAL_CHAR_NAMING - // ̹ڴ ʴ´. + // 이문자는 허용되지 않는다. if ((BYTE)p[0]==0x81 && (BYTE)p[1]==0x40) return false; p += 2; @@ -345,7 +345,7 @@ int check_name_sjis(const char *str) } else { - // ̳ ڴ Ѵ. + // 영문이나 수자는 허용한다. if (isalpha(*p) || isdigit(*p)) { p += 1; @@ -888,7 +888,7 @@ static void __LocaleService_Init_Singapore() check_name = check_name_alphabet; g_iUseLocale = true; - //exp_table = exp_table_newcibn; 2013 09 11 CYH europe ϰ . + //exp_table = exp_table_newcibn; 2013 09 11 CYH europe 과 동일하게 간다. } static void __LocaleService_Init_Vietnam() @@ -1309,18 +1309,18 @@ bool LC_IsEurope() case LC_DENMARK: case LC_BULGARIA: case LC_CROATIA: - case LC_MEXICO: // GF ϹǷ - case LC_ARABIA: // ߵ GF ϹǷ + case LC_MEXICO: // 남미지만 GF에서 서비스 하므로 여기 넣음 + case LC_ARABIA: // 중동이지만 GF에서 서비스 하므로 여기 넣음 case LC_CZECH: case LC_ROMANIA: case LC_HUNGARY: case LC_NETHERLANDS: case LC_USA: - case LC_WE_KOREA: // ѱ UK ̹Ƿ - case LC_TAIWAN: // 븸 WE_KOREA ̹Ƿ - case LC_JAPAN: // Ϻ WE(World Edition -_-) ̹Ƿ + case LC_WE_KOREA: // 한국이지만 UK 버전 기반이므로 여기 넣음 + case LC_TAIWAN: // 대만이지만 WE_KOREA 버전 기반이므로 여기 넣음 + case LC_JAPAN: // 일본이지만 WE(World Edition -_-) 버전이므로 여기 넣음 case LC_NEWCIBN: - case LC_CANADA: // ij GF + case LC_CANADA: // 캐나다 GF에서 서비스 시작 return true; } diff --git a/src/game/src/main.cpp b/src/game/src/main.cpp index 8cd2b42..fa9176e 100644 --- a/src/game/src/main.cpp +++ b/src/game/src/main.cpp @@ -86,10 +86,10 @@ void WriteMallocMessage(const char* p1, const char* p2, const char* p3, const ch #endif // TRAFFIC_PROFILER -static const DWORD TRAFFIC_PROFILE_FLUSH_CYCLE = 3600; ///< TrafficProfiler Flush cycle. 1ð +static const DWORD TRAFFIC_PROFILE_FLUSH_CYCLE = 3600; ///< TrafficProfiler 의 Flush cycle. 1시간 간격 // END_OF_TRAFFIC_PROFILER -// Ӱ Ǵ +// 게임과 연결되는 소켓 volatile int num_events_called = 0; int max_bytes_written = 0; int current_bytes_written = 0; @@ -227,7 +227,7 @@ void heartbeat(LPHEART ht, int pulse) t = get_dword_time(); - // 1ʸ + // 1초마다 if (!(pulse % ht->passes_per_sec)) { if (!g_bAuthServer) @@ -279,14 +279,14 @@ void heartbeat(LPHEART ht, int pulse) } // - // 25 PPS(Pulse per second) + // 25 PPS(Pulse per second) 라고 가정할 때 // - // 1.16ʸ + // 약 1.16초마다 if (!(pulse % (passes_per_sec + 4))) CHARACTER_MANAGER::instance().ProcessDelayedSave(); - // 5.08ʸ + // 약 5.08초마다 if (!(pulse % (passes_per_sec * 5 + 2))) { ITEM_MANAGER::instance().Update(); @@ -849,7 +849,7 @@ int io_loop(event_base * base) LPDESC d; int num_events, event_idx; - DESC_MANAGER::instance().DestroyClosed(); // PHASE_CLOSE ӵ ش. + DESC_MANAGER::instance().DestroyClosed(); // PHASE_CLOSE인 접속들을 끊어준다. DESC_MANAGER::instance().TryConnect(); // Process network events diff --git a/src/game/src/marriage.cpp b/src/game/src/marriage.cpp index dade791..22a10b3 100644 --- a/src/game/src/marriage.cpp +++ b/src/game/src/marriage.cpp @@ -21,19 +21,19 @@ namespace marriage DWORD dwVnum; int value[MAX_LOVE_GRADE]; } g_ItemBonus[MAX_MARRIAGE_UNIQUE_ITEM] = { - { 71069, { 4, 5, 6, 8, } }, // - { 71070, { 10, 12, 15, 20, } }, // ġ - { 71071, { 4, 5, 6, 8, } }, // ũƼ - { 71072, { -4, -5, -6, -8, } }, // ݷ - { 71073, { 20, 25, 30, 40, } }, // ݷ (밪) - { 71074, { 12, 16, 20, 30, } }, // (밪) + { 71069, { 4, 5, 6, 8, } }, // 관통 증가 + { 71070, { 10, 12, 15, 20, } }, // 경험치 증가 + { 71071, { 4, 5, 6, 8, } }, // 크리티컬 증가 + { 71072, { -4, -5, -6, -8, } }, // 상대방 공격력 감소 + { 71073, { 20, 25, 30, 40, } }, // 공격력 증가 (절대값) + { 71074, { 12, 16, 20, 30, } }, // 방어력 증가 (절대값) - //{ 71069, 1, 2, 3, 6, 8, }, // - //{ 71070, 5, 7, 10, 15, 20, }, // ġ - //{ 71071, 1, 2, 3, 6, 8, }, // ũƼ - //{ 71072, 5, 10, 15, 20, 30, }, // Է - //{ 71073, 10, 15, 20, 25, 40, }, // ݷ (밪) - //{ 71074, 5, 10, 15, 20, 30, }, // (밪) + //{ 71069, 1, 2, 3, 6, 8, }, // 관통 증가 + //{ 71070, 5, 7, 10, 15, 20, }, // 경험치 증가 + //{ 71071, 1, 2, 3, 6, 8, }, // 크리티컬 증가 + //{ 71072, 5, 10, 15, 20, 30, }, // 상대방이 입은 데미지를 나에게로 + //{ 71073, 10, 15, 20, 25, 40, }, // 공격력 증가 (절대값) + //{ 71074, 5, 10, 15, 20, 30, }, // 방어력 증가 (절대값) }; const int MARRIAGE_POINT_PER_DAY = 1; @@ -101,17 +101,17 @@ namespace marriage else days /= 86400; - // ⺻ 50% + // 기본 50% - // : - // ¥ 80% Ϸ 8% - // 80% - // Ż 100% + // 원앙의 깃털 사용중일 때 : + // 날짜에 의한 영향 80% 하루당 8% + // 전투에 의한 영향 80% + // 토탈 100% - // : - // ¥ 60% Ϸ 6% - // 60% - // Ż 100% + // 비사용중일 때 : + // 날짜에 의한 영향 60% 하루당 6% + // 전투에 의한 영향 60% + // 토탈 100% return std::min(50 + std::min(days * point_per_day, max_limit) + std::min(love_point / 1000000, max_limit), 100); } @@ -124,11 +124,11 @@ namespace marriage return ch1->GetMapIndex() == ch2->GetMapIndex(); - // Ƽ üũ + // 파티 체크가 사라졌음 /*if (!ch1->GetParty() || ch1->GetParty() != ch2->GetParty()) return false;*/ - // Ÿ üũ + // 거리 체크가 사라졌음 /*const int DISTANCE = 5000; if (labs(ch1->GetX() - ch2->GetX()) > DISTANCE) @@ -140,15 +140,15 @@ namespace marriage return (DISTANCE_APPROX(ch1->GetX() - ch2->GetX(), ch1->GetY() - ch2->GetY()) < DISTANCE);*/ } - // ݽ ġ + // 금슬 수치 int TMarriage::GetBonus(DWORD dwItemVnum, bool bShare, LPCHARACTER me) { if (!is_married) return 0; - // ֺ ڱ ɸ ȴ. + // 주변에 없을때는 자기 기능만 적용된다. - // ش  ϴ ã´. + // 해당 아이템이 어떤 기능을 하는지 찾는다. int iFindedBonusIndex=0; { for (iFindedBonusIndex = 0; iFindedBonusIndex < MAX_MARRIAGE_UNIQUE_ITEM; ++iFindedBonusIndex) @@ -163,7 +163,7 @@ namespace marriage if (bShare) { - // θ ʽ Ѵ. + // 두명의 보너스를 합한다. int count = 0; if (NULL != ch1 && ch1->IsEquipUniqueItem(dwItemVnum)) count ++; @@ -178,7 +178,7 @@ namespace marriage } else { - // ͸ + // 상대방 것만 계산 int count = 0; if (me != ch1 && NULL!= ch1 && ch1->IsEquipUniqueItem(dwItemVnum)) count ++; @@ -208,7 +208,7 @@ namespace marriage SendLoverInfo(ch2, name1, GetMarriagePoint()); } - // μ α ̸ ͸ ϰ ̺Ʈ ߻ + // 둘 다 이 프로세스에 로그인 중이면 포인터를 연결하고 이벤트 발생 if (IsOnline()) { ch1->SetMarryPartner(ch2); @@ -217,7 +217,7 @@ namespace marriage StartNearCheckEvent(); } - // α Ǿ ִٸ Ŷ . + // 둘 다 로그인 되어 있다면 패킷을 보낸다. if (is_married) { LPDESC d1, d2; @@ -581,7 +581,7 @@ namespace marriage if (A && B) { - // û + // 웨딩 맵 요청을 보낸다 TPacketWeddingRequest p; p.dwPID1 = dwPID1; p.dwPID2 = dwPID2; @@ -703,11 +703,11 @@ namespace marriage if (!pwi) return; - // ȥڵ Ѿ + // 결혼자들을 워프시켜야함 pMarriage->WarpToWeddingMap(dwPID1); pMarriage->WarpToWeddingMap(dwPID2); - // ؼ ޴â ̸; + // 등록해서 메뉴창에서 이름나와야함 m_setWedding.insert(make_pair(dwPID1, dwPID2)); } @@ -726,7 +726,7 @@ namespace marriage return; } - // ʿ մϴ + // 맵에서 빼내야합니다 if (map_allow_find(WEDDING_MAP_INDEX)) if (!WeddingManager::instance().End(pMarriage->pWeddingInfo->dwMapIndex)) { diff --git a/src/game/src/matrix_card.cpp b/src/game/src/matrix_card.cpp index 80212fa..fd1dc4d 100644 --- a/src/game/src/matrix_card.cpp +++ b/src/game/src/matrix_card.cpp @@ -1,4 +1,4 @@ -//#define __MATRIX_MAIN_ENABLE__ // define Ǿ main Լ Եȴ. Unit test ÿ +//#define __MATRIX_MAIN_ENABLE__ // define 되어 있으면 main 함수가 포함된다. Unit test 시에 사용 #ifndef __MATRIX_MAIN_ENABLE__ #include "stdafx.h" #else diff --git a/src/game/src/messenger_manager.cpp b/src/game/src/messenger_manager.cpp index 7762566..1e7042d 100644 --- a/src/game/src/messenger_manager.cpp +++ b/src/game/src/messenger_manager.cpp @@ -240,11 +240,11 @@ void MessengerManager::RemoveAllList(keyA account) { std::set company(m_Relation[account]); - /* SQL Data */ + /* SQL Data 삭제 */ DBManager::instance().Query("DELETE FROM messenger_list%s WHERE account='%s' OR companion='%s'", get_table_postfix(), account.c_str(), account.c_str()); - /* ִ Ʈ */ + /* 내가 가지고있는 리스트 삭제 */ for (std::set::iterator iter = company.begin(); iter != company.end(); iter++ ) @@ -252,7 +252,7 @@ void MessengerManager::RemoveAllList(keyA account) this->RemoveFromList(account, *iter); } - /* Ÿ */ + /* 복사한 데이타 삭제 */ for (std::set::iterator iter = company.begin(); iter != company.end(); ) diff --git a/src/game/src/monarch.cpp b/src/game/src/monarch.cpp index a2c79da..244eabb 100644 --- a/src/game/src/monarch.cpp +++ b/src/game/src/monarch.cpp @@ -86,10 +86,10 @@ int CMonarch::HealMyEmpire(LPCHARACTER ch ,DWORD price) f.m_bEmpire = Empire; SECTREE_MANAGER::instance().for_each(iMapIndex, f); - // DB 谨 + // DB에 돈 삭감 보내기 SendtoDBDecMoney(price, Empire, ch); - // Ÿ + // 쿨타임 설정 ch->SetMC(CHARACTER::MI_HEAL); if (test_server) @@ -139,7 +139,7 @@ bool CMonarch::SendtoDBDecMoney(int Money, BYTE bEmpire, LPCHARACTER ch) if (GetMoney(bEmpire) - Money < 0) return false; - // ̴ κ óȴ + // 실제 줄이는 부분은 서버에 갔다 온 다음에 처리된다 int nEmpire = bEmpire; db_clientdesc->DBPacketHeader(HEADER_GD_DEC_MONARCH_MONEY, ch->GetDesc()->GetHandle(), sizeof(int) + sizeof(int)); @@ -153,7 +153,7 @@ bool CMonarch::AddMoney(int Money, BYTE bEmpire) if (bEmpire >= _countof(m_MonarchInfo.money)) return false; - // 20 ̻ Ա Ұ + // 20억 이상 입금 불가능 if (GetMoney(bEmpire) + Money > 2000000000) return false; @@ -236,7 +236,7 @@ void CMonarch::PowerUp(BYTE Empire, bool On) m_PowerUp[Empire] = On; - // Ÿ + // 군주 사자후 쿨타임 m_PowerUpCT[Empire] = thecore_pulse() + PASSES_PER_SEC(60 * 10); } @@ -247,13 +247,13 @@ void CMonarch::DefenseUp(BYTE Empire, bool On) m_DefenseUp[Empire] = On; - // ݰ Ÿ + // 군주 금강권 쿨타임 m_DefenseUpCT[Empire] = thecore_pulse() + PASSES_PER_SEC(60 * 10); } bool IsMonarchWarpZone (int map_idx) { - // Ʊ͵, õǵ. + // 아귀동굴, 천의동굴. if (map_idx >= 10000) map_idx /= 10000; @@ -263,9 +263,9 @@ bool IsMonarchWarpZone (int map_idx) case 302: case 303: case 304: - // - case 351: // 漺 - case 352: // + //던전 + case 351: // 적룡성 + case 352: // 백룡지성 return false; } diff --git a/src/game/src/motion.cpp b/src/game/src/motion.cpp index 6c60509..3b85529 100644 --- a/src/game/src/motion.cpp +++ b/src/game/src/motion.cpp @@ -476,7 +476,7 @@ bool CMotion::LoadMobSkillFromFile(const char * c_pszFileName, CMob* pMob, int i continue; case MOTION_EVENT_TYPE_SPECIAL_ATTACKING: - // ʹ ϳ + // 구 데이터는 하나 라고 가정 if (!rkTextFileLoader.SetChildNode("spheredata", 0)) { SPDLOG_ERROR("Motion: no sphere data {}", c_pszFileName); diff --git a/src/game/src/p2p.cpp b/src/game/src/p2p.cpp index 193e09f..a596ce4 100644 --- a/src/game/src/p2p.cpp +++ b/src/game/src/p2p.cpp @@ -173,7 +173,7 @@ void P2P_MANAGER::Login(LPDESC d, const TPacketGGLogin * p) CGuildManager::instance().P2PLoginMember(pkCCI->dwPID); CPartyManager::instance().P2PLogin(pkCCI->dwPID, pkCCI->szName); - // CCI ÿ ޽ Ʈϸ ȴ. + // CCI가 생성시에만 메신저를 업데이트하면 된다. if (UpdateP2P) { std::string name(pkCCI->szName); MessengerManager::instance().P2PLogin(name); diff --git a/src/game/src/panama.cpp b/src/game/src/panama.cpp index e37bd18..2ac3257 100644 --- a/src/game/src/panama.cpp +++ b/src/game/src/panama.cpp @@ -84,7 +84,7 @@ void SendPanamaList(LPDESC d) DWORD* ivs = (DWORD*)pack.abIV; for (int i = 0; i != 32 / sizeof(DWORD); i++) { - ivs[i] ^= d->GetPanamaKey() + i * 16777619; // ij Ű XOR ش + ivs[i] ^= d->GetPanamaKey() + i * 16777619; // 더블워드단위로 변형된 파나마 키를 XOR 해준다 } ++it; diff --git a/src/game/src/party.cpp b/src/game/src/party.cpp index 902958c..b2b2ad0 100644 --- a/src/game/src/party.cpp +++ b/src/game/src/party.cpp @@ -34,7 +34,7 @@ void CPartyManager::DeleteAllParty() } } -bool CPartyManager::SetParty(LPCHARACTER ch) // PC ؾ Ѵ!! +bool CPartyManager::SetParty(LPCHARACTER ch) // PC만 사용해야 한다!! { TPartyMap::iterator it = m_map_pkParty.find(ch->GetPlayerID()); @@ -295,7 +295,7 @@ void CParty::Destroy() { SPDLOG_TRACE("Party::Destroy"); - // PC Ƽ ƼŴ ʿ PID ؾ Ѵ. + // PC가 만든 파티면 파티매니저에 맵에서 PID를 삭제해야 한다. if (m_bPCParty) { for (TMemberMap::iterator it = m_memberMap.begin(); it != m_memberMap.end(); ++it) @@ -327,7 +327,7 @@ void CParty::Destroy() } else { - // NPC ð ƴ ϴ ̺Ʈ ۽Ų. + // NPC일 경우 일정 시간 후 전투 중이 아닐 때 사라지게 하는 이벤트를 시작시킨다. rMember.pCharacter->SetLastAttacked(dwTime); rMember.pCharacter->StartDestroyWhenIdleEvent(); } @@ -458,7 +458,7 @@ void CParty::Join(DWORD dwPID) TPacketPartyAdd p; p.dwLeaderPID = GetLeaderPID(); p.dwPID = dwPID; - p.bState = PARTY_ROLE_NORMAL; // #0000790: [M2EU] CZ ũ : ʱȭ ߿! + p.bState = PARTY_ROLE_NORMAL; // #0000790: [M2EU] CZ 크래쉬 증가: 초기화 중요! db_clientdesc->DBPacket(HEADER_GD_PARTY_ADD, 0, &p, sizeof(p)); } } @@ -504,11 +504,11 @@ void CParty::P2PQuit(DWORD dwPID) if (m_bPCParty) CPartyManager::instance().SetPartyMember(dwPID, NULL); - // Ƽ ػǾ Ѵ. + // 리더가 나가면 파티는 해산되어야 한다. if (bRole == PARTY_ROLE_LEADER) CPartyManager::instance().DeleteParty(this); - // Ʒ ڵ带 ߰ !!! DeleteParty ϸ this . + // 이 아래는 코드를 추가하지 말 것!!! 위 DeleteParty 하면 this는 없다. } void CParty::Quit(DWORD dwPID) @@ -546,7 +546,7 @@ void CParty::Link(LPCHARACTER pkChr) return; } - // ÷̾ Ƽ Ʈ ̺Ʈ + // 플레이어 파티일 경우 업데이트 이벤트 생성 if (m_bPCParty && !m_eventUpdate) { party_update_event_info* info = AllocEventInfo(); @@ -643,7 +643,7 @@ void CParty::Unlink(LPCHARACTER pkChr) if (pkChr->IsPC()) { SendPartyUnlinkOneToAll(pkChr); - //SendPartyUnlinkAllToOne(pkChr); // ̹Ƿ Unlink Ŷ ʿ . + //SendPartyUnlinkAllToOne(pkChr); // 끊기는 것이므로 구지 Unlink 패킷을 보낼 필요 없다. if (it->second.bRole == PARTY_ROLE_LEADER) { @@ -651,7 +651,7 @@ void CParty::Unlink(LPCHARACTER pkChr) if (it->second.pCharacter->GetDungeon()) { - // TODO: + // TODO: 던젼에 있으면 나머지도 나간다 FExitDungeon f; ForEachNearMember(f); } @@ -898,9 +898,9 @@ void CParty::SendMessage(LPCHARACTER ch, BYTE bMsg, DWORD dwArg1, DWORD dwArg2) } break; - case PM_ATTACKED_BY: // ޾, û + case PM_ATTACKED_BY: // 공격 받았음, 리더에게 도움을 요청 { - // + // 리더가 없을 때 LPCHARACTER pkChrVictim = ch->GetVictim(); if (!pkChrVictim) @@ -1067,7 +1067,7 @@ void CParty::RemoveBonusForOne(DWORD pid) void CParty::HealParty() { - // XXX DELETEME Ŭ̾Ʈ Ϸɶ + // XXX DELETEME 클라이언트 완료될때까지 { return; } @@ -1355,7 +1355,7 @@ void CParty::Update() bool bLongTimeExpBonusChanged = false; - // Ƽ Ἲ ð ġ ʽ ޴´. + // 파티 결성 후 충분한 시간이 지나면 경험치 보너스를 받는다. if (!m_iLongTimeExpBonus && (get_dword_time() - m_dwPartyStartTime > PARTY_ENOUGH_MINUTE_FOR_EXP_BONUS * 60 * 1000 / (g_iUseLocale?1:2))) { bLongTimeExpBonusChanged = true; @@ -1400,9 +1400,9 @@ void CParty::Update() if (!m_bCanUsePartyHeal && m_iLeadership >= 18) m_dwPartyHealTime = get_dword_time(); - m_bCanUsePartyHeal = m_iLeadership >= 18; // ַ 18 ̻ . + m_bCanUsePartyHeal = m_iLeadership >= 18; // 통솔력 18 이상은 힐을 사용할 수 있음. - // ַ 40̻ Ƽ Ÿ . + // 통솔력 40이상은 파티 힐 쿨타임이 적다. DWORD PartyHealCoolTime = (m_iLeadership >= 40) ? PARTY_HEAL_COOLTIME_SHORT * 60 * 1000 : PARTY_HEAL_COOLTIME_LONG * 60 * 1000; if (m_bCanUsePartyHeal) @@ -1412,7 +1412,7 @@ void CParty::Update() m_bPartyHealReady = true; // send heal ready - if (0) // XXX DELETEME Ŭ̾Ʈ Ϸɶ + if (0) // XXX DELETEME 클라이언트 완료될때까지 if (GetLeaderCharacter()) GetLeaderCharacter()->ChatPacket(CHAT_TYPE_COMMAND, "PartyHealReady"); } @@ -1681,7 +1681,7 @@ int CParty::ComputePartyBonusExpPercent() if (leader && (leader->IsEquipUniqueItem(UNIQUE_ITEM_PARTY_BONUS_EXP) || leader->IsEquipUniqueItem(UNIQUE_ITEM_PARTY_BONUS_EXP_MALL) || leader->IsEquipUniqueItem(UNIQUE_ITEM_PARTY_BONUS_EXP_GIFT) || leader->IsEquipUniqueGroup(10010))) { - // ߱ ȮؾѴ. + // 중국측 육도 적용을 확인해야한다. if (g_iUseLocale) { iBonusPartyExpFromItem = 30; diff --git a/src/game/src/polymorph.cpp b/src/game/src/polymorph.cpp index b600af5..7f779b1 100644 --- a/src/game/src/polymorph.cpp +++ b/src/game/src/polymorph.cpp @@ -64,7 +64,7 @@ bool CPolymorphUtils::PolymorphCharacter(LPCHARACTER pChar, LPITEM pItem, const // dwDuration *= 60; - // Ȯ = ij - + а + 29 + а ų + // 변신 확률 = 캐릭터 레벨 - 몹 레벨 + 둔갑서 레벨 + 29 + 둔갑 스킬 레벨 iPolyPercent = pChar->GetLevel() - pMob->m_table.bLevel + pItem->GetSocket(2) + (29 + bySkillLevel); if (iPolyPercent <= 0) @@ -83,7 +83,7 @@ bool CPolymorphUtils::PolymorphCharacter(LPCHARACTER pChar, LPITEM pItem, const pChar->AddAffect(AFFECT_POLYMORPH, POINT_POLYMORPH, pMob->m_table.dwVnum, AFF_POLYMORPH, dwDuration, 0, true); - // ʽ = а ų + а + // 변신 보너스 = 둔갑 스킬 레벨 + 둔갑서 레벨 dwBonusPercent = bySkillLevel + pItem->GetSocket(2); switch (GetBonusType(pMob->m_table.dwVnum)) @@ -123,8 +123,8 @@ bool CPolymorphUtils::UpdateBookPracticeGrade(LPCHARACTER pChar, LPITEM pItem) bool CPolymorphUtils::GiveBook(LPCHARACTER pChar, DWORD dwMobVnum, DWORD dwPracticeCount, BYTE BookLevel, BYTE LevelLimit) { - // 0 1 2 - // а ȣ а + // 소켓0 소켓1 소켓2 + // 둔갑할 몬스터 번호 수련정도 둔갑서 레벨 if (pChar == NULL) return false; @@ -140,9 +140,9 @@ bool CPolymorphUtils::GiveBook(LPCHARACTER pChar, DWORD dwMobVnum, DWORD dwPract return false; } - pItem->SetSocket(0, dwMobVnum); // а ȣ - pItem->SetSocket(1, dwPracticeCount); // ؾ Ƚ - pItem->SetSocket(2, BookLevel); // ÷ + pItem->SetSocket(0, dwMobVnum); // 둔갑할 몬스터 번호 + pItem->SetSocket(1, dwPracticeCount); // 수련해야할 횟수 + pItem->SetSocket(2, BookLevel); // 수련레벨 return true; } diff --git a/src/game/src/priv_manager.cpp b/src/game/src/priv_manager.cpp index 6662cc6..3d83034 100644 --- a/src/game/src/priv_manager.cpp +++ b/src/game/src/priv_manager.cpp @@ -225,7 +225,7 @@ void CPrivManager::RemoveCharacterPriv(DWORD pid, BYTE type) int CPrivManager::GetPriv(LPCHARACTER ch, BYTE type) { - // ij ġ - - ǰ + // 캐릭터의 변경 수치가 -라면 무조건 -만 적용되게 int val_ch = GetPrivByCharacter(ch->GetPlayerID(), type); if (val_ch < 0 && !ch->IsEquipUniqueItem(UNIQUE_ITEM_NO_BAD_LUCK_EFFECT)) @@ -234,7 +234,7 @@ int CPrivManager::GetPriv(LPCHARACTER ch, BYTE type) { int val; - // , , , ü ū Ѵ. + // 개인, 제국, 길드, 전체 중 큰 값을 취한다. val = std::max(val_ch, GetPrivByEmpire(0, type)); val = std::max(val, GetPrivByEmpire(ch->GetEmpire(), type)); diff --git a/src/game/src/pvp.cpp b/src/game/src/pvp.cpp index 0c30046..e50ff1b 100644 --- a/src/game/src/pvp.cpp +++ b/src/game/src/pvp.cpp @@ -131,7 +131,7 @@ void CPVP::Win(DWORD dwPID) m_bRevenge = true; - m_players[iSlot].bAgree = true; // ڵ + m_players[iSlot].bAgree = true; // 자동으로 동의 m_players[!iSlot].bCanRevenge = true; m_players[!iSlot].bAgree = false; @@ -180,7 +180,7 @@ void CPVPManager::Insert(LPCHARACTER pkChr, LPCHARACTER pkVictim) if ((pkPVP = Find(kPVP.m_dwCRC))) { - // ٷ ο! + // 복수할 수 있으면 바로 싸움! if (pkPVP->Agree(pkChr->GetPlayerID())) { pkVictim->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s\xB4\xD4\xB0\xFA\xC0\xC7 \xB4\xEB\xB0\xE1 \xBD\xC3\xC0\xDB!"), pkChr->GetName()); @@ -299,8 +299,8 @@ void CPVPManager::GiveUp(LPCHARACTER pkChr, DWORD dwKillerPID) // This method is } } -// ϰ: 0 = PK, 1 = PVP -// PVP ϸ ġ PK ʴ´. +// 리턴값: 0 = PK, 1 = PVP +// PVP를 리턴하면 경험치나 아이템을 떨구고 PK면 떨구지 않는다. bool CPVPManager::Dead(LPCHARACTER pkChr, DWORD dwKillerPID) { CPVPSetMap::iterator it = m_map_pkPVPSetByID.find(pkChr->GetPlayerID()); @@ -354,7 +354,7 @@ bool CPVPManager::CanAttack(LPCHARACTER pkChr, LPCHARACTER pkVictim) return false; } - if (pkChr == pkVictim) // ĥ ϳ -_- + if (pkChr == pkVictim) // 내가 날 칠라고 하네 -_- return false; if (pkVictim->IsNPC() && pkChr->IsNPC() && !pkChr->IsGuardNPC()) @@ -380,7 +380,7 @@ bool CPVPManager::CanAttack(LPCHARACTER pkChr, LPCHARACTER pkVictim) case 20116: case 20117: case 20118: - //ű Ż + //신규 탈것 고급 case 20205: case 20206: case 20207: @@ -389,21 +389,21 @@ bool CPVPManager::CanAttack(LPCHARACTER pkChr, LPCHARACTER pkVictim) case 20210: case 20211: case 20212: - case 20119: // 󸶴 渶 - case 20219: // 󸶴 渶 Ŭ (ҷ) - case 20220: // ũ Ż - case 20221: // - case 20222: // Ҵ + case 20119: // 라마단 흑마 + case 20219: // 라마단 흑마 클론 (할로윈용) + case 20220: // 크리스마스 탈것 + case 20221: // 전갑 백웅 + case 20222: // 전갑 팬더 case 20120: case 20121: case 20122: case 20123: case 20124: case 20125: - case 20214: // - case 20215: // - case 20217: // ϼ - case 20218: // ϼ + case 20214: // 난폭한 전갑순순록 + case 20215: // 용맹한 전갑순순록 + case 20217: // 난폭한 전갑암순록 + case 20218: // 용맹한 전갑암순록 break; default: @@ -460,7 +460,7 @@ bool CPVPManager::CanAttack(LPCHARACTER pkChr, LPCHARACTER pkVictim) { if (g_protectNormalPlayer) { - // ڴ ȭ ѻ . + // 범법자는 평화모드인 착한사람을 공격할 수 없다. if (PK_MODE_PEACE == pkVictim->GetPKMode()) return false; } @@ -592,7 +592,7 @@ void CPVPManager::SendList(LPDESC d) if (!pkPVP->m_players[0].dwVID || !pkPVP->m_players[1].dwVID) continue; - // VID Ѵ 쿡 . + // VID가 둘다 있을 경우에만 보낸다. if (pkPVP->IsFight()) { pack.bMode = PVP_MODE_FIGHT; @@ -647,7 +647,7 @@ void CPVPManager::Process() { CPVP * pvp = (it++)->second; - if (get_dword_time() - pvp->GetLastFightTime() > 600000) // 10 ̻ ο + if (get_dword_time() - pvp->GetLastFightTime() > 600000) // 10분 이상 싸움이 없었으면 { pvp->Packet(true); Delete(pvp); diff --git a/src/game/src/questevent.cpp b/src/game/src/questevent.cpp index 96933ba..e7d2c02 100644 --- a/src/game/src/questevent.cpp +++ b/src/game/src/questevent.cpp @@ -35,7 +35,7 @@ namespace quest if (!q.ServerTimer(info->npc_id, info->arg)) return passes_per_sec / 2 + 1; - if (0 == info->time_cycle) // ƴ϶ Ų. + if (0 == info->time_cycle) // 루프가 아니라면 종료 시킨다. { q.ClearServerTimerNotCancel(info->name, info->arg); M2_DELETE_ARRAY(info->name); @@ -62,7 +62,7 @@ namespace quest if (!CQuestManager::instance().Timer(info->player_id, info->npc_id)) return (passes_per_sec / 2 + 1); - if (0 == info->time_cycle) // ƴ϶ Ų. + if (0 == info->time_cycle) // 루프가 아니라면 종료 시킨다. goto END_OF_TIMER_EVENT; } else diff --git a/src/game/src/questlua.cpp b/src/game/src/questlua.cpp index 2b78367..352f358 100644 --- a/src/game/src/questlua.cpp +++ b/src/game/src/questlua.cpp @@ -443,7 +443,7 @@ namespace quest } /** - * @version 05/06/08 Bang2ni - __get_guildid_byname ũƮ Լ + * @version 05/06/08 Bang2ni - __get_guildid_byname 스크립트 함수 등록 */ bool CQuestManager::InitializeLua() { @@ -688,7 +688,7 @@ namespace quest if (chReply) { - // ð ˾Ƽ + // 시간 지나면 알아서 닫힘 } if (chWait) @@ -708,12 +708,12 @@ namespace quest SPDLOG_DEBUG("GotoConfirmState vid {} msg '{}', timeout {}", dwVID, szMsg, iTimeout); - // 1. 濡 Ȯâ - // 2. Ȯ ٸٰ ǥϴ â - // 3. ŸӾƿ (ŸӾƿ Ǹ â ݰ Ե â ) + // 1. 상대방에게 확인창 띄움 + // 2. 나에게 확인 기다린다고 표시하는 창 띄움 + // 3. 타임아웃 설정 (타임아웃 되면 상대방 창 닫고 나에게도 창 닫으라고 보냄) // 1 - // ׳ 濡 ʴ´. ŸӾƿ ؼ ѾԵ + // 상대방이 없는 경우는 그냥 상대방에게 보내지 않는다. 타임아웃에 의해서 넘어가게됨 LPCHARACTER ch = CHARACTER_MANAGER::instance().Find(dwVID); if (ch && ch->IsPC()) { @@ -749,7 +749,7 @@ namespace quest AddScript("[INPUT]"); SendScript(); - // ð + // 시간 제한을 검 //event_create(input_timeout_event, dwEI, PASSES_PER_SEC(iTimeout)); } diff --git a/src/game/src/questlua_affect.cpp b/src/game/src/questlua_affect.cpp index 20c0cf2..fa0c0be 100644 --- a/src/game/src/questlua_affect.cpp +++ b/src/game/src/questlua_affect.cpp @@ -31,7 +31,7 @@ namespace quest return 0; } - if (ch->FindAffect(AFFECT_QUEST_START_IDX, applyOn)) // Ʈ ȿ ɷ ŵ + if (ch->FindAffect(AFFECT_QUEST_START_IDX, applyOn)) // 퀘스트로 인해 같은 곳에 효과가 걸려있으면 스킵 return 0; int value = (int) lua_tonumber(L, 2); @@ -62,14 +62,14 @@ namespace quest return 0; } - int affect_remove_bad(lua_State * L) // ȿ + int affect_remove_bad(lua_State * L) // 나쁜 효과를 없앰 { LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr(); ch->RemoveBadAffect(); return 0; } - int affect_remove_good(lua_State * L) // ȿ + int affect_remove_good(lua_State * L) // 좋은 효과를 없앰 { LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr(); ch->RemoveGoodAffect(); @@ -104,7 +104,7 @@ namespace quest return 0; } - int affect_remove_hair(lua_State * L) // ȿ ش. + int affect_remove_hair(lua_State * L) // 헤어 효과를 없앤다. { LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr(); @@ -123,7 +123,7 @@ namespace quest return 1; } - // ijͰ AFFECT_TYPE affect bApplyOn ȯϰ nil ȯϴ Լ. + // 현재 캐릭터가 AFFECT_TYPE affect를 갖고있으면 bApplyOn 값을 반환하고 없으면 nil을 반환하는 함수. // usage : applyOn = affect.get_apply(AFFECT_TYPE) int affect_get_apply_on(lua_State * L) { diff --git a/src/game/src/questlua_dungeon.cpp b/src/game/src/questlua_dungeon.cpp index 3f9e8ba..cd70595 100644 --- a/src/game/src/questlua_dungeon.cpp +++ b/src/game/src/questlua_dungeon.cpp @@ -991,7 +991,7 @@ namespace quest return 0; } - int dungeon_exit(lua_State* L) // ġ + int dungeon_exit(lua_State* L) // 던전에 들어오기 전 위치로 보냄 { LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr(); @@ -999,7 +999,7 @@ namespace quest return 0; } - int dungeon_exit_all(lua_State* L) // ִ ġ + int dungeon_exit_all(lua_State* L) // 던전에 있는 모든 사람을 던전에 들어오기 전 위치로 보냄 { CQuestManager& q = CQuestManager::instance(); LPDUNGEON pDungeon = q.GetCurrentDungeon(); @@ -1127,7 +1127,7 @@ namespace quest } }; - int dungeon_exit_all_by_item_group (lua_State* L) // Ư ׷쿡 » + int dungeon_exit_all_by_item_group (lua_State* L) // 특정 아이템 그룹에 속한 아이템이 없는사람은 강퇴 { if (!lua_isstring(L, 1)) { @@ -1192,7 +1192,7 @@ namespace quest } }; - int dungeon_delete_item_in_item_group_from_all(lua_State* L) // Ư pcԼ . + int dungeon_delete_item_in_item_group_from_all(lua_State* L) // 특정 아이템을 던전 내 pc에게서 삭제. { if (!lua_isstring(L, 1)) { diff --git a/src/game/src/questlua_global.cpp b/src/game/src/questlua_global.cpp index a67c558..70da03b 100644 --- a/src/game/src/questlua_global.cpp +++ b/src/game/src/questlua_global.cpp @@ -790,7 +790,7 @@ namespace quest return 1; } - // ο state . + // 새로운 state를 만든다. int _set_quest_state(lua_State* L) { if (!lua_isstring(L, 1) || !lua_isstring(L, 2)) @@ -1012,7 +1012,7 @@ namespace quest return 0; } - //: ȵǴ ʿ + //주의: 몹 리젠이 안되는 맵에서만 사용 int _regen_in_map( lua_State * L ) { int iMapIndex = static_cast(lua_tonumber(L, 1)); diff --git a/src/game/src/questlua_guild.cpp b/src/game/src/questlua_guild.cpp index 8ed5f97..0b43159 100644 --- a/src/game/src/questlua_guild.cpp +++ b/src/game/src/questlua_guild.cpp @@ -297,12 +297,12 @@ namespace quest int guild_change_master(lua_State* L) { - // ϰ - // 0 : Է ̸ ߸Ǿ ( ڿ ƴ ) - // 1 : ƴ - // 2 : ̸ - // 3 : û - // 4 : 尡 + // 리턴값 + // 0 : 입력한 이름이 잘못되었음 ( 문자열이 아님 ) + // 1 : 길드장이 아님 + // 2 : 지정한 이름의 길드원이 없음 + // 3 : 요청 성공 + // 4 : 길드가 없음 LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr(); @@ -338,23 +338,23 @@ namespace quest int guild_change_master_with_limit(lua_State* L) { - // - // arg0 : ̸ - // arg1 : - // arg2 : resign_limit ð - // arg3 : be_other_leader ð - // arg4 : be_other_member ð - // arg5 : ijΰ ƴѰ + // 인자 + // arg0 : 새 길드장 이름 + // arg1 : 새 길드장 레벨 제한 + // arg2 : resign_limit 제한 시간 + // arg3 : be_other_leader 제한 시간 + // arg4 : be_other_member 제한 시간 + // arg5 : 캐시템인가 아닌가 // - // ϰ - // 0 : Է ̸ ߸Ǿ ( ڿ ƴ ) - // 1 : ƴ - // 2 : ̸ - // 3 : û - // 4 : 尡 - // 5 : ̸ ¶ ƴ - // 6 : ij ط - // 7 : be_other_leader ѿ ɸ + // 리턴값 + // 0 : 입력한 이름이 잘못되었음 ( 문자열이 아님 ) + // 1 : 길드장이 아님 + // 2 : 지정한 이름의 길드원이 없음 + // 3 : 요청 성공 + // 4 : 길드가 없음 + // 5 : 지정한 이름이 온라인이 아님 + // 6 : 지정한 캐릭터 레벨이 기준레벨보다 낮음 + // 7 : 새 길드장이 be_other_leader 제한에 걸림 LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr(); diff --git a/src/game/src/questlua_horse.cpp b/src/game/src/questlua_horse.cpp index 1f44735..5ea7def 100644 --- a/src/game/src/questlua_horse.cpp +++ b/src/game/src/questlua_horse.cpp @@ -61,10 +61,10 @@ namespace quest { LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr(); - // ȯϸ ָ ޷ + // 소환하면 멀리서부터 달려오는지 여부 bool bFromFar = lua_isboolean(L, 1) ? lua_toboolean(L, 1) : false; - // ȯ vnum + // 소환수의 vnum DWORD horseVnum= lua_isnumber(L, 2) ? lua_tonumber(L, 2) : 0; const char* name = lua_isstring(L, 3) ? lua_tostring(L, 3) : 0; @@ -212,10 +212,10 @@ namespace quest int horse_set_name(lua_State* L) { - // ϰ - // 0 : - // 1 : ߸ ̸̴ - // 2 : ̸ ٲٱ + // 리턴값 + // 0 : 소유한 말이 없다 + // 1 : 잘못된 이름이다 + // 2 : 이름 바꾸기 성공 if ( lua_isstring(L, -1) != true ) return 0; diff --git a/src/game/src/questlua_item.cpp b/src/game/src/questlua_item.cpp index c5e0978..6da9fe8 100644 --- a/src/game/src/questlua_item.cpp +++ b/src/game/src/questlua_item.cpp @@ -437,7 +437,7 @@ namespace quest ITEM_MANAGER::instance().FlushDelayedSave(pkNewItem); pkNewItem->AttrLog(); - // ! + // 성공! lua_pushboolean(L, 1); } diff --git a/src/game/src/questlua_marriage.cpp b/src/game/src/questlua_marriage.cpp index cbe769e..975ed32 100644 --- a/src/game/src/questlua_marriage.cpp +++ b/src/game/src/questlua_marriage.cpp @@ -162,7 +162,7 @@ namespace quest } if (pMarriage->pWeddingInfo) { - // ȥ û + // 결혼식 끝내기 요청 pMarriage->RequestEndWedding(); } return 0; diff --git a/src/game/src/questlua_monarch.cpp b/src/game/src/questlua_monarch.cpp index d806b12..5cb2736 100644 --- a/src/game/src/questlua_monarch.cpp +++ b/src/game/src/questlua_monarch.cpp @@ -145,7 +145,7 @@ namespace quest int HealPrice = quest::CQuestManager::instance().GetEventFlag("MonarchHealGold"); if (HealPrice == 0) - HealPrice = 2000000; // 200 + HealPrice = 2000000; // 200만 if (CMonarch::instance().HealMyEmpire(ch, HealPrice)) { @@ -160,7 +160,7 @@ namespace quest return 1; } - // Ʈ Լ + // 군주의 사자후 퀘스트 함수 int monarch_powerup(lua_State * L) { LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr(); @@ -168,7 +168,7 @@ namespace quest if (!ch) return 0; - // üũ + //군주 체크 if (false==ch->IsMonarch()) { if (!ch->IsGM()) @@ -179,8 +179,8 @@ namespace quest } } - // ˻ - int money_need = 5000000; // 500 + //군주 국고 검사 + int money_need = 5000000; // 500만 if (!CMonarch::instance().IsMoneyOk(money_need, ch->GetEmpire())) { int NationMoney = CMonarch::instance().GetMoney(ch->GetEmpire()); @@ -195,10 +195,10 @@ namespace quest return 0; } - // + //군주의 사자후 적용 CMonarch::instance().PowerUp(ch->GetEmpire(), true); - // ð + //군주의 사자후 적용시간 int g_nMonarchPowerUpCT = 60 * 3; monarch_powerup_event_info* info = AllocEventInfo(); @@ -216,7 +216,7 @@ namespace quest return 1; } - // ݰ Ʈ Լ + // 군주의 금강권 퀘스트 함수 int monarch_defenseup(lua_State * L) { LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr(); @@ -225,7 +225,7 @@ namespace quest return 0; - // üũ + //군주 체크 if (false==ch->IsMonarch()) { @@ -237,7 +237,7 @@ namespace quest } } - int money_need = 5000000; // 500 + int money_need = 5000000; // 500만 if (!CMonarch::instance().IsMoneyOk(money_need, ch->GetEmpire())) { int NationMoney = CMonarch::instance().GetMoney(ch->GetEmpire()); @@ -252,10 +252,10 @@ namespace quest return 0; } - // ݰ + //군주의 금강권 적용 CMonarch::instance().DefenseUp(ch->GetEmpire(), true); - // ݰ ð + //군주의 금강권 적용 시간 int g_nMonarchDefenseUpCT = 60 * 3; monarch_defenseup_event_info* info = AllocEventInfo(); @@ -326,9 +326,9 @@ namespace quest int x = ch->GetX(); int y = ch->GetY(); #if 0 - if (11505 == mob_vnum) // Ȳݵβ + if (11505 == mob_vnum) // 황금두꺼비 { - // ˻ + //군주 국고 검사 if (!CMonarch::instance().IsMoneyOk(CASTLE_FROG_PRICE, ch->GetEmpire())) { int NationMoney = CMonarch::instance().GetMoney(ch->GetEmpire()); @@ -340,7 +340,7 @@ namespace quest if (mob) { - // + // 국고감소 CMonarch::instance().SendtoDBDecMoney(CASTLE_FROG_PRICE, ch->GetEmpire(), ch); castle_save(); } @@ -417,7 +417,7 @@ namespace quest { int money_need = castle_cost_of_hiring_guard(group_vnum); - // ˻ + //군주 국고 검사 if (!CMonarch::instance().IsMoneyOk(money_need, ch->GetEmpire())) { int NationMoney = CMonarch::instance().GetMoney(ch->GetEmpire()); @@ -428,7 +428,7 @@ namespace quest if (guard_leader) { - // + // 국고감소 CMonarch::instance().SendtoDBDecMoney(money_need, ch->GetEmpire(), ch); castle_save(); } @@ -491,7 +491,7 @@ namespace quest return 0; } - // Ÿ ˻ + //군주 쿨타임 검사 if (!ch->IsMCOK(CHARACTER::MI_WARP)) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d \xC3\xCA\xB0\xA3 \xC4\xF0\xC5\xB8\xC0\xD3\xC0\xCC \xC0\xFB\xBF\xEB\xC1\xDF\xC0\xD4\xB4\xCF\xB4\xD9."), ch->GetMCLTime(CHARACTER::MI_WARP)); @@ -499,10 +499,10 @@ namespace quest } - // ȯ + //군주 몹 소환 비용 const int WarpPrice = 10000; - // ˻ + //군주 국고 검사 if (!CMonarch::instance().IsMoneyOk(WarpPrice, ch->GetEmpire())) { int NationMoney = CMonarch::instance().GetMoney(ch->GetEmpire()); @@ -547,10 +547,10 @@ namespace quest ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s \xBF\xA1\xB0\xD4\xB7\xCE \xC0\xCC\xB5\xBF\xC7\xD5\xB4\xCF\xB4\xD9"), name.c_str()); ch->WarpSet(pos.x, pos.y); - // 谨 + //군주 돈 삭감 CMonarch::instance().SendtoDBDecMoney(WarpPrice, ch->GetEmpire(), ch); - //Ÿ ʱȭ + //쿨타임 초기화 ch->SetMC(CHARACTER::MI_WARP); } @@ -584,10 +584,10 @@ namespace quest ch->WarpSet(x,y); ch->Stop(); - // 谨 + //군주 돈 삭감 CMonarch::instance().SendtoDBDecMoney(WarpPrice, ch->GetEmpire(), ch); - //Ÿ ʱȭ + //쿨타임 초기화 ch->SetMC(CHARACTER::MI_WARP); return 0; @@ -646,17 +646,17 @@ namespace quest return 0; } - // Ÿ ˻ + // 군주 쿨타임 검사 if (!ch->IsMCOK(CHARACTER::MI_TRANSFER)) { ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d \xC3\xCA\xB0\xA3 \xC4\xF0\xC5\xB8\xC0\xD3\xC0\xCC \xC0\xFB\xBF\xEB\xC1\xDF\xC0\xD4\xB4\xCF\xB4\xD9."), ch->GetMCLTime(CHARACTER::MI_TRANSFER)); return 0; } - // + // 군주 워프 비용 const int WarpPrice = 10000; - // ˻ + // 군주 국고 검사 if (!CMonarch::instance().IsMoneyOk(WarpPrice, ch->GetEmpire())) { int NationMoney = CMonarch::instance().GetMoney(ch->GetEmpire()); @@ -705,10 +705,10 @@ namespace quest P2P_MANAGER::instance().Send(&pgg, sizeof(TPacketGGTransfer)); ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%s \xB4\xD4\xC0\xBB \xBC\xD2\xC8\xAF\xC7\xCF\xBF\xB4\xBD\xC0\xB4\xCF\xB4\xD9."), name.c_str()); - // 谨 + // 군주 돈 삭감 CMonarch::instance().SendtoDBDecMoney(WarpPrice, ch->GetEmpire(), ch); - // Ÿ ʱȭ + // 쿨타임 초기화 ch->SetMC(CHARACTER::MI_TRANSFER); } else @@ -743,9 +743,9 @@ namespace quest } tch->WarpSet(ch->GetX(), ch->GetY(), ch->GetMapIndex()); - // 谨 + // 군주 돈 삭감 CMonarch::instance().SendtoDBDecMoney(WarpPrice, ch->GetEmpire(), ch); - // Ÿ ʱȭ + // 쿨타임 초기화 ch->SetMC(CHARACTER::MI_TRANSFER); return 0; } diff --git a/src/game/src/questlua_party.cpp b/src/game/src/questlua_party.cpp index 607377e..022ff4c 100644 --- a/src/game/src/questlua_party.cpp +++ b/src/game/src/questlua_party.cpp @@ -323,8 +323,8 @@ namespace quest } }; - // Ƽ ִ Լ. - // ʿ ִ Ƽ ޴´. + // 파티 단위로 버프 주는 함수. + // 같은 맵에 있는 파티원만 영향을 받는다. int party_give_buff (lua_State* L) { CQuestManager & q = CQuestManager::instance(); @@ -405,7 +405,7 @@ namespace quest { "is_in_dungeon", party_is_in_dungeon }, { "give_buff", party_give_buff }, { "is_map_member_flag_lt", party_is_map_member_flag_lt }, - { "get_member_pids", party_get_member_pids }, // Ƽ pid return + { "get_member_pids", party_get_member_pids }, // 파티원들의 pid를 return { NULL, NULL } }; diff --git a/src/game/src/questlua_pc.cpp b/src/game/src/questlua_pc.cpp index a413b57..bd9d642 100644 --- a/src/game/src/questlua_pc.cpp +++ b/src/game/src/questlua_pc.cpp @@ -232,7 +232,7 @@ namespace quest return; } //PREVENT_PORTAL_AFTER_EXCHANGE - //ȯ ðüũ + //교환 후 시간체크 if ( iPulse - pkChr->GetExchangeTime() < PASSES_PER_SEC(60) ) { pkChr->ChatPacket( CHAT_TYPE_INFO, LC_TEXT("\xB0\xC5\xB7\xA1 \xC8\xC4 1\xBA\xD0 \xC0\xCC\xB3\xBB\xBF\xA1\xB4\xC2 \xB4\xD9\xB8\xA5\xC1\xF6\xBF\xAA\xC0\xB8\xB7\xCE \xC0\xCC\xB5\xBF \xC7\xD2 \xBC\xF6 \xBE\xF8\xBD\xC0\xB4\xCF\xB4\xD9." ) ); @@ -447,7 +447,7 @@ namespace quest DWORD dwVnum; - if (lua_isnumber(L,2)) // ȣΰ ȣ ش. + if (lua_isnumber(L,2)) // 번호인경우 번호로 준다. dwVnum = (int) lua_tonumber(L, 2); else if (!ITEM_MANAGER::instance().GetVnum(lua_tostring(L, 2), dwVnum)) { @@ -487,7 +487,7 @@ namespace quest DWORD dwVnum; - if (lua_isnumber(L, 1)) // ȣΰ ȣ ش. + if (lua_isnumber(L, 1)) // 번호인경우 번호로 준다. { dwVnum = (int) lua_tonumber(L, 1); } @@ -543,7 +543,7 @@ namespace quest DWORD dwVnum; - if (lua_isnumber(L, 1)) // ȣΰ ȣ ش. + if (lua_isnumber(L, 1)) // 번호인경우 번호로 준다. { dwVnum = (int) lua_tonumber(L, 1); } @@ -804,7 +804,7 @@ namespace quest LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr(); - if (val > 0) // Ű ̹Ƿ + if (val > 0) // 증가시키는 것이므로 무조건 성공 리턴 ch->PointChange(POINT_SP, val); else if (val < 0) { @@ -857,18 +857,18 @@ namespace quest PC* pPC = CQuestManager::instance().GetCurrentPC(); LogManager::instance().QuestRewardLog(pPC->GetCurrentQuestName().c_str(), ch->GetPlayerID(), ch->GetLevel(), newLevel, 0); - //Ʈ : ų, 꽺ų, + //포인트 : 스킬, 서브스킬, 스탯 ch->PointChange(POINT_SKILL, newLevel - ch->GetLevel()); ch->PointChange(POINT_SUB_SKILL, newLevel < 10 ? 0 : newLevel - std::max(ch->GetLevel(), 9)); ch->PointChange(POINT_STAT, ((std::clamp(newLevel, 1, 90) - ch->GetLevel()) * 3) + ch->GetPoint(POINT_LEVEL_STEP)); - // + //레벨 ch->PointChange(POINT_LEVEL, newLevel - ch->GetLevel(), false, true); //HP, SP ch->SetRandomHP((newLevel - 1) * Random::get(JobInitialPoints[ch->GetJob()].hp_per_lv_begin, JobInitialPoints[ch->GetJob()].hp_per_lv_end)); ch->SetRandomSP((newLevel - 1) * Random::get(JobInitialPoints[ch->GetJob()].sp_per_lv_begin, JobInitialPoints[ch->GetJob()].sp_per_lv_end)); - // ȸ + // 회복 ch->PointChange(POINT_HP, ch->GetMaxHP() - ch->GetHP()); ch->PointChange(POINT_SP, ch->GetMaxSP() - ch->GetSP()); @@ -931,8 +931,8 @@ namespace quest return 1; } - // 20050725.myevan. ȥ ý ġ ι ҸǴ װ ߻ - // ġ ̿ ϰ Ѵ. + // 20050725.myevan.은둔의 망토 사용중 혼석 수련시 선악치가 두배 소모되는 버그가 발생해 + // 실제 선악치를 이용해 계산을 하게 한다. int pc_get_real_alignment(lua_State* L) { lua_pushnumber(L, CQuestManager::instance().GetCurrentCharacterPtr()->GetRealAlignment()/10); @@ -1257,7 +1257,7 @@ namespace quest ch->RemoveAffect(AFFECT_MOUNT); ch->RemoveAffect(AFFECT_MOUNT_BONUS); - // ȯǾ ٴϴ ¶ + // 말이 소환되어 따라다니는 상태라면 말부터 없앰 if (ch->GetHorse()) ch->HorseSummon(false); @@ -1525,7 +1525,7 @@ namespace quest if (pct == 100 || Random::get(1, 100) <= pct) { - // + // 개량 성공 lua_pushboolean(L, 1); LPITEM pkNewItem = ITEM_MANAGER::instance().CreateItem(item->GetRefinedVnum(), 1, 0, false); @@ -1562,7 +1562,7 @@ namespace quest } else { - // + // 개량 실패 lua_pushboolean(L, 0); } @@ -1599,7 +1599,7 @@ namespace quest pdw[1] = 1; pdw[2] = q.GetEventFlag("lotto_round"); - // ÷ Ѵ + // 추첨서는 소켓을 설정한다 DBManager::instance().ReturnQuery(QID_LOTTO, ch->GetPlayerID(), pdw, "INSERT INTO lotto_list VALUES(0, 'server%s', %u, NOW())", get_table_postfix(), ch->GetPlayerID()); @@ -1848,14 +1848,14 @@ namespace quest return 0; } - //ڷƮ + //텔레포트 int pc_teleport ( lua_State * L ) { LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr(); int x=0,y=0; if ( lua_isnumber(L, 1) ) { - // + // 지역명 워프 const int TOWN_NUM = 10; struct warp_by_town_name { @@ -2056,13 +2056,13 @@ teleport_area: int pc_change_name(lua_State* L) { - // ϰ - // 0: ̸ α׾ƿ - // 1: ũƮ ڿ Ѿ ʾ - // 2: check_name - // 3: ̹ ̸ - // 4: - // 5: ش + // 리턴값 + // 0: 새이름을 설정한 뒤 로그아웃을 안했음 + // 1: 스크립트에서 문자열이 넘어오지 않았음 + // 2: check_name 을 통과하지 못했음 + // 3: 이미 같은 이름이 사용중 + // 4: 성공 + // 5: 해당 기능 지원하지 않음 if ( LC_IsEurope() ) { lua_pushnumber(L, 5); @@ -2102,7 +2102,7 @@ teleport_area: int count = 0; str_to_number(count, row[0]); - // ̹ ش ̸ ijͰ + // 이미 해당 이름을 가진 캐릭터가 있음 if ( count != 0 ) { lua_pushnumber(L, 3); @@ -2353,8 +2353,8 @@ teleport_area: int idx = 1; - // ȥ ʿ . - // Լ Ż Լ ϴ. + // 용혼석 슬롯은 할 필요 없을 듯. + // 이 함수는 탈석서용 함수인 듯 하다. for ( int i=0; i < INVENTORY_MAX_NUM + WEAR_MAX_NUM; i++ ) { LPITEM pItem = pChar->GetInventoryItem(i); @@ -2743,7 +2743,7 @@ teleport_area: return 1; } - int pc_get_informer_type(lua_State* L) // + int pc_get_informer_type(lua_State* L) //독일 선물 기능 { LPCHARACTER pChar = CQuestManager::instance().GetCurrentCharacterPtr(); @@ -2986,17 +2986,17 @@ teleport_area: { "charge_cash", pc_charge_cash }, - { "get_informer_type", pc_get_informer_type }, // + { "get_informer_type", pc_get_informer_type }, //독일 선물 기능 { "get_informer_item", pc_get_informer_item }, - { "give_award", pc_give_award }, //Ϻ ѹ ݱ - { "give_award_socket", pc_give_award_socket }, // κ丮 . Լ. + { "give_award", pc_give_award }, //일본 계정당 한번씩 금괴 지급 + { "give_award_socket", pc_give_award_socket }, //몰 인벤토리에 아이템 지급. 소켓 설정을 위한 함수. - { "get_killee_drop_pct", pc_get_killee_drop_pct }, /* mob_vnum.kill ̺Ʈ killee pc level , pc ̾ Ȯ. - * return (, и). - * ( ѵ, CreateDropItem GetDropPct iDeltaPercent, iRandRange returnѴٰ .) - * ( Ф) - * ǻ : kill event ! + { "get_killee_drop_pct", pc_get_killee_drop_pct }, /* mob_vnum.kill 이벤트에서 killee와 pc와의 level 차이, pc의 프리미엄 드랍률 등등을 고려한 아이템 드랍 확률. + * return 값은 (분자, 분모). + * (말이 복잡한데, CreateDropItem의 GetDropPct의 iDeltaPercent, iRandRange를 return한다고 보면 됨.) + * (이 말이 더 어려울라나 ㅠㅠ) + * 주의사항 : kill event에서만 사용할 것! */ { NULL, NULL } diff --git a/src/game/src/questlua_pet.cpp b/src/game/src/questlua_pet.cpp index d5c62dd..cc1d6a1 100644 --- a/src/game/src/questlua_pet.cpp +++ b/src/game/src/questlua_pet.cpp @@ -34,13 +34,13 @@ namespace quest return 1; } - // ȯ vnum + // 소환수의 vnum DWORD mobVnum= lua_isnumber(L, 1) ? lua_tonumber(L, 1) : 0; - // ȯ ̸ + // 소환수의 이름 const char* petName = lua_isstring(L, 2) ? lua_tostring(L, 2) : 0; - // ȯϸ ָ ޷ + // 소환하면 멀리서부터 달려오는지 여부 bool bFromFar = lua_isboolean(L, 3) ? lua_toboolean(L, 3) : false; CPetActor* pet = petSystem->Summon(mobVnum, pItem, petName, bFromFar); @@ -62,7 +62,7 @@ namespace quest if (0 == petSystem) return 0; - // ȯ vnum + // 소환수의 vnum DWORD mobVnum= lua_isnumber(L, 1) ? lua_tonumber(L, 1) : 0; petSystem->Unsummon(mobVnum); @@ -94,7 +94,7 @@ namespace quest if (0 == petSystem) return 0; - // ȯ vnum + // 소환수의 vnum DWORD mobVnum= lua_isnumber(L, 1) ? lua_tonumber(L, 1) : 0; CPetActor* petActor = petSystem->GetByVnum(mobVnum); diff --git a/src/game/src/questlua_quest.cpp b/src/game/src/questlua_quest.cpp index b442cb5..e90b482 100644 --- a/src/game/src/questlua_quest.cpp +++ b/src/game/src/questlua_quest.cpp @@ -140,7 +140,7 @@ namespace quest int quest_coroutine_yield(lua_State * L) { CQuestManager& q = CQuestManager::instance(); - // other_pc_block ο yield Ͼ ȵȴ. . + // other_pc_block 내부에서는 yield가 일어나서는 안된다. 절대로. if (q.IsInOtherPCBlock()) { quest_err("FATAL ERROR! Yield occur in other_pc_block."); @@ -214,10 +214,10 @@ namespace quest { "done", quest_done }, { "getcurrentquestindex", quest_get_current_quest_index }, { "no_send", quest_no_send }, - // begin_other_pc_block(pid), end_other_pc_block ̸ other_pc_block̶ . - // other_pc_block current_pc pid ȴ. - // ٽ current_pc ư. - /* ̷ . + // begin_other_pc_block(pid), end_other_pc_block 사이를 other_pc_block이라고 하자. + // other_pc_block에서는 current_pc가 pid로 변경된다. + // 끝나면 다시 원래의 current_pc로 돌아간다. + /* 이런 것을 위해 만듬. for i, pid in next, pids, nil do q.begin_other_pc_block(pid) if pc.count_item(PASS_TICKET) < 1 then @@ -227,7 +227,7 @@ namespace quest q.end_other_pc_block() end */ - // : other_pc_block ο yield Ͼ ȵȴ.(ex. wait, select, input, ...) + // 주의 : other_pc_block 내부에서는 절대로 yield가 일어나서는 안된다.(ex. wait, select, input, ...) { "begin_other_pc_block", quest_begin_other_pc_block }, { "end_other_pc_block", quest_end_other_pc_block }, { NULL, NULL } diff --git a/src/game/src/questlua_target.cpp b/src/game/src/questlua_target.cpp index 2f7264b..01abf0d 100644 --- a/src/game/src/questlua_target.cpp +++ b/src/game/src/questlua_target.cpp @@ -69,7 +69,7 @@ namespace quest return 0; } - // Ʈ ϵ Ÿ Ѵ. + // 현재 퀘스트에 등록된 타겟을 삭제 한다. int target_delete(lua_State* L) { LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr(); @@ -86,7 +86,7 @@ namespace quest return 0; } - // Ʈ ε Ǿִ Ÿ Ѵ. + // 현재 퀘스트 인덱스로 되어있는 타겟을 모두 삭제한다. int target_clear(lua_State* L) { LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr(); diff --git a/src/game/src/questmanager.cpp b/src/game/src/questmanager.cpp index 0cf51c7..ec0e0f2 100644 --- a/src/game/src/questmanager.cpp +++ b/src/game/src/questmanager.cpp @@ -57,29 +57,29 @@ namespace quest m_pSelectedDungeon = NULL; - m_mapEventName.insert(TEventNameMap::value_type("click", QUEST_CLICK_EVENT)); // NPC Ŭ - m_mapEventName.insert(TEventNameMap::value_type("kill", QUEST_KILL_EVENT)); // Mob - m_mapEventName.insert(TEventNameMap::value_type("timer", QUEST_TIMER_EVENT)); // ̸ ص ð - m_mapEventName.insert(TEventNameMap::value_type("levelup", QUEST_LEVELUP_EVENT)); // - m_mapEventName.insert(TEventNameMap::value_type("login", QUEST_LOGIN_EVENT)); // α - m_mapEventName.insert(TEventNameMap::value_type("logout", QUEST_LOGOUT_EVENT)); // α׾ƿ - m_mapEventName.insert(TEventNameMap::value_type("button", QUEST_BUTTON_EVENT)); // Ʈ ư - m_mapEventName.insert(TEventNameMap::value_type("info", QUEST_INFO_EVENT)); // Ʈ â - m_mapEventName.insert(TEventNameMap::value_type("chat", QUEST_CHAT_EVENT)); // Ư Ű ȭ - m_mapEventName.insert(TEventNameMap::value_type("in", QUEST_ATTR_IN_EVENT)); // Ư Ӽ  - m_mapEventName.insert(TEventNameMap::value_type("out", QUEST_ATTR_OUT_EVENT)); // Ư Ӽ - m_mapEventName.insert(TEventNameMap::value_type("use", QUEST_ITEM_USE_EVENT)); // Ʈ - m_mapEventName.insert(TEventNameMap::value_type("server_timer", QUEST_SERVER_TIMER_EVENT)); // Ÿ̸ ( ׽Ʈ ȵ) - m_mapEventName.insert(TEventNameMap::value_type("enter", QUEST_ENTER_STATE_EVENT)); // Ʈ - m_mapEventName.insert(TEventNameMap::value_type("leave", QUEST_LEAVE_STATE_EVENT)); // Ʈ ٸ Ʈ ٲ - m_mapEventName.insert(TEventNameMap::value_type("letter", QUEST_LETTER_EVENT)); // α ϰų Ʈ ٲ - m_mapEventName.insert(TEventNameMap::value_type("take", QUEST_ITEM_TAKE_EVENT)); // - m_mapEventName.insert(TEventNameMap::value_type("target", QUEST_TARGET_EVENT)); // Ÿ - m_mapEventName.insert(TEventNameMap::value_type("party_kill", QUEST_PARTY_KILL_EVENT)); // Ƽ ͸ ( ) + m_mapEventName.insert(TEventNameMap::value_type("click", QUEST_CLICK_EVENT)); // NPC를 클릭 + m_mapEventName.insert(TEventNameMap::value_type("kill", QUEST_KILL_EVENT)); // Mob을 사냥 + m_mapEventName.insert(TEventNameMap::value_type("timer", QUEST_TIMER_EVENT)); // 미리 지정해둔 시간이 지남 + m_mapEventName.insert(TEventNameMap::value_type("levelup", QUEST_LEVELUP_EVENT)); // 레벨업을 함 + m_mapEventName.insert(TEventNameMap::value_type("login", QUEST_LOGIN_EVENT)); // 로그인 시 + m_mapEventName.insert(TEventNameMap::value_type("logout", QUEST_LOGOUT_EVENT)); // 로그아웃 시 + m_mapEventName.insert(TEventNameMap::value_type("button", QUEST_BUTTON_EVENT)); // 퀘스트 버튼을 누름 + m_mapEventName.insert(TEventNameMap::value_type("info", QUEST_INFO_EVENT)); // 퀘스트 정보창을 염 + m_mapEventName.insert(TEventNameMap::value_type("chat", QUEST_CHAT_EVENT)); // 특정 키워드로 대화를 함 + m_mapEventName.insert(TEventNameMap::value_type("in", QUEST_ATTR_IN_EVENT)); // 맵의 특정 속성에 들어감 + m_mapEventName.insert(TEventNameMap::value_type("out", QUEST_ATTR_OUT_EVENT)); // 맵의 특정 속성에서 나옴 + m_mapEventName.insert(TEventNameMap::value_type("use", QUEST_ITEM_USE_EVENT)); // 퀘스트 아이템을 사용 + m_mapEventName.insert(TEventNameMap::value_type("server_timer", QUEST_SERVER_TIMER_EVENT)); // 서버 타이머 (아직 테스트 안됐음) + m_mapEventName.insert(TEventNameMap::value_type("enter", QUEST_ENTER_STATE_EVENT)); // 현재 스테이트가 됨 + m_mapEventName.insert(TEventNameMap::value_type("leave", QUEST_LEAVE_STATE_EVENT)); // 현재 스테이트에서 다른 스테이트로 바뀜 + m_mapEventName.insert(TEventNameMap::value_type("letter", QUEST_LETTER_EVENT)); // 로긴 하거나 스테이트가 바껴 새로 정보를 세팅해줘야함 + m_mapEventName.insert(TEventNameMap::value_type("take", QUEST_ITEM_TAKE_EVENT)); // 아이템을 받음 + m_mapEventName.insert(TEventNameMap::value_type("target", QUEST_TARGET_EVENT)); // 타겟 + m_mapEventName.insert(TEventNameMap::value_type("party_kill", QUEST_PARTY_KILL_EVENT)); // 파티 멤버가 몬스터를 사냥 (리더에게 옴) m_mapEventName.insert(TEventNameMap::value_type("unmount", QUEST_UNMOUNT_EVENT)); - m_mapEventName.insert(TEventNameMap::value_type("pick", QUEST_ITEM_PICK_EVENT)); // ִ . - m_mapEventName.insert(TEventNameMap::value_type("sig_use", QUEST_SIG_USE_EVENT)); // Special item group . - m_mapEventName.insert(TEventNameMap::value_type("item_informer", QUEST_ITEM_INFORMER_EVENT)); // ϼ׽Ʈ + m_mapEventName.insert(TEventNameMap::value_type("pick", QUEST_ITEM_PICK_EVENT)); // 떨어져있는 아이템을 습득함. + m_mapEventName.insert(TEventNameMap::value_type("sig_use", QUEST_SIG_USE_EVENT)); // Special item group에 속한 아이템을 사용함. + m_mapEventName.insert(TEventNameMap::value_type("item_informer", QUEST_ITEM_INFORMER_EVENT)); // 독일선물기능테스트 m_bNoSend = false; @@ -253,9 +253,9 @@ namespace quest if (!pPC->GetRunningQuestState()->chat_scripts.empty()) { - // ä ̺Ʈ - // Ʈ Ʈ ΰ Ʈ ̹Ƿ - // õ Ʈ Ѵ. + // 채팅 이벤트인 경우 + // 현재 퀘스트는 어느 퀘스트를 실행할 것인가를 고르는 퀘스트 이므로 + // 끝내고 선택된 퀘스트를 실행한다. QuestState& old_qs = *pPC->GetRunningQuestState(); CloseState(old_qs); @@ -368,7 +368,7 @@ namespace quest pPC->CancelRunning(); } - // α׾ƿ Ѵ. + // 지우기 전에 로그아웃 한다. Logout(ch->GetPlayerID()); if (ch == m_pCurrentCharacter) @@ -380,7 +380,7 @@ namespace quest /////////////////////////////////////////////////////////////////////////////////////////// // - // Quest Event + // Quest Event 관련 // /////////////////////////////////////////////////////////////////////////////////////////// void CQuestManager::Login(unsigned int pc, const char * c_pszQuest) @@ -427,9 +427,9 @@ namespace quest if (!CheckQuestLoaded(pPC)) return; - /* [hyo] kill ߺ ī ̽ - quest script when 171.kill begin ... ڵ Ͽ ũƮ óǾ - ٷ return ʰ ٸ ˻絵 ϵ . (2011/07/21) + /* [hyo] 몹 kill시 중복 카운팅 이슈 관련한 수정사항 + quest script에 when 171.kill begin ... 등의 코드로 인하여 스크립트가 처리되었더라도 + 바로 return하지 않고 다른 검사도 수행하도록 변경함. (2011/07/21) */ // call script m_mapNPC[npc].OnKill(*pPC); @@ -684,7 +684,7 @@ namespace quest } } - // Speical Item Group ǵ Group Use + // Speical Item Group에 정의된 Group Use bool CQuestManager::SIGUse(unsigned int pc, DWORD sig_vnum, LPITEM item, bool bReceiveAll) { SPDLOG_TRACE("questmanager::SIGUse Start : itemVnum : {} PC : {}", item->GetOriginalVnum(), pc); @@ -826,7 +826,7 @@ namespace quest else SPDLOG_ERROR("QUEST no such pc id : {}", pc); } - // ׽Ʈ + //독일 선물 기능 테스트 void CQuestManager::ItemInformer(unsigned int pc,unsigned int vnum) { @@ -836,7 +836,7 @@ namespace quest m_mapNPC[QUEST_NO_NPC].OnItemInformer(*pPC,vnum); } /////////////////////////////////////////////////////////////////////////////////////////// - // END OF Ʈ ̺Ʈ ó + // END OF 퀘스트 이벤트 처리 /////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////// @@ -1258,19 +1258,19 @@ namespace quest continue; if (value) { - // + // 밤 ch->ChatPacket(CHAT_TYPE_COMMAND, "DayMode dark"); } else { - // + // 낮 ch->ChatPacket(CHAT_TYPE_COMMAND, "DayMode light"); } } if (value && !prev_value) { - // ش + // 없으면 만들어준다 struct SNPCSellFireworkPosition { int lMapIndex; @@ -1306,7 +1306,7 @@ namespace quest } else if (!value && prev_value) { - // ش + // 있으면 지워준다 CharacterVectorInteractor i; if (CHARACTER_MANAGER::instance().GetCharactersByRaceNum(xmas::MOB_XMAS_FIRWORK_SELLER_VNUM, i)) @@ -1395,7 +1395,7 @@ namespace quest } else if (name == "new_xmas_event") { - // 20126 newŸ. + // 20126 new산타. static DWORD new_santa = 20126; if (value != 0) { @@ -1534,12 +1534,12 @@ namespace quest bool CQuestManager::ExecuteQuestScript(PC& pc, const string& quest_name, const int state, const char* code, const int code_size, vector* pChatScripts, bool bUseCache) { - // + // 실행공간을 생성 QuestState qs = CQuestManager::instance().OpenState(quest_name, state); if (pChatScripts) qs.chat_scripts.swap(*pChatScripts); - // ڵ带 о + // 코드를 읽어들임 if (bUseCache) { lua_getglobal(qs.co, "__codecache"); @@ -1578,10 +1578,10 @@ namespace quest else luaL_loadbuffer(qs.co, code, code_size, quest_name.c_str()); - // ÷̾ + // 플레이어와 연결 pc.SetQuest(quest_name, qs); - // + // 실행 QuestState& rqs = *pc.GetRunningQuestState(); if (!CQuestManager::instance().RunState(rqs)) { diff --git a/src/game/src/questnpc.cpp b/src/game/src/questnpc.cpp index 6e5d20b..446a7c3 100644 --- a/src/game/src/questnpc.cpp +++ b/src/game/src/questnpc.cpp @@ -131,7 +131,7 @@ namespace quest // /////////////////////////////////////////////////////////////////////////// - // Index ( Ƿ ִ , index ) + // 순서 Index (여러개 있을 수 있으므로 있는 것임, 실제 index 값은 쓰지 않음) j = i; i = s.find('.', i + 1); @@ -410,7 +410,7 @@ namespace quest void operator()(PC::QuestInfoIterator& itPCQuest, NPC::QuestMapType::iterator& itQuestMap) { - // + // 없으니 새로 시작 DWORD dwQuestIndex = itQuestMap->first; if (NPC::HasStartState(itQuestMap->second) && CQuestManager::instance().CanStartQuest(dwQuestIndex)) @@ -494,8 +494,8 @@ namespace quest for (int i = 0; i < fMatch.size; i++) { if ( i != 0 ) { - //2012.05.14 <> : Ʈ Ŵ m_pCurrentPC ٲ 찡 ߻Ͽ, - //ΰ ̻ ũƮ , ι° ʹ Ʈ Ŵ PC Ѵ. + //2012.05.14 <김용욱> : 퀘스트 매니저의 m_pCurrentPC가 바뀌는 경우가 발생하여, + //두개 이상의 스크립트를 실행시, 두번째 부터는 퀘스트 매니저의 PC 값을 새로 셋팅한다. PC * pPC = CQuestManager::instance().GetPC(pc.GetID()); } @@ -805,7 +805,7 @@ namespace quest QuestMapType & rmapEventOwnQuest = m_mapOwnQuest[EventIndex]; QuestMapType::iterator itQuestMap = rmapEventOwnQuest.find(quest_index); - // ׷ Ʈ + // 그런 퀘스트가 없음 if (itQuestMap == rmapEventOwnQuest.end()) return false; @@ -817,7 +817,7 @@ namespace quest } else { - // ұ? + // 새로 시작할까요? if (CQuestManager::instance().CanStartQuest(itQuestMap->first, pc) && HasStartState(itQuestMap->second)) iState = 0; else @@ -962,7 +962,7 @@ namespace quest else return HandleEvent(pc, QUEST_ITEM_PICK_EVENT); } - // ׽Ʈ + //독일 선물 기능 테스트 bool NPC::OnItemInformer(PC& pc, unsigned int vnum) { return HandleEvent(pc, QUEST_ITEM_INFORMER_EVENT); diff --git a/src/game/src/questpc.cpp b/src/game/src/questpc.cpp index c3a1872..0106462 100644 --- a/src/game/src/questpc.cpp +++ b/src/game/src/questpc.cpp @@ -307,10 +307,10 @@ namespace quest { LPCHARACTER npc = CQuestManager::instance().GetCurrentNPCCharacterPtr(); LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr(); - // npc ־ + // npc 있었던 경우 if (npc && !npc->IsPC()) { - // Ǿ + // 그 엔피씨가 나에게 락인 경우 if (ch->GetPlayerID() == npc->GetQuestNPCID()) { npc->SetQuestNPCID(0); diff --git a/src/game/src/regen.cpp b/src/game/src/regen.cpp index eaff2b3..8ddb138 100644 --- a/src/game/src/regen.cpp +++ b/src/game/src/regen.cpp @@ -24,7 +24,7 @@ enum ERegenModes MODE_VNUM }; -static bool get_word(FILE *fp, char *buf) // ޴´. +static bool get_word(FILE *fp, char *buf) // 워드단위로 받는다. { int i = 0; int c; @@ -172,7 +172,7 @@ static bool read_line(FILE *fp, LPREGEN regen) case MODE_Z_SECTION: str_to_number(regen->z_section, szTmp); - // ͼ ̸ . + // 익셉션 이면 나가주자. if (regen->type == REGEN_TYPE_EXCEPTION) return true; @@ -500,7 +500,7 @@ bool regen_do(const char* filename, int lMapIndex, int base_x, int base_y, LPDUN // before the call to CHARACTER::SetRegen() } - // ó ش. + // 처음엔 무조건 리젠 해준다. regen_spawn_dungeon(regen, pDungeon, bOnce); } @@ -576,7 +576,7 @@ bool regen_load_in_file(const char* filename, int lMapIndex, int base_x, int bas } } - // ó ش. + // 처음엔 무조건 리젠 해준다. regen_spawn(regen, true); } } @@ -683,11 +683,11 @@ bool regen_load(const char* filename, int lMapIndex, int base_x, int base_y) } //NO_REGEN - // Desc: regen.txt ( ؽƮ ) ð 0 ҽ - // Ѵ. + // Desc: regen.txt (외 리젠관련 텍스트 ) 에서 리젠 시간을 0으로 세팅할시 + // 리젠을 하지 안한다. if (regen->time != 0) { - // ó ش. + // 처음엔 무조건 리젠 해준다. regen_spawn(regen, false); regen_event_info* info = AllocEventInfo(); @@ -752,14 +752,14 @@ void regen_reset(int x, int y) if (!regen->event) continue; - // ǥ ǥ ִ Ʈ Ų. + // 좌표가 있으면 좌표 내에 있는 리젠 리스트만 리젠 시킨다. if (x != 0 || y != 0) { if (x >= regen->sx && x <= regen->ex) if (y >= regen->sy && y <= regen->ey) event_reset_time(regen->event, 1); } - // + // 없으면 전부 리젠 else event_reset_time(regen->event, 1); } diff --git a/src/game/src/safebox.cpp b/src/game/src/safebox.cpp index 0586fe5..a70e83a 100644 --- a/src/game/src/safebox.cpp +++ b/src/game/src/safebox.cpp @@ -62,7 +62,7 @@ bool CSafebox::Add(DWORD dwPos, LPITEM pkItem) pkItem->SetWindow(m_bWindowMode); pkItem->SetCell(m_pkChrOwner, dwPos); - pkItem->Save(); // Save ҷ Ѵ. + pkItem->Save(); // 강제로 Save를 불러줘야 한다. ITEM_MANAGER::instance().FlushDelayedSave(pkItem); m_pkGrid->Put(dwPos, 1, pkItem->GetSize()); @@ -141,7 +141,7 @@ bool CSafebox::IsEmpty(DWORD dwPos, BYTE bSize) void CSafebox::ChangeSize(int iSize) { - //  ں ũ  д. + // 현재 사이즈가 인자보다 크면 사이즈를 가만 둔다. if (m_iSize >= iSize) return; @@ -189,7 +189,7 @@ bool CSafebox::MoveItem(BYTE bCell, BYTE bDestCell, BYTE count) if ((item2 = GetItem(bDestCell)) && item != item2 && item2->IsStackable() && !IS_SET(item2->GetAntiFlag(), ITEM_ANTIFLAG_STACK) && - item2->GetVnum() == item->GetVnum()) // ĥ ִ + item2->GetVnum() == item->GetVnum()) // 합칠 수 있는 아이템의 경우 { for (int i = 0; i < ITEM_SOCKET_MAX_NUM; ++i) if (item2->GetSocket(i) != item->GetSocket(i)) diff --git a/src/game/src/sectree.cpp b/src/game/src/sectree.cpp index 7273d1e..daab5bb 100644 --- a/src/game/src/sectree.cpp +++ b/src/game/src/sectree.cpp @@ -149,7 +149,7 @@ bool SECTREE::InsertEntity(LPENTITY pkEnt) if (pkCurTree) pkCurTree->DecreasePC(); } - else if (m_iPCCount > 0 && !pkChr->IsWarp() && !pkChr->IsGoto()) // PC ƴϰ PC ִٸ Idle event Ų. + else if (m_iPCCount > 0 && !pkChr->IsWarp() && !pkChr->IsGoto()) // PC가 아니고 이 곳에 PC가 있다면 Idle event를 시작 시킨다. { pkChr->StartStateMachine(); } diff --git a/src/game/src/sectree_manager.cpp b/src/game/src/sectree_manager.cpp index 80374b7..498d5af 100644 --- a/src/game/src/sectree_manager.cpp +++ b/src/game/src/sectree_manager.cpp @@ -76,8 +76,8 @@ LPSECTREE SECTREE_MAP::Find(DWORD x, DWORD y) void SECTREE_MAP::Build() { - // Ŭ̾Ʈ ݰ 150m ij ֱ - // 3x3ĭ -> 5x5 ĭ ֺsectree Ȯ(ѱ) + // 클라이언트에게 반경 150m 캐릭터의 정보를 주기위해 + // 3x3칸 -> 5x5 칸으로 주변sectree 확대(한국) if (LC_IsYMIR() || LC_IsKorea()) { #define NEIGHBOR_LENGTH 5 @@ -106,7 +106,7 @@ void SECTREE_MAP::Build() } // - // sectree sectree Ʈ . + // 모든 sectree에 대해 주위 sectree들 리스트를 만든다. // MapType::iterator it = map_.begin(); @@ -114,7 +114,7 @@ void SECTREE_MAP::Build() { LPSECTREE tree = it->second; - tree->m_neighbor_list.push_back(tree); // ڽ ִ´. + tree->m_neighbor_list.push_back(tree); // 자신을 넣는다. SPDLOG_TRACE("{}x{}", (int) tree->m_id.coord.x, (int) tree->m_id.coord.y); @@ -153,7 +153,7 @@ void SECTREE_MAP::Build() }; // - // sectree sectree Ʈ . + // 모든 sectree에 대해 주위 sectree들 리스트를 만든다. // MapType::iterator it = map_.begin(); @@ -161,7 +161,7 @@ void SECTREE_MAP::Build() { LPSECTREE tree = it->second; - tree->m_neighbor_list.push_back(tree); // ڽ ִ´. + tree->m_neighbor_list.push_back(tree); // 자신을 넣는다. SPDLOG_TRACE("{}x{}", (int) tree->m_id.coord.x, (int) tree->m_id.coord.y); @@ -230,7 +230,7 @@ LPSECTREE SECTREE_MANAGER::Get(DWORD dwIndex, DWORD x, DWORD y) } // ----------------------------------------------------------------------------- -// Setting.txt SECTREE +// Setting.txt 로 부터 SECTREE 만들기 // ----------------------------------------------------------------------------- int SECTREE_MANAGER::LoadSettingFile(int lMapIndex, const char * c_pszSettingFileName, TMapSetting & r_setting) { @@ -365,10 +365,10 @@ void SECTREE_MANAGER::LoadDungeon(int iIndex, const char * c_pszFileName) } // Fix me -// Town.txt x, y ׳ ް, װ ڵ base ǥ ֱ -// ٸ ʿ ִ Ÿ ̵ Ǿִ. -// տ map̶ų, Ÿ ٸ ĺڰ , -// ٸ Ÿε ̵ ְ . +// 현재 Town.txt에서 x, y를 그냥 받고, 그걸 이 코드 내에서 base 좌표를 더해주기 때문에 +// 다른 맵에 있는 타운으로 절대 이동할 수 없게 되어있다. +// 앞에 map이라거나, 기타 다른 식별자가 있으면, +// 다른 맵의 타운으로도 이동할 수 있게 하자. // by rtsummit bool SECTREE_MANAGER::LoadMapRegion(const char * c_pszFileName, TMapSetting & r_setting, const char * c_pszMapName) { @@ -472,7 +472,7 @@ bool SECTREE_MANAGER::LoadAttribute(LPSECTREE_MAP pkMapSectree, const char * c_p for (int y = 0; y < iHeight; ++y) for (int x = 0; x < iWidth; ++x) { - // UNION ǥ ĸ DWORD ̵ Ѵ. + // UNION 으로 좌표를 합쳐만든 DWORD값을 아이디로 사용한다. SECTREEID id; id.coord.x = (r_setting.iBaseX / SECTREE_SIZE) + x; id.coord.y = (r_setting.iBaseY / SECTREE_SIZE) + y; @@ -543,7 +543,7 @@ bool SECTREE_MANAGER::GetRecallPositionByEmpire(int iMapIndex, BYTE bEmpire, PIX { std::vector::iterator it = m_vec_mapRegion.begin(); - // 10000 Ѵ νϽ Ǿִ. + // 10000을 넘는 맵은 인스턴스 던전에만 한정되어있다. if (iMapIndex >= 10000) { iMapIndex /= 10000; @@ -677,7 +677,7 @@ const TMapRegion * SECTREE_MANAGER::FindRegionByPartialName(const char* szMapNam //if (rRegion.index == lMapIndex) //return &rRegion; if (rRegion.strMapName.find(szMapName)) - return &rRegion; // ij ؼ + return &rRegion; // 캐싱 해서 빠르게 하자 } return NULL; @@ -768,7 +768,7 @@ int SECTREE_MANAGER::Build(const char * c_pszListFileName, const char* c_pszMapB SPDLOG_TRACE("[BUILD] Build {} {} {} ",c_pszMapBasePath, szMapName, iIndex ); - // ͸ ؾ ϴ° Ȯ Ѵ. + // 먼저 이 서버에서 이 맵의 몬스터를 스폰해야 하는가 확인 한다. if (map_allow_find(iIndex)) { LPSECTREE_MAP pkMapSectree = BuildSectreeFromSetting(setting); @@ -967,7 +967,7 @@ bool SECTREE_MANAGER::GetRandomLocation(int lMapIndex, PIXEL_POSITION & r_pos, D int SECTREE_MANAGER::CreatePrivateMap(int lMapIndex) { - if (lMapIndex >= 10000) // 10000 ̻ . (Ȥ ̹ private ̴) + if (lMapIndex >= 10000) // 10000번 이상의 맵은 없다. (혹은 이미 private 이다) return 0; LPSECTREE_MAP pkMapSectree = GetMap(lMapIndex); @@ -1077,7 +1077,7 @@ struct FDestroyPrivateMapEntity void SECTREE_MANAGER::DestroyPrivateMap(int lMapIndex) { - if (lMapIndex < 10000) // private map ε 10000 ̻ ̴. + if (lMapIndex < 10000) // private map 은 인덱스가 10000 이상 이다. return; LPSECTREE_MAP pkMapSectree = GetMap(lMapIndex); @@ -1085,11 +1085,11 @@ void SECTREE_MANAGER::DestroyPrivateMap(int lMapIndex) if (!pkMapSectree) return; - // ϴ ͵ ش. + // 이 맵 위에 현재 존재하는 것들을 전부 없앤다. // WARNING: - // ʿ  Sectree - // ⼭ delete Ƿ Ͱ - // ó ؾ + // 이 맵에 있지만 어떤 Sectree에도 존재하지 않을 수 있음 + // 따라서 여기서 delete 할 수 없으므로 포인터가 깨질 수 있으니 + // 별도 처리를 해야함 FDestroyPrivateMapEntity f; pkMapSectree->for_each(f); @@ -1105,7 +1105,7 @@ TAreaMap& SECTREE_MANAGER::GetDungeonArea(int lMapIndex) if (it == m_map_pkArea.end()) { - return m_map_pkArea[-1]; // ӽ÷ Area + return m_map_pkArea[-1]; // 임시로 빈 Area를 리턴 } return it->second; } @@ -1128,7 +1128,7 @@ void SECTREE_MANAGER::SendNPCPosition(LPCHARACTER ch) TNPCPosition np; - // TODO m_mapNPCPosition[lMapIndex] ּ + // TODO m_mapNPCPosition[lMapIndex] 를 보내주세요 itertype(m_mapNPCPosition[lMapIndex]) it; for (it = m_mapNPCPosition[lMapIndex].begin(); it != m_mapNPCPosition[lMapIndex].end(); ++it) @@ -1361,7 +1361,7 @@ bool SECTREE_MANAGER::ForAttrRegion(int lMapIndex, int lStartX, int lStartY, int } // - // ǥ Cell ũ⿡ ȮѴ. + // 영역의 좌표를 Cell 의 크기에 맞춰 확장한다. // lStartX -= lStartX % CELL_SIZE; @@ -1370,7 +1370,7 @@ bool SECTREE_MANAGER::ForAttrRegion(int lMapIndex, int lStartX, int lStartY, int lEndY += lEndY % CELL_SIZE; // - // Cell ǥ Ѵ. + // Cell 좌표를 구한다. // int lCX = lStartX / CELL_SIZE; diff --git a/src/game/src/shop.cpp b/src/game/src/shop.cpp index 5821224..dcfe8a0 100644 --- a/src/game/src/shop.cpp +++ b/src/game/src/shop.cpp @@ -159,8 +159,8 @@ void CShop::SetShopItems(TShopItemTable * pTable, BYTE bItemCount) if (item.pkItem) { item.vnum = pkItem->GetVnum(); - item.count = pkItem->GetCount(); // PC ¥ Ѵ. - item.price = pTable->price; // ݵ ڰ Ѵ.. + item.count = pkItem->GetCount(); // PC 샵의 경우 아이템 개수는 진짜 아이템의 개수여야 한다. + item.price = pTable->price; // 가격도 사용자가 정한대로.. item.itemid = pkItem->GetID(); } else @@ -243,7 +243,7 @@ int CShop::Buy(LPCHARACTER ch, BYTE pos) LPITEM item; - if (m_pkPC) // Ǿ ϴ Ǿ ־ Ѵ. + if (m_pkPC) // 피씨가 운영하는 샵은 피씨가 실제 아이템을 가지고있어야 한다. item = r_item.pkItem; else item = ITEM_MANAGER::instance().CreateItem(r_item.vnum, r_item.count); @@ -255,7 +255,7 @@ int CShop::Buy(LPCHARACTER ch, BYTE pos) { if (quest::CQuestManager::instance().GetEventFlag("hivalue_item_sell") == 0) { - //ູ && ö ̺Ʈ + //축복의 구슬 && 만년한철 이벤트 if (item->GetVnum() == 70024 || item->GetVnum() == 70035) { return SHOP_SUBHEADER_GC_END; @@ -290,7 +290,7 @@ int CShop::Buy(LPCHARACTER ch, BYTE pos) ch->PointChange(POINT_GOLD, -dwPrice, false); - // + //세금 계산 DWORD dwTax = 0; int iVal = 0; @@ -330,13 +330,13 @@ int CShop::Buy(LPCHARACTER ch, BYTE pos) } } - // ?? 5% + // 상점에서 살?? 세금 5% if (!m_pkPC) { CMonarch::instance().SendtoDBAddMoney(dwTax, ch->GetEmpire(), ch); } - // ý : ¡ + // 군주 시스템 : 세금 징수 if (m_pkPC) { m_pkPC->SyncQuickslot(QUICKSLOT_TYPE_ITEM, item->GetCell(), 255); @@ -439,7 +439,7 @@ bool CShop::AddGuest(LPCHARACTER ch, DWORD owner_vid, bool bOtherEmpire) //HIVALUE_ITEM_EVENT if (quest::CQuestManager::instance().GetEventFlag("hivalue_item_sell") == 0) { - //ູ && ö ̺Ʈ + //축복의 구슬 && 만년한철 이벤트 if (item.vnum == 70024 || item.vnum == 70035) { continue; diff --git a/src/game/src/shopEx.cpp b/src/game/src/shopEx.cpp index e9e9ac4..fedcd70 100644 --- a/src/game/src/shopEx.cpp +++ b/src/game/src/shopEx.cpp @@ -69,7 +69,7 @@ bool CShopEx::AddGuest(LPCHARACTER ch,DWORD owner_vid, bool bOtherEmpire) pack2.owner_vid = owner_vid; pack2.shop_tab_count = m_vec_shopTabs.size(); - char temp[8096]; // ִ 1728 * 3 + char temp[8096]; // 최대 1728 * 3 char* buf = &temp[0]; size_t size = 0; for (itertype(m_vec_shopTabs) it = m_vec_shopTabs.begin(); it != m_vec_shopTabs.end(); it++) diff --git a/src/game/src/shop_manager.cpp b/src/game/src/shop_manager.cpp index 20a1e10..aa04963 100644 --- a/src/game/src/shop_manager.cpp +++ b/src/game/src/shop_manager.cpp @@ -97,10 +97,10 @@ LPSHOP CShopManager::GetByNPCVnum(DWORD dwVnum) } /* - * ̽ Լ + * 인터페이스 함수들 */ -// ŷ +// 상점 거래를 시작 bool CShopManager::StartShopping(LPCHARACTER pkChr, LPCHARACTER pkChrShopKeeper, int iShopVnum) { if (pkChr->GetShopOwner() == pkChrShopKeeper) @@ -187,7 +187,7 @@ void CShopManager::DestroyPCShop(LPCHARACTER ch) M2_DELETE(pkShop); } -// ŷ +// 상점 거래를 종료 void CShopManager::StopShopping(LPCHARACTER ch) { LPSHOP shop; @@ -203,7 +203,7 @@ void CShopManager::StopShopping(LPCHARACTER ch) SPDLOG_DEBUG("SHOP: END: {}", ch->GetName()); } -// +// 아이템 구입 void CShopManager::Buy(LPCHARACTER ch, BYTE pos) { if (!ch->GetShop()) @@ -243,7 +243,7 @@ void CShopManager::Buy(LPCHARACTER ch, BYTE pos) int ret = pkShop->Buy(ch, pos); - if (SHOP_SUBHEADER_GC_OK != ret) // ־ . + if (SHOP_SUBHEADER_GC_OK != ret) // 문제가 있었으면 보낸다. { TPacketGCShop pack; @@ -313,7 +313,7 @@ void CShopManager::Sell(LPCHARACTER ch, BYTE bCell, BYTE bCount) dwPrice /= 5; - // + //세금 계산 DWORD dwTax = 0; int iVal = 3; @@ -339,7 +339,7 @@ void CShopManager::Sell(LPCHARACTER ch, BYTE bCell, BYTE bCount) return; } - // 20050802.myevan. Ǹ α׿ ID ߰ + // 20050802.myevan.상점 판매 로그에 아이템 ID 추가 SPDLOG_DEBUG("SHOP: SELL: {} item name: {}(x{}):{} price: {}", ch->GetName(), item->GetName(), bCount, item->GetID(), dwPrice); if (iVal > 0) @@ -349,8 +349,8 @@ void CShopManager::Sell(LPCHARACTER ch, BYTE bCell, BYTE bCount) if (bCount == item->GetCount()) { - // ѱ ش޶ Ƽ - // ǸŽ Ӽα׸ . + // 한국에는 아이템을 버리고 복구해달라는 진상유저들이 많아서 + // 상점 판매시 속성로그를 남긴다. if (LC_IsYMIR()) item->AttrLog(); @@ -359,7 +359,7 @@ void CShopManager::Sell(LPCHARACTER ch, BYTE bCell, BYTE bCount) else item->SetCount(item->GetCount() - bCount); - // ý : ¡ + //군주 시스템 : 세금 징수 CMonarch::instance().SendtoDBAddMoney(dwTax, ch->GetEmpire(), ch); ch->PointChange(POINT_GOLD, dwPrice, false); @@ -490,8 +490,8 @@ bool ConvertToShopItemTable(IN CGroupNode* pNode, OUT TShopTableEx& shopTable) bool CShopManager::ReadShopTableEx(const char* stFileName) { - // file üũ. - // ó ʴ´. + // file 유무 체크. + // 없는 경우는 에러로 처리하지 않는다. FILE* fp = fopen(stFileName, "rb"); if (NULL == fp) return true; diff --git a/src/game/src/skill.cpp b/src/game/src/skill.cpp index d402423..b00ee3f 100644 --- a/src/game/src/skill.cpp +++ b/src/game/src/skill.cpp @@ -297,7 +297,7 @@ bool CSkillManager::Initialize(TSkillTable * pTab, int iSize) if (!bError) { - // ̺ . + // 기존 테이블의 내용을 지운다. itertype(m_map_pkSkillProto) it = m_map_pkSkillProto.begin(); while (it != m_map_pkSkillProto.end()) { @@ -307,7 +307,7 @@ bool CSkillManager::Initialize(TSkillTable * pTab, int iSize) m_map_pkSkillProto.clear(); - // ο + // 새로운 내용을 삽입 it = map_pkSkillProto.begin(); while (it != map_pkSkillProto.end()) diff --git a/src/game/src/start_position.cpp b/src/game/src/start_position.cpp index 6d6dcae..4cc5e74 100644 --- a/src/game/src/start_position.cpp +++ b/src/game/src/start_position.cpp @@ -17,26 +17,26 @@ char g_nation_name[4][32] = int g_start_map[4] = { 0, // reserved - 1, // ż - 21, // õ - 41 // 뱹 + 1, // 신수국 + 21, // 천조국 + 41 // 진노국 }; DWORD g_start_position[4][2] = { { 0, 0 }, // reserved - { 469300, 964200 }, // ż - { 55700, 157900 }, // õ - { 969600, 278400 } // 뱹 + { 469300, 964200 }, // 신수국 + { 55700, 157900 }, // 천조국 + { 969600, 278400 } // 진노국 }; DWORD arena_return_position[4][2] = { { 0, 0 }, - { 347600, 882700 }, // ھ - { 138600, 236600 }, // - { 857200, 251800 } // ڶ + { 347600, 882700 }, // 자양현 + { 138600, 236600 }, // 복정현 + { 857200, 251800 } // 박라현 }; diff --git a/src/game/src/threeway_war.cpp b/src/game/src/threeway_war.cpp index e75a211..fa12cde 100644 --- a/src/game/src/threeway_war.cpp +++ b/src/game/src/threeway_war.cpp @@ -323,13 +323,13 @@ void CThreeWayWar::onDead(LPCHARACTER pChar, LPCHARACTER pkKiller) if (NULL == pkKiller || true != pkKiller->IsPC()) return; - // + // 같은 제국은 계산하지 않음 if (pChar->GetEmpire() == pkKiller->GetEmpire()) return; int nKillScore = GetKillScore(pkKiller->GetEmpire()); - // ų ھ -1ϰ Ẕ̇⶧ üũ ϸ ȵȴ. + // 제국 킬 스코어가 -1일경우는 탈락국가이기때문에 점수 체크를 하면 안된다. if (nKillScore >= 0) { nKillScore += GetKillValue(pChar->GetLevel()); @@ -366,7 +366,7 @@ void CThreeWayWar::onDead(LPCHARACTER pChar, LPCHARACTER pkKiller) return; //---------------------- - //īƮ ʱȭ + //카운트 초기화 //---------------------- SetKillScore(1, 0); SetKillScore(2, 0); @@ -376,7 +376,7 @@ void CThreeWayWar::onDead(LPCHARACTER pChar, LPCHARACTER pkKiller) quest::warp_all_to_map_my_empire_event_info * info; //---------------------- - //Ż Ű : + //탈락국가 퇴장 시키기 : 성지에서 //---------------------- info = AllocEventInfo(); @@ -389,7 +389,7 @@ void CThreeWayWar::onDead(LPCHARACTER pChar, LPCHARACTER pkKiller) event_create(quest::warp_all_to_map_my_empire_event, info, PASSES_PER_SEC(10)); //---------------------- - //Ż Ű : ο + //탈락국가 퇴장 시키기 : 통로에서 //---------------------- info = AllocEventInfo(); @@ -402,7 +402,7 @@ void CThreeWayWar::onDead(LPCHARACTER pChar, LPCHARACTER pkKiller) event_create(quest::warp_all_to_map_my_empire_event, info, PASSES_PER_SEC(10)); //---------------------- - // ñ ̾߱⸦ ! + //성지에 팅기는 국가에 대한 이야기를 마왕이 함! //---------------------- const std::string Nation(EMPIRE_NAME(bLoseEmpire)); const std::string Script( @@ -415,7 +415,7 @@ void CThreeWayWar::onDead(LPCHARACTER pChar, LPCHARACTER pkKiller) CHARACTER_MANAGER::instance().SendScriptToMap(pChar->GetMapIndex(), Script); //---------------------- - // ѹ . + // 공지 한방 날려줌. //---------------------- char szNotice[512+1]; snprintf(szNotice, sizeof(szNotice), LC_TEXT("\xBB\xEF\xB0\xC5\xB8\xAE \xC0\xFC\xC5\xF5\xBF\xA1\xBC\xAD %s \xB1\xB9\xB0\xA1\xB0\xA1 \xB0\xA1\xC0\xE5\xB8\xD5\xC0\xFA \xC5\xBB\xB6\xF4\xC0\xBB \xC7\xCF\xBF\xB4\xBD\xC0\xB4\xCF\xB4\xD9"), Nation.c_str()); @@ -425,7 +425,7 @@ void CThreeWayWar::onDead(LPCHARACTER pChar, LPCHARACTER pkKiller) LogManager::instance().CharLog(0, 0, 0, 0, "THREEWAY", szNotice, NULL); //---------------------- - // Ѵ. + // 몹을 리젠한다. //---------------------- regen_mob_event_info* regen_info = AllocEventInfo(); @@ -464,7 +464,7 @@ void CThreeWayWar::onDead(LPCHARACTER pChar, LPCHARACTER pkKiller) quest::warp_all_to_map_my_empire_event_info * info; //---------------------- - //Ż Ű : + //탈락국가 퇴장 시키기 : 성지에서 //---------------------- info = AllocEventInfo(); @@ -477,7 +477,7 @@ void CThreeWayWar::onDead(LPCHARACTER pChar, LPCHARACTER pkKiller) event_create(quest::warp_all_to_map_my_empire_event, info, PASSES_PER_SEC(5)); //---------------------- - //Ż Ű : ο + //탈락국가 퇴장 시키기 : 통로에서 //---------------------- info = AllocEventInfo(); @@ -492,7 +492,7 @@ void CThreeWayWar::onDead(LPCHARACTER pChar, LPCHARACTER pkKiller) } //------------------------------ - // ھ ǥ + // 최종 스코어 표시 //------------------------------ { char szBuf[64 + 1]; @@ -502,7 +502,7 @@ void CThreeWayWar::onDead(LPCHARACTER pChar, LPCHARACTER pkKiller) SendNoticeMap(szBuf, GetSungziMapIndex(), false); } - // ޼ ش. + // 메세지를 띄워준다. LPSECTREE_MAP pSecMap = SECTREE_MANAGER::instance().GetMap(pChar->GetMapIndex()); if (NULL != pSecMap) @@ -534,7 +534,7 @@ void CThreeWayWar::onDead(LPCHARACTER pChar, LPCHARACTER pkKiller) } //------------------------------ - // : ȣ ȯ + // 마지막 보상 : 진구미호 소환 //----------------------------- for (int n = 0; n < quest::CQuestManager::instance().GetEventFlag("threeway_war_boss_count");) { diff --git a/src/game/src/trigger.cpp b/src/game/src/trigger.cpp index ceb1a51..460cf53 100644 --- a/src/game/src/trigger.cpp +++ b/src/game/src/trigger.cpp @@ -46,7 +46,7 @@ int OnClickShop(TRIGGERPARAM) } /* - * AI Լ BattleAI Ŭ + * 몬스터 AI 함수들을 BattleAI 클래스로 수정 */ int OnIdleDefault(TRIGGERPARAM) { @@ -100,7 +100,7 @@ class FuncFindMobVictim pkChr->IsAffectFlag(AFF_REVIVE_INVISIBLE)) return false; - if (pkChr->IsAffectFlag(AFF_TERROR) && m_pkChr->IsImmune(IMMUNE_TERROR) == false ) // ó + if (pkChr->IsAffectFlag(AFF_TERROR) && m_pkChr->IsImmune(IMMUNE_TERROR) == false ) // 공포 처리 { if ( pkChr->GetLevel() >= m_pkChr->GetLevel() ) return false; @@ -137,7 +137,7 @@ class FuncFindMobVictim LPCHARACTER GetVictim() { - // ó ǹ ְ ǰ ִٸ ǹ Ѵ. ǹ ־ ǹ + // 근처에 건물이 있고 피가 많이 있다면 건물을 공격한다. 건물만 있어도 건물을 공격 if (m_pkChrBuilding && m_pkChr->GetHP() * 2 > m_pkChr->GetMaxHP() || !m_pkChrVictim) { return m_pkChrBuilding; diff --git a/src/game/src/utils.cpp b/src/game/src/utils.cpp index 12294a9..f12ab0d 100644 --- a/src/game/src/utils.cpp +++ b/src/game/src/utils.cpp @@ -30,12 +30,12 @@ size_t str_lower(const char * src, char * dest, size_t dest_size) return len; } - // \0 ڸ Ȯ + // \0 자리 확보 --dest_size; while (*src && len < dest_size) { - *dest = LOWER(*src); // LOWER ũο ++ --ϸ ȵ!! + *dest = LOWER(*src); // LOWER 매크로에서 ++나 --하면 안됨!! ++src; ++dest; @@ -63,7 +63,7 @@ const char *one_argument(const char *argument, char *first_arg, size_t first_siz return NULL; } - // \0 ڸ Ȯ + // \0 자리 확보 --first_size; skip_spaces(&argument); @@ -101,7 +101,7 @@ const char *first_cmd(const char *argument, char *first_arg, size_t first_arg_si size_t cur_len = 0; skip_spaces(&argument); - // \0 ڸ Ȯ + // \0 자리 확보 first_arg_size -= 1; while (*argument && !isspace(*argument) && cur_len < first_arg_size) diff --git a/src/game/src/war_map.cpp b/src/game/src/war_map.cpp index a1b10b8..4989087 100644 --- a/src/game/src/war_map.cpp +++ b/src/game/src/war_map.cpp @@ -304,7 +304,7 @@ void CWarMap::STeamData::AppendMember(LPCHARACTER ch) void CWarMap::STeamData::RemoveMember(LPCHARACTER ch) { - // set_pidJoiner ο ϱ ʴ´ + // set_pidJoiner 는 누적 인원을 계산하기 때문에 제거하지 않는다 --iMemberCount; } @@ -688,11 +688,11 @@ bool CWarMap::CheckScore() if (m_bEnded) return true; - // 30 ȮѴ. + // 30초 이후 부터 확인한다. if (get_dword_time() - m_dwStartTime < 30000) return false; - // üũ ʴ´. + // 점수가 같으면 체크하지 않는다. if (m_TeamData[0].iScore == m_TeamData[1].iScore) return false; diff --git a/src/game/src/wedding.cpp b/src/game/src/wedding.cpp index 4b14d36..9f28315 100644 --- a/src/game/src/wedding.cpp +++ b/src/game/src/wedding.cpp @@ -87,7 +87,7 @@ namespace marriage if (ch->GetPlayerID() == dwPID1 || ch->GetPlayerID() == dwPID2) continue; - if (ch->GetLevel() < 10) // 10 ϴ ʴ´. + if (ch->GetLevel() < 10) // 10 레벨이하는 주지않는다. continue; //ch->AutoGiveItem(27003, 5); @@ -122,9 +122,9 @@ namespace marriage { if (ch->IsPC()) { - // ExitToSavedLocation WarpSet θµ Լ - // Sectree NULL ȴ. SectreeManager ʹ - // ij͸ ã Ƿ Ʒ DestroyAll ó + // ExitToSavedLocation은 WarpSet을 부르는데 이 함수에서 + // Sectree가 NULL이 된다. 추 후 SectreeManager로 부터는 + // 이 캐릭터를 찾을 수 없으므로 아래 DestroyAll에서 별도 처리함 ch->ExitToSavedLocation(); } } diff --git a/src/game/src/xmas_event.cpp b/src/game/src/xmas_event.cpp index 0fa73dd..fcf0920 100644 --- a/src/game/src/xmas_event.cpp +++ b/src/game/src/xmas_event.cpp @@ -14,7 +14,7 @@ namespace xmas { if (name == "xmas_snow" || name == "xmas_boom" || name == "xmas_song" || name == "xmas_tree") { - // ѷش + // 뿌려준다 const DESC_MANAGER::DESC_SET & c_ref_set = DESC_MANAGER::instance().GetClientSet(); for (itertype(c_ref_set) it = c_ref_set.begin(); it != c_ref_set.end(); ++it) @@ -44,13 +44,13 @@ namespace xmas { CharacterVectorInteractor i; - // ش + // 없으면 만들어준다 if (!CHARACTER_MANAGER::instance().GetCharactersByRaceNum(MOB_XMAS_TREE_VNUM, i)) CHARACTER_MANAGER::instance().SpawnMob(MOB_XMAS_TREE_VNUM, 61, 76500 + 358400, 60900 + 153600, 0, false, -1); } else if (prev_value > 0 && value == 0) { - // ش + // 있으면 지워준다 CharacterVectorInteractor i; if (CHARACTER_MANAGER::instance().GetCharactersByRaceNum(MOB_XMAS_TREE_VNUM, i)) @@ -68,7 +68,7 @@ namespace xmas switch (value) { case 0: - // ڵ + // 있으면 지우는 코드 { CharacterVectorInteractor i; @@ -84,7 +84,7 @@ namespace xmas break; case 1: - // ѻ̸ Ÿ ¸ 2 . + // 내가 서한산이면 산타 없으면 만들고 상태를 2로 만든다. if (map_allow_find(61)) { quest::CQuestManager::instance().RequestSetEventFlag("xmas_santa", 2); @@ -160,7 +160,7 @@ namespace xmas { if ( spawn == true ) { - // ش + // 없으면 만들어준다 struct SNPCSellFireworkPosition { int lMapIndex; @@ -199,7 +199,7 @@ namespace xmas { CharacterVectorInteractor i; - // ش + // 있으면 지워준다 if (CHARACTER_MANAGER::instance().GetCharactersByRaceNum(MOB_XMAS_FIRWORK_SELLER_VNUM, i)) { CharacterVectorInteractor::iterator it = i.begin();