Добавлен , опубликован
Алгоритмы, Наработки и Способности
Способ реализации:
cJass
Тип:
Наработка
Версия Warcraft:
1.26а
Наработка, сохраняющая последний приказ юнита и позволяющая его отдавать.
Чтобы отдать приказ обратитесь к функции GiveSavedOrder(unit u).
call GiveSavedOrder(GetTriggerUnit()) //Пример.
GetTriggerUnit() ссылается на юнита, который активирует событие триггера. Вы можете заменить это на любую переменную типа unit, но не забывайте что глобальные переменные, объявленные в редакторе, имеют приставку udg_
Вы также можете указать, чтобы следующий приказ юнита не сохранялся, для этого вызовите функцию NoSaveOrder(unit u).
call NoSaveOrder(GetTriggerUnit()) //Пример.
Нужно для того, чтобы не сохранять не нужные приказы. Например, при перемещении юнита.
Установка
  • Скопируйте триггер SavingOrder.
История обновлений
v1.1
  • Исправлен баг.
v2.0
  • Код полностью написан с нуля.
  • Теперь не использует UnitUserDara.
  • Убран лимит юнитов.
  • Исправлены мелкие баги.
  • Добавлен отладочный мод.
  • Работает через хэш-таблицу, вместо массивов.
  • Имитирует произвольный приказ атаки.
  • Функции и переменные стали приватными.
  • Сохраняет только приказы smart, attack, move, harvest, holdposition, stop.
Код

