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

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

Ответ
 
Kenshi245

offline
Опыт: 2,252
Активность:
Помогите со скиллом
Помогите пожалуйста написать скилл на джассе чтобы он не юзал функции из blizzard.j и не имел утечек памяти, скилл делает следующее:
Скилл называется Ballance Life:
Берет всех дружественных юнитов вокруг кастера и подсчитывает общее количество ХП, затем делит эти хп межту всеми юнитами поровну.
Сам пробовал написать, но получалось криво и и извращениями.
Старый 27.03.2008, 13:12
adic3x

offline
Опыт: 108,439
Активность:
Старый 27.03.2008, 13:25
Kenshi245

offline
Опыт: 2,252
Активность:
По идее что-то типа этого должно получиться:
function Trig_BallanceLife_Conditions takes nothing returns boolean
if ( not ( GetSpellAbilityId() == 'САМ_СКИЛЛ' ) ) then
return false
endif
return true
endfunction
function Trig_Ballance_Life_Actions takes nothing returns nothing
local location loc = GetUnitLoc(GetTriggerUnit())
local group groupA = GetUnitsInRangeOfLocMatching(300, loc, null)
local group groupB = groupA
local unit unitA
local real HP = 0
local integer Nunits = 0
loop
set unitA=FirstOfGroup(groupA)
exitwhen unitA==null
Nunits = Nunits + 1
set HP = HP + GetUnitState(UnitA, UNIT_STATE_LIFE)
call GroupRemoveUnit(groupA,unitA)
endloop
set HP = HP / Nunits
loop
set unitA=FirstOfGroup(groupB)
exitwhen unitA==null
call SetUnitState(UnitA,UNIT_STATE_LIFE,GetUnitState(UnitA, UNIT_STATE_LIFE)+HP
call GroupRemoveUnit(groupB,unitA)
endloop
endfunction
Старый 27.03.2008, 14:08
adic3x

offline
Опыт: 108,439
Активность:
а, так тебе надо не написать, а помочь довести до ума? так и говорите)

Код:
globals
 group gr_temp=CreateGroup()
 real r_temp=0.
 integer i_temp=0x00
endglobals

function Trig_BallanceLife_Conditions takes nothing returns boolean
 return GetSpellAbilityId() == 'САМ_СКИЛЛ'
endfunction

function XxX takes nothing returns nothing
 call SetWidgetLife(GetEnumUnit(), r_temp)
endfunction

function xXx takes nothing returns boolean
 set i_temp=i_temp+0x01
 set r_temp=r_temp+GetWidgetLife(GetFilterUnit())
 return true
endfunction

function Trig_Ballance_Life_Actions takes nothing returns nothing
 set r_temp=0.
 set i_temp=0x00
 call GroupEnumUnitsInRange(gr_temp, GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), 300., Condition(xXx))
 set r_temp=r_temp/i_temp
 call ForGroup(gr_temp, function XxX)
 call GroupClear(gr_temp)
endfunction


+ на мой код будет ругаццо обычный редактор, смотри соседний топи про жасс нью ген пак
Старый 27.03.2008, 14:20
Kenshi245

offline
Опыт: 2,252
Активность:
Почему-то редактор ругается на это:
set HP = HP + GetUnitState(UnitA, UNIT_STATE_LIFE)
Где тут ошибка?

Kenshi245 добавил:
Цитата:
Сообщение от ADOLF
а, так тебе надо не написать, а помочь довести до ума? так и говорите)

Код:
globals
 group gr_temp=CreateGroup()
 real r_temp=0.
 integer i_temp=0x00
endglobals

function Trig_BallanceLife_Conditions takes nothing returns boolean
 return GetSpellAbilityId() == 'САМ_СКИЛЛ'
endfunction

function XxX takes nothing returns nothing
 call SetWidgetLife(GetEnumUnit(), r_temp)
endfunction

