XGM Forum
Сайт - Статьи - Проекты - Ресурсы - Блоги

Форуме в режиме ТОЛЬКО ЧТЕНИЕ. Вы можете задать вопросы в Q/A на сайте, либо создать свой проект или ресурс.
Вернуться   XGM Forum > Warcraft> Барахолка
Ник
Пароль
Войти через VK в один клик
Сайт использует только имя.

Ответ
 
Helpmeplz

offline
Опыт: 11,738
Активность:
Aggro System
Собственно, система аггро.

Что такое "аггро-система"?


автор MARTY

Аггро-система определяет, какого противника из атакующих юнита этот юнит будет атаковать. Что-то подобное можно видеть в онлайн играх вроде WoW.
Само слово "аггро" по звучанию близко к "angry" (англ. "злой").
То есть, к примеру, пехотинца атакуют два противника... например паладин и рыцарь. Первым напал рыцарь, и аггро пехотинца к рыцарю стало 100%. Но тут вдруг навалился паладин и стал наносить пехотинцу больший урон. Аггро пехотинца:
Рыцарь: 98%
Паладин: 1%
Постепенно оно вырастает до:
Рыцарь: 49%
Паладин: 50%
С этого момента пехотинец начинает больше " злиться " на паладина и начинает атаковать последнего, а не рыцаря.

.


Дабы не тревожить хештейбл и сторонние библиотеки, система использует GetUnitUserData() для хранения индекса аггро-таблицы.

» функции:


Код:
Threat.new(unit ForUnit)
//Создает таблицу угрозы для юнита ForUnit.

Код:
Threat.add(unit ForUnit,unit Attacker,real amount)
//Добавляет количество угрозы amount для юнита ForUnit от юнита Attacker.

Код:
Threat.get(unit ForUnit,unit Attacker,boolean percent)
//Возвращает количество угрозы созданной юнитом Attacker для юнита ForUnit. Если параметр Percent - true, то вернет процент угрозы для юнита Attacker от общего количество угрозы на юните ForUnit.

Код:
Threat.target(unit ForUnit)
//Возвращает текущую цель(цель с максимальной угрозой) для ForUnit.

Код:
Threat.top(unit ForUnit)
//Возвращает количество угрозы для вышеуказанной цели.

Код:
Threat.clear(unit ForUnit,unit Attacker)
//Очищает угрозу созданную юнитом Attacker для юнита ForUnit. Если вместо параметра Attacker - null, то очищает всю таблицу угрозы для юнита ForUnit.

Код:
Threat.remove(unit ForUnit)
//Удаляет таблицу угрозы для юнита ForUnit.

Код:
Threat.chase(unit ForUnit,unit Target,boolean Chase)
//Заставляет юнита "ForUnit" преследовать юнита "Target", игнорируя угрозу от остальных, если параметр Chase - true.


» сама система:
Код:
library Aggro initializer onInit

/*******************************************************************
CREEP AGGRO SYSTEM V1.04                                           *
Created by GodLike! aka Helpmeplz                                  *
********************************************************************

Give me credit if use it in your map.

This system allows you to improve the Creep's AI by adding a Threat Table to him.
Creep attacks the target with the most Threat amount.
For example: use damage event to add an amount of Threat from Damage Source to his target.

Uses GetUnitUserData()

functions:

Threat.new(unit ForUnit) - creates an Threat table for "ForUnit"
Threat.add(unit ForUnit,unit Attacker,real amount) - adds a "amount" of Threat to "ForUnit" from "Attacker"
Threat.get(unit ForUnit,unit Attacker,boolean percent) - returns an Threat amount of "ForUnit" genericed by "Attacker". If "percent" is true then returns the percent value from ALL Threat
Threat.target(unit ForUnit) - returns the current target for "ForUnit"
Threat.top(unit ForUnit) - returns the amount of Threat for "ForUnit"'s Target
Threat.clear(unit ForUnit,unit Attacker) - clears the Threat of "Attacker" for "ForUnit". If "Attacker" is null then clears FULL Threat table for "ForUnit"
Threat.remove(unit ForUnit) - removes an Threat Table for "ForUnit"
Threat.chase(unit ForUnit,unit Target,boolean Chase) - causes the unit "ForUnit" to chase unit "Target", ignoring all incoming threat from others, if "Chase" is true.

*******************************************************************/


