Combat System — различия между версиями

Материал из Wiki
Перейти к: навигация, поиск
Строка 87: Строка 87:
  
  
=== Расчет защиты ===
 
  
 +
=== Расчет защиты ===
  
 
<pre>
 
<pre>
Строка 134: Строка 134:
 
absorbed  = (<absorbed > * (100 + (<parrying> / 10))) / 200
 
absorbed  = (<absorbed > * (100 + (<parrying> / 10))) / 200
 
absorbed = <absorbed> * <shield.repair> / <shield.max_repair> //понижение поглощения в зависимости от повреждения щита
 
absorbed = <absorbed> * <shield.repair> / <shield.max_repair> //понижение поглощения в зависимости от повреждения щита
 +
</pre>
 +
 +
 +
 +
=== Скорость ударов ===
 +
 +
<pre>
 +
CombatAttackSpeed = 150000 / ( ( DEX + 100 ) * speed )
 +
задержка между ударами
 +
speed - характеристика оружия
 +
</pre>
 +
 +
 +
 +
=== Healing skill ===
 +
 +
<pre>
 +
//staminadrain
 +
if <paladin>
 +
    staminadrain = {2 3}
 +
elseif <elf>
 +
    staminadrain = {2 3}
 +
else
 +
    staminadrain = 3
 +
endif
 +
 +
 +
if <food> > 14
 +
        stamina = <stamina> - <staminadrain>
 +
else
 +
    if <stamina> < <staminadrain> + ((15 - food) / 2))
 +
        stamina = 0
 +
    else
 +
        stamina = <stamina> - (<staminadrain> + ((15 - food) / 2)))
 +
    endif
 +
endif
 +
 +
//delay
 +
firstspeed = 9
 +
if <stamina> >= <dex>
 +
    speed = <firstspeed>
 +
else
 +
    if dex < 70
 +
        speed = ((1 + ((70 - <stamina>) / 15))*<firstspeed>)
 +
    else
 +
        speed = ((1 + ((<dex> - <stamina>) / 15))*<firstspeed>)
 +
    endif
 +
endif
 +
 +
if <dwarf>
 +
    speed = ((<speed> * 12) / 14)
 +
elseif <orc> && (i_giggling_orc_shaman)
 +
    speed = ((<speed> * 12) / 14)
 +
elseif !<orc>
 +
    speed = ((<speed> * 12) / 15)
 +
endif
 +
 +
 +
//heal
 +
min = ( (<healing> / 55) + (<anatomy> / 500) + (<dex> / 50) )
 +
max = ( (<healing> / 35) + (<anatomy> / 233) + (<dex> / 23) )
 +
 +
 +
if (<elf>) || (<paladin>)
 +
    min = (<min> + 20%)
 +
    max = (<max> + 15%)
 +
elseif <human>
 +
    min = (<min> + 15%)
 +
    max = (<max> + 10%)
 +
endif
 +
</pre>
 +
 +
 +
 +
=== Repair skill ===
 +
 +
<pre>
 +
    res_type = <resources.type>
 +
    if (<res_type> == ingot) || (<res_type> == log) || (<res_type> == board) || (<res_type> == leather)
 +
    local.res_amount = <eval ((<maxrepair> - <repair>) * <resources.value>) / <maxrepair>>
 +
    if <res_amount> <= 0
 +
        res_amount = 1
 +
    endif
 +
</pre>
 +
 +
 +
 +
=== CombatChanceToHit ===
 +
 +
</pre>
 +
int CResource::Calc_CombatChanceToHit( CChar * pChar, SKILL_TYPE skill, CChar * pCharTarg, CItem * pWeapon )
 +
{
 +
    // If no target, must be a training dummy
 +
    if ( pCharTarg == NULL )
 +
    {
 +
        return( Calc_GetRandVal(31));
 +
    }
 +
 +
    // Frozen targets should be easy.
 +
    if ( pCharTarg->IsStatFlag( STATF_Sleeping | STATF_Freeze | STATF_Stone ))
 +
    {
 +
        return( Calc_GetRandVal(10));
 +
    }
 +
 +
    int iSkillVal = pChar->Skill_GetAdjusted( skill );
 +
 +
    int iSkillAttack = ( iSkillVal + pChar->Skill_GetAdjusted( SKILL_TACTICS )) / 2;
 +
    int iSkillDefend = pCharTarg->Skill_GetAdjusted( SKILL_TACTICS );
 +
 +
    int iStam = pCharTarg->m_StatStam;
 +
    if ( pCharTarg->Skill_GetActive() == SKILL_ARCHERY && skill != SKILL_ARCHERY )
 +
        // The defender uses ranged weapon and the attacker is not.
 +
        iSkillDefend = ( iSkillDefend + iStam*9 ) / 2;
 +
    else
 +
        // The defender is using a nonranged, or they both use bows.
 +
        iSkillDefend = ( iSkillDefend + iStam*10 ) / 2;
 +
 +
    int iDiff = ( iSkillAttack - iSkillDefend ) / 5;
 +
 +
    iDiff = ( iSkillVal - iDiff ) / 10;
 +
    if ( iDiff < 0 )
 +
        iDiff = 0;    // just means it's very easy.
 +
    else if ( iDiff > 100 )
 +
        iDiff = 100;    // just means it's very hard.
 +
 +
    return( Calc_GetRandVal(iDiff));    // always need to have some chance. );
 +
}
 
