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

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

Закрытая тема
 
playerzorg

offline
Опыт: 214
Активность:
Стрела и хеш-таблицы
Сделал способность стрелы в JassNewGenPack на патче 1.24 карта запускается, способность не работает, может хэштаблицами нужно по другому пользоваться?) Непонятно
Нестандартный код
	globals
		timer T1m      =null
		hashtable h1T  =null
		integer I1g    =1
		gamecache G1C  =null
		boolean B1e    =false
		boolean B2e    =false
		integer I2g    =0
		integer I3g    =0
		trigger T1g    =null
		destructable array D1b
		destructable array D2b
		destructable array D3b
		trigger array T1gA
		real array R1e
	endglobals

function H2I takes handle h returns integer
	return GetHandleId(h)
endfunction

function PolarProjectionX takes real x, real distance, real angle returns real
    return x+distance*Cos(angle * (3.14159/180.0))
endfunction

function PolarProjectionY takes real y, real distance, real angle returns real
    return y+distance*Sin(angle * (3.14159/180.0))
endfunction

function KillWood takes nothing returns nothing
    if GetDestructableTypeId(GetEnumDestructable()) == 'ATtr' or GetDestructableTypeId(GetEnumDestructable()) == 'VTlt' then
    call KillDestructable(GetEnumDestructable())
    endif
endfunction
Код способности:
function Trig_FastArrow_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00V'
endfunction

function Barrier takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit c = LoadUnitHandle(h1T, H2I(t), StringHash("Arrow"))
    local unit q = LoadUnitHandle(h1T, H2I(t), StringHash("Caster"))
    if GetDestructableTypeId(GetEnumDestructable()) == 'YTpb' and DistanceBetweenPoints(GetUnitLoc(c),GetUnitLoc(q))>=256 then
    call SetUnitUserData(c, 1)
    endif
endfunction

function MoveArrow takes nothing returns nothing
//Vars
    local timer t    = GetExpiredTimer()
    local real angle = LoadReal(h1T, H2I(t), StringHash("Angle"))
    local unit b     = LoadUnitHandle(h1T, H2I(t), StringHash("Caster"))
    local unit c     = LoadUnitHandle(h1T, H2I(t), StringHash("Arrow"))
    local integer i  = LoadInteger(h1T, H2I(t), StringHash("Time"))
    local real z     = LoadReal(h1T, H2I(t), StringHash("Height"))
    local group g    = LoadGroupHandle(h1T, H2I(t), StringHash("Group"))
    local group gl = CreateGroup()
    local unit u
