1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  3. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  4. The Lich King demands your service! We've reached the 19th edition of the Icon Contest. Come along and make some chilling servants for the one true king.
    Dismiss Notice
  5. The 4th SFX Contest has started. Be sure to participate and have a fun factor in it.
    Dismiss Notice
  6. The poll for the 21st Terraining Contest is LIVE. Be sure to check out the entries and vote for one.
    Dismiss Notice
  7. The results are out! Check them out.
    Dismiss Notice
  8. Don’t forget to sign up for the Hive Cup. There’s a 555 EUR prize pool. Sign up now!
    Dismiss Notice
  9. The Hive Workshop Cup contest results have been announced! See the maps that'll be featured in the Hive Workshop Cup tournament!
    Dismiss Notice
  10. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

Vampiric Strike v.46

Submitted by 1)ark_NiTe
This bundle is marked as approved. It works and satisfies the submission rules.
Before viewing the code, note that this is for the spell only. There are two triggers that add the "Unit Takes Damage" events to this trigger. You will find these when you open the map.

Vampiric Strike code
Code (vJASS):
////////////////////////////////////////////////////////////////////
//  Vampiric Strike by 1)ark_NiTe                                 //
//  Originally made for Against the Darkness                      //
//                                                                //
//  dmg = Strength (you can change this to Agility or Intel)      //
//  Total damage = Strength + Real Damage                         //
//  Amount healed = (total damage) * (1 / (7 - Level of Ability)) //
//                                                                //
////////////////////////////////////////////////////////////////////

//==================================================================================================================================
// Start of constants. These provide the user with easier implementing//changing of the spell's rawcodes and effects. All of these can be changed.
//==================================================================================================================================

constant function Vamp_Strike_ID takes nothing returns integer
    return 'A002' // Vampiric Strike ability rawcode.
endfunction

constant function Vamp_Strike_Weapon_SFX takes nothing returns string
    return "Abilities\\Spells\\Human\\SpellSteal\\SpellStealTarget.mdl" // SFX created on the attacker's weapon.
endfunction

constant function Vamp_Strike_Link_SFX takes nothing returns string
    return "Abilities\\Spells\\NightElf\\ManaBurn\\ManaBurnTarget.mdl" // SFX created on both units to represent their link.
endfunction

constant function Vamp_Strike_Heal_SFX takes nothing returns string
    return "Abilities\\Spells\\Undead\\VampiricAura\\VampiricAuraTarget.mdl" // SFX created on the attacker's body to represent life healed.
endfunction

//==================================================================================================================================
//End of constants. Do not touch anything below this if you are unfamiliar with JASS.
//==================================================================================================================================

//==================================================================================================================================
//Spell conditions.
//==================================================================================================================================

function Vampiric_Strike_Conds takes nothing returns boolean
    return GetOwningPlayer(GetTriggerUnit()) != GetOwningPlayer(GetEventDamageSource()) and IsUnitType(GetTriggerUnit(), UNIT_TYPE_STRUCTURE) == false and IsUnitInGroup(GetEventDamageSource(), udg_JustCastSpell) == false and GetUnitAbilityLevel(GetEventDamageSource(), Vamp_Strike_ID()) >=1 and GetRandomInt(1, 100) <= 15
endfunction

//==================================================================================================================================
//Spell actions. Main block of coding
//==================================================================================================================================

