GMCP

A category for whatever! Can be Mudlet-related or offtopic.
Delrayne
Posts: 159
Joined: Tue Jun 07, 2011 7:07 pm
Contact:

Re: GMCP

Post by Delrayne »

I sort of just briefly ran through this thread but I made an AUTOBASHER(no user input except which area to go to) If this is what you are trying to accomplish I can try and package it for the forums, I won't post it on IRE's site cause....well your not suppose to autobash....anyway. Let me know if you guys would like to see it or if you were going a completely different direction with this.

Darmir
Posts: 226
Joined: Sun May 01, 2011 6:51 pm
Contact:

Re: GMCP

Post by Darmir »

I am trying to use the function by getting only certain enemies from the list and getting a count of them. For some reason when I create a infunction that calls this one I loose the information from roomEnemies.get().

Caelic
Posts: 65
Joined: Sun Nov 20, 2011 4:52 am

Re: GMCP

Post by Caelic »

Darmir, that'd be something I'd be interested in also.. I'd love an ability to pull room enemies list, and if those room enemies are on my list, it puts them in a list 1 through X, and then in that, I target 1, when it dies, I go down to X

Darmir
Posts: 226
Joined: Sun May 01, 2011 6:51 pm
Contact:

Re: GMCP

Post by Darmir »

I got something partially written that I started from scratch. The issue I am having is the gmcp.Char.Items.Remove doesn't send the same as the gmcp.Char.Items.Add in Achaea. It is missing the name of the item in the table which is sent to the client. I reported it to Achaea which they replied and are sending the issue to the developers.

User avatar
tsuujin
Posts: 695
Joined: Fri Feb 26, 2010 12:59 am
Location: California
Contact:

Re: GMCP

Post by tsuujin »

Here's the basis for my system for handling enemy recognition:
"areaEnemies" keeps a running list of known NPC enemies, based on your current area.
Code: [show] | [select all] lua
--[[ Area Enemies Tracker ]] --

require "dba"
require "messages"

module("areaEnemies",package.seeall)

-- Private Variables
local areaList = {}
local trigList = {}
local currentArea = nil
local enemyRegex = {}

function init()
    dba.execute([[
        CREATE TABLE IF NOT EXISTS npc_enemies (
            name TEXT,
            area TEXT,
            priority INTEGER,
            CONSTRAINT pk PRIMARY KEY(name, area) ON CONFLICT REPLACE
        );
    ]])
    dbLoad()
end

--[[ Database Manipulation Functions ]]--
function dbLoad()
    -- Gain the list of areas first.
    areaList = {}
    local results = dba.query([[SELECT DISTINCT area FROM npc_enemies]])
    for num,tbl in results:pairs() do areaList[tbl.area] = {} end

    -- Requery once for each area, gaining a list of enemies by priority
    for area,_ in pairs(areaList) do
        results = dba.query(string.format([[SELECT * FROM npc_enemies WHERE area = "%s" ORDER BY priority DESC]],area))
        for num,tbl in results:pairs() do table.insert(areaList[area],tbl.name) end
    end
end

function dbSave()
     if not dba.begin() then
        tempTimer(1,[[areaEnemies.dbSave()]])
        msg.print("delayed...")
        return false
    end
    for area,enemies in pairs(areaList) do
        for priority,enemy in pairs(enemies) do
            dba.execute(string.format([[INSERT INTO npc_enemies VALUES ("%s","%s",%d)]],enemy,area,priority))
        end
    end
    dba.commit()
end

--[[ Area Manipulation Functions ]]--
function addEnemy(enemy,priority,area)
    area = area or gmcp.Room.Info.area
    if not areaList[area] then areaList[area] = {} end
    table.insert(areaList[area],priority,enemy)
end

function removeEnemy(enemy,area)
    area = area or gmcp.Room.Info.area
    if not areaList[area] then return end
    for i,v in pairs(areaList[area]) do
        if v:lower() == enemy:lower() then
            table.remove(areaList[area],i)
            return i
        end
    end
    return false
end

function switchPriority(enemy,priority,area)
    area = area or gmcp.Room.Info.area
    if not areaList[area] then return end
    if not removeEnemy(enemy,area) then return false end
    table.insert(areaList[area],priority,enemy)
end

--[[ Basic Information Retrieval Functions]]--
function isEnemy(enemy,area)
    area = area or gmcp.Room.Info.area
    if not areaList[area] then return false end
    for _,tar in pairs(areaList[area]) do
        if not enemyRegex[tar] then enemyRegex[tar] = rex.new(string.format([[(?i:\b%s\b)]],tar)) end
        if enemyRegex[tar]:match(enemy) then return tar end
    end
    return false
end

