Библиотека является системой для гибкого управления юнитами компьютерных игроков.
Даёт возможность заготовить шаблоны путей и в любой момент отправлять юнитов в движение по ним.
Путь юнитам можно задать в обратном порядке, а так же приказать патрулировать его.
Пути можно легко подменять в зависимости от ситуации.
Система может быть особенно полезна для создания карт жанра Tower Defense или для создания.
Даёт возможность заготовить шаблоны путей и в любой момент отправлять юнитов в движение по ним.
Путь юнитам можно задать в обратном порядке, а так же приказать патрулировать его.
Пути можно легко подменять в зависимости от ситуации.
Система может быть особенно полезна для создания карт жанра Tower Defense или для создания.
Тема на форуме xgm.guru/forum/showthread.php?p=1307984
Код библиотеки
/**
* Waypoints
* Библиотека для гибкого управления юнитами компьютерных игроков
*
* Created by Zeds
* Version: 1.1
*/
library Waypoints initializer Init {
private hashtable ht
private path array paths
// Создать путь
public path CreatePath(integer id) {
path p = path.create()
p.Register(id)
return p
}
// Добавить область к пути
public nothing PathAddRect(integer id, rect rt) {
path p = paths[id]
if (p == null) {
p = CreatePath(id)
}
p.AddRect(rt)
}
// Прикрепить юниту направляющую
public nothing SetUnitGuide(unit u, integer pathId, string order, boolean reverse, boolean infinite) {
integer uId = GetHandleId(u)
guide g = guide.create()
guide oldg = LoadInteger(ht, uId, -1)
if (oldg != null) {
oldg.destroy()
}
g.u = u
g.order = order
g.p = paths[pathId]
if (reverse) {
g.pos = g.p.GetCount() - 1
g.direction = -1
}
g.infinite = infinite
SaveInteger(ht, uId, -1, g)
g.Order()
}
// Получить направляющую юнита
public guide GetUnitGuide(unit u) {
integer uId = GetHandleId(u)
return LoadInteger(ht, uId, -1)
}
private nothing EnterAction() {
unit u = GetTriggerUnit()
integer uId = GetHandleId(u)
guide g = LoadInteger(ht, uId, -1)
g.pos += g.direction
if (g.infinite and g.direction == 1 and g.pos == g.p.GetCount() - 1) {
g.direction = -1
g.Order()
return
}
if (g.infinite and g.direction == -1 and g.pos == 0) {
g.direction = 1
g.Order()
return
}
if (g.direction == 1 and g.pos < g.p.GetCount()) {
g.Order()
return
}
if (g.direction == -1 and g.pos >= 0) {
g.Order()
return
}
g.destroy()
}
private boolean EnterCondition() {
unit u = GetTriggerUnit()
real x = GetUnitX(u)
real y = GetUnitY(u)
integer uId = GetHandleId(u)
guide g = LoadInteger(ht, uId, -1)
if (g == null) {
return false
}
rect rt = LoadRectHandle(ht, g.p, g.pos)
rt = Rect(GetRectMinX(rt) - 32, GetRectMinY(rt) - 32, GetRectMaxX(rt) + 32, GetRectMaxY(rt) + 32)
if ((GetRectMinX(rt) <= x) and (x <= GetRectMaxX(rt)) and (GetRectMinY(rt) <= y) and (y <= GetRectMaxY(rt))) {
return true
}
return false
}
private boolean UnitDeathCondition() {
unit u = GetTriggerUnit()
integer uId = GetHandleId(u)
guide g = LoadInteger(ht, uId, -1)
return g != null
}
private nothing UnitDeathAction() {
unit u = GetTriggerUnit()
integer uId = GetHandleId(u)
guide g = LoadInteger(ht, uId, -1)
g.destroy()
}
// Направляющая(объект для управления юнитом)
struct guide {
unit u
path p
string order
boolean infinite
integer direction = 1
integer pos = 0
// Отдать приказ движения к текущей цели
nothing Order() {
rect rt = LoadRectHandle(ht, this.p, this.pos)
real x = GetRectCenterX(rt)
real y = GetRectCenterY(rt)
IssuePointOrder(this.u, this.order, x, y)
}
nothing onDestroy() {
FlushChildHashtable(ht, GetHandleId(this.u))
}
}
// Путь(Объект для управления путями)
struct path {
private region rg = CreateRegion()
private integer count = 0
private integer id = -1
trigger trig = CreateTrigger()
event e
region GetRegion() {
return this.rg
}
integer GetCount() {
return this.count
}
nothing Register(integer id) {
integer rgId = GetHandleId(this.rg)
SaveInteger(ht, rgId, -1, id)
this.id = id
paths[id] = this
}
nothing AddRect(rect rt) {
integer trId = GetHandleId(rt)
integer rgId = GetHandleId(this.rg)
RegionAddRect(this.rg, rt)
if (this.e == null) {
this.e = TriggerRegisterEnterRegion(this.trig, this.rg, null)
TriggerAddCondition(this.trig, function EnterCondition)
TriggerAddAction(this.trig, function EnterAction)
}
SaveInteger(ht, trId, -1, this)
SaveRectHandle(ht, this, this.count, rt)
this.count++
}
}
private nothing Init() {
ht = InitHashtable()
trigger trig = CreateTrigger()
integer i = 0
loop {
TriggerRegisterPlayerUnitEvent(trig, Player(i), EVENT_PLAYER_UNIT_DEATH, null)
i++
exitwhen i == 12
}
TriggerAddCondition(trig, function UnitDeathCondition)
TriggerAddAction(trig, function UnitDeathAction)
}
}
История версий
v1.1
* Более логичный нэйминг функций, структур и переменных
+ Добавлена возможность регистрировать пути на триггерах
Ред. Doc