• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[JASS] Tax function not functioning! Help please?

Status
Not open for further replies.
Level 17
Joined
Sep 2, 2005
Messages
1,029
JASS:
function ResourceTaxes takes nothing returns nothing
    local integer i = -1
    local integer taxes = 0
    local integer water = 0 //These are just to make the code easier to read
    local group g
    local integer heroRate = 50
    local integer buildingRate = 25
    local integer entRate = buildingRate
    local integer entBuilderRate = entRate/2
    local integer remainder
    local group all
    local integer allCount
    local integer i2 = -1
    

    loop
      set i = i+1
      exitwhen i==12
      set water = GetPlayerState(Player(i),PLAYER_STATE_RESOURCE_GOLD)
      //call DisplayTextToForce( GetPlayersAll(), "Current Water: "+I2S(water)+" water" )
      //Remove the water for the cost of the buildings and units.
      set all= GetUnitsOfPlayerAll(Player(i))
      set allCount = CountUnitsInGroup(all)
      //Ent Heroes = 10/s
      set g = GetUnitsOfPlayerAndTypeId(Player(i), 'e00A')
      set taxes = taxes + CountUnitsInGroup(g) * heroRate
      set g = GetUnitsOfPlayerAndTypeId(Player(i), 'e00H')
      set taxes = taxes + CountUnitsInGroup(g) * heroRate
      set g = GetUnitsOfPlayerAndTypeId(Player(i), 'e00K')
      set taxes = taxes + CountUnitsInGroup(g) * heroRate
      set g = GetUnitsOfPlayerAndTypeId(Player(i), 'e00J')
      set taxes = taxes + CountUnitsInGroup(g) * heroRate
      set g = GetUnitsOfPlayerAndTypeId(Player(i), 'e00B')
      set taxes = taxes + CountUnitsInGroup(g) * heroRate
      set g = GetUnitsOfPlayerAndTypeId(Player(i), 'e00I')
      set taxes = taxes + CountUnitsInGroup(g) * heroRate
      set g = GetUnitsOfPlayerAndTypeId(Player(i), 'e00M')
      set taxes = taxes + CountUnitsInGroup(g) * heroRate
      set g = GetUnitsOfPlayerAndTypeId(Player(i), 'e00L')
      set taxes = taxes + CountUnitsInGroup(g) * heroRate
      set g = GetUnitsOfPlayerAndTypeId(Player(i), 'n000')
      set taxes = taxes + CountUnitsInGroup(g) * heroRate
      set g = GetUnitsOfPlayerAndTypeId(Player(i), 'n001')
      set taxes = taxes + CountUnitsInGroup(g) * heroRate
      set g = GetUnitsOfPlayerAndTypeId(Player(i), 'n002')
      set taxes = taxes + CountUnitsInGroup(g) * heroRate
      set g = GetUnitsOfPlayerAndTypeId(Player(i), 'n003')
      set taxes = taxes + CountUnitsInGroup(g) * heroRate
        
      //Buildings = 2/s
      set g = GetUnitsOfPlayerAndTypeId(Player(i), 'h000')
      set taxes = taxes + CountUnitsInGroup(g) * buildingRate

      //Ent Builders = 1/s
      set g = GetUnitsOfPlayerAndTypeId(Player(i), 'e00e')
      set taxes = taxes + CountUnitsInGroup(g) * entBuilderRate
      set g = GetUnitsOfPlayerAndTypeId(Player(i), 'e00s')
      set taxes = taxes + CountUnitsInGroup(g) * entBuilderRate
      set g = GetUnitsOfPlayerAndTypeId(Player(i), 'e00t')
      set taxes = taxes + CountUnitsInGroup(g) * entBuilderRate
      set g = GetUnitsOfPlayerAndTypeId(Player(i), 'e00u')
      set taxes = taxes + CountUnitsInGroup(g) * entBuilderRate

      call DisplayTextToForce( GetPlayersAll(), "Taxes: "+I2S(taxes)+" water" )
      //call DisplayTextToForce( GetPlayersAll(), "Total: "+I2S(water-taxes)+" water" )
      call SetPlayerState( Player(i), PLAYER_STATE_RESOURCE_GOLD, water - taxes)
      call DestroyGroup(g)
      set g = null  //This is how you clear the group,
    endloop       // and it must be in the loop for this function
endfunction

There's my function.

So its supposed to go through the units and have taxes according to the unit in question. Unfortunately, at the end, the tax amount always comes up as 0 regardless of what I do. Any suggestions?
 
Level 9
Joined
Mar 25, 2005
Messages
252
You leak 204 groups and 205 group variables every time that function is run.

I would fix those and then check if the function hits the op limit.
I suggest that you take a look at how GetUnitsOfPlayerAndTypeId and CountUnitsInGroup work and write your own filter function that does both of those functions' actions. This way you have to create and destroy only one group.
 
Level 17
Joined
Sep 2, 2005
Messages
1,029
You leak 204 groups and 205 group variables every time that function is run.

