Skocz do zawartości
Opublikowano

Cześć wszystkim,

 

Wczoraj kolega @ExoCarossa poprosił mnie o modyfikację mechanizmu ataku z łuku. Jak zapewne wiecie, strzelając z łuku do przeciwnika, atak jest redukowany w zależności od dystansu do celu.

Moim zdaniem jest to rozwiązanie realistyczne, ponieważ w rzeczywistości siła uderzenia strzały maleje wraz z jej odległością od źródła. Niemniej jednak takie rozwiązanie może sprawiać wiele trudności z balansem postaci, więc wyłączenie tego mechanizmu może ułatwić pracę w tym zakresie. Przedstawiam zatem zmodyfikowaną funkcję ataku z łuku z wyłączeniem ataku w zależności od zasięgu przeciwnika.

 

Rozwiązanie:

Aby obrażenia zadawane przez strzały były stałe, niezależne od dystansu, należy usunąć kod odpowiedzialny za modyfikację wartości obrażeń na podstawie zmiennej 'iPercent'. Zmienna ta jest wyliczana w oparciu o dystans pomiędzy atakującym a celem, co wpływa na końcowe obrażenia. Usunięcie tej zależności spowoduje, że obrażenia będą takie same, bez względu na odległość.

 

Przedstawienie opisanego problemu:

 

Przedstawienie zmian:

 

Implementacja:

📂 Lokalizacja pliku: 'game -> battle.cpp'

 

🔍 Szukaj:

🔐 Ukryta Treść 🔐

 

♻️ Zamień

🔐 Ukryta Treść 🔐

 

Featured Replies

Opublikowano

Szef 😎

Opublikowano

Cóż za kocur w c++ 😄

Opublikowano
  • Autor

Jak ktoś chce dodać to rozwiązanie na define to robicie jak poniżej. 

 

Implementacja:

📂 Lokalizacja pliku: 'common -> service.h'

 

Dodaj:

#define ENABLE_ARROW_DISTANCE_DAMAGE

 

 

📂 Lokalizacja pliku: 'game -> battle.cpp'

 

Wtedy funkcja powinna wyglądać tak:

int CalcArrowDamage(LPCHARACTER pkAttacker, LPCHARACTER pkVictim, LPITEM pkBow, LPITEM pkArrow, bool bIgnoreDefense)
{
    if (!pkBow || pkBow->GetType() != ITEM_WEAPON || pkBow->GetSubType() != WEAPON_BOW)
        return 0;

    if (!pkArrow)
        return 0;

    int iDam = 0;
    float fAR = CalcAttackRating(pkAttacker, pkVictim, false);
    iDam = number(pkBow->GetValue(3), pkBow->GetValue(4)) * 2 + pkArrow->GetValue(3);
    int iAtk;

    iAtk = pkAttacker->GetPoint(POINT_ATT_GRADE) + iDam - (pkAttacker->GetLevel() * 2);
    iAtk = static_cast<int>(iAtk * fAR);
    iAtk += pkAttacker->GetLevel() * 2;

    iAtk += pkBow->GetValue(5) * 2;

    iAtk += pkAttacker->GetPoint(POINT_PARTY_ATTACKER_BONUS);
    iAtk = static_cast<int>(iAtk * (100 + (pkAttacker->GetPoint(POINT_ATT_BONUS) + pkAttacker->GetPoint(POINT_MELEE_MAGIC_ATT_BONUS_PER))) / 100);

    iAtk = CalcAttBonus(pkAttacker, pkVictim, iAtk);

    int iDef = 0;

    if (!bIgnoreDefense)
        iDef = (pkVictim->GetPoint(POINT_DEF_GRADE) * (100 + pkVictim->GetPoint(POINT_DEF_BONUS)) / 100);

    if (pkAttacker->IsNPC())
        iAtk = static_cast<int>(iAtk * pkAttacker->GetMobDamageMultiply());

    iDam = MAX(0, iAtk - iDef);

#if defined(ENABLE_ARROW_DISTANCE_DAMAGE)
    int iDist = static_cast<int>(DISTANCE_SQRT(pkAttacker->GetX() - pkVictim->GetX(), pkAttacker->GetY() - pkVictim->GetY()));
    int iGap = (iDist / 100) - 5 - pkAttacker->GetPoint(POINT_BOW_DISTANCE);
    int iPercent = 100 - (iGap * 5);
    if (iPercent < 0)
        iPercent = 0;
    else if (iPercent > 100)
        iPercent = 100;

    iDam = (iDam * iPercent) / 100;

	if (test_server)
	{
		pkAttacker->ChatPacket(CHAT_TYPE_INFO, "ARROW %s -> %s, DAM %d DIST %d GAP %d %% %d",
				pkAttacker->GetName(), 
				pkVictim->GetName(), 
				iDam, 
				iDist, 
				iGap,
				iPercent);
	}
#endif

    return iDam;
}

 

 

Opublikowano

Najs 😄

 

Opublikowano

Dzięki wielkie, przyda się 😉

Opublikowano

Ten bug od dawna mnie irytował, ale twój kod to zmienił, wielkie dzięki.

 

  • 4 tygodnie później...
Opublikowano

Dziekuje

Dołącz do dyskusji

Możesz dodać zawartość już teraz a zarejestrować się później. Jeśli posiadasz już konto, zaloguj się aby dodać zawartość za jego pomocą.

Gość
Dodaj odpowiedź do tematu...