• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

setAttribute v.1.3

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
  • Like
Reactions: TriggerHappy
Unit's parameters control system
This time I required a system which could allow to have a full control over some of unit's parameters. I did it.
So, we have:
  • ability to set unit's HP Regeneration
  • ability to set unit's Mana Regeneration
  • ability to set unit's Max HP
  • ability to set unit's Max Mana
  • ability to set unit's Base Damage
  • ability to set unit's Bonus Damage
  • ability to set unit's Bonus Armor
  • ability to block some percent of taken damage
  • ability to block some ammount of taken damage
  • ability to set unit's Attack Speed (limited in (0-400))
To import this system you need:
  • read the instructions inside the map
  • replace "Hash" with your hashtable
  • use "FlushChildHashtable" for every unit which you are going to remove from the game
  • The data are stored in unit's handle. So you need to to specify the keys which are not occupied to avoid bugs/conflicts.
  • recreate/import all dummy abilities and items. It's better to save their iDs, otherwise you should have to rewrite them at the bottom of the main trigger yourself.
Disadvantages:
  • It's boring to copy all abilities to make the system to work.
JASS:
library setAttribute initializer Initialization
   globals
//===================================================================================================================//
//                                                    Information. ReadMe.                                           //
//-------------------------------------------------------------------------------------------------------------------//
//                                      The library provides the following abilities                                 //
//-------------------------------------------------------------------------------------------------------------------//
//                                                                                                                   //
//     The bonus parameters are limited: (-8191;8191)                                                                //
//     It's impossible to set the parameters over that amount via this system                                        //
//                                                                                                                   //
//   - Ability to control unit's Bonus Damage                                                                        //
//     [function SetUnitExtraDamage takes unit u, integer ammount] - Sets damage                                     //
//     [function GetUnitExtraDamage takes unit u returns integer] - Returns damage                                   //
//                                                                                                                   //
//   - Ability to control unit's Bonus Armor                                                                         //
//     [function SetUnitExtraArmor takes unit u, integer ammount] - Sets armor                                       //
//     [function GetUnitExtraArmor takes unit u returns integer] - Returns armor                                     //
//                                                                                                                   //
//   - Ability to control unit's max. HP                                                                             //
//     [function SetUnitLife takes unit u, integer ammount] - Sets unit's max. HP                                    //
//     [function GetUnitLife takes unit u returns integer] - Returns unit's max. HP bonus taken from this system     //
//                                                                                                                   //
//   - Ability to control unit's max. Mana                                                                           //
//     [function SetUnitMana takes unit u, integer ammount] - Sets unit's max. Mana                                  //
//     [function GetUnitMana takes unit u returns integer] - Returns unit's max. Mana bonus taken from this system   //                                                                                                                //                                             //
//                                                                                                                   //
//   - Ability to control unit's HP Regeneration                                                                     //
//     [function SetUnitLifeRegeneration takes unit u, real ammount] - Sets unit's HP regeneration                   //
//     [function GetUnitLifeRegeneration takes unit u returns real] - Returns unit's HP regeneration                 //
//                                                                                                                   //
//   - Ability to control unit's Mana Regeneration                                                                   //
//     [function SetUnitManaRegeneration takes unit u, real ammount] - Sets unit's Mana regeneration                 //
//     [function GetUnitManaRegeneration takes unit u returns real] - Returns unit's Mana regeneration               //
//                                                                                                                   //
//   - Ability to control unit's Base Damage                                                                         //
//     [function SetUnitBaseDamage takes unit getUnit, integer ammount] - Sets unit's Base Damage                    //
//     [function GetUnitBaseDamage takes unit u returns integer] - Returns unit's Base Damage bonus                  //
//                                                                                                                   //                        
//   - Ability to block some ammount of damage for any unit                                                          //  
//     [function SetUnitBlockDamageAmmount takes unit u, real ammount] - Sets unit's damage block ammount            //
//     [function GetUnitBlockDamageAmmount takes unit u, real ammount] - Returns unit's damage block ammount         //
//                                                                                                                   //                        
//   - Ability to block some percent of damage for any unit (0-100)                                                  //
//     [function SetUnitBlockDamagePercent takes unit u, real ammount] - Sets unit's damage block percent            //
//     [function GetUnitBlockDamagePercent takes unit u, real ammount] - Returns unit's damage block percent         //
//                                                                                                                   //
//   - Ability to control unit's Attack Speed (the bonus AS is limited from 0 to 400(%))                             //
//     [function SetUnitAttackSpeed takes unit u, integer ammount] - Sets unit's Attack Speed                        //
//     [function GetUnitAttackSpeed takes unit u, integer ammount] - Returns unit's Attack Speed                     //
//                                                                                                                   //
//-------------------------------------------------------------------------------------------------------------------//
//    Replace "Hash" with the name of your hashtable (CTRL+H)
//    Configure the following arrays
      private integer HASH_BASE_DAMAGE_INDEX = 1                 //The Base Damage data are stored in Hashtable on unit's handle with this key
      private integer HASH_LIFE_REGENERATION_INDEX = 2           //The HP regeneration data are stored in Hashtable on unit's handle with this key
      private integer HASH_MANA_REGENERATION_INDEX = 3           //The Mana regeneration data are stored in Hashtable on unit's handle with this key
      private integer HASH_EXTRA_ARMOR_INDEX = 4                 //The Bonus Damage data are stored in Hashtable on unit's handle with this key
      private integer HASH_EXTRA_DAMAGE_INDEX = 5                //The Bonus Armor data are stored in Hashtable on unit's handle with this key
      private integer HASH_BLOCK_DAMAGE_AMMOUNT_INDEX = 6        //The Block Damage Ammount data are stored in Hashtable on unit's handle with this key
      private integer HASH_BLOCK_DAMAGE_PERCENT_INDEX = 7        //The Block Damage Percent data are stored in Hashtable on unit's handle with this key
      private integer HASH_ATTACK_SPEED_INDEX = 8                //The Attack Speed data are stored in Hashtable on unit's handle with this key
      private integer HASH_MAX_LIFE_BONUS_INDEX = 9              //The Max HP data are stored in Hashtable on unit's handle with this key
      private integer HASH_MAX_MANA_BONUS_INDEX = 10             //The Max Mana data are stored in Hashtable on unit's handle with this key
      private real restorationPeriod = 0.01                      //The period of restoration of HP/Mana

      private integer array abilityAddArmor                      //An array of abilities to increase an armor
      private integer array abilityRemoveArmor                   //An array of abilities to reduce an armor

      private integer array abilityAddHp                         //An array of abilities to increase HP
      private integer array abilityRemoveHp                      //An array of abilities to reduce HP

      private integer array abilityAddMana                       //An array of abilities to increase Mana
      private integer array abilityRemoveMana                    //An array of abilities to reduce HP

      private integer array abilityAddDamage                     //An array of abilities to increase Bonus Damage
      private integer array abilityRemoveDamage                  //An array of abilities to reduce Bonus Damage

      private integer array itemAddBaseDamage                    //An array of items to increase Base Damage
      private integer array itemRemoveBaseDamage                 //An array of items to reduce Bonus Damage

      private integer array abilityAddAttackSpeed                //An array of abilities to increase Attack Speed
      private trigger detectDamage
      private timer restoration = CreateTimer()
      private group allUnits = CreateGroup()
      private region wholeMap
   endglobals

   function GetUnitMana takes unit u returns integer
      local integer iD = GetHandleId(u)
      local integer ammount
 
         set ammount = LoadInteger(Hash,iD,HASH_MAX_MANA_BONUS_INDEX)
   return ammount
   endfunction

   function GetUnitLife takes unit u returns integer
      local integer iD = GetHandleId(u)
      local integer ammount
 
         set ammount = LoadInteger(Hash,iD,HASH_MAX_LIFE_BONUS_INDEX)
   return ammount
   endfunction

   function GetUnitExtraArmor takes unit u returns integer
      local integer iD = GetHandleId(u)
      local integer ammount
 
         set ammount = LoadInteger(Hash,iD,HASH_EXTRA_ARMOR_INDEX)
   return ammount
   endfunction

   function GetUnitExtraDamage takes unit u returns integer
      local integer iD = GetHandleId(u)
      local integer ammount
 
         set ammount = LoadInteger(Hash,iD,HASH_EXTRA_DAMAGE_INDEX)
   return ammount
   endfunction

   function GetUnitBaseDamage takes unit u returns integer
      local integer iD = GetHandleId(u)
      local integer ammount
 
         set ammount = LoadInteger(Hash,iD,HASH_BASE_DAMAGE_INDEX)
   return ammount
   endfunction

   function GetUnitLifeRegeneration takes unit u returns real
      local integer iD = GetHandleId(u)
      local real ammount
 
         set ammount = LoadReal(Hash,iD,HASH_LIFE_REGENERATION_INDEX)
   return ammount
   endfunction

   function GetUnitManaRegeneration takes unit u returns real
      local integer iD = GetHandleId(u)
      local real ammount
 
         set ammount = LoadReal(Hash,iD,HASH_MANA_REGENERATION_INDEX)
   return ammount
   endfunction

   function GetUnitBlockDamageAmmount takes unit u returns real
      local integer iD = GetHandleId(u)
      local real ammount
         set ammount = LoadReal(Hash,iD,HASH_BLOCK_DAMAGE_AMMOUNT_INDEX)
   return ammount
   endfunction

   function GetUnitBlockDamagePercent takes unit u returns real
      local integer iD = GetHandleId(u)
      local real ammount
         set ammount = LoadReal(Hash,iD,HASH_BLOCK_DAMAGE_PERCENT_INDEX)
   return ammount
   endfunction

   function GetUnitAttackSpeed takes unit u returns integer
      local integer iD = GetHandleId(u)
      local integer ammount
         set ammount = LoadInteger(Hash,iD,HASH_ATTACK_SPEED_INDEX)
   return ammount
   endfunction

   function SetUnitBlockDamageAmmount takes unit u, real ammount returns nothing
      local integer iD = GetHandleId(u)
         if ammount > 8191 then
            set ammount = 8191
            call SaveReal(Hash,iD,HASH_BLOCK_DAMAGE_AMMOUNT_INDEX,ammount)
         elseif ammount < 0 then
            set ammount = 0
            call SaveReal(Hash,iD,HASH_BLOCK_DAMAGE_AMMOUNT_INDEX,ammount)
         else
            call SaveReal(Hash,iD,HASH_BLOCK_DAMAGE_AMMOUNT_INDEX,ammount)
         endif
   endfunction

   function SetUnitBlockDamagePercent takes unit u, real ammount returns nothing
      local integer iD = GetHandleId(u)
         if ammount > 100 then
            set ammount = 100
            call SaveReal(Hash,iD,HASH_BLOCK_DAMAGE_PERCENT_INDEX,ammount)
         elseif ammount < 0 then
            set ammount = 0
            call SaveReal(Hash,iD,HASH_BLOCK_DAMAGE_PERCENT_INDEX,ammount)
         else
            call SaveReal(Hash,iD,HASH_BLOCK_DAMAGE_PERCENT_INDEX,ammount)
         endif
   endfunction

   function SetUnitAttackSpeed takes unit u, integer ammount returns nothing

      local integer iD = GetHandleId(u)  
      local integer power = 8
      local integer index = 0
      local integer rest
         if ammount > 400 then
            set ammount = 400
         endif
   
         loop
            call UnitRemoveAbility(u,abilityAddAttackSpeed[index])
         exitwhen index == 8
            set index = index+1
         endloop
   
         if ammount > 0 then
            set rest = ammount
            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,abilityAddAttackSpeed[power])
                  set rest = rest-R2I(Pow(2,power))
                  set power = power-1
               endif
            endloop
            call SaveInteger(Hash,iD,HASH_ATTACK_SPEED_INDEX,ammount)
         endif
   endfunction

   function SetUnitExtraArmor takes unit u, integer ammount returns nothing

      local integer iD = GetHandleId(u)  
      local integer power = 13
      local integer index = 0
      local integer rest
         if ammount > 8191 then
            set ammount = 8191
         elseif ammount < -8191 then
            set ammount = -8191
         endif
   
         loop
            call UnitRemoveAbility(u,abilityAddArmor[index])
            call UnitRemoveAbility(u,abilityRemoveArmor[index])
         exitwhen index == 12
            set index = index+1
         endloop
   
         if ammount > 0 then
            set rest = ammount
            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,abilityAddArmor[power])
                  set rest = rest-R2I(Pow(2,power))
                  set power = power-1
               endif
            endloop
            call SaveInteger(Hash,iD,HASH_EXTRA_ARMOR_INDEX,ammount)
         elseif ammount < 0 then
            set ammount = -ammount
            set rest = ammount
            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,abilityRemoveArmor[power])
                  set rest = rest-R2I(Pow(2,power))
                  set power = power-1
               endif
            endloop
            call SaveInteger(Hash,iD,HASH_EXTRA_ARMOR_INDEX,-ammount)
         endif
   endfunction

   function SetUnitBaseDamage takes unit u, integer ammount returns nothing

      local integer power = 12
      local integer rest
      local integer iD = GetHandleId(u)
      local integer prevID = LoadInteger(Hash,iD,HASH_BASE_DAMAGE_INDEX)
      local boolean removeInventory = false
         if GetUnitAbilityLevel(u,'AInv') <= 0 then
            set removeInventory = true
            call UnitAddAbility(u,'AInv')
         endif
   
         if ammount > 8191 then
            set ammount = 8191
         endif
   
         if prevID+ammount < 0 then
            set ammount = -prevID
         else
            if prevID != 0 and prevID+ammount > 0 then
               set ammount = -(prevID-ammount)
            endif
         endif
         if ammount > 0 then
            set rest = ammount
            loop
            exitwhen rest <= 0
               if R2I(Pow(2,power)) > rest then
                  set power = power-1
               elseif R2I(Pow(2,power)) <= rest then
                  set bj_lastCreatedItem = CreateItem(itemAddBaseDamage[power],GetUnitX(u),GetUnitY(u))
                  call UnitAddItem(u,bj_lastCreatedItem)
                  call RemoveItem(bj_lastCreatedItem)
                  set rest = rest-R2I(Pow(2,power))
                  set power = power-1
               endif
            endloop
            set prevID = prevID+ammount
            call SaveInteger(Hash,iD,HASH_BASE_DAMAGE_INDEX,prevID)
         elseif ammount < 0 then
            set ammount = -ammount
            set rest = ammount
            loop
            exitwhen rest <= 0
               if R2I(Pow(2,power)) > rest then
                  set power = power-1
               elseif R2I(Pow(2,power)) <= rest then
                  set bj_lastCreatedItem = CreateItem(itemRemoveBaseDamage[power],GetUnitX(u),GetUnitY(u))
                  call UnitAddItem(u,bj_lastCreatedItem)
                  call RemoveItem(bj_lastCreatedItem)
                  set rest = rest-R2I(Pow(2,power))
                  set power = power-1
               endif
            endloop
            set prevID = prevID-ammount
            call SaveInteger(Hash,iD,HASH_BASE_DAMAGE_INDEX,prevID)
         endif
   
         if GetUnitAbilityLevel(u,'AInv') > 0 and removeInventory == true then
            call UnitRemoveAbility(u,'AInv')
         endif
   
   endfunction

   function SetUnitExtraDamage takes unit u, integer ammount returns nothing

      local integer iD = GetHandleId(u)
      local integer power = 12
      local integer index = 0
      local integer rest

         if ammount > 8191 then
            set ammount = 8191
         elseif ammount < -8191 then
            set ammount = -8191
         endif
         loop
            call UnitRemoveAbility(u,abilityAddDamage[index])
            call UnitRemoveAbility(u,abilityRemoveDamage[index])
         exitwhen index == 12
            set index = index+1
         endloop
         if ammount > 0 then
            set rest = ammount
            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,abilityAddDamage[power])
                  set rest = rest-R2I(Pow(2,power))
                  set power = power-1
               endif
            endloop
            call SaveInteger(Hash,iD,HASH_EXTRA_DAMAGE_INDEX,ammount)
         elseif ammount < 0 then
            set ammount = -ammount
            set rest = ammount
            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,abilityRemoveDamage[power])
                  set rest = rest-R2I(Pow(2,power))
                  set power = power-1
               endif
            endloop
            call SaveInteger(Hash,iD,HASH_EXTRA_DAMAGE_INDEX,-ammount)
         endif
   endfunction

   function SetUnitLife takes unit u, integer ammount returns nothing

      local integer power = 12
      local integer rest
      local integer loadedLife
      local integer newLife
      local integer iD = GetHandleId(u)
         if ammount > 8191 then
            set ammount = 8191
         elseif GetUnitState(u,UNIT_STATE_MAX_LIFE)+ammount <= 0 then
            set ammount = 1
         endif
   
         set loadedLife = LoadInteger(Hash,iD,HASH_MAX_LIFE_BONUS_INDEX)
         set newLife = loadedLife+(ammount-R2I(GetUnitState(u,UNIT_STATE_MAX_MANA)))
         call SaveInteger(Hash,iD,HASH_MAX_LIFE_BONUS_INDEX,newLife)
         set ammount = ammount-R2I(GetUnitState(u,UNIT_STATE_MAX_LIFE))
         if ammount > 0 then
            set rest = ammount
            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
         elseif ammount < 0 then
            set ammount = -ammount
            set rest = ammount
            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,abilityRemoveHp[power])
                  call SetUnitAbilityLevel(u,abilityRemoveHp[power],2)
                  call UnitRemoveAbility(u,abilityRemoveHp[power])
                  set rest = rest-R2I(Pow(2,power))
                  set power = power-1
               endif
            endloop
         endif
   endfunction

   function SetUnitMana takes unit u, integer ammount returns nothing

      local integer power = 12
      local integer rest
      local integer loadedMana
      local integer newMana
      local integer iD = GetHandleId(u)
         if ammount > 8191 then
            set ammount = 8191
         elseif GetUnitState(u,UNIT_STATE_MAX_MANA)+ammount < 0 then
            set ammount = 0
         endif
   
         set loadedMana = LoadInteger(Hash,iD,HASH_MAX_MANA_BONUS_INDEX)
         set newMana = loadedMana+(ammount-R2I(GetUnitState(u,UNIT_STATE_MAX_MANA)))
         call SaveInteger(Hash,iD,HASH_MAX_MANA_BONUS_INDEX,newMana)
   
         set ammount = ammount-R2I(GetUnitState(u,UNIT_STATE_MAX_MANA))
         if ammount > 0 then
            set rest = ammount
            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,abilityAddMana[power])
                  call SetUnitAbilityLevel(u,abilityAddMana[power],2)
                  call UnitRemoveAbility(u,abilityAddMana[power])
                  set rest = rest-R2I(Pow(2,power))
                  set power = power-1
               endif
            endloop
         elseif ammount < 0 then
            set ammount = -ammount
            set rest = ammount
            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,abilityRemoveMana[power])
                  call SetUnitAbilityLevel(u,abilityRemoveMana[power],2)
                  call UnitRemoveAbility(u,abilityRemoveMana[power])
                  set rest = rest-R2I(Pow(2,power))
                  set power = power-1
               endif
            endloop
         endif
   endfunction

   function SetUnitLifeRegeneration takes unit u, real ammount returns nothing
      local integer iD = GetHandleId(u)
         call SaveReal(Hash,iD,HASH_LIFE_REGENERATION_INDEX,ammount)
         call GroupAddUnit(allUnits,u)
   endfunction

   function SetUnitManaRegeneration takes unit u, real ammount returns nothing
      local integer iD = GetHandleId(u)
         call SaveReal(Hash,iD,HASH_MANA_REGENERATION_INDEX,ammount)
         call GroupAddUnit(allUnits,u)
   endfunction

   private function restoreParamatersCallback takes nothing returns nothing
      local integer iD = GetHandleId(GetEnumUnit())
      local real hpRegen = LoadReal(Hash,iD,HASH_LIFE_REGENERATION_INDEX)
      local real manaRegen = LoadReal(Hash,iD,HASH_MANA_REGENERATION_INDEX)
   
         call SetUnitState(GetEnumUnit(),UNIT_STATE_LIFE,GetUnitState(GetEnumUnit(),UNIT_STATE_LIFE)+hpRegen*restorationPeriod)
         call SetUnitState(GetEnumUnit(),UNIT_STATE_MANA,GetUnitState(GetEnumUnit(),UNIT_STATE_MANA)+manaRegen*restorationPeriod)      

   endfunction

   private function restoreParamaters takes nothing returns nothing
      call ForGroup(allUnits,function restoreParamatersCallback)
   endfunction

   private function onMapEntering takes nothing returns nothing
      if GetEnteringUnit()!=null then
         call TriggerRegisterUnitEvent(GetTriggeringTrigger(),GetEnteringUnit(),EVENT_UNIT_DAMAGED)
      endif
   endfunction

   private function TriggerRegisterUnitEventDamaged takes trigger detectDamageTrig returns nothing
 
      local group groupEnumUnits = CreateGroup()
      local unit enumUnit

         call GroupEnumUnitsInRect(groupEnumUnits,bj_mapInitialPlayableArea,null)
   
         loop
            set enumUnit = FirstOfGroup(groupEnumUnits)
         exitwhen enumUnit == null
            call TriggerRegisterUnitEvent(detectDamageTrig,enumUnit,EVENT_UNIT_DAMAGED)
            call GroupRemoveUnit(groupEnumUnits,enumUnit)
         endloop
   
         call TriggerRegisterEnterRegion(detectDamageTrig,wholeMap,null)
         call TriggerAddAction(detectDamageTrig,function onMapEntering)
   
         call DestroyGroup(groupEnumUnits)
         set groupEnumUnits=null
         set enumUnit=null
   
   endfunction

   private 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

   private 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

   private function Initialization takes nothing returns nothing

      //Increase Armor
      set abilityAddArmor[0] = 'aa00'
      set abilityAddArmor[1] = 'aa01'
      set abilityAddArmor[2] = 'aa02'
      set abilityAddArmor[3] = 'aa03'
      set abilityAddArmor[4] = 'aa04'
      set abilityAddArmor[5] = 'aa05'
      set abilityAddArmor[6] = 'aa06'
      set abilityAddArmor[7] = 'aa07'
      set abilityAddArmor[8] = 'aa08'
      set abilityAddArmor[9] = 'aa09'
      set abilityAddArmor[10] = 'aa10'
      set abilityAddArmor[11] = 'aa11'
      set abilityAddArmor[12] = 'aa12'

      //Reduce Armor
      set abilityRemoveArmor[0] = 'ra00'
      set abilityRemoveArmor[1] = 'ra01'
      set abilityRemoveArmor[2] = 'ra02'
      set abilityRemoveArmor[3] = 'ra03'
      set abilityRemoveArmor[4] = 'ra04'
      set abilityRemoveArmor[5] = 'ra05'
      set abilityRemoveArmor[6] = 'ra06'
      set abilityRemoveArmor[7] = 'ra07'
      set abilityRemoveArmor[8] = 'ra08'
      set abilityRemoveArmor[9] = 'ra09'
      set abilityRemoveArmor[10] = 'ra10'
      set abilityRemoveArmor[11] = 'ra11'
      set abilityRemoveArmor[12] = 'ra12'
      set abilityRemoveArmor[13] = 'ra13'

      //Increase HP
      set abilityAddHp[0] = 'ah00'
      set abilityAddHp[1] = 'ah01'
      set abilityAddHp[2] = 'ah02'
      set abilityAddHp[3] = 'ah03'
      set abilityAddHp[4] = 'ah04'
      set abilityAddHp[5] = 'ah05'
      set abilityAddHp[6] = 'ah06'
      set abilityAddHp[7] = 'ah07'
      set abilityAddHp[8] = 'ah08'
      set abilityAddHp[9] = 'ah09'
      set abilityAddHp[10] = 'ah10'
      set abilityAddHp[11] = 'ah11'
      set abilityAddHp[12] = 'ah12'
      set abilityAddHp[13] = 'ah13'

      //Reduce HP
      set abilityRemoveHp[0] = 'rh00'
      set abilityRemoveHp[1] = 'rh01'
      set abilityRemoveHp[2] = 'rh02'
      set abilityRemoveHp[3] = 'rh03'
      set abilityRemoveHp[4] = 'rh04'
      set abilityRemoveHp[5] = 'rh05'
      set abilityRemoveHp[6] = 'rh06'
      set abilityRemoveHp[7] = 'rh07'
      set abilityRemoveHp[8] = 'rh08'
      set abilityRemoveHp[9] = 'rh09'
      set abilityRemoveHp[10] = 'rh10'
      set abilityRemoveHp[11] = 'rh11'
      set abilityRemoveHp[12] = 'rh12'

      //Increase Mana
      set abilityAddMana[0] = 'am00'
      set abilityAddMana[1] = 'am01'
      set abilityAddMana[2] = 'am02'
      set abilityAddMana[3] = 'am03'
      set abilityAddMana[4] = 'am04'
      set abilityAddMana[5] = 'am05'
      set abilityAddMana[6] = 'am06'
      set abilityAddMana[7] = 'am07'
      set abilityAddMana[8] = 'am08'
      set abilityAddMana[9] = 'am09'
      set abilityAddMana[10] = 'am10'
      set abilityAddMana[11] = 'am11'
      set abilityAddMana[12] = 'am12'

      //Reduce mana
      set abilityRemoveMana[0] = 'rm00'
      set abilityRemoveMana[1] = 'rm01'
      set abilityRemoveMana[2] = 'rm02'
      set abilityRemoveMana[3] = 'rm03'
      set abilityRemoveMana[4] = 'rm04'
      set abilityRemoveMana[5] = 'rm05'
      set abilityRemoveMana[6] = 'rm06'
      set abilityRemoveMana[7] = 'rm07'
      set abilityRemoveMana[8] = 'rm08'
      set abilityRemoveMana[9] = 'rm09'
      set abilityRemoveMana[10] = 'rm10'
      set abilityRemoveMana[11] = 'rm11'
      set abilityRemoveMana[12] = 'rm12'

      //Increace Bonus Damage
      set abilityAddDamage[0] = 'ad00'
      set abilityAddDamage[1] = 'ad01'
      set abilityAddDamage[2] = 'ad02'
      set abilityAddDamage[3] = 'ad03'
      set abilityAddDamage[4] = 'ad04'
      set abilityAddDamage[5] = 'ad05'
      set abilityAddDamage[6] = 'ad06'
      set abilityAddDamage[7] = 'ad07'
      set abilityAddDamage[8] = 'ad08'
      set abilityAddDamage[9] = 'ad09'
      set abilityAddDamage[10] = 'ad10'
      set abilityAddDamage[11] = 'ad11'
      set abilityAddDamage[12] = 'ad12'

      //Reduce Bonus Damage
      set abilityRemoveDamage[0] = 'rd00'
      set abilityRemoveDamage[1] = 'rd01'
      set abilityRemoveDamage[2] = 'rd02'
      set abilityRemoveDamage[3] = 'rd03'
      set abilityRemoveDamage[4] = 'rd04'
      set abilityRemoveDamage[5] = 'rd05'
      set abilityRemoveDamage[6] = 'rd06'
      set abilityRemoveDamage[7] = 'rd07'
      set abilityRemoveDamage[8] = 'rd08'
      set abilityRemoveDamage[9] = 'rd09'
      set abilityRemoveDamage[10] = 'rd10'
      set abilityRemoveDamage[11] = 'rd11'
      set abilityRemoveDamage[12] = 'rd12'

      //Increase Base Damage
      set itemAddBaseDamage[0] = 'id00'
      set itemAddBaseDamage[1] = 'id01'
      set itemAddBaseDamage[2] = 'id02'
      set itemAddBaseDamage[3] = 'id03'
      set itemAddBaseDamage[4] = 'id04'
      set itemAddBaseDamage[5] = 'id05'
      set itemAddBaseDamage[6] = 'id06'
      set itemAddBaseDamage[7] = 'id07'
      set itemAddBaseDamage[8] = 'id08'
      set itemAddBaseDamage[9] = 'id09'
      set itemAddBaseDamage[10] = 'id10'
      set itemAddBaseDamage[11] = 'id11'
      set itemAddBaseDamage[12] = 'id12'

      //Reduce Base Damage
      set itemRemoveBaseDamage[0] = 'im00'
      set itemRemoveBaseDamage[1] = 'im01'
      set itemRemoveBaseDamage[2] = 'im02'
      set itemRemoveBaseDamage[3] = 'im03'
      set itemRemoveBaseDamage[4] = 'im04'
      set itemRemoveBaseDamage[5] = 'im05'
      set itemRemoveBaseDamage[6] = 'im06'
      set itemRemoveBaseDamage[7] = 'im07'
      set itemRemoveBaseDamage[8] = 'im08'
      set itemRemoveBaseDamage[9] = 'im09'
      set itemRemoveBaseDamage[10] = 'im10'
      set itemRemoveBaseDamage[11] = 'im11'
      set itemRemoveBaseDamage[12] = 'im12'

      //Increase Attack Speed
      set abilityAddAttackSpeed[0] = 'as00'
      set abilityAddAttackSpeed[1] = 'as01'
      set abilityAddAttackSpeed[2] = 'as02'
      set abilityAddAttackSpeed[3] = 'as03'
      set abilityAddAttackSpeed[4] = 'as04'
      set abilityAddAttackSpeed[5] = 'as05'
      set abilityAddAttackSpeed[6] = 'as06'
      set abilityAddAttackSpeed[7] = 'as07'
      set abilityAddAttackSpeed[8] = 'as08'

      set restoration = CreateTimer()
      call TimerStart(restoration,restorationPeriod,true,function restoreParamaters)

      set wholeMap = CreateRegion()
      call RegionAddRect(wholeMap, bj_mapInitialPlayableArea)

      set detectDamage = CreateTrigger()
      call TriggerRegisterUnitEventDamaged(detectDamage)
      call TriggerAddAction(detectDamage,function onDamage)

   endfunction
