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

[Snippet] Trade Event

Level 31
Joined
Jul 10, 2007
Messages
6,306
It increases the probability of detecting an actual trade by ensuring that both playerstate changes occur at the same instant.

Sync must be true for a trade to register (along with the other vars)

If sync isn't true, it resets the vars, sets sync to true, and starts a timer that sets sync back to false.

Keep in mind that this system works off of probability; it has no way of knowing that what it detects is actually a trade. The probability is so high that it might as well be 100% though.
 
Last edited:
Level 17
Joined
Apr 27, 2008
Messages
2,455
I did kinda the same before but i'm not posting for that.

I mean i'm quite sure we can avoid the timer usage, only with playing native events (amount of resource of a player changes) and values of native triggerplayer playerstate (gold given/received,total ...).
But since you need a real player (you can't trade only with a computer on your map) i never finished the test, because that was annoying for the tester and i was lazy to make a full only one complete test.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
I get your idea, but let's say that we had this scenario

Player buys an item for 400 gold
Player sells an item for 400 gold

Without the timer thing, that'd register as a trade event.

You have a player state "gold given" or something like that (old in my mind).
You would be able to make the difference.
Code will be better than many words, i will make the needed test code.
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
Then it's player score or something. And you could play with donor / receiver datas.
You don't have to trust on me, i will give you results of my test anyway, even if i have no concrete better way (no timer) i will say it.
I won't post more here without some code.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
I see, you are right ;D
JASS:
constant playerscore PLAYER_SCORE_GOLD_GIVEN                = ConvertPlayerScore(14)
    constant playerscore PLAYER_SCORE_GOLD_RECEIVED             = ConvertPlayerScore(15)
    constant playerscore PLAYER_SCORE_LUMBER_TOTAL              = ConvertPlayerScore(16)
    constant playerscore PLAYER_SCORE_LUMBER_LOST_UPKEEP        = ConvertPlayerScore(17)
    constant playerscore PLAYER_SCORE_LUMBER_LOST_TAX           = ConvertPlayerScore(18)
    constant playerscore PLAYER_SCORE_LUMBER_GIVEN              = ConvertPlayerScore(19)
    constant playerscore PLAYER_SCORE_LUMBER_RECEIVED           = ConvertPlayerScore(20)

You don't have to write a test, I'll update the code ^_^.

It'll have to run on resource changes still. It can be very simple, if GIVEN != prev given, a trade occurred and donor is stored. On recieve, read the donor and store the change of donor ^_^. Code can be greatly simplified and this doesn't even need to run on Resource.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Idea fails because the player scores are modified after* the thing occurs ;|. I'd still require a timer on the thingie.

As it stands, this is actually the best way to do it >.>. There is no player score event.

This was my thingie
JASS:
library Trade uses /*
    */Event //hiveworkshop.com/forums/submissions-414/snippet-event-186555/
    
    //Version 3.0.0.0
    
    //struct Trade extends array
        //static constant Event EVENT_GOLD
        //static constant Event EVENT_LUMBER
    
        //readonly static player giver
        //readonly static player reciever
        //readonly static integer amount
        //readonly static playerstate state
        
    private module Init
        private integer goldScore
        private integer lumberScore
        
        private static method tradeGold takes nothing returns boolean
            local integer i
            local player p = GetTriggerPlayer()
            local thistype this = GetPlayerId(p)
            if (giver == null) then
                set i = GetPlayerScore(p, PLAYER_SCORE_GOLD_GIVEN)
                set amount = i-goldScore
                if (amount != 0) then
                    set goldScore = i
                    set giver = p
                    set state = PLAYER_STATE_RESOURCE_GOLD
                endif
            else
                set reciever = p
                
                call EVENT_GOLD.fire()
                
                set giver = null
                set giver = null
                set reciever = null
                set state = null
                set amount = 0
            endif
            set p = null //decrease pointer count to handle
            return false
        endmethod
        private static method tradeLumber takes nothing returns boolean
            local integer i
            local player p = GetTriggerPlayer()
            local thistype this = GetPlayerId(p)
            if (giver == null) then
                set i = GetPlayerScore(p, PLAYER_SCORE_LUMBER_GIVEN)
                set amount = i-lumberScore
                if (amount != 0) then
                    set lumberScore = i
                    set giver = p
                    set state = PLAYER_STATE_RESOURCE_LUMBER
                endif
            else
                set reciever = p
                
                call EVENT_LUMBER.fire()
                
                set giver = null
                set giver = null
                set reciever = null
                set state = null
                set amount = 0
            endif
            set p = null //decrease pointer count to handle
            return false
        endmethod
        private static method onInit takes nothing returns nothing
            local integer this = 16
            local trigger t = CreateTrigger()
            local trigger t2 = CreateTrigger()
            set EVENT_GOLD = CreateEvent()
            set EVENT_LUMBER = CreateEvent()
            loop
                set this = this - 1
                set goldScore = GetPlayerScore(Player(this), PLAYER_SCORE_GOLD_GIVEN)
                set lumberScore = GetPlayerScore(Player(this), PLAYER_SCORE_LUMBER_GIVEN)
                call TriggerRegisterPlayerStateEvent(t, Player(this), PLAYER_STATE_RESOURCE_GOLD, GREATER_THAN_OR_EQUAL, 0)
                call TriggerRegisterPlayerStateEvent(t2, Player(this), PLAYER_STATE_RESOURCE_LUMBER, GREATER_THAN_OR_EQUAL, 0)
                exitwhen this == 0
            endloop
            call TriggerAddCondition(t, Condition(function thistype.tradeGold))
            call TriggerAddCondition(t2, Condition(function thistype.tradeLumber))
        endmethod
    endmodule
    struct Trade extends array
        readonly static player giver = null
        readonly static player reciever = null
        readonly static playerstate state = null
        readonly static integer amount = 0
        readonly static Event EVENT_GOLD = 0
        readonly static Event EVENT_LUMBER = 0
        implement Init
    endstruct
endlibrary
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
You could really expand the description on this thing, like adding a description of what each variable is used for. Yes, the names are intuitive enough, but I've got someone who's been complaining about it. Use this as a good example how you can improve your description:

JASS:
*       function GetUnitById takes integer index returns unit
*           -   Returns unit given a unit index
*       function GetUnitId takes unit u returns integer
*           -   Returns unit index given a unit
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
I wouldn't even know how to describe things as simple as this, lol..

JASS:
        //static constant Event EVENT_GOLD
        //static constant Event EVENT_LUMBER
    
        //readonly static player giver
        //readonly static player taker
        //readonly static integer amount
        //readonly static playerstate state

I mean, for state, I'd just say it's the playerstate... for amount, it's the amount.. giver is the giver and taker is the taker. That's the reason why I didn't describe ;P.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
I think it's more of a formality than anything else. While it's redundant, it'd make it complete. Maybe add a note that shows how to use EVENT_GOLD, EVENT_LUMBER or at least a link to a how-to that shows how to use those things.

That's part of the Event API. It's not good to show how to use APIs in other resources =). I don't believe in redundant information as that just clutters everything up =).

To see how to use Event, u'd look at the Event resource ^)^.
 
I don't believe in redundant information

=o
In that case, I refuse to believe in your existence whoever you are xD lol
You still have to describe the functions (even if the descriptions are redundant)
I did the same thing with "Mode Manager".
Most of the functions explained themselves, but I described them anyways.
As Bribe said, you need to make it complete by adding a description to your API.
 
Top