Spell God's Hand

Immolation

Member
Reaction score
20
God's Hand​
Calls forth rays of holy light to allies around the caster. The rays jump and heal nearby targets. Heals less each bounce.

GUI/vJASS= vJASS
Leakless?= Yes.
Lagless?= Yes.
MUI/MPI?= MUI


Changelog:
v2.00
-Updated code.
-Spell can now target random units around the caster.
-Replaced some globals with configurable functions.
-Changed test map.
Code:
JASS:
scope GodsHand initializer Init

//-------------------------------------------------------------
//                  God's Hand by Immolation                
//-------------------------------------------------------------

// Description:
//---------------------------
// Calls forth rays of holy light to allies around the caster. The rays jump and heal nearby targets.
// Heals less each bounce.

// What do I need to import it in my map?
//---------------------------
// You need to download JASS NewGen, available at the following links:
//
// -http://www.thehelper.net/forums/showthread.php?t=73936-
// -http://www.wc3c.net/showthread.php?t=90999-
//
//Install it and then read the following paragraph.

// How do I put it in my map?
//---------------------------
// 1. Copy:
//  a. The "God's Hand" ability.
//  b. The "Healing Wave(God's Hand) ability.
//  c. Copy the "Dummy Unit" into your map(if you already don't have one).
//  d. Copy this trigger.
// 2. Press CTRL + D while in Abilities section in Object Editor to find out the rawcode of:
//  a. The "God's Hand" ability. Change the SPELL_ID to the rawcode that you find(it's 'A000' in this map).
//  b. The "Healing Wave(God's Hand)" ability. Change the HEALWAVE_ID to the rawcode that you find(it's 'A001' in this map).
//  c. The "Dummy Unit" unit. Change the DUMMY_ID to the rawcode that you find(it's 'n000' in this map).
//      (If you already have a dummy unit, change DUMMY_ID to the rawcode of your unit.)
// 3. You have succesfully imported the spell <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />

// Changelog:
//---------------------------
// v2.00
//-Updated code.
//-Spell can now target random units around the caster.
//-Replaced some globals with configurable functions.
//-Changed test map.

//---------------------------
// TheHelper.net

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//                             LIST OF CONFIGURABLES
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//About Configurables:
// Configure the bounces and the healing amount in the Object Editor.

    globals
        //Rawcodes:
        private constant integer SPELL_ID = &#039;A000&#039; //Rawcode of the &quot;God&#039;s Hand&quot; ability.
        private constant integer HEALWAVE_ID = &#039;A001&#039; //Rawcode of the &quot;Healing Wave(God&#039;s Hand)&quot; ability.
        private constant integer DUMMY_ID = &#039;n000&#039; //Rawcode of the &quot;Dummy Unit&quot;.
        
        //Other stuff:
        private constant boolean RANDOM_RAYS = true // If set to true, rays will choose a random target within range to heal.
                                                    // If set to false, rays will always heal the caster and then bounce to nearby targets.
    endglobals

    private function DummyHeight takes integer level returns real
        return 3000 + (level * 1000.00) //Note that this has a graphical effect in game, rays are &quot;faster&quot; if the dummy is higher.
    endfunction
    
    private function NumberOfRays takes integer level returns integer
        return 2 + level
    endfunction
    
    private function TimeBetweenRays takes integer level returns real
        return 0.50 - (0.03 * level)
    endfunction
    
    private function RandomizeArea takes integer level returns real
        return 400.00 + (level * 15.00) // No use unless RANDOM_RAYS is set to true.
    endfunction

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

    globals
        private group g = CreateGroup()
    endglobals

    private function Conditions takes nothing returns boolean
        return GetSpellAbilityId() == SPELL_ID
    endfunction
    
    private function GroupFilter takes nothing returns boolean
        return IsPlayerAlly(GetOwningPlayer(GetFilterUnit()), GetOwningPlayer(GetTriggerUnit())) == true and GetUnitTypeId(GetFilterUnit()) != &#039;n000&#039; 
    endfunction

    private function Main takes nothing returns nothing
        local unit caster = GetTriggerUnit()
        local real x
        local real y
        local integer level = GetUnitAbilityLevel(caster, SPELL_ID)
        local integer LoopStart = 1
        local integer LoopEnd = NumberOfRays(level)
        local player p = GetOwningPlayer(caster)
        local unit dummy
        local unit target
        loop
            exitwhen LoopStart &gt; LoopEnd
            set LoopStart = LoopStart + 1
            if RANDOM_RAYS == true then
                set x = GetUnitX(caster)
                set y = GetUnitY(caster)
                call GroupEnumUnitsInRange(g, x, y, RandomizeArea(level), Condition(function GroupFilter))
                set target = GroupPickRandomUnit(g)
                set dummy = CreateUnit(p, DUMMY_ID, x, y, 0.00)
                call UnitAddAbility(dummy, HEALWAVE_ID)
                call SetUnitAbilityLevel(dummy, HEALWAVE_ID, GetUnitAbilityLevel(caster, level))
                call SetUnitFlyHeight(dummy, DummyHeight(level), 0.00)
                call SetUnitState(target, UNIT_STATE_LIFE, GetUnitState(target, UNIT_STATE_LIFE) - 1.00) //Dummies won&#039;t cast the spell on units with full HP.
                call IssueTargetOrder(dummy, &quot;healingwave&quot;, target)
                call TriggerSleepAction(TimeBetweenRays(level)) 
                else
                set x = GetUnitX(caster)
                set y = GetUnitY(caster)
                set dummy = CreateUnit(p, DUMMY_ID, x, y, 0.00)
                call UnitAddAbility(dummy, HEALWAVE_ID)
                call SetUnitAbilityLevel(dummy, HEALWAVE_ID, GetUnitAbilityLevel(caster, level))
                call SetUnitFlyHeight(dummy, DummyHeight(level), 0.00)
                call SetUnitState(caster, UNIT_STATE_LIFE, GetUnitState(caster, UNIT_STATE_LIFE) - 1.00) //Dummies won&#039;t cast the spell on units with full HP.
                call IssueTargetOrder(dummy, &quot;healingwave&quot;, caster)
                call TriggerSleepAction(TimeBetweenRays(level))
            endif
        endloop
    endfunction

    //===========================================================================
    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(t, Condition(function Conditions))
        call TriggerAddAction(t, function Main)
    endfunction
