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

Displaying Image

Status
Not open for further replies.
Level 2
Joined
Apr 1, 2019
Messages
156
I'm trying to show an Image at the point where a unit is attacked, problem is it only shows if the unit is standing in certain positions. Here's the trigger

  • Sarah Palin
    • Events
      • Game - GDD_Event becomes Equal to 0.00
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • |c00FF6347Demonic|r|nThe Life and Times of Sarah Palin Equal to (Unit-type of GDD_DamageSource)
          • (Owner of GDD_DamageSource) Not equal to (Owner of GDD_DamagedUnit)
        • Then - Actions
          • Set TempPointSpell = (Position of GDD_DamagedUnit)
          • Image - Create an image using war3mapImported\PalinCrop.blp of size 256.00 at TempPointSpell with Z offset 256.00 using image type Indicator
          • Image - Change (Last created image): Enable render always state
          • Image - Show (Last created image)
          • Set Image_SarahPalin_Int[1] = (Image_SarahPalin_Int[1] + 1)
          • Set Image_SarahPalin[Image_SarahPalin_Int[1]] = (Last created image)
          • Custom script: call RemoveLocation(udg_TempPointSpell)
          • Wait 1.00 seconds
          • Set Image_SarahPalin_Int[2] = (Image_SarahPalin_Int[2] + 1)
          • Image - Hide Image_SarahPalin[Image_SarahPalin_Int[2]]
          • Image - Destroy Image_SarahPalin[Image_SarahPalin_Int[2]]
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Image_SarahPalin_Int[1] Equal to Image_SarahPalin_Int[2]
            • Then - Actions
              • Set Image_SarahPalin_Int[1] = 0
              • Set Image_SarahPalin_Int[2] = 0
            • Else - Actions
        • Else - Actions
  • [\trigger]
 
Level 2
Joined
Apr 1, 2019
Messages
156
I was wanting the image to remain for 1 second then disappear. If multiple units are attacking causing this to trigger, would I need to set each created image to a variable then remove them using the 1 and 2 so that way some images don't bug and remain?
 
Level 2
Joined
Apr 1, 2019
Messages
156
Hey I figured it out, I'm a dingus and had the unit attack type "Missle(splash)" but no AOE targets so as long as the unit was moving he'd take no damage not triggering anything.

But is there a better way to trigger than using the 1 and 2 indices of the int counter variable?
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,567
That's pretty clever using two Integers with Arrays to keep track of the Images. I feel stupid for having never Indexed that way before...

