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

[Lua] Problems making a trigger with Lua

Status
Not open for further replies.
Level 2
Joined
Mar 31, 2020
Messages
12
Lua:
function ResourceDropGetInitalize()
    local i = 0
    local trigger = CreateTrigger()
    print("started resource drop get init")
    local ResourceDropGetConditions = function()   
        print("Resource Picked Up")
        local item = GetItemTypeId(GetManipulatedItem())
        print("Picked up "..GetItemName(item))
        correctitem = false
        for i = 1, 6, 1 do
            if item == CraftItemTable[i] then
                return true
            end
        end
    end
    local ResourceDropGetActions = function()
        
        local i
        local item = GetItemTypeId(GetManipulatedItem())
        local itemindex
        for i = 1, 6, 1 do
            if item == CraftItemTable[i] then
                itemindex = i
                break
            end
        end
        UpdateHeroData(itemindex, 1)
        print("Resource Updated")
    end
    i = 0
    while true do
        if i > MaxPlayerIndex then
                break
            end
            print("testing player "..i.."playstate")
        if (GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING) then
            dCall(TriggerRegisterPlayerUnitEventSimple(trigger, Player(i), EVENT_PLAYER_UNIT_PICKUP_ITEM), "ResourceDropEvent Added")
            print("player"..i.."player unit event established")
        end
        i = i + 1
    end
    print("adding resource conditions")
    dCall(TriggerAddCondition(trigger, Condition(ResourceDropGetConditions)),"ResourceDropConditions Added")
    print("adding resource actions")
    dCall(TriggerAddAction(trigger, ResourceDropGetActions),"ResourceDropAction Added")
end

So that is my code, dCall just does an xpcall and prints the error plus the string shown.

With my xpcalls I get these errors, although it runs through all of the code and has no problem looking at the player state.

attempt to call event value
attempt to call triggercondition value
attempt to call triggeraction value.


I just came back to working on this project from a long absence. I thought this system worked fine before, but it didn't do anything when I've come back so I added these xpcalls to try and figure out the problem, but this leaves me at a loss for what to try next.
 
Level 2
Joined
Mar 31, 2020
Messages
12
Lua:
function MapSetup()
    DebugSetting = TRUE
    --dCall(MapSetupReal,"MapSetupReal")
    --MapSetupReal()
dCall(TriggerTemplate(), "TriggerTemplate")
end

function dCall(localfunction,functionname)
    if DebugSetting == TRUE then
        local status, err = xpcall(localfunction,errorHandler)
        if status == FALSE then
        print("Error In "..tostring(functionname))
        print(err)
        end
    else
        xpcall(localfunction,silentErrorHandler)
    end
end

function errorHandler(text)
    t = tostring(text)
    return t
end

function silentErrorHandler()
end

function TriggerTemplate()
    local trigger = CreateTrigger()
    local TriggerConditions = function()
    end
    local TriggerActions = function()
    end
    dCall(TriggerRegisterPlayerUnitEventSimple(trigger, Player(0), EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER))
    dCall(TriggerAddCondition(trigger, Condition(TriggerConditions)))
    dCall(TriggerAddAction(trigger, TriggerActions))
end

This gets the sample outputs too, the simplest I could boil everything into.
 

Attachments

  • WC3ScrnShot_060721_135927_001.png
    WC3ScrnShot_060721_135927_001.png
    99.2 KB · Views: 19
Lua:
function MapSetup()
    DebugSetting = TRUE
    --dCall(MapSetupReal,"MapSetupReal")
    --MapSetupReal()
dCall(TriggerTemplate(), "TriggerTemplate")
end

function dCall(localfunction,functionname)
    if DebugSetting == TRUE then
        local status, err = xpcall(localfunction,errorHandler)
        if status == FALSE then
        print("Error In "..tostring(functionname))
        print(err)
        end
    else
        xpcall(localfunction,silentErrorHandler)
    end
end

function errorHandler(text)
    t = tostring(text)
    return t
end

function silentErrorHandler()
end

function TriggerTemplate()
    local trigger = CreateTrigger()
    local TriggerConditions = function()
    end
    local TriggerActions = function()
    end
    dCall(TriggerRegisterPlayerUnitEventSimple(trigger, Player(0), EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER))
    dCall(TriggerAddCondition(trigger, Condition(TriggerConditions)))
    dCall(TriggerAddAction(trigger, TriggerActions))
end
From the looks of it, it appears that the localfunction parameter (for dCall) is set to the result of what is evaluated inside.
Since the result inside is not a function, dCall generates those errors. Also, the name is not actually supplied in the sample.

I've written up a fixed version of the sample lua script below:
Lua:
function MapSetup()
    DebugSetting = TRUE
    --dCall(MapSetupReal,"MapSetupReal")
    --MapSetupReal()

    -- Removed the brackets in TriggerTemplate
    -- since including them would result into the
    -- evaluation of the passed function, which might
    -- return something. In this case, it's null.
    dCall(TriggerTemplate, "TriggerTemplate")
end

-- Added a vararg field [...], which can take
-- any number of parameters (Don't know
-- the exact limits). That way, local functions
-- with varying parameters can invoke the
-- same function for debugging purposes
function dCall(localfunction,functionname,...)
    -- Not sure if TRUE or FALSE are literal
    -- values or constant values, but optimizing
    -- this anyway (assuming they are boolean
    -- values)
    if DebugSetting then
        local status, err = xpcall(localfunction,errorHandler,...)
        if not status then
            print("Error In "..tostring(functionname))
            print(err)
        end
    else
        xpcall(localfunction,silentErrorHandler,...)
    end
