• You've discovered RedGuides, an EverQuest multi-boxing and scripting community 🧙‍♀️⚙️. We want you to play several EQ characters at once, come join us and say hello! 👋

  • A TLP without truebox has thawed (Very Vanilla ready)
    Frostreaver

Question - SQLLite and spawn ID's

Joined
Jul 23, 2021
RedCents
360¢
Hitting this hard teaching myself Lua as well as the MQ TLO logic - want to contribute so the community in some fashion. I use SQL daily and often program in C#/python at work so the learning curve isn't so bad.

Couple questions:
  1. I compiled SQLLite no issues but if I distribute the dll with the script, will it run on other PCs or will they have to compile?
    • SQLLite is overkill for this little script but this is a learning adventure.
  2. Spawn ID's - Do they ever change? If I try to target an NPC with multiple of the same name but I only want spawn ID NPC 1234, does the spawn ID for this NPC ever change?
    • I'm hoping they don't but if they do, how does one target the NPC on the south side for example when there is an NPC with the same name on the north side?
As always, thanks for any the help!
 
spawn ids are generated when a spawn is generated. so bill_the_mob might have 123 right now, but next time he spawns he might be 548
 
spawn ids are generated when a spawn is generated. so bill_the_mob might have 123 right now, but next time he spawns he might be 548

thanks - what about static NPCs - stuff in like PoK or the guild lobby. They spawn once I assume but if the server restarts, will it change (I think yes at this point)?
 
thanks - what about static NPCs - stuff in like PoK or the guild lobby. They spawn once I assume but if the server restarts, will it change (I think yes at this point)?
i've never checked, but i would imagine that to be the case
 
It will change any time the NPC pops/depops regardless of server up/down. Best not to store spawn IDs for anything more permanent than the current check.

We have a Lua rocks server that has sqlite on it, but we don't have a good method of distributing rocks yet.
 
Last edited:
Thanks for the replies.

This code looks very messy, but seems to work. Looping through all NPC's and loading those that qualify into a table to be dealt with later. Since I'm grabbing the ID and the distance, I can make a decision which one I want to nav to. Not sure how else to tackle traveling to a specific NPC when many share the same name otherwise.

The Lua pattern matching takes something like A_Priest_of_Discord01 to apriestofdiscord and that allows me to ignore all other NPCs.

INI:
    local npctbl = {}
    local npc_find_name  = 'apriestofluclin'
    local npc_find_surname = 'corpsesummoner'

    local i = 1
    while mq.TLO.NearestSpawn(i..', npc')() do
        local this_vendor_npc = string.gsub(tostring(mq.TLO.NearestSpawn(i..', npc')):lower(), "[_0-9]", "")
        local this_vendor_surname = string.gsub(tostring(mq.TLO.NearestSpawn(i..', npc').Surname):lower(), "[_0-9 ]", "")
        local this_npc_distance = mq.TLO.NearestSpawn(i..', npc').Distance3D()
        local this_npc_id = mq.TLO.NearestSpawn(i..', npc').ID()
      
        if this_vendor_npc == npc_find_name and this_vendor_surname == npc_find_surname then
            npctbl[this_npc_id] = this_npc_distance
        end
        --debug
        print('NPC: ',  this_vendor_surname, ' Distance: ', this_npc_distance , ' ID', this_npc_id )
        i=i+1
      
    end
 
Progress.

I wiped a few days ago and was done for the night - tired and frustration set in! I was really annoyed I had to flip to each session to buy the proper reagent for each of my toons and then give it to the corpse summoner in the GL for the rez. Perhaps there is an easier way or some sort of solution already exists but I couldn't find if there is one, I am still going to press on with this even if there is already a solution as I am thoroughly enjoying myself with the learning process of Lua and MQ. I think I have a decent grasp of Lua now after a lot of reading and trial and error over the last day or so.

This simple script is going to use SQLLite and like I said above, I know its overkill but that's ok for this little project.

Below is only the start of the SQL portion of the script.

Thought I'd share, maybe someone will find it useful. Of course, open to any feedback!


