Увеличение запаса здоровья героя
Можно ли реализовать триггерно увеличение максимального запаса здоровья героя на определённое значение(не фиксированное) ?
Пока придумал, но не реализовал, вариант добавлять к макс. здоровью книгами Трактат жизни +1HP N-колличество штук.

Лучший ответ:
Extremator, Интересно, любой последующий каст устанавливает заново значение максимального хп, то есть оно даже меньше может стать, мне нужно чтобы бонусы стакались.
Это для установки текущего бонуса ХП.
Если ты хочешь увеличивать значение, то нужно сделать получение текущего значения.
Т.е. выглядеть будет как с лечением:
Установить бонус ХП как (текущий бонус ХП + число)
Для получения надо либо напрямую считывать данные: циклом пройтись и за каждую абилку добавить её значение к переменной, тем самым нарастив её обратно (напротив с тем что при установке её значения она наоборот расходовалась). getHP
Либо просто хранить БД с юнитами, которым было изменено ХП (т.е. внести их в систему юнит-число)
И, получив число, изменить это число в нужную сторону и выполнить установку setHP
. . . 10 минут спустя ...
Вот как-то так - setHP_16k.w3x
Добавил триггер getHP для получения числа, как и описал выше.
И чуть переделал тест скиллом (даёт рандомно от +1 до +100).
По сути, может давать и отрицательные числа, но упрётся в 0
Для этого надо добавить работу с число -32768



Просмотров: 475

» Лучшие комментарии


XGM Bot #1 - 2 месяца назад 3
Похожие вопросы:

» ответ
есть вопрос про изменение хп героя
в редакторе есть действие arifmetic
остается сложить одно с другим

