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 haven't received your rank award? Then please contact the administration.
    Dismiss Notice
  4. Rubbed the right way, the genie is out of its lamp! The 12th Concept Art Contest Results have been announced.
    Dismiss Notice
  5. Race against the odds and Reforge, Don't Refund. The 14th Techtree Contest has begun!
    Dismiss Notice
  6. 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.

Dummy Hotkeys

Submitted by CanFight
This bundle is marked as pending. It has not been reviewed by a staff member yet.
A quite small system that allows you to bind a dummy ability to a hidden ability.
This allows you to more or less "change ability hotkeys with triggers".

Note system is limited to MPI.

Code (vJASS):

library DummyHotkeys initializer init

    //NOTE THIS SYSTEM DOES ONLY SUPPORT ACTIVLY USED ABILITIES. DOES NOT WORK WITH AUTOCAST ABILITIES.
    //Written By CanFight

    globals
 
        private integer array DummySpells
        private integer DummySpellCount
        private integer array RealSpellId
        private string array RealSpellOrder
        private boolean array RealSpellTargeting
        private integer SpellCount
        private integer PlayerCount = 24            
 
    endglobals
 
    //make sure that the unit has the Abillity before you apply this.
    //takes player id (0 based), your spells ID, the spells Order Id, its target Type (instant, unit, point or both) and if its an area target spell.
    function SetDummyHotkey takes unit u, integer sid, integer index, string order, integer targetType, boolean aoe returns nothing
        local integer pid = GetPlayerId(GetOwningPlayer(u))
        local integer alvl = GetUnitAbilityLevel(u,sid) - 1
        if RealSpellId[index * PlayerCount + pid] == 0 then
            call UnitRemoveAbility(u, RealSpellId[index * PlayerCount + pid])
        endif
     
        set RealSpellId[index * PlayerCount + pid] = sid
        set RealSpellOrder[index * PlayerCount + pid] = order
     
        if targetType != 0 then
            set RealSpellTargeting[index * PlayerCount + pid] = true
        else
            set RealSpellTargeting[index * PlayerCount + pid] = false
        endif
 
        if GetLocalPlayer() == Player(pid) then
            call BlzSetAbilityIcon(DummySpells[index], BlzGetAbilityIcon(sid) )
            call BlzSetAbilityTooltip(DummySpells[index], BlzGetAbilityTooltip(sid, alvl), 0 )
            call BlzSetAbilityExtendedTooltip(DummySpells[index], BlzGetAbilityExtendedTooltip(sid, alvl), 0 )
        endif
       
        if aoe then
            call BlzSetAbilityIntegerLevelField(BlzGetUnitAbility(u, DummySpells[index]), ABILITY_ILF_OPTIONS, 0, 3 )
            call BlzSetAbilityRealLevelField(BlzGetUnitAbility(u, DummySpells[index]), ABILITY_RLF_AREA_OF_EFFECT, 0, BlzGetAbilityRealLevelField(BlzGetUnitAbility(u, sid), ABILITY_RLF_AREA_OF_EFFECT, alvl) )
        else
            call BlzSetAbilityIntegerLevelField(BlzGetUnitAbility(u, DummySpells[index]), ABILITY_ILF_OPTIONS, 0, 1 )
        endif
     
        call BlzSetAbilityRealLevelField(BlzGetUnitAbility(u, DummySpells[index]), ABILITY_RLF_CAST_RANGE, 0, BlzGetAbilityRealLevelField(BlzGetUnitAbility(u, sid), ABILITY_RLF_CAST_RANGE, alvl) - 10 )
                   
        call BlzUnitHideAbility(u, sid, true )
        call BlzSetAbilityIntegerLevelField( BlzGetUnitAbility(u, DummySpells[index]), ABILITY_ILF_TARGET_TYPE, 0, targetType)
        call BlzSetUnitAbilityManaCost(u, DummySpells[index], 0, BlzGetAbilityManaCost(sid, alvl) )
        call BlzSetUnitAbilityCooldown(u, DummySpells[index], 0, BlzGetAbilityCooldown(sid, alvl) )
     
    endfunction

    private function DummyCast takes nothing returns nothing
        local unit caster = GetTriggerUnit()
        local integer pid = GetPlayerId(GetOwningPlayer(caster))
        local location castPos = GetUnitLoc(caster)
        local location p
        local integer DAbiId = GetSpellAbilityId()
        local integer SAbiIndex = -1
        local integer i = 0
        loop
            exitwhen i >= DummySpellCount
            if DAbiId == DummySpells[i] then
                set SAbiIndex = i
            endif
            set i = i + 1
        endloop
     
        if SAbiIndex == -1 then
            return
        endif
        call BlzSetUnitAbilityManaCost(caster,RealSpellId[SAbiIndex * PlayerCount + pid], GetUnitAbilityLevel(caster,RealSpellId[SAbiIndex * PlayerCount + pid]) - 1,0)
        call BlzUnitHideAbility( caster, RealSpellId[SAbiIndex * PlayerCount + pid], false ) //abillity cant be hidden while being cast.
                                           
        set p = GetSpellTargetLoc()
     
        if RealSpellTargeting[SAbiIndex * PlayerCount + pid] then
            call IssuePointOrderLoc( caster, RealSpellOrder[SAbiIndex * PlayerCount + pid], p)
        else
            call IssueImmediateOrder(caster, RealSpellOrder[SAbiIndex * PlayerCount + pid])
        endif
     
        call RemoveLocation(p)
     
        call BlzUnitHideAbility( caster, RealSpellId[SAbiIndex * PlayerCount + pid], true )
     
        call RemoveLocation(castPos)
        call SetUnitState(caster, UNIT_STATE_MANA, GetUnitState(caster, UNIT_STATE_MANA) + I2R(BlzGetUnitAbilityManaCost(caster, DummySpells[SAbiIndex] , 0)))
    endfunction
 
    private function init takes nothing returns nothing
        local trigger t = CreateTrigger()
     
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT  )
        call TriggerAddAction(t, function DummyCast)
 
        //setup the dummy spells they should be based on a blank channel spell. All of them need base order ids that are not used by other spells.
 
        set DummySpells[0] = 'A000'
        set DummySpells[1] = 'A001'
        set DummySpells[2] = 'A002'
        set DummySpells[3] = 'A003'
        set DummySpellCount = 4
 
    endfunction