globals
private constant integer MAX_ATTACKERS = 20      //maximum attackers of one unit
private constant real CLEAR_AGGRO_PERIOD = 5.   //time after the last attack when the Aggro of unit will be cleared
private constant real TARGET_AGGRO_BONUS = 1.5   //multiplier if the unit gets aggro from its attacker
endglobals

struct Threat
    static Threat array st
    static integer index = 0
    static timer t = CreateTimer()
    static trigger trg = CreateTrigger()
    static group ordered = CreateGroup()
    integer Count = 0
    unit Unit = null
    unit Target = null
    boolean CHASE = false
    real Maxaggro = 0.
    unit array Attacker[MAX_ATTACKERS]
    real array Aggro[MAX_ATTACKERS]
    real array Dur[MAX_ATTACKERS]
    
 static method GetNewTarget takes unit whichUnit returns integer
  local integer i = GetUnitUserData(whichUnit)
  local integer k = 0
  local integer j = 0
    loop
     exitwhen j >= .st[i].Count
      if .st[i].Aggro[j] > .st[i].Aggro[k] then
       set k = j
      endif
     set j = j + 1
    endloop
  return k
 endmethod
 
 static method chase takes unit whichUnit, unit TARGET,boolean CHASE returns nothing
  local integer i = GetUnitUserData(whichUnit)
  set .st[i].CHASE = CHASE
  if CHASE then
  set .st[i].Target = TARGET
  call IssueTargetOrder(.st[i].Unit,"attack",.st[i].Target)
  endif
 endmethod
    
 static method add takes unit whichUnit, unit ATTACKER,real amount returns nothing
  local integer i = GetUnitUserData(whichUnit)
  local integer j = 0
  local boolean founded = false
  if not .st[i].CHASE then
   if .st[i].Target == ATTACKER then
     set amount = amount * TARGET_AGGRO_BONUS
   endif
      loop
       exitwhen j >= .st[i].Count
       if .st[i].Attacker[j] == ATTACKER then
        set founded = true
        set .st[i].Aggro[j] = .st[i].Aggro[j] + amount
        set .st[i].Dur[j] = CLEAR_AGGRO_PERIOD
        if .st[i].Aggro[j] > .st[i].Maxaggro then
         set .st[i].Maxaggro = .st[i].Aggro[j]
         set .st[i].Target = ATTACKER
         call IssueTargetOrder(whichUnit,"attack",ATTACKER)
        endif
        set j = .st[i].Count
       endif
       set j = j + 1
      endloop
      if not founded then
       if .st[i].Count <= MAX_ATTACKERS then
        set .st[i].Attacker[.st[i].Count] = ATTACKER
        set .st[i].Aggro[.st[i].Count] = amount
        set .st[i].Dur[.st[i].Count] = CLEAR_AGGRO_PERIOD
        if amount > .st[i].Maxaggro then
         set .st[i].Maxaggro = amount
         set .st[i].Target = ATTACKER
         call IssueTargetOrder(whichUnit,"attack",ATTACKER)
        endif
        set .st[i].Count = .st[i].Count + 1
       endif
      endif
  endif
 endmethod
 
 static method get takes unit TARGET, unit ATTACKER, boolean percent returns real
  local integer i = GetUnitUserData(TARGET)
  local integer j = 0
  local real aggro = 0.
  local real mainaggro = 0.
  if .st[i].Count > 0 then
    loop
     exitwhen j >= .st[i].Count
      set mainaggro = mainaggro + .st[i].Aggro[j]
      if .st[i].Attacker[j] == ATTACKER then
       set aggro = .st[i].Aggro[j]
      endif
     set j = j + 1
    endloop
   if percent then
    return aggro / mainaggro * 100.
   endif
    return aggro
  endif
  return 0.
 endmethod
 
 static method target takes unit whichUnit returns unit
  if whichUnit == .st[GetUnitUserData(whichUnit)].Unit then
    return .st[GetUnitUserData(whichUnit)].Target
  endif
  return null
 endmethod
 
 static method top takes unit whichUnit returns real
  if whichUnit == .st[GetUnitUserData(whichUnit)].Unit then
    return .st[GetUnitUserData(whichUnit)].Maxaggro
  endif
  return 0.
 endmethod
 
 static method clear takes unit whichUnit, unit forUnit returns nothing
  local integer i = GetUnitUserData(whichUnit)
  local integer j = 0
  local integer k = 0
  if not (forUnit == null) then
   loop
    exitwhen j >= .st[i].Count
     if forUnit == .st[i].Attacker[j] then
        if .st[i].Attacker[j] == .st[i].Target then
          set .st[i].Target = null
          call IssueImmediateOrder(.st[i].Unit,"stop")
        endif
       set .st[i].Count = .st[i].Count - 1
       set .st[i].Attacker[j] = .st[i].Attacker[.st[i].Count]
       set .st[i].Aggro[j] = .st[i].Aggro[.st[i].Count]
       set .st[i].Dur[j] = .st[i].Dur[.st[i].Count]
        if .st[i].Count == 0 then
         set .st[i].Target = null
         set .st[i].Maxaggro = 0.
        elseif .st[i].Target == null then
         set k = Threat.GetNewTarget(.st[i].Unit)
         set .st[i].Target = .st[i].Attacker[k]
         set .st[i].Maxaggro = .st[i].Aggro[k]
         call IssueTargetOrder(.st[i].Unit,"attack",.st[i].Target)
        endif
       set j = .st[i].Count
     endif
    set j = j + 1
   endloop
  else
   set .st[i].Count = 0
   set .st[i].Maxaggro = 0.
   set .st[i].Target = null
  endif
 endmethod
 
 static method remove takes unit whichUnit returns nothing
  local integer i = GetUnitUserData(whichUnit)
   if .st[i].Unit == whichUnit then
    if .st[i].Count > 0 then
    call .st[i].destroy()
    endif
    set .index = .index - 1
    set .st[i] = .st[.index]
    call GroupRemoveUnit(.ordered,whichUnit)
    if .index == 0 then
      call PauseTimer(.t)
    endif
   endif
 endmethod
 
 static method onTimer takes nothing returns nothing
  local integer i = 0
  local integer j = 0
  local integer k = 0
   loop
    exitwhen i >= .index
     set j = 0
     loop
      exitwhen j >= .st[i].Count
       set .st[i].Dur[j] = .st[i].Dur[j] - 1.
       if .st[i].Dur[j] <= 0. or IsUnitType(.st[i].Target,UNIT_TYPE_DEAD) then
        if .st[i].Attacker[j] == .st[i].Target then
         set .st[i].Target = null
         call IssueImmediateOrder(.st[i].Unit,"stop")
        endif
        set .st[i].Count = .st[i].Count - 1
        set .st[i].Attacker[j] = .st[i].Attacker[.st[i].Count]
        set .st[i].Aggro[j] = .st[i].Aggro[.st[i].Count]
        set .st[i].Dur[j] = .st[i].Dur[.st[i].Count]
        if .st[i].Count == 0 then
         set .st[i].Target = null
         set .st[i].Maxaggro = 0.
        elseif .st[i].Target == null then
         set k = Threat.GetNewTarget(.st[i].Unit)
         set .st[i].Target = .st[i].Attacker[k]
         set .st[i].Maxaggro = .st[i].Aggro[k]
         call IssueTargetOrder(.st[i].Unit,"attack",.st[i].Target)
        endif
        set j = j - 1
       endif
      set j = j + 1
     endloop
    set i = i + 1
  endloop
 endmethod
 
 static method new takes unit whichUnit returns nothing
  if not (.st[GetUnitUserData(whichUnit)].Unit == whichUnit) then
   set .st[.index] = Threat.create()
   set .st[.index].Unit = whichUnit
   set .st[.index].Target = null
   set .st[.index].Count = 0
   set .st[.index].Maxaggro = 0.
   call SetUnitUserData(whichUnit,.index)
   if .index == 0 then
      call TimerStart(.t,1.,true,function Threat.onTimer)
   endif
   if not IsUnitInGroup(whichUnit,.ordered) then
    call TriggerRegisterUnitEvent(Threat.trg,whichUnit,EVENT_UNIT_ISSUED_TARGET_ORDER)
    call GroupAddUnit(.ordered,whichUnit)
   endif
   set .index = .index + 1
  endif
 endmethod
 
 static method onOrder takes nothing returns boolean
 local integer i = 0
  if GetIssuedOrderId() == OrderId("attack")
   set i = GetUnitUserData(GetTriggerUnit())
   if not (GetOrderTargetUnit() == .st[i].Target) and not (.st[i].Target == null) then
    call IssueTargetOrder(.st[i].Unit,"attack",.st[i].Target)
   endif
  endif
  return false
 endmethod