endscope


Need feedback, thanks.
 

Attachments

  • God's Hand v2.00.w3x
    48.7 KB · Views: 192

bOb666777

Stand against the ugly world domination face!
Reaction score
117
Doesn't this do exactly the same thing as Healing Wave?
 

Immolation

Member
Reaction score
20
Yes, but it is a no-target spell and is cooler(I hope :D)

EDIT: And I made it only to test my JASS skills :O
 

Tom Jones

N/A
Reaction score
437
Yes, but it is a no-target spell and is cooler(I hope :D)

EDIT: And I made it only to test my JASS skills :O
Allow me to comment then:

GH_Constants is useless, you're effictively calling nothing on intialization because globals are moved to the top of the script by JassHelper.

JASS:
function Trig_Gods_Hand_Conditions takes nothing returns boolean
    //if ( not ( GetSpellAbilityId() == GH_SPELL_ID ) ) then
    //    return false
   //endif
    //return true
    return GetSpellAbilityId() == GH_SPELL_ID 
endfunction


JASS:
        call SetUnitAbilityLevel( u, GH_DUMMY_SPELLID, GetUnitAbilityLevel(GetTriggerUnit(), GH_SPELL_ID))
//You&#039;ve assigned the level of the ability to a variable, you might as well use that variable.


You're generally calling alot of constant functions that could be assigned to variables, such as GetTriggerUnit(), GetOwningPlayer(...), and GetUnitState(...).

You may just aswell have your functions inside the scope, and then use the private keyword and use some more intuitive function names.

We normally rename InitTrig to Init and then use that as initializer for the scope/library. Note that by doing so, access to gg_trig_whatever is removed, you'll have to declare a local or global trigger.
 

WolfieeifloW

