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

(GUI) Bounty Controller

Bounty Controller

This system alows you to have control of almost everything related to the bounties (I am surprised that no one else has done this as far as I saw, I mean, I already saw other systems and none does everything that it does, and that I am not an expert and this is the first system that I share).

If you don't use GUI, here is a pure vJass/Lua version: https://www.hiveworkshop.com/threads/vjass-lua-bounty-controller-pure-code-version.333801/

How to use it:

Important is have deactivated the bounties (this system do that, but don't active them) and you have to set the values of the bounties manually.

First use the event "BountyEvent becomes Equal to 2.00" (If you wanna do it in the map initialization, especially in the Lua version) and set the values like this:
  • Set BountyUnitID = "Unit-type"
  • Set BountyBase = "Bounty base"
  • Set BountyDice = "Bounty number of dices"
  • Set BountySides = "Bounty sides per dice"
  • Trigger - Run BountySet (ignoring conditions)
Or you can do it in Jass like this
vJASS:
call BOUNTY(<'ID of the unit'>,<Bounty: Base>,<Bounty: Number of dice>,<Bounty: Sides per dice>)
Or in other case the bounty will be 0, and when a unit dies and there is a killing unit it will fire the event:
  • Game - BountyDeadEvent becomes Equal to 1.00
And with this you can edit the values:
"Bounty": The quantity of gold or lumber that you will receive (it can be negative).
"BountyTextTag": The texttag that will be displayed (never edit this value).
"BountyPermanent": This allows erase it (care, if this value is true and you don't use the texttag later it can be an object leak)
"BountyAge": For some reason the x,y position of the texttag respect to the camera depends of its speed and age, so you can edit it.
"BountyColor": The color of the text (if is not set, the color of the text will have the default values depending of the state).
"BountySize": The size of the text.
"BountyLifeSpan": The max. lifetime of the text.
"BountyFadePoint": How many seconds the text will fade after apear.
"BountySpeed": The speed of the text.
"BountyDirection": The direction to the texttag will move.
"BountyHeight": How many distance the text will be from the floor.
"BountyShow": To show the text or not.
"BountyShowNothing": If the Bounty is 0 by default the text is not showed, if you set this to true, the text will be showed even if the bounty is 0.
"BountyAllowFriendFire": By default the bounty only will happen if the dying unit is enemy of the killing unit, if you set this to true, the bounty will happen even if they weren't enemies.
"BountyEffect": The effect that will be displayed (In the same place of the text)
"BountyShowEffect": The effect will be displayed if this value is true.
"BountyPlayer": The player who will receive the bounty.
"BountyPlayerState": What type of bounty the player will receive (only "gold" and "lumber" are valid).
"BountyUnitPos": The position of the text and the effect (If is a unit)
"BountyLocPos": The position of the text and the effect (If is a location, this have more priority than BountyUnitPos, and is removed with the clear function to prevent object leak, of course only if "BountyNotClear" is not true, and for this reason don't set it to a variable that you gonna use later)
"BountyWhoSee": The players who can see the text (if you change the variable "BountyPlayer", you must remove him from this group before and then add the new player).
"BountyData": Is an integer that you can store (Since the process is practically instant there is no much point on storing a value, but you can use it to add an extra "condition").
And to replace the values "Killing unit" and "Dying unit" you have "BountyKillingUnit" and "BountyDyingUnit" respectively
If you wanna create a bounty with your own event just do:
  • Get money
    • Events
      • What you want
    • Conditions
      • What you want
    • Actions
      • Set Bounty = Your value
      • Set BountyUnitPos = Your unit
      • Set BountyPlayer = Your player
      • Player Group - Add BountyPlayer to BountyWhoSee
      • Anything else you wanna
      • Trigger - Run BountyText (ignoring conditions) or in Jass just do "call BountyText()"
But if the event is BountyDeadEvent or BountyEvent you should use BountyHold and BountyRelease like this:
  • Get money
    • Events
      • Game - BountyDeadEvent becomes Equal to 1.00
    • Conditions
      • There must be a condition to prevent an infinite loop
    • Actions
      • What you want (even the normal edit of the bounty values)
      • Trigger - Run BountyHold (ignoring conditions)
      • -------- --------
      • Set Bounty = Your value
      • Set BountyUnitPos = Your unit
      • Set BountyPlayer = Your player
      • Player Group - Add BountyPlayer to BountyWhoSee
      • Anything else you wanna
      • Trigger - Run BountyText (ignoring conditions)
      • -------- --------
      • Trigger - Run BountyRelease (ignoring conditions)
      • What you want (even the normal edit of the bounty values)
  • Get money
    • Events
      • Game - BountyEvent becomes Equal to 1.00
    • Conditions
      • There must be a condition to prevent an infinite loop
    • Actions
      • What you want
      • Trigger - Run BountyHold (ignoring conditions)
      • -------- --------
      • Set Bounty = Your value
      • Set BountyUnitPos = Your unit
      • Set BountyPlayer = Your player
      • Player Group - Add BountyPlayer to BountyWhoSee
      • Anything else you wanna
      • Trigger - Run BountyText (ignoring conditions)
      • -------- --------
      • Trigger - Run BountyRelease (ignoring conditions)
      • What you want
If you wanna do some extra edit to the texttag do:
  • Trigger
    • Events
      • Game - BountyEvent becomes Equal to 1.00
    • Conditions
    • Actions
      • Set LastCreatedTextTag = BountyTextTag
and then do whatever you want with that saved variable.

For more information look the comment section of the system.

To install it go to File>Prefferences>"Create unknow variables automatically while trigger data is pasted" and copy the carpet "Bounty Controller" (there are things those are "optional") and paste it in your map.

Give me tips to improve this system, thank you

v1.0
Released.
v1.1
  • Added intialization event.
  • Added BountyTextTag, BountyPermanent, BountyDirection, BountyPosX, BountyPosY.
  • Added the function BountyCall to short the process to Jass programmers.
v1.2
  • Added ChangeBountyPlayer to short the process to Jass programmers.
  • Lua version released.
v1.3 (v1.1 Lua)
  • vJass version compatible with Table.
  • vJass and Lua version compatible with RegisterNativeEvent and added RegisterBountyDeadEvent and RegisterBountyEvent functions.
v1.4 (v1.2 Lua)
  • Recursion prevent added.
  • Added BountyHold and BountyRelease to use BountyText in a trigger with an event BountyDeadEvent or BountyEvent.
  • Added BountyData and BountyAge.
  • The clear function is now usable (and called "BountyClear").
  • Lua version no longer need RegisterNativeEvent (is just optional).
v1.4.1
  • Some things I missed.
Contents

Bounty Controller Lua v1.2 (Map)

Bounty Controller v1.4.1 (Map)

Reviews
MyPad
In its current state, the Bounty Controller system works like a charm. There aren't any major issues encountered while testing the system, but it is worth mentioning to the user that the system overrides the built-in bounty system, so that the user...
Level 23
Joined
Jun 26, 2020
Messages
1,835
Question: Is there a library that saves the data of the texttags?, If not, I will create it.
Another question: If I use the function CreateTextTag() have I edit it inmediatly or it gets deleted or something?
 
Last edited:
Level 23
Joined
Jun 26, 2020
Messages
1,835
Yes, that should do it.
Well, basically the lifespan is not the remaining life of the texttag, is the age it must have to get elimanted, so for that I have to set a lifespan with a big number to the text don't get deleted if I set its permanence to false.

PD: Updated (see the ChangeLog) and Lua version added (thank you @Uncle and @Tasyen).
 
In its current state, the Bounty Controller system works like a charm. There aren't any major issues encountered while testing the system,
but it is worth mentioning to the user that the system overrides the built-in bounty system, so that the user can take that into account
when designating which players (in addition to neutral hostile) can have units which give bounty.

The function SetPlayerFlagBJ can be replaced with a direct call to SetPlayerState, albeit with the following argument
parameters:

JASS:
// The native function used by SetPlayerFlagBJ
native SetPlayerState takes player whichplayer, playerstate whichstate, integer state returns nothing
// Line to copy
call SetPlayerState(whichplayer, PLAYER_STATE_GIVES_BOUNTY, 0)

The temporary variables TempX, TempY, and TempZ have generic names. This might have an impact
on importing this system on certain maps which might contain variables with the same name. I suggest
adding a prefix or a suffix identifier so that no name collisions occur.

In the Lua version, you might want to declare the closure function within CopyForce as its own function.
From what I've heard, closures when created dynamically are notoriously difficult to reclaim as usable
memory.

Status:
Approved

 
Level 23
Joined
Jun 26, 2020
Messages
1,835
@MyPad Thank you.
but it is worth mentioning to the user that the system overrides the built-in bounty system, so that the user can take that into account
when designating which players (in addition to neutral hostile) can have units which give bounty.
The comment section warns you that you must have deactiveted the normal bounties, it just left warn it in the bundle.
The function SetPlayerFlagBJ can be replaced with a direct call to SetPlayerState, albeit with the following argument
parameters
I can do that if I need update the map.
The temporary variables TempX, TempY, and TempZ have generic names.
They are variables just for the test map, you shouldn't import them.
In the Lua version, you might want to declare the closure function within CopyForce as its own function.
From what I've heard, closures when created dynamically are notoriously difficult to reclaim as usable
memory.
What do you mean?
 
@MyPad Thank you.

The comment section warns you that you must have deactiveted the normal bounties, it just left warn it in the bundle.

I can do that if I need update the map.

They are variables just for the test map, you shouldn't import them.

What do you mean?
As for the closure part, the suggested code change will look like this:

Lua:
-- New (former closure function declared as external func)
function callbackex()
    bar()
end
function foo()
    DoFunc(callbackex, otherparam)
end

-- Old
function foo()
    DoFunc(function()
        bar()
    end, otherparam)
end

Since that particular function will be called multiple times, I suppose it would be better to just declare the closure function explicitly rather than generate copies of the same function throughout the game.
 
Level 23
Joined
Jun 26, 2020
Messages
1,835
As for the closure part, the suggested code change will look like this:

Lua:
-- New (former closure function declared as external func)
function callbackex()
    bar()
end
function foo()
    DoFunc(callbackex, otherparam)
end

-- Old
function foo()
    DoFunc(function()
        bar()
    end, otherparam)
end

Since that particular function will be called multiple times, I suppose it would be better to just declare the closure function explicitly rather than generate copies of the same function throughout the game.
Ah that, I would do that, but 2 diferent functions use it, so I can't make that function anonymus (Is that new/old in the wrong place?).
 
Top