MQCharinfo¶
MQCharinfo
Publishes your character's state over the Actors (post office) system so other clients can see it, and exposes a Lua module to read peer data.
Authors: Cezero
Publishes your character’s state over the Actors (post office) system so other clients can see it, and exposes a Lua module to read peer data. The data shape and API are similar to NetBots-style peer info: vitals, buffs, zone, target, experience, and more.
Loading the Lua module¶
Load the module with:
local charinfo = require("plugin.charinfo")
The plugin DLL is MQCharinfo.dll (canonical name Charinfo). Use plugin.charinfo in Lua; the loader resolves it via case-insensitive lookup. If you see "does not export CreateLuaModule", the plugin may be unloaded.
You can instead use require("mqcharinfo") for the same API with EmmyLua annotations (IDE completion and hover docs). Copy the mqcharinfo folder from the plugin directory into your MacroQuest install's lua/ folder (e.g. MacroQuest/lua/mqcharinfo/) so require("mqcharinfo") is found.
Configuration: For consistent behavior across clients (e.g. postoffice mailbox), list the plugin in your [Plugins] section as MQCharinfo or charinfo, not MQCharInfo. This ensures all clients get the same plugin identity and can see each other's data.
API (read-only peers + watchers)¶
| Function | Description |
|---|---|
charinfo.GetInfo(name) |
Returns the peer table for character name, or nil if not found. |
charinfo.GetPeers() |
Returns a sorted array of peer character names. |
charinfo.GetPeerCnt() |
Returns the number of peers. |
charinfo.GetInjuredPeers() |
Returns a sorted array of peer names with PctHPs < 100. |
charinfo(name) |
Same as GetInfo(name) (module is callable). |
Watchers (heal / buff / cure)¶
Register criteria keyed by signature (spell + scope + filters). Queries union all watchers for (kind, scope, spellId) and return spawn IDs (self never included; same-zone via Zone.ShortName match).
| Function | Description |
|---|---|
RegisterHealWatcher({ spellId, scope, minHp, maxHp, classes?, names? }) |
scope: LIST | INGROUP | GRPAGG | ALL | PET. names required for LIST. HoT spells (SPA 100 / SPA_HEALDOT) also require the peer (or pet for PET) not already have spellId. PET matches peer pets (PetHP / PetID) and GetWatchList returns pet spawn IDs. |
RegisterBuffWatcher({ spellId, scope, classes?, names?, equivIds?, height? }) |
Needs buff (missing or duration < 20s) and stacks. For peer scopes also FreeBuffSlots > 0 and optional height. PET uses pet buffs / StacksPet and returns pet spawn IDs (no owner FreeBuffSlots / height). |
RegisterCureWatcher({ spellId, cureType, scope, classes?, names? }) |
cureType: POISON | DISEASE | CURSE | CORRUPTION. |
DeregisterHealWatcher / DeregisterBuffWatcher / DeregisterCureWatcher |
Same table fields as register. |
GetWatchList(kind, scope, spellId) |
Union of matching spawn IDs for that triple. |
GetWatchCount(kind, scope, spellId) |
Size of that union (use for GRPAGG). |
ClearWatchers() / ClearWatchers(kind) |
Remove all, or only HEAL / BUFF / CURE. |
Stacks / StacksPet / HasBuff / GetBuffDuration (on the table returned by GetInfo(name) and charinfo(name)):
These are methods and must be called with a colon: use peer:Stacks(spell), not peer.Stacks(spell).
peer:Stacks(spell)—trueif the given spell (name or ID) would stack with all of this peer’s long and short buffs. Accepts a string or number (spell ID).peer:StacksPet(spell)— same, but for the peer’s pet buffs.peer:HasBuff(spell)—trueif the peer has this spell ID on Buff or ShortBuff (O(1) index; no Lua Buff table copy).peer:GetBuffDuration(spell)— remaining duration ms for that buff, ornilif absent.peer:HasPetBuff(spell)/peer:GetPetBuffDuration(spell)— same for pet buffs.
Peer data structure¶
Each peer is a table with the following keys. All data is read-only and comes from the last publish received from that character.
Top-level fields¶
| Key | Type | Description |
|---|---|---|
Name |
string | Character name. |
ID |
number | Spawn ID. |
Level |
number | Level. |
Height |
number | Avatar height (same as Spawn.Height). |
PctHPs |
number | HP percent (0–100). |
PctMana |
number | Mana percent (0–100). |
PctAggro |
number | Aggro percent (0–100); same as Me.PctAggro. |
TargetHP |
number | Current target’s HP percent (0–100). |
FreeBuffSlots |
number | Free long buff slots. |
Detrimentals |
number | Count of detrimental buffs. |
CountPoison |
number | Poison counters. |
CountDisease |
number | Disease counters. |
CountCurse |
number | Curse counters. |
CountCorruption |
number | Corruption counters. |
PetHP |
number | Pet HP percent (0–100). |
MaxEndurance |
number | Max endurance. |
CurrentHP |
number | Current HP. |
MaxHP |
number | Max HP. |
CurrentMana |
number | Current mana. |
MaxMana |
number | Max mana. |
CurrentEndurance |
number | Current endurance. |
PctEndurance |
number | Endurance percent (0–100). |
PetID |
number | Pet spawn ID (0 if none). |
PetAffinity |
boolean | Whether the character has the pet AA (e.g. Companion’s Suspension). |
NoCure |
number | No-cure detrimental counter. |
LifeDrain |
number | Life drain counter. |
ManaDrain |
number | Mana drain counter. |
EnduDrain |
number | Endurance drain counter. |
Version |
number | Protocol version (e.g. 1.1). |
CombatState |
number | Combat state (e.g. ACTIVE, COMBAT, RESTING). |
CastingSpellID |
number | Spell ID currently being cast (0 if not casting). |
Arrays (1-based in Lua)¶
| Key | Type | Description |
|---|---|---|
State |
array of strings | Active state flags, e.g. "STAND", "LEVITATING", "SIT", "MOUNT". |
BuffState |
array of strings | Active buff-state flags (e.g. "Slowed", "Hasted", "Cursed"). |
Buff |
array of tables | Long buffs. Each entry: Duration, Spell (table with Name, ID, Category, Level). |
ShortBuff |
array of tables | Short buffs. Same structure as Buff. |
PetBuff |
array of tables | Pet buffs. Same structure as Buff. |
Gems |
array of tables | Spell gems in order. Each entry: ID, Name, Category, Level (full spell info). Use Gems[1].ID, Gems[1].Name, etc. |
FreeInventory |
array of numbers | Free inventory counts by size (indices 1–5 correspond to sizes 0–4). |
Subtables¶
Class
| Key | Type |
|---|---|
Name |
string |
ShortName |
string |
ID |
number |
Target
| Key | Type |
|---|---|
Name |
string |
ID |
number |
Zone
| Key | Type | Description |
|---|---|---|
Name |
string | Zone long name. |
ShortName |
string | Zone short name. |
ID |
number | Zone ID. |
InstanceID |
number | Instance ID. |
X, Y, Z |
number | Position in zone. |
Heading |
number | Heading (degrees). |
Distance |
number or nil | Client-side only. 3D distance from your character to this peer. nil if the peer is not in the same zone/instance as you. |
Experience (present when data is available)
| Key | Type |
|---|---|
PctExp |
number |
PctAAExp |
number |
PctGroupLeaderExp |
number |
TotalAA |
number |
AASpent |
number |
AAUnused |
number |
AAAssigned |
number |
MakeCamp (present when MQ2MoveUtils is loaded and camp data is sent)
| Key | Type |
|---|---|
Status |
number |
X, Y |
number |
Radius |
number |
Distance |
number |
Macro (present when data is available)
| Key | Type |
|---|---|
MacroState |
number (0 = none, 1 = running, 2 = paused) |
MacroName |
string |
Lua (present when data is available)
| Key | Type | Description |
|---|---|---|
Scripts |
array of tables | Running/paused scripts only. |
Lua.Scripts[i] fields:
| Key | Type | Description |
|---|---|---|
PID |
number | Lua script PID. |
Name |
string | Script name. |
Path |
string | Script file path (empty for string scripts). |
Status |
string | Script status (RUNNING or PAUSED). |
Arguments |
array of strings | Script arguments. |
Example¶
local charinfo = require("plugin.charinfo")
local names = charinfo.GetPeers()
for i = 1, #names do
local peer = charinfo.GetInfo(names[i])
if peer then
print(peer.Name, "HP:", peer.PctHPs, "Zone:", peer.Zone.ShortName)
if peer.Zone.Distance then
print(" Distance:", peer.Zone.Distance)
end
if peer.Stacks and peer:Stacks("Clarity II") then
print(" Clarity II would stack")
end
end
end
Settings panel¶
The plugin adds a plugins/Charinfo settings panel that lists all peers and their data in a tree (same structure as above). Use it to inspect what each peer is publishing.