JASS Spells to work on.

warden13

New Member
Reaction score
32
Hi, I started to jass yesterday. I want to use it for spellmaking. I read some tutorials and got the basics. However, I need some easy JASS spells to work on. So I will be able to deal with all types of spells. If you have some basic spells coded with JASS. I need them. Every kind of spell is ok. I looked here and some other sites but their JASS Spell Resources are advanced things +rep for each spell. ...
 

wraithseeker

Tired.
Reaction score
122
Try making a JASS spell that steals life from the target and give the life to the caster, it is included in cohadar's graveyarded tutorial.
 

Viikuna

No Marlo no game.
Reaction score
265
JASS:
scope WarStomp initializer init
//====================================================================================
//==================================================================================
globals
            private constant integer ABILITY_ID = 'A000'
            private constant integer DEALERS_HAND = 'A001'
            private constant integer DEALER_ID = 'n000'
            private constant real AOE = 250.0
            private constant real DAMAGE = 25.0
            private constant string EFFECT_PATH = "Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl"

//====================================================================================
//====================================================================================    
    private group TempG = CreateGroup()
    private unit TempU
    private filterfunc F
    private unit Dealer
endglobals

private function Filtteri takes nothing returns boolean
    return IsUnitAlly(GetFilterUnit(),GetOwningPlayer(TempU))==false and GetWidgetLife(GetFilterUnit())>.405
endfunction

private function YesWeCan takes nothing returns nothing
     local unit u=GetTriggerUnit()
     local real x=GetUnitX(u)
     local real y=GetUnitY(u)
     local integer level=GetUnitAbilityLevel(u,ABILITY_ID)
     local unit target
     local player p=GetOwningPlayer(u)
     set TempU=u
     call GroupEnumUnitsInRange(TempG,x,y,AOE,F)
     call DestroyEffect(AddSpecialEffect(EFFECT_PATH,x,y))
     call SetUnitAbilityLevel(Dealer,DEALERS_HAND,level)
     loop
         set target = FirstOfGroup(TempG)
         exitwhen target == null
         set x = GetUnitX(target)
         set y = GetUnitY(target)
         call SetUnitX(Dealer,x)
         call SetUnitY(Dealer,y)
         call IssueTargetOrder(Dealer,"thunderbolt",target)
         call UnitDamageTarget(u,target,DAMAGE*level,false,false,ATTACK_TYPE_NORMAL,DAMAGE_TYPE_MAGIC,WEAPON_TYPE_WHOKNOWS)
         call GroupRemoveUnit(TempG,target)
     endloop
     set u = null
endfunction

private function CanWeStomp takes nothing returns boolean
    return GetSpellAbilityId() == ABILITY_ID
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 CanWeStomp))
    call TriggerAddAction(t,function YesWeCan)
    set F = Filter(function Filtteri)
    set Dealer = CreateUnit(Player(13),DEALER_ID,0.0,0.0,0.0)
endfunction

endscope


War Stomp. You know what it is like. This might be helpful and it is really simple.
 

warden13

New Member
Reaction score
32
I have some quetsions.
1-)What is scope, what it does?
2-)Do I have to set globals? Or they are just making easier to work with them?
3-)Dealer = Dummy Right?
4-)What is difference between
JASS:
private constant
and
JASS:
private

5-)In this line,
JASS:
private group TempG = CreateGroup()
Can I change it to
JASS:
private group TempG

6-)What is . I don't get how to filter units.
7-)What is and why it must be bigger than .405
:cool:What it is .405? Isn't it supposed to be 0.405. (Or what is the function of [.] in jass?)
9-)Maybe more in future...
 

wraithseeker

Tired.
Reaction score
122
Take a look at my post.


Private is well private, you can't touch it outside the trigger.

Private constant is something that cannot change it's value.

For the Group part, using CreateGroup() shortens one line of code you need to do, if you do not have that then there will ben o group but a variable available only.

GetFilterUnit() is Matching Unit in GUI

GetWidgetLife have to be bigger then .xxxxx because warcraft coutns a unit dead if it gos down that limit so if you get a widget's life that is lower then that then there is no point.

Or what is the function of [.] in jass?)

> I do not get what you are saying.
 

Tom Jones

N/A
Reaction score
437
5) Nope.
6) Matching Unit.
7) Units, item, and destructables are all "sub" types of widget type. A widget with hp below .405 is considered dead.
8) .405 = 0.405 and .01 = 0.01 and 1.25 != .25
 

Viikuna

No Marlo no game.
Reaction score
265
Widgets are things that can take damage. Thats why UnitDamageTarget takes widget target.

Units, destructibles and items extend widget.

5) If you do that, you need to create your group in initializer function, like this: set TempG=CreateGroup()
Groups have to be created before you can use them.

3) Yea, Dealer is a dummy unit. I use him to stun all those units who need to be stunned.
 

