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

Добавлен , опубликован
Алгоритмы, Наработки и Способности
Способ реализации:
cJass
Тип:
Наработка
Пример базы данных, позволяющей узнавать броню любого юнита или героя с учётом внесённых в базу предметов и показателей ловкости. Также учитываются способности, повышающие броню и одноуровневые ауры.
Код
library ArmorDB initializer initialize {
    #include "cj_types_priv.j"

    private int unitRawCode[];
    private float unitArmor[];
    private int unitsCount = 0;

    private int itemRawCode[];
    private float itemArmor[];
    private int itemsCount = 0;

    private int abilityRawCode[];
    private float abilityArmor[1000][4];
    private int abilitiesCount = 0;

    private constant float armorPerAgility = 0.3;    //from constants
    private constant float armorPenAgility = -2.0;   //from constants

    public void addUnit(int rawCode, float armor) {
        unitRawCode[unitsCount] = rawCode;
        unitArmor[unitsCount] = armor;
        unitsCount++;
    }

    public void addItem(int rawCode, float armor) {
        itemRawCode[itemsCount] = rawCode;
        itemArmor[itemsCount] = armor;
        itemsCount++;
    }

    public void addAbility(int rawCode, float armorLevel1, float armorLevel2, float armorLevel3, float armorLevel4) {
        abilityRawCode[abilitiesCount] = rawCode;
        abilityArmor[abilitiesCount][1] = armorLevel1;
        abilityArmor[abilitiesCount][2] = armorLevel2;
        abilityArmor[abilitiesCount][3] = armorLevel3;
        abilityArmor[abilitiesCount][4] = armorLevel4;
        abilitiesCount++;
    }

    private void initialize() {
        // do not remove
        // item, unit or ability with id == 0 represents respective entity that was not found in DB
        addUnit(0, 0.0);
        addItem(0, 0.0);
        addAbility(0, 0.0, 0.0, 0.0, 0.0);
    }

    // математическое округление
    private int integral(float a) {
        if (a >= 0) {
            return R2I(a + 0.5);
        }
        return R2I(a - 0.5);
    }

    private int getUnitIndex(int rawCode) {
        for (int unitIndex = 0; unitIndex <= unitsCount; unitIndex++) {
            if (unitRawCode[unitIndex] == rawCode) {
                return unitIndex;
            }
        }
        return 0;
    }

    private int getItemIndex(int rawCode) {
        for (int itemIndex = 0; itemIndex <= itemsCount; itemIndex++) {
            if (itemRawCode[itemIndex] == rawCode) {
                return itemIndex;
            }
        }
        return 0;
    }

    public float getUnitBasicArmor(unit u) {
        return unitArmor[getUnitIndex(GetUnitTypeId(u))];
    }

    public float getItemArmor(item i) {
        return itemArmor[getItemIndex(GetItemTypeId(i))];
    }

    public float getArmorFromAbilities(unit u) {
        float armor = 0.0;
        for (int abilityIndex = 1; abilityIndex <= abilitiesCount; abilityIndex++) {
            int abilityLevel = GetUnitAbilityLevel(u, abilityRawCode[abilityIndex]);
            if (abilityLevel > 0) {
                armor = armor + abilityArmor[abilityIndex][abilityLevel];
            }
        }
        return armor;
    }

    public float getUnitArmor(unit u) {
        if (IsHeroUnitId(GetUnitTypeId(u))) {
            float armorFromItems = 0;
            for (int itemSlotIndex = 0; itemSlotIndex < 6; itemSlotIndex++) {
                if (UnitItemInSlot(u, itemSlotIndex) != null) {
                    armorFromItems = armorFromItems + getItemArmor(UnitItemInSlot(u, itemSlotIndex));
                }
            }
            return armorFromItems + getArmorFromAbilities(u) \
                    + integral(getUnitBasicArmor(u) + armorPerAgility*GetHeroAgi(u, false) + armorPenAgility) \
                    + armorPerAgility*(GetHeroAgi(u, true) - GetHeroAgi(u, false));
        }
        return getUnitBasicArmor(u) + getArmorFromAbilities(u);
    }
}

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

Новые элементы базы добавляются следующим набором методов:
// Добавление значения базовой (указанной в редакторе объектов) брони юнита:
void ArmorDB.addUnit(int rawCode, float armor);

// Добавление показателя брони, получаемого от предмета:
void ArmorDB.addItem(int rawCode, float armor);

// Добавление брони от способностей:
void ArmorDB.addAbility(int rawCode, float armorLevel1, float armorLevel2, float armorLevel3, float armorLevel4);
Например:
library ExampleUsage uses ArmorDB initializer addDataToArmorDB {
    void addDataToArmorDB() {
        ArmorDB.addUnit('Hpal', 2);
        ArmorDB.addUnit('Hmkg', 1);

        ArmorDB.addItem('rde1', 2);
        ArmorDB.addItem('rde2', 3);
        ArmorDB.addItem('rde3', 4);

        ArmorDB.addAbility('AHad', 1.5, 3.0, 4.5, 0.0);
    }
}
Показатель брони получаем функциями:
// Текущий показатель брони юнита:
float ArmorDB.getUnitArmor(unit u);

// Базовое значение брони юнита, указанное в РО:
float ArmorDB.getUnitBasicArmor(unit u);

// Значение брони, получаемое от предмета:
float ArmorDB.getItemArmor(item i);

// Количество брони, которую юнит получает от воздействующих на него способностей:
float ArmorDB.getArmorFromAbilities(unit u);

Не забудьте вписывать библиотеку ArmorDB в uses библиотеки со способностями или требующими этой БД системами, а также в библиотеки, в которых в базу добавляются новые значения.
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
31
просто и понятно... +
много людей спрашивали о нечто подобном...
думаю, найдутся те, кому будет полезно...
30
Для справки: наносимый урон вычисляется по формуле:
Ожидаемый_урон * (0.06*GetUnitArmor(Target)/(1+(0.06*GetUnitArmor(Target))))
28
А не проще ли сделать через получение урона? тем более если в карте есть система получения урона, куда занесены все юниты.
zumm:
Не понял зачем это надо.
чтобы узнать количество брони юнита. У меня вот в карте есть спелы дамажущие от брони врага.
38
int integral(real a)
real GetUnitArmor(unit u) {
...
return integral(...
в типах запутались, уважаемый
кстати у векса там кривой десятичный логарифм =)
ЛОЛ define
{
exit exitwhen
30
Ну мне было влом пробегаться по коду и менять дефайн :)
Броня - реальное, в чем проблема?
38
возвращаешь инт, теряя точность
30
Очевидно, что математическое округление дает целое на выходе, ведь оно округляет -.-
Зато я могу использовать эту функцию и в функциях, возвращающих целые.
Базовая броня героев от основной ловкости всегда целое, а от дополнительной она уже меняется по десятым долям.
38
Я имею ввиду, что в той формуле не надо округлять, ведь требуется то real, а ты отдаешь int, непонятно зачем.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.