function xXx takes nothing returns boolean
 set i_temp=i_temp+0x01
 set r_temp=r_temp+GetWidgetLife(GetFilterUnit())
 return true
endfunction

function Trig_Ballance_Life_Actions takes nothing returns nothing
 set r_temp=0.
 set i_temp=0x00
 call GroupEnumUnitsInRange(gr_temp, GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), 300., Condition(xXx))
 set r_temp=r_temp/i_temp
 call ForGroup(gr_temp, function XxX)
 call GroupClear(gr_temp)
endfunction


+ на мой код будет ругаццо обычный редактор, смотри соседний топи про жасс нью ген пак


А можешь плиз написать комменты, а то я только начал джасс юзать, и еще не умею на лету читать чужой код?
Старый 27.03.2008, 14:37
adic3x

offline
Опыт: 108,439
Активность:
ща попробую...
Код:
globals
 group gr_temp=CreateGroup()
 real r_temp=0. //временные переменные используются только в одном потоке
 integer i_temp=0x00 // все они глобальны т.е. область видимости весь код
endglobals

function Trig_BallanceLife_Conditions takes nothing returns boolean
 return GetSpellAbilityId() == 'САМ_СКИЛЛ' // просто записал условие в правильной форме
endfunction

function XxX takes nothing returns nothing
 call SetWidgetLife(GetEnumUnit(), r_temp) // устанавливает жизнь
endfunction

function xXx takes nothing returns boolean
 set i_temp=i_temp+0x01 // счетчик юнитов в группе
 set r_temp=r_temp+GetWidgetLife(GetFilterUnit()) // общее хп
 return true // возращает бул добавлять ли юнита в группу
endfunction

function Trig_Ballance_Life_Actions takes nothing returns nothing
 set r_temp=0. // ставлю им значение 0 что бы при каждом касте они насчитывали заново
 set i_temp=0x00
 call GroupEnumUnitsInRange(gr_temp, GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), 300., Condition(xXx)) // заноси в группу гр_темп всех юнитов ис точки юнита в радиусе 300., причем
// для каждого юнита вызывается функция хХх, в ней доступ к юниту 
//можно получить черех ГетФилтерЮнит()
 set r_temp=r_temp/i_temp // получаю значение сколько надо поставить жизни каждому юниту
 call ForGroup(gr_temp, function XxX) // опять же цикл по группе, в ней к каждому юниту который 
// находиться в группе применяется ХхХ, причем доступ к нему через ГетЕнумЮнит(), ему и ставлю хп из переменной
 call GroupClear(gr_temp) // удаляю всех из группы что бы она снова была чиста
endfunction


ADOLF добавил:
вообще мой код всегда не особо понятен непосвещеннім, поєтому лучше спрашивай что конкретно неясно
Старый 27.03.2008, 17:37
Kenshi245

offline
Опыт: 2,252
Активность:
Короче какие бывают способы переборки каждого юнита в группе и выполнения действия, кроме такого?

loop
set unitA=FirstOfGroup(groupA)
exitwhen unitA==null
call GroupRemoveUnit(groupA,unitA)
endloop

Kenshi245 добавил:
Или вот еще проблема - есть функция
call ForGroup(GetUnitsInRangeOfLocAll(1000, loc), function MyFunction )
Она должна на каждого юнита в радиусе выполнять функцию MyFunction
И я даже могу передать туда параметры
call ForGroup(GetUnitsInRangeOfLocAll(1000, loc), function MyFunction(lala) )
Но обратно я ничего получить не могу, то есть выполнив MyFunction как мне получить что-нибуть обратно?
Старый 27.03.2008, 20:58
adic3x

offline
Опыт: 108,439
Активность:
теперь обьясняю, (зри мой пример) есть глобальные переменные - их область видимости - весь код (надеюсь это понятно) - ими я и пользуюсь