function getAreas()
    local areas = {}
    for area,_ in pairs(areaList) do table.insert(areas,area) end
    return areas
end

function getAreaEnemies(area)
    area = area or gmcp.Room.Info.area
    return areaList[area] or {}
end

--[[ Display Functions ]]--
function listEnemies(area)
    area = area or gmcp.Room.Info.area
    msg.print(string.format("<yellow>%s <white>targets:",area))
    if not areaList[area] then return end
    for i,v in pairs(areaList[area]) do
        msg.print(string.format("<cyan>%3d  <white>%s",i,v))
    end
end

--[[ Highlight Functions ]]--
function defineTargets(area)
    area = area or gmcp.Room.Info.area
    if area == currentArea then return end

    for _,trig in pairs(trigList) do killTrigger(trig) end


    currentArea = area
    if not areaList[area] then return end
    local sf = [[areaEnemies.highlight("%s")]]
    for _,tar in pairs(areaList[area]) do
        table.insert(trigList,tempTrigger(tar,sf:format(tar)))
    end
end

function highlight(tar)
    local i = 1
    while selectString(tar,i) ~= -1 do
        fg("coral")
        setItalics(true)
        i = i + 1
    end
end

init()
"roomEnemies" tracks enemies currently in the room by referencing GMCP items against the list generated from areaEnemies:
Code: [show] | [select all] lua
-- [[ Room Enemies Tracker ]] --

require "mod_areaEnemies"

module("roomEnemies",package.seeall)

local current = {}
local roomTarget = ""
local oldlist = nil

function add(toadd)
    if not toadd then return end
    if toadd.item.name:find("the corpse of") then return end
    if toadd.location ~= "room" then return end
    current[tonumber(toadd.item.id)] = areaEnemies.isEnemy(toadd.item.name) or nil
end

function remove(tosub)
    if not tosub then return end
    if tosub.location ~= "room" then return end
    local subID = tonumber(tosub.item) or 0
    current[subID] = nil
end

function reset(newlist)
    if not newlist then return end
    if newlist.location ~= "room" then return end
    if newlist == oldlist then return end
    oldlist = newlist
    current = {}
    for i,v in pairs(newlist.items or {}) do
        if not v.name:find("the corpse of") then
            current[tonumber(v.id)] = areaEnemies.isEnemy(v.name) or nil
        end
    end
end

function get() return current end

function print()
    msg.print("<yellow>Enemies currently tracked in room:")
    for i,v in pairs(current) do
        msg.print(string.format("%-15s%s",i,v))
    end
end

User avatar
Vadi
Posts: 5035
Joined: Sat Mar 14, 2009 3:13 pm

Re: GMCP

Post by Vadi »

Nice script! We could use with a 'like' button on the forums...

Darmir
Posts: 226
Joined: Sun May 01, 2011 6:51 pm
Contact:

Re: GMCP

Post by Darmir »

tsuujin wrote:Here's the basis for my system for handling enemy recognition:
"areaEnemies" keeps a running list of known NPC enemies, based on your current area.
Code: [show] | [select all] lua
--[[ Area Enemies Tracker ]] --

require "dba"
require "messages"

module("areaEnemies",package.seeall)

-- Private Variables
local areaList = {}
local trigList = {}
local currentArea = nil
local enemyRegex = {}

function init()
    dba.execute([[
        CREATE TABLE IF NOT EXISTS npc_enemies (
            name TEXT,
            area TEXT,
            priority INTEGER,
            CONSTRAINT pk PRIMARY KEY(name, area) ON CONFLICT REPLACE
        );
    ]])
    dbLoad()
end

--[[ Database Manipulation Functions ]]--
function dbLoad()
    -- Gain the list of areas first.
    areaList = {}
    local results = dba.query([[SELECT DISTINCT area FROM npc_enemies]])
    for num,tbl in results:pairs() do areaList[tbl.area] = {} end

    -- Requery once for each area, gaining a list of enemies by priority
    for area,_ in pairs(areaList) do
        results = dba.query(string.format([[SELECT * FROM npc_enemies WHERE area = "%s" ORDER BY priority DESC]],area))
        for num,tbl in results:pairs() do table.insert(areaList[area],tbl.name) end
    end
end

function dbSave()
     if not dba.begin() then
        tempTimer(1,[[areaEnemies.dbSave()]])
        msg.print("delayed...")
        return false
    end
    for area,enemies in pairs(areaList) do
        for priority,enemy in pairs(enemies) do
            dba.execute(string.format([[INSERT INTO npc_enemies VALUES ("%s","%s",%d)]],enemy,area,priority))
        end
    end
    dba.commit()
end

--[[ Area Manipulation Functions ]]--
function addEnemy(enemy,priority,area)
    area = area or gmcp.Room.Info.area
    if not areaList[area] then areaList[area] = {} end
    table.insert(areaList[area],priority,enemy)