easypeasy #3 - 2 месяца назад -4
Hate, Это для меня сложно, не gui
8gabriel8 #4 - 2 месяца назад 5
Можно сделать несколько вариантов способности Камня жизни, например, +1, +2, +4, +8, +16, +32, +64, +128, +256 и так далее. В разных сочетаниях они дадут любое число, которое необходимо. Но как делать алгоритм, по которому выдавать нужные способности, запамятовал)
Ранее придумывал систему с другими числами, которые не являются степенью двойки, но в мае накрылся жёсткий диск, а заново придумывать не имею цели.
easypeasy #5 - 2 месяца назад 0
8gabriel8, а можно сделать 4 способности, каждая с 10 уровнями. Первая добавляет еденицы, другая десятки, третья сотни и 4-ая - тясячи? Рассчитать какие дать из этих способностей и какого уровня я смогу, только не могу понять как перед дачей этой абилки выставить для неё нужный уровень.
Nelloy #6 - 2 месяца назад -3
easypeasy, вполне рабочее решение. Нельзя установить уровень способности до того как она будет получена юнитом. Поэтому сначала вручаем способность, потом устанавливаем ее уровень у данного юнита.
pro100master #7 - 2 месяца назад (отредактировано ) 0
есть же баг вручаем абилку с 4 уровней
1 ур - 0 хп
2 ур - 1 хп
3 ур - 2 хп
4 ур - 4 хп
как мы вручаем и меняем уровень если 4 хп и удаляем а хп не теряет...
а расчет вроде
» внутри код
library StateMax initializer init requires CoreState, optional AbilityPreload, optional xepreload
    globals
        private integer array powersOf2
        private integer powersOf2Count = 1
    endglobals

    struct StateMax extends TypeState
        private unitstate us = null
        private integer id = 0
        private integer count = 0
        
        public static method create takes integer id, unitstate us, integer count returns thistype
            local thistype this = thistype.allocate(0, 0)
            local integer i
            
            set this.id = id
            set this.us = us
            set this.count = count
        
            // Grow powers of 2
            if powersOf2Count < count then
                set i = powersOf2Count
                loop
                    exitwhen i == count * 2 * 2 * 3 + 1
                    
                    set powersOf2[i] = 2 * powersOf2[i - 1]

                    set i = i + 1
                endloop
                set powersOf2Count = count
            endif
            
            static if xe_PRELOAD_ABILITIES then
                call AbilityRangePreload(id, id + count * 2 - 1)
            endif
            
            return this
        endmethod
        
        method operator[]= takes unit u, real amount returns nothing
            local integer rawcode = this.id
            local integer abilityId
            local integer abilityLevel
            local integer currentAbility
            
            set amount = R2I(amount) - R2I(this[u])
            
            if amount < 0 then
                set amount = -amount
                set rawcode = rawcode + this.count
            endif
            
            set abilityId = this.count - 1
            set abilityLevel = 4
            set currentAbility = rawcode + abilityId
            loop
                exitwhen amount == 0
                
                if amount >= powersOf2[abilityId * 3 + (abilityLevel - 2)] then
                    call UnitAddAbility(u, currentAbility)
                    call SetUnitAbilityLevel(u, currentAbility, abilityLevel)
                    call UnitRemoveAbility(u, currentAbility)
                    
                    set amount = amount - powersOf2[abilityId * 3 + (abilityLevel - 2)]
                else
                    set abilityLevel = abilityLevel - 1
                    if abilityLevel <= 1 then
                        set abilityId = abilityId - 1
                        set abilityLevel = 4
                        set currentAbility = rawcode + abilityId
                    endif
                endif
            endloop
        endmethod
        
        method operator[] takes unit u returns real
            return GetUnitState(u, this.us)
        endmethod
    endstruct
    
    //! textmacro StateMaxStart takes CREATE_ABILITIES
        function StateMaxSetup takes nothing returns nothing
        /*
        //! externalblock extension=lua ObjectMerger $FILENAME$
        //! i if $CREATE_ABILITIES$ == "true" then
        //! i function CreateAbility(baseAbility, rawcodePrefix, field, abilityCount, name, icon)
        //! i     k = 0
        //! i     for sign = -1, 1, 2 do
        //! i         signStr = "+"
        //! i         if sign < 0 then
        //! i             signStr = "-"
        //! i         end
        //! i         j = 0
        //! i         for i = 0, (abilityCount - 1) * 3, 3 do
        //! i             j = j + 1
        //! i             createobject(baseAbility, rawcodePrefix .. string.sub(chars, k + 1, k + 1))
        //! i             makechange(current, "anam", "StateMax - " .. name)
        //! i             makechange(current, "ansf", "(" .. signStr .. tostring(j) .. ")")
        //! i             makechange(current, "aart", "ReplaceableTextures\\CommandButtons\\" .. icon)
        //! i             makechange(current, "aite", 0)
        //! i             makechange(current, "alev", 4)
        //! i             makechange(current, field, 1, 0)
        //! i             makechange(current, field, 2, 2^(i + 0) * sign)
        //! i             makechange(current, field, 3, 2^(i + 1) * sign)
        //! i             makechange(current, field, 4, 2^(i + 2) * sign)
        //! i             k = k + 1
        //! i         end
        //! i     end
        //! i end
        //! i setobjecttype("abilities")
        //! i chars = "abcdefghijklmnopqrstuvwxyz"
        */
    //! endtextmacro
    
    //! textmacro StateMaxCreate takes NAME, COUNT, PREFIX, SOURCE_ABILITY, FIELD, ICON
        //! i CreateAbility("$ABILITY$", "$PREFIX$", "$FIELD$", $COUNT$, "$NAME$", "$ICON$")
        globals
            TypeState STATE_$NAME$
        endglobals
        set STATE_$NAME$ = StateMax.create('$PREFIX$a', UNIT_STATE_$NAME$, $COUNT$)
    //! endtextmacro
    
    //! textmacro StateMaxEnd
        /*
        //! i end
        //! endexternalblock
        */
        endfunction
    //! endtextmacro
    
    //! runtextmacro StateMaxStart("false")
    //! runtextmacro StateMaxCreate("MAX_LIFE", "3", "ZxL", "AIlf", "Ilif", "BTNHealthStone.blp")
    //! runtextmacro StateMaxCreate("MAX_MANA", "3", "ZxM", "AImz", "Iman", "BTNManaStone.blp")
    //! runtextmacro StateMaxEnd()
        
    private function init takes nothing returns nothing
        set powersOf2[0] = 1
        
        call StateMaxSetup()
    endfunction