warden13

New Member
Reaction score
32
Ok thanks for all help. I tried to convert my old GUI abilites to JASS. I had only one problem with this. I want to create units in a line between two trees. It does not work properly. Everytime I cast this, units are spawned as a line but everytime to 45 degrees. I figure out I always increase X and Y, so it is normal. What should I change here.
After fixing this, how to destroy leaks or errors.

JASS:
function Trig_ET_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
endfunction

function filtre takes nothing returns boolean
    return ( GetDestructableTypeId(GetFilterDestructable()) == 'ATtr' )
endfunction

function Trig_ET_Actions takes nothing returns nothing
    local unit u
    local player p
    local group g = CreateGroup()
    local destructable t1
    local destructable t2
    local location loc0
    local location loc1
    local location loc2
    local real x
    local real y
    local real dis
    local integer mc
    local integer count
    local rect area
    local unit m
set count = 0
set u = GetSpellAbilityUnit()
set p = GetOwningPlayer(u)
set t1 = GetSpellTargetDestructable()
set loc0 = GetUnitLoc(u)
set area = RectFromCenterSizeBJ(loc0, 300.00, 300.00)
set t2 = RandomDestructableInRectBJ(area, Condition(function filtre))
set loc1 = GetDestructableLoc(t1)
set loc2 = GetDestructableLoc(t2)
set x = GetDestructableX(t2)
set y = GetDestructableY(t2)
set dis = DistanceBetweenPoints(loc1, loc2)
set mc = R2I(dis/30)

loop
    exitwhen count > mc
    set x = x + 30
    set y = y + 30
    set m = CreateUnit(p, 'n001', x, y, 0)
    call GroupAddUnit(g, m)
    set count = count + 1
endloop
endfunction

function InitTrig_ET takes nothing returns nothing
    set gg_trg_ET = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_ET, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_ET, Condition( function Trig_ET_Conditions ) )
    call TriggerAddAction( gg_trg_ET, function Trig_ET_Actions )
endfunction
 

13lade619

is now a game developer :)
Reaction score
399
Angle between points.
JASS:
function AngleBetweenPoints takes location locA, location locB returns real
    return bj_RADTODEG * Atan2(GetLocationY(locB) - GetLocationY(locA), GetLocationX(locB) - GetLocationX(locA))
endfunction


and polar projection.
JASS:
function PolarProjectionBJ takes location source, real dist, real angle returns location
    local real x = GetLocationX(source) + dist * Cos(angle * bj_DEGTORAD)
    local real y = GetLocationY(source) + dist * Sin(angle * bj_DEGTORAD)
    return Location(x, y)
endfunction


..use the calculations, not the functions.
 

wraithseeker

Tired.
Reaction score
122
You should explain it to him on how to use it the non BJ way, using their calculations is no different from using a BJ

Use polarprojection calculations but take away that bj_DEGTORad as it is useless.

For distance between points just do Atan2(.....)
 

warden13

New Member
Reaction score
32
JASS:
set abp = bj_RADTODEG * Atan2(GetLocationY(loc1) - GetLocationY(loc2), GetLocationX(loc1) - GetLocationX(loc2))
set x = x + 30 * Cos(abp * bj_DEGTORAD)
set y = y + 30 * Sin(abp * bj_DEGTORAD)


This works now.

OMG. It worked awesome. Thank you. This was first part of my spell. Now senond part. You may be noticed I add every spawned unit to a unit group. By the way:
JASS:
set m = CreateUnit(p, 'n001', x, y, 0)
call GroupAddUnit(g, m)
Does that work?

If a unit in unit group dies, kill all units in group. How can I do it?
 

Akolyt0r

New Member
Reaction score
33
wraithseeker, if you want to help, please be as precise as possible, or you might cause even more outrage...
Private is well private, you can't touch it outside the trigger.
wrong - private doesnt even work inside a plain trigger ...private/public refer to the scope/library they are in, NOT the trigger.
However, most of the timer you will have one scope for each spell ...and librarys for the systems..

Private constant is something that cannot change it's value.
private has nothing to do with this...
you can use constant for functions and/or variables.
constant variables cannot be change at runtime, and have to be initialized.
constant functions can NOT call non-constant functions.
the advantage of "constant" is, that constant functions/variables are slightly faster than their non-constant counterparts.
constant stuff is most often used for configuration in spells/systems..
 

wraithseeker

Tired.
Reaction score
122
JassHelper Private members With the adition of libraries it was a good idea to add some scope control said:
JASS:
library privatetest
    globals
        private integer N=0
    endglobals
    private function x takes nothing returns nothing
        set N=N+1
    endfunction

    function privatetest takes nothing returns nothing
        call x()
        call x()
    endfunction
endlibrary