WEHZ Helper
Reaction score
372
Okay...
You're a mind-reader or something Immolation.
I just made this spell a couple days ago:
JASS:
// +------------------------------------------------------------+
// |                                                            |
// |             -=-=- God&#039;s Right-Hand [v1.0] -=-=-            |
// |                -=-=- By Wolfie[NoCT] -=-=-                 |
// |                    Requires Jass NewGen                    |
// |                                                            |
// +------------------------------------------------------------+
// |                                                            |
// |   Call upon the power of God himself to aid the            |
// |      caster and nearby allies. God sends such holy power   |
// |         the caster gets healed for double the amount of    |
// |            his allies.                                     |
// |                                                            |
// +------------------------------------------------------------+
// |                                                            |
// |   -=-=- How To Implement -=-=-                             |
// |      1. Copy this trigger into your map                    |
// |      2. Copy the abilities into your map                   |
// |      3. Copy DummyCaster unit into your map                |
// |      4. Make sure the &#039;Rawcodes&#039; in the trigger match      |
// |            your maps rawcodes in Object Editor             |
// |      5. Customize the spell                                |
// |      6. Enjoy!                                             |
// |                                                            |
// +------------------------------------------------------------+
// |                                                            |
// |   -=-=- Credits -=-=-                                      |
// |      Credits are not needed, but appreciated               |
// |         Just don&#039;t claim this as yours                     |
// |                                                            |
// +------------------------------------------------------------+
// |   -=-=- Version History -=-=-                              |
// |                                                            |
// |      Version 1.0                                           |
// |         - Initial release                                  |
// |                                                            |
// +------------------------------------------------------------+

scope GodsRightHand initializer GRInit

// +-------------------------------------+
// |       -=-=- MODIFY HERE -=-=-       |
// |       -=-=- MODIFY HERE -=-=-       |
// |       -=-=- MODIFY HERE -=-=-       |
// +-------------------------------------+

    globals
        private constant integer GR_ID = &#039;A000&#039;
        //Rawcode of the &#039;God&#039;s Right-Hand&#039; ability
        
        private constant integer WH_ID = &#039;A001&#039;
        //Rawcode of the &#039;WHeal&#039; ability
        
        private constant integer DUM_ID = &#039;n000&#039;
        //Rawcode of the &#039;DummyCaster&#039; unit
        
        private constant string WHORDER = &quot;healingwave&quot;
        //&#039;Order String - Use/Turn On&#039; of the &#039;WHeal&#039; ability
        
        //Do not touch!
        private sound SIMSOUND = null//Do not touch!
        //Do not touch!
    endglobals
    
    private function HEAL takes integer level returns integer
        return (level * 50)
        //The amount extra that the caster gets healed
    endfunction
    
    private function MANARETURN takes integer level returns integer
        return ((level * 15) + 55)
        //The mana cost of the spell, used to return the mana if unit is at full HP
    endfunction
    