endstruct

private function onInit takes nothing returns nothing
  call TriggerAddCondition(Threat.trg,Condition(function Threat.onOrder))
endfunction

endlibrary


Настройки:


MAX_ATTACKERS - максимальное количество юнитов, которые будут занесены в аггро таблицу к данному
CLEAR_AGGRO_PERIOD - время с последней атаки юнита, после которого он потеряет все свое аггро на цели
TARGET_AGGRO_BONUS - множитель аггро если нападающий юнит является целью

Визуализация




» код

Код:
library ThreatBars initializer onInit requires Aggro

/*******************************************************************
THREAT BARS for CREEP AGGRO SYSTEM V1.04                           *
Created by GodLike! aka Helpmeplz                                  *
********************************************************************

Give me credit if use it in your map.

This system allows you to adds a Threat Bar for your multiboard, showing an Threat amount of any Unit on the other.

functions:

TBar.add(ForUnit,Attacker,Mb,Row,S_COLUMN,E_COLUMN) - adds an Aggro Bar (showing Threat of "Attacker" on "ForUnit") for multiboard "mb" in row "ROW" starts with S_COMUN and Ends with E_COLUMN.
Automaticaly increases the counts of rows/columns of multiboard if they are lesser than needed.
NOTE: the differense beetwen the starting column and the ending column must be at least 3!

TBar.remove(ForUnit,Attacker,Mb,Row) - removes an Threat Bar (showing Threat of "Attacker" on "ForUnit") for multiboard "mb" from row "Row".

*******************************************************************/

