Пример базы данных по броне юнитов

» опубликован
» Способ реализации: cJass
» Тип: Наработка
Пример базы данных, позволяющей узнавать броню любого юнита или героя с учётом внесённых в базу предметов и показателей ловкости. Также учитываются способности, повышающие броню и одноуровневые ауры.
» Код
define
{
    exit exitwhen
    int integer
}

library ArmorDB initializer Init
{
    private int array UnitID
    private real array UnitAM
    private int MaxUID = 0
    private int array ItemID
    private real array ItemAM
    private int MaxIID = 0
    private int array AbilID
    private real array AbilAM[1000][4]
    private int MaxAID = 0
    private constant real ArmorPerAgility = 0.3     //from constants
    private constant real ArmorPenAgility = -2.0    //from constants
    
    define AddUnitDB(a,b)=
    {
        UnitID[MaxUID]=a
        UnitAM[MaxUID]=b
        MaxUID++
    }
    define AddItemDB(a,b)=
    {
        ItemID[MaxIID]=a
        ItemAM[MaxIID]=b
        MaxIID++
    }
    define AddAbilDB(a,b,c,d,e)=
    {
        AbilID[MaxAID]=a
        AbilAM[MaxAID][1]=b
        AbilAM[MaxAID][2]=c
        AbilAM[MaxAID][3]=d
        AbilAM[MaxAID][4]=e
        MaxAID++
    }
    define AddAbilDB(a,b,c,d)=
    {
        AbilID[MaxAID]=a
        AbilAM[MaxAID][1]=b
        AbilAM[MaxAID][2]=c
        AbilAM[MaxAID][3]=d
        AbilAM[MaxAID][4]=0
        MaxAID++
    }
    define AddAbilDB(a,b,c)=
    {
        AbilID[MaxAID]=a
        AbilAM[MaxAID][1]=b
        AbilAM[MaxAID][2]=c
        AbilAM[MaxAID][3]=0
        AbilAM[MaxAID][4]=0
        MaxAID++
    }
    define AddAbilDB(a,b)=
    {
        AbilID[MaxAID]=a
        AbilAM[MaxAID][1]=b
        AbilAM[MaxAID][2]=0
        AbilAM[MaxAID][3]=0
        AbilAM[MaxAID][4]=0
        MaxAID++
    }
    
    private void BaseSet()
    {
        //system, do not remove
        AddUnitDB('zero',0)
        AddItemDB('zero',0)
        AddAbilDB('zero',0,0,0,0)
        
        //units         for heroes it is armor which set in object editor
        AddUnitDB('Hpal',2)
        AddUnitDB('Hmkg',1)
        
        //items
        AddItemDB('rde1',2)
        AddItemDB('rde2',3)
        AddItemDB('rde3',4)
    
        //abilities
        AddAbilDB('AHad',1.5,3.0,4.5)
    }

    private int integral(real a)    //математическое округление
    {
        if(a>=0)
        {
            return(R2I(a+.5))
        }
        if(a <0)
        {
            return(R2I(a-.5))
        }
        return R2I(a)
    }
    
    private int GetIID(int RCode)
    {
        int i = 0
        loop
        {
            if(ItemID[i]==RCode)
            {
                return i
            }
            exit i==MaxIID
            i++
        }
        return 0
    }
    
    private int GetAID(int RCode)
    {
        int i = 0
        loop
        {
            if(AbilID[i]==RCode)
            {
                return i
            }
            exit i==MaxAID
            i++
        }
        return 0
    }
    
    private int GetUID(int RCode)
    {
        int i = 0
        loop
        {
            if(UnitID[i]==RCode)
            {
                return i
            }
            exit i==MaxUID
            i++
        }
        return 0
    }
    
    private real GetUnitArmorByAbils(unit u)
    {
        int i = 1
        real s = 0
        loop
        {
            if(GetUnitAbilityLevel(u, AbilID[i])>0)
            {
                s = s + AbilAM[i][GetUnitAbilityLevel(u, AbilID[i])]
            }
            exit i==MaxAID
            i++
        }
        return s
    }
    
    private real GetUnitArmorEx(unit u)
    {
        return UnitAM[GetUID(GetUnitTypeId(u))]
    }
    
    private real GetItemArmorEx(item u)
    {
        return ItemAM[GetIID(GetItemTypeId(u))]
    }

    real GetUnitArmor(unit u)
    {
        real am = 0
        int i = 0
        real byabil = GetUnitArmorByAbils(u)
        if(IsHeroUnitId(GetUnitTypeId(u)))
        {
            loop
            {
                if(UnitItemInSlot(u,i)!=null)
                {
                    am = am + GetItemArmorEx(UnitItemInSlot(u,i))
                }
                exit i == 6
                i++
            }
            return integral(GetUnitArmorEx(u) + ArmorPenAgility + GetHeroAgi(u,false)*ArmorPerAgility) + am + (GetHeroAgi(u,true)-GetHeroAgi(u,false))*ArmorPerAgility + byabil
        }
        return GetUnitArmorEx(u) + byabil
    }
    
    private void Init()
    {
        BaseSet()
    }
}