// +----------------------------------------------+
// |       -=-=- NO TOUCHIE PAST HERE -=-=-       |
// |       -=-=- NO TOUCHIE PAST HERE -=-=-       |
// |       -=-=- NO TOUCHIE PAST HERE -=-=-       |
// +----------------------------------------------+
    
    private function SimError takes player ForPlayer, string msg returns nothing
        if SIMSOUND == null then
            set SIMSOUND = CreateSoundFromLabel(&quot;InterfaceError&quot;, false, false, false, 10, 10)
        endif
        if (GetLocalPlayer() == ForPlayer) then
            call ClearTextMessages()
            call DisplayTimedTextToPlayer(ForPlayer, 0.52, -1.00, 2.00, &quot;|cffffcc00&quot;+msg+&quot;|r&quot;)
            call StartSound(SIMSOUND)
        endif
    endfunction    
    
    private function GRConditions takes nothing returns boolean
        return (GetSpellAbilityId() == GR_ID)
    endfunction
    
    private function GRActions takes nothing returns nothing
        local unit tu = GetTriggerUnit()
        local integer QT = GetUnitAbilityLevel(tu, GR_ID)
        local unit u
        
        if(GetUnitState(tu, UNIT_STATE_LIFE) &gt;= GetUnitState(tu, UNIT_STATE_MAX_LIFE)) then
            call SimError(GetOwningPlayer(tu), &quot;Already at full health.&quot;)
            call IssueImmediateOrder(tu, &quot;stop&quot;)
            call TriggerSleepAction(0.00)
            call SetUnitState(tu, UNIT_STATE_MANA, GetUnitState(tu, UNIT_STATE_MANA) + MANARETURN(QT))
        endif
        set u = CreateUnit(GetOwningPlayer(tu), DUM_ID, GetUnitX(tu), GetUnitY(tu), bj_UNIT_FACING)
        call UnitAddAbility(u, WH_ID)
        call SetUnitAbilityLevel(u, WH_ID, QT)
        call IssueTargetOrder(u, WHORDER, tu)
        call UnitApplyTimedLife(u, &#039;BTLF&#039;, 2.00)
        call SetUnitState(tu, UNIT_STATE_LIFE, GetUnitState(tu, UNIT_STATE_LIFE) + HEAL(QT))
        set u = null
        set tu = null
    endfunction

//====================================================================================================
    private function GRInit takes nothing returns nothing
        local trigger t = CreateTrigger()
        local integer i = 0
        
        loop
            call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
            set i = i + 1
        exitwhen i == bj_MAX_PLAYER_SLOTS
        endloop
        call TriggerAddCondition(t, Condition(function GRConditions))
        call TriggerAddAction(t, function GRActions)
    endfunction

endscope
 

wraithseeker

Tired.
Reaction score
122
I think you should trigger the whole thing, wouldn't be that hard.

There is a tutorial by daelin on Chain issues but it is in GUI, check it out.
 

trb92

Throwing science at the wall to see what sticks
Reaction score
142
JASS:
globals
    constant integer GH_SPELL_ID = &#039;A000&#039; //Rawcode of the &quot;God&#039;s Hand&quot; ability.
    constant integer GH_DUMMY_SPELLID = &#039;A002&#039; //Rawcode of the &quot;Healing Wave(God&#039;s Hand)&quot; ability.
    constant integer GH_DUMMY_UNITID = &#039;n000&#039; //Rawcode of the &quot;Dummy Unit&quot;.
    constant real GH_DUMMY_DURATION = 5.00 //Duration of dummy unit.    
    constant real GH_DUMMY_HEIGHT = 10000.00 //Height of dummy unit.
    constant real GH_TIME_BETWEEN_RAYS = 0.33 // Time between rays of light. 
    constant integer GH_RAYS_PER_LEVEL = 1 //Additional rays gained for each level of the spell.
    constant integer GH_RAYS_ADDITIONAL = 2 //Additional rays.
endglobals

Why aren't the globals private? You don't need the GH_ crap, just add the 'private' keyword before 'constant'.

Other then that, the code looks good. Might have downloaded and tried out, but I lack a WC3 on this comp, so I guess I won't.
 

Immolation

Member
Reaction score
20
Updated.

v1.2:
-Updated documentation and code.
- Removed some unneccesary triggers that were in this test map.
 

WolfieeifloW

WEHZ Helper
Reaction score
372
Just two things like your other spell:
  • No [noparse][/noparse] tags needed around links
  • Spacing to make it more readable
 

Dinowc

don't expect anything, prepare for everything
Reaction score
223
it is a no-target spell

call IssueTargetOrder(dummy, "healingwave", caster)

it doesn't matter if it is a non-target spell because it will always cast it on caster (or am I wrong? I haven't tested it actually)... make the dummy cast it on a random allied unit (just for a challenge :p)

and get rid of the BJs, it makes me sick
 

Immolation

Member
Reaction score
20
1) Test it.
2) That BJ(The event one) is needed.
Will fix the other one soon.
3) I think that the spell is fine as it is, with the caster as the target.
 

FhelZone

Have a drink of a nice cold mellowberry juice!
Reaction score
103
Looks pretty cool actually, though I won't agree with the skills name. I would prefer naming it with something else. Something like Iluminate, Devastate, etc.
 

simonake

New Member
Reaction score
72
The map seems to be corrupted. I opened it, pressed on "test map". It opened warcraft at the main page without starting the map.
 

Azlier

Old World Ghost
Reaction score
461
Save the map twice. If you scrolled through the code and such, it requires saving before you can test.
 

WolfieeifloW

WEHZ Helper
Reaction score
372
Make sure to save the map then Test Map right away (JASS makes you have to do that, at least for me) .

Anyways, what's wrong with God's Hand?
I think it fits perfectly.

Again, code looks good although I haven't thoroughly looked through;
Will later along with Pestilence ;) .
 

Immolation

Member
Reaction score
20
Updated.

v1.2b
-Replaced a BJ.

I also noticed that it lags a bit on the first cast, so I suggest preloding it in actual maps. ;)
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top