Anyway, the code seems fine besides the fact that you're using Waits. Waits aren't precise and are less efficient (or so I've been told). I think timers are usually your best bet.

If you want to improve your code then I'd steer away from GUI and get on the vJASS/Lua train. Or use a combination of both GUI and vJASS/Lua. Here's the Actions taken from your trigger and converted to vJASS. The Timer used in this is precise and completely MUI.

vJASS:
library DisplayImages

function PalinTimer takes nothing returns nothing
    local timer t = GetExpiredTimer()

    set udg_Image_SarahPalin_Int[2] = udg_Image_SarahPalin_Int[2] + 1
    call ShowImageBJ(false, udg_Image_SarahPalin[udg_Image_SarahPalin_Int[2]])
    call DestroyImage(udg_Image_SarahPalin[udg_Image_SarahPalin_Int[2]])
    if udg_Image_SarahPalin_Int[1] == udg_Image_SarahPalin_Int[2] then
        set udg_Image_SarahPalin_Int[1] = 0
        set udg_Image_SarahPalin_Int[2] = 0
    endif

    call PauseTimer(t)
    call DestroyTimer(t)

    set t = null
endfunction

function PalinImage takes nothing returns nothing
    local timer t = CreateTimer()

    set udg_TempPointSpell = GetUnitLoc(udg_GDD_DamagedUnit)
    call CreateImageBJ("war3mapImported\\PalinCrop.blp", 256, udg_TempPointSpell, 256, 2)
    call SetImageRenderAlways(GetLastCreatedImage(), true)
    call ShowImageBJ(true, GetLastCreatedImage())
    set udg_Image_SarahPalin_Int[1] = udg_Image_SarahPalin_Int[1] + 1
    set udg_Image_SarahPalin[udg_Image_SarahPalin_Int[1]] = GetLastCreatedImage()
    call RemoveLocation(udg_TempPointSpell)

    call TimerStart (t, 1.00, false, function PalinTimer)

    set t = null
endfunction

endlibrary

Then you can edit your original trigger to call the PalinImage() function instead.
  • Sarah Palin
    • Events
      • Game - GDD_Event becomes Equal to 0.00
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Your conditions here
        • Then - Actions
          • Custom script: call PalinImage()
        • Else - Actions
And what on God's green earth are you making. Sarah Palin??? Lol!
 
Last edited:
Level 39
Joined
Feb 27, 2007
Messages
5,023
@Uncle, if one wanted to write this script in JASS or Lua then one would just use a local integer variable to keep track of it. For that matter it can be done in GUI by shadowing locally:

  • Sarah Palin
    • Events
      • Game - GDD_Event becomes Equal to 0.00
    • Conditions
    • Actions
      • Custom script: local image udg_Image_SarahPalin
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • |c00FF6347Demonic|r|nThe Life and Times of Sarah Palin Equal to (Unit-type of GDD_DamageSource)
          • (Owner of GDD_DamageSource) Not equal to (Owner of GDD_DamagedUnit)
        • Then - Actions
          • Set TempPointSpell = (Position of GDD_DamagedUnit)
          • Image - Create an image using war3mapImported\PalinCrop.blp of size 256.00 at TempPointSpell with Z offset 256.00 using image type Indicator
          • Image - Change (Last created image): Enable render always state
          • Image - Show (Last created image)
          • Set Image_SarahPalin = (Last created image)
          • Custom script: call RemoveLocation(udg_TempPointSpell)
          • Wait 1.00 seconds
          • Image - Hide Image_SarahPalin
          • Image - Destroy Image_SarahPalin
        • Else - Actions
      • Custom script: set udg_Image_SarahPalin = null
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,567
I messed that code up. The PalinTimer function needs to be above the PalinImage function. Anyway, you should do what Pyrogasm said about the shadowing local var. It still uses a Wait but that's not that big of a deal.

@Pyrogasm In Lua you can create a Timer inside of a function (like I did below) and then reference the same local variables between the two functions.
Lua:
function PalinImage()
    local t = CreateTimer()
    local p = GetUnitLoc(udg_GDD_DamagedUnit)
    local i = CreateImageBJ("war3mapImported\\PalinCrop.blp", 256, p, 256, 2)
    SetImageRenderAlways(i, true)
    ShowImageBJ(true, i)

    TimerStart(t, 1.00, false, function()
        ShowImageBJ(false, i)
        DestroyImage(i)
        PauseTimer(t)
        DestroyTimer(t)
    end)
end

Is it possible to do something like that in Jass? Or will i have to use some global variables or another method?
vJASS:
library DisplayImages

function PalinImage takes nothing returns nothing
    local timer t = CreateTimer()
    local location p = GetUnitLoc(udg_GDD_DamagedUnit)
    local image i = CreateImageBJ("war3mapImported\\PalinCrop.blp", 256, p, 256, 2)
    call SetImageRenderAlways(i, true)
    call ShowImageBJ(true, i)
    call RemoveLocation(p)
    set p = null

    call TimerStart(t, 1.00, false, function()
        call ShowImageBJ(false, i)
        call DestroyImage(i)
 
        call PauseTimer(t)
        call DestroyTimer(t)
 
        set t = null
        set i = null
    endfunction)
 
endfunction

endlibrary
 
Last edited:

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,567
Sounds like a fun map :)

I know that I was using Jass in the code that I posted before but if you really want to further improve your code/make your life easier then I can't help but recommend learning Lua. Lua is awesome and with the right tools it's even easier than GUI. As someone who has learned Jass alongside Lua I found Lua to be easier/more flexible to use in just about every case.

What you need to get started:
Visual Studio Code - Code Editing. Redefined <- Much nicer than Blizzard's editor.

Lua VSCode Integration <- Adds a Lua Extension to Visual Studio Code that contains all of the natives/functions/globals. It will basically autocomplete your sentences. Type "Unit" and a dropdown list will pop up with all of the possible Unit-related options like GetUnitFacing, GetUnitLevel, GetUnitName, GetUnitMoveSped, etc... The names are all self-explanatory so it's really not confusing at all.

So with Lua there's no more "udg_RemoveLocation" and nulling variables. And with local variables just about everything becomes MUI. It also allows you to create proper Tables/Lists with as many dimensions as you want. And you can store objects directly into your Tables so no need for Unit Indexers.

Here's how simple your trigger would be in Lua:
Lua:
function PalinImage()
    local t = CreateTimer()
    local p = GetUnitLoc(udg_GDD_DamagedUnit)
    local i = CreateImageBJ("war3mapImported\\PalinCrop.blp", 256, p, 256, 2)
    SetImageRenderAlways(i, true)
    ShowImageBJ(true, i)

    TimerStart(t, 1.00, false, function()
        ShowImageBJ(false, i)
        DestroyImage(i)
        PauseTimer(t)
        DestroyTimer(t)
    end)