end

function removeEnemy(enemy,area)
    area = area or gmcp.Room.Info.area
    if not areaList[area] then return end
    for i,v in pairs(areaList[area]) do
        if v:lower() == enemy:lower() then
            table.remove(areaList[area],i)
            return i
        end
    end
    return false
end

function switchPriority(enemy,priority,area)
    area = area or gmcp.Room.Info.area
    if not areaList[area] then return end
    if not removeEnemy(enemy,area) then return false end
    table.insert(areaList[area],priority,enemy)
end

--[[ Basic Information Retrieval Functions]]--
function isEnemy(enemy,area)
    area = area or gmcp.Room.Info.area
    if not areaList[area] then return false end
    for _,tar in pairs(areaList[area]) do
        if not enemyRegex[tar] then enemyRegex[tar] = rex.new(string.format([[(?i:\b%s\b)]],tar)) end
        if enemyRegex[tar]:match(enemy) then return tar end
    end
    return false
end

function getAreas()
    local areas = {}
    for area,_ in pairs(areaList) do table.insert(areas,area) end
    return areas
end

function getAreaEnemies(area)
    area = area or gmcp.Room.Info.area
    return areaList[area] or {}
end

--[[ Display Functions ]]--
function listEnemies(area)
    area = area or gmcp.Room.Info.area
    msg.print(string.format("<yellow>%s <white>targets:",area))
    if not areaList[area] then return end
    for i,v in pairs(areaList[area]) do
        msg.print(string.format("<cyan>%3d  <white>%s",i,v))
    end
end

--[[ Highlight Functions ]]--
function defineTargets(area)
    area = area or gmcp.Room.Info.area
    if area == currentArea then return end

    for _,trig in pairs(trigList) do killTrigger(trig) end


    currentArea = area
    if not areaList[area] then return end
    local sf = [[areaEnemies.highlight("%s")]]
    for _,tar in pairs(areaList[area]) do
        table.insert(trigList,tempTrigger(tar,sf:format(tar)))
    end
end

function highlight(tar)
    local i = 1
    while selectString(tar,i) ~= -1 do
        fg("coral")
        setItalics(true)
        i = i + 1
    end
end

init()
"roomEnemies" tracks enemies currently in the room by referencing GMCP items against the list generated from areaEnemies:
Code: [show] | [select all] lua
-- [[ Room Enemies Tracker ]] --

require "mod_areaEnemies"

module("roomEnemies",package.seeall)

local current = {}
local roomTarget = ""
local oldlist = nil

function add(toadd)
    if not toadd then return end
    if toadd.item.name:find("the corpse of") then return end
    if toadd.location ~= "room" then return end
    current[tonumber(toadd.item.id)] = areaEnemies.isEnemy(toadd.item.name) or nil
end

function remove(tosub)
    if not tosub then return end
    if tosub.location ~= "room" then return end
    local subID = tonumber(tosub.item) or 0
    current[subID] = nil
end

function reset(newlist)
    if not newlist then return end
    if newlist.location ~= "room" then return end
    if newlist == oldlist then return end
    oldlist = newlist
    current = {}
    for i,v in pairs(newlist.items or {}) do
        if not v.name:find("the corpse of") then
            current[tonumber(v.id)] = areaEnemies.isEnemy(v.name) or nil
        end
    end
end

function get() return current end

function print()
    msg.print("<yellow>Enemies currently tracked in room:")
    for i,v in pairs(current) do
        msg.print(string.format("%-15s%s",i,v))
    end
end
Is that the whole script for tracking enemies? If not can you post the xml file?

Caelic
Posts: 65
Joined: Sun Nov 20, 2011 4:52 am

Re: GMCP

Post by Caelic »

Yeah, I'm interested in all of this.. I have this uploaded, what is here, and I don't see anything happening. though I could be doing something wrong.. heh

User avatar
tsuujin
Posts: 695
Joined: Fri Feb 26, 2010 12:59 am
Location: California
Contact:

Re: GMCP

Post by tsuujin »

Darmir wrote: Is that the whole script for tracking enemies? If not can you post the xml file?
I did not post the required database or message printing functions, so this will not work by itself (it's essentially one module in my very large system). However, it is entirely complete in the way that it handles the GMCP requests, tracks enemies and responds.

User avatar
tsuujin
Posts: 695
Joined: Fri Feb 26, 2010 12:59 am
Location: California
Contact:

Re: GMCP

Post by tsuujin »

Vadi wrote:Nice script! We could use with a 'like' button on the forums...
Thanks! It's one of my better utility scripts, I think. Really pulled it together with the database integration.

Post Reply