endlibrary
KaneThaumaturge #8 - 2 месяца назад 5
easypeasy:
Hate, Это для меня сложно, не gui
Просто используй личный сценарий SetUnitMaxState(unit, UNIT_STATE_MAX_LIFE, R2I(GetUnitState(unit, UNIT_STATE_MAX_LIFE) + (50)))
Например увеличение здоровья на 50 ед.
Вместо unit нужно название переменной вставить, где хранится твой юнит. Только не забудь, что глобалки объявленные через оболочку редактора имеют приставку udg_
pro100master #9 - 2 месяца назад 3
KaneThaumaturge, он сидит на 1.26
KaneThaumaturge #10 - 2 месяца назад 3
pro100master, это функция из наработки, которую он назвал сложной. Я тоже использую 1.26а
Extremator #11 - 2 месяца назад (отредактировано ) 4
Создаёшь ряд абилок для повышения ХП, и делаешь им бонус в виде растущей степени двойки (по +1, +2, +4, +8, +16 и т.д.).
Забиваешь в переменные эти абилки и числа, которым они будут соответствовать (хотя тут можно прибегнуть и к хитрости с вычленением значения из рав-кода абилки... но... кому это надо?).
» типа кодэ
set HP_Ability[1] = 'A001' абилка дающая +16 хп
set HP_Ability[2] = 'A002' абилка дающая +8 хп
set HP_Ability[3] = 'A003' абилка дающая +4 хп
set HP_Ability[4] = 'A004' абилка дающая +2 хп
set HP_Ability[5] = 'A005' абилка дающая +1 хп
set HP_value[1] = 16
set HP_value[2] = 8
set HP_value[3] = 4
set HP_value[4] = 2
set HP_value[5] = 1
Почему запись идёт в обратном порядке? - да просто потому что на GUI цикл считает лишь в одну сторону (хотя можно это обойти, надо лишь понимать что там внутри переменная находится), а на Jass'е можешь с ним творить что угодно, даже вовсе не считать ничего.
Дальше нужен небольшой триггер без события (а в идеале - функция), внутри которого запустится цикл с рядом однообразных проверок и вычислений. Залог успеха - необходимость послать юнита и нужное число в этот триггер. Назовём условно этот триггер как setHP.
Как это будет работать? - В нужном месте записываем юнита и то самое число, которое должно быть установлено как дополнительное здоровье. Тут следует понимать что не получится задать два раза +5 хп и получить в итоге +10 хп, т.к. это установка значения, а не прибавление к текущему имеющемуся в данный момент... но это безусловно решаемый момент, за счёт конструирования дополнительных триггеров-функций которые будут выполнять сложение используя всё необходимое.
» типа кодэ 2
set HP_unit = (твой юнит)
set HP_set = (число)
Триггер - Вызвать триггер setHP (без проверки условий)
Внутри этого триггера (условно setHP) будет содержаться примерно следующее:
» типа кодэ 3
Цикл А от 1 до 5
Если:
Сравнение чисел - HP_set больше или равно HP_value[A]
Тогда:
set HP_set = HP_set - HP_value[A]
Боевая единица - Добавить юниту HP_unit способность HP_Ability[A]
Иначе:
Боевая единица - Отнять у юнита HP_unit способность HP_Ability[A]
set HP_unit = (Нет боевой единицы)
Чуть пояснений:
Число 5 это конечное значение для описанной сейчас "системы", в идеале там должно быть 12-15 значений, хотя можно и больше (и +1 для отрицательных чисел).
Число А это целое для работы цикла. Если ты не знаешь как они работают (циклы/переменные), то всё это тебе объяснять - совсем другой разговор...
Хз что тут ещё добавить...
Clamp #12 - 2 месяца назад 0
Но как делать алгоритм, по которому выдавать нужные способности, запамятовал
Вот тут можно почитать
Когда-то сам допёр до разложения из двоичного представления, но не помню деталей той реализации.
easypeasy #13 - 2 месяца назад 0
Extremator, сложно, но я постараюсь разобраться, спасибо
Raised #14 - 2 месяца назад (отредактировано ) 0
  loop
  exitwhen rest <= 0
    if R2I(Pow(2,power)) > rest then
      set power = power-1
    elseif R2I(Pow(2,power)) <= rest then
      call UnitAddAbility(u,abilityAddHp[power])
      call SetUnitAbilityLevel(u,abilityAddHp[power],2)
      call UnitRemoveAbility(u,abilityAddHp[power])
      set rest = rest-R2I(Pow(2,power))
      set power = power-1
    endif
  endloop
8gabriel8 #15 - 2 месяца назад 0
Clamp:
Когда-то сам допёр до разложения из двоичного представления, но не помню деталей той реализации.
У меня ранее вроде изначально через способности +1, +2 и +5 было сделано, потом прибавлялись ещё какие-то числа, при этом можно было использовать две одинаковые способности, но в целом фишка была в том, что почти для любого числа в пределах 100, хватало максимум 3 способностей, лишь для нескольких нужно было 4, но на этапе проектирования, может в итоге их вообще не стало. А для степени двойки может требоваться больше, например, 91=64+16+8+2+1 - пять способностей.
У меня алгоритм вручения был не помню каким, но очень хитрым. На основе смутных воспоминаний вырисовывается алгоритм для степеней двойки:
  • сначала определить чётное число или нет, в итоге вручить или нет способность на единичку;
  • потом циклом для степеней двойки опредеделить, какая степень больше, предыдущую вычесть и дать соответствующую способность;
  • с остатком повторить операцию до тех пор, пока не останется 0.

