• Check out the results of the Techtree Contest #19!
  • Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!

Block X attacks.

Status
Not open for further replies.
Level 2
Joined
Aug 15, 2018
Messages
5
Looking for help making a castable hero ability that will Block the next 3 attacks. Melee, Ranged or spells.

Im using a custom damage engine but im not sure how to get the code to interact with it. Im assuming Ive got to set an integer that drops by 1 each time an attack occurs.

Any advice ?
 
Last edited:
Your damage engine has some sort of trigger that runs when a unit is damaged. As you thought you will increment some sort of variable each time the proper unit is damaged.

How you approach this depends on if there is only one unit on the map at any given time that can cast this spell (or one unit on the map per player), or if there may be many units that can cast it simultaneously. The former is much easier: create 1 unit variable and 1 integer variable and set them whenever the unit casts the spell. The latter is more complicated and will require you to either learn Dynamic Indexing or how to use Hashtables.

Blocking spell damage is easy. Blocking spells entirely will be more difficult, even more so if you have a significant number of triggered spell effects on your map (where something like spell shield won't work because many triggers don't check for spell immunity/spell shield in their target selection).
 
The spell would be unique to a single hero And preventing the damage would be sufficient I believe. Could you possibly post or show me how to set this up using the GUI or PM me on how to get the JASS going, I know the very jass basics but i fail utterly if something requires booleans, hashtables or loops lol.
 
You should base the ability on something like Bloodlust that targets itself and simply gives a buff with a visual effect for the duration. I'm using PDD as an example DDS just to keep my syntax and variable names straight.

  • Events
    • -------- Whatever event runs things from your damage detection system/damage engine --------
    • -------- Usually something like the following --------
    • Game - PDD_damageEventTrigger becomes Equal to 1.00
  • Conditions
    • -------- We can try to filter out everything except the appropriate unit taking damage while it has the damage block buff --------
    • -------- usually your DDS will give you some variables for the damaged unit, damager, amount of damage, etc. --------
    • (PDD_target has buff BLOCK_BUFF) equal to true
    • -------- You could also filter out damage amounts that are too small, so something like a periodic spell that deals 2 damage every 0.05 seconds wouldn't eat all 3 blocks instantly, but that choice is up to you; this is not necessary --------
    • PDD_amount greater than 5.00
    • -------- You could also choose to only block damage from heroes, or from player-controlled units like this (also optional) --------
    • Or - Any (Conditions) are true
      • Conditions
        • (PDD_source is A Hero) equal to true
        • ((Owner of PDD_source) controller) Equal to User
  • Actions
    • -------- Increase the counter for the number of attacks blocked --------
    • Set BLOCK_count = BLOCK_count + 1
    • -------- the DDS will have some way to modify the event damage, usually by setting a variable --------
    • Set PDD_amount = 0.00
    • -------- If this is the 3rd block, then end the effect for the unit --------
    • If (All conditions are true) then do (Then actions) else do (Else actions)
      • If - Conditions
        • BLOCK_count greater than or equal to 3
      • Then - Actions
        • Unit - Remove BLOCK_BUFF from PDD_target
      • Else - Actions
  • -------- --------
  • Events
    • Unit - A unit starts the effect of an ability
  • Conditions
    • (Ability being cast) equal to BLOCK_ABILITY
  • Actions
    • Set BLOCK_count = 0

PDD has a vJASS version for easy comparison, so a simple JASS'd version of this spell requires WEX or the 1.30 editor and looks like this:
JASS:
library DamageBlockSpell requires DamageEvent initializer init
  globals
      //configuration constants (I use capitals for these)
      private integer BLOCK_ABILITY = 'A001' //rawcode of the ability, see this in the object editor by pressing ctrl+d
      private integer BLOCK_BUFF = 'B001' //rawcode of the buff
      private integer BLOCK_TIMES = 3 //how many times to block
      private real BLOCK_MINIMUM = 5.00

      //non-constants
      private integer BlockCount //doesn't need to be initialized
      public trigger CastTrigger //will be initialized below, only primitives can be init'd in globals blocks
  endglobals

  private function BlockDamage takes nothing returns nothing
      local boolean B_min        //splitting up your conditions into multiple booleans can sometimes be useful
      local boolean B_type       //but because this funtion runs ANY time ANY unit takes damage,
      local boolean B_controller //we don't want to calculate these booleans unless we need to

      if GetUnitAbilityLevel(PDDS.target, BLOCK_BUFF) > 0 then
          set B_min = PDDS.amount >= BLOCK_MINIMUM
          set B_type = IsUnitType(PDDS.source, UNIT_TYPE_HERO)
          set B_controller = GetPlayerController(GetOwningPlayer(PDDS.source)) == MAP_CONTROL_USER

          if B_min and (B_type or B_controller) then
              set BlockCount = BlockCount+1
              set PDDS.amount = 0.00

              if BlockCount >= BLOCK_TIMES then
                  call UnitRemoveAbility(PDDS.target, BLOCK_BUFF)
              endif
          endif
      endif
  endfunction

  private function onCast takes nothing returns nothing
      if GetSpellAbilityId() == BLOCK_ABILITY then
        set BlockCount = 0
      endif
  endfunction

  private function init takes nothing returns nothing
      set CastTrigger = CreateTrigger() //set up the trigger to detect spell casts, which is necessary because the spell block count will break without this if a unit dies with the buff active (unlikely) or it is dispelled
      call TriggerRegisterAnyUnitEventBJ(CastTrigger, EVENT_PLAYER_UNIT_SPELL_EFFECT) //this BJ saves you lots of time
      call TriggerAddAction(CastTrigger, function onCast)

      call AddDamageHandler(function BlockDamage) //The PDD call that tells BlockDamage to run when things take damage
  endfunction
endlibrary
 
Last edited:
There is another way to make it work but it will never work on custom spells or area of effect abilities, temporarily add hardened skin with modified block values and spell block from amulet spell shield item, if you want to hide the buttons, put them in a spell book and disable spell book ability for player, that way the player won’t be able to open the spell book. As you can imagine, the target will be immune to Attack damage and targetted spells. I admit it is a trick but remember to remove the spell book after a certain duration or after 3 hits, using the damage detection you can do that, or if you are lazy then just use duration.
 
or after 3 hits ... using the damage detection you can do that
The only way to know when 3 hits happens is if you were using a damage detection system. There aren't any other methods that won't fail some of the time. If you're already using a DDS and writing an on-damage trigger to count damage instances for this spell, then you have done 90% of the work of triggering the damage block yourself. Seriously, look at the example trigger/code I posted. Blocking the damage yourself is preferable to relying on Hardened Skin (which AFAIK can only reduce damage to 1, not 0) and a Spell Shield, neither of which (as you say) work for triggered damage or spells that don't target spell immune units. So while the OP could do what you suggested, there's no real reason to do so.

Incidentally, I see you're still not reading jack shit in the threads you reply to:
Blocking spells entirely will be more difficult, even more so if you have a significant number of triggered spell effects on your map (where something like spell shield won't work because many triggers don't check for spell immunity/spell shield in their target selection).
 
Looking for help making a castable hero ability that will Block the next 3 attacks. Melee, Ranged or spells.

Im using a custom damage engine but im not sure how to get the code to interact with it. Im assuming Ive got to set an integer that drops by 1 each time an attack occurs.

Any advice ?
 

Attachments

Status
Not open for further replies.
Back
Top