Есть предположим пассивка которая с каким-то шансом блокирует нанесенный урон на 100%. Казалось бы все просто, отследить нанесение урона, шанс и просто полечить юнита на нанесенный урон. Но если у цели будет, скажем, 500 ед. здоровья, ее ударят на 600, пассивка вроде как успешно срабатывает, но цель умирает после нанесения 500 урона и будучи мертвой уже не может получить лечение. Как избежать такого ляпа и сделать нормальную блокировку урона?

  • Если урон > здоровья, тогда делаешь юнита неуязвимым, запускаешь таймер на 0 сек., по истечению делаешь юнита уязвимым и восстанавливаешь здоровье
  • Если после восстановления здоровье превышает максимальное значение, тогда восстанавливай здоровье не сразу, а, как и в п.1, с помощью таймера
`
ОЖИДАНИЕ РЕКЛАМЫ...
15
Нанесение урона происходит через какое-то время после его отлова. Если урон не превышает текущее здоровье юнита, надо лечить его через 0.0. Если урон больше чем максимальное хп - пилить костыли, которые будут как-то чекать это.
7
  • Если урон > здоровья, тогда делаешь юнита неуязвимым, запускаешь таймер на 0 сек., по истечению делаешь юнита уязвимым и восстанавливаешь здоровье
  • Если после восстановления здоровье превышает максимальное значение, тогда восстанавливай здоровье не сразу, а, как и в п.1, с помощью таймера
Принятый ответ
21

Спойлер
   function damageTarget takes nothing returns nothing

      local timer dealDamage = GetExpiredTimer() 
      local integer iD = GetHandleId(dealDamage) 
      local unit Attacked = LoadUnitHandle(Hash,iD,'trgD') 
      local unit Attacker = LoadUnitHandle(Hash,iD,'DMGS') 
      local real Damage = LoadReal(Hash,iD,'TDMG') 
        
         call SetUnitInvulnerable(Attacked,false)
      
         call DisableTrigger(detectDamage)
         call UnitDamageTarget(Attacker,Attacked,(Damage-GetUnitBlockDamageAmmount(Attacked))*(1-GetUnitBlockDamagePercent(Attacked)/100),true,false,ATTACK_TYPE_CHAOS,DAMAGE_TYPE_UNIVERSAL,WEAPON_TYPE_WHOKNOWS)         
         call EnableTrigger(detectDamage) 
     
         call DestroyTimer(dealDamage) 
         call FlushChildHashtable(Hash,iD) 
      
         set dealDamage = null 
         set Attacked = null 
         set Attacker = null 
 
   endfunction

   function onDamage takes nothing returns nothing
   
      local timer dealDamage
      local integer iD
      local unit Attacked = GetTriggerUnit()
      local real Damage = GetEventDamage()
      local unit Attacker = GetEventDamageSource()
      
            if GetWidgetLife(Attacked) <= Damage or GetWidgetLife(Attacked)+Damage+GetUnitBlockDamageAmmount(Attacked) > GetUnitState(Attacked,UNIT_STATE_MAX_LIFE) then
               call SetUnitInvulnerable(Attacked,true)
            
               set dealDamage = CreateTimer()
               set iD = GetHandleId(dealDamage)
               call TimerStart(dealDamage,0,false,function damageTarget)
            
               call SaveUnitHandle(Hash,iD,'trgD',Attacked)
               call SaveReal(Hash,iD,'TDMG',Damage)
               call SaveUnitHandle(Hash,iD,'DMGS',Attacker)
         
            elseif GetWidgetLife(Attacked) > Damage and GetWidgetLife(Attacked)+Damage+GetUnitBlockDamageAmmount(Attacked) <= GetUnitState(Attacked,UNIT_STATE_MAX_LIFE) then
               if Damage > GetUnitBlockDamageAmmount(Attacked) then
                  call SetWidgetLife(Attacked,GetWidgetLife(Attacked)+GetUnitBlockDamageAmmount(Attacked)+(Damage-GetUnitBlockDamageAmmount(Attacked))*GetUnitBlockDamagePercent(Attacked)/100)
               else 
                  call SetWidgetLife(Attacked,GetWidgetLife(Attacked)+Damage)
               endif
            endif 

         set dealDamage = null 
         set Attacked = null
         set Attacker = null
         
   endfunction
32
Я просто добавлял пассивку на 15000 хп, ставил хп макс, а через 0.00 сек. таймером ставил сколько было.
28
если тебе надо только физ урон то можно юзать каменные доспехи или уворот
Чтобы оставить комментарий, пожалуйста, войдите на сайт.