Добавлен Clamp,
опубликован
Здесь лягут все системы, которые есть в каждой моей карте, благо они весьма хороши.
один спойлер - одна библиотека, первый спойлер это дефайны. Библиотеки довольно-таки универсальны, поэтому имеют неиспользуемые функции.
Defines
define
{
lib = library
init = initializer
void = nothing
bool = boolean
int = integer
exit = exitwhen
stop = exitwhen true
break = return
GetHp(u) = GetWidgetLife(u, UNIT_STATE_LIFE)
GetMp(u) = GetUnitState (u, UNIT_STATE_MANA)
IfDead(u) = GetWidgetLife(u, UNIT_STATE_LIFE) <= .405
sqrt(a) = SquareRoot(a)
}
bool Spellcast = false //Становится true во время нанесения урона способностью.
boolexpr VoidExpr = Condition(null) //Пустое условие, во избежание утечек условий.
Math
Всякие математические функции.
lib Match
{
real rabs(real a) //модуль действ. числа
{
if(a<0)
{
return -a
}
return a
}
int iabs(int a) //модуль целого числа
{
if(a<0)
{
return -a
}
return a
}
int integral(real a) //математическое округление
{
if(a>=0)
{
return(R2I(a+.5))
}
if(a <0)
{
return(R2I(a-.5))
}
return R2I(a)
}
real rzeroing(real a) //сведение действ. числа к нулю, если оно меньше 0
{
if(a<0)
{
return 0
}
return a
}
int izeroing(int a) //сведение целого числа к нулю, если оно меньше 0
{
if(a<0)
{
return 0
}
return a
}
int iborder(int a, int val, int b) //ограничение числа с двух сторон
{
if(val<a)
{
return a
}
if(val>b)
{
return b
}
return val
}
}
ArmorDB
База данных по физической защите юнитов.
Броня юнита узнаётся через функцию
Броня юнита узнаётся через функцию
real GetUnitArmor(unit u)
lib ArmorDB init Init uses Match
{
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 private AddUnitDB(a,b)={UnitID[MaxUID]=a;UnitAM[MaxUID]=b;MaxUID++}
define private AddItemDB(a,b)={ItemID[MaxIID]=a;ItemAM[MaxIID]=b;MaxIID++}
define private 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 private 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 private 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 private AddAbilDB(a,b)={AbilID[MaxAID]=a;AbilAM[MaxAID][1]=b;AbilAM[MaxAID][2]=0;AbilAM[MaxAID][3]=0;AbilAM[MaxAID][4]=0;MaxAID++}
//HERE EVERY ITEM, WHICH HAVE ARMOR
//AND EVERY UNIT
//AND EVERY ABILITY WITH ARMOR
private void BaseSet()
{
AddUnitDB('zero',0) //id = 0
AddItemDB('zero',0) //id = 0
AddAbilDB('zero',0,0,0,0) //id = 0
//units for heroes it is armor which set in object editor
AddUnitDB('Hpal',2)
AddUnitDB('Hmkg',1)
AddUnitDB('hfoo',2)
//items
AddItemDB('rde1',2)
AddItemDB('rde2',3)
AddItemDB('rde3',4)
//abilities
AddAbilDB('AHad',1.5,3.0,4.5)
}
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 GetUnitArmorEx(unit u)
{
return UnitAM[GetUID(GetUnitTypeId(u))]
}
private real GetItemArmorEx(item u)
{
return ItemAM[GetIID(GetItemTypeId(u))]
}
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
}
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()
}
}
MresDB
База данных по магической защите войск. В силу того, что я использую полностью кастомный урон заклинаниями, совершенно не зависит от "родного" магического сопротивления.
Сопротивление юнита узнаётся через функцию
real GetUnitMres(unit u)
Используется через стандартную формулу понижения урона от защиты юнита.
lib MresDB init Init uses Match
{
private int array UnitID
private real array UnitMR
private int MaxUID = 0
private int array ItemID
private real array ItemMR
private int MaxIID = 0
private int array AbilID
private real array AbilMR[1000][4]
private int MaxAID = 0
private constant real MresPerInt = 0.8
private constant real MresPenInt = -5.0
define private AddUnitDB3(a,b)={UnitID[MaxUID]=a;UnitMR[MaxUID]=b;MaxUID++}
define private AddItemDB3(a,b)={ItemID[MaxIID]=a;ItemMR[MaxIID]=b;MaxIID++}
define private AddAbilDB3(a,b,c,d,e)={AbilID[MaxAID]=a;AbilMR[MaxAID][1]=b;AbilMR[MaxAID][2]=c;AbilMR[MaxAID][3]=d;AbilMR[MaxAID][4]=e;MaxAID++}
define private AddAbilDB3(a,b,c,d)={AbilID[MaxAID]=a;AbilMR[MaxAID][1]=b;AbilMR[MaxAID][2]=c;AbilMR[MaxAID][3]=d;AbilMR[MaxAID][4]=0;MaxAID++}
define private AddAbilDB3(a,b,c)={AbilID[MaxAID]=a;AbilMR[MaxAID][1]=b;AbilMR[MaxAID][2]=c;AbilMR[MaxAID][3]=0;AbilMR[MaxAID][4]=0;MaxAID++}
define private AddAbilDB3(a,b)={AbilID[MaxAID]=a;AbilMR[MaxAID][1]=b;AbilMR[MaxAID][2]=0;AbilMR[MaxAID][3]=0;AbilMR[MaxAID][4]=0;MaxAID++}
//HERE EVERY ITEM, WHICH HAVE MRESIST
//AND EVERY UNIT
//AND EVERY ABILITY WITH MRESIST
private void BaseSet()
{
AddUnitDB3('zero',0) //id = 0
AddItemDB3('zero',0) //id = 0
AddAbilDB3('zero',0,0,0,0) //id = 0
//units
AddUnitDB3('Hpal',5)
AddUnitDB3('Hmkg',1)
//items
AddItemDB3('rde1',15)
AddItemDB3('rde2',15)
AddItemDB3('rde3',15)
//abilities
AddAbilDB3('AHad',3,6,9)
}
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 GetUnitMresEx(unit u)
{
return UnitMR[GetUID(GetUnitTypeId(u))]
}
private real GetItemMresEx(item u)
{
return ItemMR[GetIID(GetItemTypeId(u))]
}
private real GetUnitMresByAbils(unit u)
{
int i = 1
real s = 0
loop
{
if(GetUnitAbilityLevel(u, AbilID[i])>0)
{
s = s + AbilMR[i][GetUnitAbilityLevel(u, AbilID[i])]
}
exit i==MaxAID
i++
}
return s
}
real GetUnitMres(unit u)
{
real am = 0
int i = 0
real byabil = GetUnitMresByAbils(u)
if(IsHeroUnitId(GetUnitTypeId(u)))
{
loop
{
if(UnitItemInSlot(u,i)!=null)
{
am = am + GetItemMresEx(UnitItemInSlot(u,i))
}
exit i == 6
i++
}
return integral(GetUnitMresEx(u) + MresPenInt + GetHeroInt(u,false)*MresPerInt) + am + (GetHeroInt(u,true)-GetHeroInt(u,false))*MresPerInt + byabil
}
return GetUnitMresEx(u) + byabil
}
private void Init()
{
BaseSet()
}
}
DealDamage
Наносит урон посредством функции
void DealDmg(unit Caster, unit Target, bool MDmg, real Dmg)
Учитывает защиту/сопротивление магии цели, вампиризм от предметов (как физический, так и магический).
В силу того, что у меня способности могут наносить физический урон, эта функция используется только при уроне способностями, что позволяет определить, с руки урон, или от заклинания.
В силу того, что у меня способности могут наносить физический урон, эта функция используется только при уроне способностями, что позволяет определить, с руки урон, или от заклинания.
lib DealDamage init Init uses ArmorDB, MresDB
{
//for magic spells
private int array MageVamp //база итемов
private int array MageVampN //база вампиризма по итемам
private int MageVampNr = 0//количество различных итемов в базе
//for physical spells
private int array PhysVamp
private int array PhysVampN
private int PhysVampNr = 0
define private AddPVamp(a,b)={PhysVamp[PhysVampNr]=a;PhysVampN[PhysVampNr]=b;PhysVampNr++}
define private AddMVamp(a,b)={MageVamp[MageVampNr]=a;MageVampN[MageVampNr]=b;MageVampNr++}
private void ItemsSet()
{
AddMVamp('none',15)
AddMVamp('none',25)
AddPVamp('none',15)
AddPVamp('none',10)
}
private real GetVamp(unit Caster, bool MDmg)
{
int i=0,j=0,ID
real k = 0
if MDmg
{
loop
{
ID = GetItemTypeId(UnitItemInSlot(Caster,i))
loop
{
if(ID == MageVamp[j])
{
k = k + MageVampN[j]
}
j++
exit j == MageVampNr
}
j = 0
i++
exit i == 6
}
}
else
{
loop
{
ID = GetItemTypeId(UnitItemInSlot(Caster,i))
loop
{
if(ID == PhysVamp[j])
{
k = k + PhysVampN[j]
}
j++
exit j == PhysVampNr
}
j = 0
i++
exit i == 6
}
}
return k/100
}
define DealMagicDamage(a,b,c) = DealDmg(a,b,true,c)
define DealPhysicDamage(a,b,c) = DealDmg(a,b,false,c)
void DealDmg(unit Caster, unit Target, bool MDmg, real Dmg)
{
real PMultipler = 1-(0.06*GetUnitArmor(Target)/(1+(0.06*GetUnitArmor(Target))))
real MMultipler = 1-(0.06*GetUnitMres(Target)/(1+(0.06*GetUnitMres(Target))))
Spellcast = true
if(!MDmg)
{
UnitDamageTarget(Caster,Target,PMultipler*Dmg,true,true,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_UNKNOWN,WEAPON_TYPE_WHOKNOWS)
SetUnitState(Caster,UNIT_STATE_LIFE,GetUnitState(Caster,UNIT_STATE_LIFE)+GetVamp(Caster,false)*PMultipler*Dmg)
}
else
{
UnitDamageTarget(Caster,Target,MMultipler*Dmg,true,true,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_UNKNOWN,WEAPON_TYPE_WHOKNOWS)
SetUnitState(Caster,UNIT_STATE_LIFE,GetUnitState(Caster,UNIT_STATE_LIFE)+GetVamp(Caster, true)*MMultipler*Dmg)
}
Spellcast = false
}
private void Init()
{
ItemsSet()
}
}
В добавок ко всему, я вброшу системку, позволяющую узнать точный физический урон каждого юнита.
MainStatDB
База по основным характеристикам героев.
Узнать основную характеристику можно через функцию
Узнать основную характеристику можно через функцию
int GetHeroMainStat(unit u)
здесь 1 = agil, 2 = str, 3 = int.
lib MainStatDB init Init
{
private int array HeroID
private int array StatID //1 = agil, 2 = str, 3 = int
private int StatIDMax =0
define private AddStatRow(a,b)={HeroID[StatIDMax]=a;StatID[StatIDMax]=b;StatIDMax++}
private void SetDB()
{
AddStatRow('Hpal',2)
}
int GetHeroMainStat(unit h)
{
int i = 0
loop
{
if(HeroID[i]==GetUnitTypeId(h))
{
return StatID[i]
}
exit i == StatIDMax
i++
}
return 0
}
private void Init()
{
SetDB()
}
}
DamageDB
База данных по урону, учитывает все модификаторы, внесённые в неё.
Урон узнаётся через функцию
Урон узнаётся через функцию
real GetUnitDamage(unit u)
У юнитов с некоторым разбросом урона выводится среднее значение.
lib DamageDB init Init uses MainStatDB, Match
{
private int array UnitID
private real array UnitDM
private int MaxUID = 0
private int array ItemID
private real array ItemDM
private int MaxIID = 0
private int array AbilID
private real array AbilDM[1000][4]
private int MaxAID = 0
private constant real DamagePerPoint = 1 //for main state
define private AddUnitDB2(a,b)={UnitID[MaxUID]=a;UnitDM[MaxUID]=b;MaxUID++}
define private AddItemDB2(a,b)={ItemID[MaxIID]=a;ItemDM[MaxIID]=b;MaxIID++}
define private AddAbilDB2(a,b,c,d,e)={AbilID[MaxAID]=a;AbilDM[MaxAID][1]=b;AbilDM[MaxAID][2]=c;AbilDM[MaxAID][3]=d;AbilDM[MaxAID][4]=e;MaxAID++}
define private AddAbilDB2(a,b,c,d)={AbilID[MaxAID]=a;AbilDM[MaxAID][1]=b;AbilDM[MaxAID][2]=c;AbilDM[MaxAID][3]=d;AbilDM[MaxAID][4]=0;MaxAID++}
define private AddAbilDB2(a,b,c)={AbilID[MaxAID]=a;AbilDM[MaxAID][1]=b;AbilDM[MaxAID][2]=c;AbilDM[MaxAID][3]=0;AbilDM[MaxAID][4]=0;MaxAID++}
define private AddAbilDB2(a,b)={AbilID[MaxAID]=a;AbilDM[MaxAID][1]=b;AbilDM[MaxAID][2]=0;AbilDM[MaxAID][3]=0;AbilDM[MaxAID][4]=0;MaxAID++}
private void BaseSet()
{
AddUnitDB2('zero',0) //id = 0
AddItemDB2('zero',0) //id = 0
AddAbilDB2('zero',0,0,0,0) //id = 0
AddUnitDB2('Hpal',1)
}
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 GetUnitDamageEx(unit u)
{
return UnitDM[GetUID(GetUnitTypeId(u))]
}
private real GetItemDamageEx(item u)
{
return ItemDM[GetIID(GetItemTypeId(u))]
}
private real GetUnitDamageByAbils(unit u)
{
int i = 1
real s = 0
loop
{
if(GetUnitAbilityLevel(u, AbilID[i])>0)
{
s = s + AbilDM[i][GetUnitAbilityLevel(u, AbilID[i])]
}
exit i==MaxAID
i++
}
return s
}
real GetUnitDamage(unit u)
{
real dm = 0
int i = 0
real byabil = GetUnitDamageByAbils(u)
if(IsHeroUnitId(GetUnitTypeId(u)))
{
loop
{
if(UnitItemInSlot(u,i)!=null)
{
dm = dm + GetItemDamageEx(UnitItemInSlot(u,i))
}
exit i == 6
i++
}
if(GetHeroMainStat(u) == 1)
{
return dm + GetUnitDamageEx(u) + GetHeroAgi(u, true)*DamagePerPoint
}
elseif(GetHeroMainStat(u) == 2)
{
return dm + GetUnitDamageEx(u) + GetHeroStr(u, true)*DamagePerPoint
}
elseif(GetHeroMainStat(u) == 3)
{
return dm + GetUnitDamageEx(u) + GetHeroInt(u, true)*DamagePerPoint
}
}
return GetUnitDamageEx(u) + byabil
}
private void Init()
{
BaseSet()
}
}
Ну и на закуску системка, определяющая факт нанесения урона.
UnitDamaged
Регистирует факт получения урона юнитом.
Инициализируется функцией
Инициализируется функцией
void AnyUnitDamagedEvent(trigger trg)
library UnitDamaged initializer InitRect
{
private region Region
private group Group
private int TrigsNum = 0
private trigger array Trigger
private boolexpr Cond
private void Adder()
{
int i = 0
loop
{
TriggerRegisterUnitEvent(Trigger[i],GetEnteringUnit(),EVENT_UNIT_DAMAGED)
exitwhen i==TrigsNum
i++
}
GroupAddUnit(Group,GetEnteringUnit())
}
private void Registrator()
{
TriggerRegisterUnitEvent(Trigger[TrigsNum],GetEnumUnit(),EVENT_UNIT_DAMAGED)
}
void AnyUnitDamagedEvent(trigger trg)
{
Trigger[TrigsNum]=trg
TriggerAddCondition(Trigger[TrigsNum],Cond)
ForGroup(Group,function Registrator)
TrigsNum++
}
private bool IsntZero()
{
return GetEventDamage() > 0
}
private void InitRect()
{
trigger trg = CreateTrigger()
Cond = Condition(function IsntZero)
Group = CreateGroup()
Region = CreateRegion()
GroupEnumUnitsInRect(Group,bj_mapInitialPlayableArea,null)
RegionAddRect(Region, bj_mapInitialPlayableArea)
TriggerRegisterEnterRegion(trg,Region,null)
TriggerAddAction(trg,function Adder)
}
}
`
ОЖИДАНИЕ РЕКЛАМЫ...
Этот комментарий удален
Чтобы оставить комментарий, пожалуйста, войдите на сайт.