Как привязать один юнит к другому - чтобы при смерте одного умирал и другой. Связываются они способностью. Таких войск на карте очень много. Повторяться они не будут.

Принятый ответ

Extremator, эмм, перебирать всех юнитов это тупо. Есть же хэш-таблица.
А как сделать хэш-таблицей?
Могу предположить, что это будет работать так, на примере созданных юнитов: Так то любых можно добавить, наступивших в область, убивших и так далее
    ...
    local unit UNIT_1=CreateUnitAtLoc(Player(0),'hfoo',REGION, bj_UNIT_FACING)
    local unit UNIT_2=CreateUnitAtLoc(Player(0),'hfoo',REGION2, bj_UNIT_FACING)
    ...
	//Сохраняем пару по уникальному id первого Объекта
    call SaveUnitHandle(HASH_TABLE,GetHandleId(UNIT_1),1,UNIT_1)
    call SaveUnitHandle(HASH_TABLE,GetHandleId(UNIT_1),2,UNIT_2)
    //Сохраняем пару по уникальному id второго Объекта
    call SaveUnitHandle(HASH_TABLE,GetHandleId(UNIT_2),1,UNIT_2)
    call SaveUnitHandle(HASH_TABLE,GetHandleId(UNIT_2),2,UNIT_1)
    ...
	//Условие
    if GetDyingUnit()=='hfoo' or (GetOwningPlayer(GetDyingUnit()) == Player(PLAYER_NEUTRAL_AGGRESSIVE)) then
		//Загружаем по уникальному ID умирающего юнита его вторую половинку)
        call KillUnit(LoadUnitHandle(HASH_TABLE, GetHandleId(GetDyingUnit()), 2)
    endif
...
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
2
29
1 год назад
2
...которая медленнее
Получить однно значение из ХТ медленнее перебора массива непонятной длины?
0
27
1 год назад
0
...которая медленнее
какую-то чушь сказал_)
поиск ключа циклом намного медленнее хэштаблицы
1
3
1 год назад
1
Extremator, эмм, перебирать всех юнитов это тупо. Есть же хэш-таблица.
А как сделать хэш-таблицей?
Могу предположить, что это будет работать так, на примере созданных юнитов: Так то любых можно добавить, наступивших в область, убивших и так далее
    ...
    local unit UNIT_1=CreateUnitAtLoc(Player(0),'hfoo',REGION, bj_UNIT_FACING)
    local unit UNIT_2=CreateUnitAtLoc(Player(0),'hfoo',REGION2, bj_UNIT_FACING)
    ...
	//Сохраняем пару по уникальному id первого Объекта
    call SaveUnitHandle(HASH_TABLE,GetHandleId(UNIT_1),1,UNIT_1)
    call SaveUnitHandle(HASH_TABLE,GetHandleId(UNIT_1),2,UNIT_2)
    //Сохраняем пару по уникальному id второго Объекта
    call SaveUnitHandle(HASH_TABLE,GetHandleId(UNIT_2),1,UNIT_2)
    call SaveUnitHandle(HASH_TABLE,GetHandleId(UNIT_2),2,UNIT_1)
    ...
	//Условие
    if GetDyingUnit()=='hfoo' or (GetOwningPlayer(GetDyingUnit()) == Player(PLAYER_NEUTRAL_AGGRESSIVE)) then
		//Загружаем по уникальному ID умирающего юнита его вторую половинку)
        call KillUnit(LoadUnitHandle(HASH_TABLE, GetHandleId(GetDyingUnit()), 2)
    endif
...
Принятый ответ
0
29
1 год назад
0
Smeto, зачем на юнита сохранять хэндл этого же юнита? Да и условие можно убрать, а поиск второй половинки засунуть в триггер смерти юнита.
0
3
1 год назад
Отредактирован Smeto
0
Smeto, зачем на юнита сохранять хэндл этого же юнита? Да и условие можно убрать, а поиск второй половинки засунуть в триггер смерти юнита.
Не совсем понял тебя, если ты про GetHandleId(UNIT_Х), нам же нужен уникальный ключ, который не будет повторяться и по которому мы будем находить второго юнита, поэтому у двух разных Юнитов ключ первого и так же наоборот. Грубо говоря, два ключа)
Я же сохраняю первого юнита под его же id и второго же под id первого и так же наоборот для того чтоб отследить по id умирающего второго юнита, потому что если умрет первый, а у второго будет другой хэндл в ключе, то мы второго не найдём.
А условие я прописал для того чтоб не всех подряд проверял, автор же не уточнял каких крипов проверять
Может я что то не понимаю, то подправь меня пожалуйста)
0
4
1 год назад
Отредактирован DazzleFirst
0
Делаем триггер на него вешаем бойцов и смерть бойцов по хэндлу триггера.
Один из них умер - убиваем второго (или двоих). Ну, и не забываем очищать всё. Дабы утечек небыло.
Профит
0
3
1 год назад
0
Делаем триггер на него вешаем бойцов и смерть бойцов по хэндлу триггера.
Один из них умер - убиваем второго (или двоих). Ну, и не забываем очищать всё. Дабы утечек небыло.
Профит
Допустим, одновременно 50 пар на карте, профит будет в создании 50 триггеров и удалении их? Мне вот не понятно, если это один триггер, как отличить допустим первую пару от второй и так далее?)
0
29
1 год назад
Отредактирован nazarpunk
0
Smeto, смотри, на хэндл юнита A вещаем хэндл юнита B. На хэндл юнита B вешаем хэндл юнита A.
При смерти одного из них убиваем второго.
Ты же на хэндл юнита A вешаеш хэндл юнита A. Зачем? Его же можно получить через GetUnitHandle().
Другой момент, что таким образом к одному юниту можно привязать только одного юнита. Для более сложных взаимодействий и цепочек связей придётся что-то похитрее городить.