library SavingOrder initializer svInit
        
    private constant integer orderNoSave_id = 0 //сохранять ли следующий приказ.
    private constant integer orderID_id = 1 //cохранённый ID приказа.
    private constant integer orderWidget_id = 2 //Цель приказа.
    private constant integer orderX_id = 3 //x координата приказа.
    private constant integer orderY_id = 4 //y координата приказа.
    private constant integer orderPoint_id = 5
    private constant integer orderTarget_id = 6
    private constant integer stop = 851972
    private constant integer attack = 851983
    private constant integer move = 851986
    private constant integer smart = 851971
    private constant integer harvest = 852018
    private constant integer holdposition = 851993
    private trigger svTrigger //триггер сохранения приказов.
    private hashtable HT //хэш-таблица.
    private boolean dbg = false //отладочный мод.
    
    private nothing dbgXY( string s, real x, real y ) { // Создает отладочный текст по координатам.
        texttag tt
        tt = CreateTextTagLocBJ( s, null, 0, 10, 60, 60, 100, 20 )
        SetTextTagPos( tt, x + GetRandomReal( -20, 20 ), y + GetRandomReal( -20, 20 ), 0 )
        SetTextTagPermanent( tt, false )
        SetTextTagLifespan( tt, 1.60 )
        SetTextTagFadepoint( tt, 0.80 )
        SetTextTagVelocityBJ( tt, 80.00, 90.00 )
        tt = null
    }
    
    nothing NoSaveOrder( unit u ) {
        integer id = GetHandleId(u)
        SaveInteger( HT, id, orderNoSave_id, 1 )
        u = null
    }
    
    nothing GiveSavedOrder( unit u ) { // Отдает последний сохранённый приказ или приказ "стоп". Приказ стоп отдается в том случае, если orderID = 0.
        DisableTrigger( svTrigger )
        integer id = GetHandleId( GetTriggerUnit() )
        integer orderID = LoadInteger( HT, id, orderID_id )
        real orderX = LoadReal( HT, id, orderX_id )
        real orderY = LoadReal( HT, id, orderY_id )
        widget orderWidget = LoadWidgetHandle( HT, id, orderWidget_id )
        if orderID == 0 {
            SaveReal( HT, id, orderX_id, 0 )
            SaveReal( HT, id, orderY_id, 0 )
            orderX = 0
            orderY = 0
            SaveInteger( HT, id, orderID_id, stop )
            orderID = stop
            SaveWidgetHandle( HT, id, orderWidget_id, null )
            orderWidget = null
        } 
        if LoadBoolean( HT, id, orderPoint_id) == true {
            IssuePointOrderById( u, orderID, orderX, orderY )
            if dbg { dbgXY( OrderId2StringBJ(orderID) + " X" + I2S(R2I(orderX)) + " Y" + I2S(R2I(orderY)), orderX, orderY ) }
        } elseif LoadBoolean( HT, id, orderTarget_id) == true {
            IssueTargetOrderById( u, orderID, orderWidget )
            if dbg { dbgXY( OrderId2StringBJ(orderID) + " tX" + I2S(R2I(GetWidgetX(orderWidget))) + " tY" + I2S(R2I(GetWidgetY(orderWidget))), GetWidgetX(orderWidget), GetWidgetY(orderWidget) ) }
        } else {
            IssueImmediateOrderById( u, orderID)
            if dbg { dbgXY( OrderId2StringBJ(orderID), GetWidgetX(u), GetWidgetY(u) ) }
        }
        u = null
        EnableTrigger( svTrigger )
    }
    
    private nothing svAttack(){ // Сохраняет приказ, когда юнит атакует произвольно, а прошлый приказ был перейти в точку.
        unit u = GetAttacker()
        integer id = GetHandleId(u)
        integer orderNoSave = LoadInteger( HT, id, orderNoSave_id )
        if orderNoSave == 0 {
            real orderX = LoadReal( HT, id, orderX_id )
            real orderY = LoadReal( HT, id, orderY_id )
            if ( orderX != 0 ) and ( orderY != 0 ) {
                SaveBoolean( HT, id, orderPoint_id, false)
                SaveBoolean( HT, id, orderTarget_id, true)
                SaveInteger( HT, id, orderID_id, attack )
                SaveWidgetHandle( HT, id, orderWidget_id, GetTriggerUnit() )
                SaveReal( HT, id, orderX_id, 0 )
                SaveReal( HT, id, orderY_id, 0 )
                if dbg { dbgXY( "attack++" + " | id=" + I2S(id), GetUnitX(u), GetUnitY(u) ) }
            }
        } else {
            SaveInteger( HT, id, orderNoSave_id, 0 )
        }
        u = null
    }
    
    private nothing svActions(){ // Сохраняет отданный приказ.
        integer id = GetHandleId( GetTriggerUnit() )
        integer orderNoSave = LoadInteger( HT, id, orderNoSave_id )
        if orderNoSave == 0 {
            integer ord = GetIssuedOrderId() 
            if ( ord == stop) or ( ord == attack ) or ( ord == move ) or ( ord == holdposition ) or ( ord == smart ) or ( ord == harvest ) {
                if GetWidgetLife(GetOrderTarget()) <= 0. {
                    SaveBoolean( HT, id, orderTarget_id, false)
                } else {SaveBoolean( HT, id, orderTarget_id, true)}
                if GetOrderPointX() == 0. and GetOrderPointY() == 0. {
                    SaveBoolean( HT, id, orderPoint_id, false)
                } else {SaveBoolean( HT, id, orderPoint_id, true)}
                SaveInteger( HT, id, orderID_id, GetIssuedOrderId() )
                SaveWidgetHandle( HT, id, orderWidget_id, GetOrderTarget() )
                SaveReal( HT, id, orderX_id, GetOrderPointX() )
                SaveReal( HT, id, orderY_id, GetOrderPointY() )
                if dbg { dbgXY(OrderId2StringBJ(GetIssuedOrderId()) + "+ | id=" + I2S(id), GetUnitX(GetTriggerUnit()), GetUnitY(GetTriggerUnit()) ) }
            }
        } else {
            SaveInteger( HT, id, orderNoSave_id, 0 )
        }
    }
    
    
    private nothing svInit(){ // Инициализация.
        HT = InitHashtable()
        
        // Произвольная атака.
        trigger t2 = CreateTrigger()
        TriggerRegisterAnyUnitEventBJ( t2, EVENT_PLAYER_UNIT_ATTACKED )
        TriggerAddAction( t2, function svAttack )
        t2 = null
        
        // Сохранение приказов.
        svTrigger = CreateTrigger()
        TriggerRegisterAnyUnitEventBJ( svTrigger, EVENT_PLAYER_UNIT_ISSUED_TARGET_ORDER )
        TriggerRegisterAnyUnitEventBJ( svTrigger, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER )
        TriggerRegisterAnyUnitEventBJ( svTrigger, EVENT_PLAYER_UNIT_ISSUED_ORDER )
        TriggerAddAction(svTrigger, function svActions )
        
    }
    
