• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

[JASS] Very First Library

Status
Not open for further replies.
Level 16
Joined
Oct 12, 2008
Messages
1,570
Hello people,,
I tried to do some vJass some day,,
And this is what i made,, I am asking you for any mistakes i made or improvements!
JASS:
library GoldGain Initializer Init
   globals
      private constant real TimeInterval = 60
      private constant real array GoldPerInterval
      private constant integer AbID = 'A000' 
   endglobals
   struct GG
   unit u
      timer t
   method Start
      local GG g = g.Allocate()
             set g.u = GetTriggerUnit
      call TimerStart(g.t, TimeInterval, true, function GG.Loop)
   endmethod
   method Loop
      local GG g = g.Allocate()
      if GetUnitAbilityLevel(g.u, AbID()) != 0 then
         call SetPlayerState(GetOwningPlayer(g.u), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(GetOwningPlayer(g.u), PLAYER_STATE_RESOURCE_GOLD) + GoldPerInterval[GetUnitAbilityLevel(g.u, AbID)])
      else
         call PauseTimer(g.t)
         call Destroy Timer(g.t)
      endif
   endstruct 
   function Init takes nothing returns nothing
      local trigger t = CreateTrigger()
      local integer i = 1
      call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_HERO_SKILL)
      call TriggerAddAction(t, function GG.Start)
      loop
         exitwhen i = 4
         set GoldPerInterval[i] = -20 + 60 * i
      endloop
   endfunction
endlibrary

Thanks!:grin:

-Yixx,,-

EDIT: I had a good look at Dynasti's spells to understand properly how to manage methods!
Thank you Dynasti =)

RE-EDIT: My computer wont let me instal any vJass programs (Yet, but it will!), so mistakes in typing are not stupid, =P
Well, they still are, but you know what i mean!
 
Last edited:
Level 14
Joined
Nov 23, 2008
Messages
187
JASS:
library GoldGain initializer Init uses TimerUtils
  globals
    private constant real TimeInterval = 60

    // integer, not real
    private integer array GoldPerInterval
    private constant integer AbID = 'A000'
  endglobals

  struct GG
    unit u
    timer t

    // forgot about "takes" and "returns"?
    static method Loop takes nothing returns nothing
      local GG g = GetTimerData(GetExpiredTimer())

      // AbID is not a function, it's variable, therefore it doesn't need ()
      if GetUnitAbilityLevel(g.u, AbID) != 0 then
        call SetPlayerState(GetOwningPlayer(g.u), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(GetOwningPlayer(g.u), PLAYER_STATE_RESOURCE_GOLD) + GoldPerInterval[GetUnitAbilityLevel(g.u, AbID)])
      else
        call PauseTimer(g.t)

        // any name should not contain spaces
        // "DestroyTimer", not "Destroy Timer"
        // we would use TimerUtils, so ReleaseTimer(g.t) instead of DestroyTimer(g.t) 
        call ReleaseTimer(g.t)
        
        // I almost forgot about this ^_^
        call g.destroy()
      endif

    // there WAS no endmethod... therefore it is here
    endmethod

    // forgot about "takes" and "returns"?
    // also, this method should be static
    // to call it in such notation "GG.Start")
    static method Start takes nothing returns nothing

      // the right syntax is <struct_name>.allocate()
      local GG g = GG.allocate()

      // there should be ()
      set g.u = GetTriggerUnit()

      // how can you start timer if you even doesn't created it?
      // we would use TimerUtils, so NewTimer() instead of CreateTimer()
      set g.t = NewTimer()

      // attaching struct id to timer
      call SetTimerData(g.t, integer(g))
      call TimerStart(g.t, TimeInterval, true, function GG.Loop)
    endmethod
    
  endstruct
  
  function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    //local integer i = 1
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_HERO_SKILL)
    call TriggerAddAction(t, function GG.Start)
    set GoldPerInterval[1] = 40
    set GoldPerInterval[2] = 100
    set GoldPerInterval[3] = 160
    set GoldPerInterval[4] = 220

    // no reason to use loop if you manually set values
    //loop
    //  exitwhen i = 4
    //  set GoldPerInterval[i] = -20 + 60 * i
    //endloop
  endfunction

endlibrary
 
Last edited:
Level 16
Joined
Oct 12, 2008
Messages
1,570
Omg, omg omg omg omg omg!
Thanks,, ^^

1. For the integer, right, need to remember resources are integers =P
2. Methods also take and return,, succesfully implented in brain:grin:
3. I made it a function before, but i thought that it was easier if all editable things would be in globals, but you are right ^^,,
4. Dumb dumb dumb,,
5. TimerUtils is a Library right? So next time i need to use timerutils,,
6. o_O,, im stupid,,
7. see step 2. :grin:
8. What does the 'static' mean? Also, i name the GG.Loop a function in
JASS:
 Timerstart(g.t, TimeInterval, true, function GG.Loop)
