ok, I am jsut learning JASS and I have been working on my first truly ALL Jass script, but as many of you have probably guessed by now, I am running into some trouble. The point of my script is to get a very accurate read out of how much damage a unit does to another unit, and get gold equal to that damage. This is the script I have right now.
function Calc takes real Life, unit Attacked, unit Attacker returns nothing
local integer Damage
set Damage = ( R2I(Life) - R2I(GetUnitStateSwap(UNIT_STATE_LIFE, Attacker)) )
call DisplayTextToForce( GetPlayersAll(), R2S(Damage) )
call AdjustPlayerStateBJ( Damage, GetOwningPlayer(Attacker), PLAYER_STATE_RESOURCE_GOLD )
endfunction
function DamageSource takes unit Attacker returns boolean
if ( not ( Attacker == GetEventDamageSource() ) ) then
return false
endif
return true
endfunction
function InitCalc takes real Life, unit Attacked, unit Attacker returns nothing
local trigger Calcstart
set Calcstart = CreateTrigger()
call TriggerAddCondition(Calcstart, Condition(function DamageSource))
call TriggerRegisterUnitEvent(Calcstart, Attacked, EVENT_UNIT_DAMAGED)
call TriggerAddAction( Calcstart, function Calc )
endfunction
function InitialLife takes nothing returns nothing
local real Life = GetUnitStateSwap(UNIT_STATE_LIFE, GetTriggerUnit())
call DisplayTextToForce( GetPlayersAll(), R2S(Life) )
call InitCalc(Life, GetTriggerUnit(), GetEventDamageSource())
endfunction
function InitTrig_DamageToGold takes nothing returns nothing
set gg_trg_DamageToGold = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_DamageToGold, EVENT_PLAYER_UNIT_ATTACKED )
call TriggerAddAction( gg_trg_DamageToGold, function InitialLife )
endfunction
The trigger works and gives me the first value when the unit starts the attack, but as soon as the other unit takes damage, the game crashes. I think it probably has to do something with my condition function and the local trigger i created. If anyone can tell me how to fix this I would really appreciate it alot.
function InitCalc takes real Life, unit Attacked, unit Attacker returns nothing
local trigger Calcstart
set Calcstart = CreateTrigger()
call TriggerAddCondition(Calcstart, Condition(function DamageSource))
call TriggerRegisterUnitEvent(Calcstart, Attacked, EVENT_UNIT_DAMAGED)
call TriggerAddAction( Calcstart, function Calc )
endfunction
An action function must take nothing and return nothing. That means that you can't pass the parameters Life, Attacked and Attacker to that function. The common solution is using the Handle Vars.
Now about what you are trying to accomplish. There is a native function called GetEventDamage(), that will return the amount of damage dealt. So I'm afraid your Jass script will end up as simple as this:
wow that is awesome, I am not familiar yet with all of the native functions. That function isn't in the GUI is it? because I seriously don't recall a "get damage" as an integer or real number option.
That function looks great! I just need to make a trigger function which activates when any unit takes damage, the only problem with that, is also in the GUI EVENT_UNIT_DAMAGED can only to refer to a specific unit, not an "any unit event" so how would i go about calling that function without causing problems in confusing which "GetEventDamage" value to use?
hooray! i got it working, this is the script i used
function Calc takes nothing returns nothing
call AdjustPlayerStateBJ(R2I(GetEventDamage()), GetOwningPlayer(GetEventDamageSource()), PLAYER_STATE_RESOURCE_GOLD)
endfunction
function InitCalc takes unit Attacked returns nothing
local trigger Calcstart
set Calcstart = CreateTrigger()
call TriggerRegisterUnitEvent(Calcstart, Attacked, EVENT_UNIT_DAMAGED)
call TriggerAddAction( Calcstart, function Calc )
endfunction
function InitialLife takes nothing returns nothing
local real Life = GetUnitStateSwap(UNIT_STATE_LIFE, GetTriggerUnit())
call DisplayTextToForce( GetPlayersAll(), R2S(Life) )
call InitCalc(GetTriggerUnit())
endfunction
function InitTrig_DamageToGold takes nothing returns nothing
set gg_trg_DamageToGold = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_DamageToGold, EVENT_PLAYER_UNIT_ATTACKED )
call TriggerAddAction( gg_trg_DamageToGold, function InitialLife )
endfunction
Thank you Kattana!
Edit: seems to leak = / Edit2: I tried to add another line in "InitCalc" function to " set Calcstart = null " It did not fix the leak. Edit3: I re-read what you said about not being able to pass through those variables, you meant that the "actions" function couldn't receive those paramaters right?
Edit4: haha I swear this is my last edit. Ok, this is a script I came up with to prevent leaks, I used the Native function "DestroyTrigger" Will this function completely remove the trigger from memory?
function Calc takes nothing returns nothing
call AdjustPlayerStateBJ(R2I(GetEventDamage()), GetOwningPlayer(GetEventDamageSource()), PLAYER_STATE_RESOURCE_GOLD)
call DisplayTextToForce( GetPlayersAll(), R2S(GetEventDamage()) )
call DestroyTrigger( GetTriggeringTrigger() )
endfunction
function InitCalc takes unit Attacked returns nothing
local trigger Calcstart
set Calcstart = CreateTrigger()
call TriggerRegisterUnitEvent(Calcstart, Attacked, EVENT_UNIT_DAMAGED)
call TriggerAddAction( Calcstart, function Calc )
endfunction
function InitialLife takes nothing returns nothing
call DisplayTextToForce( GetPlayersAll(), "Attacked!" )
call InitCalc(GetTriggerUnit())
endfunction
function InitTrig_DamageToGold takes nothing returns nothing
set gg_trg_DamageToGold = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_DamageToGold, EVENT_PLAYER_UNIT_ATTACKED )
call TriggerAddAction( gg_trg_DamageToGold, function InitialLife )
endfunction
Your final script looks fine. Creating a trigger on the fly and letting it destroy itself is a good solution, often used by experienced Jass coders. You can become a great Jass scripter
I think GetEventDamage() is called "Event Response - Damage dealt" or something like that in GUI under the functions returning a real.
Yeah, it works great, when one unit is attacking. But now here is the problem...
The local trigger gets created when a unit initiates the attack, so if you have 2 units attacking the same unit. It will create 2 triggers, and BOTH triggers will fire when the first damage is dealt, giving the player that amount of gold twice, instead of 2 seperate amounts for each time it is damaged.
I tried adding a condition to the local essentially saying "Attacker = getdamagesource()". The problem is I found out you can't pass parameters to conditions either = /. so I guess the only thing you can pass a parameter to is a Register Event huh?
Is there any simple way I could solve this problem?
function DamageToGold takes nothing returns nothing
local trigger trg = GetTriggeringTrigger()
if ( GetHandleUnit(trg, "attacker") != GetEventDamageSource() ) then
return
endif
/// Give gold to player here...
call FlushHandleLocals(trg)
call DestroyTrigger(trg)
endfunction
function NextDamageToGold takes unit attacker, unit attacked returns nothing
local trigger trg = CreateTrigger()
call SetHandleHandle(trg, "attacker", attacker)
call TriggerRegisterUnitEvent(trg, attacked, EVENT_UNIT_DAMAGED)
call TriggerAddAction( trg, function DamageToGold )
endfunction
The handle vars code in that link makes my map crash when the editor looks for errors, I made a global variable and changed it under the localvars function. I am very confused = /.
I don't know what to do and this is racking my brain, this is what i have...
// ===========================
function H2I takes handle h returns integer
return h
return 0
endfunction
// ===========================
function LocalVars takes nothing returns gamecache
return udg_handlevars
endfunction
function SetHandleHandle takes handle subject, string name, handle value returns nothing
if value==null then
call FlushStoredInteger(LocalVars(),I2S(H2I(subject)),name)
else
call StoreInteger(LocalVars(), I2S(H2I(subject)), name, H2I(value))
endif
endfunction
function SetHandleInt takes handle subject, string name, integer value returns nothing
if value==0 then
call FlushStoredInteger(LocalVars(),I2S(H2I(subject)),name)
else
call StoreInteger(LocalVars(), I2S(H2I(subject)), name, value)
endif
endfunction
function SetHandleReal takes handle subject, string name, real value returns nothing
if value==0 then
call FlushStoredReal(LocalVars(), I2S(H2I(subject)), name)
else
call StoreReal(LocalVars(), I2S(H2I(subject)), name, value)
endif
endfunction
function SetHandleString takes handle subject, string name, string value returns nothing
if value==null then
call FlushStoredString(LocalVars(), I2S(H2I(subject)), name)
else
call StoreString(LocalVars(), I2S(H2I(subject)), name, value)
endif
endfunction
function GetHandleHandle takes handle subject, string name returns handle
return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
return null
endfunction
function GetHandleInt takes handle subject, string name returns integer
return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
endfunction
function GetHandleReal takes handle subject, string name returns real
return GetStoredReal(LocalVars(), I2S(H2I(subject)), name)
endfunction
function GetHandleString takes handle subject, string name returns string
return GetStoredString(LocalVars(), I2S(H2I(subject)), name)
endfunction
function GetHandleUnit takes handle subject, string name returns unit
return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
return null
endfunction
function GetHandleTimer takes handle subject, string name returns timer
return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
return null
endfunction
function GetHandleTrigger takes handle subject, string name returns trigger
return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
return null
endfunction
function GetHandleEffect takes handle subject, string name returns effect
return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
return null
endfunction
function GetHandleGroup takes handle subject, string name returns group
return GetStoredInteger(LocalVars(), I2S(H2I(subject)), name)
return null
endfunction
function FlushHandleLocals takes handle subject returns nothing
call FlushStoredMission(LocalVars(), I2S(H2I(subject)) )
endfunction
//=========================================================================================================
function DamageCheck takes nothing returns boolean
local trigger Calcstart = GetTriggeringTrigger()
return (GetHandleUnit(Calcstart, "attacker") == GetEventDamageSource())
set Calcstart = null
endfunction
function Damage takes nothing returns nothing
if ( DamageCheck() ) then
call AdjustPlayerStateBJ(R2I(GetEventDamage()), GetOwningPlayer(GetEventDamageSource()), PLAYER_STATE_RESOURCE_GOLD)
call DisplayTextToForce(GetPlayersAll(), I2S(R2I(GetEventDamage())))
call FlushHandleLocals(Calcstart)
call DestroyTrigger(GetTriggeringTrigger())
else
call DoNothing()
endif
endfunction
function LocalEvent takes unit attacked, unit attacker returns nothing
local trigger Calcstart
set Calcstart = CreateTrigger()
call SetHandleHandle(Calcstart, "attacker", attacker)
call TriggerRegisterUnitEvent(Calcstart, attacked, EVENT_UNIT_DAMAGED)
call TriggerAddAction(Calcstart, function Damage)
endfunction
function CurrentLife takes nothing returns nothing
local real Life = GetUnitStateSwap(UNIT_STATE_LIFE, GetTriggerUnit())
call DisplayTextToForce(GetPlayersAll(), "Attacked!")
call LocalEvent(GetTriggerUnit(), GetEventDamageSource())
endfunction
function InitTrig_DamageToReal takes nothing returns nothing
set gg_trg_DamageToReal = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(gg_trg_DamageToReal, EVENT_PLAYER_UNIT_ATTACKED)
call TriggerAddAction(gg_trg_DamageToReal, function CurrentLife)
endfunction
When i try to run it through syntax check in WE it crashes the game... I have a global variable set to handlevars. This is frsustrating. I think it keeps leaking but i don't know why = (. I can't figure it out at all.
Alright, after hours of trying to figure this out, I still get a game crash when I try to compile it. I don't understand at all why its crashing. I have systematicly tried changeing different things and palcement and i still can't figure it out... = /
i just read through the script a few more times and came to a realization.... This isn't going to solve anything even if it does work, All it will do is keep changing the game cache to the most current unit, I am going to have to change the label for each unit as it attacks wont I?
imported_Switch33
#12
The handle vars are supposed to go in your custom script section with the map icon,... and i had the same problem with the handle vars.. (map crashing, when i put them in the map)
I wonder... maybe we can compare whats the same about our maps and figure out what was crashing the map because of the handle vars.