Button with proggramed actions

Share your scripts and packages with other Mudlet users.
Post Reply
newbie
Posts: 18
Joined: Thu Jan 26, 2012 10:56 am

Button with proggramed actions

Post by newbie »

I need some help with this idea.

Create a button that launch the lua code with:
Movement
Actions on each room or not
Wait kill if needed
Movement
Actions
Wait kill if needed
Movement
ect

Until the movement arrives to the same point and a loop begin again.

I need a basic idea and after that work, improve with count mobs and change the wait time, if could be that all the movements could be a variable and the function take each time one of the directions.

Thank you

Jor'Mox
Posts: 1146
Joined: Wed Apr 03, 2013 2:19 am

Re: Button with proggramed actions

Post by Jor'Mox »

So this will need a number of different parts working together to get the results you want. The button part is pretty easy, either using actual buttons or a styled label that is made to act like a button using the setLabelClickCallback function. Either way, your button needs to then call some sort of initialization function, which will create a table of directions, a table of valid targets, and any other relevant variables, like the mentioned actions you may want to take in a room.

Once it has all your variables made in such a way that your other functions can access them, it should kick off the cycle by grabbing the first entry from the directions table, enabling triggers to look for your targets, clear/create a table to record any found targets, moving the appropriate direction, and looking in the room if that isn't something that is done automatically when you move.

Your triggers, if they see a valid target, should record any matches by adding them to the appropriate table, and then when your script sees your prompt, it will look at that table to either move on if there are no targets, or attack the target of your choice, perhaps using particular actions you have setup in advance. Either way, you will want to disable the triggers looking for targets here.

Once you attack a target, you want to enable another trigger that will capture the death of your target, letting your script know that it is time to once again look at the room and look for targets, with the same steps here as when you are moving. Again, if there are targets, fight them, if not, move on.

Once your script reaches for directions to move in but gets nothing, it knows that it has finished, and can close things out.

There will 100% be multiple parts of this that are used in different contexts, so for consistency, I strongly recommend breaking things into smaller functions that perform just the specific block of actions that you need. For instance, have a function that preps to look for enemies (enabling triggers, clearing the target table, etc.), have a function that performs the 'end of look' decision making (disable target triggers, look for found enemies in the table, and either attack or move on as appropriate). If at all possible, you never want the same chunk of code repeated anywhere.

Here is an example of tables of targets and directions from a script I have seen used that does what you are talking about, for a wide list of selectable areas.