So shouldnt that one be static too then?
9. Create timer before starting,, sounds logical!
10. Why attach struct id to timer? I dont get that,,
11. Yeah, you quoted just before i realized i needed to delete the manual set ^^

All in all, i thank you for helping me!!
though i still would like to know the answer to those questions! o_O
+rep
 
Level 14
Joined
Nov 23, 2008
Messages
187
5. Yes, it's library.
8. "Static" is similar to "single", i.e. "method that is not connected with any single struct, but does work for structs". There is no possibility to use non-static methods as function handlers for TimerStart, ForGroup, etc. (due to obvious, I think, reasons). In this code Loop method is already static, so there would be no problem.
10. We attached struct id to get struct contents in another function - timer handler (static method Loop).

Hmm, I almost forgot about something... See my previous post again (loop method).
 
Level 16
Joined
Oct 12, 2008
Messages
1,570
So it should also have TimerUtils library in map? Ok,,
Also,, does it need to be in front of this library?
(same as with normal functions, it has to be before the function you call it in, otherwise it will do nothing)
Like:
JASS:
Library TimerUtils Initializer Init
endlibrary
Library Spell1 Initializer Init uses TimerUtils
endlibrary
Library Spell2 Initializer Init uses TimerUtils
enlibrary

I dont really get the attach thing with structs, when do you attach it? And how to declare it properly? (cause you just put that line in, i dont know how to do that properly when i try it next time)
You do it when you use the things in a struct somewhere else then in that library? (seems to me, since you use the timer from this library in TimerUtils Library =\ )

EDIT:
Does it always need to be:
JASS:
Library mylibrary Initializer Init
endlibrary
// or can it also be:
Library mylibrary2
endlibrary

Shouldnt the
JASS:
call g.destroy()
be outside of the if/then/else? Cause you'd need to destroy it anyways!

RE-AGAIN-EDIT:
current library:

JASS:
library GoldGain Initializer Init uses TimerUtils
   globals
      private constant real TimeInterval = 60
      private integer array GoldPerInterval
      private constant integer AbID = 'A000' //Change this to rawcode of your Ability!
   endglobals
   struct GG
      unit u
      timer t
      static method Loop takes nothing returns nothing
         local GG g = GetTimerData(GetExpiredTimer)
         if GetUnitAbilityLevel(g.u, AbID) != 0 then
            call SetPlayerState(GetOwningPlayer(g.u), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(GetOwningPlayer(g.u), PLAYER_STATE_RESOURCE_GOLD) + GoldPerInterval[GetUnitAbilityLevel(g.u, AbID)])
         else         
            call PauseTimer(g.t)         
            call ReleaseTimer(g.t)     
         endif
         call g.destroy()
      endmethod
      static method Start takes nothing returns nothing
         local GG g = g.Allocate()
         set g.u = GetTriggerUnit()
         set g.t = NewTimer()
         call SetTimerData(g.t, integer(g))
         call TimerStart(g.t, TimeInterval, true, function GG.Loop)
      endmethod 
   endstruct
   private function Condition takes nothing returns boolean
      return GetSpellAbilityId() == AbID                                      
   function Init takes nothing returns nothing
      local trigger t = CreateTrigger()
      call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_HERO_SKILL)
      call TriggerAddCondition(t, function Condition) 
      call TriggerAddAction(t, function GG.Start)
      set GoldPerInterval[1] = 40
      set GoldPerInterval[2] = 100
      set GoldPerInterval[3] = 160
      set GoldPerInterval[4] = 220
   endfunction
endlibrary
 
Last edited:
Level 22
Joined
Dec 31, 2006
Messages
2,216
JASS:
library GoldGain initializer Init uses TimerUtils

   globals
      private constant real TimeInterval = 60
      private integer array GoldPerInterval
      private constant integer AbID = 'A000' //Change this to rawcode of your Ability!
   endglobals

   struct GG
      unit u
      timer t

      static method Loop takes nothing returns nothing
         local timer t = GetExpiredTimer()
         local GG g = GetTimerData(t)
         if GetUnitAbilityLevel(g.u, AbID) != 0 then
            call SetPlayerState(GetOwningPlayer(g.u), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(GetOwningPlayer(g.u), PLAYER_STATE_RESOURCE_GOLD) + GoldPerInterval[GetUnitAbilityLevel(g.u, AbID)])
         else
            call PauseTimer(g.t)
            call ReleaseTimer(g.t)
            call g.destroy()
         endif
         set t = null
      endmethod

      static method Start takes nothing returns nothing
         local GG g = g.allocate()
         set g.u = GetTriggerUnit()
         set g.t = NewTimer()
         call SetTimerData(g.t, g)
         call TimerStart(g.t, TimeInterval, true, function GG.Loop)
      endmethod

      method onDestroy takes nothing returns nothing
          set .u = null
          set .t = null
      endmethod
   endstruct

   private function Condition takes nothing returns boolean
      return GetSpellAbilityId() == AbID
   endfunction

   private function Init takes nothing returns nothing
      local trigger t = CreateTrigger()
      local player p
      local integer i = 0
      loop
          exitwhen i == bj_MAX_PLAYER_SLOTS
          set p = Player(i)
          call TriggerRegisterPlayerUnitEvent(t, p, EVENT_PLAYER_HERO_SKILL, null)
          set p = null
          set i = i + 1
      endloop
      call TriggerAddCondition(t, function Condition)
      call TriggerAddAction(t, function GG.Start)
      set GoldPerInterval[1] = 40
      set GoldPerInterval[2] = 100
      set GoldPerInterval[3] = 160
      set GoldPerInterval[4] = 220
      set t = null
   endfunction