endlibrary
`
ОЖИДАНИЕ РЕКЛАМЫ...

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
32
5 лет назад
0
Норм, не давно кстати всё это обсуждали, самый просто реализуемый вариант из возможных
0
19
5 лет назад
Отредактирован KaneThaumaturge
0
Hate, не знаю, пофиксил и заявил на публикацию.
0
26
5 лет назад
0
Чего-то не понял. Вот был приказ юниту от игрока идти, например, в другой конец карты, на полпути юнит триггерно использует высасывание жизни из врага. Потом он продолжит следовать в другой конец карты?
Обычно приказы для способностей без цели не сбивают приказ. Если они отданы игроком, а не триггерно.
0
19
5 лет назад
0
8gabriel8, Да, если ты укажешь какие-то специальные условия и они не выполнятся. Нет, если все условия совпадут. В оригинале нельзя было изменить максимальный уровень пожираемого юнита против игроков. Искусственно создал эти условия. Я просто сбиваю приказ способности, если не подходят условия, и не сбиваю, если все хорошо. Можно было использовать "stop", но в таком случае приказ бы сбивался.
Однако это можно использовать и в других случаях. Сохранение приказа часто нужно.
8gabriel8, xgm.guru/p/100/224658 - сделал после этого вопроса.
1
28
5 лет назад
1
Не нашёл - создал.
Но ведь я кидал неделю назад это.
0
19
5 лет назад
0
PT153, не заметил, из недостатков твоя наработка не ловит приказы способностей.
0
27
5 лет назад
0
А может ли серию приказов с таргетами через шифт запомнить? шифт только мем хаком кажись только наверн
0
32
5 лет назад
0
Steal nerves, самое стремное что любой приказ через IssueXXXOrder сбивает всю очередь, только стан умеет сдвигать всю очередь и сувать свой приказ. Но это можно абузить.
0
19
5 лет назад
0
Steal nerves, можно было бы такое сделать, но я делаю без мемхака, т.к хочу безболезненно адаптировать карту и под новую версию.
0
19
5 лет назад
0

Обновление v2.0

  • Код полностью написан с нуля.
  • Теперь не использует UnitUserDara.
  • Убран лимит юнитов.
  • Исправлены мелкие баги.
  • Добавлен отладочный мод.
  • Работает через хэш-таблицу, вместо массивов.
  • Имитирует произвольный приказ атаки.
  • Функции и переменные стали приватными.
  • Сохраняет только приказы smart, attack, move, harvest, holdposition, stop.
Если руки дойдут, то и бары обновлю, а то они с багом уже месяц висят.
1
28
5 лет назад
1
Сохраняет только приказы smart, attack, move, harvest, holdposition, stop.
А ведь недавно ты мою систему ругал, что она приказы способностей не сохраняет)
не заметил, из недостатков твоя наработка не ловит приказы способностей.
В этот список ещё можно добавить приказы attackonce и attackground.
GetOrderPointX() == 0. and GetOrderPointY() == 0.
Ведь не факт, что это означает, что приказ не является приказом в точку.
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.