Code: Select all

    ["training ground"] = {
        ["dirs"] = {
            "n", "w", "w", "e", "e", "e", "e", "n", "w", "w", "w", "w", "n", "e", "e", "e", 
            "e", "n", "w", "w", "w", "w", "n", "e", "e", "e", "e", "w", "w", "s", "s", "s", 
            "s", "s",
        },
        ["allowed_mobs"] = {
            ["green dummy"] = "A practice dummy wearing green clothing is affixed to a pole here.",
            ["yellow dummy"] = "A practice dummy wearing yellow clothing is affixed to a pole here.",
            ["red dummy"] = "A practice dummy wearing red clothing is affixed to a pole here.",
            ["purple dummy"] = "A practice dummy wearing purple clothing is affixed to a pole here.",
            ["black dummy"] = "A practice dummy wearing black clothing is affixed to a pole here.",
            ["white recruit"] = "A recruit with a white sash is here, training.",
            ["cyan recruit"] = "A recruit with a cyan sash is here, training.",
            ["blue recruit"] = "A recruit with a blue sash is here, training.",
            ["jade recruit"] = "A recruit with a jade sash is here, training.",
            ["brown recruit"] = "A recruit with a long sash is here, training.",
            ["magenta recruit"] = "A recruit with a magenta sash is here, training.",
        }
For the "allowed_mobs", what you see is the words used to target the enemy on the left, and how they appear in the room on the right.

newbie
Posts: 18
Joined: Thu Jan 26, 2012 10:56 am

Re: Button with proggramed actions

Post by newbie »

Thank you for your answer, at the moment I want the basic: dirs, kill mobs (at the moment all the mobs in my alias), wait seconds and continue with the following dir and at the end of the dirs, loop all again.

Can you show me a basic code with 2 o 3 dirs, allowed mob to send the kill command, wait and loop option?

With the basic, after I can check to count the mobs and count the killed ones to know when move, check weapons, check health, etc

One doubs about dirs, how it knows my last dir to know whitch one is the next dir to go?

Thank you

Jor'Mox
Posts: 1146
Joined: Wed Apr 03, 2013 2:19 am

Re: Button with proggramed actions

Post by Jor'Mox »

Using timers, i.e. waiting, is 100% the wrong way to go about this, and will create far too much work to get it going via that method, that will have to all be undone to switch over do making it trigger driven, which is how it will have to be done if it is supposed to be smart at all. While I didn't create any triggers to go along with the script included below, in no small part because I don't know anything about the game you play, I tried to include useful comments to help you figure out what should do what.

As for your specific question about how it will know what step to take next, each time it moves, it removes the first entry from the table of directions, then sends that command, leaving the next move to make as the new first entry in the table. Similarly, it knows it has finished all the directions when there are no entries left to take out of the table of directions.
Code: [show] | [select all] lua
Leveling = Leveling or {}

local dirs, enemies, area, looking = {}, {}, "", false

-- these tables needs to be a list of the names of the relevant triggers, as strings
local moveTriggerNames = {

}
local fightTriggerNames = {

}

-- this table needs to contain the important information for each area the script is supposed to cover
-- NOTE: area names should all be lowercase
Leveling.areas = {
    hallway = {
        dirs = {'n','w','e','e','w','n','w','e','e','w','n','w','e','e','w','n','w','e','e','w','s','s','s','s'},
        enemies = {
            dummy = "A dummy is here.",
            bully = "A bully is here.",
            thug = "A thug is here.",
        },
    },
    box = {
        dirs = {'n','n','n','n','e','s','s','s','e','n','n','n','e','s','s','s','w','w','w','s'},
        enemies = {
            boar = "A boar is here.",
            bear = "A bear is here.",
            moose = "A moose is here.",
        },
    },
    path = {
        dirs = {'n','w','n','n','e','e','e','s','w','s','w','s'},
        enemies = {
            bandit = "A bandit is here.",
            pirate = "A pirate is here.",
            seagull = "A seagull is here.",
        },
    },
}

-- this function should be called by an alias to set the area that the script is working in
Leveling.setArea = function(name)
    name = string.lower(name)
    if Leveling.areas[name] then
        area = name
        echo("Leveling Script: Area set to " .. name .. ".")
    else
        echo("Leveling Script: Area " .. name .. " not found.")
    end
end

-- this function should be called by your button to start the script off
Leveling.startArea = function()
    dirs = table.copy(Leveling.areas[area].dirs)
    enemies = table.copy(Leveling.areas[area].enemies)
    Leveling.takeStep()
end

-- this function moves to the next room
-- in addition to internal use, this function should be called by a 'Move' trigger that matches your prompt
-- this is to handle the case where there are no enemies to fight found
Leveling.takeStep = function()
    dir = table.remove(dirs,1)
    if dir then
        Leveling.enableMoveTriggers()
        send(dir)
    else
        Leveling.endArea()
    end
end

-- this function takes a line of text suspected to have an enemy name in it, checks to see if it is in the approved list
-- if an approved enemy is found, automatically fights them
-- should be called by an appropriate 'Move' trigger that matches anything that could possibly be an enemy
-- the appropriate match should be used as an argument for this function
Leveling.checkEnemy = function(text)
    if not looking then return end
    for k,v in pairs(enemies) do
        if string.match(text,v) then
            looking = false
            Leveling.fightEnemy(k)
        end
    end
end

-- INTERNAL: this function starts a fight with an approved enemy
Leveling.fightEnemy = function(name)
    assert(enemies[name], "Invalid enemy name.")
    Leveling.enableFightTriggers()
    send("kill " .. name)
end

-- this function should be called by an appropriate 'Fight' trigger, to look for more enemies once a fight ends
Leveling.checkRoom = function()
    Leveling.enableMoveTriggers()
    send("look")
end

-- INTERNAL: this function should be used to turn on the triggers that look for enemies when you move into a room
Leveling.enableMoveTriggers = function()
    looking = true
    Leveling.disableFightTriggers()
    for i,v in ipairs(moveTriggerNames) do
        enableTrigger(v)
    end
end

-- INTERNAL: this function should be used to turn off the triggers that look for enemies when you move into a room
Leveling.disableMoveTriggers = function()
    for i,v in ipairs(moveTriggerNames) do
        disableTrigger(v)
    end
end

-- INTERNAL: this function should be used to turn on the trigger(s) that track fight status
Leveling.enableFightTriggers = function()
    Leveling.disableMoveTriggers()
    for i,v in ipairs(fightTriggerNames) do
        enableTrigger(v)
    end
end

-- INTERNAL: this function should be used to turn off the triggers that track fight status
Leveling.disableFightTriggers = function()
    for i,v in ipairs(fightTriggerNames) do
        disableTrigger(v)
    end
end

-- INTERNAL: this function notifies you when a complete pass of an area is finished, and does appropriate cleanup
-- NOTE: this function could also be called as a form of "emergency stop" for the script
Leveling.endArea = function()
    Leveling.disableMoveTriggers()
    Leveling.disableFightTriggers()
    dirs, enemies, looking = {}, {}, false
    echo("Leveling Script: Area completed.")
end
At the most basic level, you need to create three triggers for this to work. First, you need a trigger that captures every full line of text, ^(.*)$ should work fine as a pattern here, and it will call the Leveling.checkEnemy function. Unsurprisingly, this is an extremely basic method to look for things to fight when you are moving around, or after a fight ends, and it should be listed as a 'Move' trigger in the script. Second, you will need a trigger that will capture your prompt, and it will call the Leveling.takeStep function. This is so that if you move into a room, or look after a fight, and there are no enemies, it will go ahead and move to the next room, and this should also be listed as a 'Move' trigger. And third, you need a trigger to capture when the enemy you are fighting dies or runs away or whatever, and it should call the Leveling.checkRoom function, which will look for another enemy to fight, and it should be listed as a 'Fight' trigger in the script.

newbie
Posts: 18
Joined: Thu Jan 26, 2012 10:56 am

Re: Button with proggramed actions

Post by newbie »

Thank you a lot, I need time to check the code to apply and ask anything to apply it fine.

i will reply this week I hope.

Post Reply