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

[JASS] Damage to Gold?

Status
Not open for further replies.
Level 6
Joined
Feb 15, 2005
Messages
183
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.

JASS:
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.
 
Level 3
Joined
Mar 27, 2004
Messages
70
JASS:
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:
JASS:
function Trig_DamageToGold_Actions takes nothing returns nothing
    call AdjustPlayerStateBJ(R2I(GetEventDamage()), GetOwningPlayer(GetEventDamageSource()), PLAYER_STATE_RESOURCE_GOLD)
endfunction
 
Level 6
Joined
Feb 15, 2005
Messages
183
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?
 
Level 6
Joined
Feb 15, 2005
Messages
183
hooray! i got it working, this is the script i used

JASS:
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?

JASS:
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
 
Level 3
Joined
Mar 27, 2004
Messages
70
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 :D

I think GetEventDamage() is called "Event Response - Damage dealt" or something like that in GUI under the functions returning a real.
 
Level 6
Joined
Feb 15, 2005
Messages
183
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?
 
Level 3
Joined
Mar 27, 2004
Messages
70
Using the Handle Vars:
JASS:
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
 
Level 6
Joined
Feb 15, 2005
Messages
183
I don't know what to do and this is racking my brain, this is what i have...

JASS:
// ===========================
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... = /
 
Level 6
Joined
Feb 15, 2005
Messages
183
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?
 
Level 2
Joined
Mar 9, 2004
Messages
39
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.
 
Status
Not open for further replies.
Top