теперь конструкция call ForGroup(GetUnitsInRangeOfLocAll(1000, loc), function MyFunction ) неверна, выкладываю код используемой в них функции
Код:
function GetUnitsInRangeOfLocMatching takes real radius, location whichLocation, boolexpr filter returns group
    local group g = CreateGroup()
    call GroupEnumUnitsInRangeOfLoc(g, whichLocation, radius, filter)
    call DestroyBoolExpr(filter)
    return g
endfunction

function GetUnitsInRangeOfLocAll takes real radius, location whichLocation returns group
    return GetUnitsInRangeOfLocMatching(radius, whichLocation, null)
endfunction


т.е. обьект создает и неудаляется

еще раз самое главное - параметры в ФорГроуп передаются через глобалки
Старый 28.03.2008, 10:25
Kenshi245

offline
Опыт: 2,252
Активность:
А зачем они создает еще одну группу?
local group g = CreateGroup()
и что здесь значит call DestroyBoolExpr(filter)?
Старый 28.03.2008, 11:13
J
expert
offline
Опыт: 48,447
Активность:
Цитата:
и что здесь значит call DestroyBoolExpr(filter)?

Это действие удаляет фильтер функцию...
но если подумать то это делать не такуж и обязательно
Старый 28.03.2008, 13:53
adic3x

offline
Опыт: 108,439
Активность:
Цитата:
А зачем они создает еще одну группу

они не шарят=/
Старый 28.03.2008, 15:53
J
expert
offline
Опыт: 48,447
Активность:
Цитата:
А зачем они создает еще одну группу?

Это упрощает работу с этими функциями через GUI
Старый 28.03.2008, 16:58
Kenshi245

offline
Опыт: 2,252
Активность:
а как мне присвоить переменной группу в радиусе, не используя близовскую функцию GetUnitsInRangeOfLocMatching, и чтоб было граммотно и без утечек памяти?
Старый 28.03.2008, 18:34
J
expert
offline
Опыт: 48,447
Активность:
call GroupEnumUnitsInRange(g, X, Y, radius, filter)
это самый оптимальный вариает, принимает группу и запихивает в нее юнитов в радиусе от указаной точки (X, Y)
Старый 28.03.2008, 19:26
Kenshi245

offline
Опыт: 2,252
Активность:
GroupEnumUnitsInRangeOfLoc - а этот вроде тоже стандартный, мне по координатам просто не удобно, если потом локацию удалить то, наверное утечки и не будет вовсе...

local location loc = GetUnitLoc(GetTriggerUnit())
local group groupA = CreateGroup()
call GroupEnumUnitsInRangeOfLoc(groupA, loc, 300, null) <- ошибку выдает

Отредактировано Kenshi245, 28.03.2008 в 19:50.
Старый 28.03.2008, 19:42
J
expert
offline
Опыт: 48,447
Активность:
Во первых надо так:

local group groupA = CreateGroup()
call GroupEnumUnitsInRange(groupA, GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()), 300, null)

во вторых чтобы адольф не плакал можеш сдлеать глабальную группу
в третих ошибки нет, ищи проблему гдето рядом в коде

Jon добавил:
учись работать с координатами, точки это не по трукодерски
Старый 28.03.2008, 20:04
Kenshi245

offline
Опыт: 2,252
Активность:
Всеравно ошибку выдает, именно когда вставляю этот код. (((
Expected a code statement
Старый 28.03.2008, 20:12
J
expert
offline
Опыт: 48,447
Активность:
выложи всю функцию в которой используеш этот код
Старый 28.03.2008, 20:18
Kenshi245

offline
Опыт: 2,252
Активность:
Ошибка была в том, что я после всего этого объявил еще несколько переменных, не знал, что так нельзя.
Старый 28.03.2008, 20:51
adic3x

offline
Опыт: 108,439
Активность:
кста напомню что оно часто ругаеться не на ту строку, к примеру если ошибка в строке 19, то оно может ругать на 20, на 18 и т.д.
Старый 28.03.2008, 21:55
Ответ

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

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

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

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



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