globals
private string array Bars[24]
endglobals

struct TBar
     static TBar array st
     static integer index = 0
     static timer t = CreateTimer()
     unit Target = null
     unit Attacker = null
     multiboard mb = null
     integer ROW = 0
     real COUNT = 0
     integer S_COL = 0
     integer E_COL = 0
     
 static method GetIcon takes integer index,integer s_col, integer e_col returns string
  if index == s_col then
   return Bars[0]
  elseif index == e_col then
    return Bars[23]
  endif
  return Bars[24]
 endmethod
 
 static method RefreshTable takes nothing returns nothing
  local integer i = 0
  local integer j = 0
  local multiboarditem mbi = null
  local string icon = ""
  local integer k = 0
   loop
    exitwhen i >= .index
     set j = .st[i].S_COL
     set k = R2I(Threat.get(.st[i].Target,.st[i].Attacker,true) / .st[i].COUNT)
      loop
       exitwhen j > .st[i].E_COL
       set mbi = MultiboardGetItem(.st[i].mb,.st[i].ROW,j)
       if j == .st[i].S_COL then
        if k == 0 then
         set icon = Bars[0]
        elseif k>=7 then
         set k=k-7
         set icon = Bars[7]
        else
         set icon = Bars[k]
         set k = 0
        endif
       elseif j == .st[i].E_COL then
        if k==0 then
         set icon = Bars[23]
        elseif k>=7 then
         set icon = Bars[22]
        else
         set icon = Bars[15+k]
        endif
       else
        if k==0 then
         set icon = Bars[24]
        elseif k>=7 then
         set k = k - 7
         set icon = Bars[15]
        else
         set icon = Bars[7+k]
         set k = 0
        endif
       endif
       set j = j + 1
       call MultiboardSetItemIcon(mbi,icon)
       call MultiboardReleaseItem(mbi)
       set mbi = null
      endloop
    set i = i + 1
   endloop
 endmethod
 
 static method remove takes unit Target,unit Attacker,multiboard m,integer Row returns nothing
  local integer i = 0
  local integer j = 0
  local multiboarditem mbi = null
   loop
    exitwhen i >=. index
     if .st[i].Target == Target and .st[i].Attacker == Attacker and .st[i].mb == m and .st[i].ROW == Row then
      set j = .st[i].S_COL
      loop
       exitwhen j > .st[i].E_COL
        set mbi = MultiboardGetItem(.st[i].mb,.st[i].ROW,j)
        call MultiboardSetItemStyle(mbi,false,false)
        call MultiboardReleaseItem(mbi)
        set mbi = null
       set j = j + 1
      endloop
      call .st[i].destroy()
      set .index = .index - 1
      set .st[i] = .st[.index]
      if .index == 0 then
       call PauseTimer(.t)
      endif
      set i = .index
     endif
    set i = i + 1
   endloop
 endmethod
     
 static method add takes unit Target,unit Attacker, multiboard m,integer row,integer s_col,integer e_col returns nothing
  local integer i = 0
  local multiboarditem mbi = null
  set .st[.index] = TBar.create()
  set .st[.index].mb = m
  set .st[.index].ROW = row
  set .st[.index].S_COL = s_col
  set .st[.index].E_COL = e_col
  set .st[.index].Target = Target
  set .st[.index].Attacker = Attacker
  set .st[.index].COUNT = 100. / ( (e_col - s_col + 1) * 8 - 2)
  if e_col > MultiboardGetColumnCount(m) then
   call MultiboardSetColumnCount(m,e_col)
  endif
  if row > MultiboardGetRowCount(m) then
   call MultiboardSetRowCount(m,row)
  endif
  set i = s_col
  loop
   exitwhen i > .st[.index].E_COL
   set mbi = MultiboardGetItem(m,row,i)
   call MultiboardSetItemStyle(mbi,false,true)
   call MultiboardSetItemWidth(mbi,0.01)
   call MultiboardSetItemIcon(mbi,TBar.GetIcon(i,.st[.index].S_COL,.st[.index].E_COL))
   call MultiboardReleaseItem(mbi)
   set mbi = null
   set i = i + 1
  endloop
  if .index == 0 then
   call TimerStart(.t,0.04,true,function TBar.RefreshTable)
  endif
  set .index = .index + 1
 endmethod
 