//***************************************************************************
    call GroupEnumUnitsInRangeOfLoc(gl, GetUnitLoc(c), 90, null)
    loop
        set u = FirstOfGroup(gl)
        call GroupRemoveUnit(gl, u)
        exitwhen u == null
        if IsUnitEnemy(u, GetOwningPlayer(c)) and IsUnitType(u, UNIT_TYPE_STRUCTURE) == false and IsUnitDeadBJ(u) == false and GetUnitUserData(u) != 1 then
        call SetUnitUserData(u, 1)
        call GroupAddUnit(g,u)
        call UnitDamageTarget(b, u, 120, true, true, ATTACK_TYPE_PIERCE, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
        endif
    endloop
    call SaveGroupHandle(h1T, H2I(t), S2I("Group"), g)
//***************************************************************************

//===========================================================================
// Перемещение стрелы
//===========================================================================
    call SetUnitPosition(c, PolarProjectionX(GetUnitX(c), 45, angle), PolarProjectionY(GetUnitY(c), 45, angle))
    call SetUnitFacing(c,angle)
    call SaveInteger(h1T, H2I(t), StringHash("Time"), i+1)
    set u = CreateUnitAtLoc(GetOwningPlayer(c), 'e005', GetUnitLoc(c), 0)
    call UnitApplyTimedLife(u, 'BTLF', 1-i*0.02)
    call SetUnitPathing(u,false)
    call SetUnitPositionLoc(u,GetUnitLoc(c))
//***************************************************************************

//===========================================================================
// Уничтожение леса
//===========================================================================
    call EnumDestructablesInCircleBJ( 90, GetUnitLoc(c), function KillWood )
//***************************************************************************

//===========================================================================
// Вычисление препятсвий
//===========================================================================
    call EnumDestructablesInCircleBJ( 45, GetUnitLoc(c), function Barrier )
//***************************************************************************

//===========================================================================
// Проверка
//===========================================================================
    if i>35 or GetLocationZ(GetUnitLoc(c))>z+60 or GetUnitUserData(c) == 1 then
        loop
            set u = FirstOfGroup(g)
            call GroupRemoveUnit(g, u)
            call SetUnitUserData(u, 0)
            exitwhen u == null
        endloop
        call DestroyGroup(g)
        call DestroyGroup(gl)
        call KillUnit(c)
        call FlushChildHashtable(h1T, H2I(t))
        call PauseTimer(t)
        call DestroyTimer(t)
    endif
endfunction

function Trig_FastArrow_Actions takes nothing returns nothing
    local timer t = CreateTimer()
    local unit u = GetTriggerUnit()
    local real angle = Atan2(GetLocationY(GetSpellTargetLoc()) - GetLocationY(GetUnitLoc(u)), GetLocationX(GetSpellTargetLoc()) - GetLocationX(GetUnitLoc(u)))*180.0/3.14159
    local unit arrow = CreateUnitAtLoc(GetOwningPlayer(u), 'e001', GetUnitLoc(u), angle)
    local real z = GetLocationZ(GetUnitLoc(u))
    local group g = CreateGroup()
    set h1T = InitHashtable()
    call SetUnitPathing(arrow,false)
    call SaveUnitHandle(h1T, H2I(t), StringHash("Caster"), GetTriggerUnit())
    call SaveUnitHandle(h1T, H2I(t), StringHash("Arrow"), arrow)
    call SaveGroupHandle(h1T, H2I(t), StringHash("Group"), g)
    call SaveReal(h1T, H2I(t), StringHash("Angle"), angle)
    call SaveReal(h1T, H2I(t), StringHash("Height"), z)
    call SaveInteger(h1T, H2I(t), StringHash("Time"), 0)
    call TimerStart(t,0.02,true,function MoveArrow)
endfunction

//===========================================================================
function InitTrig_FastArrow takes nothing returns nothing
    set gg_trg_FastArrow = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_FastArrow, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_FastArrow, Condition( function Trig_FastArrow_Conditions ) )
    call TriggerAddAction( gg_trg_FastArrow, function Trig_FastArrow_Actions )
endfunction

Отредактировано playerzorg, 10.08.2009 в 18:10.
Старый 10.08.2009, 15:39
JimALIEN
вдупляет sc2 editor
offline
Опыт: 7,176
Активность:
playerzorg, ятп вместо H2I() надо бы теперь использовать GetHandleId()
Старый 10.08.2009, 16:24
playerzorg

offline
Опыт: 214
Активность:
Забыл написать) В нестандартном коде H2I у меня выглядит так
function H2I takes handle h returns integer
return GetHandleId(h)
endfunction
Карта на новом патче 1.24 запускается отлично, но при использовании способности появляется только стрела и всё
Старый 10.08.2009, 16:29
ShadoW DaemoN

offline
Опыт: 37,078
Активность:
playerzorg, ты используешь неверную функцию для получения числа из строки. Нужно использовать не S2I("строка"), а StringHash("строка").
В твоем коде все параметры записываются на один и тот же адрес - [H2I(timer), 0], а согласно определению хеш-таблиц, при записи объекта на одну и ту же пару чисел, предыдущий объект будет перезаписан.
Кстати, ты два раза инициализируешь хеш-таблицу - один раз при объявлении, другой раз в спелле.
Старый 10.08.2009, 16:33
playerzorg