INI:
local mq = require('mq')
local sqlite3 = require('lsqlite3complete')
local db
local sqlquery


local debug_toggle = true

local _SQL = {}


_SQL.InScopeTbls = { 'AppData', 'Logs', 'NPCs', 'Items' }


_SQL.tblCreate = {
    AppData = {
        sql = 'CREATE TABLE AppData ( npc_id NUMERIC , npc_distance NUMERIC );',
        tblCreated = false,
        contents = {
                 a = '11',   --place holders
                 b = '21',    --place holders
                 c = '31'    --place holders
        }
    },
    Logs = {   
        sql = 'CREATE TABLE Logs ( npc_id NUMERIC , npc_distance NUMERIC );',
        tblCreated = false,
            contents = {
                 a = '12',     --place holders
                 b = '22',    --place holders
                 c = '32'    --place holders
        }
        
    },
    NPCs ={
        sql = 'CREATE TABLE NPCs ( npc_id NUMERIC , npc_distance NUMERIC );',
        tblCreated = false,
        contents = {
                 a = '13',     --place holders
                 b = '23',     --place holders
                 c = '33'    --place holders
        }
    },
    Items ={
        sql = 'CREATE TABLE Items (  id INTEGER PRIMARY KEY AUTOINCREMENT, min_lvl NUMERIC , max_level NUMERIC, item_name TEXT, item_id max_level, item_price NUMERIC );',
        tblCreated = false,
        contents = {
                 item1 = 'INSERT INTO Items (min_lvl, max_level, item_name, item_id, item_price) VALUES (1, 20, \'Minor Soulstone\', 76013, 11)',
                 item2 = 'INSERT INTO Items (min_lvl, max_level, item_name, item_id, item_price) VALUES (21, 30, \'Lesser Soulstone\', 76014, 25)',
                 item3 = 'INSERT INTO Items (min_lvl, max_level, item_name, item_id, item_price) VALUES (31, 40, \'Soulstone\', 76015, 53)',
                 item4 = 'INSERT INTO Items (min_lvl, max_level, item_name, item_id, item_price) VALUES (41, 50, \'Greater Soulstone\', 76016, 84)',
                 item5 = 'INSERT INTO Items (min_lvl, max_level, item_name, item_id, item_price) VALUES (51, 60, \'Faceted Soulstone\', 76017, 116)',
                 item6 = 'INSERT INTO Items (min_lvl, max_level, item_name, item_id, item_price) VALUES (61, 70, \'Pristine Soulstone\', 76018, 158)',
                 item7 = 'INSERT INTO Items (min_lvl, max_level, item_name, item_id, item_price) VALUES (71, 75, \'Glowing Soulstone\', 76019, 263)',
                 item8 = 'INSERT INTO Items (min_lvl, max_level, item_name, item_id, item_price) VALUES (76, 80, \'Prismatic Soulstone\', 76048, 420)',
                 item9 = 'INSERT INTO Items (min_lvl, max_level, item_name, item_id, item_price) VALUES (81, 85, \'Iridescent Soulstone\', 76065, 525)',
                 item10 = 'INSERT INTO Items (min_lvl, max_level, item_name, item_id, item_price) VALUES (86, 90, \'Phantasmal Soulstone\', 76274, 630)',
                 item11 = 'INSERT INTO Items (min_lvl, max_level, item_name, item_id, item_price) VALUES (91, 95, \'Luminous Soulstone\', 76275, 735)',
                 item12 = 'INSERT INTO Items (min_lvl, max_level, item_name, item_id, item_price) VALUES (96, 100, \'Coalescent Soulstone\', 94076, 840)',
                 item13 = 'INSERT INTO Items (min_lvl, max_level, item_name, item_id, item_price) VALUES (101, 105, \'Torrential Soulstone\', 94091, 1050)',
                 item14 = 'INSERT INTO Items (min_lvl, max_level, item_name, item_id, item_price) VALUES (106, 110, \'Draconic Soulstone\', 94092, 2100)',
                 item15 = 'INSERT INTO Items (min_lvl, max_level, item_name, item_id, item_price) VALUES (111,115, \'Velium Soulstone\', 94093, 3150)'
        }
    }
}

