WarCraft 3: Решение задач

Тип integer

Золото за убийство

globals
 real array goldMin
 real array goldMax
 // два массива которые образуют базу
 // данных по бонусному золоту
endglobals

function Init takes nothing returns nothing
 set goldMin[0x00]=1
 set goldMin[0x01]=25
 set goldMin[0x02]=12
 set goldMin[0x03]=85
 set goldMin[0x04]=10
 set goldMin[...n]=n

 set goldMax[0x00]=5
 set goldMax[0x01]=28
 set goldMax[0x02]=15
 set goldMax[0x03]=285
 set goldMax[0x04]=12
 set goldMax[...n]=n
endfunction
Первый элемент массива 0x00 или 0x75303030-0x75303030 (т.е. 'u000' - 'u000') будет соответствовать юниту 'u000', 0x01 или 0x75303031-0x75303030 (т.е. 'u001' - 'u000') юниту 'u001' и так далее.
Это кстати весьма просто и эффективный вариант базы данных по стандартным объектам на массивах, единственно что надо помнить - <raw code> - 0x75303030 < 8190 (максимальный размер массива, 0x75303030 наш офсет).
Вот так это будет выглядеть в коде
function AddGlod takes real x, real y, player p, integer gold returns nothing

 ...

 local integer i=GetUnitTypeId(GetDyingUnit())
 call AddGold(<x>, <y>, <player>, GetRandomInt(goldMin[i-0x75303030], goldMax[i-0x75303030])*<factor>)
Хорошо, а теперь попробуем разместить информацию о золоте в самом равкоде юнита.
  0000 0000 0000 0000 0000 0000 0000 0000
  ----  ----  xaaa  aaaa  xbbb  bbbb  ----  ----

a - минимальное золото, b - максимальное золото, x - сепаратор
Вот так это будет выглядеть в коде
function AddGlod takes real x, real y, player p, integer gold returns nothing

 ...
 local integer i=GetUnitTypeId(GetDyingUnit())
 call AddGold(x, y, owning_player, GetRandomInt(i*0x00000100/0x01000000-0x00000030, i*0x00010000/0x01000000-0x00000030)*factor
Для юнита 'h1<0' выдаст от 1 до 12, и для 'u\{1' - от 44 до 75 золота. В rawcode мы можем свободно использовать любые символы от 0x30 до 0x7b, и я думаю, что это - достаточно простое и изящное решение этой задачи ;)
Напомню также что в NewGenWE можно вводить равкоды объектов в РО вручную.

Добавление предмета

 ...
 call CreateItem(GetUnitTypeId(<hero>)+0x01000000, GetUnitX(<hero>), GetUnitY(<hero>))
 ...
Слишком просто? Да, это будет работать даже для сотни героев, единственное условие состоит в том, что равкод предмета должен быть больше равкода героя на 0x01000000, то есть для героя 'H000' будет создан предмет 'I000', для 'H005' - 'I005' и т.д. Вроде все понятно, но на самом деле это очень удобный и эффективный метод)

Данные юнита

Теперь мы условно разделим UserData нашего юнита следующим образом
  0000  0000  0000  0000  0000 0000  0000 0000
  -AAA AAAA AAAA -BBB BBBB BB-C  ----  ----
A - счетчик крипов, значения от 0 до 2047, B - счетчик героев, от 0 до 511, и C - bool является ли юнит светлым (1==светлый, 0==темный)
В коде это будет использоваться следующим образом
// увеличить счетчик крипов на 1
function IncCC takes unit u returns nothing
 call SetUnitUserData(u, GetUnitUserData(u)+0x00100000)
endfunction

// сколько юнит убил крипов
function GetCC takes unit u returns integer
 return GetUnitUserData(u)/0x00100000
endfunction

// увеличить счетчик героев на 1
function IncHC takes unit u returns nothing
 call SetUnitUserData(u, GetUnitUserData(u)+0x00000400)
endfunction

// сколько юнит убил героев
function GetHC takes unit u returns integer
 return GetUnitUserData(u)*0x00001000/0x00400000
endfunction

function MakeUnitEvil takes unit u returns nothing
 local integer i=GetUnitUserData(u)
 if i*0x00400000/0x40000000==0x01then
  call SetUnitUserData(u, i-0x00000100)
 endif
endfunction

function MakeUnitHoly takes unit u returns nothing
 local integer i=GetUnitUserData(u)
 if i*0x00400000/0x40000000==0x00then
  call SetUnitUserData(u, i+0x00000100)
 endif
endfunction

function GetUnitPropensity takes unit u returns nothing
 return GetUnitUserData(u)*0x00400000/0x40000000
endfunction
Отлично! Просто и со вкусом, никаких утечек и т.д. И конечно же в UserData можно хранить две vJass структуры и еще два boolean
  0000 0000  0000 0000  0000  0000  0000  0000
  -AAA AAAA AAAA AA-B BBBB BBBB BBBB -C-D

Заключение

Ну что же, я думаю хоть эти примеры и немного банальны, они помогут Вам понять идею этой темы.

Просмотров: 3 018

Комментарии пока отсутcтвуют