short CUser::GetDamage(int tid, int magicid) { short damage = 0; float Attack = 0; float Avoid = 0; short Hit = 0; short HitB = 0; short Ac = 0; int random = 0; uint8 result; _MAGIC_TABLE* pTable = nullptr; _MAGIC_TYPE1* pType1 = nullptr; _MAGIC_TYPE2* pType2 = nullptr; if (tid < NPC_BAND || tid > INVALID_BAND) return damage; CNpc* pNpc = nullptr; pNpc = g_pMain->m_arNpc.GetData(tid-NPC_BAND); if(pNpc == nullptr) return damage; if(pNpc->m_proto->m_tNpcType == NPC_ARTIFACT || pNpc->m_proto->m_tNpcType == NPC_PHOENIX_GATE || pNpc->m_proto->m_tNpcType == NPC_GATE_LEVER || pNpc->m_proto->m_tNpcType == NPC_SPECIAL_GATE ) return damage; Attack = (float)m_fHitrate; // 공격민첩 Avoid = (float)pNpc->m_sEvadeRate; // 방어민첩 Hit = m_sHitDamage; // 공격자 Hit // Ac = (short)(pNpc->m_sDefense) + pNpc->m_sLevel; // 방어자 Ac 2002.07.06 Ac = (short)(pNpc->m_sDefense); // 방어자 Ac HitB = (int)((Hit * 200) / (Ac + 240)) ; // 새로운 공격식의 B if( magicid > 0 ) { // Skill Hit. pTable = g_pMain->m_MagictableArray.GetData( magicid ); // Get main magic table. if( !pTable ) return -1; if (pTable->bType[0] == 1) { // SKILL HIT! pType1 = g_pMain->m_Magictype1Array.GetData( magicid ); // Get magic skill table type 1. if( !pType1 ) return -1; if(pType1->bHitType) { // Non-relative hit. random = myrand(0,100) ; if (pType1->sHitRate <= random) result = FAIL; else result = SUCCESS; } else { // Relative hit. result = GetHitRate( (Attack / Avoid) * (pType1->sHitRate / 100.0f) ); } /* if(pType1->bHitType) { // Non-relative hit. Hit = m_sHitDamage * (pType1->sHit / 100.0f); } else { // Hit = (m_sHitDamage - pNpc->m_sDefense) Hit = HitB * (pType1->sHit / 100.0f) ; } */ Hit = (short)(HitB * (pType1->sHit / 100.0f)); } else if (pTable->bType[0] == 2) { // ARROW HIT! pType2 = g_pMain->m_Magictype2Array.GetData( magicid ); // Get magic skill table type 1. if( !pType2 ) return -1; if(pType2->bHitType == 1 || pType2->bHitType == 2 ) { // Non-relative/Penetration hit. random = myrand(0,100) ; if (pType2->sHitRate <= random) result = FAIL; else result = SUCCESS; //result = SUCCESS; } else { // Relative hit/Arc hit. result = GetHitRate( (Attack / Avoid) * (pType2->sHitRate / 100.0f) ); } if(pType2->bHitType == 1 /* || pType2->bHitType == 2 */ ) { Hit = (short)(m_sHitDamage * (pType2->sAddDamage / 100.0f)); } else { // Hit = (m_sHitDamage - pNpc->m_sDefense) * (pType2->sAddDamage / 100.0f); Hit = (short)(HitB * (pType2->sAddDamage / 100.0f)); } } } else { // Normal Hit. result = GetHitRate(Attack/Avoid); // 타격비 구하기 } switch(result) { case GREAT_SUCCESS: case SUCCESS: case NORMAL: if( magicid > 0 ) { // 스킬 공격 damage = (short)Hit; random = myrand(0, damage); // damage = (short)((0.85f * (float)Hit) + 0.3f * (float)random); if (pTable->bType[0] == 1) { damage = (short)((float)Hit + 0.3f * (float)random + 0.99); } else { damage = (short)((float)(Hit*0.6f) + 1.0f * (float)random + 0.99); } } else { //일반 공격 damage = (short)(HitB); random = myrand(0, damage); damage = (short)((0.85f * (float)HitB) + 0.3f * (float)random); } break; case FAIL: // 사장님 요구 damage = 0; break; } if (damage <= 0) return 0; damage = GetMagicDamage(damage,tid); // 2. Magical item damage.... //return 3000; return damage; }
short Unit::GetDamage(Unit *pTarget, _MAGIC_TABLE *pSkill) { short damage = 0; int random = 0; short common_damage = 0, temp_hit = 0, temp_ac = 0, temp_hit_B = 0; uint8 result; if (pTarget == nullptr || pTarget->isDead()) return -1; temp_ac = pTarget->m_sTotalAc + pTarget->m_sACAmount; temp_hit_B = (int)((m_sTotalHit * m_bAttackAmount * 200 / 100) / (temp_ac + 240)); // Skill/arrow hit. if (pSkill != nullptr) { // SKILL HIT! YEAH! if (pSkill->bType[0] == 1) { _MAGIC_TYPE1 *pType1 = g_pMain->m_Magictype1Array.GetData(pSkill->iNum); if (pType1 == nullptr) return -1; // Non-relative hit. if (pType1->bHitType) { result = (pType1->sHitRate <= myrand(0, 100) ? FAIL : SUCCESS); } // Relative hit. else { result = GetHitRate((m_sTotalHitrate / pTarget->m_sTotalEvasionrate) * (pType1->sHitRate / 100.0f)); } temp_hit = (short)(temp_hit_B * (pType1->sHit / 100.0f)); } // ARROW HIT! YEAH! else if (pSkill->bType[0] == 2) { _MAGIC_TYPE2 *pType2 = g_pMain->m_Magictype2Array.GetData(pSkill->iNum); if (pType2 == nullptr) return -1; // Non-relative/Penetration hit. if (pType2->bHitType == 1 || pType2->bHitType == 2) { result = (pType2->sHitRate <= myrand(0, 100) ? FAIL : SUCCESS); } // Relative hit/Arc hit. else { result = GetHitRate((m_sTotalHitrate / pTarget->m_sTotalEvasionrate) * (pType2->sHitRate / 100.0f)); } if (pType2->bHitType == 1 /* || pType2->bHitType == 2 */) temp_hit = (short)(m_sTotalHit * m_bAttackAmount * (pType2->sAddDamage / 100.0f) / 100); else temp_hit = (short)(temp_hit_B * (pType2->sAddDamage / 100.0f)); } } // Normal hit (R attack) else { temp_hit = m_sTotalHit * m_bAttackAmount / 100; result = GetHitRate(m_sTotalHitrate / pTarget->m_sTotalEvasionrate); } switch (result) { // 1. Magical item damage.... case GREAT_SUCCESS: case SUCCESS: case NORMAL: if (pSkill != nullptr) { // Skill Hit. damage = (short)temp_hit; random = myrand(0, damage); if (pSkill->bType[0] == 1) damage = (short)((temp_hit + 0.3f * random) + 0.99f); else damage = (short)(((temp_hit * 0.6f) + 1.0f * random) + 0.99f); } else { // Normal Hit. damage = (short)temp_hit_B; random = myrand(0, damage); damage = (short)((0.85f * temp_hit_B) + 0.3f * random); } break; case FAIL: damage = 0; break; } damage = GetMagicDamage(damage, pTarget); // 2. Magical item damage.... // These two only apply to players if (isPlayer() && pTarget->isPlayer()) { damage = GetACDamage(damage, pTarget); // 3. Additional AC calculation.... damage = damage / 3; } return damage; }