• 🏆 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!

[vJASS] code not working... ?

Status
Not open for further replies.
Level 21
Joined
Mar 29, 2020
Messages
1,237
this is supposed to create 1 TC for each player, and put it in the unit group HEROES if it belongs to a computer controlled player. It's not doing anything. where did I go wrong? (there is no traceback error)

JASS:
library StartThings initializer Init

    globals
      public group HEROES = CreateGroup()
    endglobals

    private function iscomphero takes nothing returns boolean
    if ( not ( GetPlayerController(GetEnumPlayer()) == MAP_CONTROL_COMPUTER ) ) then
        return false
    endif
    return true
    endfunction

    private function Createheroes takes nothing returns nothing
        local location tempoint = GetRandomLocInRect(GetPlayableMapRect())
        call CreateNUnitsAtLoc(1,'Otch',Player(0),tempoint,bj_UNIT_FACING)
        call RemoveLocation(tempoint)  
        set  tempoint = null
        if ( iscomphero()) then
            call GroupAddUnitSimple( GetLastCreatedUnit(), HEROES)
        else
        endif
    endfunction


    private function Actions takes nothing returns nothing
        call ForForce(GetPlayersAll(),function Createheroes)  
    endfunction
  
    private function Init takes nothing returns nothing
        local trigger initrig = CreateTrigger()
        call TriggerAddAction(initrig,function Actions)             
    endfunction

endlibrary

thanks!
 
Level 17
Joined
Mar 21, 2011
Messages
1,597
Well, your function Init runs at map init. If you want to call a function on map init, call it inside this function, or put your code directly into this function
JASS:
library lib initializer Init

   function foo takes nothing returns nothing
      // runs at map init
   endfunction

   function Init takes nothing returns nothing
      // runs at map init
      call foo()
   endfunction

endlibrary
 
Level 21
Joined
Mar 29, 2020
Messages
1,237
thanks! that sorted that.

Edit:{
this is what it looks like now:
JASS:
library StartThings initializer Init
    globals
      public group HEROES = CreateGroup() 
    endglobals
    private function iscomphero takes nothing returns boolean
    return GetPlayerController(GetEnumPlayer()) == MAP_CONTROL_COMPUTER
    endfunction
    private function Createheroes takes nothing returns nothing
        local location tempoint = GetRandomLocInRect(GetPlayableMapRect())
        call CreateNUnitsAtLoc(1,'Otch',Player(0),tempoint,bj_UNIT_FACING)
        call RemoveLocation(tempoint)   
        set  tempoint = null
        if ( iscomphero()) then
            call GroupAddUnitSimple( GetLastCreatedUnit(), HEROES)
        else
        endif
    endfunction
    private function Actions takes nothing returns nothing
        call ForForce(GetPlayersAll(),function Createheroes)   
    endfunction
   
    private function Init takes nothing returns nothing
        local trigger initrig = CreateTrigger()
        call Actions()               
    endfunction
endlibrary
}
Now I have another problem that all the units are being created for player(0) = red.

I pretty much copied this from the GUI translation, but I guess something got lost. I am trying to loop through all players in the player group and create a unit for each of them. what do I need to change?

(I could have a counter for each loop and change the player number accordingly, but I assume there is a more normal way...)
 
Last edited:
Level 21
Joined
Mar 29, 2020
Messages
1,237
thanks a lot! that did it.


it seems none of this is working either... it's a little longer... any tips on what I need to fix would be great. only one of the debug messages are working...:

