Troll-Brain
You can change this now in User CP.
- Reaction score
- 85
I don't really like to name it as a "system", cause it's a very simple logic but i think it's not a snippet.
Because blizzard suck and don't create an event to register when a player give gold or lumber to another player, i made this thing.
It requires a vJass compiler (for the system alone) and the jass new gen pack with UMWSE activated for the demo map with a gui example.
I attached a demo map without the UMWSE features.
I highly recommend to use UMWSE for gui users.
For the if/then/else multiple actions, the events,actions,conditions added, etc.
You need to be two players at least to test the map.
Here is the code :
Here is the documentation :
Because blizzard suck and don't create an event to register when a player give gold or lumber to another player, i made this thing.
It requires a vJass compiler (for the system alone) and the jass new gen pack with UMWSE activated for the demo map with a gui example.
I attached a demo map without the UMWSE features.
I highly recommend to use UMWSE for gui users.
For the if/then/else multiple actions, the events,actions,conditions added, etc.
You need to be two players at least to test the map.
Here is the code :
JASS:
//==============================================================================
// DRES -> DETECT RESOURCE EXCHANGE SYSTEM -- v1.3 // by Troll-Brain
//==============================================================================
//
// REQUIREMENTS :
// * The last JassHelper
// * The library DataSystem by grim001, more infos about that :
// <a href="http://wc3campaigns.net/pastebint.php?t=100400&code=87e482563039fa6408a045efca81ea5e" target="_blank" class="link link--external" rel="nofollow ugc noopener">http://wc3campaigns.net/pastebint.php?t=100400&code=87e482563039fa6408a045efca81ea5e</a>
//
// THE GOAL :
// * Detect when a player gives gold or wood to an allie, and ofc to know wich one is the donor, the receiver
// and the amount of the deal.
//
// HOW IT WORKS :
// * It add a new TriggerRegisterPlayerStateEvent event to your trigger, for each player in the force you define
// and also a condition because this function don't have a boolexpr parameter.
//
// HOW TO IMPORT:
// * Just create a trigger named DRES or whatever.
// * Convert it to text and replace the trigger text with this one.
// * Do the same with the library DataSystem.
//
// HOW TO USE IT :
// * Read the documentation and check the example in the demo map.
library DRES initializer init needs DataSystem
globals
public constant integer GOLD= 1 // If you don't already use these common name for constants
public constant integer LUMBER= 2 // , then you can remove the public attribute
private constant real MAX= 1000000.0 // you should not edit this value, because it's simply the max possible of a resource
private constant real TIME_OUT= 1.0 // i think that's a good value
endglobals
globals // don't edit them
private timer Tim= null
private trigger Trig= null
private integer Ref= 0
public playerstate Ple= null
private integer Count= 1
endglobals
//! runtextmacro DataDeclareFast("DRES_GoldTrig","trigger")
//! runtextmacro DataDeclareFast("DRES_LumberTrig","trigger")
//Or use the textmacro DataDeclare instead, if you REALLY need more.
//! textmacro DRES_Resource takes TYPE , NAME
globals
private player $TYPE$Donor= null
private player $TYPE$PossibleDonor= null
private player $TYPE$Receiver= null
private integer array $TYPE$Given
private real $TYPE$Time= 0.0
private conditionfunc $TYPE$C= null
private integer $TYPE$Deal= 0
private integer $TYPE$PossibleDeal= 0
endglobals
private function $TYPE$Check takes nothing returns boolean
local player p= GetTriggerPlayer()
if GetEventPlayerState () == PLAYER_STATE_RESOURCE_$NAME$ then
if TimerGetElapsed(Tim)*Count != $TYPE$Time then
set $TYPE$PossibleDonor= GetTriggerPlayer()
set $TYPE$Time= TimerGetElapsed(Tim)*Count
return false
else
set Ref= GetPlayerId($TYPE$PossibleDonor)
set $TYPE$PossibleDeal= GetPlayerScore($TYPE$PossibleDonor, PLAYER_SCORE_$NAME$_GIVEN) - $TYPE$Given[Ref]
if $TYPE$PossibleDeal == 0 then
set $TYPE$PossibleDonor= GetTriggerPlayer()
return false
endif
set $TYPE$Deal= $TYPE$PossibleDeal
set $TYPE$Donor= $TYPE$PossibleDonor
set $TYPE$Receiver= GetTriggerPlayer()
set $TYPE$Given[Ref] = GetPlayerScore($TYPE$Donor, PLAYER_SCORE_$NAME$_GIVEN)
endif
set $TYPE$Time= TimerGetElapsed(Tim)*Count
endif
return true
endfunction
private function $TYPE$ForForce takes nothing returns nothing
call TriggerRegisterPlayerStateEvent( Trig, GetEnumPlayer(), PLAYER_STATE_RESOURCE_$NAME$, NOT_EQUAL, MAX )
endfunction
function Get$TYPE$Donor takes nothing returns player
if GetEventPlayerState()!= PLAYER_STATE_RESOURCE_$NAME$ then
debug call BJDebugMsg("you tried to use the function Get$TYPE$Donor with a bad event")
return null
elseif GetDRES_$TYPE$Trig(GetTriggeringTrigger()) != GetTriggeringTrigger() then
debug call BJDebugMsg("you didn039;t use the function TriggerRegisterTrade to register the $TYPE$ trade")
return null
endif
return $TYPE$Donor
endfunction
function Get$TYPE$Receiver takes nothing returns player
if GetEventPlayerState()!= PLAYER_STATE_RESOURCE_$NAME$ then
debug call BJDebugMsg("you tried to use the function Get$TYPE$Receiver with a bad event")
return null
elseif GetDRES_$TYPE$Trig(GetTriggeringTrigger()) != GetTriggeringTrigger() then
debug call BJDebugMsg("you didn039;t use the function TriggerRegisterTrade to register the $TYPE$ trade")
return null
endif
return $TYPE$Receiver
endfunction
function Get$TYPE$Deal takes nothing returns integer
if GetEventPlayerState()!= PLAYER_STATE_RESOURCE_$NAME$ then
debug call BJDebugMsg("you tried to use the function Get$TYPE$Deal with a bad event")
return 0
elseif GetDRES_$TYPE$Trig(GetTriggeringTrigger()) != GetTriggeringTrigger() then
debug call BJDebugMsg("you didn039;t use the function TriggerRegisterTrade to register the $TYPE$ trade")
return 0
endif
return $TYPE$Deal
endfunction
function GetLast$TYPE$Donor takes nothing returns player
return $TYPE$Donor
endfunction
function GetLast$TYPE$Receiver takes nothing returns player
return $TYPE$Receiver
endfunction
function GetLast$TYPE$Deal takes nothing returns integer
return $TYPE$Deal
endfunction
//! endtextmacro
//! runtextmacro DRES_Resource("Gold","GOLD")
//! runtextmacro DRES_Resource("Lumber","LUMBER")
function TriggerRegisterTrade takes trigger t , force f , integer resourceType returns boolean
if f== null then
debug call BJDebugMsg("the force taken in the function TriggerRegisterTrade is null")
return false
elseif t== null then
debug call BJDebugMsg("the trigger taken in the function TriggerRegisterTrade is null")
return false
endif
set Trig= t
if resourceType== GOLD then
if GetDRES_GoldTrig(t)== t then
debug call BJDebugMsg("You had already register a gold exchange for this trigger")
return false
endif
call ForForce(f,function GoldForForce)
call TriggerAddCondition(t,Condition(function GoldCheck))
call SetDRES_GoldTrig(t,t)
return true
elseif resourceType== LUMBER then
if GetDRES_LumberTrig(t)== t then
debug call BJDebugMsg("You had already register a lumber exchange for this trigger")
return false
endif
call ForForce(f,function LumberForForce)
call TriggerAddCondition(t,Condition(function LumberCheck))
call SetDRES_LumberTrig(t,t)
return true
endif
debug call BJDebugMsg("the resourceType taken in the function TriggerRegisterTrade is invalid")
return false
endfunction
// This textmacro should be used if you want other events in your trigger, because in the case of a trade, the conditions will be evaluated two times.
// Using this macro won't avoid the double evaluation but if you use it just after the local declaration in your condition, it will return false
// if the players events GOLD or LUMBER start the trigger. Check the demo trigger to see an example of usage.
//! textmacro DRES_C
set DRES_Ple = GetEventPlayerState()
if DRES_Ple== PLAYER_STATE_RESOURCE_GOLD or DRES_Ple== PLAYER_STATE_RESOURCE_GOLD then
return true
endif
//! endtextmacro
private function TimeOut takes nothing returns nothing
set Count= Count+1
endfunction
private function init takes nothing returns nothing
local trigger t=CreateTrigger()
call TriggerAddAction(t,function TimeOut)
set Tim=CreateTimer()
call TimerStart(Tim,TIME_OUT,true,null)
set GoldC=Condition(function GoldCheck)
set LumberC=Condition(function LumberCheck)
endfunction
endlibrary
Here is the documentation :
JASS:
// ~~ CHANGELOG
* v1.3
-updated with the new library DataSystem
* v1.2
- Fixed a bug, i used GetTriggerEventId() instead of GetEventPlayerState() without any compilation error ...
* v1.1
- Renamed the function TriggerRegisterResourceExchange by this shorter name : TriggerRegisterTrade.
- Added a demo map.
* v1.0
- Edited the code to follow the jass convention.
- Added the functions GetLast...
- Fixed a possible bug if the time beetween two trades was very closed.
- Now i039;ts completly friendly user, because :
~ you won039;t be able to add many time the same ResourceExchange event in a same trigger, even if you call it.
~ the gets returns null if it039;s not the right event.
~ added a texmacro for your trigger conditions.
~ added more debug messages.
* v0.2
- Added a miss setting of the variables $TYPE$Time in the Alt$TYPE$Check functions.
- Added more comments about how to use the AltRegister$TYPE$Exchange function.
* v0.1
- Initial Release.
// ~~ HOW TO USE IT
I will comment the functions.
>>> Register function <<<
You should use only allies for the force parameter but if the alliance can change in the game,
or if you can give resource to ennemies then simply add all players.
The function below is friendly user, it will add for you the events and the condition to your trigger.
** function TriggerRegisterResourceExchange takes trigger t , force f , integer resourceType returns boolean
- Use this function to register a trade. For the ressourceType simply use the constants DRES_GOLD and DRES_LUMBER.
or GOLD and LUMBER if you can delete the public attribute of them in the library.
- It returns true if the event is register and false if not.
You are not allowed to add the same event in the same trigger with this function.
If you try it it won039;t add it anyway, so just don039;t.
Now it039;s hardier.
The function TriggerRegisterResourceExchange add players event PLAYER_STATE_RESOURCE_(GOLD or LUMBER) to your trigger.
You can add more other events to your trigger but you must consider these facts:
- You are not allowed to add these players event PLAYER_STATE_RESOURCE_GOLD or PLAYER_STATE_RESOURCE_LUMBER.
- Your conditions will be evaluated when a resource player change (gold or lumber ofc).
- In case of a trade, the conditions will be evaluated two times.
- I have created a textmacro to fix this problem, check the example.
The condition added by the function TriggerRegisterResourceExchange returns true when the system detect an exchange of ressources between players, but also true,
when the event which fire the trigger, is different to PLAYER_STATE_RESOURCE_(GOLD or LUMBER). To allow the other conditions evaluate.
>>> Get functions <<<
The different Get return null if you try to use it with a bad event.
But ofc you can use the GetLast... anywhere.
** function GetGoldDonor takes nothing returns player
- Use this function to return which player gives gold.
** function GetGoldReceiver takes nothing returns player
- Use this function to return which player get gold.
** function GetLumberDonor takes nothing returns player
- Use this function to return which player gives lumber.
** function GetLumberReceiver takes nothing returns player
- Use this function to return which player get lumber.
** function GetGoldDeal takes nothing returns integer
- Use this function to return the amount of the gold exchange.
** function GetLumberDeal takes nothing returns integer
- Use this function to return the amount of the lumber exchange.
** function GetLastGoldDonor takes nothing returns player
- Use this function to return the last gold donor.
** function GetLastLumberDonor takes nothing returns player
- Use this function to return the last lumber donor.
** function GetLastGoldReceiver takes nothing returns player
- Use this function to return the last gold receiver.
** function GetLastLumberReceiver takes nothing returns player
- Use this function to return the last lumber receiver.
** function GetLastGoldDeal takes nothing returns integer
- Use this function to return the last gold deal.
** function GetLastLumberDeal takes nothing returns integer
- Use this function to return the last lumber deal.
// ~~ SPECIAL THANKS TO
//! popp
- Asked me the system and tested it a lot with me.
//! Blubb-Tec
- Found a code error and reminder me the double evaluation of the trigger.
//! Earth-Fury
- Helped me for respect the jass convention and gave me some tips.
//! grim001
- For his library DataSystem.