offline
Опыт: 214
Активность:
ShadoW DaemoN, спасибо)) круто, заработало)) в общем я изменил с S2I("строка") на StringHash("строка"), а для того чтобы каждое значение не перезаписывало друг друга прибавил к H2I(timer) StringHash("строка") вот например
сохранение call SaveUnitHandle(h1T, H2I(t)+StringHash("Caster"), StringHash("Caster"), GetTriggerUnit())
загрузка LoadUnitHandle(h1T, H2I(t)+StringHash("Caster"), StringHash("Caster"))
Только есть вопрос нет ли тут утечек или багов каких-нибудь, которые будут тормозить игру, может есть способ лучше?
Инициализирование хештаблицы при объявлении убрал
playerzorg добавил:
При одновременном использовании способности перестаёт работать, одна из стрел зависает и не удаляется

Отредактировано playerzorg, 10.08.2009 в 17:00.
Старый 10.08.2009, 17:25
ToChilo
■□□□□
offline
Опыт: 356
Активность:
еще посли использования хэша неплохо бы чистить его от устаревших значений
Старый 10.08.2009, 17:39
playerzorg

offline
Опыт: 214
Активность:
у меня выдаёт ошибку когда я его чищу Too Many arguments passed to function
        call FlushParentHashtable(h1T, H2I(t)+StringHash("Angle"))
        call FlushParentHashtable(h1T, H2I(t)+StringHash("Height"))
        call FlushParentHashtable(h1T, H2I(t)+StringHash("Time"))
        call FlushParentHashtable(h1T, H2I(t)+StringHash("Arrow"))
        call FlushParentHashtable(h1T, H2I(t)+StringHash("Caster"))
        call FlushParentHashtable(h1T, H2I(t)+StringHash("Group"))
ну или вместо этого вставляю
	set h1T = null
ошибка не выскакивает, но в игре всё равно остаётся зависание и неудаление стрелы при одновременном использовании способности двумя или более юнитами
Старый 10.08.2009, 17:46
ShadoW DaemoN

offline
Опыт: 37,078
Активность:
playerzorg, ты меня неправильно понял. Я говорил, что если пара ключей совпадет, а не какой-то один совпадет. StringHash() выдает для разных строк разные значения.
    call SaveUnitHandle(h1T, H2I(t), StringHash("Caster"), GetTriggerUnit())
    call SaveUnitHandle(h1T, H2I(t), StringHash("Arrow"), arrow)
    call SaveGroupHandle(h1T, H2I(t), StringHash("Group"), g)
    call SaveReal(h1T, H2I(t), StringHash("Angle"), angle)
    call SaveReal(h1T, H2I(t), StringHash("Height"), z)
    call SaveInteger(h1T, H2I(t), StringHash("Time"), 0)
Так что не нужно к первому ключу что-то приплюсовывать.
Чистить так:
    call FlushChildHastable(h1T, H2I(t))
Я уж молчу про то, что код написан плохо и с утечками
Старый 10.08.2009, 17:54
playerzorg

offline
Опыт: 214
Активность:
в игре всё равно остаётся стрела при одновременном использовании способности двумя или более юнитами(Ответьте кто-нибудь из-за чего этот бред!?), я обновил код вначале страницы, бред в общем какой-то)
Может у кого-нибудь есть карта где наглядно показано как пользоваться хэштаблицами?

Отредактировано ShadoW DaemoN, 10.08.2009 в 22:42.
Старый 10.08.2009, 18:12
Ranger21
I love beatiul days XD
offline
Опыт: 13,274
Активность:
Наслаждайся и не парься насчёт хеш-таблиц
Работает MUI( мультиприменима большим количеством юнитов)
Прикрепленные файлы
Тип файла: w3x Arrow.w3x (22.3 Кбайт, 23 просмотров )
Старый 10.08.2009, 22:08
playerzorg

offline
Опыт: 214
Активность:
Во Круто))) Спасибо! а таким же способом я могу на своей карте все спеллы делать?
Старый 10.08.2009, 22:22
Ranger21
I love beatiul days XD
offline
Опыт: 13,274
Активность:
playerzorg, Можешь, если ты разберёшься в структурах. Правда я на XGM статей не видел грамотных по ним... может у кого-нибудь есть.
Старый 10.08.2009, 22:25
Закрытая тема

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

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

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

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



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