(it's a rudementary AI system for a minigame. maybe I should start a new thread for this, even though the title is still true...)

JASS:
library AI initializer Init
    globals
        public group HEROES
        private group swap = CreateGroup()
        private group temp
       
        //this is the place to set the distance away that the AI "clicks".
        //should be larger than width of map frame (trees cliffs etc') so that point hits outside map.
        //bc this function can only detect when clicked point is out of bounds, not blocked. 
        private real rundistance = 800.
        private location leftpoint
        private location rightpoint
        //might need to use the two above to avoid a lot of leaking points.
         
       
    endglobals
//====================    Here I turn away from walls    ==========================
    private function NotWall takes location targetp , location runnerp returns location
        local real targetx = GetLocationX(targetp)
        local real targety = GetLocationY(targetp)
        local real rightx
        local real righty
        //local location rightpoint
        local integer rightcounter
        local real leftx
        local real lefty
        //local location leftpoint
        local integer leftcounter
        local real angle
       
       
        if RectContainsLoc(GetPlayableMapRect(),targetp) then
            return targetp
        else
            //here I choose the shorter angle:
            set rightcounter = 0
            set leftcounter = 0
            set angle = AngleBetweenPoints(runnerp,targetp) 
            loop
                exitwhen RectContainsLoc(GetPlayableMapRect(),rightpoint)
                set rightcounter = rightcounter + 1
                set angle = angle + 30.
                call RemoveLocation(rightpoint)
                set rightpoint = null
                //set rightx = null
                //set righty = null 
                set rightpoint = PolarProjectionBJ(runnerp,rundistance,angle)
                set rightx = GetLocationX(rightpoint)
                set righty = GetLocationY(rightpoint)           
            endloop
           
            set angle = 0.
            set angle = AngleBetweenPoints(runnerp,targetp)
            //the left side:
            loop
                exitwhen RectContainsLoc(GetPlayableMapRect(),leftpoint)
                set leftcounter = leftcounter + 1
                //here is the distance which should be a constant so I should just change the number here:
                set angle =  angle - 30.
                call RemoveLocation(leftpoint)
                set leftpoint = null
                //set leftx = null
                //set lefty = null  (I commented these bc I understand it's not necessary)
                set leftpoint = PolarProjectionBJ(runnerp,rundistance,angle)
                set leftx = GetLocationX(rightpoint)
                set lefty = GetLocationY(rightpoint)           
            endloop
           
            if rightcounter > leftcounter then
                call RemoveLocation(rightpoint)
                set rightpoint = null
                return leftpoint
            else
                //leak removal bla bla
                call RemoveLocation(leftpoint)
                set leftpoint = null
                return rightpoint
            endif
        //can I remove leaks after return statement or are those lines not read?                       
        endif
    endfunction
   
//============================================================================================
    private function isthreat takes unit u returns boolean
    if u == udg_Dragon then
    return true
    else
        return IsUnitType(u, UNIT_TYPE_HERO)
    endif
    endfunction
   
//=============================================================================================
   
    private function Flee takes unit fleer returns location
    //this need to find who is in range, and accordingly decide how to run. 
        local location fleeloc = GetUnitLoc(fleer)
        local real fleerx = GetLocationX(fleeloc)
        local real fleery = GetLocationY(fleeloc)
        local location targetpoint
        local real angle
        local group threatgroup = CreateGroup()
        local group tempgroup = CreateGroup() 
        local unit FOG = null
        local real threatrange = 1000.
        local integer counter = 0
        local unit threat1
        local unit threat2
       
       
        ///now need to check for threats in range:
        call GroupEnumUnitsInRange(threatgroup,fleerx,fleery,threatrange,null) 
        loop
            set FOG = FirstOfGroup(threatgroup)
            exitwhen FOG==null
            if isthreat(FOG) then
                set counter = counter + 1
                call GroupAddUnit(tempgroup,FOG)
            endif
            call GroupRemoveUnit(threatgroup,FOG)
        endloop
        if CountUnitsInGroup(tempgroup) == 1 then
            set FOG = FirstOfGroup(tempgroup)
            set angle = AngleBetweenPoints(fleeloc,GetUnitLoc(FOG))
       
        elseif CountUnitsInGroup(tempgroup) == 2 then
            set threat1 = FirstOfGroup(tempgroup)
            call GroupRemoveUnit(tempgroup,threat1)
            set threat2 = FirstOfGroup(tempgroup)
            call GroupRemoveUnit(tempgroup,threat2)
            set angle = ((AngleBetweenPoints(fleeloc,GetUnitLoc(threat1))) + (AngleBetweenPoints(fleeloc,GetUnitLoc(threat2))))/2.
             
        elseif CountUnitsInGroup(tempgroup) > 2 then
            //eventually this should find the biggest threat and run from it. for now just random.     
            if IsUnitInGroup(udg_Dragon,tempgroup)then
                 set angle = AngleBetweenPoints(fleeloc,GetUnitLoc(udg_Dragon))
            else
                set FOG = FirstOfGroup(tempgroup)
                set angle = AngleBetweenPoints(fleeloc,GetUnitLoc(FOG))
            endif
        endif   
        set targetpoint = PolarProjectionBJ(fleeloc,-1*(rundistance),angle)
       
        //cleanup:
        loop
            exitwhen FirstOfGroup(tempgroup) == null
            call GroupRemoveUnit(tempgroup,FirstOfGroup(tempgroup))
        endloop
        set threat1 = null
        set threat2 = null
        set FOG = null
        call DestroyGroup(threatgroup)
        call DestroyGroup(tempgroup)
       
        return targetpoint
       
    endfunction
   
 //==========================================================================================
   
    private function mainAI takes nothing returns nothing
        local unit FOG
        loop
        //call BJDebugMsg("mainAI") - this one went off... the rest didn't
            set FOG = FirstOfGroup(HEROES)
            exitwhen FOG == null 
        call BJDebugMsg("exited loop")
            ///starting the actual function...
           
            if UnitHasItem(FOG,udg_Crown)then
                if GetUnitLifePercent(FOG)<50. then
                    if IsUnitInRange(FOG,udg_Dragon,800.)then
                        call UnitDropItemPointLoc(FOG,udg_Crown,GetUnitLoc(FOG))
                    endif
                else
                    call IssuePointOrderLoc(FOG,"smart",Flee(FOG))
                endif
            else
        call BJDebugMsg("dont havit")
                if IsUnitInRange(FOG,udg_Dragon,1500.)then
                    call IssuePointOrderLoc(FOG,"smart",Flee(FOG))
                else
                    if udg_Carrier != FOG then
                        call IssueTargetOrderBJ( FOG, "attack", udg_Carrier )
                    else
                        call IssueTargetItemOrder( FOG, "smart", udg_Crown )
            call BJDebugMsg("oredered to get crown")
                    endif
                endif
            endif             
            ///relevant function till here
            call GroupAddUnit(swap,FOG)
            call GroupRemoveUnit(HEROES,FOG)
        endloop
        set temp = HEROES
        set HEROES = swap
        set swap = temp
    call BJDebugMsg("finished AI loop")
             
    endfunction 
//==============================================================
    private function Init takes nothing returns nothing 
        local trigger AItrig  = CreateTrigger()
        call TriggerRegisterTimerEventPeriodic(AItrig,1.)
       
        call TriggerAddAction(AItrig, function mainAI )
    endfunction
                   
 endlibrary
 
Level 21
Joined
Mar 29, 2020
Messages
1,237
that is supposed to be a variable I can access from any function and I already initialized it in the first function (the one that triggers on init that I started this thread with.) AFAIK the word public helps do that.

Do I need to initialize it again in every library I use it?
 
Level 17
Joined
Mar 21, 2011
Messages
1,597
Do I need to initialize it again in every library I use it?
No, you only need to initialize it once, i would also declare it once.

JASS:
public group HEROES = CreateGroup()
As far as i can remember, Groups cannot be initialized inside a globals block. You have to do:

JASS:
globals
   group g
endglobals

function init takes nothing returns nothing
   set g = CreateGroup()
endfunction
 

LeP

LeP

Level 13
Joined
Feb 13, 2008
Messages
539
No, you only need to initialize it once, i would also declare it once.

JASS:
public group HEROES = CreateGroup()
As far as i can remember, Groups cannot be initialized inside a globals block. You have to do:

JASS:
globals
   group g
endglobals

function init takes nothing returns nothing
   set g = CreateGroup()
endfunction
No, CreateGroup should work fine in a globals block.
You can see here which natives pjass will report when used in a globals block.
Also you can try to use the pjass flag +checkglobalsinit to detect unsafe usage of uninitialized globals. Do note though that that analysis isn't too good so it's not enabled by default.
 
Level 21
Joined
Mar 29, 2020
Messages
1,237
just the one that said "main AI" before I commented it.

Edit: when I try to erase the declaration of the unit group HEROES from the second library, it gives me a traceback that HEROES is an undeclared variable in that library. why isn't it reading the public declaration and initialization of HEROES from the first library?
 
Last edited:
Level 17
Joined
Mar 21, 2011
Messages
1,597
Tbh, i wonder why it didnt throw an error because of redeclaration.
Anyway, you can remove the public keyword. Anything, that is not private, is public.

just the one that said "main AI" before I commented it.
That means your group is empty. Maybe there is a mistake in your first trigger.

iscomphero()
Maybe this always returns false. You can check with a debug message, if any unit gets added
 
Level 17
Joined
Mar 21, 2011
Messages
1,597
There are three location leaks inside mainAI for example:
JASS:
call UnitDropItemPointLoc(FOG,udg_Crown,GetUnitLoc(FOG))
call IssuePointOrderLoc(FOG,"smart",Flee(FOG))
call IssuePointOrderLoc(FOG,"smart",Flee(FOG))

To prevent leaking, you have to do
JASS:
local location loc
//...
set loc = GetUnitLoc(someUnit)
call UnitDropItemPointLoc(someUnit, someItem, loc)
//...
call RemoveLocation(loc)
set loc = null

Generally, i would recommend to use real coordinates instead of locations.

JASS:
local real x
local real y
//...
set x = GetUnitX(someUnit)
set y = GetUnitY(someUnit)
call UnitDropItemPoint(someUnit, someItem, x, y)

This way, you don't create a location handle. UnitDropItemPoint is also a native function, UnitDropItemPointLoc just calls UnitDropItemPoint and reads the passed location x and y values.
 
Status
Not open for further replies.
Top