</pre>
 
</pre>

Версия 22:07, 24 января 2024

Расчет урона оружия

dam = {<weapon.dam.min> <weapon.dam.max>} //базовый урон оружия случайное число от мин до макс (до удара)

dam = ((<dam> * <weapon.repair>) / <weapon.max_repair>) //понижение урона от повреждения оружия

dam = (<dam> * (<tactics> + 500)) / 1000) //бонус от тактики (помним что все навыки считаются как 100.0 или 1000)

dam = (<dam> + ((<dam> * <str>) / 500)) //бонус от силы

dam = (<dam> + ((<dam> * <anatomy>) / 5000)) //бонус от анатомии

dam = ((<dam> * (100 + (<skill> / 10))) / 200) //бонус от боевого навыка


//расчет бонуса от магии или цвета оружия (см.таблицу цветов)
if <weapon.damage_plus>
   dam = (<dam> + <weapon.damage_plus>)
elseif (<weapon.magic>)
   dam = (<dam> + ((((<weapon.magic> / 70) + 1) * 5) / 2))
endif


if (<weapon.дистанционное>) && (<distance> <= 1) && НЕТ great_elven_archer //бонус от кольца при стрельбе вплотную
   dam = <dam> * 2/3
endif
- Часть формул может быть скрыта или представлена не в том виде, в котором она существует на данный момент. Это сделано ввиду существующих коллизий. Их список возможно будет представлен позже.


Таблица цветов

    weapon/armor magic plus:
    of Ruin +5
    of Might +10
    of Force +15
    of Power +20
    of Vanquishing +25
    weapon/armor damage plus:
    Hot/Rose +0
    Agapite +5
    Flame/Gold +5 
    Orion +5
    Verite +5
    Dwarf + 10
    Shadow +10
    Valorite +15
    Holy/Silver +15
    Crystal +15
    Infernal/Magma +20
    Obsidian +25
    Mythic +25
    Titan Leather +5
    Daemon Leather +10
    Red Leather +5
    Blue Leather +20
    Green Leather +20
    Yellow Leather +20
    Gray Leather +15
    Gold Leather +20
    Silver Leather +20
    Crystal Leather +20
    Black Leather +20
    dragon_increase:        armor.magic = ((<str> + 15) * 10)
    titan_increase:         armor.magic = ((<str> + 15) * 10)
    chrome_increase:        armor.magic = ((<str> + 15) * 10)
    platinum_increase:      armor.magic = ((<str> + 15) * 10)


    i_dragon_claw:          weapon.magic = ((<swordsmanship> * 2) / 3)
    i_titan_fist:           weapon.magic = ((<macefighting> * 2) / 3)
    i_chrome_lance:         weapon.magic = ((<fencing> * 2) / 3)
    i_platinum_broadsword:  weapon.magic = ((<swordsmanship> * 2) / 3)


Расчет защиты

//выбор слоя для защиты

armor_base = //базовая защита в зависимости от типа доспехов
                
dfns = (<armor_base> * LAYER_[]_AC_K) / 1000 //коэффициент защиты конкретного слоя
                
dfns =  (<dfns> * <armor.more1l>) / <armor.more1h> //понижение защиты от повреждения доспеха

//расчет бонуса от магии или цвета доспеха (см.таблицу цветов)

if <armor.armor_plus>
   dfns = <dfns> + <armor.armor_plus>
elseif (<armor.attr> & attr_magic)
   dfns = <dfns> + (<armor.magic> / 70)
endif


//Бонус защиты от магических и алхимических эффектов
spell_effect = 1
potion_effect = 1

