Snippet SetTrade

Troll-Brain

You can change this now in User CP.
Reaction score
85
JASS:
library SetTrade initializer init uses DRES

globals
    public constant integer ALL = 3
    public constant integer GIVE = 4
    public constant integer RECEIVE = 5
endglobals

globals
    private integer ResourceType
    private integer TradeType
    private boolean Enable
    private force GoldForbiddenReceivers
    private force GoldForbiddenDonors
    private force LumberForbiddenReceivers
    private force LumberForbiddenDonors
endglobals

function SetPlayerTrade takes player p, integer resourceType, integer tradeType , boolean enable returns boolean
    if p == null then
        debug call BJDebugMsg("library " + SCOPE_PREFIX + " : the player p argument for the function SetPlayerTrade is null")
        return false
    endif
    
    if resourceType == DRES_GOLD then
    
        if tradeType == GIVE then
            if enable then
                call ForceRemovePlayer(GoldForbiddenDonors,p)
            else
                call ForceAddPlayer(GoldForbiddenDonors,p)
            endif
        elseif tradeType == RECEIVE then
            if enable then
                call ForceRemovePlayer(GoldForbiddenReceivers,p)
            else
                call ForceAddPlayer(GoldForbiddenReceivers,p)
            endif
        elseif tradeType == DRES_ALL then
            if enable then
                call ForceRemovePlayer(GoldForbiddenReceivers,p)
                call ForceRemovePlayer(GoldForbiddenDonors,p)
            else
                call ForceAddPlayer(GoldForbiddenReceivers,p)
                call ForceAddPlayer(GoldForbiddenDonors,p)
            endif
        else
            debug call BJDebugMsg("library " + SCOPE_PREFIX + " : the integer tradeType argument for the function SetPlayerTrade is invalid")
            return false
        endif
        
    elseif resourceType == DRES_LUMBER then
    
        if tradeType == GIVE then
            if enable then
                call ForceRemovePlayer(LumberForbiddenDonors,p)
            else
                call ForceAddPlayer(LumberForbiddenDonors,p)
            endif
        elseif tradeType == RECEIVE then
            if enable then
                call ForceRemovePlayer(LumberForbiddenReceivers,p)
            else
                call ForceAddPlayer(LumberForbiddenReceivers,p)
            endif
        elseif tradeType == DRES_ALL then
            if enable then
                call ForceRemovePlayer(LumberForbiddenReceivers,p)
                call ForceRemovePlayer(LumberForbiddenDonors,p)
            else
                call ForceAddPlayer(LumberForbiddenReceivers,p)
                call ForceAddPlayer(LumberForbiddenDonors,p)
            endif
        else
            debug call BJDebugMsg("library " + SCOPE_PREFIX + " : the integer tradeType argument for the function SetPlayerTrade is invalid")
            return false
        endif
        
    elseif resourceType == DRES_ALL then
    
        if tradeType == GIVE then
            if enable then
                call ForceRemovePlayer(LumberForbiddenDonors,p)
                call ForceRemovePlayer(GoldForbiddenDonors,p)
            else
                call ForceAddPlayer(LumberForbiddenDonors,p)
                call ForceAddPlayer(GoldForbiddenDonors,p)
            endif
        elseif tradeType == RECEIVE then
            if enable then
                call ForceRemovePlayer(LumberForbiddenReceivers,p)
                call ForceRemovePlayer(GoldForbiddenReceivers,p)
            else
                call ForceAddPlayer(LumberForbiddenReceivers,p)
                call ForceAddPlayer(GoldForbiddenReceivers,p)
            endif
        elseif tradeType == DRES_ALL then
            if enable then
                call ForceRemovePlayer(LumberForbiddenReceivers,p)
                call ForceRemovePlayer(LumberForbiddenDonors,p)
                call ForceRemovePlayer(GoldForbiddenReceivers,p)
                call ForceRemovePlayer(GoldForbiddenDonors,p)
            else
                call ForceAddPlayer(LumberForbiddenReceivers,p)
                call ForceAddPlayer(LumberForbiddenDonors,p)
                call ForceAddPlayer(GoldForbiddenReceivers,p)
                call ForceAddPlayer(GoldForbiddenDonors,p)
            endif
        else
            debug call BJDebugMsg("library " + SCOPE_PREFIX + " : the integer tradeType argument for the function SetPlayerTrade is invalid")
            return false
        endif
    
    else
        debug call BJDebugMsg("library " + SCOPE_PREFIX + " : the integer resourceType argument for the function SetPlayerTrade is invalid")
        return false
    endif
    
    return true