function Trig_Vampiric_Strike takes nothing returns nothing
    // Declares Local Variables
    local unit d = GetEventDamageSource()
    local unit t = GetTriggerUnit()
    local texttag tag
    local integer i = GetUnitAbilityLevel(d, Vamp_Strike_ID())
    local force f = CreateForce()
    local force g = CreateForce()
    local real a
    local real r
    local real rd
    local real dmg = GetHeroStr(GetEventDamageSource(), true)
    local real l = GetEventDamage()
    local trigger trig = GetTriggeringTrigger()
    call DisableTrigger(trig)
    set a = GetUnitArmor(t)
    set rd = GetFullDamage(dmg, a)
    set r = GetReducedDamage(rd, a)
    call DestroyEffect(AddSpecialEffectTarget(Vamp_Strike_Weapon_SFX(), d, "weapon"))
    call DestroyEffect(AddSpecialEffectTarget(Vamp_Strike_Link_SFX(), d, "origin"))
    call DestroyEffect(AddSpecialEffectTarget(Vamp_Strike_Heal_SFX(), d, "origin"))
    call DestroyEffect(AddSpecialEffectTarget(Vamp_Strike_Link_SFX(), t, "origin"))
    call DisableTrigger( GetTriggeringTrigger() )
    call UnitDamageTarget(d, t, r, true, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
    call EnableTrigger(trig)
    // If you wish to change the amount healed, you can do so in the line below.
    call SetWidgetLife(d, (GetWidgetLife(d)) + ((l + r) * (1.00 / (7.00 - I2R(i)))))
    call EnableTrigger( GetTriggeringTrigger() )
    // Creates Floating Text showing the Damage Dealt + Damage Healed
    set tag = CreateTextTagUnitBJ( ( "|cffFF0000" + ( I2S(R2I(( l + r ))) + ( "|r" + ( "/" + ( "|cff00FF00" + I2S(R2I(( ( l + r ) * ( 1 / ( 7.00 - i )))))))))), d, 0, 10, 100, 100, 100, 0 )
    if (IsPlayerInForce(GetLocalPlayer(), bj_FORCE_ALL_PLAYERS))then
        call SetTextTagVisibility(tag, false)
    endif
    call ForceEnumAllies(f, GetOwningPlayer(d), null)
    call ForceEnumAllies(g, GetOwningPlayer(t), null)
    if (IsPlayerInForce(GetLocalPlayer(), f)) or (IsPlayerInForce(GetLocalPlayer(), g)) then
        call SetTextTagVisibility(tag, true)
    endif
    call SetTextTagVelocity(tag, 0, 0.04)
    call SetTextTagPermanent(tag, false)
    call SetTextTagFadepoint(tag, 2.00)
    call SetTextTagLifespan(tag, 3.00)
    call DestroyForce(f)
    call DestroyForce(g)
    set tag = null
    set f = null
    set g = null
    set d = null
    set t = null
endfunction

//===========================================================================
function InitTrig_Vampiric_Strike takes nothing returns nothing
    set gg_trg_Vampiric_Strike = CreateTrigger(  )
    call TriggerAddCondition( gg_trg_Vampiric_Strike, Condition( function Vampiric_Strike_Conds ) )
    call TriggerAddAction( gg_trg_Vampiric_Strike, function Trig_Vampiric_Strike )
endfunction


Gives a 15% chance to deal the Hero's total Strength in extra damage on an attack and regain hit points by a factor of the extra damage.

Level 1 - 1/6 total damage regained.
Level 2 - 1/5 total damage regained.
Level 3 - 1/4 total damage regained.
Level 4 - 1/3 total damage regained.

This spell was originally made for my project Against the Darkness.

+Multi-Instanceable
+Leakless
+No Imports
+Easily Transferable


Known Error: This spell will trigger from Immolation damage. If anyone knows of a way to fix this then let me know.

Updates (recent to past):

v.46 (current):

-Removed unnecessary function I2R. Thanks Bribe!

v.45:

-Added Rising_Dusk's ArmorUtils system to very accurately damage units.

v.40:

-Added a trigger that prevents Vampiric Strike from executing when any negative ability is cast by the Hero.


v.35:

-Created constant functions to make replacing rawcodes and effects simple during spell implementation.
-Updated/expanded documentation

v.30:
-Fixed Force leaks
-Changed SetUnitState() to SetWidgetLife()

v.25:
-bj's fixed by Deuterium. Thanks :p

v.20:
-Changed effects
-Removed 'Swap' bj's
-Added groups to show text tags to
-Added natives inside "ShowTextTagForceBJ"
-Will no longer trigger if attacking structures

v.15:

-Replaced SetUnitLifeBJ() with SetUnitState()
-Fixed Text Tag Line because it was referencing wrong rawcode
-Added comment block to beginning of spell

Keywords:
Death Knight, Against the Darkness, Vampire, Vampiric Strike, Critical Strike, Strike, 1)ark_NiTe, AtD
Contents