endstruct

private function onInit takes nothing returns nothing
set Bars[0] = "war3mapImported\\AggroL0.tga"
set Bars[1] = "war3mapImported\\AggroL1.tga"
set Bars[2] = "war3mapImported\\AggroL2.tga"
set Bars[3] = "war3mapImported\\AggroL3.tga"
set Bars[4] = "war3mapImported\\AggroL4.tga"
set Bars[5] = "war3mapImported\\AggroL5.tga"
set Bars[6] = "war3mapImported\\AggroL6.tga"
set Bars[7] = "war3mapImported\\AggroL7.tga"
set Bars[8] = "war3mapImported\\AggroM1.tga"
set Bars[9] = "war3mapImported\\AggroM2.tga"
set Bars[10] = "war3mapImported\\AggroM3.tga"
set Bars[11] = "war3mapImported\\AggroM4.tga"
set Bars[12] = "war3mapImported\\AggroM5.tga"
set Bars[13] = "war3mapImported\\AggroM6.tga"
set Bars[14] = "war3mapImported\\AggroM7.tga"
set Bars[15] = "war3mapImported\\AggroM8.tga"
set Bars[16] = "war3mapImported\\AggroR1.tga"
set Bars[17] = "war3mapImported\\AggroR2.tga"
set Bars[18] = "war3mapImported\\AggroR3.tga"
set Bars[19] = "war3mapImported\\AggroR4.tga"
set Bars[20] = "war3mapImported\\AggroR5.tga"
set Bars[21] = "war3mapImported\\AggroR6.tga"
set Bars[22] = "war3mapImported\\AggroR7.tga"
set Bars[23] = "war3mapImported\\AggroR0.tga"
set Bars[24] = "war3mapImported\\AggroM0.tga"
endfunction

endlibrary


» +функции

Код:
TBar.add(ForUnit,Attacker,Mb,Row,S_COLUMN,E_COLUMN)
//добавляет Трит-бар(показывает угрозу юнита Attacker на юните ForUnit) в строку Row мультиборда Mb, начиная со столбца S_COLUM и заканчивая столбцом E_COLUMN.
Автоматически увеличивает количество строк/столбцов в мультиборде, если их меньше чем указано.
Примечание: в этом случае не инициализируются ячейки в строках не относящихся к Трит-бару.
Примечание: количество столбцов в промежутке должно быть не менее 3.


Код:
TBar.remove(ForUnit,Attacker,Mb,Row)
//удаляет Трит-бар(показывает угрозу юнита Attacker на юните ForUnit) из строки Row мультиборда Mb.



карта-пример прилагается(обновлено)
Прикрепленные файлы
Тип файла: w3x Creep Aggro System v1.04.w3x (55.0 Кбайт, 46 просмотров )