Для получения корректного результата в базу помимо базовых параметров защиты войск должны быть введены все способности и предметы, влияющие непосредственно на защиту. Ауры не выше 1 уровня, вписывать равкод баффа, не способности!

Новые элементы базы добавляются в функции private void BaseSet()
        AddUnitDB('zero',0) //Добавление юнитов, сначала равкод, потом базовая броня.
        AddItemDB('zero',0) //Добавление предметов, сначала равкод, потом модификатор брони.
        AddAbilDB('zero',0,0,0,0)   //Добавление способностей. Можно заполнять как все 4 уровня, так и 1~3.
        AddAbilDB('zero',0,0,0)     //Вполне состоятельные варианты.
        AddAbilDB('zero',0,0)
        AddAbilDB('zero',0)
Показатель брони получаем функцией
real GetUnitArmor(unit u)
Не забудьте вписывать библиотеку ArmorDB в uses библиотеки со способностями или требующими этой БД системами.


Просмотров: 3 753

Андреич #1 - 4 года назад 2
просто и понятно... +
много людей спрашивали о нечто подобном...
думаю, найдутся те, кому будет полезно...
Clamp #2 - 4 года назад (отредактировано ) 1
Для справки: наносимый урон вычисляется по формуле:
Ожидаемый_урон * (0.06*GetUnitArmor(Target)/(1+(0.06*GetUnitArmor(Target))))
zumm #3 - 4 года назад -2
Не понял зачем это надо.
16GB #4 - 4 года назад 0
А не проще ли сделать через получение урона? тем более если в карте есть система получения урона, куда занесены все юниты.
zumm:
Не понял зачем это надо.
чтобы узнать количество брони юнита. У меня вот в карте есть спелы дамажущие от брони врага.
DualShock #5 - 4 года назад 0
ScorpioT1000 #6 - 4 года назад (отредактировано ) 0
int integral(real a)
real GetUnitArmor(unit u) {
...
return integral(...
в типах запутались, уважаемый
кстати у векса там кривой десятичный логарифм =)
ЛОЛ define
{
exit exitwhen
Clamp #7 - 4 года назад 0
Ну мне было влом пробегаться по коду и менять дефайн :)
Броня - реальное, в чем проблема?
ScorpioT1000 #8 - 4 года назад 0
возвращаешь инт, теряя точность
Clamp #9 - 4 года назад 0
Очевидно, что математическое округление дает целое на выходе, ведь оно округляет -.-
Зато я могу использовать эту функцию и в функциях, возвращающих целые.
Базовая броня героев от основной ловкости всегда целое, а от дополнительной она уже меняется по десятым долям.
ScorpioT1000 #10 - 4 года назад 0
Я имею ввиду, что в той формуле не надо округлять, ведь требуется то real, а ты отдаешь int, непонятно зачем.
Daro #11 - 4 года назад 0
не понятно.хелп нубу
Clamp #12 - 4 года назад (отредактировано ) 0
ScorpioT1000, ты про эту формулу?
return integral(GetUnitArmorEx(u) + ArmorPenAgility + GetHeroAgi(u,false)*ArmorPerAgility) + am + (GetHeroAgi(u,true)-GetHeroAgi(u,false))*ArmorPerAgility + byabil
Объясняю почему так. Когда герой не имеет бонусов к защите, его показатель брони просто-напросто округляется. Не знаю, как на самом деле, но "damage reduction" пишется именно от этого округленного значения, причем сам он тоже округляется до целых процентов, хотя это округление чисто косметическое.
От ловкости защита пляшет уже от десятых долей.
Единственное что, в реально получаемом уроне никакие округления не ставятся, это исключительно косметический момент. Но, если в карте это реально заметно (уменьшение 100%, урон проходит), то карта идиотична, ибо это овер99999 брони.

Моей целью было получить реально отображаемое значение брони в общем, всё работает =)
ScorpioT1000 #13 - 4 года назад 0
ясно