library otherprivatetest
    globals
        private integer N=5
    endglobals
    private function x takes nothing returns nothing
        set N=N+1
    endfunction

    function otherprivatetest takes nothing returns nothing
        call x()
        call x()
    endfunction
endlibrary
[/JASS]
Notice how both libraries have private globals and functions with the same names, this wouldn't cause any syntax errors since the private preprocessor will make sure that private members are only available for that scope and don't conflict with things named the same present in other scopes. In this case private members are only to be used by the libraries in which they are declared.

Sometimes, you don't want the code to go to the top of your script (it is not really a function library) yet you' still want to use the private keyword for a group of globals and functions. This is the reason we defined the scope keyword

The scope keyword has this syntax: scope NAME [...script block...] endscope

So, functions and other declarations inside an scope can freely use the private members of the scope, but code outside won't be able to. (Notice that a library is to be considered to have an internal scope with its name)

There are many applications for this feature:

JASS:
scope GetUnitDebugStr

    private function H2I takes handle h returns integer
        return h
        return 0
    endfunction

    function GetUnitDebugStr takes unit u returns string
        return GetUnitName(u)+"_"+I2S(H2I(u))
    endfunction
endscope

In this case, the function uses H2I, but H2I is a very common function name, so there could be conflicts with other scripts that might declare it as well, you could add a whole preffix to the H2I function yourself, or make the function a library that requires another library H2I, but that can be sometimes too complicated, by using an scope and private you can freely use H2I in that function without worrying. It doesn' matter if another H2I is declared elsewhere and it is not a private function, private also makes the scope keep a priority for its members.

It is more important for globals because if you make a function pack you might want to disallow direct access to globals but just allow access to some functions, to keep a sense of encapsullation, for example.

The way private work is actually by automatically prefixing scopename(random digit)__ to the identifier names of the private members. The random digit is a way to let it be truly private so people can not even use them by adding the preffix themselves. A double _ is used because we decided that it is the way to recognize preprocessor-generated variables/functions, so you should avoid to use double __ in your human-declarated identifier names. Being able to recognize preprocessor-generated identifiers is useful when reading the output file (for example when PJass returns syntax errors).

In order to use private members ExecuteFunc or real value change events you have to use SCOPE_PRIVATE (see bellow)

Hint:Scopes support initializer just like libraries, there is a difference in implementation and it is that they use a normal call rather than an ExecuteFunc call, if you need a heavy process to init a scope, better use a library initializer or call a subfunction using ExecuteFunc from the scope initializer.

Note:In a similar way to libraries, scopes used to have a syntax that required //! , that old syntax is deprecated and will cause a syntax error

For private constant, It's true I am right, what I am trying to say that the value is fixed and shouldn't be changed and like you said yeah, for spell ID code, order strings etc.

If you don't really know that, then if you read it up you should get the meaning of constant is about something that is a fixed value.
 

warden13

New Member
Reaction score
32
LoL I am just a beginner :D And I just need to know how to detect If a unit in g group dies, then kill all units in g, clean all variables and no leak..

JASS:
function Trig_ET_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A000'
endfunction

function filtre takes nothing returns boolean
    return ( GetDestructableTypeId(GetFilterDestructable()) == 'ATtr' )
endfunction

function Trig_ET_Actions takes nothing returns nothing
    local unit u
    local player p
    local group g = CreateGroup()
    local destructable t1
    local destructable t2
    local location loc0
    local location loc1
    local location loc2
    local real x
    local real y
    local real dis
    local integer mc
    local integer count
    local rect area
    local unit m
set count = 0
set u = GetSpellAbilityUnit()
set p = GetOwningPlayer(u)
set t1 = GetSpellTargetDestructable()
set loc0 = GetUnitLoc(u)
set area = RectFromCenterSizeBJ(loc0, 300.00, 300.00)
set t2 = RandomDestructableInRectBJ(area, Condition(function filtre))
set loc1 = GetDestructableLoc(t1)
set loc2 = GetDestructableLoc(t2)
set x = GetDestructableX(t2)
set y = GetDestructableY(t2)
set dis = DistanceBetweenPoints(loc1, loc2)
set mc = R2I(dis/30)
set abp = bj_RADTODEG * Atan2(GetLocationY(loc1) - GetLocationY(loc2), GetLocationX(loc1) - GetLocationX(loc2))


loop
    exitwhen count > mc
    set x = x + 30 * Cos(abp * bj_DEGTORAD)
    set y = y + 30 * Sin(abp * bj_DEGTORAD)
    set m = CreateUnit(p, 'n001', x, y, 0)
    call GroupAddUnit(g, m)
    set count = count + 1
endloop
endfunction

function InitTrig_ET takes nothing returns nothing
    set gg_trg_ET = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_ET, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_ET, Condition( function Trig_ET_Conditions ) )
    call TriggerAddAction( gg_trg_ET, function Trig_ET_Actions )
endfunction
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top