endlibrary
 
Level 16
Joined
Oct 12, 2008
Messages
1,570
Ok, but that was from when i still used call DestroyTimer(g.t),, (But still, i learned something =D)

@ Reborn,, why is this better? (Well, it obviously is, otherwise you wouldnt post it) but why is it better to use that local timer and get the timer data from it? Cause it is only an extra variable,, (no problem with me,, but i see no real difference =\ , since you only refer to it when calling TimerData, which already was done without that variable)
And the 'onDestroy' method? I see nowhere where it gets called, so why is it there? =\
And the event, its cool, it gets rid of the BJ at least! =P
 
Level 22
Joined
Dec 31, 2006
Messages
2,216
Yixx said:
why is it better to use that local timer and get the timer data from it?
Fix a leak.

Yixx said:
And the 'onDestroy' method? I see nowhere where it gets called, so why is it there? =\
It is called here:
JASS:
         else
            call PauseTimer(g.t)
            call ReleaseTimer(g.t)
            call g.destroy()  //<-----------------HERE
         endif
 
Level 16
Joined
Oct 12, 2008
Messages
1,570
Well ok then =)
I think it is ok this way? No leaks, bugs, improvements?

Thanks all! +rep

EDIT: Any programs where i can easily check the code for mistakes? And of course check if it works?
Cuase i am totally new to vJass(programs)
 
Last edited:
Level 22
Joined
Dec 31, 2006
Messages
2,216
Yixx said:
improvements?
It is possible to improve it, but I don't think you should move so fast through it. It takes time to learn and understand vJASS and of course other languages.

Yixx said:
EDIT: Any programs where i can easily check the code for mistakes? And of course check if it works?
Cuase i am totally new to vJass(programs)
Jass NewGen Pack
 
Level 14
Joined
Nov 18, 2007
Messages
816
JASS:
library GoldGain initializer Init uses TimerUtils, PUI

   globals
      private constant real TimeInterval = 60
      private integer array GoldPerInterval
      private constant integer AbID = 'A000' //Change this to rawcode of your Ability!
   endglobals
   
   //! runtextmacro PUI_PROPERTY("private", "integer", "GGLvl", "0")

   private struct GG // private because we dont want a user to use this struct
      unit u
      timer t

      static method Loop takes nothing returns nothing
         local GG g = GetTimerData(GetExpiredTimer())
         if GetUnitAbilityLevel(g.u, AbID) != 0 then
            call SetPlayerState(GetOwningPlayer(g.u), PLAYER_STATE_RESOURCE_GOLD, GetPlayerState(GetOwningPlayer(g.u), PLAYER_STATE_RESOURCE_GOLD) + GoldPerInterval[GetUnitAbilityLevel(g.u, AbID)])
         else
            call g.destroy()
         endif
         set t = null
      endmethod

      static method Start takes nothing returns nothing
         local GG g
         if GGLvl[g.u]==0 then
             set g = GG.allocate()
             set g.u = GetTriggerUnit()
             set g.t = NewTimer()
             set GGLvl[g.u]=GetUnitAbilityLevel(g.u, AbID)
             call SetTimerData(g.t, g)
             call TimerStart(g.t, TimeInterval, true, function GG.Loop)
         endif 
      endmethod

      method onDestroy takes nothing returns nothing
          set .u = null
          call ReleaseTimer(.t)
      endmethod
   endstruct

   private function Condition takes nothing returns boolean
      return GetSpellAbilityId() == AbID
   endfunction

   private function Init takes nothing returns nothing
      local trigger t = CreateTrigger()
      call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_HERO_SKILL)
      call TriggerAddCondition(t, function Condition)
      call TriggerAddAction(t, function GG.Start)
      set GoldPerInterval[1] = 40
      set GoldPerInterval[2] = 100
      set GoldPerInterval[3] = 160
      set GoldPerInterval[4] = 220
   endfunction
endlibrary

Program? JassNewGenPack, which would be the World Editor. Other than that, you could try to run JassHelper via command prompt.
 
Status
Not open for further replies.
Top