-- #### helpers ####


-- source for this snazzy little function an be found on various Lua scripts on the Redguides website.
--TODO: make this more "mine". Right now it works but need to do something else with this.
local Output = function(msg) print('\aw\at['..mq.TLO.Time()..'] [EZ Wipe Rez\aw] \a-t' .. msg) end


--this simple function accepts a lua table and value and loops through in an efforts to find match and returns trueif one is found.
local function FindTblVal (tab, val)
    for index, value in ipairs(tab) do
        if value == val then
            return true
        end
    end

    return false
end


-- #### end helpers ####



--setup our SQLLite DB - this will create a new DB if one does not exist or open if it does

local function SetupShop()
    local mq_install_path = mq.TLO.MacroQuest.Path():gsub('\\', '/')
    local config_path = '/config/'
    local db_name = 'WipeEZRezInfo.db'
    db  = sqlite3.open(mq_install_path .. config_path .. db_name, sqlite3.OPEN_READWRITE + sqlite3.OPEN_CREATE)
    
end



--[[

Since this is a simple script, the DB will need to be built upon first run. 
This checks the DB for the required in scope tables, and creates if they don't exist. Within the lua table above, the specific row inserts are listed as well.
Since my row inserts are small, this solution will work for this simple script. However, should I need to deploy a bigger dataset, a DB will either 
need to be distributed or I will need some other solution.

--]]

local function ConfirmDBIntegeregity()

    if db:isopen() then  --is our DB open? sure hope so!
    
        sqlquery = "SELECT tbl_name FROM sqlite_master WHERE type='table'"  -- query all tables within the DB
        
        for x in db:urows(sqlquery) do
             if FindTblVal(_SQL.InScopeTbls, x) then  -- sometimes SQLLite creates system tables within the DB (sqllite_sequence for example). I need to ignore any table wihtin the DB that is not in scope.
                _SQL.tblCreate[x]['tblCreated'] = true  -- update the created flag to true if found.
            end
        end
        
        for i,tbl in pairs(_SQL.tblCreate) do
        
            if tbl['tblCreated'] == false then
                print('executing this sql coding',tbl['sql'] ) -- debug/change this. This is ugly!
                
                db:exec(tbl['sql']) -- execute the table create TSQL
                
                for x,tblz in pairs(_SQL.tblCreate[i].contents) do
                    --print(tblz) -- debug
                    db:exec(tblz)  --loop through the contents of the table to insert the required records.

                end               
            end
        
        end

        --TODO: implement a full debug system
        if debug_toggle then

        
        end
        
    else   
    -- TODO: need some sort of graceful exit, i think...TBD
        GracefulExit('Somethin ain\'t right yo!')
    end
end


SetupShop()
ConfirmDBIntegeregity()
 
Well, there's already a macro available to do this. Check out lazylobbyrez.mac. It'll go by the stone from the nearest lobby merchant that sells the soul stones and then run to one of the summoners to do the hand-in (along with reviving your merc if possible). RGMercs incorporates the functionality from this macro as a bind. Not sure if other macro-based combat systems do the same.

Might get your further along with your Lua functionality if you refer to the macro.
 
Well, there's already a macro available to do this. Check out lazylobbyrez.mac. It'll go by the stone from the nearest lobby merchant that sells the soul stones and then run to one of the summoners to do the hand-in (along with reviving your merc if possible). RGMercs incorporates the functionality from this macro as a bind. Not sure if other macro-based combat systems do the same.

Might get your further along with your Lua functionality if you refer to the macro.

Thanks - I was not aware but the amount of macros available here is vast am I'm not surprised there already is one. Still going to press on with this as this is mostly a learning exercise and maybe the framework will provide some examples for those who want to create additional scripts.
 
Question - SQLLite and spawn ID's

Users who are viewing this thread

Back
Top
Cart