endlibrary

Credits: Hate, Doc, Clamp, nvc123
One more thing. I have no idea how does usual English looks like so I'll appreciate if you show me my mistakes so I could write correctly.
Contents

setAttribute v.1.3 (Map)

Reviews
MyPad
Reviving this thread back from the forgotten to release an updated review: System: Notes: As the resource is more of a system than a spell, it is recommended to use a module initializer instead of a library initializer for the sake of...
Level 4
Joined
May 8, 2016
Messages
58
The differences are:

  • I haven't used any abilities to add regeneration to unit. I used for it a periodical timer with configurable period of restoration.
  • There is no ability to set bonus attributes (there is a way to manipulate them via natives, so I've found it unreasonable to recreate an existing functionality). However I might add it later.
  • there are no following features in "Bonus Mod":
- ability to set unit's Base Damage bonus (white damage)
- ability to block some percent of taken damage
- ability to block some ammount of taken damage
- ability to set unit's Attack Speed
- this system can't be imported via objectmerger because I didn't knew that that staff exists
- I used HT instead of structs
  • there are also some minor differences:
- at this system the range of values is between -8191 and 8191 (1+2+4...+4096). A bit wider range =/ Methints that author of that system made mistake calculating the maximum ammount of bonus parameters which could be achieved via that system.
- at this system I created separate functions to Set/Get each parameter
- there are some minor differences in system's logic. Though it should take too much time to describe them all.

That's all. Maybe.
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
I can see the attack speed manipulation being useful, but the rest is not really better. However bonus mod got sight range which you don't, so it equals out I suppose.

Blocking damage is done through a DDS with one line of code, actually modifying the damage in any way is.
Allowing a higher number is better, but to be honest that high numbers are not needed in the first place.

I am not the most knowledgeable when it comes to speed but your system seems slower as well. Mainly due the use of hashtables.

edit: I overstepped. I should not talk about speed, I know too little.
 
Last edited:
Level 4
Joined
May 8, 2016
Messages
58
It should be too difficult to import this, anyway. There are minor speed differences. Besides there are not so much parameters and which could be implemented into such kind of system which are not configurable via natives.

Where can i find info about objectmerger?
 
Review:
- the hashes and other values preset in the globals should be declared constant
- functions like GetUnitLife and SetUnitLife can create collision issues with DDS like PDD, the reason I pointed this out is because DDS is one of the most used system out there.
- 100 frames per second is a bit fast(even Windows can't handle such quality of time, according to my friend), try 64 or 32 fps
- BonusMod has already supported most of things here even the Attack Speed bonus, but not the White Damage. Can you tell me how you achieved the bonus damage without the use of tomes?
- your binary search is a bit off. you are using Pow, which makes it inefficient. If I were you I will create a power of 2s table, then use it instead of Pow
- Magtheridon's Heal libray is much better than your regeneration support.
- You should use a Unit Indexer if somehow you are still going to add support to regeneration functions

off-topic:
use [code=jass][/code] tags :V
 
Level 4
Joined
May 8, 2016
Messages
58
Item type ID comparison works strange with conditions. Vexorian's system doesn't work properly to remove this kind of leaks. I know the way to fix this leak but it requires the user to rethink an items in his map.
 
Level 23
Joined
Apr 16, 2012
Messages
4,041
- ability to block some percent of taken damage
- ability to block some ammount of taken damage

There is no reason you should be doing that, and that should be left for independant resource, that is much closer to some DDS.

If you insist on doing this, for love of god, import some DDS, there are plenty, for GUI, Jass, vJass, all you will ever need, bucket-based, naive-based(but still tons better), var-based, over-complexed(on github and they all do 10000x better job than this very naive approach will ever be able to.
 
Level 4
Joined
May 8, 2016
Messages
58
Please share a link where I can find 10000 times better DDS than this. Or your favorite one.

If you insist on doing this, for love of god, import some DDS, there are plenty, for GUI, Jass, vJass, all you will ever need, bucket-based, naive-based(but still tons better), var-based, over-complexed(on github and they all do 10000x better job than this very naive approach will ever be able to.

It sounds shitty. Especially with no links.
 
Last edited:
Level 39
Joined
Feb 27, 2007
Messages
4,992
It seems that whether or not a system like this is acceptable is more of a 'site policy' question. Setting aside any coding/methodology problems inherent to the submission, the question becomes: does a system like this need to do anything sufficiently different to be approvable, or is rehashing a couple different systems and adding a bit of functionality that some of them didn't have in the first place okay?

I think you can argue that having options A, B, and C that all do roughly the same thing in slightly different ways is totally fine (see: the number of different TimerUtils libraries there have been in wc3 history) because a user might legitimately want things done this way rather than that way. But at that point the methodology used (the question I decided to set aside above) becomes extremely important as it is basically the only distinguishing factor. On the other side of the coin, a basic user might not really understand the differences between implementations or the nuance of why one version of a system might conflict with, say, a DDS and another wouldn't. Perhaps then you might say that as resource section curators it should be our job to keep the uninformed away from things that will cause them problems/headaches.

I am personally in favor of multiple 'flavors' of systems, but my surface level analysis of this code/method (I have not read each function in detail) is that this does nothing superior to BonusMod except white damage (there are BonusMod addons for both flat AND percentage life/mana regen which this one doesn't, plus attackspeed/movespeed) and in fact can cause a real headache when trying to use any other DDS in combination. I agree that blocking incoming damage should be relegated to DDS and not to a system like this.

tl;dr: I don't think we're having the right type of discussion here.
 
@GF RaiseD hi,

The damage reduction functionality is commenly applied by DDS systems (it's good to have modular systems), examples [vJASS] - [System] Physical Damage Detection, GUI Damage Engine v3.6.0.1.

Other functionality is as far I can see covered here BonusMod - Wc3C.net.
BonusMod, you're probably right, that it doesn't work with white damage like your system does, but I'm not sure it's a problem?

Your's does allow wider range for example damage, but also a lower range for HP.

Methints that author of that system made mistake calculating the maximum ammount of bonus parameters which could be achieved via that system.
What do you mean?

at this system I created separate functions to Set/Get each parameter
BonusMod does have have getters as well.

It's definitly a good approach you made here. Does it something do BonusMod doesn't do?
 
Level 4
Joined
May 8, 2016
Messages
58
Does it something do BonusMod doesn't do?
I don't think so. It was just my approach to achieve the same results as BM at the other side of WC III community (Russian). I didn't even knew that BonusMod exist.

I don't recommend to use this system because it should be reworked soon (and manipulations with the white damage causes leaks).

What do you mean?
I wrote that several month before. I no more remember what I've meant.
 
I don't recommend to use this system because it should be reworked soon (and manipulations with the white damage causes leaks).
I see, thanks for quick response then.

I wrote that several month before. I no more remember what I've meant.
I know that feel. :D Sorry for late response by the way.

Ok, so let's hold it pending for a bit until you think it's okay to use again and in case the resource would be pending for too long, then we put it into substandard until the point your expected update comes.
 
Reviving this thread back from the forgotten to release an updated review:

System:

Notes:

  • As the resource is more of a system than a spell, it is recommended to use a module initializer instead of a library initializer for the sake of initialization order.

  • Modularity in this system leaves a lot to be desired. A DDS would better suit the damage blocking functions; the functions SetUnitLife, SetUnitMana, SetUnitBonusArmor could behave as wrapper functions for current versions of Warcraft 3, and SetUnitLifeRegeneration, SetUnitManaRegeneration could be implemented in a different library altogether.

  • Import instructions are (admittedly) very cumbersome, and may be prone to buggy behavior, considering rawcode collision of different abilities. Similarly, generated abilities are resource-intensive for the importing entity, which may likely end up just as described above. A way to (probably) mitigate this problem is to assign those abilities to GUI variables (which must be done in a separate trigger in order to work).

  • (Added note) In the system, a timer reserved for updating the health and mana of certain units wastes performance when there are no units in the group (it is not paused when there are no units).

  • As of now, the resource shall be moved to Substandard, due to it having remained under Awaiting Update for a significant period of time.

Status:

  • Substandard
 
Last edited:
Top