I would fix those and then check if the function hits the op limit.
I suggest that you take a look at how GetUnitsOfPlayerAndTypeId and CountUnitsInGroup work and write your own filter function that does both of those functions' actions. This way you have to create and destroy only one group.

good to know. I'll look into removing the leaks. that still doesnt explain the part that doesnt work though, that just shows me its gravely inefficient. (which I will need to look at/fix)

All the leaks you refer to are in the blizzard functions aren't they. . . .

In mine I found 1.

Bastards.
---------------------Edit----------------------------
Custom Function: should be less leaky, but now I have it telling me I didnt declare the function. I thought in wc3 you just had to write the function before it gets called to declare it. what am I missing?
JASS:
function CountUnitsOfPlayerAndTypeID takes player WhichPlayer, integer IdOfUnit returns integer
    local group g = CreateGroup()
    set bj_groupEnumTypeId = IdOfUnit
    call GroupEnumUnitsOfPlayer(g, WhichPlayer, filterGetUnitsOfPlayerAndTypeId)
    set bj_groupCountUnits = 0
    call ForGroup(g, function CountUnitsInGroupEnum)
    set g = null
    return bj_groupCountUnits
endfunction

function ResourceTaxes takes nothing returns nothing
    local integer i = -1
    local integer counter =0
    local integer taxes = 0
    local integer water = 0 //These are just to make the code easier to read
    local group g
    local integer heroRate = 50
    local integer buildingRate = 25
    local integer entRate = buildingRate
    local integer entBuilderRate = entRate/2
    local integer remainder
    local group all
    local integer allCount
    local integer i2 = -1
    

    loop
      set i = i+1
      exitwhen i==12
      set counter = 0
      set taxes = 0
      set water = GetPlayerState(Player(i),PLAYER_STATE_RESOURCE_GOLD)
      //call DisplayTextToForce( GetPlayersAll(), "Current Water: "+I2S(water)+" water" )
      //Remove the water for the cost of the buildings and units.
      //set all= GetUnitsOfPlayerAll(Player(i))
      //set allCount = CountUnitsInGroup(all)
      //Ent Heroes = 10/s
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'e00A')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'e00H')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'e00K')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'e00B')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'e00I')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'e00M')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'e00L')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'e00J')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'n000')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'n001')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'n002')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'n003')
      set taxes = taxes + counter * heroRate
      call DisplayTextToForce( GetPlayersAll(), "Heroes: "+I2S(counter))      
      set counter = 0
        
      //Buildings = 2/s
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'h000')
      set taxes = taxes + counter * buildingRate
      call DisplayTextToForce( GetPlayersAll(), "Buildings: "+I2S(counter))
      
      set counter = 0
      
      //Ent Builders = 1/s
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'e00e')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'e00s')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'e00t')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'e00u')
      call DisplayTextToForce( GetPlayersAll(), "Builders: "+I2S(counter))
      set taxes = taxes + counter * entBuilderRate

      call DisplayTextToForce( GetPlayersAll(), "Taxes: "+I2S(taxes)+" water" )

      call SetPlayerState( Player(i), PLAYER_STATE_RESOURCE_GOLD, water - taxes)
      call DestroyGroup(g)
      set g = null  //This is how you clear the group,
      set all = null
    endloop       // and it must be in the loop for this function
endfunction

The group all, though not currently implemented, used to serve a purpose, and will again when I get the taxes working right. When you can't pay the taxes (water), all of your units will take a small quantity of damage. but this will happen every 5 seconds.
 
Last edited:
Level 17
Joined
Sep 2, 2005
Messages
1,029
It leaks just as much. You aren't destroying the groups...

JASS:
function CountUnitsOfPlayerAndTypeID takes player WhichPlayer, integer IdOfUnit returns integer
    local group g = CreateGroup()
    set bj_groupEnumTypeId = IdOfUnit
    call GroupEnumUnitsOfPlayer(g, WhichPlayer, filterGetUnitsOfPlayerAndTypeId)
    set bj_groupCountUnits = 0
    call ForGroup(g, function CountUnitsInGroupEnum)
    call DestroyGroup(g)
    set g = null
    return bj_groupCountUnits
endfunction