endfunction

private function SetPlayerTradeForceEnum takes nothing returns nothing
    call SetPlayerTrade(GetEnumPlayer(),ResourceType,TradeType,Enable)
endfunction

function SetForceTrade takes force f, integer resourceType, integer tradeType , boolean enable returns boolean
    if f == null then
        debug call BJDebugMsg("library " + SCOPE_PREFIX + " : the force f argument for the function SetPlayerTradeForGroup is invalid")
        return false
    endif
    if resourceType != DRES_GOLD and resourceType != DRES_LUMBER and resourceType != DRES_ALL then
        debug call BJDebugMsg("library " + SCOPE_PREFIX + " : the integer resourceType argument for the function SetPlayerTradeForGroup is invalid")
        return false
    endif
    if tradeType != GIVE and tradeType != RECEIVE and tradeType != DRES_ALL then
        debug call BJDebugMsg("library " + SCOPE_PREFIX + " : the integer tradeType argument for the function SetPlayerTradeForGroup is invalid")
        return false
    endif
    set ResourceType = resourceType
    set TradeType = tradeType
    set Enable = enable
    call ForForce(f,function SetPlayerTradeForceEnum)
    return true
endfunction

function SetTradeForAll takes integer resourceType, integer tradeType, boolean enable returns boolean
    local integer i = -1
    
    if resourceType != DRES_GOLD and resourceType != DRES_LUMBER and resourceType != DRES_ALL then
        debug call BJDebugMsg("library " + SCOPE_PREFIX + " : the integer resourceType argument for the function SetPlayerTradeForGroup is invalid")
        return false
    endif
    if tradeType != GIVE and tradeType != RECEIVE and tradeType != DRES_ALL then
        debug call BJDebugMsg("library " + SCOPE_PREFIX + " : the integer tradeType argument for the function SetPlayerTradeForGroup is invalid")
        return false
    endif
    
    loop
    exitwhen i == 11
    set i = i+1
    
        call SetPlayerTrade(Player(i),resourceType,tradeType,enable)
        
    endloop
    
    return true
endfunction

private function AvoidForbiddenTrades takes nothing returns nothing
    local eventid evd = GetTriggerEventId()
    local player donor
    local player receiver
    local integer deal
    
    if evd == PLAYER_STATE_RESOURCE_GOLD then
    
        set receiver = GetGoldReceiver()
        set donor = GetGoldDonor()
        set deal = GetGoldDeal()
        if IsPlayerInForce(receiver,GoldForbiddenReceivers) or IsPlayerInForce(donor,GoldForbiddenDonors) then
            call SetPlayerState(receiver,PLAYER_STATE_RESOURCE_GOLD,GetPlayerState(receiver,PLAYER_STATE_RESOURCE_GOLD)-deal)
            call SetPlayerState(donor,PLAYER_STATE_RESOURCE_GOLD,GetPlayerState(donor,PLAYER_STATE_RESOURCE_GOLD)+deal)
        endif
    
    elseif evd == PLAYER_STATE_RESOURCE_LUMBER then
        
        set receiver = GetLumberReceiver()
        set donor = GetLumberDonor()
        set deal = GetLumberDeal()
        if IsPlayerInForce(receiver,LumberForbiddenReceivers) or IsPlayerInForce(donor,LumberForbiddenDonors) then
            call SetPlayerState(receiver,PLAYER_STATE_RESOURCE_GOLD,GetPlayerState(receiver,PLAYER_STATE_RESOURCE_GOLD)-deal)
            call SetPlayerState(donor,PLAYER_STATE_RESOURCE_GOLD,GetPlayerState(donor,PLAYER_STATE_RESOURCE_GOLD)+deal)
        endif
    endif