Делаем триггер на него вешаем бойцов и смерть бойцов по хэндлу триггера.
Один из них умер - убиваем второго (или двоих). Ну, и не забываем очищать всё. Дабы утечек небыло.
Профит
Не вижу смысла в динамических триггерах, ибо всёравно с хэндлами возиться, а задача спокойно и с одним триггером решается.
0
3
1 год назад
0
Smeto, смотри, на хэндл юнита A вещаем хэндл юнита B. На хэндл юнита B вешаем хэндл юнита A.
При смерти одного из них убиваем второго.
Ты же на хэндл юнита A вешаеш хэндл юнита A. Зачем? Его же можно получить через GetUnitHandle().
Другой момент, что таким образом к одному юниту можно привязать только одного юнита. Для более сложных взаимодействий и цепочек связей придётся что-то похитрее городить.

Делаем триггер на него вешаем бойцов и смерть бойцов по хэндлу триггера.
Один из них умер - убиваем второго (или двоих). Ну, и не забываем очищать всё. Дабы утечек небыло.
Профит
Не вижу смысла в динамических триггерах, ибо всёравно с хэндлами возиться, а задача спокойно и с одним триггером решается.
Спасибо за разбор )
Ты прав делал лишние действие)
😎Зацени😎:
Если больше юнитов допустим, трое связанных, то работать с параметром *set custom value*)
Пришла идея в голову:)
Целочисленная переменная Index, для того что избежать повторов пар из трёх юнитов)
Set custom value Unit1,Unit2,Unit 3=Index
SaveUnitHandle(HASH_TABLE,Index,1,U1)
SaveUnitHandle(HASH_TABLE,Index,2,U2)
SaveUnitHandle(HASH_TABLE,Index,3,U3)
Set Index++
…
Юнит умер:
local unit u
set bj_forLoopAIndex=1
loop 
exitwhen bj_forLoopAIndex>3
set u=LoadUnitHandle(HASH_TABLE,GetUnitPointValue(GetDyingUnit()), bj_forLoopAIndex)
If u=Живой then 
     call KillUnit(u) 
Endif
bj_forLoopAIndex++
endloop
    
...
0
29
1 год назад
0
Если больше юнитов допустим, трое связанных, то работать с параметром *set custom value*)
CustomValue лучше не использовать. Уж очень многие системы пытаются в него писать. Коль уже используется ХТ, то лучше на хэндл юнита дополнительно integer сохранить. Разница в одну строчку, зато точно ничего не сломается.
set bj_forLoopAIndex=1
Зачем юзать глобалку? integer i = 1 ничем не хуже.
0
29
1 год назад
0
native UnitAlive takes unit u returns boolean

//! zinc
    library DeathTie {
        hashtable HT = InitHashtable();
        key K;
        
        function onInit() {
            integer i;
            trigger ts = CreateTrigger();
            trigger td = CreateTrigger();
            player p;
    
            for (0 <= i < bj_MAX_PLAYER_SLOTS) {
                p = Player(i);
                TriggerRegisterPlayerUnitEvent(ts, p, EVENT_PLAYER_UNIT_SPELL_EFFECT, null);
                TriggerRegisterPlayerUnitEvent(td, p, EVENT_PLAYER_UNIT_DEATH, null);
            }

            // spell
            TriggerAddCondition(ts, Filter(function() -> boolean {
                return GetSpellAbilityId() == 'Ainf';
            }));

            TriggerAddAction(ts, function() {
                unit caster = GetTriggerUnit();
                unit target = GetSpellTargetUnit();
                integer cid = GetHandleId(caster);
                integer tid = GetHandleId(target);
                SaveUnitHandle(HT, cid, K, tid);
                SaveUnitHandle(HT, tid, K, cid);
                caster = null;
                target = null;
            });

            // die
            TriggerAddAction(td, function() {
                unit u = GetTriggerUnit();
                integer uid = GetHandleId(u);
                unit t;
                
                if (HaveSavedHandle(HT, uid, K)) {
                    t = LoadUnitHandle(HT, uid, K);
                    if (UnitAlive(t)) {
                        KillUnit(t);
                    }
                }

                u = null;
                t = null;

            });

            // leaks
            ts = null;
            td = null;
        }

    }

//! endzinc
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.