end

-- Assigned errorHandler to the same function
-- handle as tostring as a form of optimization. 
-- (I don't know why, but it works in Lua).
errorHandler = tostring

-- Just added a parameter (technically for completeness)
function silentErrorHandler(text)
end

function TriggerTemplate()
    local trigger = CreateTrigger()
    local TriggerConditions = function()
    end
    local TriggerActions = function()
    end
    -- Moved the parameters supplied to the function outside of it.
    dCall(TriggerRegisterPlayerUnitEventSimple, "TriggerRegisterPlayerUnitEventSimple", trigger, Player(0), EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)
    -- dCall(TriggerRegisterPlayerUnitEventSimple(trigger, Player(0), EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER))

    -- Same case here.
    dCall(TriggerAddCondition, "TriggerAddCondition", trigger, Condition(TriggerConditions))
    -- dCall(TriggerAddCondition(trigger, Condition(TriggerConditions)))
    
    -- Same case here.
    dCall(TriggerAddAction, "TriggerAddAction", trigger, TriggerActions)
    -- dCall(TriggerAddAction(trigger, TriggerActions))
    -- No return value, so this function returns null
end

(Technically, functions that do not return anything in Lua return nil upon evaluation, not null)
 
Level 2
Joined
Mar 31, 2020
Messages
12
Ah you are right I should proofread it better, wasn't passing the function names back in the simplified version.

I believe TRUE and FALSE are constants WC3 sets, but I forget where I learned that you could use them like that.

Many thanks, so basically the biggest issue was I didn't understand how xpcall worked so I wasn't passing arguments correctly and it was trying to evaluate the output of the functions I was passing it instead of evaluating the functions.

Now I can start troubleshooting the original code I started with and figure out if its a syntax issue somewhere, or start looking at the logic behind the trigger conditions and the event to see why its not happening properly.
 
Level 2
Joined
Mar 31, 2020
Messages
12
Okay, with Lua telling me more information by xpcall I figured out two things.

1) GetItemTypeId() would cause an error with how I used it in conditions as GetItemName() expects an item.

2) The event happens when picking up an item but GetManipulatedItem() is returning nil so nothing is happening.

This part doesn't make sense and I'm still trying to figure out why GetManipulatedItem() doesn't work in the conditions portion of a trigger after EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER occurs.

I tried changing TriggerRegisterPlayerUnitEventSimple to TriggerRegisterPlayerUnitEvent but the output is the same.
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,570
GetManipulatedItem() is equal to the Acquired/Lost/Sold item. It has no relation to a Point order.

What are you trying to do exactly? If you want to get the target item of an issued order you would need to use a TARGET_ORDER Event and GetOrderTargetItem().
 
Level 2
Joined
Mar 31, 2020
Messages
12
Oh my bad, I meant EVENT_PLAYER_UNIT_PICKUP_ITEM, the event used in the first post not the one from the template.

I'm basically making a system with UI that has a set of custom resources that players collect. That resource drops off of mobs in the form of an item based on Bundle of Lumber, picking up the item should increment the value by 1 and I just need to detect which item it was.

But EVENT_PLAYER_UNIT_PICKUP_ITEM isn't working with GetManipulatedItem which the Jass manual shows should work with this event. The event does trigger, but GetManipulatedItem() as well as the one that gets the unit returns nil.
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,570
Hmm, I see now. The main issue (and maybe only issue) was here:
Lua:
local item = GetItemTypeId(GetManipulatedItem())
print("Picked up "..GetItemName(item))
You're trying to get the item name of an integer (item is set to the item id).

This works:
Lua:
function ResourceDropGetInitalize()
    local i = 0
    local trig = CreateTrigger()
    local ResourceDropGetConditions = function()
        local itm = GetManipulatedItem()
        local id = GetItemTypeId(itm)
        correctitem = false -- i had this disabled while testing
        for i = 1, 6, 1 do
            if id == CraftItemTable[i] then
                return true
            end
        end
    end
    local ResourceDropGetActions = function()
        local itm = GetManipulatedItem()
        local id = GetItemTypeId(itm)
        local itemindex
        for i = 1, 6, 1 do
            if id == CraftItemTable[i] then
                itemindex = i
                break
            end
        end
        UpdateHeroData(itemindex, 1) -- i had this disabled while testing
    end
    i = 0
    while true do
        if i > MaxPlayerIndex then
            break
        end
        if (GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING) then
            TriggerRegisterPlayerUnitEventSimple(trig, Player(i), EVENT_PLAYER_UNIT_PICKUP_ITEM)
        end
        i = i + 1
    end
    TriggerAddCondition(trig, Condition(ResourceDropGetConditions))
    TriggerAddAction(trig, ResourceDropGetActions)
end
Note:
  • I tested this with Claws of Attack (a non-powerup item).
  • I changed some variable names as well, maybe that fixed some things too.
  • UpdateHeroData(itemindex, 1) will fail if itemindex is nil. That's probably intentional but just something I thought I'd mention.
 
Last edited:
Status
Not open for further replies.
Top