dfns = <dfns> + <p_layer_i.armor_bonus> //повышение защиты от бонуса слоев, непосредственно не участвующих в защите (квестовые предметы)


Расчет парирования

shield_size = //коэффициент размера щита

if (rand(75) < <shield_size>) //удача на абсорбацию урона щитом, если успех, то рассчитывает далее.


//расчет бонуса от магии или цвета щита (см.таблицу цветов)
if <shield.shield_plus>
   absorbed = <absorbed> + <shield.shield_plus> + 9
elseif (<shield.attr> & attr_magic)
   absorbed = <absorbed > + (<shield.magic> / 70) + 9>
endif
absorbed  = (<shield_size> * <absorbed>) / 100
absorbed  = (<absorbed > * (100 + (<parrying> / 10))) / 200
absorbed = <absorbed> * <shield.repair> / <shield.max_repair> //понижение поглощения в зависимости от повреждения щита


Скорость ударов

CombatAttackSpeed = 150000 / ( ( DEX + 100 ) * speed )
задержка между ударами
speed - характеристика оружия


Healing skill

//staminadrain
if <paladin>
    staminadrain = {2 3}
elseif <elf>
    staminadrain = {2 3}
else
    staminadrain = 3
endif


if <food> > 14
        stamina = <stamina> - <staminadrain>
else
    if <stamina> < <staminadrain> + ((15 - food) / 2))
        stamina = 0
    else
        stamina = <stamina> - (<staminadrain> + ((15 - food) / 2)))
    endif
endif

//delay
firstspeed = 9
if <stamina> >= <dex>
    speed = <firstspeed>
else
    if dex < 70
        speed = ((1 + ((70 - <stamina>) / 15))*<firstspeed>)
    else
        speed = ((1 + ((<dex> - <stamina>) / 15))*<firstspeed>)
    endif
endif

if <dwarf>
    speed = ((<speed> * 12) / 14)
elseif <orc> && (i_giggling_orc_shaman)
    speed = ((<speed> * 12) / 14)
elseif !<orc>
    speed = ((<speed> * 12) / 15)
endif


//heal
min = ( (<healing> / 55) + (<anatomy> / 500) + (<dex> / 50) )
max = ( (<healing> / 35) + (<anatomy> / 233) + (<dex> / 23) )


if (<elf>) || (<paladin>)
    min = (<min> + 20%)
    max = (<max> + 15%)
elseif <human>
    min = (<min> + 15%)
    max = (<max> + 10%)
endif


Repair skill

    res_type = <resources.type>
    if (<res_type> == ingot) || (<res_type> == log) || (<res_type> == board) || (<res_type> == leather)
    local.res_amount = <eval ((<maxrepair> - <repair>) * <resources.value>) / <maxrepair>>
    if <res_amount> <= 0
        res_amount = 1
    endif


CombatChanceToHit

</pre> int CResource::Calc_CombatChanceToHit( CChar * pChar, SKILL_TYPE skill, CChar * pCharTarg, CItem * pWeapon )

{
   // If no target, must be a training dummy
    if ( pCharTarg == NULL )
   {
       return( Calc_GetRandVal(31));
   }
   // Frozen targets should be easy.
   if ( pCharTarg->IsStatFlag( STATF_Sleeping | STATF_Freeze | STATF_Stone ))
   {
       return( Calc_GetRandVal(10));
   }
   int iSkillVal = pChar->Skill_GetAdjusted( skill );
   int iSkillAttack = ( iSkillVal + pChar->Skill_GetAdjusted( SKILL_TACTICS )) / 2;
   int iSkillDefend = pCharTarg->Skill_GetAdjusted( SKILL_TACTICS );
   int iStam = pCharTarg->m_StatStam;
   if ( pCharTarg->Skill_GetActive() == SKILL_ARCHERY && skill != SKILL_ARCHERY )
       // The defender uses ranged weapon and the attacker is not.
       iSkillDefend = ( iSkillDefend + iStam*9 ) / 2;
   else
       // The defender is using a nonranged, or they both use bows.
       iSkillDefend = ( iSkillDefend + iStam*10 ) / 2;
   int iDiff = ( iSkillAttack - iSkillDefend ) / 5;
   iDiff = ( iSkillVal - iDiff ) / 10;
   if ( iDiff < 0 )
       iDiff = 0;    // just means it's very easy.
   else if ( iDiff > 100 )
       iDiff = 100;    // just means it's very hard.
   return( Calc_GetRandVal(iDiff));    // always need to have some chance. );

} </pre>