Vampiric Strike (Map)

Reviews
Moderator
18:25, 11th Jun 2009 hvo-busterkomo: A decent JASS spell, although lacking configuration the effect is nice. The strings of the effects should be configurable, as well the spell id. The only thing stopping me from approving this is the leaks. You...
  1. 18:25, 11th Jun 2009
    hvo-busterkomo: A decent JASS spell, although lacking configuration the effect is nice. The strings of the effects should be configurable, as well the spell id.

    The only thing stopping me from approving this is the leaks. You should be using DestroyForce, not ForceClear.

    Edit: Changes made, looks good.
     
  2. Kingz

    Kingz

    Joined:
    Jun 5, 2008
    Messages:
    2,470
    Resources:
    6
    Spells:
    5
    Tutorials:
    1
    Resources:
    6
    Remove the floating text, those are rare and not so usefull in spells.
    Btw why are you using so many bj's?
    Use natives they are faster, bj functions just call another function making it slower.
    Also please replace gg_trg_Vampiric_Strike with a local trigger t.
    Make a settings block on the begining of the spell:
    -dummy raw number
    -ability raw number
    -damage
    and so on...
    Not to be harsh but this looks like you just converted a GUI trigger and made little modifications :p
    Again remove the bj functions and optionaly add a better damage detection system.
     
  3. Deuterium

    Deuterium

    Joined:
    Mar 17, 2009
    Messages:
    1,301
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    Nicee ideaa :) I'll check the triggering and scripting tonight :)
     
  4. 1)ark_NiTe

    1)ark_NiTe

    Joined:
    Nov 1, 2006
    Messages:
    1,680
    Resources:
    5
    Maps:
    1
    Spells:
    3
    Tutorials:
    1
    Resources:
    5
    Floating text is important in this spell to know what your extra damage dealt is and how much you were healed for. Why would I remove it?

    I know bj's call other functions, however the remaining text tag bj's are really confusing to replace. The coding for them all to be replaced would be nearly 20 lines longer. I think in this case using those bj's is perfectly acceptable.

    However, I just changed the SetUnitLifeBJ() to "SetUnitState()". Thanks for pointing that out.

    I did originally convert the blank trigger from GUI, but all JASS the work was done in Jasscraft. That is only because I don't know how to create the bottom part from scratch. I'm pretty sure changing "gg_trg_Vampiric_Strike" to "t" is purely aesthetic though and wouldn't make a difference in efficiency. Correct me if I'm wrong.

    Done deal.
     
  5. Deuterium

    Deuterium

    Joined:
    Mar 17, 2009
    Messages:
    1,301
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    Well you do use alot of BJ's. Here are some of the things you can fix:

    Code (vJASS):
    local integer i = GetUnitAbilityLevelSwapped('A002', d)


    Code (vJASS):
    call SetUnitState(d,UNIT_STATE_LIFE,((GetUnitStateSwap(UNIT_STATE_LIFE, d)) + ((l + r) * (1.00 / (7.00 - I2R(i))))))

    Said simple, the keyword Swap means that the parameters in the parenthesis are swapped.

    Example: BlaSwap(Bye, Hi) calls Bla(Hi, Bye)
    So just remove that keyword and swap what's inside.

    More:
    Code (vJASS):
    GetForceOfPlayer(GetOwningPlayer(d))


    Code (vJASS):
    GetPlayersAllies(GetOwningPlayer(t))


    There might be one or two more. Btw, I ignored TextTags as those are very complicated if not BJ's...


    EDIT:
    I came back for some more!

    Add some eyecandy :) and an effect to the weapon or something... some nice yet simple touch

    And to help you further with BJ's as I missed these two very simple things:
    Code (vJASS):
    call ShowTextTagForceBJ( false, bj_lastCreatedTextTag, bj_FORCE_ALL_PLAYERS )

    instead of,
    Code (vJASS):
    call ShowTextTagForceBJ( false, GetLastCreatedTextTag(), GetPlayersAll() )
     
  6. 1)ark_NiTe

    1)ark_NiTe

    Joined:
    Nov 1, 2006
    Messages:
    1,680
    Resources:
    5
    Maps:
    1
    Spells:
    3
    Tutorials:
    1
    Resources:
    5
    Cool I'll fix those. I had no idea that's what swap meant haha. Thanks.

    Also, what did you want me to do with these?

    You just pasted what I had, not what I should do with them.
     
  7. Deuterium

    Deuterium

    Joined:
    Mar 17, 2009
    Messages:
    1,301
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    Hahaha I though you'll know how to fix these...

    Here it is:

    Code (vJASS):
        local force f = CreateForce()
        local force al = CreateForce()
        //all the actions
        call ForceAddPlayer(f, GetOwningPlayer(t))
        call ShowTextTagForceBJ( true, GetLastCreatedTextTag(), f )
        call ForceEnumAllies(al, GetOwningPlayer(t), null)
        call ShowTextTagForceBJ( true, GetLastCreatedTextTag(), al)
     
  8. Kingz

    Kingz

    Joined:
    Jun 5, 2008
    Messages:
    2,470
    Resources:
    6
    Spells:
    5
    Tutorials:
    1
    Resources:
    6
    o_O
    You didn't know what Swap means?
    Just that the parameters are switched, also it's immensively stupid that blizzard made swaped version of already existing functions :p
    Again this was made because of GUI.
     
  9. Deuterium

    Deuterium

    Joined:
    Mar 17, 2009
    Messages:
    1,301
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    exactly Kingz, the whole swap thing was so that GUI functions properly... specially since everything in GUI comes in the form of text rather than code
     
  10. 1)ark_NiTe

    1)ark_NiTe

    Joined:
    Nov 1, 2006
    Messages:
    1,680
    Resources:
    5
    Maps:
    1
    Spells:
    3
    Tutorials:
    1
    Resources:
    5
    OOooh right Deut. I had no idea what you were inferring there for a sec heh.
     
  11. Deuterium

    Deuterium

    Joined:
    Mar 17, 2009
    Messages:
    1,301
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    hehe don't worry, now you knw xD

    EDIT:
    I should have mentioned this earlier but I didn't notice:
    Code (vJASS):
    bj_lastCreatedTextTag

    instead of:
    Code (vJASS):
    GetLastCreatedTextTag()


    EDIT:
    Here's an edited one by me where I removed all BJ's except for one which whenever I remove bugs although I'm 100% I was doing it right!
    I also nulled two locals you forgot to null...
    ENJOY :D
     

    Attached Files:

    Last edited: Jun 10, 2009
  12. 1)ark_NiTe

    1)ark_NiTe

    Joined:
    Nov 1, 2006
    Messages:
    1,680
    Resources:
    5
    Maps:
    1
    Spells:
    3
    Tutorials:
    1
    Resources:
    5
    Thanks. but I was taught by PurplePoot that integers and reals do not need to be nulled. I mean 0 is still a value, as is 1 or 2 or 3. Right? Why set = 0?
     
  13. Deuterium

    Deuterium

    Joined:
    Mar 17, 2009
    Messages:
    1,301
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    Well, some people say it needs to be nulled some say it doesnt. Now I always used to think like Purplepoot does and believe that nulling reals and integers is stupid, but most people do it, so we need some proof to which is better.

    Well anyone who understands binary codes should be able to judge, I mean we just need to know if the binary code of the number zero takes space or nope, for it's binary code is simply made of a spam of zeroes...
     
  14. Kingz

    Kingz

    Joined:
    Jun 5, 2008
    Messages:
    2,470
    Resources:
    6
    Spells:
    5
    Tutorials:
    1
    Resources:
    6
    Integers and reals do not need to be nulled, that is set to 0.
     
  15. Deuterium

    Deuterium

    Joined:
    Mar 17, 2009
    Messages:
    1,301
    Resources:
    2
    Spells:
    1
    Tutorials:
    1
    Resources:
    2
    "Changed SetUnitState() to SetWidgetLife()"
    Does it really make a difference? I mean I use the Widget one but it's just cause it's more general...
     
  16. Flame_Phoenix

    Flame_Phoenix

    Joined:
    May 4, 2007
    Messages:
    2,283
    Resources:
    11
    Tools:
    1
    Maps:
    1
    Spells:
    6
    Tutorials:
    3
    Resources:
    11
    I fills me with joy to see one of my old old friends didn't leave wc3 yet.
    And even better, he is now a Jasser (why not vJasser too? ) xD

    God, long time no see. I will take a look at this, for the sake of good old times.
    Hope you still remember my name, I surely remember yours buddy =P
     
  17. 1)ark_NiTe

    1)ark_NiTe

    Joined:
    Nov 1, 2006
    Messages:
    1,680
    Resources:
    5
    Maps:
    1
    Spells:
    3
    Tutorials:
    1
    Resources:
    5
    It makes it easier to read, as HVO said, and also GetUnitState(u, UNIT_STATE_LIFE) is longer than GetWidgetLife(u).

    Hey Flame. Of course I remember you. You gave me many good suggestions for AtD. Good to see you and hopefully you appreciate the spell.
     
  18. Dark_Dragon

    Dark_Dragon

    Joined:
    Jul 19, 2007
    Messages:
    596
    Resources:
    8
    Tools:
    1
    Spells:
    7
    Resources:
    8
    GetWidgetLife and SetWidgetLife are more safe and faster...

    as well your hide for texttag is way to bad! its acceptable but i suggest fully leakless and fast way!

    you where leaking this null filters and you had to first hide texttag and then do local player while my code does not leak at all, uses one force and simple hides it for players which are not ally of attacked unit or attacker (same as u did)

    Code (vJASS):

    function VS_EnumPlayers takes nothing returns boolean
        if not ( IsPlayerAlly(GetOwningPlayer(GetTriggerUnit(), GetFilterPlayer()) or IsPlayerAlly(GetOwningPlayer(GetEventDamageSource(), GetFilterPlayer())) ) then
            if (GetLocalPlayer() == GetFilterPlayer()) then
                call SetTextTagVisibility(bj_lastCreatedTextTag, false)
            endif
        endif
        return false
    endfunction

    local force f = CreateForce()
        local filterfunc ff = Filter(function VS_EnumPlayers)
        call ForceEnumPlayers(f, ff)
        call DestroyFilter(ff)
        call DestroyForce(f)
        set f = null
        set ff = null
     


    all other is fine, well ofc damage detection is way to bad, but until i release my librarys there is currently no better way of doing it... and yeah your trigger will fire even if an spell deals an damage... as well not possible until libs are done!

    i expect that you will fix this filter leaks and make spell more configurable!

    in default jass its done by writing constant functions which are very fast!

    Code (vJASS):

    constant function VS_DamageEffect takes nothing returns string
        return "Abilities\\Spells\\Human\\SpellSteal\\SpellStealTarget.mdl"
    endfunction

    constant function VS_AttachPoint takes nothing returns string
        return "weapon"
    endfunction

    call DestroyEffect(AddSpecialEffectTarget(VS_DamageEffect(), d, VS_AttachPoint()))
     


    like that ofc give your own names to functions!

    for now its 3/5!
    but ill give it a 4/5 once you fix leaks and make it easy editable!

    Greets!
    ~Dark Dragon
     
  19. Flame_Phoenix

    Flame_Phoenix

    Joined:
    May 4, 2007
    Messages:
    2,283
    Resources:
    11
    Tools:
    1
    Maps:
    1
    Spells:
    6
    Tutorials:
    3
    Resources:
    11
    They are not safer, they are simply faster. Even if you change them, you will win only a few nanoseconds.

    However I agree you should use them, in the name of code readability.

    There are other ways...
    - IDDS
    - LLDD
    - ADamage
    - xedamage
    ....

    all systems of high quality made by other people ...