end

Then run the function like this:
  • Sarah Palin
    • Events
      • Game - GDD_Event becomes Equal to 0.00
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Your conditions here
        • Then - Actions
          • Custom script: PalinImage()
        • Else - Actions
The only major issue is that you can't use Lua/Jass together at the moment. And since Lua is new and Jass has been around forever, majority of the systems/content make use of Jass. But I'm sure this issue will get sorted out eventually (ideally you could use both together). I know Bribe has already uploaded Lua versions of most of his systems. And if your map is using strictly GUI then making the switch to Lua is super easy. All you have to do is temporarily disable any triggers that use Custom Script, then go to Scenario -> Map Options -> Change Script Language from Jass to Lua. Then you can re-enable those triggers.
 

Attachments

  • Image Lua.w3x
    16.2 KB · Views: 38
Last edited:
Level 2
Joined
Apr 1, 2019
Messages
156
Hey I know this post is a bit old, but I actually started writing in Lua and I got questions:

In Visual Studio Code I debug with no errors but trying to save in wc3 map I get unexpected symbol errors, on my global GUI variables, if I delete the Globals I get it on my Lua script. Can I not use gui globals with Lua?

Trying to find a reason, I read you gotta use these lines on each line of code which seems very redundant
//! i

And this at the start of the code
//! externalblock extension=lua ObjectMerger $FILENAME$

Anyways, here's some of the code I'm trying to use

JASS:
function grid_loop_set()
    waypoint = 5
    for L = 5, 40 do
        if G_table{L}{1} == 0 or nil then
        G_table[L][1] = 100
        G_array_1 = G_array_1 + 1
        G_1_X[G_array_1] = L
        G_1_Y[G_array_1] = 1
        end
    end
    grid_loop_begin_1()
end

It's not vjass, don't know how to post as lua, lol
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,567
To reference GUI variables you need to type "udg_" beforehand:
Lua:
function GlobalExample()
    udg_GlobalInteger = udg_GlobalInteger + 1
end

Also, I THINK you might need to use square brackets in your condition instead of {L}{1}
Lua:
if G_table[L][1] == 0 or nil then

Also, you don't have to type anything extra like that with Lua.
Maybe you were looking at this?
JNGP Lua Edition - Combining JASS/vJass/Lua
I've never tried combining the two so I don't know.

And to post lua code type "code=lua" between the square brackets.
 
Last edited:
Level 2
Joined
Apr 1, 2019
Messages
156
thanks, adding the udg_ to globals worked.
Found out I also needed '####' the quotes around certain words, players, triggers, ect

One other thing, how do you remove GUI leaks with lua like with Jass, I see there's a garbage collector on this site, but that isn't exactly what I need
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,567
Never used #### before, where exactly are you using it?

Also, some random things about Lua:
You will have to type FourCC before raw data like this:
Lua:
UnitAddAbility(SomeUnit, FourCC('Aslo'))
CreateUnit(Player(0), FourCC("h000"), 0, 0, 0)
And type "%%" in strings if you want to display the % symbol.
Lua:
TestString = "This is 100%% working"
print(TestString)
^That will print "This is 100% working"
I think you have to do that because % normally serves as Modulo.

Another thing, use ".." to incorporate variables in your strings:
Lua:
StormBoltLevel = 1
StormBoltString = StormBoltLevel .. "/3"
print(StormBoltString)
^That will print "1/3"

Edit:
Lua should garbage collect most things automatically. You don't have to null/nil variables either.
However, you still Destroy Special Effects, Timers, etc...
Lua:
DestroyEffect(whichEffect)
PauseTimer(whichTimer)
DestroyTimer(whichTimer)
RemoveLocation(whichLocation)
Edit 2:
Quote from the Doctor
"Lua does not suffer the local declared local agent variable reference counter leak on return bug that JASS does. No need to nil locals before function return with Lua.
Lua currently does not garbage collection Warcraft III object types like location, group and force."
Edit 3:
Another thing I didn't know right away. This allows you to define default values for your Arrays:
Lua:
ExampleVariable = __jarray(100) --This integer will have a default value of 100
 
Last edited:
Level 2
Joined
Apr 1, 2019
Messages
156
Thanks for all the help, '####' I meant as just being any word like player, trigger ect I'm not actually using "####'
Do you know if there is a wc3 lua tutorial somewhere. There's lots of lua tutorials online but none that incorporate wc3 triggers.

Like I can't seem to get a way to get some functions to work, I don't wanna keep bothering you lol
Lua:
    TriggerExecute(Test)
    TriggerExecute("Test")
    TriggerExecute('Test')
 
Status
Not open for further replies.
Top