Raised как раз пример цикла показал.
Bergi_Bear #16 - 2 месяца назад 0
Переходите на 131 и тыкайте своё гуи, хватит работать на гарену, ради чего всё делаете?
easypeasy #17 - 2 месяца назад 0
подскажите пожалуйста как запустить один триггер другим N-количество раз?
1 пункт от : 4.1.2 (оффтоп)
NazarPunk #18 - 2 месяца назад (отредактировано ) -5
подскажите пожалуйста как запустить один триггер другим N-количество раз?
Вы бы хоть редактор открыли.
прикреплены файлы
8gabriel8 #19 - 2 месяца назад (отредактировано ) 3
easypeasy:
подскажите пожалуйста как запустить один триггер другим N-количество раз?
Цикл от 1 до N.
easypeasy #20 - 2 месяца назад (отредактировано ) 3
NazarPunk, позвольте, сударь, но это не оффтоп был. Я пытаюсь решить текущую проблему путём добавления способностей несколько раз(не фиксированное количество раз)
NazarPunk #21 - 2 месяца назад 2
easypeasy, берёте наработку из комментария Hate, берёте код от KaneThaumaturge, SetUnitMaxState(unit, UNIT_STATE_MAX_LIFE, R2I(GetUnitState(unit, UNIT_STATE_MAX_LIFE) + (50))) и вставляете в карту.
Если вы не можете воспользоваться готовым решением, то делать своё вам ещё пока рано.
прикреплены файлы
easypeasy #22 - 2 месяца назад 0
NazarPunk, не робит, может из за того что у меня вар версии 1.27b. Постараюсь додумать сам как это сделать триггерами без кастом скриптов, спасибо
NazarPunk #23 - 2 месяца назад -3
не робит, может из за того что у меня вар версии 1.27b
Не робит из-за того, что нужно использовать JNGP или переходить на последний патч.
easypeasy #24 - 2 месяца назад (отредактировано ) 0
8gabriel8, NazarPunk, если интересно гляньте, всего понадобилось 4 однолэвельных способности и одна переменная. Запилил триггер который работает отдельно с тысячами, сотнями, десятками и единицами числа N на которое нужно добавить макс ХП герою.
прикреплены файлы
8gabriel8 #25 - 2 месяца назад 3
easypeasy, как формируется HPTransformation? По триггеру получается, что через 7 секунд игры у Лаидрин сносится сколько-то хп, которое в итоге прибавится к её максимальному здоровью. С циклами уже не припомню, будет ли работать один раз цикл от 1 до 0, ведь тебе надо, чтобы не работал. В последнем действии не вижу смысла, оно уже не требуется. И убери модель у книг на хп, так как у стандартных моделей рун и книг после использования остаётся уменьшенная модель предмета, которая сообщает другим игрокам эффектом магического дыма, что здесь было что-то использовано, а после загрузки там будет видна тень предмета.
Это сообщение удалено
Extremator #27 - 2 месяца назад (отредактировано ) 3
easypeasy:
Extremator, сложно, но я постараюсь разобраться, спасибо
easypeasy, как-то так - setHP_16k.w3x
прикреплены файлы
easypeasy #28 - 2 месяца назад 3
8gabriel8, в этом триггере я просто для примера выбрал соотношение макс хп к текущему хп, у героя выставлено изначально не фулл хп. 8gabriel8:
С циклами уже не припомню, будет ли работать один раз цикл от 1 до 0
с циклами работает норм, можно добавить от 1 до 10000 хп,8gabriel8:
убери модель у книг на хп
Ставил в графе Файл модели - .mdl
В последнем действии не вижу смысла, оно уже не требуется
Кстати, верно, спасибо
Extremator, Интересно, любой последующий каст устанавливает заново значение максимального хп, то есть оно даже меньше может стать, мне нужно чтобы бонусы стакались. Проверь мой вариант он вроде рабочий и проще
прикреплены файлы
8gabriel8 #29 - 2 месяца назад -3
Не знаю пределов работы цикла, но по идее можно книжкой на +1 всё сделать)
easypeasy #30 - 2 месяца назад 2
8gabriel8, да можно я пробовал, но лагало в момент добавления всегда видимо из за количества
Extremator #31 - 2 месяца назад (отредактировано ) 3