endlibrary
 
Contents

Dummy Hotkeys (Map)

  1. _Guhun_

    _Guhun_

    Joined:
    Jun 12, 2010
    Messages:
    371
    Resources:
    7
    Spells:
    6
    Tutorials:
    1
    Resources:
    7
    You should use [ jass ] tag and not [ code ] tag in order to highlight your code. Also, you're gonna need a better description/documentation xD

    Seems to be the same principle that's been discussed in the HiveWE a few times, should be a pretty good system.
     
    Last edited: Jan 2, 2020
  2. JC Helas

    JC Helas

    Joined:
    Oct 19, 2014
    Messages:
    127
    Resources:
    3
    Maps:
    1
    Spells:
    2
    Resources:
    3
    I have to suggest this,
    1. As you share this system obviously a user will read and will look for descriptions, I suggestto document each ability what they does, what will dummy do, how the whole system work.

    2. In SetDummyHotkey, think you have to declare even one local player for getting ID and so the very sensitive GetLocalPlayer()

    Edit: ps dont forget to null the local player

    3. DummyCast, why have to use location when you have the opportunity to use the x,y coords, seems you did used of jass, you have to know location is only good for getting ground heights

    Edit: I guess it is better to use OrderID
    After all the system is useful :D
     
    Last edited: Jan 5, 2020
  3. _Guhun_

    _Guhun_

    Joined:
    Jun 12, 2010
    Messages:
    371
    Resources:
    7
    Spells:
    6
    Tutorials:
    1
    Resources:
    7
    It's pointless to null a local player, player handles are not reference counted and can't even be destroyed.
     
  4. JC Helas

    JC Helas

    Joined:
    Oct 19, 2014
    Messages:
    127
    Resources:
    3
    Maps:
    1
    Spells:
    2
    Resources:
    3
    I dont think so, but we dont do that XD we never left local handle in filled.
     
  5. _Guhun_

    _Guhun_

    Joined:
    Jun 12, 2010
    Messages:
    371
    Resources:
    7
    Spells:
    6
    Tutorials:
    1
    Resources:
    7
    That just shows that you don't know the reason why handle types are nulled. The reason handles are nulled is to avoid a bug that causes JASS to not reduce the reference counter for declared locals when they go out of scope. Players can't be destroyed, so they aren't refrence counted. Which means there is no need to null them at the end of a function.
     
  6. JC Helas

    JC Helas

    Joined:
    Oct 19, 2014
    Messages:
    127
    Resources:
    3
    Maps:
    1
    Spells:
    2
    Resources:
    3
    Thank you for sharing knowledge sir :D
     
  7. KILLCIDE

    KILLCIDE

    Administrator

    Joined:
    Jul 22, 2015
    Messages:
    3,503
    Resources:
    20
    Models:
    2
    Icons:
    10
    Spells:
    7
    Tutorials:
    1
    Resources:
    20
    This is true.


    I took a quick look through your code. Is there a particular reason you are using locations?
     
  8. CanFight

    CanFight

    Joined:
    May 27, 2012
    Messages:
    106
    Resources:
    1
    Maps:
    1
    Resources:
    1
    A thats my mistake actually, might as well have used xy. Will see if i get around fixing it. This system is sadly obsolete as GRID HOTKEYS in reforged more or less make this system useless.

    Edit: Realised i couldnt find a way to not use "GetSpellTargetLoc()". As i already aquire the location no reason to not use the IssuePointOrderLoc instead of IssuePointOrder.
     
    Last edited: Jan 7, 2020
  9. _Guhun_

    _Guhun_

    Joined:
    Jun 12, 2010
    Messages:
    371
    Resources:
    7
    Spells:
    6
    Tutorials:
    1
    Resources:
    7
    Why can't you use GetSpellTargetX and GetSpellTargetY?
     
  10. Diegoit

    Diegoit

    Joined:
    Apr 8, 2017
    Messages:
    1,266
    Resources:
    1
    Models:
    1
    Resources:
    1
    Tbh i didnt understand the spell description