DWORD GET_ATTACK_SPEED(LPCHARACTER ch) { if (NULL == ch) return 1000; LPITEM item = ch->GetWear(WEAR_WEAPON); DWORD default_bonus = SPEEDHACK_LIMIT_BONUS; // 유두리 공속(기본 80) DWORD riding_bonus = 0; if (ch->IsRiding()) { // 뭔가를 탔으면 추가공속 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배 if (item && item->GetSubType() == WEAPON_DAGGER) real_speed /= 2; return real_speed; }
LPITEM CSafebox::Remove(DWORD dwPos) { LPITEM pkItem = Get(dwPos); if (!pkItem) return NULL; if (!m_pkGrid) sys_err("Safebox::Remove : nil grid"); else m_pkGrid->Get(dwPos, 1, pkItem->GetSize()); pkItem->RemoveFromCharacter(); m_pkItems[dwPos] = NULL; TPacketGCItemDel pack; pack.header = m_bWindowMode == SAFEBOX ? HEADER_GC_SAFEBOX_DEL : HEADER_GC_MALL_DEL; pack.pos = dwPos; m_pkChrOwner->GetDesc()->Packet(&pack, sizeof(pack)); sys_log(1, "SAFEBOX: REMOVE %s %s count %d", m_pkChrOwner->GetName(), pkItem->GetName(), pkItem->GetCount()); return pkItem; }
bool DSManager::DeactivateDragonSoul(LPITEM pItem, bool bSkipRefreshOwnerActiveState) { if (NULL == pItem) return false; LPCHARACTER pOwner = pItem->GetOwner(); if (NULL == pOwner) return false; if (!IsActiveDragonSoul(pItem)) return false; char buf[128]; pItem->StopTimerBasedOnWearExpireEvent(); pItem->SetSocket(ITEM_SOCKET_DRAGON_SOUL_ACTIVE_IDX, 0); pItem->ModifyPoints(false); sprintf (buf, "LEFT TIME(%d)", LeftTime(pItem)); LogManager::instance().ItemLog(pOwner, pItem, "DS_DEACTIVATE", buf); if (false == bSkipRefreshOwnerActiveState) RefreshDragonSoulState(pOwner); return true; }
bool COver9RefineManager::Over9Refine(LPCHARACTER pChar, LPITEM item) { DWORD dwVnum = item->GetRefinedVnum(); if (dwVnum == 0) return false; LPITEM over9 = ITEM_MANAGER::instance().CreateItem(dwVnum, 1); if (over9 == NULL) return false; item->CopySocketTo(over9); item->CopyAttributeTo(over9); int iEmptyCell = pChar->GetEmptyInventory(over9->GetSize()); if (iEmptyCell == -1) return false; item->RemoveFromCharacter(); over9->AddToCharacter(pChar, TItemPos(INVENTORY, iEmptyCell)); char szBuf[256]; snprintf(szBuf, sizeof(szBuf), "SUCCESS %u %s %u", over9->GetID(), over9->GetName(), over9->GetOriginalVnum()); LogManager::instance().ItemLog(pChar, item, "REFINE OVER9", szBuf); return true; }
void CBuffOnAttributes::RemoveBuffFromItem(LPITEM pItem) { if (0 == m_bBuffValue) return ; if (NULL != pItem) { if (pItem->GetCell() < INVENTORY_MAX_NUM) return; std::vector <BYTE>::iterator it = find (m_p_vec_buff_wear_targets->begin(), m_p_vec_buff_wear_targets->end(), pItem->GetCell() - INVENTORY_MAX_NUM); if (m_p_vec_buff_wear_targets->end() == it) return; int m = pItem->GetAttributeCount(); for (int j = 0; j < m; j++) { TPlayerItemAttribute attr = pItem->GetAttribute(j); TMapAttr::iterator it = m_map_additional_attrs.find(attr.bType); // m_map_additional_attrs에서 해당 attribute type에 대한 값을 제거하고, // 변경된 값의 (m_bBuffValue)%만큼의 버프 효과 감소 if (it != m_map_additional_attrs.end()) { int& sum_of_attr_value = it->second; int old_value = sum_of_attr_value * m_bBuffValue / 100; int new_value = (sum_of_attr_value - attr.sValue) * m_bBuffValue / 100; m_pBuffOwner->ApplyPoint(attr.bType, new_value - old_value); sum_of_attr_value -= attr.sValue; } else { sys_err ("Buff ERROR(type %d). This item(%d) attr_type(%d) was not in buff pool", m_bPointType, pItem->GetVnum(), attr.bType); return; } } } }
DWORD ani_attack_speed(LPCHARACTER ch) { DWORD speed = 1000; if (NULL == ch) return speed; LPITEM item = ch->GetWear(WEAR_WEAPON); if (NULL == item) return speed; if (ITEM_WEAPON != item->GetType()) return speed; int race = ch->GetRaceNum(); int weapon = item->GetSubType(); /* dev_log(LOG_DEB0, "%s : (race,weapon) = (%s,%s) POINT_ATT_SPEED = %d", ch->GetName(), FN_race_name(race), FN_weapon_type(weapon), ch->GetPoint(POINT_ATT_SPEED)); */ /* ЕхЗЪµрµе јТµеАЗ °жїм »пї¬Вь°ш°Э°ъ ЅВё¶ЅГ */ /* їА·щ°Ў ё№ѕЖ ЗСјХ°Л јУµµ·О »э°ўЗПАЪ */ if (weapon == WEAPON_TWO_HANDED) weapon = WEAPON_SWORD; return s_ANI.attack_speed(race, weapon); }
DWORD GET_ATTACK_SPEED(LPCHARACTER ch) { if (NULL == ch) return 1000; LPITEM item = ch->GetWear(WEAR_WEAPON); DWORD default_bonus = SPEEDHACK_LIMIT_BONUS; // АЇµОё® °шјУ(±вє» 80) DWORD riding_bonus = 0; if (ch->IsRiding()) { // №є°Ўё¦ ЕААёёй ГЯ°Ў°шјУ 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№и if (item && item->GetSubType() == WEAPON_DAGGER) real_speed /= 2; return real_speed; }
int battle_hit(LPCHARACTER pkAttacker, LPCHARACTER pkVictim, int & iRetDam) { //PROF_UNIT puHit("Hit"); if (test_server) sys_log(0, "battle_hit : [%s] attack to [%s] : dam :%d type :%d", pkAttacker->GetName(), pkVictim->GetName(), iRetDam); int iDam = CalcMeleeDamage(pkAttacker, pkVictim); if (iDam <= 0) return (BATTLE_DAMAGE); NormalAttackAffect(pkAttacker, pkVictim); // 데미지 계산 //iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST)) / 100; LPITEM pkWeapon = pkAttacker->GetWear(WEAR_WEAPON); if (pkWeapon) switch (pkWeapon->GetSubType()) { case WEAPON_SWORD: iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST_SWORD)) / 100; break; case WEAPON_TWO_HANDED: iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST_TWOHAND)) / 100; break; case WEAPON_DAGGER: iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST_DAGGER)) / 100; break; case WEAPON_BELL: iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST_BELL)) / 100; break; case WEAPON_FAN: iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST_FAN)) / 100; break; case WEAPON_BOW: iDam = iDam * (100 - pkVictim->GetPoint(POINT_RESIST_BOW)) / 100; break; } //최종적인 데미지 보정. (2011년 2월 현재 대왕거미에게만 적용.) float attMul = pkAttacker->GetAttMul(); float tempIDam = iDam; iDam = attMul * tempIDam + 0.5f; iRetDam = iDam; //PROF_UNIT puDam("Dam"); if (pkVictim->Damage(pkAttacker, iDam, DAMAGE_TYPE_NORMAL)) return (BATTLE_DEAD); return (BATTLE_DAMAGE); }
bool IsDragonSoulRefineMaterial(LPITEM pItem) { if (pItem->GetType() != ITEM_MATERIAL) return false; return (pItem->GetSubType() == MATERIAL_DS_REFINE_NORMAL || pItem->GetSubType() == MATERIAL_DS_REFINE_BLESSED || pItem->GetSubType() == MATERIAL_DS_REFINE_HOLLY); }
DWORD ani_combo_speed(LPCHARACTER ch, BYTE combo) { LPITEM item = ch->GetWear(WEAR_WEAPON); if (NULL == item || combo > 8) return 1000; return s_ANI.attack_speed(ch->GetRaceNum(), item->GetSubType(), combo, ch->IsRiding()); }
bool CPolymorphUtils::BookUpgrade(LPCHARACTER pChar, LPITEM pItem) { if (pChar == NULL || pItem == NULL) return false; pItem->SetSocket(1, pItem->GetSocket(2) * 50); pItem->SetSocket(2, pItem->GetSocket(2)+1); return true; }
bool DSManager::DragonSoulItemInitialize(LPITEM pItem) { if (NULL == pItem || !pItem->IsDragonSoul()) return false; PutAttributes(pItem); int time = DSManager::instance().GetDuration(pItem); if (time > 0) pItem->SetSocket(ITEM_SOCKET_REMAIN_SEC, time); return true; }
bool CItem::IsSameSpecialGroup(const LPITEM item) const { // ј·О VNUMАМ °°ґЩёй °°Ає ±Ч·мАО °НАё·О °ЈБЦ if (this->GetVnum() == item->GetVnum()) return true; if (GetSpecialGroup() && (item->GetSpecialGroup() == GetSpecialGroup())) return true; return false; }
bool CItem::IsSameSpecialGroup(const LPITEM item) const { // ¼·Î VNUMÀÌ °°´Ù¸é °°Àº ±×·ìÀÎ °ÍÀ¸·Î °£ÁÖ if (this->GetVnum() == item->GetVnum()) return true; if (GetSpecialGroup() && (item->GetSpecialGroup() == GetSpecialGroup())) return true; return false; }
bool CPolymorphUtils::UpdateBookPracticeGrade(LPCHARACTER pChar, LPITEM pItem) { if (pChar == NULL || pItem == NULL) return false; if (pItem->GetSocket(1) > 0) pItem->SetSocket(1, pItem->GetSocket(1) - 1); else pChar->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("둔갑서 수련을 마첬습니다. 신선에게 찾아가세요.")); return true; }
bool CPolymorphUtils::UpdateBookPracticeGrade(LPCHARACTER pChar, LPITEM pItem) { if (pChar == NULL || pItem == NULL) return false; if (pItem->GetSocket(1) > 0) pItem->SetSocket(1, pItem->GetSocket(1) - 1); else pChar->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("µР°©ј јц·ГА» ё¶ГєЅАґПґЩ. ЅЕј±їЎ°Ф ГЈѕЖ°Ўјјїд.")); return true; }
void LogManager::ItemLog(LPCHARACTER ch, LPITEM item, const char * c_pszText, const char * c_pszHint) { if (NULL == ch || NULL == item) { sys_err("character or item nil (ch %p item %p text %s)", get_pointer(ch), get_pointer(item), c_pszText); return; } ItemLog(ch->GetPlayerID(), ch->GetX(), ch->GetY(), item->GetID(), NULL == c_pszText ? "" : c_pszText, c_pszHint, ch->GetDesc() ? ch->GetDesc()->GetHostName() : "", item->GetOriginalVnum()); }
WORD DSManager::GetBasePosition(const LPITEM pItem) const { if (NULL == pItem) return WORD_MAX; BYTE type, grade_idx, step_idx, strength_idx; GetDragonSoulInfo(pItem->GetVnum(), type, grade_idx, step_idx, strength_idx); BYTE col_type = pItem->GetSubType(); BYTE row_type = grade_idx; if (row_type > DRAGON_SOUL_GRADE_MAX) return WORD_MAX; return col_type * DRAGON_SOUL_STEP_MAX * DRAGON_SOUL_BOX_SIZE + row_type * DRAGON_SOUL_BOX_SIZE; }
bool DSManager::IsTimeLeftDragonSoul(LPITEM pItem) const { if (pItem == NULL) return false; // АПґЬАє timer based on wearАО їлИҐј®ёё ЅГ°Ј ґЩ µЗѕоµµ ѕИ ѕшѕоБшґЩ. if (pItem->GetProto()->cLimitTimerBasedOnWearIndex >= 0) { return pItem->GetSocket(ITEM_SOCKET_REMAIN_SEC) > 0; } // ґЩёҐ limit typeАО їлИҐј®µйАє ЅГ°Ј µЗёй ёрµО »з¶уБц±в ¶§№®їЎ ї©±в µйѕоїВ ѕЖАМЕЫАє АПґЬ ЅГ°ЈАМ іІѕТґЩ°н ЖЗґЬ. else { return true; } }
bool DSManager::IsTimeLeftDragonSoul(LPITEM pItem) const { if (pItem == NULL) return false; // 일단은 timer based on wear인 용혼석만 시간 다 되어도 안 없어진다. if (pItem->GetProto()->cLimitTimerBasedOnWearIndex >= 0) { return pItem->GetSocket(ITEM_SOCKET_REMAIN_SEC) > 0; } // 다른 limit type인 용혼석들은 시간 되면 모두 사라지기 때문에 여기 들어온 아이템은 일단 시간이 남았다고 판단. else { return true; } }
// ДіёЇЕНАЗ 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++) { LPITEM pItem = GetItem(TItemPos(INVENTORY, i)); if (NULL != pItem) pItem->SetSocket(ITEM_SOCKET_DRAGON_SOUL_ACTIVE_IDX, 0); } if (FindAffect(AFFECT_DRAGON_SOUL_DECK_0)) { DragonSoul_ActivateDeck(DRAGON_SOUL_DECK_0); } else if (FindAffect(AFFECT_DRAGON_SOUL_DECK_1)) { DragonSoul_ActivateDeck(DRAGON_SOUL_DECK_1); } }
void SECTREE::Destroy() { if (!m_set_entity.empty()) { sys_err("Sectree: entity set not empty!!"); ENTITY_SET::iterator it = m_set_entity.begin(); for ( ; it != m_set_entity.end(); ++it) { LPENTITY ent = *it; if (ent->IsType(ENTITY_CHARACTER)) { LPCHARACTER ch = (LPCHARACTER) ent; sys_err("Sectree: destroying character: %s is_pc %d", ch->GetName(), ch->IsPC() ? 1 : 0); if (ch->GetDesc()) DESC_MANAGER::instance().DestroyDesc(ch->GetDesc()); else M2_DESTROY_CHARACTER(ch); } else if (ent->IsType(ENTITY_ITEM)) { LPITEM item = (LPITEM) ent; sys_err("Sectree: destroying Item: %s", item->GetName()); M2_DESTROY_ITEM(item); } else sys_err("Sectree: unknown type: %d", ent->GetType()); } } m_set_entity.clear(); if (!isClone && m_pkAttribute) { M2_DELETE(m_pkAttribute); m_pkAttribute = NULL; } }
bool iCHARACTER::UseItemEx(LPITEM item, int iDestCell) { switch (item->GetVnum()) { case 71051: case 71052: CItem* useon = this->GetItem(iDestCell); if (useon && useon->GetType()==ITEM_COSTUME){ this->ChatPacket(CHAT_TYPE_INFO,locale_find("¼Ó¼ºÀ» º¯°æÇÒ ¼ö ¾ø´Â ¾ÆÀÌÅÛÀÔ´Ï´Ù.")); return true; } } return globals::instance()->UseItemEx->GetOriginalFunction()(this, item, iDestCell); }
void Item_GetDamage(LPITEM pkItem, int* pdamMin, int* pdamMax) { *pdamMin = 0; *pdamMax = 1; if (!pkItem) return; switch (pkItem->GetType()) { case ITEM_ROD: case ITEM_PICK: return; } if (pkItem->GetType() != ITEM_WEAPON) sys_err("Item_GetDamage - !ITEM_WEAPON vnum=%d, type=%d", pkItem->GetOriginalVnum(), pkItem->GetType()); *pdamMin = pkItem->GetValue(3); *pdamMax = pkItem->GetValue(4); }
bool DSManager::ActivateDragonSoul(LPITEM pItem) { if (NULL == pItem) return false; LPCHARACTER pOwner = pItem->GetOwner(); if (NULL == pOwner) return false; int deck_idx = pOwner->DragonSoul_GetActiveDeck(); if (deck_idx < 0) return false; if (INVENTORY_MAX_NUM + WEAR_MAX_NUM + DS_SLOT_MAX * deck_idx <= pItem->GetCell() && pItem->GetCell() < INVENTORY_MAX_NUM + WEAR_MAX_NUM + DS_SLOT_MAX * (deck_idx + 1)) { if (IsTimeLeftDragonSoul(pItem) && !IsActiveDragonSoul(pItem)) { char buf[128]; sprintf (buf, "LEFT TIME(%d)", LeftTime(pItem)); LogManager::instance().ItemLog(pOwner, pItem, "DS_ACTIVATE", buf); pItem->ModifyPoints(true); pItem->SetSocket(ITEM_SOCKET_DRAGON_SOUL_ACTIVE_IDX, 1); pItem->StartTimerBasedOnWearExpireEvent(); } return true; } else return false; }
void CBuffOnAttributes::AddBuffFromItem(LPITEM pItem) { if (0 == m_bBuffValue) return ; if (NULL != pItem) { if (pItem->GetCell() < INVENTORY_MAX_NUM) return; std::vector <BYTE>::iterator it = find (m_p_vec_buff_wear_targets->begin(), m_p_vec_buff_wear_targets->end(), pItem->GetCell() - INVENTORY_MAX_NUM); if (m_p_vec_buff_wear_targets->end() == it) return; int m = pItem->GetAttributeCount(); for (int j = 0; j < m; j++) { TPlayerItemAttribute attr = pItem->GetAttribute(j); TMapAttr::iterator it = m_map_additional_attrs.find(attr.bType); // 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)%만큼의 버프 효과 추가 else { int& sum_of_attr_value = it->second; int old_value = sum_of_attr_value * m_bBuffValue / 100; int new_value = (sum_of_attr_value + attr.sValue) * m_bBuffValue / 100; m_pBuffOwner->ApplyPoint(attr.bType, new_value - old_value); sum_of_attr_value += attr.sValue; } } } }
bool CBuffOnAttributes::On(BYTE bValue) { if (0 != m_bBuffValue || 0 == bValue) return false; int n = m_p_vec_buff_wear_targets->size(); m_map_additional_attrs.clear(); for (int i = 0; i < n; i++) { LPITEM pItem = m_pBuffOwner->GetWear(m_p_vec_buff_wear_targets->at(i)); if (NULL != pItem) { int m = pItem->GetAttributeCount(); for (int j = 0; j < m; j++) { TPlayerItemAttribute attr = pItem->GetAttribute(j); TMapAttr::iterator it = m_map_additional_attrs.find(attr.bType); if (it != m_map_additional_attrs.end()) { it->second += attr.sValue; } else { m_map_additional_attrs.insert(TMapAttr::value_type(attr.bType, attr.sValue)); } } } } for (TMapAttr::iterator it = m_map_additional_attrs.begin(); it != m_map_additional_attrs.end(); it++) { m_pBuffOwner->ApplyPoint(it->first, it->second * bValue / 100); } m_bBuffValue = bValue; return true; }
void CWarMap::UsePotion(LPCHARACTER ch, LPITEM item) { if (m_pkEndEvent) return; if (ch->IsObserverMode()) return; if (!ch->GetGuild()) return; if (!item->GetProto()) return; int iPrice = item->GetProto()->dwGold; DWORD gid = ch->GetGuild()->GetID(); if (gid == m_TeamData[0].dwID) m_TeamData[0].iUsePotionPrice += iPrice; else if (gid == m_TeamData[1].dwID) m_TeamData[1].iUsePotionPrice += iPrice; }
bool CPolymorphUtils::GiveBook(LPCHARACTER pChar, DWORD dwMobVnum, DWORD dwPracticeCount, BYTE BookLevel, BYTE LevelLimit) { // 소켓0 소켓1 소켓2 // 둔갑할 몬스터 번호 수련정도 둔갑서 레벨 if (pChar == NULL) return false; LPITEM pItem = pChar->AutoGiveItem(POLYMORPH_BOOK_ID, 1); if (pItem == NULL) return false; if (CMobManager::instance().Get(dwMobVnum) == NULL) { sys_err("Wrong Polymorph vnum passed: CPolymorphUtils::GiveBook(PID(%d), %d %d %d %d)", pChar->GetPlayerID(), dwMobVnum, dwPracticeCount, BookLevel, LevelLimit); return false; } pItem->SetSocket(0, dwMobVnum); // 둔갑할 몬스터 번호 pItem->SetSocket(1, dwPracticeCount); // 수련해야할 횟수 pItem->SetSocket(2, BookLevel); // 수련레벨 return true; }
bool CPolymorphUtils::GiveBook(LPCHARACTER pChar, DWORD dwMobVnum, DWORD dwPracticeCount, BYTE BookLevel, BYTE LevelLimit) { // јТДП0 јТДП1 јТДП2 // µР°©ЗТ ёуЅєЕН №шИЈ јц·ГБ¤µµ µР°©ј ·№є§ if (pChar == NULL) return false; LPITEM pItem = pChar->AutoGiveItem(POLYMORPH_BOOK_ID, 1); if (pItem == NULL) return false; if (CMobManager::instance().Get(dwMobVnum) == NULL) { sys_err("Wrong Polymorph vnum passed: CPolymorphUtils::GiveBook(PID(%d), %d %d %d %d)", pChar->GetPlayerID(), dwMobVnum, dwPracticeCount, BookLevel, LevelLimit); return false; } pItem->SetSocket(0, dwMobVnum); // µР°©ЗТ ёуЅєЕН №шИЈ pItem->SetSocket(1, dwPracticeCount); // јц·ГЗШѕЯЗТ ИЅјц pItem->SetSocket(2, BookLevel); // јц·Г·№є§ return true; }