Отредактировано Helpmeplz, 19.08.2011 в 20:11.
Старый 14.07.2011, 09:01
Suite
┌_____┐
offline
Опыт: 11,222
Активность:
Helpmeplz, а можна спросить че она делает и с чем его едят? я впервые вижу это слово •_О
Старый 14.07.2011, 10:18
Wine
ЙАААЗЬ?
offline
Опыт: 17,126
Активность:
лидерборд либо некорректно отображается, либо в системе есть ошибки
Старый 14.07.2011, 10:49
Helpmeplz

offline
Опыт: 11,738
Активность:
Wine, ты мог просто не обновить его. хотя не утверждаю, что косяков нет - писал в 4 утра. но я вроде бы все нюансы проверил.
Suite, в первом посте есть ссылка на wiki.

Отредактировано Helpmeplz, 14.07.2011 в 18:22.
Старый 14.07.2011, 18:02
MARTY
Осильте мою писанину...
offline
Опыт: 1,122
Активность:
То есть, если я правильно понял, то это система, определяющая отношение НПС`а к игроку?
Например:
враг, нейтральный, союзник.
Так?
Или я опять показал свою глупость?

Сделай нормальное описание, чтоб было понятно, что за наработка.
И проверь её, потому что не работает.

А, всё, понял, как работает.
Неплохая задумка!

Сделай нормальное описание наработке, например:
» Пример описания

Описание

Данная наработка позволяет вам использовать в своей карте аггро-систему.

Что такое "аггро-система"?

Аггро-система определяет, какого противника из атакующих юнита этот юнит будет атаковать. Что-то подобное можно видеть в онлайн играх вроде WoW.
Само слово "аггро" по звучанию близко к "angry" (англ. "злой").
То есть, к примеру, пехотинца атакуют два противника... например паладин и рыцарь. Первым напал рыцарь, и аггро пехотинца к рыцарю стало 100%. Но тут вдруг навалился паладин и стал наносить пехотинцу больший урон. Аггро пехотинца:
  • Рыцарь: 98%
  • Паладин: 1%
Постепенно оно вырастает до:
  • Рыцарь: 49%
  • Паладин: 50%
С этого момента пехотинец начинает больше " злиться " на паладина и начинает атаковать последнего, а не рыцаря.

Подводя итог

Это довольно полезная наработка для ОРПГ, так как добавляет ИИ ещё одну новую функцию. В действительности, противник предпочтёт атаковать не лечащего противника, а ДД. А уже убив ДД, он убьёт беззащитного лекаря.

Плюсы

Ну уж их описывай сам, могу лишь предложить:
  • малый вес
  • отсутствие необходимости в JNGP и тому подобных системах

Минусы

Тоже пиши сам :)
  • мультибоард не обновляется

Отредактировано MARTY, 14.07.2011 в 19:52.
Старый 14.07.2011, 19:19
Helpmeplz

offline
Опыт: 11,738
Активность:
эта система ничего не определяет
она может установить "отношение" компьютерного юнита к вражеским. под отношением подразумевается выбор конкретной цели с наибольшим параметром на данном юните - аггро.
Старый 14.07.2011, 19:21
Elf_Stratigo

offline
Опыт: 4,699
Активность:
это не тоже самое, что поле upri?
Старый 14.07.2011, 22:51
LOR_D
    
offline
Опыт: 8,450
Активность:
граждане, играйте в вов
Хорошая системка, возможно скоро заюзаю.
А можно изменить как-нибудь коэффициент набора аггро. Например, маг продамажил молнией на 1000 урона и набрал, скажем, 100 аггропунктов, а воин ударил с руки 100 дамага и получил столько же аггропунктов, не являясь при этом целью.
Старый 14.07.2011, 23:08
Helpmeplz

offline
Опыт: 11,738
Активность:
Исправил баг когда аггро не сбрасывалось. Добавил нормальный мультиборд в карту-пример.

Цитата:
Сообщение от Elf_Stratigo
это не тоже самое, что поле upri?

что это?

LOR_D, отлавливать урон от мага это уже задача пользователя, а не системы. есть Aggro.add() - используйте когда захотите.
Старый 14.07.2011, 23:08
Doc

offline
Опыт: 63,163
Активность:
Сделай нормальную визуализацию лучше. (как дополнение к системе офк) а то как чисто логический контейнер слабенько.
Старый 14.07.2011, 23:28
Helpmeplz

offline
Опыт: 11,738
Активность:
добавил визуализацию, исправил некоторые баги.
» код

Код:
library AggroTable initializer onInit requires CreepAggro

/*
Created by GodLike aka Helpmeplz
Give me credit if you use it in your map.

This system allows you to adds an Aggro bar for your multiboard, showing an Aggro amount of any Unit on the other.

functions:

Table.add(ForUnit,Attacker,Mb,Row,S_COLUMN,E_COLUMN) - adds an Aggro Bar (showing Aggro of "Attacker" on "ForUnit") for multiboard "mb" in row "ROW" starts with S_COMUN and Ends with E_COLUMN.
Automaticaly increases the counts of rows/columns of multiboard if they are lesser than needed.
NOTE: the differense beetwen the start column and the end column must be at least 3!

Table.remove(ForUnit,Attacker,Mb) - removes an Aggro Bar (showing Aggro of "Attacker" on "ForUnit") for multiboard "mb"
NOTE: I think you won't create two aggro bars in various rows. That's why this function doesn't require row number.

*/

globals
private string array Bars[24]
endglobals

struct Table
     static Table array st
     static integer index = 0
     static timer t = CreateTimer()
     unit Target = null
     unit Attacker = null
     multiboard mb = null
     integer ROW = 0
     real COUNT = 0
     integer S_COL = 0
     integer E_COL = 0
     
 static method GetIcon takes integer index,integer s_col, integer e_col returns string
  if index == s_col then
   return Bars[0]
  elseif index == e_col then
    return Bars[23]
  endif
  return Bars[24]
 endmethod
 
 static method RefreshTable takes nothing returns nothing
  local integer i = 0
  local integer j = 0
  local multiboarditem mbi = null
  local string icon = ""
  local integer k = 0
   loop
    exitwhen i >= .index
     set j = .st[i].S_COL
     set k = R2I(Aggro.get(.st[i].Target,.st[i].Attacker,true) / .st[i].COUNT)
      loop
       exitwhen j > .st[i].E_COL
       set mbi = MultiboardGetItem(.st[i].mb,.st[i].ROW,j)
       if j == .st[i].S_COL then
        if k == 0 then
         set icon = Bars[0]
        elseif k>=7 then
         set k=k-7
         set icon = Bars[7]
        else
         set icon = Bars[k]
         set k = 0
        endif
       elseif j == .st[i].E_COL then
        if k==0 then
         set icon = Bars[23]
        elseif k>=7 then
         set icon = Bars[22]
        else
         set icon = Bars[15+k]
        endif
       else
        if k==0 then
         set icon = Bars[24]
        elseif k>=7 then
         set k = k - 7
         set icon = Bars[15]
        else
         set icon = Bars[7+k]
         set k = 0
        endif
       endif
       set j = j + 1
       call MultiboardSetItemIcon(mbi,icon)
       call MultiboardReleaseItem(mbi)
       set mbi = null
      endloop
    set i = i + 1
   endloop
 endmethod
 
 static method remove takes unit Target,unit Attacker,multiboard m returns nothing
  local integer i = 0
  local integer j = 0
  local multiboarditem mbi = null
   loop
    exitwhen i >=. index
     if .st[i].Target == Target and .st[i].Attacker == Attacker and .st[i].mb == m then
      set j = .st[i].S_COL
      loop
       exitwhen j > .st[i].E_COL
        set mbi = MultiboardGetItem(.st[i].mb,.st[i].ROW,j)
        call MultiboardSetItemStyle(mbi,false,false)
        call MultiboardReleaseItem(mbi)
        set mbi = null
       set j = j + 1
      endloop
      call .st[i].destroy()
      set .index = .index - 1
      set .st[i] = .st[.index]
      if .index == 0 then
       call PauseTimer(.t)
      endif
      set i = .index
     endif
    set i = i + 1
   endloop
 endmethod
     
 static method add takes unit Target,unit Attacker, multiboard m,integer row,integer s_col,integer e_col returns nothing
  local integer i = 0
  local multiboarditem mbi = null
  set .st[.index] = Table.create()
  set .st[.index].mb = m
  set .st[.index].ROW = row
  set .st[.index].S_COL = s_col
  set .st[.index].E_COL = e_col
  set .st[.index].Target = Target
  set .st[.index].Attacker = Attacker
  set .st[.index].COUNT = 100. / ( (e_col - s_col + 1) * 8 - 2)
  if e_col > MultiboardGetColumnCount(m) then
   call MultiboardSetColumnCount(m,e_col)
  endif
  if row > MultiboardGetRowCount(m) then
   call MultiboardSetRowCount(m,row)
  endif
  set i = s_col
  loop
   exitwhen i > .st[.index].E_COL
   set mbi = MultiboardGetItem(m,row,i)
   call MultiboardSetItemStyle(mbi,false,true)
   call MultiboardSetItemWidth(mbi,0.01)
   call MultiboardSetItemIcon(mbi,Table.GetIcon(i,.st[.index].S_COL,.st[.index].E_COL))
   call MultiboardReleaseItem(mbi)
   set mbi = null
   set i = i + 1
  endloop
  if .index == 0 then
   call TimerStart(.t,0.04,true,function Table.RefreshTable)
  endif
  set .index = .index + 1
 endmethod
 
endstruct

private function onInit takes nothing returns nothing
set Bars[0] = "war3mapImported\\AggroL0.tga"
set Bars[1] = "war3mapImported\\AggroL1.tga"
set Bars[2] = "war3mapImported\\AggroL2.tga"
set Bars[3] = "war3mapImported\\AggroL3.tga"
set Bars[4] = "war3mapImported\\AggroL4.tga"
set Bars[5] = "war3mapImported\\AggroL5.tga"
set Bars[6] = "war3mapImported\\AggroL6.tga"
set Bars[7] = "war3mapImported\\AggroL7.tga"
set Bars[8] = "war3mapImported\\AggroM1.tga"
set Bars[9] = "war3mapImported\\AggroM2.tga"
set Bars[10] = "war3mapImported\\AggroM3.tga"
set Bars[11] = "war3mapImported\\AggroM4.tga"
set Bars[12] = "war3mapImported\\AggroM5.tga"
set Bars[13] = "war3mapImported\\AggroM6.tga"
set Bars[14] = "war3mapImported\\AggroM7.tga"
set Bars[15] = "war3mapImported\\AggroM8.tga"
set Bars[16] = "war3mapImported\\AggroR1.tga"
set Bars[17] = "war3mapImported\\AggroR2.tga"
set Bars[18] = "war3mapImported\\AggroR3.tga"
set Bars[19] = "war3mapImported\\AggroR4.tga"
set Bars[20] = "war3mapImported\\AggroR5.tga"
set Bars[21] = "war3mapImported\\AggroR6.tga"
set Bars[22] = "war3mapImported\\AggroR7.tga"
set Bars[23] = "war3mapImported\\AggroR0.tga"
set Bars[24] = "war3mapImported\\AggroM0.tga"
endfunction

endlibrary


» +функции

Код:
Table.add(ForUnit,Attacker,Mb,Row,S_COLUMN,E_COLUMN)
//добавляет Аггро-бар(показывает аггро юнита Attacker на юните ForUnit) в строку Row мультиборда Mb, начиная со столбца S_COLUM и заканчивая столбцом E_COLUMN.
Автоматически увеличивает количество строк/столбцов в мультиборде, если их меньше чем указано.
Примечание: в этом случае не инициализируются ячейки в строках не относящихся к Аггро-бару.
Примечание: количество столбцов в промежутке должно быть не менее 3.


Код:
Table.remove(ForUnit,Attacker,Mb)
//удаляет Аггро-бар(показывает аггро юнита Attacker на юните ForUnit) из мультиборда Mb.
Примечание: я думаю вам не придет в голову создавать два одинаковых Аггро-бара в одном мультиборде, но с разными строками. Поэтому функция не требует номера строки.


Старый 19.07.2011, 07:49
Rampage
Бицепс
offline
Опыт: 9,722
Активность:
Классный бар, но неудобно в мультиборде такое держать.
Старый 19.07.2011, 12:19
LuNa_aDa
Trolling For Ever
offline
Опыт: 12,610
Активность:
Как данная система может помочь картам популярных, на данный момент, стилей?
Старый 20.07.2011, 10:19
Rapture

offline
Опыт: 16,634
Активность:
Hell_oy, ну Тд, Аосу, развитию, арене и тп. ничем не поможет, а Рпг да.
Старый 20.07.2011, 10:22
Helpmeplz

offline
Опыт: 11,738
Активность:
Обновлено.
Добавил функцию преследования(например для таунта). Немного поправил другие.
Старый 19.08.2011, 20:12
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы можете скачивать файлы

BB-коды Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход



Часовой пояс GMT +3, время: 18:11.