Extremator, Интересно, любой последующий каст устанавливает заново значение максимального хп, то есть оно даже меньше может стать, мне нужно чтобы бонусы стакались.
Это для установки текущего бонуса ХП.
Если ты хочешь увеличивать значение, то нужно сделать получение текущего значения.
Т.е. выглядеть будет как с лечением:
Установить бонус ХП как (текущий бонус ХП + число)
Для получения надо либо напрямую считывать данные: циклом пройтись и за каждую абилку добавить её значение к переменной, тем самым нарастив её обратно (напротив с тем что при установке её значения она наоборот расходовалась). getHP
Либо просто хранить БД с юнитами, которым было изменено ХП (т.е. внести их в систему юнит-число)
И, получив число, изменить это число в нужную сторону и выполнить установку setHP
. . . 10 минут спустя ...
Вот как-то так - setHP_16k.w3x
Добавил триггер getHP для получения числа, как и описал выше.
И чуть переделал тест скиллом (даёт рандомно от +1 до +100).
По сути, может давать и отрицательные числа, но упрётся в 0
Для этого надо добавить работу с число -32768
прикреплены файлы
Raised #32 - 2 месяца назад 3
Даю еще один шанс выбрать лучший ответ.
easypeasy #33 - 1 месяц назад -2
Raised, Свой нельзя выбирать?
Raised #34 - 1 месяц назад 0
easypeasy, не в этом случае.
easypeasy #35 - 1 месяц назад 0
Raised, почему это нет? поясни
Raised #36 - 1 месяц назад (отредактировано ) 0
Твой метод утекает. Из-за бага в движке вара, усиливающие предметы не удаляются после использования, даже если ты напрямую запросишь их удаление.
Раз уж по какой-то причине решил использовать этот метод, то нужно хотя бы минимизировать количество итераций. Но метод все равно далеко не лучший.
Лучшее решение сделать то же самое с помощью предметной абилки на увеличение ХП, так можно избежать утечек. Но и тут количество итераций можно уменьшить, если разложить твое число на степени двойки.
Ну и самым лучшим/простым решением будет использовать новый патч, в котором есть возможность устанавливать эти показатели напрямую, без танцев с бубном.

Предложенный тобой вариант почти самый неэффективный (хуже может быть лишь добавление +100500 книг с прибавкой +1 к здоровью).
KaneThaumaturge #37 - 1 месяц назад 0
2 коммент - лучший ответ, имхо, но со мной согласится большая часть ХГМ. После него вообще можно было закрывать вопрос.
easypeasy #38 - 1 месяц назад 0
Raised,Ааа утечки, ну для конкретно моей карты это не будет критично, тк этот триггер будет срабатывать раз 30 за всё время
Я попробовал запускать этот триггер каждые 0.1 сек в течение минуты-две, фпс немного проседал в этот момент, после выключения триггера нормализовался и в оперативу добавилось где то 10 Мб. За это время герою дали несколько тысяч книг
KaneThaumaturge, это прерогатива Raised'а
Raised #39 - 1 месяц назад (отредактировано ) 0
easypeasy, я понимаю что это решение тебе подходит, но тем не менее это и близко не лучший ответ на твой вопрос. Из всех возможных, он второй снизу.
Extremator #40 - 1 месяц назад (отредактировано ) 0
Raised:
easypeasy, я понимаю что это решение тебе подходит, но тем не менее это и близко не лучший ответ на твой вопрос. Из всех возможных, он второй снизу.
Raised, т.е. никого не смущает то что там происходит?))
Raised #41 - 1 месяц назад 0
Extremator, сомневаюсь что кто-то в этом может быть заинтересован больше автора. Ну а раз ему подходит, ну пусть, и так сойдет. Но это не будет отмечено лучшим ответом.
Extremator #42 - 1 месяц назад 0
Raised, я к тому что он спрашивает конктно за повышение ХП юнита, а там система разных статов. И даже если оттуда тупо вычленить только измение ХП, то её всё равно надо ещё будет дорабатывать (т.к. юниты будут дохнуть если пытаться понизить ХП), либо высекать минусовую базу. И получится ровным счётом то же самое что я ему скинул (только при этом оно будет на непонятном ему vJass'е).