Пример #1
0
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;
}
Пример #2
0
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;	  
}