mirror of
https://github.com/brues-code/ClassicAPI.git
synced 2026-11-11 12:27:35 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cdb515e0c3 | ||
|
|
d55613e88c | ||
|
|
3c0bf3abed | ||
|
|
3179d1741e | ||
|
|
63c003db26 | ||
|
|
d01e51d862 | ||
|
|
92d868424c | ||
|
|
eb4c42b1e0 | ||
|
|
2968f51661 | ||
|
|
dbd3f7f6a5 | ||
|
|
2f5cec35ea | ||
|
|
706b8597b6 | ||
|
|
644aa21459 | ||
|
|
a77d8f3fac | ||
|
|
766d128a5d | ||
|
|
6f543ec762 | ||
|
|
d9102bae3b | ||
|
|
ca6189cc1e | ||
|
|
7e86aa9dc5 | ||
|
|
2ca5624aa0 | ||
|
|
19397782f7 | ||
|
|
284b951038 | ||
|
|
1df48772f4 | ||
|
|
939b52ae69 | ||
|
|
2403ff7233 |
@@ -27,6 +27,7 @@ Util\EventUtil.lua
|
||||
Util\ItemUtil.lua
|
||||
Util\AddOnCompat.lua
|
||||
Util\FunctionUtil.lua
|
||||
Util\CacheUtil.lua
|
||||
Util\Pools.lua
|
||||
Util\FrameWatcher.lua
|
||||
Util\TimedCallback.lua
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
-- On-demand, throttled cache warmer (/warmcache). A brute-force scan of the
|
||||
-- whole ID space floods the client's network buffers and panics in
|
||||
-- WDataStoreSmallBuffer ("not enough memory") — the engine can't hold that
|
||||
-- many pending queries. So this warms a *bounded* range, started/stopped
|
||||
-- manually, at a low fixed rate. Tune WARM_RATE / WARM_INTERVAL if needed,
|
||||
-- but keep it modest. Note: IDs the server doesn't know (gaps in the range)
|
||||
-- get no response, so their pending entries linger — warm ranges you expect
|
||||
-- to be mostly real, not arbitrary millions.
|
||||
--
|
||||
-- /warmcache item 1 40000 warm item IDs 1..40000
|
||||
-- /warmcache <type> <a> <b> type = item | quest | creature | object | all
|
||||
-- /warmcache stop abort an in-progress warm
|
||||
local WARM_RATE = 20 -- IDs queued per tick
|
||||
local WARM_INTERVAL = 0.2 -- seconds between ticks (-> ~20 IDs/sec)
|
||||
|
||||
local WARM_FN = {
|
||||
item = function(id) C_Item.RequestLoadItemDataByID(id) end,
|
||||
quest = function(id) C_QuestLog.RequestLoadQuestByID(id) end,
|
||||
creature = function(id) C_CreatureInfo.RequestLoadCreatureByID(id) end,
|
||||
object = function(id) C_GameObjectInfo.RequestLoadGameObjectByID(id) end,
|
||||
all = function(id)
|
||||
C_QuestLog.RequestLoadQuestByID(id)
|
||||
C_Item.RequestLoadItemDataByID(id)
|
||||
C_CreatureInfo.RequestLoadCreatureByID(id)
|
||||
C_GameObjectInfo.RequestLoadGameObjectByID(id)
|
||||
end,
|
||||
}
|
||||
|
||||
local warm = { running = false, cancel = false }
|
||||
|
||||
local function warm_msg(s)
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff66ccff[WarmCache]|r " .. s)
|
||||
end
|
||||
|
||||
local function warm_step(fn, id, stop, lastMsg)
|
||||
if warm.cancel then
|
||||
warm.running = false
|
||||
warm_msg("stopped at " .. (id - 1))
|
||||
return
|
||||
end
|
||||
local n = 0
|
||||
while n < WARM_RATE and id <= stop do
|
||||
fn(id)
|
||||
n = n + 1
|
||||
id = id + 1
|
||||
end
|
||||
if id > stop then
|
||||
warm.running = false
|
||||
warm_msg("done (through " .. stop .. ")")
|
||||
else
|
||||
if (id - 1) - lastMsg >= 1000 then
|
||||
warm_msg((id - 1) .. " / " .. stop .. " ...")
|
||||
lastMsg = id - 1
|
||||
end
|
||||
C_Timer.After(WARM_INTERVAL, function() warm_step(fn, id, stop, lastMsg) end)
|
||||
end
|
||||
end
|
||||
|
||||
SLASH_WARMCACHE1 = "/warmcache"
|
||||
SlashCmdList["WARMCACHE"] = function(msg)
|
||||
local args = {}
|
||||
for tok in string.gmatch(msg or "", "%S+") do
|
||||
table.insert(args, string.lower(tok))
|
||||
end
|
||||
local cmd = args[1]
|
||||
|
||||
if cmd == "stop" then
|
||||
if warm.running then warm.cancel = true else warm_msg("not running") end
|
||||
return
|
||||
end
|
||||
if warm.running then
|
||||
warm_msg("already running - /warmcache stop first")
|
||||
return
|
||||
end
|
||||
|
||||
local fn = WARM_FN[cmd]
|
||||
local a, b = tonumber(args[2]), tonumber(args[3])
|
||||
if not fn or not a or not b or a < 1 or b < a then
|
||||
warm_msg("usage: /warmcache item|quest|creature|object|all <startID> <stopID>")
|
||||
warm_msg(" /warmcache stop")
|
||||
return
|
||||
end
|
||||
|
||||
warm.running, warm.cancel = true, false
|
||||
warm_msg(string.format("warming %s %d..%d (~%d/sec, /warmcache stop to abort)",
|
||||
cmd, a, b, math.floor(WARM_RATE / WARM_INTERVAL)))
|
||||
warm_step(fn, a, b, a - 1)
|
||||
end
|
||||
@@ -27,13 +27,12 @@ INVSLOT_BACK = 15;
|
||||
INVSLOT_MAINHAND = 16;
|
||||
INVSLOT_OFFHAND = 17;
|
||||
INVSLOT_RANGED = 18;
|
||||
INVSLOT_TABARD = 19;
|
||||
INVSLOT_LAST_EQUIPPED = INVSLOT_TABARD;
|
||||
INVSLOT_TABARD = 19; INVSLOT_LAST_EQUIPPED = INVSLOT_TABARD;
|
||||
|
||||
INVSLOTS_EQUIPABLE_IN_COMBAT = {
|
||||
[INVSLOT_MAINHAND] = true,
|
||||
[INVSLOT_OFFHAND] = true,
|
||||
[INVSLOT_RANGED] = true,
|
||||
[INVSLOT_MAINHAND] = true,
|
||||
[INVSLOT_OFFHAND] = true,
|
||||
[INVSLOT_RANGED] = true,
|
||||
}
|
||||
|
||||
-- Item IDs
|
||||
|
||||
@@ -1,3 +1,92 @@
|
||||
function GameTooltip_Hide()
|
||||
GameTooltip:Hide()
|
||||
end
|
||||
|
||||
GameTooltip.shoppingTooltips = GameTooltip.shoppingTooltips or { ShoppingTooltip1, ShoppingTooltip2 }
|
||||
|
||||
function GameTooltip_ShowCompareItem(self, shift)
|
||||
if ( not self ) then
|
||||
self = GameTooltip;
|
||||
end
|
||||
local item, link = self:GetItem();
|
||||
link = link or self.compareLink
|
||||
if ( not link ) then
|
||||
return;
|
||||
end
|
||||
|
||||
local shoppingTooltip1, shoppingTooltip2 = unpack(self.shoppingTooltips or { ShoppingTooltip1, ShoppingTooltip2 });
|
||||
|
||||
local SEPARATION = 6;
|
||||
local backdrop = shoppingTooltip1.GetBackdrop and shoppingTooltip1:GetBackdrop();
|
||||
local GAP = SEPARATION + ((type(backdrop) == "table" and backdrop.edgeSize) or 0);
|
||||
|
||||
local item1 = nil;
|
||||
local item2 = nil;
|
||||
local side = "left";
|
||||
if ( shoppingTooltip1:SetHyperlinkCompareItem(link, 1, shift, self) ) then
|
||||
item1 = true;
|
||||
end
|
||||
if ( shoppingTooltip2:SetHyperlinkCompareItem(link, 2, shift, self) ) then
|
||||
item2 = true;
|
||||
end
|
||||
|
||||
-- find correct side
|
||||
local rightDist = 0;
|
||||
local leftPos = self:GetLeft();
|
||||
local rightPos = self:GetRight();
|
||||
if ( not rightPos ) then
|
||||
rightPos = 0;
|
||||
end
|
||||
if ( not leftPos ) then
|
||||
leftPos = 0;
|
||||
end
|
||||
|
||||
rightDist = GetScreenWidth() - rightPos;
|
||||
|
||||
if (leftPos and (rightDist < leftPos)) then
|
||||
side = "left";
|
||||
else
|
||||
side = "right";
|
||||
end
|
||||
|
||||
-- see if we should slide the tooltip
|
||||
if ( self:GetAnchorType() and self:GetAnchorType() ~= "ANCHOR_PRESERVE" ) then
|
||||
local totalWidth = 0;
|
||||
if ( item1 ) then
|
||||
totalWidth = totalWidth + shoppingTooltip1:GetWidth();
|
||||
end
|
||||
if ( item2 ) then
|
||||
totalWidth = totalWidth + shoppingTooltip2:GetWidth();
|
||||
end
|
||||
|
||||
if ( (side == "left") and (totalWidth > leftPos) ) then
|
||||
self:SetAnchorType(self:GetAnchorType(), (totalWidth - leftPos), 0);
|
||||
elseif ( (side == "right") and (rightPos + totalWidth) > GetScreenWidth() ) then
|
||||
self:SetAnchorType(self:GetAnchorType(), -((rightPos + totalWidth) - GetScreenWidth()), 0);
|
||||
end
|
||||
end
|
||||
|
||||
if ( item1 ) then
|
||||
shoppingTooltip1:SetOwner(self, "ANCHOR_NONE");
|
||||
shoppingTooltip1:ClearAllPoints();
|
||||
if ( side and side == "left" ) then
|
||||
shoppingTooltip1:SetPoint("TOPRIGHT", self, "TOPLEFT", -GAP, -10);
|
||||
else
|
||||
shoppingTooltip1:SetPoint("TOPLEFT", self, "TOPRIGHT", GAP, -10);
|
||||
end
|
||||
shoppingTooltip1:SetHyperlinkCompareItem(link, 1, shift, self);
|
||||
shoppingTooltip1:Show();
|
||||
|
||||
if ( item2 ) then
|
||||
shoppingTooltip2:SetOwner(shoppingTooltip1, "ANCHOR_NONE");
|
||||
shoppingTooltip2:ClearAllPoints();
|
||||
if ( side and side == "left" ) then
|
||||
shoppingTooltip2:SetPoint("TOPRIGHT", shoppingTooltip1, "TOPLEFT", -GAP, 0);
|
||||
else
|
||||
shoppingTooltip2:SetPoint("TOPLEFT", shoppingTooltip1, "TOPRIGHT", GAP, 0);
|
||||
end
|
||||
shoppingTooltip2:SetHyperlinkCompareItem(link, 2, shift, self);
|
||||
shoppingTooltip2:Show();
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
local className = UnitClass('player')
|
||||
local classFile, classID = UnitClassBase('player')
|
||||
local className, classFile, classID = UnitClass('player'), UnitClassBase('player')
|
||||
|
||||
PlayerUtil = PlayerUtil or {}
|
||||
|
||||
@@ -32,12 +31,8 @@ function PlayerUtil.GetCurrentSpeed()
|
||||
return GetUnitSpeed("player") / 7 * 100
|
||||
end
|
||||
|
||||
local playerGuid
|
||||
function GetPlayerGuid()
|
||||
if not playerGuid then
|
||||
playerGuid = UnitGUID("player")
|
||||
end
|
||||
return playerGuid
|
||||
return UnitGUID("player")
|
||||
end
|
||||
|
||||
function IsPlayerGuid(guid)
|
||||
|
||||
@@ -6,6 +6,7 @@ FOCUSTARGET = "Focus Target";
|
||||
GENERIC_FRACTION_STRING = "%d/%d";
|
||||
GOLD_AMOUNT_SYMBOL = "g";
|
||||
HOURS_MINUTES_SECONDS = "%.2d:%.2d:%.2d";
|
||||
ITEM_DELTA_DESCRIPTION = "If you replace this item, the following stat changes will occur:";
|
||||
ITEMS_EQUIPPED = "%d |4item:items; equipped";
|
||||
ITEMS_IN_INVENTORY = "%d |4item:items; in inventory";
|
||||
ITEMS_NOT_IN_INVENTORY = "%d |4item:items; missing";
|
||||
|
||||
@@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
@@ -36,11 +36,11 @@ Full per-function reference: **[docs/API.md](docs/API.md)**.
|
||||
| [FriendList](docs/API.md#friendlist) | `C_FriendList.IsWhoQueryPending`, `C_FriendList.SendWhoQueryByName` |
|
||||
| [GameObject](docs/API.md#gameobject) | `C_GameObjectInfo.GetGameObjectInfoByID`, `C_GameObjectInfo.RequestLoadGameObjectByID` |
|
||||
| [Gossip](docs/API.md#gossip) | `C_GossipInfo.CloseGossip`, `C_GossipInfo.GetActiveQuests`, `C_GossipInfo.GetAvailableQuests`, `C_GossipInfo.GetNumActiveQuests`, `C_GossipInfo.GetNumAvailableQuests`, `C_GossipInfo.GetNumOptions`, `C_GossipInfo.GetOptions`, `C_GossipInfo.GetText`, `C_GossipInfo.SelectActiveQuest`, `C_GossipInfo.SelectAvailableQuest`, `C_GossipInfo.SelectOption`, `C_GossipInfo.SelectOptionByIndex` |
|
||||
| [GameTooltip](docs/API.md#gametooltip) | `GameTooltip:GetGameObject`, `GameTooltip:GetItem`, `GameTooltip:GetOwner`, `GameTooltip:GetSpell`, `GameTooltip:GetUnitGUID`, `GameTooltip:HasGameObject`, `GameTooltip:HasItem`, `GameTooltip:HasSpell`, `GameTooltip:HasUnit`, `GameTooltip:SetEquipmentSet`, `GameTooltip:SetInventoryItemByID`, `GameTooltip:SetItemByGUID`, `GameTooltip:SetItemByID`, `GameTooltip:SetSpellByID`, `GameTooltip:SetTalentByID`, `GameTooltip:SetUnitAura` |
|
||||
| [GameTooltip](docs/API.md#gametooltip) | `GameTooltip:GetGameObject`, `GameTooltip:GetItem`, `GameTooltip:GetOwner`, `GameTooltip:GetSpell`, `GameTooltip:GetUnitGUID`, `GameTooltip:HasGameObject`, `GameTooltip:HasItem`, `GameTooltip:HasSpell`, `GameTooltip:HasUnit`, `GameTooltip:IsEquippedItem`, `GameTooltip:SetEquipmentSet`, `GameTooltip:SetHyperlinkCompareItem`, `GameTooltip:SetInventoryItemByID`, `GameTooltip:SetItemByGUID`, `GameTooltip:SetItemByID`, `GameTooltip:SetSpellByID`, `GameTooltip:SetTalentByID`, `GameTooltip:SetUnitAura`, `OnTooltipSetItem` (script) |
|
||||
| [Hooks](docs/API.md#hooks) | `hooksecurefunc` |
|
||||
| [Input](docs/API.md#input) | `IsLeftAltKeyDown`, `IsLeftControlKeyDown`, `IsLeftShiftKeyDown`, `IsModifierKeyDown`, `IsMouseButtonDown`, `IsRightAltKeyDown`, `IsRightControlKeyDown`, `IsRightShiftKeyDown` |
|
||||
| [Instance](docs/API.md#instance) | `GetInstanceInfo` |
|
||||
| [Item](docs/API.md#item) | `C_Item.DoesItemExist`, `C_Item.DoesItemExistByID`, `C_Item.EquipItemByName`, `C_Item.GetCurrentItemLevel`, `C_Item.GetDetailedItemLevelInfo`, `C_Item.GetEnchantInfo`, `C_Item.GetItemCount`, `C_Item.GetItemFamily`, `C_Item.GetItemGUID`, `C_Item.GetItemIcon`, `C_Item.GetItemIconByID`, `C_Item.GetItemID`, `C_Item.GetItemInfoInstant`, `C_Item.GetItemInventoryType`, `C_Item.GetItemInventoryTypeByID`, `C_Item.GetItemLink`, `C_Item.GetItemLocation`, `C_Item.GetItemMaxStackSize`, `C_Item.GetItemMaxStackSizeByID`, `C_Item.GetItemName`, `C_Item.GetItemNameByID`, `C_Item.GetItemQuality`, `C_Item.GetItemQualityByID`, `C_Item.GetItemSellPrice`, `C_Item.GetItemSellPriceByID`, `C_Item.GetItemSetID`, `C_Item.GetItemSetIDByID`, `C_Item.GetItemSetInfo`, `C_Item.GetItemSpell`, `C_Item.GetItemUniqueness`, `C_Item.GetItemUniquenessByID`, `C_Item.GetStackCount`, `C_Item.GetWeaponEnchantInfo`, `C_Item.IsBound`, `C_Item.IsEquippableItem`, `C_Item.IsEquippedItem`, `C_Item.IsItemDataCached`, `C_Item.IsItemDataCachedByID`, `C_Item.IsItemOpenable`, `C_Item.IsLocked`, `C_Item.LockItem`, `C_Item.LockItemByGUID`, `C_Item.UnlockAllItems`, `C_Item.UnlockItem`, `C_Item.RequestLoadItemData`, `C_Item.RequestLoadItemDataByID`, `C_Item.UseAtCursor`, `C_Item.UseAtUnit`, `C_Item.UseItemByName`, `GetAuctionItemID`, `GetAuctionSellItemID`, `GetAverageItemLevel`, `GetCraftReagentItemID`, `GetInboxItemID`, `GetInventoryItemDurability`, `GetInventoryItemID`, `GetInventoryItemsForSlot`, `GetInventoryItemRepairCost`, `GetItemIcon`, `GetLootRollItemID`, `GetLootSlotItemID`, `GetMerchantItemID`, `GetQuestItemID`, `GetQuestLogItemID`, `GetTradePlayerItemID`, `GetTradeSkillItemID`, `GetTradeSkillReagentItemID`, `GetTradeTargetItemID`, `OffhandHasWeapon` |
|
||||
| [Item](docs/API.md#item) | `C_Item.DoesItemExist`, `C_Item.DoesItemExistByID`, `C_Item.EquipItemByName`, `C_Item.GetCurrentItemLevel`, `C_Item.GetDetailedItemLevelInfo`, `C_Item.GetEnchantInfo`, `C_Item.GetItemCount`, `C_Item.GetItemFamily`, `C_Item.GetItemGUID`, `C_Item.GetItemIcon`, `C_Item.GetItemIconByID`, `C_Item.GetItemID`, `C_Item.GetItemInfoInstant`, `C_Item.GetItemInventorySlotInfo`, `C_Item.GetItemInventorySlotKey`, `C_Item.GetItemInventoryType`, `C_Item.GetItemInventoryTypeByID`, `C_Item.GetItemLink`, `C_Item.GetItemLocation`, `C_Item.GetItemMaxStackSize`, `C_Item.GetItemMaxStackSizeByID`, `C_Item.GetItemName`, `C_Item.GetItemNameByID`, `C_Item.GetItemQuality`, `C_Item.GetItemQualityByID`, `C_Item.GetItemSellPrice`, `C_Item.GetItemSellPriceByID`, `C_Item.GetItemSetID`, `C_Item.GetItemSetIDByID`, `C_Item.GetItemSetInfo`, `C_Item.GetItemSpell`, `C_Item.GetItemStatDelta`, `C_Item.GetItemStats`, `C_Item.GetItemSubClassInfo`, `C_Item.GetItemUniqueness`, `C_Item.GetItemUniquenessByID`, `C_Item.GetStackCount`, `C_Item.GetWeaponEnchantInfo`, `C_Item.IsBound`, `C_Item.IsEquippableItem`, `C_Item.IsEquippedItem`, `C_Item.IsItemDataCached`, `C_Item.IsItemDataCachedByID`, `C_Item.IsItemGUIDInInventory`, `C_Item.IsItemOpenable`, `C_Item.IsLocked`, `C_Item.LockItem`, `C_Item.LockItemByGUID`, `C_Item.UnlockAllItems`, `C_Item.UnlockItem`, `C_Item.RequestLoadItemData`, `C_Item.RequestLoadItemDataByID`, `C_Item.UseAtCursor`, `C_Item.UseAtUnit`, `C_Item.UseItemByName`, `GetAuctionItemID`, `GetAuctionSellItemID`, `GetAverageItemLevel`, `GetCraftReagentItemID`, `GetInboxItemID`, `GetInventoryItemDurability`, `GetInventoryItemID`, `GetInventoryItemsForSlot`, `GetInventoryItemRepairCost`, `GetItemIcon`, `GetLootRollItemID`, `GetLootSlotItemID`, `GetMerchantItemID`, `GetQuestItemID`, `GetQuestLogItemID`, `GetTradePlayerItemID`, `GetTradeSkillItemID`, `GetTradeSkillReagentItemID`, `GetTradeTargetItemID`, `OffhandHasWeapon` |
|
||||
| [Loot](docs/API.md#loot) | `C_Loot.GetNearbyLootableUnits`, `C_Loot.GetLastScanResults`, `C_Loot.IsScanInProgress`, `C_Loot.LootUnit`, `C_Loot.LootUnitItem`, `C_Loot.ScanNearbyLoot` |
|
||||
| [Macros](docs/API.md#macros) | `GetLooseMacroIcons`, `GetLooseMacroItemIcons`, `GetMacroIcons`, `GetMacroItemIcons`, `GetMacroSpell` |
|
||||
| [Mail](docs/API.md#mail) | `GetInboxItemLink`, `GetSendMailItemLink` |
|
||||
@@ -143,6 +143,7 @@ when launching with `-console`), not as Lua functions. See the
|
||||
| Unit stat | `LE_UNIT_STAT_STRENGTH` … `LE_UNIT_STAT_SPIRIT` |
|
||||
| Addon security | `Enum.AddOnSecurityStatus.{Secure,Insecure,Banned,NotAvailable}` |
|
||||
| Power type | `Enum.PowerType.{HealthCost,None,Mana,Rage,Focus,Energy,Happiness}` |
|
||||
| Inventory type | `Enum.InventoryType.Index*Type` (0–34, e.g. `IndexHeadType`=1 … `IndexRelicType`=28) |
|
||||
|
||||
### Unit tokens
|
||||
|
||||
@@ -164,6 +165,14 @@ native targeting bindings instead of orphaned at the bottom.
|
||||
|
||||
See [Focus / Bindings](docs/API.md#bindings-focustarget--targetfocus) for the implementation note.
|
||||
|
||||
### Behaviors
|
||||
|
||||
Transparent engine tweaks — no API to call, they just fix a vanilla limitation:
|
||||
|
||||
| Tweak | Effect |
|
||||
|-------|--------|
|
||||
| Tooltip line cap | Lifts `GameTooltip`'s hard 30-line limit to 60 for every `GameTooltipTemplate` frame (`GameTooltip`, `ShoppingTooltip1/2`, `ItemRefTooltip`, AtlasLoot, …). Stat-heavy tooltips and comparison blocks (e.g. pfUI's eqcompare) no longer have their extra lines silently dropped. Done in pure C++ by growing the engine's FontString pool at tooltip-creation time. |
|
||||
|
||||
## Installation
|
||||
|
||||
Download the prebuilt `ClassicAPI.dll` from the
|
||||
@@ -265,4 +274,4 @@ at configure time; the value exposed to Lua will be `X*10000 + Y*100 + Z`.
|
||||
|
||||
## License
|
||||
|
||||
LGPL v3 or later. See the headers in `src/` for the full notice.
|
||||
GPL v3 or later. See the headers in `src/` for the full notice.
|
||||
|
||||
@@ -3301,3 +3301,272 @@ the matching read. Both should be straightforward once the field
|
||||
offset is identified — 3.3.5's `Script_*` equivalents are a good
|
||||
starting point for what the parameter shape and bounds-clamp
|
||||
behavior should be.
|
||||
|
||||
## ~~97. Lift GameTooltip's 30-line cap~~ — DONE
|
||||
|
||||
Shipped as [src/tooltip/LinePool.cpp](src/tooltip/LinePool.cpp): pure C++,
|
||||
no addon Lua. Co-hooks the XML-OnLoad region scan (FUN_00529650, vtable
|
||||
slot 9) via `Game::HookAutoRegister`; after the engine sets up the
|
||||
template's 30 lines it creates `TextLeft/Right 31..60` in C++ (alloc →
|
||||
ctor → name → font-copied-from-prev → anchor, offsets scaled pixel →
|
||||
internal like Script_SetPoint) and appends them to the tooltip's three
|
||||
line arrays, bumping `numLinesAllocated`. Runs once per GameTooltip-family
|
||||
frame at creation + per `/reload`, so it auto-covers GameTooltip,
|
||||
ShoppingTooltip1/2, ItemRefTooltip, AtlasLootTooltip, WorldMapTooltip, …
|
||||
Verified in-game: AtlasLoot tooltip rendered a 31st line correctly. Cap is
|
||||
`kMaxLines = 60`. The design notes below record the RE trail; Approach A
|
||||
(hook AddLine) / Approach B (addon Lua) were both explored and dropped in
|
||||
favor of the scan-hook.
|
||||
|
||||
Vanilla 1.12's `GameTooltip:AddLine` silently drops any line past the
|
||||
pool of `TextLeftN`/`TextRightN` FontStrings the XML template
|
||||
pre-declares (30). Modern (3.3.5+) engines grow the pool on demand.
|
||||
Addons that append comparison summaries, item-info footers, or aura
|
||||
details to a full item tooltip get their tail chopped. Practical
|
||||
example — pfUI's eqcompare block (base-stat deltas inline + extended
|
||||
stats appended at the bottom) hits the cap on stat-heavy items where
|
||||
the vendor tooltip already has ~22 lines and the compare block adds
|
||||
another 10; extended-stat rows past line 30 disappear silently.
|
||||
|
||||
Also affects `ShoppingTooltip1`/`ShoppingTooltip2` (same
|
||||
`GameTooltipTemplate`).
|
||||
|
||||
### Root cause (verified in Ghidra on the 1.12 Octo binary)
|
||||
|
||||
`AddLine` internal impl at `FUN_00530270` — the shared body called
|
||||
from both `Script_GameTooltipAddLine` (`FUN_00531630`, method ptr
|
||||
stored in the GameTooltip method table alongside the `"AddLine"`
|
||||
string at `0x00854560`) and `Script_GameTooltipAddDoubleLine`:
|
||||
|
||||
```c
|
||||
void FUN_00530270(int this, char *leftText, char *rightText,
|
||||
colorLeft, colorRight, wrapFlag) {
|
||||
if ((*(int *)(this + 0x31c) != *(int *)(this + 0x320)) && anyHasText) {
|
||||
// set leftText on textLeft[numLines_used],
|
||||
// set rightText on textRight[numLines_used],
|
||||
// wrapFlag[numLines_used] = wrapFlag,
|
||||
// ++numLines_used
|
||||
}
|
||||
// else: silently drop the line
|
||||
}
|
||||
```
|
||||
|
||||
`0x320 == 800` decimal, matches decompile. Pool exhausted ⇒ nothing
|
||||
happens.
|
||||
|
||||
### CGameTooltip struct offsets (1.12)
|
||||
|
||||
Derived from `FUN_00530270` and the pool-init at `FUN_00529650`:
|
||||
|
||||
| Offset | Field |
|
||||
|--------|----------------------------------------------------|
|
||||
| `+0x31c` | `numLines` — current write index (0-based) |
|
||||
| `+0x320` | `numLinesAllocated` — pool size (30 default) |
|
||||
| `+0x328..+0x32c` | `textLeft[]` — array of `CSimpleFontString *`, count `+0x320` |
|
||||
| `+0x334..+0x338` | `textRight[]` — same, symmetric right column |
|
||||
| `+0x340..+0x344` | `wrapFlag[]` — per-line wrap bool |
|
||||
|
||||
Actual layout of the array slots: `+0x328` is the first ptr in an
|
||||
external heap block whose base is `param_1[0xcb]` = `+0x32c`. The
|
||||
init function reallocates all three arrays whenever `numLinesAllocated`
|
||||
would change — see `FUN_00536c80` (the reallocator) and `FUN_004368c0`
|
||||
(a matching alloc for the wrap-flag array of a different element size).
|
||||
|
||||
### The pool-init function
|
||||
|
||||
`FUN_00529650` — walks `%sTextLeftN` / `%sTextRightN` FontString names
|
||||
from the FrameXML-declared pool, counts them, reallocates the three
|
||||
arrays, stores the pointers. Called via vtable slot at `0x00808f84`
|
||||
(only xref) — likely `SetOwner` or an equivalent virtual reset method
|
||||
runs it. It's the natural growth path — if we can force it to see a
|
||||
larger pool of Lua-visible FontStrings and trigger it, the arrays
|
||||
resize themselves.
|
||||
|
||||
### The 3.3.5 reference (already REd)
|
||||
|
||||
3.3.5's `GameTooltip::AddLine` at `0x0061fec0` has the grow-on-demand
|
||||
branch we want to backport. Shape:
|
||||
|
||||
```c
|
||||
if (currentLine == numLinesAllocated - 1) {
|
||||
format(buf, 256, "%sTextLeft%d", tooltipName, currentLine + 1);
|
||||
auto *fs = SimpleFontString::create(this, /*layer*/2, /*subLayer*/1);
|
||||
fs->setName(buf);
|
||||
fs->setFontObject(prevLeft->fontObject);
|
||||
fs->anchor(TOPLEFT, prevLeft, BOTTOMLEFT, 0.0, calculatedYOffset);
|
||||
// ... mirror for TextRight ...
|
||||
// ... append fs to textLeft[]/textRight[] at [numLinesAllocated],
|
||||
// then ++numLinesAllocated.
|
||||
}
|
||||
// fall through to the existing "set text on line[currentLine]" path
|
||||
```
|
||||
|
||||
3.3.5 helpers (offsets 3.3.5-specific — 1.12 equivalents need to be
|
||||
re-derived):
|
||||
- `FUN_00485240` — SimpleFontString constructor `(parent, layer, sublayer)`
|
||||
- `FUN_0048b6c0` — set-name helper (registers under global `_G[name]`)
|
||||
- `FUN_0048a260` — anchor helper `(this, anchorPoint, relativeTo, relativePoint, xoff, yoff)`
|
||||
|
||||
Struct offsets in 3.3.5 were `+0x2a4` (numLines) / `+0x2a8` (numAlloc) /
|
||||
`+0x2b4` (textLeft) / `+0x2c0` (textRight) / `+0x2cc` (wrapFlag). All
|
||||
shifted vs. 1.12 (see above), unsurprising given TBC/WotLK bloat.
|
||||
|
||||
### Implementation plan
|
||||
|
||||
**Approach A — pre-hook AddLine with a grow-if-needed prelude
|
||||
(preferred)**:
|
||||
|
||||
1. Locate the 1.12 equivalents of the three 3.3.5 helpers. Trace them
|
||||
from existing `CSimpleFontString`-creating sites in the engine —
|
||||
the CreateFontString API dispatch is a good starting point (it's
|
||||
Lua-visible and calls the same constructor).
|
||||
2. Locate the array reallocators used by `FUN_00529650`
|
||||
(`FUN_00536c80` for the two pointer arrays, `FUN_004368c0` for the
|
||||
wrap-flag byte array).
|
||||
3. MinHook `FUN_00530270`. Pre-hook body:
|
||||
- If `numLines != numLinesAllocated`, call original — done.
|
||||
- Otherwise: realloc the three arrays to `numLinesAllocated + 1`,
|
||||
create two new `CSimpleFontString` (left + right), name them
|
||||
`"%sTextLeft%d"` / `"%sTextRight%d"` with `tooltip->GetName()` and
|
||||
the new index, anchor each below the prior-slot FontString on the
|
||||
same side, use the prior FontString's `fontObject` (`+0xd8` in the
|
||||
3.3.5 layout — confirm on 1.12) as the default, write the pointers
|
||||
into `textLeft[numLinesAllocated]` / `textRight[numLinesAllocated]`,
|
||||
zero-init `wrapFlag[numLinesAllocated]`, and bump
|
||||
`numLinesAllocated`.
|
||||
- Then tail-call the original — it now succeeds normally.
|
||||
|
||||
**Approach B — pre-declare a wider pool via Lua** (fallback if the
|
||||
constructor helpers turn out to be too tangled):
|
||||
|
||||
1. In `!!!ClassicAPI` addon, at load time, call
|
||||
`GameTooltip:CreateFontString("GameTooltipTextLeft" .. i, "ARTWORK",
|
||||
"GameTooltipText")` for `i = 31..60`, plus `TextRightN`, plus set
|
||||
anchors matching the pattern in the template.
|
||||
2. Force the engine's pool-init to re-scan. If we can't reach the
|
||||
vtable trigger cleanly, expose a small C entrypoint that walks the
|
||||
pool the same way `FUN_00529650` does — takes `tooltip` as arg,
|
||||
reallocates arrays, refills.
|
||||
|
||||
Approach B is less code but ties the cap to a fixed number (60 lines
|
||||
is enough for pfUI's use case but arbitrary). Approach A grows on
|
||||
demand like retail and has no ceiling.
|
||||
|
||||
### Testing
|
||||
|
||||
- Hover a random-suffix weapon with several equip-spell bonuses (Krol
|
||||
Blade, Ironfoe, any ZG/AQ trinket) — tooltip should render >30 lines
|
||||
without truncation.
|
||||
- Hover an item that produces a 40+ line tooltip when pfUI's eqcompare
|
||||
block is enabled (Priest Judgement Set chest against another
|
||||
Judgement chest: item tooltip ~22 lines + compare block ~10 lines).
|
||||
- Verify no crash / no visual glitches on:
|
||||
- ShoppingTooltip1/2 (same class, same `GameTooltipTemplate`)
|
||||
- Rapid re-hovers (create/destroy pressure on the added FontStrings)
|
||||
- Item tooltips that stay under 30 lines (pre-existing behavior unchanged)
|
||||
|
||||
### Risks
|
||||
|
||||
- If the array reallocation logic in `FUN_00536c80` doesn't null-out
|
||||
the tail on grow, `textLeft[N]`/`textRight[N]` might contain
|
||||
garbage for a frame — anchor before write, or memset to zero.
|
||||
- FontString lifetime: 3.3.5 leaks the extras for the tooltip
|
||||
lifetime (they stay hidden when unused). GameTooltip is a
|
||||
singleton, so leak is bounded. Fine.
|
||||
- Interaction with `pfUI`'s existing tooltip skinning (frame borders,
|
||||
status bar reposition, etc.): the layer we're modifying is beneath
|
||||
the skinning; shouldn't touch anything visible unless anchor math
|
||||
is wrong.
|
||||
|
||||
### Related
|
||||
|
||||
If we ever consider dropping the whole "GameTooltipTemplate declares
|
||||
30 FontStrings in XML" scheme and instead having the engine start
|
||||
with 0 and grow entirely on demand — that would be even cleaner, but
|
||||
requires patching every consumer of the initial pool (there aren't
|
||||
many, but they need audit). Filed for future if the incremental grow
|
||||
turns out to be fragile.
|
||||
|
||||
### Investigation update (resolved unknowns)
|
||||
|
||||
Traced the pool machinery end-to-end. The open questions above are now
|
||||
answered, and they point away from both the AddLine hook (Approach A)
|
||||
and the "trigger the engine's scan" idea — a **hybrid** is cleaner than
|
||||
either.
|
||||
|
||||
**The scan is virtual slot 9, run only at XML-template instantiation.**
|
||||
`FUN_00529650` is slot 9 (`vtable+0x24`) of the CGameTooltip vtable
|
||||
(base `0x00808f60`; the null at `0x00808f5c` is the boundary, and slot 2
|
||||
`0x005368d0` is the `tooltip:method()` dispatcher — confirms the class).
|
||||
The two vtable-base xrefs are the constructors `FUN_00529240` /
|
||||
`FUN_00529480`. The scan's prologue calls
|
||||
`FUN_0076a2f0(node) → FUN_0076a060(node)`, which reads the XML
|
||||
`"inherits"` attribute and child `"Frames"` — i.e. the scan is the
|
||||
frame's **XML OnLoad / region-setup** virtual. It runs once when
|
||||
`GameTooltip` is built from `GameTooltipTemplate` (and again per
|
||||
`/reload`), **not** on `SetOwner`/show. So we can't cheaply re-trigger
|
||||
it — the `node` arg is a live XML-parse handle we don't have, and
|
||||
calling it with a bogus node runs the inherits/Frames path on garbage.
|
||||
|
||||
**The scan finds lines by `_G[name]`, so Lua-created FontStrings count.**
|
||||
`numLinesAllocated` (`+0x320`) is literally "how many contiguous
|
||||
`%sTextLeftN` **and** `%sTextRightN` exist by name": pass 0 counts (stop
|
||||
at the first missing index), pass 1 reallocs the three arrays to that
|
||||
count and fills the pointers. The name lookup `FUN_0076c760` does
|
||||
`lua_pushstring(name); gettable(_G); if type==TABLE: FrameScript_GetObject`
|
||||
— a plain `_G[name]` resolve, so a FontString made with
|
||||
`GameTooltip:CreateFontString("GameTooltipTextLeft31", …)` **is**
|
||||
visible to it. (Names must be contiguous and exist in *both* columns.)
|
||||
|
||||
**The array reallocators are simple and callable from C.**
|
||||
`FUN_00536c80` (pointer arrays) and `FUN_004368c0` (wrap-flag array) are
|
||||
the same routine with different SMem tags:
|
||||
`__thiscall(descriptor, newCount)` where the descriptor is
|
||||
`{ count@+0x0, cap@+0x4, data@+0x8 }` — reallocs `data` to `newCount*4`
|
||||
and copies the old contents. In the tooltip the three descriptors are:
|
||||
|
||||
| Descriptor `this` | count / cap / data | array |
|
||||
|-------------------|--------------------|-------|
|
||||
| `tooltip + 0x324` | `+0x324 / +0x328 / +0x32c` | `textLeft[]` (`CSimpleFontString*`) |
|
||||
| `tooltip + 0x330` | `+0x330 / +0x334 / +0x338` | `textRight[]` |
|
||||
| `tooltip + 0x33c` | `+0x33c / +0x340 / +0x344` | `wrapFlag[]` (int, 4-byte) |
|
||||
|
||||
`numLinesAllocated` (`+0x320`) is a separate field the scan sets equal
|
||||
to the count; AddLine (`FUN_00530270`) gates on
|
||||
`numLines(+0x31c) != numLinesAllocated(+0x320)`.
|
||||
|
||||
**Recommended approach — Lua creates FontStrings, C grows the arrays
|
||||
(no hook, no XML re-run).** Replicate the scan's pass 1 directly:
|
||||
|
||||
1. **Lua (`!!!ClassicAPI`), at load / `PLAYER_LOGIN`:** for each frame on
|
||||
`GameTooltipTemplate` (`GameTooltip`, `ShoppingTooltip1/2`,
|
||||
`ItemRefTooltip`, …), create `<name>TextLeft31..N` and
|
||||
`<name>TextRight31..N` via `frame:CreateFontString(nm, "ARTWORK",
|
||||
"GameTooltipText")`, each anchored `TOPLEFT`/`TOPRIGHT` to the prior
|
||||
line's `BOTTOMLEFT`/`BOTTOMRIGHT` (mirror the template's chain).
|
||||
This avoids re-deriving the 1.12 FontString ctor / setName / anchor
|
||||
helpers that Approach A needed — Lua already wraps them.
|
||||
2. **C entrypoint** `GrowTooltipPool(tooltipObj, newCount)` (expose as a
|
||||
Lua global, called once per frame right after step 1):
|
||||
- `FUN_00536c80(tooltip+0x324, newCount)`; set `+0x328 = newCount`.
|
||||
- `FUN_00536c80(tooltip+0x330, newCount)`; set `+0x334 = newCount`.
|
||||
- `FUN_004368c0(tooltip+0x33c, newCount)`; set `+0x340 = newCount`.
|
||||
- for `i` in `[oldAlloc, newCount)`: resolve `<name>TextLeftN`/
|
||||
`RightN` via the `_G[name]` dance (same as `FUN_0076c760`), and if
|
||||
either is missing stop at `i`; else write the two pointers into the
|
||||
new `textLeft`/`textRight` data slots and zero `wrapFlag[i]`.
|
||||
- set `numLinesAllocated (+0x320) = i`.
|
||||
Resolve `tooltipObj` from the Lua frame the same way our other
|
||||
tooltip methods do (`FrameScript_GetObject`).
|
||||
|
||||
Runs once per frame per session (re-runs on `/reload`, which recreates
|
||||
the frames → scan resets to 30 → our addon re-creates + re-grows). No
|
||||
per-line hook (dodges the MinHook-collision risk on a moderately hot
|
||||
function), no XML-node fabrication.
|
||||
|
||||
Remaining risk to validate in-game: whether AddLine's downstream layout
|
||||
/ `Show` sizing walks `numLines` FontStrings by their anchors (expected)
|
||||
vs. any hidden fixed-30 assumption elsewhere; and that the Lua-created
|
||||
lines inherit height/spacing identical to the template's 1..30 so the
|
||||
tooltip grows seamlessly. Both are observable on the first >30-line
|
||||
hover.
|
||||
|
||||
+320
-4
@@ -139,6 +139,9 @@ build instructions.
|
||||
- [`GameTooltip:SetSpellByID(spellID)`](#gametooltipsetspellbyidspellid)
|
||||
- [`GameTooltip:SetTalentByID(talentID)`](#gametooltipsettalentbyidtalentid)
|
||||
- [`GameTooltip:SetInventoryItemByID(itemID)`](#gametooltipsetinventoryitembyiditemid)
|
||||
- [`GameTooltip:SetHyperlinkCompareItem("itemLink" [, offset, shiftButton, comparisonTooltip])`](#gametooltipsethyperlinkcompareitemitemlink--offset-shiftbutton-comparisontooltip)
|
||||
- [`GameTooltip:IsEquippedItem()`](#gametooltipisequippeditem)
|
||||
- [`OnTooltipSetItem` script](#ontooltipsetitem-script)
|
||||
- [`GameTooltip:SetItemByGUID(itemGUID)`](#gametooltipsetitembyguiditemguid)
|
||||
- [`GameTooltip:SetEquipmentSet(name)`](#gametooltipsetequipmentsetname)
|
||||
- [`GameTooltip:GetItem()`](#gametooltipgetitem)
|
||||
@@ -154,6 +157,7 @@ build instructions.
|
||||
- [`LE_ITEM_QUALITY_*`](#le_item_quality_)
|
||||
- [`LE_UNIT_STAT_*`](#le_unit_stat_)
|
||||
- [`Enum.AddOnSecurityStatus`](#enumaddonsecuritystatus)
|
||||
- [`Enum.InventoryType`](#enuminventorytype)
|
||||
- [`Enum.PowerType`](#enumpowertype)
|
||||
|
||||
- [Gossip](#gossip)
|
||||
@@ -190,6 +194,8 @@ build instructions.
|
||||
- [`C_Item.GetItemGUID(itemLocation)`](#c_itemgetitemguiditemlocation)
|
||||
- [`C_Item.GetItemID(itemLocation)`](#c_itemgetitemiditemlocation)
|
||||
- [`C_Item.GetItemInfoInstant(item)`](#c_itemgetiteminfoinstantitem)
|
||||
- [`C_Item.GetItemInventorySlotInfo(inventorySlot)`](#c_itemgetiteminventoryslotinfoinventoryslot)
|
||||
- [`C_Item.GetItemInventorySlotKey(inventorySlot)`](#c_itemgetiteminventoryslotkeyinventoryslot)
|
||||
- [`C_Item.GetItemInventoryType(itemLocation)` / `C_Item.GetItemInventoryTypeByID(item)`](#c_itemgetiteminventorytypeitemlocation--c_itemgetiteminventorytypebyiditem)
|
||||
- [`C_Item.GetItemLink(itemLocation)`](#c_itemgetitemlinkitemlocation)
|
||||
- [`C_Item.GetItemLocation(itemGUID)`](#c_itemgetitemlocationitemguid)
|
||||
@@ -200,12 +206,16 @@ build instructions.
|
||||
- [`C_Item.GetItemSetID(itemLocation)` / `C_Item.GetItemSetIDByID(item)`](#c_itemgetitemsetiditemlocation--c_itemgetitemsetidbyiditem)
|
||||
- [`C_Item.GetItemSetInfo(setID)`](#c_itemgetitemsetinfosetid)
|
||||
- [`C_Item.GetItemSpell(item)`](#c_itemgetitemspellitem)
|
||||
- [`C_Item.GetItemStatDelta(itemLink1, itemLink2)`](#c_itemgetitemstatdeltaitemlink1-itemlink2)
|
||||
- [`C_Item.GetItemStats(itemLink)`](#c_itemgetitemstatsitemlink)
|
||||
- [`C_Item.GetItemSubClassInfo(classID, subClassID)`](#c_itemgetitemsubclassinfoclassid-subclassid)
|
||||
- [`C_Item.GetItemUniqueness(itemLocation)` / `C_Item.GetItemUniquenessByID(item)`](#c_itemgetitemuniquenessitemlocation--c_itemgetitemuniquenessbyiditem)
|
||||
- [`C_Item.GetStackCount(itemLocation)`](#c_itemgetstackcountitemlocation)
|
||||
- [`C_Item.IsBound(itemLocation)`](#c_itemisbounditemlocation)
|
||||
- [`C_Item.IsEquippableItem(item)`](#c_itemisequippableitemitem)
|
||||
- [`C_Item.IsEquippedItem(item)`](#c_itemisequippeditemitem)
|
||||
- [`C_Item.IsItemDataCachedByID(item)` / `C_Item.IsItemDataCached(itemLocation)`](#c_itemisitemdatacachedbyiditem--c_itemisitemdatacacheditemlocation)
|
||||
- [`C_Item.IsItemGUIDInInventory(itemGUID)`](#c_itemisitemguidininventoryitemguid)
|
||||
- [`C_Item.IsItemOpenable(itemLocation)`](#c_itemisitemopenableitemlocation)
|
||||
- [`C_Item.IsLocked(itemLocation)`](#c_itemislockeditemlocation)
|
||||
- [`C_Item.LockItem(itemLocation)`](#c_itemlockitemitemlocation)
|
||||
@@ -3414,6 +3424,117 @@ end
|
||||
GameTooltip:Show()
|
||||
```
|
||||
|
||||
### `GameTooltip:SetHyperlinkCompareItem("itemLink" [, offset, shiftButton, comparisonTooltip])`
|
||||
|
||||
Fills the tooltip with the item **currently equipped** in the slot the
|
||||
given item would occupy — a grey `Currently Equipped` header, the
|
||||
equipped item's own tooltip, then (when `shiftButton` is set) a
|
||||
green/red per-stat delta breakdown of how the given item compares.
|
||||
This is the method behind item-comparison ("shopping") tooltips;
|
||||
`FrameXML`'s `GameTooltip_ShowCompareItem` drives it.
|
||||
|
||||
Call it on the tooltip that should show the comparison (typically
|
||||
`ShoppingTooltip1`/`ShoppingTooltip2`, but any `GameTooltipTemplate`
|
||||
frame works).
|
||||
|
||||
| Arg | Meaning |
|
||||
|-----|---------|
|
||||
| `itemLink` | The item being compared (chat link, `item:` string, or bare itemID). Optional if `comparisonTooltip` is given. |
|
||||
| `offset` | 1-based slot selector for two-slot items — rings, trinkets, and one-hand weapons expose `offset` 1 and 2 (Finger1/2, Trinket1/2, MainHand/OffHand). Default 1. |
|
||||
| `shiftButton` | Gates the stat-change breakdown. Deltas show by default (`true`/`1`/`nil`/omitted) and are hidden only for an explicit `false`/`0` (header + equipped item only). Both the boolean and vanilla `1`/`nil` conventions are accepted. |
|
||||
| `comparisonTooltip` | Optional. When `itemLink` is omitted, the compared item is taken from whatever this tooltip is displaying (matches the retail tooltip-to-tooltip call). |
|
||||
|
||||
**Returns** the number of comparison slots for the item (1, or 2 for
|
||||
rings/trinkets/one-hand weapons; 0 if it isn't equippable, isn't
|
||||
cached, or nothing is equipped in the chosen slot) — so a caller knows
|
||||
whether a second `offset` is worth querying.
|
||||
|
||||
The stat deltas cover the same keys as
|
||||
[`C_Item.GetItemStats`](#c_itemgetitemstatsitemlink) (base stats,
|
||||
resistances, weapon DPS, and on-equip-spell bonuses like crit / attack
|
||||
power / spell power), colored with the client's
|
||||
`INCREASE_STAT_COLOR` / `DECREASE_STAT_COLOR`. The method only
|
||||
populates the tooltip; the caller shows/anchors it (as retail's
|
||||
`SetHyperlinkCompareItem` does).
|
||||
|
||||
```lua
|
||||
-- Compare a hovered bag item against what's equipped:
|
||||
local link = GetContainerItemLink(bag, slot)
|
||||
ShoppingTooltip1:SetOwner(GameTooltip, "ANCHOR_NONE")
|
||||
local slots = ShoppingTooltip1:SetHyperlinkCompareItem(link, 1, true)
|
||||
ShoppingTooltip1:Show()
|
||||
if slots == 2 then -- ring/trinket/1H: also compare the other slot
|
||||
ShoppingTooltip2:SetOwner(GameTooltip, "ANCHOR_NONE")
|
||||
ShoppingTooltip2:SetHyperlinkCompareItem(link, 2, true)
|
||||
ShoppingTooltip2:Show()
|
||||
end
|
||||
```
|
||||
|
||||
### `GameTooltip:IsEquippedItem()`
|
||||
|
||||
Returns `true` when the item the tooltip is **currently displaying** is
|
||||
equipped in one of the player's character-pane slots (1..19). Backports
|
||||
the 3.3.5 `GameTooltip:IsEquippedItem` method.
|
||||
|
||||
Works regardless of how the tooltip was populated — link paths
|
||||
(`SetItemByID`, `SetHyperlink`) and CGItem paths (`SetInventoryItem`,
|
||||
`SetBagItem`, `SetItemByGUID`, …) both resolve to the displayed item.
|
||||
Returns `false` for a tooltip that isn't showing an item (e.g. a spell
|
||||
tooltip) with no false positives.
|
||||
|
||||
```lua
|
||||
GameTooltip:SetInventoryItem("player", INVSLOT_HAND)
|
||||
if GameTooltip:IsEquippedItem() then ... end -- true
|
||||
|
||||
GameTooltip:SetBagItem(0, 1)
|
||||
if GameTooltip:IsEquippedItem() then ... end -- false unless that item is also worn
|
||||
```
|
||||
|
||||
### `OnTooltipSetItem` script
|
||||
|
||||
A real frame script — settable with the standard `SetScript` / `GetScript` /
|
||||
`HookScript` — that fires whenever a tooltip's **item** is set. Backports the
|
||||
modern tooltip script so addons annotate item tooltips by hooking one script
|
||||
instead of wrapping every `Set*` method.
|
||||
|
||||
Fires for every item-setting path (`SetBagItem`, `SetInventoryItem`,
|
||||
`SetHyperlink` for an `item:` link, `SetMerchantItem`, `SetAuctionItem`,
|
||||
`SetItemByID`, …). Available on all GameTooltip-type frames (`GameTooltip`,
|
||||
`ItemRefTooltip`, `ShoppingTooltip1/2`, `AtlasLootTooltip`, …).
|
||||
|
||||
The handler receives the tooltip as the **global `this`**, the 1.12
|
||||
frame-script convention — *not* a `self` argument (like every built-in vanilla
|
||||
script: `OnShow`, `OnEvent`, `OnTooltipCleared`, …). Modern-style
|
||||
`function(self) self:… end` handlers will see `self == nil`; use `this`.
|
||||
|
||||
```lua
|
||||
GameTooltip:HookScript("OnTooltipSetItem", function()
|
||||
local name, link, id = this:GetItem() -- the tooltip is the global `this`
|
||||
if id then
|
||||
this:AddLine("ID: " .. id, 0.6, 0.6, 0.6)
|
||||
end
|
||||
end)
|
||||
```
|
||||
|
||||
Vanilla only shipped `OnTooltipAddMoney` / `OnTooltipCleared` /
|
||||
`OnTooltipSetDefaultAnchor`; `OnTooltipSetSpell` / `OnTooltipSetUnit` are not
|
||||
yet provided.
|
||||
|
||||
**Caveat — the event fires from inside the item-tooltip build.** Lightweight
|
||||
handler work is fine: reading `this:GetItem()`, `this:AddLine(...)`, printing,
|
||||
etc. But avoid *re-entrant* tooltip rebuilds from the handler — e.g.
|
||||
`GameTooltip_ShowCompareItem()`, or a `Set*` call on another tooltip. Because
|
||||
the handler runs mid-build, re-entering the tooltip / FrameScript machinery can
|
||||
collide with other DLLs that hook the same Lua paths (nampower, SuperWoW,
|
||||
weirdutils, …) and crash the client. If you need heavy work like that, defer it
|
||||
to the next frame:
|
||||
|
||||
```lua
|
||||
GameTooltip:HookScript("OnTooltipSetItem", function()
|
||||
C_Timer.After(0, function() GameTooltip_ShowCompareItem() end)
|
||||
end)
|
||||
```
|
||||
|
||||
### `GameTooltip:SetEquipmentSet(name)`
|
||||
|
||||
Fills the tooltip with a summary of the named equipment set: header,
|
||||
@@ -3613,6 +3734,39 @@ if C_AddOns.GetAddOnSecurity(name) == Enum.AddOnSecurityStatus.Secure then
|
||||
end
|
||||
```
|
||||
|
||||
### `Enum.InventoryType`
|
||||
|
||||
The equip-type enum — the numeric `inventoryType` reported by
|
||||
[`C_Item.GetItemInfoInstant`](#c_itemgetiteminfoinstantitem) /
|
||||
[`C_Item.GetItemInventoryType`](#c_itemgetiteminventorytypeitemlocation--c_itemgetiteminventorytypebyiditem),
|
||||
and the argument the `C_Item.GetItemInventorySlot*` functions take.
|
||||
|
||||
| Value | Field | Value | Field |
|
||||
|------:|-------|------:|-------|
|
||||
| 0 | `IndexNonEquipType` | 15 | `IndexRangedType` |
|
||||
| 1 | `IndexHeadType` | 16 | `IndexCloakType` |
|
||||
| 2 | `IndexNeckType` | 17 | `Index2HweaponType` |
|
||||
| 3 | `IndexShoulderType` | 18 | `IndexBagType` |
|
||||
| 4 | `IndexBodyType` | 19 | `IndexTabardType` |
|
||||
| 5 | `IndexChestType` | 20 | `IndexRobeType` |
|
||||
| 6 | `IndexWaistType` | 21 | `IndexWeaponmainhandType` |
|
||||
| 7 | `IndexLegsType` | 22 | `IndexWeaponoffhandType` |
|
||||
| 8 | `IndexFeetType` | 23 | `IndexHoldableType` |
|
||||
| 9 | `IndexWristType` | 24 | `IndexAmmoType` |
|
||||
| 10 | `IndexHandType` | 25 | `IndexThrownType` |
|
||||
| 11 | `IndexFingerType` | 26 | `IndexRangedrightType` |
|
||||
| 12 | `IndexTrinketType` | 27 | `IndexQuiverType` |
|
||||
| 13 | `IndexWeaponType` | 28 | `IndexRelicType` |
|
||||
| 14 | `IndexShieldType` | | |
|
||||
|
||||
Values `29..34` (`IndexProfessionToolType`, `IndexProfessionGearType`,
|
||||
`IndexEquipablespell{Offensive,Utility,Defensive,Weapon}Type`) are
|
||||
post-vanilla and included for parity — vanilla items never report them.
|
||||
|
||||
```lua
|
||||
if C_Item.GetItemInventoryType(loc) == Enum.InventoryType.IndexHeadType then ...
|
||||
```
|
||||
|
||||
### `Enum.PowerType`
|
||||
|
||||
The integer enum `UnitPowerType` returns and `UnitPower` /
|
||||
@@ -4370,6 +4524,25 @@ Silk Cloth lives at `(7, 0)` in this client, not the modern `(7, 5)`.
|
||||
> explicitly, or just call `GetItemInfo` (which warms via the
|
||||
> `Script_GetItemInfo` hook).
|
||||
|
||||
### `C_Item.GetItemInventorySlotInfo(inventorySlot)`
|
||||
|
||||
Returns the localized display name for an `Enum.InventoryType` value — e.g.
|
||||
`C_Item.GetItemInventorySlotInfo(1)` → `"Head"`. Returns `nil` for the
|
||||
non-equip slot (`0`) or out-of-range values.
|
||||
|
||||
The engine's INVTYPE table stores the equipLoc *key* (`"INVTYPE_HEAD"`); the
|
||||
display name is the FrameXML global string of that key (`INVTYPE_HEAD =
|
||||
"Head"`), so the result is correctly localized on non-English clients.
|
||||
|
||||
### `C_Item.GetItemInventorySlotKey(inventorySlot)`
|
||||
|
||||
Returns the equipLoc key string for an `Enum.InventoryType` value — e.g.
|
||||
`C_Item.GetItemInventorySlotKey(1)` → `"INVTYPE_HEAD"`. This is the same
|
||||
`INVTYPE_*` token [`C_Item.GetItemInfoInstant`](#c_itemgetiteminfoinstantitem)
|
||||
returns as its `itemEquipLoc`. Returns `nil` for the non-equip slot (`0`) or
|
||||
out-of-range values. Pair it with `GetItemInventorySlotInfo` to turn the key
|
||||
into a localized label.
|
||||
|
||||
### `C_Item.GetItemInventoryType(itemLocation)` / `C_Item.GetItemInventoryTypeByID(item)`
|
||||
|
||||
Returns the numeric `Enum.InventoryType` straight off the cache
|
||||
@@ -4623,6 +4796,123 @@ request. A second call after `GET_ITEM_INFO_RECEIVED` lands the
|
||||
data. Same warmup pattern as `C_Item.GetItemFamily` and the rest of
|
||||
our cache-backed accessors.
|
||||
|
||||
### `C_Item.GetItemStatDelta(itemLink1, itemLink2)`
|
||||
|
||||
Returns a table of the per-stat **difference** between two items,
|
||||
computed as `item2 - item1` — a positive value means the second item has
|
||||
more of that stat. Only stats whose delta is non-zero appear.
|
||||
|
||||
```lua
|
||||
-- Compare an equipped ring against one in your bags:
|
||||
local delta = C_Item.GetItemStatDelta(
|
||||
C_Item.GetItemLink({equipmentSlotIndex = 11}),
|
||||
C_Item.GetItemLink({bagID = 0, slotIndex = 3}))
|
||||
-- delta = { ITEM_MOD_INTELLECT_SHORT = 6, ITEM_MOD_SPIRIT_SHORT = 2 }
|
||||
-- (the bag ring has +6 Int / +2 Spirit relative to the equipped one)
|
||||
```
|
||||
|
||||
Same key set, accepted input forms, random-suffix handling, and caching
|
||||
caveat as [`C_Item.GetItemStats`](#c_itemgetitemstatsitemlink) — see
|
||||
there for the details. Returns `nil` if **either** item is uncached.
|
||||
|
||||
### `C_Item.GetItemStats(itemLink)`
|
||||
|
||||
Returns a table of an item's stats, keyed by the FrameXML global-string
|
||||
names WoW's own `GetItemStats` uses (so `_G[key]` yields the display
|
||||
label — `_G["ITEM_MOD_STRENGTH_SHORT"]` → `"Strength"`). Only stats the
|
||||
item actually carries are present.
|
||||
|
||||
```lua
|
||||
C_Item.GetItemStats("item:2244") -- Krol Blade
|
||||
-- { ITEM_MOD_STRENGTH_SHORT = 7, ITEM_MOD_STAMINA_SHORT = 5,
|
||||
-- ITEM_MOD_DAMAGE_PER_SECOND_SHORT = 40.89,
|
||||
-- ITEM_MOD_CRIT_MELEE_RATING = 1, ITEM_MOD_CRIT_RANGED_RATING = 1 }
|
||||
|
||||
C_Item.GetItemStats("item:12022:0:769") -- "of the Owl" random suffix
|
||||
-- { ITEM_MOD_INTELLECT_SHORT = 6, ITEM_MOD_SPIRIT_SHORT = 6 }
|
||||
```
|
||||
|
||||
**Sources.** The table is assembled from three places, so it reflects
|
||||
what the item actually grants — not just its stored stat slots:
|
||||
|
||||
1. **Base record** — the stored attributes, armor, resistances, and (for
|
||||
weapons) DPS.
|
||||
2. **On-equip spells** (`SpellTrigger == ON_EQUIP`) — vanilla stores the
|
||||
"special" bonuses (crit, attack power, spell power, hit, mp5, defense,
|
||||
…) as an equip spell whose aura effect carries the value, not as a
|
||||
stat slot. Their auras are decoded into the keys below.
|
||||
3. **Random suffix** — the link's third `item:id:enchant:SUFFIX:unique`
|
||||
field (`ItemRandomProperties.dbc` → `SpellItemEnchantment.dbc`): stat
|
||||
suffixes ("of the Owl") are themselves equip spells, armor suffixes
|
||||
("of Toughness") are direct resistance enchants. A bare itemID or a
|
||||
suffix-less link contributes nothing here.
|
||||
|
||||
**Keys.**
|
||||
|
||||
| Key | Stat | Source |
|
||||
|-----|------|--------|
|
||||
| `ITEM_MOD_STRENGTH_SHORT` / `_AGILITY_` / `_STAMINA_` / `_INTELLECT_` / `_SPIRIT_SHORT` | Base attributes | record / `MOD_STAT` |
|
||||
| `ITEM_MOD_MANA_SHORT` / `ITEM_MOD_HEALTH_SHORT` | Mana / health on equip | record / `MOD_INCREASE_ENERGY` (35) / `MOD_INCREASE_HEALTH` (34) |
|
||||
| `RESISTANCE0_NAME` | Armor | record / `MOD_RESISTANCE` bit 0 |
|
||||
| `RESISTANCE1_NAME` … `RESISTANCE6_NAME` | Holy / Fire / Nature / Frost / Shadow / Arcane resistance | record / `MOD_RESISTANCE` / type-4 enchant |
|
||||
| `ITEM_MOD_DAMAGE_PER_SECOND_SHORT` | Weapon DPS (float) | avg damage ÷ swing time |
|
||||
| `ITEM_MOD_ATTACK_POWER_SHORT` | Attack power | `MOD_ATTACK_POWER` (99) |
|
||||
| `ITEM_MOD_RANGED_ATTACK_POWER_SHORT` | Ranged attack power (ranged-only items) | `MOD_RANGED_ATTACK_POWER` (124) |
|
||||
| `ITEM_MOD_CRIT_MELEE_RATING` + `ITEM_MOD_CRIT_RANGED_RATING` | Crit % | weapon-crit aura (52) |
|
||||
| `ITEM_MOD_HIT_MELEE_RATING` + `ITEM_MOD_HIT_RANGED_RATING` | Hit % | hit aura (54) |
|
||||
| `ITEM_MOD_HIT_SPELL_RATING` | Spell hit % | spell-hit aura (55) |
|
||||
| `ITEM_MOD_CRIT_SPELL_RATING` | Spell crit % | spell-crit aura (57 / 71) |
|
||||
| `ITEM_MOD_SPELL_DAMAGE_DONE_SHORT` | Spell damage | `MOD_DAMAGE_DONE` (13) |
|
||||
| `ITEM_MOD_SPELL_HEALING_DONE_SHORT` | Healing | `MOD_HEALING_DONE` (135) |
|
||||
| `ITEM_MOD_MANA_REGENERATION` | mp5 (mana) | `MOD_POWER_REGEN` (85) |
|
||||
| `ITEM_MOD_DEFENSE_SKILL_RATING` | Defense skill | `MOD_SKILL` (30, misc 95) |
|
||||
| `ITEM_MOD_DODGE_RATING` | Dodge % | `MOD_DODGE_PERCENT` (49) |
|
||||
| `ITEM_MOD_PARRY_RATING` | Parry % | `MOD_PARRY_PERCENT` (47) |
|
||||
| `ITEM_MOD_BLOCK_RATING` | Block chance % | `MOD_BLOCK_PERCENT` (51) |
|
||||
| `ITEM_MOD_BLOCK_VALUE` | Shield block value | record (`m_block`) |
|
||||
|
||||
> **Values are vanilla-native, not ratings.** Vanilla has no rating
|
||||
> system, so the percent-based stats (crit / hit / defense) report the raw
|
||||
> **percentage** under the modern `*_RATING` key — e.g. Krol Blade's
|
||||
> "+1% crit" is `ITEM_MOD_CRIT_MELEE_RATING = 1`, where TBC/Era would
|
||||
> show the level-scaled rating (`13`). A native percent is the only
|
||||
> value that's honest and level-independent. Flat stats (attack power,
|
||||
> spell damage, healing, mp5) are the item's actual magnitudes.
|
||||
>
|
||||
> Rating stats that didn't exist in 1.12 at all (haste, mastery,
|
||||
> versatility, expertise, resilience) never appear. A generic "+N attack
|
||||
> power" item carries both a melee and a ranged AP aura in vanilla; the
|
||||
> generic `ITEM_MOD_ATTACK_POWER_SHORT` key subsumes it, so
|
||||
> `ITEM_MOD_RANGED_ATTACK_POWER_SHORT` shows only for ranged-only items
|
||||
> (scopes, ranged weapons). Rarer auras with no clean single key —
|
||||
> percent attack power, per-weapon-line skill, damage-taken, on-hit /
|
||||
> on-use procs — are skipped.
|
||||
|
||||
**Input.** Accepts a full chat hyperlink, an `item:N…` link string, or a
|
||||
bare itemID (a superset of retail, which is link-only). Returns `nil` if
|
||||
the item isn't cached yet — warm it via `GetItemInfo` and retry.
|
||||
|
||||
### `C_Item.GetItemSubClassInfo(classID, subClassID)`
|
||||
|
||||
Returns `subClassName, subClassUsesInvType` for an item class/subclass pair.
|
||||
|
||||
```lua
|
||||
C_Item.GetItemSubClassInfo(2, 7) -- "One-Handed Swords", false
|
||||
C_Item.GetItemSubClassInfo(4, 1) -- "Cloth", true
|
||||
```
|
||||
|
||||
- `subClassName` (string) — the localized `ItemSubClass.dbc` name (verbose
|
||||
form, e.g. `"One-Handed Swords"`; falls back to the short form for
|
||||
subclasses that only populate it, e.g. `"Consumable"`).
|
||||
- `subClassUsesInvType` (boolean) — true for subclasses whose items are
|
||||
labeled by inventory slot rather than by subclass name. On vanilla data
|
||||
that's exactly the armor material types (Miscellaneous, Cloth, Leather,
|
||||
Mail, Plate); false for weapons, shields, librams, idols, totems, and
|
||||
non-equipment. Read from the `ItemSubClass.dbc` flags bit `0x200`
|
||||
(verified against the 1.15 client).
|
||||
|
||||
Returns `nil` if the `(classID, subClassID)` pair has no row.
|
||||
|
||||
### `C_Item.GetItemUniqueness(itemLocation)` / `C_Item.GetItemUniquenessByID(item)`
|
||||
|
||||
The two functions have **different signatures** in modern (Classic
|
||||
@@ -4767,6 +5057,24 @@ if not C_Item.IsItemDataCachedByID(itemID) then
|
||||
end
|
||||
```
|
||||
|
||||
### `C_Item.IsItemGUIDInInventory(itemGUID)`
|
||||
|
||||
Returns whether the item with the given `"0x…"` GUID is currently carried
|
||||
by the player — the 19 equipment slots plus the bags (backpack + the four
|
||||
equipped bags). Equipped items count (verified against retail); the bank
|
||||
does not.
|
||||
|
||||
```lua
|
||||
local g = C_Item.GetItemGUID({bagID = 0, slotIndex = 1})
|
||||
C_Item.IsItemGUIDInInventory(g) -- true
|
||||
C_Item.IsItemGUIDInInventory(
|
||||
C_Item.GetItemGUID({equipmentSlotIndex = 1})) -- true (equipped counts)
|
||||
```
|
||||
|
||||
Accepts the GUID string [`C_Item.GetItemGUID`](#c_itemgetitemguiditemlocation)
|
||||
/ `UnitGUID` return; returns `false` for a malformed or zero GUID. To also
|
||||
cover the bank, use `C_Item.GetItemCount(itemID, true) > 0` instead.
|
||||
|
||||
### `C_Item.IsItemOpenable(itemLocation)`
|
||||
|
||||
Returns two values: `(isOpenable, canOpen)`.
|
||||
@@ -7960,10 +8268,18 @@ so progress is `(GetTime()*1000 - startTimeMs) / (endTimeMs - startTimeMs)`.
|
||||
> another unit's cast with a server-authoritative cast time, cached per
|
||||
> caster GUID. So `C_Spell.UnitCastingInfo("target")` now backs
|
||||
> enemy/target/focus/nameplate cast bars. Instant casts return `nil` (no
|
||||
> cast bar). Best-effort for remote units: only casts that began while the
|
||||
> unit was in range are seen, and — since 1.12 has no per-unit interrupt
|
||||
> packet to hook — an *interrupted* remote cast lingers until its computed
|
||||
> `endTimeMs` rather than clearing instantly.
|
||||
> cast bar). Best-effort for remote units, in three ways: only casts that
|
||||
> began while the unit was in range are seen; since 1.12 has no per-unit
|
||||
> interrupt packet to hook, an *interrupted* remote cast lingers until its
|
||||
> computed `endTimeMs` rather than clearing instantly; and the remote
|
||||
> `startTimeMs`/`endTimeMs` are shifted later by roughly your latency.
|
||||
> (1.12's `SMSG_SPELL_START` carries only a single `castTime`, so we stamp
|
||||
> `start = now, end = now + castTime` on receipt. 3.3.5+ avoids the skew
|
||||
> because its packet carries *both* total and remaining cast time and
|
||||
> back-dates `start = now − elapsed`; the 1.12 packet has no field to
|
||||
> recover `elapsed` from.) The **local player is unaffected** by all of
|
||||
> this — its cast is detected client-side at the moment of cast, no packet
|
||||
> involved.
|
||||
>
|
||||
> `isTradeskill` is real — the spell's `SPELL_ATTR_TRADESPELL` flag, so
|
||||
> profession recipe casts (smelting, cooking/enchanting recipes, …)
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
namespace Common {
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Game.h"
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Game.h"
|
||||
|
||||
+285
-5
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
@@ -87,6 +87,121 @@ enum Offsets {
|
||||
FUN_REGISTER_FRAME_METHODS = 0x00701D80,
|
||||
VAR_GAMETOOLTIP_METHOD_REGISTRY = 0x00C0CF20,
|
||||
|
||||
// CGameTooltip line pool (see TODO #97). The engine caps AddLine
|
||||
// (FUN_00530270) at `numLinesAllocated`, which the XML-OnLoad scan
|
||||
// (FUN_00529650, vtable slot 9) sets to the count of contiguous
|
||||
// `<name>TextLeftN`/`TextRightN` FontStrings the template declares
|
||||
// (30). Tooltip::LinePool grows it: it appends its own C++-created
|
||||
// FontStrings to the three parallel arrays and bumps this count. Each
|
||||
// array is a {count@+0x0, cap@+0x4, data@+0x8} descriptor; the
|
||||
// reallocators realloc `data` to newCount*4 and copy `cap` old elements.
|
||||
VAR_GAMETOOLTIP_VTABLE = 0x00808F60, // type guard for a resolved tooltip object
|
||||
OFF_GAMETOOLTIP_NUM_LINES_ALLOC = 0x320, // int — pool size AddLine gates on
|
||||
OFF_GAMETOOLTIP_TEXTLEFT_DESC = 0x324, // {count,cap,data}; data (+0x8) = CSimpleFontString*[]
|
||||
OFF_GAMETOOLTIP_TEXTRIGHT_DESC = 0x330, // symmetric right column
|
||||
OFF_GAMETOOLTIP_WRAPFLAG_DESC = 0x33C, // per-line wrap int[]
|
||||
FUN_TOOLTIP_REALLOC_PTR_ARRAY = 0x00536C80, // __thiscall(desc, newCount) — pointer arrays
|
||||
FUN_TOOLTIP_REALLOC_INT_ARRAY = 0x004368C0, // __thiscall(desc, newCount) — wrap-flag array
|
||||
|
||||
// GameTooltip:SetHyperlinkCompareItem (Tooltip::Compare) — builds the
|
||||
// equipped item's tooltip natively (no Lua roundtrip) and appends
|
||||
// colored stat deltas. FUN_GAMETOOLTIP_BUILD_ITEM is the engine's own
|
||||
// item-tooltip builder that SetInventoryItem/SetHyperlink call:
|
||||
// __thiscall(self, itemID, guid*, guid*, a4, a5, a6, headerFlag, a8, a9)
|
||||
// Proven arg shape from FUN_005353b0/FUN_00535700 (all flags 0 → a clean
|
||||
// item tooltip). The builder's own headerFlag (param_7) path merges the
|
||||
// "Currently Equipped" text into the name line and force-wraps it, so we
|
||||
// build clean (flag 0) and prepend the grey header ourselves by shifting
|
||||
// the line FontStrings — see FUN_FONTSTRING_SET_* / OFF_FONTSTRING_*.
|
||||
// FUN_GAMETOOLTIP_ADD_LINE is the raw add-line body (see LinePool notes);
|
||||
// its color args are pointers to a 4-byte packed color {b,g,r,a} — the
|
||||
// Lua AddLine handler (FUN_00531630) builds it as 0xFF<rr><gg><bb>, i.e.
|
||||
// uint32 `0xFF000000 | r<<16 | g<<8 | b` in little-endian memory.
|
||||
FUN_GAMETOOLTIP_BUILD_ITEM = 0x0052B650,
|
||||
// OnTooltipSetItem support. FUN_GAMETOOLTIP_SCRIPT_RESOLVER is the
|
||||
// CGGameTooltip vtable method (vtable 0x00808F60) that maps a script name
|
||||
// to its handler slot; __thiscall(self, const char *name) -> int* slot,
|
||||
// 0 if the name isn't a tooltip script. It first delegates to the base
|
||||
// frame resolver, then checks OnTooltipSetDefaultAnchor(+0x444) /
|
||||
// OnTooltipCleared(+0x44c) / OnTooltipAddMoney(+0x454) — each an 8-byte
|
||||
// {handler, context} slot. Vanilla has no OnTooltipSetItem, and the object
|
||||
// (alloc size 0x460) has no free 8-byte slot, so we co-hook this to hand
|
||||
// out a C-side per-tooltip cell for that name. FUN_FRAME_INVOKE_SCRIPT is
|
||||
// the engine's real script invoker __fastcall(handler /*ecx = slot[0]*/,
|
||||
// frame /*edx*/): it binds the global `this` = frame and runs the handler
|
||||
// under its own protected lua_pcall (0 args). We call it directly from the
|
||||
// item-builder co-hook to fire OnTooltipSetItem.
|
||||
// NOTE: the clear fires OnTooltipCleared via the wrapper FUN_00702690
|
||||
// (self, &slot), which additionally stamps the global exec-context
|
||||
// (DAT_00ceeac0) from slot[1]. That context mutation is only valid from
|
||||
// the engine's top-level frame-script dispatch — firing it from deep in a
|
||||
// nested Lua->C->Lua stack (e.g. an addon's SetAuctionItem wrapper)
|
||||
// corrupts the outer script's context and faults. So we skip the wrapper
|
||||
// and call the inner invoker, which is self-contained.
|
||||
FUN_GAMETOOLTIP_SCRIPT_RESOLVER = 0x005295D0,
|
||||
FUN_FRAME_INVOKE_SCRIPT = 0x00704D50,
|
||||
FUN_GAMETOOLTIP_ADD_LINE = 0x00530270, // __thiscall(self, left, right, lColorBGRA*, rColorBGRA*, wrap)
|
||||
OFF_GAMETOOLTIP_NUM_LINES = 0x31C, // int — live line count (AddLine index; +0x320 is the cap)
|
||||
// The displayed item's identity is read via the existing
|
||||
// OFF_TOOLTIP_ITEM_ID (+0x398) / OFF_TOOLTIP_ITEM_GUID_LO (+0x380) —
|
||||
// link paths set the itemID, CGItem paths (SetInventoryItem/…) set only
|
||||
// the GUID (see Tooltip::Compare::TooltipItemID and item/Tooltip.cpp).
|
||||
|
||||
// Line-shift primitives for prepending the grey "Currently Equipped"
|
||||
// header. The per-line CSimpleFontString objects live in the parallel
|
||||
// arrays at OFF_GAMETOOLTIP_TEXTLEFT/RIGHT_DESC (+8 = data). Each stores
|
||||
// its text buffer pointer at +0xF0 and its 4-byte {b,g,r,a} color behind
|
||||
// the pointer at +0xB8 (both verified from the setters below). We read a
|
||||
// line's text/color and re-apply them one slot down, then set line 0.
|
||||
FUN_FONTSTRING_SET_TEXT = 0x00771D80, // __thiscall(fs, text, flag=0)
|
||||
FUN_FONTSTRING_SET_COLOR = 0x0077F750, // __thiscall(fs, colorBGRA*)
|
||||
OFF_FONTSTRING_TEXT = 0xF0, // char* — current text buffer
|
||||
OFF_FONTSTRING_COLOR_PTR = 0xB8, // ptr → 4-byte {b,g,r,a} color storage
|
||||
// A line's FontString is only positioned once shown: set the desired
|
||||
// flag at +0xC4 then call SHOW (FUN_0077fcb0) / HIDE (FUN_0077fc60) —
|
||||
// the exact pair AddLine (FUN_00530270) and the clear use. Moving text
|
||||
// into a previously-empty (hidden) cell without this leaves it
|
||||
// unpositioned, so the line-shift must replicate it.
|
||||
FUN_FONTSTRING_SHOW = 0x0077FCB0, // __fastcall(fs) — realizes +0xC4
|
||||
FUN_FONTSTRING_HIDE = 0x0077FC60, // __fastcall(fs)
|
||||
OFF_FONTSTRING_SHOWN_FLAG = 0xC4, // int — desired-shown flag
|
||||
// The per-tooltip clear only HIDES line FontStrings (sets +0xC8 = 0)
|
||||
// and clears the left text; right-column text buffers are left intact.
|
||||
// So a shift must decide a cell's content by its actually-shown flag
|
||||
// (+0xC8), not by whether +0xF0 still holds (stale) text.
|
||||
OFF_FONTSTRING_VISIBLE = 0xC8, // int — actually-shown flag
|
||||
|
||||
// FontString creation primitives used by Tooltip::LinePool to build the
|
||||
// extra lines entirely in C++ (no addon Lua). Calling conventions and
|
||||
// offsets mirrored from Script_CreateFontString (0x00773C30),
|
||||
// Script_SetFontObject (0x0079D1A0 → 0x00770C60), and Script_SetPoint
|
||||
// (0x007A2540 → 0x00767C70) — see TODO #97's investigation update.
|
||||
FUN_GAMETOOLTIP_SETUP_LINES = 0x00529650, // vtable slot 9 — the pool scan we co-hook
|
||||
VAR_SIMPLEFONTSTRING_POOL = 0x00CF4D10, // CSimpleFontString free-list pool (allocator `this`)
|
||||
VAR_SIMPLEFONTSTRING_CLASS_TAG = 0x00846544, // ".?AVCSimpleFontString@@" (alloc debug tag)
|
||||
FUN_REGION_POOL_ALLOC = 0x00760450, // __thiscall(pool, zeroInit=0, tag, line=-2) -> raw mem
|
||||
FUN_SIMPLEFONTSTRING_CTOR = 0x00770D30, // __thiscall(mem, parent, layer, sublayer) -> fs
|
||||
FUN_REGION_SET_NAME = 0x0076C650, // __thiscall(region, name) — registers _G[name]
|
||||
FUN_FONTSTRING_SET_FONT = 0x00770C60, // __thiscall(fs + OFF_FONTSTRING_FONT_HOLDER, fontObject)
|
||||
FUN_REGION_SET_POINT = 0x00767C70, // __thiscall(region+OFF_REGION_ANCHOR, point, relAnchor, relPoint, x, y, flag=1)
|
||||
OFF_FONTSTRING_FONT_HOLDER = 0xCC, // font-reference sub-object (SetFont `this`)
|
||||
OFF_FONTSTRING_FONT_OBJECT = 0xD0, // font object pointer (holder + 4)
|
||||
OFF_REGION_ANCHOR = 0x24, // LayoutFrame anchor sub-object (SetPoint `this` / relativeTo base)
|
||||
DRAWLAYER_ARTWORK = 2,
|
||||
FRAMEPOINT_TOPLEFT = 0,
|
||||
FRAMEPOINT_LEFT = 3,
|
||||
FRAMEPOINT_RIGHT = 5,
|
||||
FRAMEPOINT_BOTTOMLEFT = 6,
|
||||
|
||||
// FUN_REGION_SET_POINT stores offsets in *internal* coordinates, not
|
||||
// pixels. Script_SetPoint converts: `internal = pixel * [0x00832A44] /
|
||||
// ([0x00832A4C] * 1024)` (FUN_0041ae60's factor × input ÷
|
||||
// (FUN_0041ad70's return × DAT_007ffd68)). Both globals are runtime
|
||||
// UI-scale floats; passing raw pixels makes offsets ~1000× too large.
|
||||
VAR_UI_COORD_SCALE_MUL = 0x00832A44, // float numerator
|
||||
VAR_UI_COORD_SCALE_DIV = 0x00832A4C, // float denominator base
|
||||
UI_COORD_SCALE_UNIT = 1024, // DAT_007ffd68
|
||||
|
||||
// "Currently displayed thing" state fields on a GameTooltip frame
|
||||
// instance. Each Set* path writes one of these (and zero or two
|
||||
// others), and the per-tooltip Clear at FUN_00530050 zeroes all of
|
||||
@@ -106,11 +221,32 @@ enum Offsets {
|
||||
// (gameobject GUID) at 0x0052AA52 / 0x0052AA59.
|
||||
// Only call site is the in-world hover handler
|
||||
// FUN_00492890; no Lua `SetGameObject` method.
|
||||
// - Clear (0x00530050) zeroes all of them.
|
||||
OFF_TOOLTIP_ITEM_GUID_LO = 0x380, // 0 for SetItemByID (no CGItem)
|
||||
// - Clear (FUN_GAMETOOLTIP_CLEAR) zeroes unit(+0x368)/GO(+0x370)/
|
||||
// itemID(+0x398)/spell(+0x39c) — but NOT the item GUID +0x380/+0x384.
|
||||
// That omission means the item GUID goes stale across a switch to a
|
||||
// tooltip that shows no item (SetUnitAura, SetEquipmentSet, …), so
|
||||
// GameTooltip:GetItem would resolve the *previous* item. We co-hook
|
||||
// the clear (Tooltip::ClearItemGuid) to zero +0x380/+0x384 too, so
|
||||
// every fresh tooltip resets it and only the item builder re-sets it.
|
||||
// All 14 Set*/builder paths route through this clear, so the co-hook
|
||||
// covers them uniformly. __fastcall(self).
|
||||
FUN_GAMETOOLTIP_CLEAR = 0x00530050,
|
||||
OFF_TOOLTIP_ITEM_GUID_LO = 0x380, // 0 for SetItemByID (no CGItem); stale-safe via the clear co-hook
|
||||
OFF_TOOLTIP_ITEM_GUID_HI = 0x384,
|
||||
OFF_TOOLTIP_ITEM_ID = 0x398,
|
||||
OFF_TOOLTIP_SPELL_ID = 0x39C,
|
||||
// Auction/compare descriptor. Script_GameTooltip_SetAuctionItem
|
||||
// (0x00535810) has no CGItem instance, so it stashes the listing's
|
||||
// random-property (suffix) id at tooltip+0x424 and marks the
|
||||
// compare-descriptor valid by writing the builder's compare flag to
|
||||
// this[0x110] (tooltip+0x440) = 1 (SetAuctionItem passes param_6=1;
|
||||
// every other Set* path passes 0, and the builder writes it on each
|
||||
// param_7==0 build — so +0x440 is a reliable per-build gate, not
|
||||
// stale). This is 1.12's analog of 3.3.5's `tooltip[0x130]`-gated
|
||||
// `piVar5[0x2d]` random-property read in GameTooltip:GetItem. GetItem
|
||||
// reads +0x424 (only when +0x440 is set) to put the suffix in the link.
|
||||
OFF_TOOLTIP_COMPARE_FLAG = 0x440,
|
||||
OFF_TOOLTIP_COMPARE_SUFFIX = 0x424,
|
||||
// Unit GUID written by the inner unit-tooltip builder
|
||||
// (FUN_00529FE0) when `tooltip:SetUnit(token)` resolves the token
|
||||
// to a non-zero GUID. Cleared by the same `FUN_00530050` clear
|
||||
@@ -253,6 +389,32 @@ enum Offsets {
|
||||
FUN_FIND_CVAR = 0x0063DEC0,
|
||||
OFF_CVAR_VALUE_STR = 0x20,
|
||||
|
||||
// Internal CVar registrar — what `Script_RegisterCVar` calls after a
|
||||
// `FindCVar` miss (the call at `0x00488B8A`). `__fastcall`; ECX=name,
|
||||
// EDX is a second string slot the script path leaves 0, then six
|
||||
// stack args: flags, defaultValue, changeCallback, categoryId,
|
||||
// hiddenBool, userData. Dedups by name (re-registering OR-merges
|
||||
// flags + updates the callback), so it's idempotent across `/reload`.
|
||||
// The new-cvar branch forces flags bit 0 on (`puVar3[7] = flags | 1`),
|
||||
// which is what makes script-registered cvars persist to Config.wtf.
|
||||
// See `CVar::Factory` for the wrapper.
|
||||
FUN_REGISTER_CVAR = 0x0063DB90,
|
||||
// Internal "apply value" — `__fastcall(cvar /*ecx*/, value, a3, a4,
|
||||
// a5, a6)`, called by `Script_SetCVar` at `0x00488CA8`. Fires the
|
||||
// change callback at `[cvar+0xBC]` as
|
||||
// `char __fastcall(cvar /*ecx*/, prevValue /*edx*/, newValue /*stack*/,
|
||||
// userData /*stack*/)` — return 0 to REJECT the change, nonzero to
|
||||
// accept (verified at `0x0063DF7D`).
|
||||
FUN_SET_CVAR_VALUE = 0x0063DF50,
|
||||
// CVar struct fields (beyond the value string at +0x20 above).
|
||||
OFF_CVAR_FLAGS = 0x1C,
|
||||
OFF_CVAR_CALLBACK = 0xBC,
|
||||
OFF_CVAR_USERDATA = 0xC0,
|
||||
// The categoryId the script path passes as the registrar's 6th stack
|
||||
// arg (the `PUSH 9` in `Script_RegisterCVar`). Cosmetic console
|
||||
// grouping; we reuse it so our cvars behave like script-registered ones.
|
||||
CVAR_SCRIPT_CATEGORY = 9,
|
||||
|
||||
// Engine-side Lua C functions backing the in-game CVar globals.
|
||||
// Standard `int __fastcall(void *L)` ABI. We don't register them
|
||||
// ourselves in-game — the engine already does at boot — but we
|
||||
@@ -706,6 +868,14 @@ enum Offsets {
|
||||
// nampower's SpellStartHandlerHook.
|
||||
FUN_SPELL_START_HANDLER = 0x006E7640,
|
||||
|
||||
// `SMSG_SPELL_DELAYED` handler — `int __stdcall(uint32_t *opCode,
|
||||
// CDataStore *packet)`. Body: `guid(u64), delayMs(u32)`. The server
|
||||
// only sends this to the affected caster, so in practice it's always
|
||||
// the local player's cast pushback (taking damage mid-cast). `Spell::
|
||||
// Cast` co-hooks it to extend the tracked cast's end time so the bar
|
||||
// reflects pushback. Mirrored from nampower's SpellDelayedHook.
|
||||
FUN_SPELL_DELAYED = 0x006E74F0,
|
||||
|
||||
// `CGUnit_C::OnAuraAdded` — `__thiscall void(CGUnit *unit, uint32_t
|
||||
// slot, uint32_t spellId)` (i.e. `__fastcall(unit /*ecx*/, edx_unused,
|
||||
// slot, spellId)`). Fires for EVERY aura that lands on a tracked unit,
|
||||
@@ -725,6 +895,18 @@ enum Offsets {
|
||||
// re-stamp expiration so stacking-DoT refreshes are picked up.
|
||||
FUN_ON_AURA_STACKS_CHANGED = 0x00612450,
|
||||
|
||||
// `CGUnit_C::OnAuraRemoved` — same ABI as `OnAuraAdded`
|
||||
// (`__fastcall(unit /*ecx*/, edx_unused, slot, spellId)`; the disassembly
|
||||
// of the diff dispatcher `FUN_00604d00` at the call site `0x00604dc4`
|
||||
// shows `ECX = unit`, stack `[slot, spellId]`). The sibling of
|
||||
// `OnAuraAdded`: `FUN_00604d00` fires this when a descriptor aura slot
|
||||
// goes from occupied to empty — a genuine removal (fell off, dispelled,
|
||||
// or replaced by a higher rank, which fires Removed(old)+Added(new)).
|
||||
// `Aura::Source` co-hooks it to EVICT the cached entry so the
|
||||
// `GetAuraDataByIndex` fallback can't resurrect a superseded/dispelled
|
||||
// aura that's still inside its computed duration window.
|
||||
FUN_ON_AURA_REMOVED = 0x00612320,
|
||||
|
||||
// CGPlayer-side sub-struct, allocated for any player-controlled
|
||||
// unit (local self, target, party, raid, inspect targets — all of
|
||||
// them). Holds player-specific data that's *not* in the broadcast
|
||||
@@ -999,6 +1181,13 @@ enum Offsets {
|
||||
// descriptor bytes for a worn-and-bound item.
|
||||
OFF_DESCRIPTOR_FLAGS = 0x3C,
|
||||
ITEM_FLAG_SOULBOUND = 0x01,
|
||||
// Within the descriptor, the item's random-property index
|
||||
// (ITEM_FIELD_RANDOM_PROPERTIES_ID) is at +0x98 — this is the live
|
||||
// instance's suffix, indexing ItemRandomProperties.dbc the same way
|
||||
// StatAccum::ApplyRandomSuffix expects. Derived from the item-tooltip
|
||||
// builder's `[descriptor + 0x26*4]` read (FUN_0052B650 @ ~0x52b7xx),
|
||||
// which feeds it straight into `ItemRandomProperties[idx]`.
|
||||
OFF_DESCRIPTOR_RANDOM_PROPERTY = 0x98,
|
||||
// Bit 2 — instance is "unlocked", i.e. the lock referenced by
|
||||
// `ItemStats.LockID` has been opened (rogue Pick Lock, key item,
|
||||
// etc.). For unlockable items, the engine gates the
|
||||
@@ -1407,6 +1596,17 @@ enum Offsets {
|
||||
OFF_ITEMSUBCLASS_RECORD_STRIDE = 0x74,
|
||||
OFF_ITEMSUBCLASS_NAME = 0x28,
|
||||
OFF_ITEMSUBCLASS_DISPLAY_NAME = 0x4C,
|
||||
// record +0x00 = classID, +0x04 = subClassID (the compound key the
|
||||
// linear scan matches on). Flags field at +0x10; bit 0x200 marks the
|
||||
// subclasses whose items display by inventory slot rather than by
|
||||
// subclass name — set on exactly the armor material types (Misc / Cloth
|
||||
// / Leather / Mail / Plate), clear on weapons, shields, librams, etc.
|
||||
// This is `C_Item.GetItemSubClassInfo`'s `subClassUsesInvType` return.
|
||||
// Derived by dumping ItemSubClass.dbc (see docs/DBCs.md dump oracle).
|
||||
OFF_ITEMSUBCLASS_CLASS_ID = 0x00,
|
||||
OFF_ITEMSUBCLASS_SUBCLASS_ID = 0x04,
|
||||
OFF_ITEMSUBCLASS_FLAGS = 0x10,
|
||||
ITEMSUBCLASS_FLAG_USES_INVTYPE = 0x200,
|
||||
|
||||
// ItemDisplayInfo.dbc — standard layout. Icon path char* at record +0x14
|
||||
// (per the helper at 0x005D88B0 that Script_GetItemInfo uses).
|
||||
@@ -1631,6 +1831,19 @@ enum Offsets {
|
||||
OFF_UNIT_DESCRIPTOR_CLASS_BYTE = 0x79,
|
||||
OFF_UNIT_DESCRIPTOR_SEX_BYTE = 0x7A,
|
||||
|
||||
// The local player's UNIT_FIELD_BYTES_0 race/class/sex bytes, mirrored
|
||||
// into a login-time global that is populated at character-enter —
|
||||
// BEFORE the in-world CGUnit/descriptor exists. Script_UnitClass
|
||||
// (0x00518350) and Script_UnitRace special-case the literal "player"
|
||||
// token to read these (Script_UnitClass calls FUN_005abde0 →
|
||||
// `return DAT_00c27e81`), which is why UnitClass("player") resolves at
|
||||
// addon-load while a descriptor read returns nil until the player
|
||||
// object spawns. Getters: race FUN_005abdd0, class FUN_005abde0,
|
||||
// sex FUN_005abdf0.
|
||||
VAR_PLAYER_RACE_BYTE = 0x00C27E80,
|
||||
VAR_PLAYER_CLASS_BYTE = 0x00C27E81,
|
||||
VAR_PLAYER_SEX_BYTE = 0x00C27E82,
|
||||
|
||||
// SkillLineAbility.dbc — maps each (class, race) pair to its
|
||||
// learnable spell list with skill-rank gating. Indexed by record
|
||||
// ID; reads via the standard `records[id]` pattern. Used by
|
||||
@@ -2365,6 +2578,18 @@ enum Offsets {
|
||||
// `FUN_006E3D10`. Non-zero means "the cast bar is showing this
|
||||
// spell"; cleared to 0 when the cast finishes or is cancelled.
|
||||
VAR_CURRENT_CAST_SPELL = 0x00CECA88,
|
||||
// The cast-start state writer — `__fastcall(int spellID, int
|
||||
// targetState)`. Sets `VAR_CURRENT_CAST_SPELL` (pushing any current
|
||||
// spell into `VAR_QUEUED_CAST_SPELL`; `spellID == 0` restores the queued
|
||||
// one). `Spell::Cast` co-hooks it for lag-free, client-side detection of
|
||||
// NORMAL player casts (stamps from the spellID arg before the original).
|
||||
// It does NOT fire for a chained same-spell recast: the caller
|
||||
// `Spell_C_CastSpell` (`0x006E4B60`) short-circuits at `spellID ==
|
||||
// VAR_CURRENT_CAST_SPELL` *before* reaching here, so those never run the
|
||||
// client cast path — they're caught by the `SMSG_SPELL_START` backstop
|
||||
// instead. nampower hooks the higher Spell_C_CastSpell, not this inner
|
||||
// writer, so contention is low.
|
||||
FUN_CAST_START_SET = 0x006E4AD0,
|
||||
// Previous / queued cast — holds the spellID that was active
|
||||
// before the latest one superseded it (mid-GCD queueing in
|
||||
// vanilla). When the current cast ends, `FUN_006E4AD0(0, ...)`
|
||||
@@ -2556,6 +2781,22 @@ enum Offsets {
|
||||
OFF_SPELLITEMENCHANT_ARG = 0x28, // int EffectArg[3]
|
||||
OFF_SPELLITEMENCHANT_NAME = 0x34, // char *name[8], locale-indexed
|
||||
|
||||
// ItemRandomProperties.dbc — the table a random-suffix ID (the third
|
||||
// field of an `item:id:enchant:suffix:unique` link) indexes to get
|
||||
// the SpellItemEnchantment IDs that apply the "of the Bear"-style
|
||||
// bonus. Standard 5-DWORD DBC instance at 0x00C0DBCC; records-ptr at
|
||||
// +0x08, count at +0x0C (see docs/DBCs.md). Verified by parsing the
|
||||
// on-disk ItemRandomProperties.dbc: 16-field / 0x40 records, field 0
|
||||
// = ID, field 1 = internal name string, and the enchant IDs occupy
|
||||
// fields 2..6 (offset +0x08, five contiguous u32 slots — only the
|
||||
// first few are used; the rest are 0). Field 7 duplicates the name
|
||||
// string offset, so it is NOT an enchant slot — do not read past
|
||||
// slot 5.
|
||||
VAR_ITEMRANDOMPROP_RECORDS = 0x00C0DBD4, // ItemRandomPropertiesRecord *records[suffixID]
|
||||
VAR_ITEMRANDOMPROP_COUNT = 0x00C0DBD8, // max suffix ID
|
||||
OFF_ITEMRANDOMPROP_ENCHANT = 0x08, // u32 Enchantment[5]
|
||||
ITEMRANDOMPROP_ENCHANT_SLOT_COUNT = 5,
|
||||
|
||||
// Spell.dbc School field — 0-based integer at record +0x04.
|
||||
// Verified empirically against Fireball (133) → School=2 (Fire)
|
||||
// and Frostbolt (116) → School=4 (Frost) on Octo 1.12.1. Vanilla
|
||||
@@ -4004,6 +4245,22 @@ enum Offsets {
|
||||
OFF_SPELL_RECORD_EFFECT_MISC_VALUE = 0x1A8, // int32[3]
|
||||
SPELL_RECORD_EFFECT_COUNT = 3,
|
||||
|
||||
// EffectBasePoints[3] — the base magnitude of each effect, stored as
|
||||
// (value - 1) for the fixed-die spells that back item stats (the
|
||||
// engine adds a 1..dieSides roll; dieSides == 1 makes it value = base
|
||||
// + 1). Verified empirically: the "Increased Intellect 01/02/03"
|
||||
// random-property spells (7468/7469/7470) hold base 0/1/2 for the
|
||||
// +1/+2/+3 tiers. Read by Item::Stats when resolving random-suffix
|
||||
// stat auras. Parallel [3] array to APPLY_AURA_NAME / MISC_VALUE.
|
||||
OFF_SPELL_RECORD_EFFECT_BASE_POINTS = 0x130, // int32[3]
|
||||
|
||||
// EffectBaseDice[3] — added to EffectBasePoints for the effect's fixed
|
||||
// magnitude (mangos `CalculateSimpleValue = BasePoints + BaseDice`).
|
||||
// For every item-stat aura BaseDice == 1, so value = BasePoints + 1;
|
||||
// reading it directly matches the engine exactly. Verified at field 67
|
||||
// (Effect@61, DieSides@64, BaseDice@67, BasePoints@76) against 7468.
|
||||
OFF_SPELL_RECORD_EFFECT_BASE_DICE = 0x10C, // int32[3]
|
||||
|
||||
// Per-effect EffectRadiusIndex[3] → SpellRadius.dbc. Verified by
|
||||
// FUN_006e6350, which reads spellRec[+0x160] (effect 0) and
|
||||
// spellRec[+0x164] (effect 1) as radius indices. 0 = effect has no
|
||||
@@ -4173,6 +4430,29 @@ enum Offsets {
|
||||
VAR_GLUE_LOGIN_READY1 = 0x00B41DFC,
|
||||
VAR_GLUE_LOGIN_READY2 = 0x00B41E04,
|
||||
VAR_GLUE_LOGIN_INPROGRESS = 0x00B41DA0,
|
||||
// The same `VAR_GLUE_LOGIN_INPROGRESS` global doubles as a glue
|
||||
// state-code: `FUN_GLUE_ENTER_WORLD` sets it to `8` ("entering world")
|
||||
// on a successful commit, which `Unit::Identity`'s enter-world co-hook
|
||||
// gates on (the rename / char-locked bail paths return before it).
|
||||
GLUE_STATE_ENTERING_WORLD = 8,
|
||||
|
||||
// `FUN_0046B500` — the enter-world worker behind `Script_EnterWorld` (the
|
||||
// glue "Enter World" button: `Script_EnterWorld` is just `call this; ret`).
|
||||
// Computes the selected character's struct into VAR_GLUE_SELECTED_CHAR and,
|
||||
// on success, sets VAR_GLUE_LOGIN_INPROGRESS = 8. `Unit::Identity` co-hooks
|
||||
// it to capture the selected character's GUID *before* the engine creates
|
||||
// the in-world player object — so `UnitGUID("player")` / `PlayerGuid()`
|
||||
// answer from addon-load time instead of returning nil/0 until the
|
||||
// SMSG_UPDATE_OBJECT that populates the player object (≈PLAYER_LOGIN).
|
||||
FUN_GLUE_ENTER_WORLD = 0x0046B500,
|
||||
|
||||
// Selected-character struct pointer (glue): char-array base +
|
||||
// selectedIndex*0x120, written by FUN_GLUE_ENTER_WORLD. The character's
|
||||
// 64-bit login GUID is at offset 0x00 (name at +0x08, race +0x100, class
|
||||
// +0x101, level +0x108 — verified against `Script_GetCharacterInfo` at
|
||||
// `0x004732A0`). Entries are filled from SMSG_CHAR_ENUM.
|
||||
VAR_GLUE_SELECTED_CHAR = 0x00B41DF4,
|
||||
OFF_GLUE_CHAR_GUID = 0x00,
|
||||
|
||||
// Cursor state — single global type-tag at VAR_CURSOR_TYPE
|
||||
// dispatches reads through one of several payload slots depending
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// `GetActionInfo(slot)` — modern-WoW-style action descriptor lookup.
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// Embedded `!!!ClassicAPI` addon fallback. When the user doesn't have
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// `C_AddOns.*` convenience wrappers. Modern WoW splits the legacy
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// `CLASSIC_API_VERSION` global — a single integer addons can read for
|
||||
|
||||
+12
-5
@@ -1,12 +1,12 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
// `C_UnitAuras.*` — modern aura-data namespace. Returns AuraData
|
||||
// tables built by `Aura::Data::Push` (see `Data.h`). The fields the
|
||||
@@ -92,11 +92,16 @@ int PushAuraByIndex(void *L, const char *unitToken, int index,
|
||||
Data::Filter filter, bool playerOnly = false) {
|
||||
const uint8_t *unit = ResolveUnit(unitToken);
|
||||
const int slot = Data::FindNthSlot(unit, index, filter, playerOnly);
|
||||
if (slot < 0) {
|
||||
Game::Lua::PushNil(L);
|
||||
if (slot >= 0) {
|
||||
Data::Push(L, unit, slot);
|
||||
return 1;
|
||||
}
|
||||
Data::Push(L, unit, slot);
|
||||
// Descriptor exhausted — an aura the engine dropped from the slot array
|
||||
// (rogue stealth, party range fluctuation) may still be live in the
|
||||
// Aura::Source cache. Surface it after the descriptor entries.
|
||||
if (Data::PushNthCacheFallback(L, unit, index, filter, playerOnly))
|
||||
return 1;
|
||||
Game::Lua::PushNil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -218,6 +223,8 @@ void AppendRangeToArray(void *L, const uint8_t *unit, int outerIdx,
|
||||
Data::Push(L, unit, slot);
|
||||
Game::Lua::SetTable(L, outerIdx);
|
||||
}
|
||||
// Append auras the descriptor dropped but Aura::Source still has live.
|
||||
Data::AppendCacheFallbacks(L, unit, filter, playerOnly, outerIdx, nextKey);
|
||||
}
|
||||
|
||||
int __fastcall Script_GetUnitAuras(void *L) {
|
||||
|
||||
+189
-85
@@ -1,12 +1,12 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
// Aura-table primitives. See `Data.h` for the contract; see `Api.cpp`
|
||||
// for the Lua-binding surface that consumes these.
|
||||
@@ -350,10 +350,13 @@ const char *DispelName(uint32_t dispelTypeID) {
|
||||
return (name == nullptr || *name == '\0') ? nullptr : name;
|
||||
}
|
||||
|
||||
void Push(void *L, const uint8_t *unit, int slot) {
|
||||
const uint32_t spellID = ReadSpellID(unit, slot);
|
||||
// Writes the full modern AuraData table on top of the Lua stack from
|
||||
// already-resolved values. Shared by the descriptor path (`Push`) and the
|
||||
// cache-fallback path (`PushFromCache`). Net stack effect: +1 (the table).
|
||||
static void BuildTable(void *L, uint32_t spellID, int applications,
|
||||
bool isHelpful, double duration, double expirationTime,
|
||||
uint64_t casterGuid) {
|
||||
const uint8_t *spellRecord = SpellRecord(spellID);
|
||||
const bool isHelpful = slot < Offsets::UNIT_AURA_BUFF_COUNT;
|
||||
|
||||
uint32_t dispelTypeID = 0;
|
||||
if (spellRecord != nullptr) {
|
||||
@@ -370,87 +373,32 @@ void Push(void *L, const uint8_t *unit, int slot) {
|
||||
Game::Lua::SetFieldString(L, "name", name);
|
||||
Game::Lua::SetFieldString(L, "icon", icon);
|
||||
Game::Lua::SetFieldNumber(L, "applications",
|
||||
static_cast<double>(ReadStacks(unit, slot)));
|
||||
static_cast<double>(applications));
|
||||
Game::Lua::SetFieldNumber(L, "spellId", static_cast<double>(spellID));
|
||||
Game::Lua::SetFieldString(L, "dispelName", dispel);
|
||||
Game::Lua::SetFieldBool(L, "isHelpful", isHelpful);
|
||||
Game::Lua::SetFieldBool(L, "isHarmful", !isHelpful);
|
||||
|
||||
// Timing fields. Vanilla doesn't broadcast cast time / duration
|
||||
// for ANY unit's auras except the local player's — for everyone
|
||||
// else (target, party, raid, mouseover) `expirationTime` stays 0
|
||||
// and addons have to track expiry themselves via aura-add events.
|
||||
// For the player we read the engine's `VAR_PLAYER_BUFF_TABLE`
|
||||
// (same data `GetPlayerBuffTimeLeft` returns), which gives us a
|
||||
// real expiration timestamp.
|
||||
//
|
||||
// `duration` comes from Spell.dbc → SpellDuration.dbc with
|
||||
// level scaling. That's the *base* value; talent / glyph
|
||||
// duration-extension modifiers (Improved PW:F, etc.) are
|
||||
// already baked into the expiration timestamp on the
|
||||
// caster's side, so `expirationTime - GetTime()` reflects the
|
||||
// true remaining time even when `duration` doesn't include
|
||||
// the talent boost. We populate `duration` for any unit (the
|
||||
// base value is identical regardless of who's affected); only
|
||||
// `expirationTime` is player-gated.
|
||||
double duration = 0.0;
|
||||
double expirationTime = 0.0;
|
||||
const uint8_t *player = LocalPlayer();
|
||||
if (spellID != 0) {
|
||||
const int unitLevel = (unit != nullptr) ? PlayerLevel(unit) : 0;
|
||||
duration = SpellBaseDurationSeconds(spellID, unitLevel);
|
||||
}
|
||||
if (unit != nullptr && unit == player) {
|
||||
const uint8_t *entry = FindPlayerBuffEntry(spellID);
|
||||
if (entry != nullptr)
|
||||
expirationTime = PlayerBuffExpirationSeconds(entry);
|
||||
}
|
||||
|
||||
// Caster + non-player expiration from the SMSG_SPELL_GO cache
|
||||
// (`Aura::Source`), captured at cast time. The vanilla descriptor has
|
||||
// neither. `sourceUnit` applies to any unit; `expirationTime` only
|
||||
// fills in here when the player-buff table above didn't — that table is
|
||||
// authoritative for the player's own auras, the cache covers everyone
|
||||
// else. Both are best-effort: a miss (aura predates login, or the cast
|
||||
// wasn't observed) leaves the modern-truthful defaults untouched.
|
||||
const char *sourceUnit = nullptr;
|
||||
const char *sourceGUID = nullptr;
|
||||
char tokenBuf[32];
|
||||
char guidBuf[Guid::STRING_SIZE];
|
||||
if (spellID != 0) {
|
||||
uint64_t casterGuid = 0;
|
||||
uint32_t expMs = 0;
|
||||
uint32_t durMs = 0;
|
||||
if (Aura::Source::Get(UnitGuid(unit), spellID, &casterGuid, &expMs,
|
||||
&durMs)) {
|
||||
if (expirationTime == 0.0 && expMs != 0)
|
||||
expirationTime = static_cast<double>(expMs) * 0.001;
|
||||
// Prefer the applied (caster-modified) duration so `duration`
|
||||
// stays consistent with `expirationTime` — otherwise a talented
|
||||
// DoT (e.g. Improved Shadow Word: Pain) shows remaining time
|
||||
// exceeding the base `duration`.
|
||||
if (durMs != 0)
|
||||
duration = static_cast<double>(durMs) * 0.001;
|
||||
if (casterGuid != 0) {
|
||||
// `sourceUnit` is a token (nil when the caster maps to no
|
||||
// current token); `sourceGUID` is the raw "0x..." GUID and
|
||||
// is set whenever we have a caster — a ClassicAPI extension
|
||||
// (not in retail AuraData) that survives the caster leaving
|
||||
// token range and doubles as a unit token under SuperWoW.
|
||||
sourceUnit = Unit::Identity::TokenFromGUID(
|
||||
casterGuid, tokenBuf, sizeof tokenBuf);
|
||||
sourceGUID = Guid::FormatAsString(casterGuid, guidBuf,
|
||||
sizeof guidBuf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Game::Lua::SetFieldNumber(L, "duration", duration);
|
||||
Game::Lua::SetFieldNumber(L, "expirationTime", expirationTime);
|
||||
if (sourceUnit != nullptr)
|
||||
Game::Lua::SetFieldString(L, "sourceUnit", sourceUnit);
|
||||
if (sourceGUID != nullptr)
|
||||
Game::Lua::SetFieldString(L, "sourceGUID", sourceGUID);
|
||||
|
||||
if (casterGuid != 0) {
|
||||
// `sourceUnit` is a token (nil when the caster maps to no current
|
||||
// token); `sourceGUID` is the raw "0x..." GUID and is set whenever we
|
||||
// have a caster — a ClassicAPI extension (not in retail AuraData) that
|
||||
// survives the caster leaving token range and doubles as a unit token
|
||||
// under SuperWoW.
|
||||
char tokenBuf[32];
|
||||
char guidBuf[Guid::STRING_SIZE];
|
||||
const char *sourceUnit = Unit::Identity::TokenFromGUID(
|
||||
casterGuid, tokenBuf, sizeof tokenBuf);
|
||||
const char *sourceGUID =
|
||||
Guid::FormatAsString(casterGuid, guidBuf, sizeof guidBuf);
|
||||
if (sourceUnit != nullptr)
|
||||
Game::Lua::SetFieldString(L, "sourceUnit", sourceUnit);
|
||||
if (sourceGUID != nullptr)
|
||||
Game::Lua::SetFieldString(L, "sourceGUID", sourceGUID);
|
||||
}
|
||||
|
||||
Game::Lua::SetFieldNumber(L, "charges", 0);
|
||||
Game::Lua::SetFieldNumber(L, "maxCharges", 0);
|
||||
Game::Lua::SetFieldNumber(L, "timeMod", 1);
|
||||
@@ -466,11 +414,167 @@ void Push(void *L, const uint8_t *unit, int slot) {
|
||||
Game::Lua::SetFieldBool(L, "shouldConsolidate", false);
|
||||
Game::Lua::SetFieldBool(L, "isRaid", false);
|
||||
|
||||
// `sourceUnit` / `sourceGUID` are set above when the `Aura::Source`
|
||||
// cache has a caster for this aura; left unset (→ nil) on a miss.
|
||||
// `auraInstanceID` and `points` are deliberately omitted — modern
|
||||
// returns nil for those when they don't apply, and Lua reading a
|
||||
// missing key yields nil, so the table doesn't need an explicit entry.
|
||||
// `auraInstanceID` and `points` are deliberately omitted — modern returns
|
||||
// nil for those when they don't apply, and Lua reading a missing key
|
||||
// yields nil, so the table doesn't need an explicit entry.
|
||||
}
|
||||
|
||||
void Push(void *L, const uint8_t *unit, int slot) {
|
||||
const uint32_t spellID = ReadSpellID(unit, slot);
|
||||
const bool isHelpful = slot < Offsets::UNIT_AURA_BUFF_COUNT;
|
||||
|
||||
// Timing fields. Vanilla doesn't broadcast cast time / duration for ANY
|
||||
// unit's auras except the local player's — for everyone else (target,
|
||||
// party, raid, mouseover) `expirationTime` stays 0 unless the
|
||||
// `Aura::Source` cache observed the cast. For the player we read the
|
||||
// engine's `VAR_PLAYER_BUFF_TABLE` (same data `GetPlayerBuffTimeLeft`
|
||||
// returns), which gives a real expiration timestamp.
|
||||
//
|
||||
// `duration` comes from Spell.dbc → SpellDuration.dbc with level scaling
|
||||
// (the *base* value); talent / glyph duration-extension modifiers are
|
||||
// already baked into the expiration timestamp on the caster's side, so
|
||||
// `expirationTime - GetTime()` reflects true remaining time even when the
|
||||
// base `duration` doesn't include the talent boost.
|
||||
double duration = 0.0;
|
||||
double expirationTime = 0.0;
|
||||
uint64_t casterGuid = 0;
|
||||
const uint8_t *player = LocalPlayer();
|
||||
if (spellID != 0) {
|
||||
const int unitLevel = (unit != nullptr) ? PlayerLevel(unit) : 0;
|
||||
duration = SpellBaseDurationSeconds(spellID, unitLevel);
|
||||
}
|
||||
if (unit != nullptr && unit == player) {
|
||||
const uint8_t *entry = FindPlayerBuffEntry(spellID);
|
||||
if (entry != nullptr)
|
||||
expirationTime = PlayerBuffExpirationSeconds(entry);
|
||||
}
|
||||
// Caster + non-player expiration from the SMSG_SPELL_GO cache, captured at
|
||||
// cast time (the descriptor has neither). The player-buff table above is
|
||||
// authoritative for the player's own expiration; the cache fills it for
|
||||
// everyone else. Prefer the applied (caster-modified) duration so it stays
|
||||
// consistent with `expirationTime` — otherwise a talented DoT (Improved
|
||||
// Shadow Word: Pain) would show remaining time exceeding the base.
|
||||
if (spellID != 0) {
|
||||
uint64_t c = 0;
|
||||
uint32_t expMs = 0;
|
||||
uint32_t durMs = 0;
|
||||
if (Aura::Source::Get(UnitGuid(unit), spellID, &c, &expMs, &durMs)) {
|
||||
if (expirationTime == 0.0 && expMs != 0)
|
||||
expirationTime = static_cast<double>(expMs) * 0.001;
|
||||
if (durMs != 0)
|
||||
duration = static_cast<double>(durMs) * 0.001;
|
||||
casterGuid = c;
|
||||
}
|
||||
}
|
||||
|
||||
BuildTable(L, spellID, ReadStacks(unit, slot), isHelpful, duration,
|
||||
expirationTime, casterGuid);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
// Builds an AuraData table from an `Aura::Source` cache entry — the fallback
|
||||
// when the descriptor has dropped the aura's slot. Stack count isn't broadcast
|
||||
// in SMSG_SPELL_GO, so `applications` defaults to 1. `duration` uses the
|
||||
// applied (caster-modified) ms when known, else the Spell.dbc base.
|
||||
void PushFromCache(void *L, const uint8_t *unit,
|
||||
const Aura::Source::CachedAura &c, bool isHelpful) {
|
||||
double duration = 0.0;
|
||||
if (c.durationMs != 0) {
|
||||
duration = static_cast<double>(c.durationMs) * 0.001;
|
||||
} else {
|
||||
const int unitLevel = (unit != nullptr) ? PlayerLevel(unit) : 0;
|
||||
duration = SpellBaseDurationSeconds(c.spellId, unitLevel);
|
||||
}
|
||||
const double expirationTime =
|
||||
(c.expirationMs != 0) ? static_cast<double>(c.expirationMs) * 0.001 : 0.0;
|
||||
BuildTable(L, c.spellId, 1, isHelpful, duration, expirationTime,
|
||||
c.casterGuid);
|
||||
}
|
||||
|
||||
// Counts populated descriptor slots matching `filter` (and `playerOnly`).
|
||||
int CountSlots(const uint8_t *unit, Filter filter, bool playerOnly) {
|
||||
if (unit == nullptr)
|
||||
return 0;
|
||||
const int start = (filter == Filter::Harmful)
|
||||
? Offsets::UNIT_AURA_BUFF_COUNT
|
||||
: 0;
|
||||
const int end = (filter == Filter::Harmful) ? Offsets::UNIT_AURA_TOTAL
|
||||
: Offsets::UNIT_AURA_BUFF_COUNT;
|
||||
int n = 0;
|
||||
for (int slot = start; slot < end; ++slot) {
|
||||
if (!IsSlotPopulated(unit, slot))
|
||||
continue;
|
||||
if (playerOnly && !IsPlayerCast(unit, slot))
|
||||
continue;
|
||||
++n;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
constexpr int kFallbackMax = Offsets::UNIT_AURA_TOTAL;
|
||||
|
||||
// Whether cache entry `c` should be surfaced as a fallback for `unit` under
|
||||
// `filter`/`playerOnly`: it must not already be in a populated descriptor slot
|
||||
// (no double-listing the same live aura) and, when player-filtered, must have
|
||||
// been cast by us. Superseded / dispelled auras are kept out of the cache by
|
||||
// `Aura::Source`'s removal eviction, not filtered here.
|
||||
bool FallbackEligible(const uint8_t *unit, const Aura::Source::CachedAura &c,
|
||||
Filter filter, bool playerOnly) {
|
||||
if (FindSlotBySpellID(unit, c.spellId, &filter, false) >= 0)
|
||||
return false; // still in the descriptor — returned via the slot path
|
||||
if (playerOnly && c.casterGuid != Unit::Identity::PlayerGuid())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool PushNthCacheFallback(void *L, const uint8_t *unit, int oneBasedIndex,
|
||||
Filter filter, bool playerOnly) {
|
||||
if (unit == nullptr)
|
||||
return false;
|
||||
// The descriptor held `descCount` matches; the caller already found fewer
|
||||
// than `oneBasedIndex` there, so the cache supplies index
|
||||
// `oneBasedIndex - descCount` (1-based) of the entries it didn't.
|
||||
const int target = oneBasedIndex - CountSlots(unit, filter, playerOnly);
|
||||
if (target < 1)
|
||||
return false;
|
||||
const uint64_t guid = UnitGuid(unit);
|
||||
if (guid == 0)
|
||||
return false;
|
||||
Aura::Source::CachedAura buf[kFallbackMax];
|
||||
const int n = Aura::Source::Enumerate(
|
||||
guid, filter == Filter::Harmful, buf, kFallbackMax);
|
||||
int seen = 0;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (!FallbackEligible(unit, buf[i], filter, playerOnly))
|
||||
continue;
|
||||
if (++seen == target) {
|
||||
PushFromCache(L, unit, buf[i], filter == Filter::Helpful);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void AppendCacheFallbacks(void *L, const uint8_t *unit, Filter filter,
|
||||
bool playerOnly, int outerIdx, int &nextKey) {
|
||||
if (unit == nullptr)
|
||||
return;
|
||||
const uint64_t guid = UnitGuid(unit);
|
||||
if (guid == 0)
|
||||
return;
|
||||
Aura::Source::CachedAura buf[kFallbackMax];
|
||||
const int n = Aura::Source::Enumerate(
|
||||
guid, filter == Filter::Harmful, buf, kFallbackMax);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (!FallbackEligible(unit, buf[i], filter, playerOnly))
|
||||
continue;
|
||||
Game::Lua::PushNumber(L, static_cast<double>(nextKey++));
|
||||
PushFromCache(L, unit, buf[i], filter == Filter::Helpful);
|
||||
Game::Lua::SetTable(L, outerIdx);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Aura::Data
|
||||
|
||||
+22
-2
@@ -1,12 +1,12 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -112,4 +112,24 @@ const char *DispelName(uint32_t dispelTypeID);
|
||||
// Net stack effect: +1 (the table).
|
||||
void Push(void *L, const uint8_t *unit, int slot);
|
||||
|
||||
// Fallback for the index path when the descriptor has dropped an aura's slot
|
||||
// (rogue stealth, party range fluctuation) but it's still active server-side.
|
||||
// `oneBasedIndex` is the same index the caller passed to `FindNthSlot`; this
|
||||
// resolves it against the `Aura::Source` cache *after* the descriptor matches
|
||||
// (so cache entries append after descriptor ones, preserving existing index
|
||||
// order). On a hit it pushes the AuraData table and returns true; on a miss it
|
||||
// pushes nothing and returns false (caller pushes nil). Only entries whose
|
||||
// helpful/harmful classification matches `filter` and that aren't already in a
|
||||
// populated descriptor slot are considered.
|
||||
bool PushNthCacheFallback(void *L, const uint8_t *unit, int oneBasedIndex,
|
||||
Filter filter, bool playerOnly = false);
|
||||
|
||||
// Appends every eligible `Aura::Source` cache fallback for `unit` matching
|
||||
// `filter` into the array table at `outerIdx`, continuing from `nextKey`
|
||||
// (updated in place). The bulk-enumeration analog of `PushNthCacheFallback`,
|
||||
// for `GetUnitAuras`. Skips entries already present in a populated descriptor
|
||||
// slot so it never double-lists.
|
||||
void AppendCacheFallbacks(void *L, const uint8_t *unit, Filter filter,
|
||||
bool playerOnly, int outerIdx, int &nextKey);
|
||||
|
||||
} // namespace Aura::Data
|
||||
|
||||
+92
-12
@@ -1,12 +1,12 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
// See `Source.h` for the contract. This is the backend: a co-hook on
|
||||
// `FUN_SPELL_GO` that mirrors nampower's `SpellGoHook` parse to capture the
|
||||
@@ -69,12 +69,19 @@ uint32_t SpellDurationMs(const uint8_t *spellRecord, bool casterIsPlayer) {
|
||||
|
||||
// ---- Cache ---------------------------------------------------------------
|
||||
|
||||
// Helpful/harmful classification, recorded from the aura's descriptor slot
|
||||
// when it's applied (the only place the buff/debuff split is known). SpellGo
|
||||
// gives no slot, so casts we only saw there stay Unknown until/unless an
|
||||
// application hook fires for the same aura.
|
||||
enum Kind : int8_t { KIND_UNKNOWN = -1, KIND_HELPFUL = 0, KIND_HARMFUL = 1 };
|
||||
|
||||
struct Entry {
|
||||
uint64_t targetGuid;
|
||||
uint64_t casterGuid;
|
||||
uint32_t spellId;
|
||||
uint32_t expirationMs; // 0 = infinite / unknown duration
|
||||
uint32_t durationMs; // applied duration (incl. caster mods); 0 = none
|
||||
int8_t kind; // Kind; descriptor-slot-derived, KIND_UNKNOWN if only seen via SpellGo
|
||||
bool used;
|
||||
};
|
||||
|
||||
@@ -88,13 +95,19 @@ int g_writeCursor = 0;
|
||||
// would replace talented timing with the unmodified base), so it skips
|
||||
// entries that already carry a caster.
|
||||
void Store(uint64_t targetGuid, uint32_t spellId, uint64_t casterGuid,
|
||||
uint32_t expirationMs, uint32_t durationMs, bool fromCast) {
|
||||
uint32_t expirationMs, uint32_t durationMs, bool fromCast,
|
||||
int8_t kind) {
|
||||
if (targetGuid == 0 || spellId == 0)
|
||||
return;
|
||||
|
||||
// Update an existing entry for this exact aura instance.
|
||||
for (auto &e : g_cache) {
|
||||
if (e.used && e.targetGuid == targetGuid && e.spellId == spellId) {
|
||||
// Learn the classification whenever a slot-derived kind arrives —
|
||||
// independent of caster/timing ownership, and never downgrade a
|
||||
// known kind back to unknown.
|
||||
if (kind != KIND_UNKNOWN)
|
||||
e.kind = kind;
|
||||
if (!fromCast && e.casterGuid != 0)
|
||||
return; // SpellGo owns this entry; keep its caster + timing
|
||||
if (casterGuid != 0)
|
||||
@@ -108,13 +121,32 @@ void Store(uint64_t targetGuid, uint32_t spellId, uint64_t casterGuid,
|
||||
const uint32_t now = NowMs();
|
||||
for (auto &e : g_cache) {
|
||||
if (!e.used || (e.expirationMs != 0 && now >= e.expirationMs)) {
|
||||
e = {targetGuid, casterGuid, spellId, expirationMs, durationMs, true};
|
||||
e = {targetGuid, casterGuid, spellId, expirationMs, durationMs,
|
||||
kind, true};
|
||||
return;
|
||||
}
|
||||
}
|
||||
Entry &slot = g_cache[g_writeCursor];
|
||||
g_writeCursor = (g_writeCursor + 1) % kCacheSize;
|
||||
slot = {targetGuid, casterGuid, spellId, expirationMs, durationMs, true};
|
||||
slot = {targetGuid, casterGuid, spellId, expirationMs, durationMs, kind,
|
||||
true};
|
||||
}
|
||||
|
||||
// Evict the entry for an aura the engine reports gone. Keyed by (target,
|
||||
// spell) like the rest of the cache. Without this, the GetAuraDataByIndex
|
||||
// fallback would keep surfacing a dropped aura until its computed expiry —
|
||||
// e.g. a Rank 1 buff replaced by Rank 2 (engine drops Rank 1 from the
|
||||
// descriptor) would show as a phantom second aura, or a dispelled buff would
|
||||
// linger.
|
||||
void Evict(uint64_t targetGuid, uint32_t spellId) {
|
||||
if (targetGuid == 0 || spellId == 0)
|
||||
return;
|
||||
for (auto &e : g_cache) {
|
||||
if (e.used && e.targetGuid == targetGuid && e.spellId == spellId) {
|
||||
e.used = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Drop entries whose timed aura has elapsed so the table doesn't fill with
|
||||
@@ -176,11 +208,13 @@ void __fastcall SpellGo_h(uint64_t *itemGUID, uint64_t *casterGUID,
|
||||
|
||||
if (numTargets == 0) {
|
||||
// No explicit hit list (self-cast with caster-implicit target).
|
||||
Store(caster, spellId, caster, expirationMs, durationMs, true);
|
||||
Store(caster, spellId, caster, expirationMs, durationMs, true,
|
||||
KIND_UNKNOWN);
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < numTargets; ++i)
|
||||
Store(targets[i], spellId, caster, expirationMs, durationMs, true);
|
||||
Store(targets[i], spellId, caster, expirationMs, durationMs, true,
|
||||
KIND_UNKNOWN);
|
||||
}
|
||||
|
||||
const Game::HookAutoRegister _hook{Offsets::FUN_SPELL_GO,
|
||||
@@ -194,7 +228,7 @@ const Game::HookAutoRegister _hook{Offsets::FUN_SPELL_GO,
|
||||
// paths, so it stamps timing only with `fromCast=false` — Store skips any
|
||||
// entry SpellGo already owns, so a directly-cast aura keeps its talented
|
||||
// timing. Base (unmodified) duration is the best estimate without a caster.
|
||||
void StampApplication(void *unit, uint32_t spellId) {
|
||||
void StampApplication(void *unit, uint32_t spellId, int8_t kind) {
|
||||
if (spellId == 0)
|
||||
return;
|
||||
const uint8_t *rec = Spell::Lookup::RecordForID(static_cast<int>(spellId));
|
||||
@@ -206,7 +240,13 @@ void StampApplication(void *unit, uint32_t spellId) {
|
||||
const uint32_t durationMs = SpellDurationMs(rec, /*casterIsPlayer*/ false);
|
||||
const uint32_t expirationMs = durationMs > 0 ? NowMs() + durationMs : 0;
|
||||
Store(unitGuid, spellId, /*casterGuid*/ 0, expirationMs, durationMs,
|
||||
/*fromCast*/ false);
|
||||
/*fromCast*/ false, kind);
|
||||
}
|
||||
|
||||
// Classify by the absolute aura slot: 0..BUFF_COUNT-1 = buff (helpful),
|
||||
// BUFF_COUNT..TOTAL-1 = debuff (harmful).
|
||||
int8_t KindForSlot(int slot) {
|
||||
return slot >= Offsets::UNIT_AURA_BUFF_COUNT ? KIND_HARMFUL : KIND_HELPFUL;
|
||||
}
|
||||
|
||||
// OnAuraAdded — a new aura occupies a slot (gives the spellId directly).
|
||||
@@ -217,7 +257,7 @@ OnAuraAdded_t g_origOnAuraAdded = nullptr;
|
||||
void __fastcall OnAuraAdded_h(void *unit, void *edx, uint32_t slot,
|
||||
uint32_t spellId) {
|
||||
g_origOnAuraAdded(unit, edx, slot, spellId);
|
||||
StampApplication(unit, spellId);
|
||||
StampApplication(unit, spellId, KindForSlot(static_cast<int>(slot)));
|
||||
}
|
||||
|
||||
const Game::HookAutoRegister _hookAuraAdded{
|
||||
@@ -234,8 +274,10 @@ OnAuraStacksChanged_t g_origOnAuraStacksChanged = nullptr;
|
||||
void __fastcall OnAuraStacksChanged_h(void *unit, void *edx, int slot,
|
||||
uint8_t stackCount) {
|
||||
g_origOnAuraStacksChanged(unit, edx, slot, stackCount);
|
||||
StampApplication(unit, Aura::Data::ReadSpellID(
|
||||
static_cast<const uint8_t *>(unit), slot));
|
||||
StampApplication(
|
||||
unit,
|
||||
Aura::Data::ReadSpellID(static_cast<const uint8_t *>(unit), slot),
|
||||
KindForSlot(slot));
|
||||
}
|
||||
|
||||
const Game::HookAutoRegister _hookAuraStacks{
|
||||
@@ -243,6 +285,26 @@ const Game::HookAutoRegister _hookAuraStacks{
|
||||
reinterpret_cast<void *>(&OnAuraStacksChanged_h),
|
||||
reinterpret_cast<void **>(&g_origOnAuraStacksChanged)};
|
||||
|
||||
// OnAuraRemoved — a descriptor aura slot went empty: the aura fell off, was
|
||||
// dispelled, or was replaced by a higher rank (the diff dispatcher fires
|
||||
// Removed(old) + Added(new)). Evict the cache entry so the fallback stops
|
||||
// surfacing it. Same ABI as OnAuraAdded (unit in ecx, slot + spellId on the
|
||||
// stack); `slot` is unused here — we evict by spellId.
|
||||
using OnAuraRemoved_t = void(__fastcall *)(void *unit, void *edx, uint32_t slot,
|
||||
uint32_t spellId);
|
||||
OnAuraRemoved_t g_origOnAuraRemoved = nullptr;
|
||||
|
||||
void __fastcall OnAuraRemoved_h(void *unit, void *edx, uint32_t slot,
|
||||
uint32_t spellId) {
|
||||
g_origOnAuraRemoved(unit, edx, slot, spellId);
|
||||
(void)slot;
|
||||
Evict(Unit::Identity::GuidForObject(unit), spellId);
|
||||
}
|
||||
|
||||
const Game::HookAutoRegister _hookAuraRemoved{
|
||||
Offsets::FUN_ON_AURA_REMOVED, reinterpret_cast<void *>(&OnAuraRemoved_h),
|
||||
reinterpret_cast<void **>(&g_origOnAuraRemoved)};
|
||||
|
||||
} // namespace
|
||||
|
||||
bool Get(uint64_t unitGuid, uint32_t spellId, uint64_t *outCaster,
|
||||
@@ -260,4 +322,22 @@ bool Get(uint64_t unitGuid, uint32_t spellId, uint64_t *outCaster,
|
||||
return false;
|
||||
}
|
||||
|
||||
int Enumerate(uint64_t unitGuid, bool harmful, CachedAura *out, int maxOut) {
|
||||
if (unitGuid == 0 || out == nullptr || maxOut <= 0)
|
||||
return 0;
|
||||
const int8_t want = harmful ? KIND_HARMFUL : KIND_HELPFUL;
|
||||
const uint32_t now = NowMs();
|
||||
int n = 0;
|
||||
for (const auto &e : g_cache) {
|
||||
if (n >= maxOut)
|
||||
break;
|
||||
if (!e.used || e.targetGuid != unitGuid || e.kind != want)
|
||||
continue;
|
||||
if (e.expirationMs != 0 && now >= e.expirationMs)
|
||||
continue; // expired (infinite-duration entries pass)
|
||||
out[n++] = {e.spellId, e.casterGuid, e.expirationMs, e.durationMs};
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
} // namespace Aura::Source
|
||||
|
||||
+22
-2
@@ -1,12 +1,12 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -42,4 +42,24 @@ namespace Aura::Source {
|
||||
bool Get(uint64_t unitGuid, uint32_t spellId, uint64_t *outCaster,
|
||||
uint32_t *outExpirationMs, uint32_t *outDurationMs);
|
||||
|
||||
// One cached aura, as returned by `Enumerate`.
|
||||
struct CachedAura {
|
||||
uint32_t spellId;
|
||||
uint64_t casterGuid; // 0 = caster unknown (application hook, no SpellGo)
|
||||
uint32_t expirationMs; // 0 = infinite / unknown
|
||||
uint32_t durationMs; // applied duration (incl. caster mods); 0 = none
|
||||
};
|
||||
|
||||
// Fills `out` with up to `maxOut` cached, non-expired auras on `unitGuid`
|
||||
// whose helpful/harmful classification matches `harmful`. Returns the count
|
||||
// written. The classification is recorded from the aura's descriptor slot at
|
||||
// application time (`OnAuraAdded`/`OnAuraStacksChanged`); entries we only ever
|
||||
// saw via `SMSG_SPELL_GO` have no slot and so an unknown classification —
|
||||
// those are excluded (we can't tell which range they belong to).
|
||||
//
|
||||
// This is the fallback source for `Aura::Data` when the unit descriptor has
|
||||
// dropped an aura's slot (rogue stealth, party range fluctuation) even though
|
||||
// the aura is still active server-side: the cache survives descriptor clears.
|
||||
int Enumerate(uint64_t unitGuid, bool harmful, CachedAura *out, int maxOut);
|
||||
|
||||
} // namespace Aura::Source
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// `BAG_UPDATE_DELAYED` event — fires once per frame in which any
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// Inject ClassicAPI-owned bindings into a chosen engine section.
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
Vendored
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "cache/QueryLoad.h"
|
||||
|
||||
Vendored
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// `GetSavedCharacterOrder(realm)` / `SetSavedCharacterOrder(realm, order)`
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// `GetCurrentChatGUID()` — call from inside an addon's OnEvent for
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// Class metadata accessors backed by `ChrClasses.dbc`.
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// `C_Container.GetContainerItemCharges(containerIndex, slotIndex)` —
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// `C_Container.GetItemCooldown(itemID)` — modern signature only
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// `C_Container.GetContainerItemDurability(containerIndex, slotIndex)` —
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Game.h"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Game.h"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// `C_Container.GetContainerItemID(bagIndex, slotIndex)` — modern
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// `C_Container.MoveItem(srcBag, srcSlot, dstBag, dstSlot, count)` —
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// `C_Container.IsContainerItemOpenable(bag, slot)` — positional-arg
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// `C_Container.GetContainerItemRepairCost(containerIndex, slotIndex)`
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// `C_Container.SwapItems(srcBag, srcSlot, dstBag, dstSlot)` — atomic
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
//
|
||||
// Restores Lua 5.0's stripped `coroutine.*` library to the in-game Lua
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// `C_CreatureInfo.GetCreatureInfoByID(creatureID)` -> table | nil
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// `GetCursorInfo()` — backport of the modern WoW global. Surfaces
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Game.h"
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "cvar/Factory.h"
|
||||
|
||||
#include "Offsets.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace CVar::Factory {
|
||||
|
||||
namespace {
|
||||
|
||||
// `FUN_REGISTER_CVAR` — verified ABI (see Offsets.h and the calibration
|
||||
// against the engine's own call site at 0x005E2490 / the Lua
|
||||
// Script_RegisterCVar path). MSVC `__fastcall` places the first two args in
|
||||
// ECX/EDX and pushes the rest right-to-left, which reproduces the engine's
|
||||
// exact push order: flags, defaultValue, callback, categoryId, hiddenBool,
|
||||
// userData (with flags as the first stack arg / last push).
|
||||
using RegisterCVar_t = void *(__fastcall *)(const char *name, int edxZero,
|
||||
uint32_t flags,
|
||||
const char *defaultValue,
|
||||
ChangeCallback callback,
|
||||
int categoryId, int hiddenBool,
|
||||
void *userData);
|
||||
|
||||
using FindCVar_t = void *(__fastcall *)(const char *name);
|
||||
|
||||
// `FUN_SET_CVAR_VALUE` — `__thiscall(cvar /*ecx*/, value, a3, a4, a5, a6)`,
|
||||
// i.e. ECX=cvar with `value` AND a3..a6 all passed on the stack (5 stack
|
||||
// args; the function cleans 20 bytes / `RET 0x14`). NOT __fastcall — that
|
||||
// would route `value` through EDX, push only 4 args, and leave the callee
|
||||
// popping 4 bytes too many → ESP corruption → silent crash. Mirror the
|
||||
// Script_SetCVar invocation (0x00488CA8): a3..a6 = 1, 0, 0, 1.
|
||||
using SetCVarValue_t = char(__thiscall *)(void *cvar, const char *value,
|
||||
int a3, int a4, int a5, int a6);
|
||||
|
||||
const char *ReadValue(void *cvar) {
|
||||
if (cvar == nullptr)
|
||||
return nullptr;
|
||||
return *reinterpret_cast<const char *const *>(
|
||||
static_cast<const uint8_t *>(cvar) + Offsets::OFF_CVAR_VALUE_STR);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Handle Register(const char *name, const char *defaultValue, uint32_t flags,
|
||||
ChangeCallback callback, void *userData) {
|
||||
if (name == nullptr)
|
||||
return nullptr;
|
||||
auto reg = reinterpret_cast<RegisterCVar_t>(Offsets::FUN_REGISTER_CVAR);
|
||||
return reg(name, /*edxZero*/ 0, flags, defaultValue, callback,
|
||||
Offsets::CVAR_SCRIPT_CATEGORY, /*hiddenBool*/ 0, userData);
|
||||
}
|
||||
|
||||
Handle Find(const char *name) {
|
||||
if (name == nullptr)
|
||||
return nullptr;
|
||||
auto find = reinterpret_cast<FindCVar_t>(Offsets::FUN_FIND_CVAR);
|
||||
return find(name);
|
||||
}
|
||||
|
||||
const char *GetString(Handle cvar) {
|
||||
return ReadValue(cvar);
|
||||
}
|
||||
|
||||
int GetInt(Handle cvar, int fallback) {
|
||||
const char *value = ReadValue(cvar);
|
||||
if (value == nullptr || value[0] == '\0')
|
||||
return fallback;
|
||||
return std::atoi(value);
|
||||
}
|
||||
|
||||
void SetString(Handle cvar, const char *value) {
|
||||
if (cvar == nullptr || value == nullptr)
|
||||
return;
|
||||
auto set = reinterpret_cast<SetCVarValue_t>(Offsets::FUN_SET_CVAR_VALUE);
|
||||
set(cvar, value, 1, 0, 0, 1);
|
||||
}
|
||||
|
||||
void SetInt(Handle cvar, int value) {
|
||||
char buf[16];
|
||||
// Hand-format to avoid pulling in a locale-aware path; value range for
|
||||
// our cvars is small, 16 bytes is ample for a 32-bit int + sign + NUL.
|
||||
std::snprintf(buf, sizeof buf, "%d", value);
|
||||
SetString(cvar, buf);
|
||||
}
|
||||
|
||||
} // namespace CVar::Factory
|
||||
@@ -0,0 +1,80 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
// CVar::Factory — create and drive engine CVars from C++.
|
||||
//
|
||||
// Vanilla 1.12 only exposes CVar *reading* and *registration without a
|
||||
// callback* through Lua (`RegisterCVar(name, default)`); there's no way for
|
||||
// an addon to register a cvar with a change-callback or to react to value
|
||||
// changes. This wraps the engine's internal registrar (`FUN_REGISTER_CVAR`)
|
||||
// and value-setter (`FUN_SET_CVAR_VALUE`) so other modules can publish
|
||||
// persisted, validated settings (clamped via the change callback and saved
|
||||
// to Config.wtf).
|
||||
//
|
||||
// CVars registered here persist to `WTF\Config.wtf` (the engine forces the
|
||||
// archive flag bit on at registration) and are visible to the in-game Lua
|
||||
// `GetCVar`/`SetCVar` globals, since cvar storage is process-global.
|
||||
|
||||
namespace CVar::Factory {
|
||||
|
||||
// Opaque handle to an engine CVar. Stable for the cvar's lifetime (vanilla
|
||||
// never reallocates a registered cvar).
|
||||
using Handle = void *;
|
||||
|
||||
// Change callback. Fires whenever the cvar's value changes (and once at
|
||||
// registration). Mirrors the engine ABI verified at FUN_SET_CVAR_VALUE:
|
||||
// - `cvar` — this cvar's Handle
|
||||
// - `prevValue` — the value before the change (may be null/empty)
|
||||
// - `newValue` — the value being applied
|
||||
// - `userData` — whatever was passed to Register
|
||||
// Return a nonzero value to ACCEPT the change, 0 to REJECT it (the engine
|
||||
// keeps the previous value). To clamp rather than reject, set the clamped
|
||||
// value with SetString from inside the callback and return 0 for the
|
||||
// out-of-range input. Must tolerate being invoked with partial context.
|
||||
using ChangeCallback = int(__fastcall *)(Handle cvar, const char *prevValue,
|
||||
const char *newValue, void *userData);
|
||||
|
||||
// Register a cvar (or fetch the existing one — the engine dedups by name,
|
||||
// and re-registering OR-merges `flags` and updates the callback). `name`
|
||||
// and `defaultValue` must outlive the process (the engine stores `name` by
|
||||
// pointer; pass string literals). `defaultValue` may be null for "". The
|
||||
// returned Handle is never null on success; null only if the engine
|
||||
// registrar itself failed.
|
||||
Handle Register(const char *name, const char *defaultValue,
|
||||
uint32_t flags = 0, ChangeCallback callback = nullptr,
|
||||
void *userData = nullptr);
|
||||
|
||||
// Look up an already-registered cvar by name, or null if none.
|
||||
Handle Find(const char *name);
|
||||
|
||||
// Read the cvar's current value string (the raw engine pointer at
|
||||
// `+OFF_CVAR_VALUE_STR`). Returns null if `cvar` is null. The pointer is
|
||||
// valid for the cvar's lifetime.
|
||||
const char *GetString(Handle cvar);
|
||||
|
||||
// Read the value parsed as a base-10 integer, or `fallback` if `cvar` is
|
||||
// null or the value isn't numeric.
|
||||
int GetInt(Handle cvar, int fallback = 0);
|
||||
|
||||
// Set the cvar's value (fires its change callback). No-op if `cvar` is
|
||||
// null. `value` is copied by the engine into the cvar's inline buffer.
|
||||
void SetString(Handle cvar, const char *value);
|
||||
|
||||
// Convenience: set from an integer.
|
||||
void SetInt(Handle cvar, int value);
|
||||
|
||||
} // namespace CVar::Factory
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// Glue-side CVar bindings. Vanilla 1.12 registers `GetCVar`,
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Lookup.h"
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Log.h"
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// Temporary probe helpers used to derive byte offsets in the player /
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// `C_EncodingUtil.EncodeBase64` / `DecodeBase64`, with `Base64Variant`
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Game.h"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// `C_EncodingUtil.CompressString` / `DecompressString`, full
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Game.h"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Game.h"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// `C_EquipmentSet.*` — backports the modern equipment-set API on top
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Data.h"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Locations.h"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Storage.h"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// `GameTooltip:SetEquipmentSet(name)` — modern method that fills the
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Custom.h"
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Game.h"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Game.h"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Game.h"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Game.h"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// FACTION_STANDING_CHANGED — fires once per reputation change with
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// Restores `UNIT_FACTION("player")` event semantics that vanilla 1.12.1
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// `C_FriendList.SendWhoQueryByName` — sends a /who name-filter query
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// `C_GameObjectInfo.GetGameObjectInfoByID(gameObjectID)` -> table | nil
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Game.h"
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// `C_GossipInfo.*` — retail-shaped wrappers around vanilla 1.12's
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Game.h"
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
#include "Game.h"
|
||||
#include "guid/Guid.h"
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Guid.h"
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Game.h"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// `GLOBAL_MOUSE_DOWN` / `GLOBAL_MOUSE_UP` — modern WoW fires these
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Game.h"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Game.h"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
// `ExportInterfaceFiles art|code` — backport of the 4.3.4 developer-
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "item/Arg.h"
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
// `GetAverageItemLevel()` → `(avgItemLevel, avgItemLevelEquipped)` —
|
||||
// polyfills the modern 2.4+ global with the same 2-tuple shape as
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Game.h"
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#include "Charges.h"
|
||||
|
||||
+3
-3
@@ -1,14 +1,14 @@
|
||||
// This file is part of ClassicAPI.
|
||||
//
|
||||
// ClassicAPI is free software: you can redistribute it and/or modify it under the terms
|
||||
// of the GNU Lesser General Public License as published by the Free Software Foundation, either
|
||||
// of the GNU General Public License as published by the Free Software Foundation, either
|
||||
// version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// ClassicAPI is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the GNU Lesser General Public License for more details.
|
||||
// PURPOSE. See the GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License along with
|
||||
// You should have received a copy of the GNU General Public License along with
|
||||
// ClassicAPI. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
#pragma once
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user