function ResourceTaxes takes nothing returns nothing
    local integer i = -1
    local integer counter =0
    local integer taxes = 0
    local integer water = 0 //These are just to make the code easier to read
    local group g
    local integer heroRate = 50
    local integer buildingRate = 25
    local integer entRate = buildingRate
    local integer entBuilderRate = entRate/2
    local integer remainder
    local group all
    local integer allCount
    local integer i2 = -1
    

    loop
      set i = i+1
      exitwhen i==12
      set counter = 0
      set taxes = 0
      set water = GetPlayerState(Player(i),PLAYER_STATE_RESOURCE_GOLD)
      //call DisplayTextToForce( GetPlayersAll(), "Current Water: "+I2S(water)+" water" )
      //Remove the water for the cost of the buildings and units.
      //set all= GetUnitsOfPlayerAll(Player(i))
      //set allCount = CountUnitsInGroup(all)
      //Ent Heroes = 10/s
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'e00A')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'e00H')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'e00K')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'e00B')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'e00I')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'e00M')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'e00L')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'e00J')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'n000')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'n001')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'n002')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'n003')
      set taxes = taxes + counter * heroRate
      call DisplayTextToForce( GetPlayersAll(), "Heroes: "+I2S(counter))      
      set counter = 0
        
      //Buildings = 2/s
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'h000')
      set taxes = taxes + counter * buildingRate
      call DisplayTextToForce( GetPlayersAll(), "Buildings: "+I2S(counter))
      
      set counter = 0
      
      //Ent Builders = 1/s
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'e00e')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'e00s')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'e00t')
      set counter = counter + CountUnitsOfPlayerAndTypeId(Player(i), 'e00u')
      call DisplayTextToForce( GetPlayersAll(), "Builders: "+I2S(counter))
      set taxes = taxes + counter * entBuilderRate

      call DisplayTextToForce( GetPlayersAll(), "Taxes: "+I2S(taxes)+" water" )

      call SetPlayerState( Player(i), PLAYER_STATE_RESOURCE_GOLD, water - taxes)
      call DestroyGroup(g)
      set g = null  //This is how you clear the group,
      call DestroyGroup(all)
      set all = null
    endloop       // and it must be in the loop for this function
endfunction

Is that better? I'm new to unleaking scripts.
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
Yes, that's better.

Try to de-BJ too -

DisplayTextToForce(GetPlayersAll(),<text>) can be replaced by DisplayTextToPlayer(GetLocalPlayer(),0,0,<text>)


Also, just add a dummy ability to all those units so you only need to do one enum, it would be way faster (hundreds of times, I should think, assuming the main speed decrease (if noticeable, which it probably is) is from group enums...).
 
Level 17
Joined
Sep 2, 2005
Messages
1,029
Yes, that's better.

Try to de-BJ too -

DisplayTextToForce(GetPlayersAll(),<text>) can be replaced by DisplayTextToPlayer(GetLocalPlayer(),0,0,<text>)


Also, just add a dummy ability to all those units so you only need to do one enum, it would be way faster (hundreds of times, I should think, assuming the main speed decrease (if noticeable, which it probably is) is from group enums...).

the displaytexttoforce is just for debugging, but I see your point. 1 player would be more efficient.

im not sure what you mean by the dummy ability. and again, there is still the problem of it saying its not declared.
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
the displaytexttoforce is just for debugging, but I see your point. 1 player would be more efficient.
? It displays to all players, just removes a BJ.

im not sure what you mean by the dummy ability. and again, there is still the problem of it saying its not declared.
For the dummy ability, an invisible ability added to all the correct unit-types, with no effects.

For the not declared part, what?
 
Level 17
Joined
Sep 2, 2005
Messages
1,029
? It displays to all players, just removes a BJ.

For the dummy ability, an invisible ability added to all the correct unit-types, with no effects.

For the not declared part, what?

when I try to save, or run the code checker, it says the top function wasnt declared and gives me an error. thats what ive been talkign about since the first correction.

before worrying about making my code more efficient, I just want the damn thing to A) compile again since it won't now that I removed the 2 bj functions, and B) actually do something instead of calculating that the taxes are 0 for some reason incomprehendable to me.
 
Level 17
Joined
Sep 2, 2005
Messages
1,029
Jass is case sensitive, you have blahblahblahId in the callbacks and blahblahblahID in the function name.

I knew Jass was case sensitive, I just didnt see my fuck up. Wow, I feel so very retarded. . . .

Edit: for the dummy ability, you mean so that I don't have to do as many counts? like 1 for each price category instead of one for each unit type? is there a way to do that without them actually needign to have a common ability? cause I don't see the ability thing working, though it would make sense if thats why it lags when counting.

Cause the pricing system may get more complicated and there may be lik 10 different groups. then I have all sorts of useless abilities on every unit on the map except for the town hall and a sortof goldmine unit. - every unit ends up getting counted, either for taxes, or for resource production.

And though I now have the taxes working, they still don't show the right quantities in the displays - always 0.
 
Last edited:
Level 40
Joined
Dec 14, 2005
Messages
10,532
The ability method works fine, I use it for stuff all the time. And no, there is no other very good way, unless you have Point Value spare and want to store the values in there.

Cause the pricing system may get more complicated and there may be lik 10 different groups. then I have all sorts of useless abilities on every unit on the map except for the town hall and a sortof goldmine unit. - every unit ends up getting counted, either for taxes, or for resource production.
In that case, point value would work well.

And though I now have the taxes working, they still don't show the right quantities in the displays - always 0.
That means you aren't getting any units in your group.
 
Status
Not open for further replies.
Top