endfunction

private function init takes nothing returns nothing
    local trigger trig = CreateTrigger()
    local force f = CreateForce()
    
    call ForceEnumPlayers(f,null)
    call TriggerRegisterTrade(trig,f,DRES_ALL)
    call TriggerAddAction(trig,function AvoidForbiddenTrades)
    
    set GoldForbiddenReceivers = CreateForce()
    set GoldForbiddenDonors = CreateForce()
    set LumberForbiddenReceivers = CreateForce()
    set LumberForbiddenDonors = CreateForce()
    
    call DestroyForce(f)
    set f = null
endfunction

endlibrary


I know i must make some comments, but first what you think about the functions and constants names ?
And should i add something else to the code ?

It is to handle gold and lumber trade between players (activate / deactivate).
For some reasons if you don't want to use a custom system for the gold/lumber trade between players, but the original warcraft one (menu ally F11), but you want disable/enable it for the player X during the game, for gold and/or lumber, that is for you.

JASS:
function SetPlayerTrade takes player p, integer resourceType, integer tradeType , boolean enable returns boolean


JASS:
function SetForceTrade takes force f, integer resourceType, integer tradeType , boolean enable returns boolean


JASS:
function SetTradeForAll takes integer resourceType, integer tradeType, boolean enable returns boolean


The constants for the resourceType are :
Code:
DRES_GOLD
DRES_LUMBER
DRES_ALL

The constants for the tradeType are :
Code:
SetTrade_ALL
SetTrade_GIVE
SetTrade_RECEIVE
 

SerraAvenger

Cuz I can
Reaction score
234
JASS:
//...
    public constant integer ALL = 3
    public constant integer GIVE = 4
    public constant integer RECEIVE = 5


Should be...

JASS:
//...
    constant integer TRADE_TYPE_ALL = 3
    constant integer TRADE_TYPE_GIVE = 4
    constant integer TRADE_TYPE_RECEIVE = 5


and since you're not setting trades, but enabling/disabling trading, the function names should be

PlayerTradeEnable
ForceTradeEnable
TradeEnable
 

Troll-Brain

You can change this now in User CP.
Reaction score
85
That's seems fine, i will also probably add functions interfaces called when a forbidden trade is detected, what you think about that ?

EDIT : What do you suggest for the library name ?
 

SerraAvenger

Cuz I can
Reaction score
234
JASS:
globals
    constant integer TRADE_TYPE_ALL = 0
    constant integer TRADE_TYPE_GIVE = 1
    constant integer TRADE_TYPE_RECEIVE = 2
    //... other globals
    private constant integer RESOURCE_TYPES = 5 // just a guess, I don't know the DRES constants...
    private constant integer TRADE_TYPES = 3
    private force array TradeForbiddenForce[TRADE_TYPES][RESOURCE_TYPES]
endglobals


I guess this one is much shorter than what you are currently using then:

JASS:

function PlayerTradeEnable takes player p, integer resourceType, integer tradeType , boolean enable returns boolean
    local integer i = tradeType
    local integer minJ = resourceType
    local integer j
    local integer maxI
    local integer maxJ

    // Manage Data Consistensy HERE... not all over the function : )
    // and most importantly, not multiple times.

    if tradeType == TRADE_TYPE_ALL then
        set maxI = TRADE_TYPES - 1
        set i = i + 1
    else
        set maxI = tradeType
    endif

    if resourceType == DRES_ALL then
        set maxJ = RESOURCE_TYPES - 1
        set minJ = minJ + 1
    else
        set maxJ = resourceType
    endif


    loop
        exitwhen i > maxI
        set j = minJ
        loop
            exitwhen j > maxJ
            if enable then
                call ForceRemovePlayer( TradeForbiddenForce[ i ][ j ], p )
            else
                call ForceAddPlayer( TradeForbiddenForce[ i ][ j ], p )
            endif
            set j = j + 1
        endloop
        set i = i + 1
    endloop
endfunction


JASS:

function SetTradeForAll takes integer resourceType, integer tradeType, boolean enable returns boolean
    // since you allready have a function for forces, either leave this out or make it use forces instead.
    return ForceTradeEnable( bj_FORCE_ALL_PLAYERS, resourceType, tradeType, enable )
endfunction


And how does this work:

JASS:

//...
    local eventid evd = GetTriggerEventId()
//...    
    if evd == PLAYER_STATE_RESOURCE_GOLD then


?

For the function interfaces... I'm sorry but I guess I don't really get what you want to achieve with these ... =?
You mean that the disable/enable functions take an additional parameter (a function that extends some interface) to determine what shall happen if a player does trade who actually shouldn't?
I think function interfaces are too much overkill for that...
Perhaps just use a function at the top of the library that is called whenever a trade is detected...

The library name should be somewhat that represents its function in the map... like TradeDisabler or TradeDeactivator
 

Troll-Brain

You can change this now in User CP.
Reaction score
85
Sure your code is shorter, but honestly it doesn't make sense for me, i really prefer the if(s)/elseif(s).
And it doesn't matter anyway.

And how does this work:
You have to read the code here :
http://www.thehelper.net/forums/showthread.php?t=127657

If you are still confused about how it works i will be happy to explain you how it does the job.

For the function interfaces... I'm sorry but I guess I don't really get what you want to achieve with these ... =?
You mean that the disable/enable functions take an additional parameter (a function that extends some interface) to determine what shall happen if a player does trade who actually shouldn't?

Exactly.
Honestly i'm just trying to add (more) usefulness xD

I think function interfaces are too much overkill for that...
Perhaps just use a function at the top of the library that is called whenever a trade is detected...
I don't really like the idea that the user must modify functions in the system itself, and i love the flexibility and usage of function interfaces.
But maybe you're right, i dunno.
The library name should be somewhat that represents its function in the map... like TradeDisabler or TradeDeactivator
I will apply all your suggestions about the names soon.

Thx for the comments, it deserves a rep at least, if only you weren't a guy you could have more :p
 

SerraAvenger

Cuz I can
Reaction score
234
Sure your code is shorter, but honestly it doesn't make sense for me
you're basically looping through all the necessary trade types and for each of the trade types you loop through all the necessary resource types.
That way, you don't have unnecessary if then elses and a much shorter code ; )

Yeah, I read that yesterday. I wasn't familiar with the use of PlayerState events : )

Exactly.
Honestly i'm just trying to add (more) usefulness xD

I don't really like the idea that the user must modify functions in the system itself, and i love the flexibility and usage of function interfaces.
But maybe you're right, i dunno.
Just test it out and see how it increases / decreases useability.
 

Troll-Brain

You can change this now in User CP.
Reaction score
85
you're basically looping through all the necessary trade types and for each of the trade types you loop through all the necessary resource types.
That way, you don't have unnecessary if then elses and a much shorter code ; )

It's not like the code is about hundreds of lines, and it's not a loop just a if/elseif.
And i also don't like the fact you use more variables than me.
The last point, even if this code shouldn't be edited, it still makes the eventual debug harder, i mean the code is less obvious.

But i'm not such arrogant, if someone else enough competent, like you, think it should be edited like this way, be sure i will do it.

Just test it out and see how it increases / decreases useability.
I will.
 

SerraAvenger

Cuz I can
Reaction score
234
It's not like the code is about hundreds of lines, and it's not a loop just a if/elseif.
What you use is a hardcoded loop.
I just made the loop more obvious and optimized it (from iterative search to array indicies)

But since this doesn't need extension (there only are 2 tradeable resources), you might just as well leave it the way it is. It is just much easier to add 2-3 lines of code for a new group and change 1 constant than adding 2 additional constants, a couple of additional (equal) "if then else" blocks (which isn't permitted by my DRY principle) and some lines in the consistency management. +it is much more efficient ;D
And i also don't like the fact you use more variables than me.
16 bytes of stack size ;)

be sure i will do it.
Never do anything because someone else told you that it would be better/faster/cleaner.
Just try it out and then decide for yourself.
Competence is no reason, anyone may err. Even the master did two or three times ( ;) )
Good.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top