Пример базы данных, позволяющей узнавать броню любого юнита или героя с учётом внесённых в базу предметов и показателей ловкости. Также учитываются способности, повышающие броню и одноуровневые ауры.
Код
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 баффа, а не самой способности.
Ауры не выше 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 библиотеки со способностями или требующими этой БД системами, а также в библиотеки, в которых в базу добавляются новые значения.
много людей спрашивали о нечто подобном...
думаю, найдутся те, кому будет полезно...
Ред. Clamp
Ожидаемый_урон * (0.06*GetUnitArmor(Target)/(1+(0.06*GetUnitArmor(Target))))
zumm:
Ред. ScorpioT1000
...
return integral(...
кстати у векса там кривой десятичный логарифм =)
ЛОЛ define
{
exit exitwhen
Броня - реальное, в чем проблема?
Зато я могу использовать эту функцию и в функциях, возвращающих целые.
Базовая броня героев от основной ловкости всегда целое, а от дополнительной она уже меняется по десятым долям.