lotrointerface.com
Search Downloads

LoTROInterface SVN SequenceBars

[/] [trunk/] [Thurallor/] [Common/] [Utils/] [Watcher.lua] - Blame information for rev 121

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 20 Thurallor-7095
-- Singleton object for efficiently observing and keeping track of game state,
2 Thurallor-7095
-- providing convenient functions and events.
3 Thurallor-7095
 
4 Thurallor-7095
local Watcher = {};
5 Thurallor-7095
Thurallor.Utils.Watcher = Watcher;
6 Thurallor-7095
 
7 23 Thurallor-7095
local function DoSave()
8 Thurallor-7095
--Puts("Saving...");
9 Thurallor-7095
    -- Workaround for Turbine localization bug.
10 Thurallor-7095
    local saveData = ExportTable(Watcher.settings);
11 Thurallor-7095
    Turbine.PluginData.Save(Turbine.DataScope.Account, "Thurallor_GameInfo", saveData, function()
12 Thurallor-7095
--Puts("Save complete.");
13 Thurallor-7095
    end);
14 Thurallor-7095
end
15 Thurallor-7095
 
16 20 Thurallor-7095
local startupTime = Turbine.Engine.GetGameTime();
17 Thurallor-7095
local function SaveSettings()
18 Thurallor-7095
    if (not Watcher.settingsLoaded) then
19 Thurallor-7095
        if (Turbine.Engine.GetGameTime() - startupTime > 5) then
20 Thurallor-7095
            -- Settings file probably doesn't exist if it hasn't loaded in 5 seconds.
21 Thurallor-7095
            Watcher.settingsLoaded = true;
22 Thurallor-7095
        else
23 Thurallor-7095
            return;
24 Thurallor-7095
        end
25 Thurallor-7095
    end
26 23 Thurallor-7095
 
27 Thurallor-7095
    -- Do the save operation at the next Update; thus aggregating multiple consecutive save requests.
28 Thurallor-7095
    if (not Watcher.saveRequested) then
29 Thurallor-7095
        Watcher.saveRequested = true;
30 Thurallor-7095
        Watcher.window:SetWantsUpdates(true);
31 Thurallor-7095
    end
32 20 Thurallor-7095
end
33 Thurallor-7095
 
34 35 Thurallor-7095
local function DoDelayedCallback(_time, event, args)
35 Thurallor-7095
    if (not Watcher.delayedCallbacks) then
36 Thurallor-7095
        Watcher.delayedCallbacks = {};
37 Thurallor-7095
    end
38 Thurallor-7095
    table.insert(Watcher.delayedCallbacks, { time = _time, event = event, args = args } );
39 Thurallor-7095
    Watcher.window:SetWantsUpdates(true);
40 Thurallor-7095
end
41 Thurallor-7095
 
42 20 Thurallor-7095
local function AddActorEffect(effectsObject, effect)
43 Thurallor-7095
    local categories, name = effect:GetCategory(), effect:GetName();
44 Thurallor-7095
    if (not effectsObject.cache[name]) then
45 Thurallor-7095
        effectsObject.cache[name] = 0;
46 Thurallor-7095
    end
47 Thurallor-7095
    effectsObject.cache[name] = effectsObject.cache[name] + 1;
48 Thurallor-7095
 
49 Thurallor-7095
    if (not Watcher.settings.knownEffects[name]) then
50 Thurallor-7095
        -- This is an effect we have never seen before.  Learn some info about it and save for future reference.
51 Thurallor-7095
        categories = effect:GetCategory();
52 Thurallor-7095
        Watcher.settings.knownEffects[name] = {
53 Thurallor-7095
            categories, effect:GetIcon(), effect:IsCurable(), effect:IsDebuff()};
54 Thurallor-7095
 
55 Thurallor-7095
        local bits = categories;
56 Thurallor-7095
        if (not Watcher.AddCategories[bits]) then
57 Thurallor-7095
            -- This is a GetCategory value we have never seen before.  Create functions for adding/removing.
58 Thurallor-7095
            local AddCategories = "local categories = ...; ";
59 Thurallor-7095
            local RemoveCategories = "local categories = ...; ";
60 Thurallor-7095
            if (bits >= 2048) then
61 Thurallor-7095
                -- Unknown bits; discard them.
62 Thurallor-7095
                bits = bits % 2048;
63 Thurallor-7095
            end
64 Thurallor-7095
            if (bits >= 1226) then
65 Thurallor-7095
                -- Turbine.Gameplay.EffectCategory.Dispellable is the OR of several bits
66 Thurallor-7095
                AddCategories = AddCategories .. "categories[1226] = categories[1226] + 1; ";
67 Thurallor-7095
                RemoveCategories = RemoveCategories .. "categories[1226] = categories[1226] - 1; ";
68 Thurallor-7095
            end
69 Thurallor-7095
            if (bits >= 1024) then
70 Thurallor-7095
                AddCategories = AddCategories .. "categories[1024] = categories[1024] + 1; ";
71 Thurallor-7095
                RemoveCategories = RemoveCategories .. "categories[1024] = categories[1024] - 1; ";
72 Thurallor-7095
                bits = bits - 1024;
73 Thurallor-7095
            end
74 Thurallor-7095
            if (bits >= 512) then
75 Thurallor-7095
                AddCategories = AddCategories .. "categories[512] = categories[512] + 1; ";
76 Thurallor-7095
                RemoveCategories = RemoveCategories .. "categories[512] = categories[512] - 1; ";
77 Thurallor-7095
                bits = bits - 512;
78 Thurallor-7095
            end
79 Thurallor-7095
            if (bits >= 256) then
80 Thurallor-7095
                AddCategories = AddCategories .. "categories[256] = categories[256] + 1; ";
81 Thurallor-7095
                RemoveCategories = RemoveCategories .. "categories[256] = categories[256] - 1; ";
82 Thurallor-7095
                bits = bits - 256;
83 Thurallor-7095
            end
84 Thurallor-7095
            if (bits >= 128) then
85 Thurallor-7095
                AddCategories = AddCategories .. "categories[128] = categories[128] + 1; ";
86 Thurallor-7095
                RemoveCategories = RemoveCategories .. "categories[128] = categories[128] - 1; ";
87 Thurallor-7095
                bits = bits - 128;
88 Thurallor-7095
            end
89 Thurallor-7095
            if (bits >= 64) then
90 Thurallor-7095
                AddCategories = AddCategories .. "categories[64] = categories[64] + 1; ";
91 Thurallor-7095
                RemoveCategories = RemoveCategories .. "categories[64] = categories[64] - 1; ";
92 Thurallor-7095
                bits = bits - 64;
93 Thurallor-7095
            end
94 Thurallor-7095
            if (bits >= 32) then
95 Thurallor-7095
                AddCategories = AddCategories .. "categories[32] = categories[32] + 1; ";
96 Thurallor-7095
                RemoveCategories = RemoveCategories .. "categories[32] = categories[32] - 1; ";
97 Thurallor-7095
                bits = bits - 32;
98 Thurallor-7095
            end
99 Thurallor-7095
            if (bits >= 16) then
100 Thurallor-7095
                AddCategories = AddCategories .. "categories[16] = categories[16] + 1; ";
101 Thurallor-7095
                RemoveCategories = RemoveCategories .. "categories[16] = categories[16] - 1; ";
102 Thurallor-7095
                bits = bits - 16;
103 Thurallor-7095
            end
104 Thurallor-7095
            if (bits >= 8) then
105 Thurallor-7095
                AddCategories = AddCategories .. "categories[8] = categories[8] + 1; ";
106 Thurallor-7095
                RemoveCategories = RemoveCategories .. "categories[8] = categories[8] - 1; ";
107 Thurallor-7095
                bits = bits - 8;
108 Thurallor-7095
            end
109 Thurallor-7095
            if (bits >= 4) then
110 Thurallor-7095
                AddCategories = AddCategories .. "categories[4] = categories[4] + 1; ";
111 Thurallor-7095
                RemoveCategories = RemoveCategories .. "categories[4] = categories[4] - 1; ";
112 Thurallor-7095
                bits = bits - 4;
113 Thurallor-7095
            end
114 Thurallor-7095
            if (bits >= 2) then
115 Thurallor-7095
                AddCategories = AddCategories .. "categories[2] = categories[2] + 1; ";
116 Thurallor-7095
                RemoveCategories = RemoveCategories .. "categories[2] = categories[2] - 1; ";
117 Thurallor-7095
                bits = bits - 2;
118 Thurallor-7095
            end
119 Thurallor-7095
            if (bits >= 1) then
120 Thurallor-7095
                AddCategories = AddCategories .. "categories[1] = categories[1] + 1; ";
121 Thurallor-7095
                RemoveCategories = RemoveCategories .. "categories[1] = categories[1] - 1; ";
122 Thurallor-7095
            end
123 Thurallor-7095
 
124 Thurallor-7095
            Watcher.settings.funcs.AddCategories[categories] = AddCategories;
125 Thurallor-7095
            Watcher.AddCategories[categories] = loadstring(AddCategories);
126 Thurallor-7095
            Watcher.settings.funcs.RemoveCategories[categories] = RemoveCategories;
127 Thurallor-7095
            Watcher.RemoveCategories[categories] = loadstring(RemoveCategories);
128 Thurallor-7095
        end
129 Thurallor-7095
 
130 Thurallor-7095
        SaveSettings();
131 Thurallor-7095
    else
132 Thurallor-7095
        categories = Watcher.settings.knownEffects[name][1];
133 Thurallor-7095
    end
134 Thurallor-7095
 
135 Thurallor-7095
    Watcher.AddCategories[categories](effectsObject.activeCategories);
136 Thurallor-7095
end
137 Thurallor-7095
 
138 Thurallor-7095
local function RemoveActorEffect(effectsObject, effect)
139 Thurallor-7095
    local categories, name = effect:GetCategory(), effect:GetName();
140 Thurallor-7095
    Watcher.RemoveCategories[categories](effectsObject.activeCategories);
141 Thurallor-7095
    effectsObject.cache[name] = effectsObject.cache[name] - 1;
142 Thurallor-7095
    if (effectsObject.cache[name] == 0) then
143 Thurallor-7095
        effectsObject.cache[name] = nil;
144 Thurallor-7095
    end
145 Thurallor-7095
end
146 Thurallor-7095
 
147 Thurallor-7095
local function GetActorEffects(effectsObject)
148 Thurallor-7095
    effectsObject.cache = {};
149 Thurallor-7095
    effectsObject.activeCategories = {
150 Thurallor-7095
        [Turbine.Gameplay.EffectCategory.Dispellable] = 0;
151 Thurallor-7095
        [Turbine.Gameplay.EffectCategory.Corruption] = 0;
152 Thurallor-7095
        [Turbine.Gameplay.EffectCategory.Elemental] = 0;
153 Thurallor-7095
        [Turbine.Gameplay.EffectCategory.Tactical] = 0;
154 Thurallor-7095
        [Turbine.Gameplay.EffectCategory.Poison] = 0;
155 Thurallor-7095
        [Turbine.Gameplay.EffectCategory.Fear] = 0;
156 Thurallor-7095
        [Turbine.Gameplay.EffectCategory.Song] = 0;
157 Thurallor-7095
        [Turbine.Gameplay.EffectCategory.Cry] = 0;
158 Thurallor-7095
        [Turbine.Gameplay.EffectCategory.Wound] = 0;
159 Thurallor-7095
        [Turbine.Gameplay.EffectCategory.Physical] = 0;
160 Thurallor-7095
        [Turbine.Gameplay.EffectCategory.Disease] = 0;
161 Thurallor-7095
        [1] = 0;
162 Thurallor-7095
    };
163 Thurallor-7095
    for e = 1, effectsObject:GetCount(), 1 do
164 Thurallor-7095
        local effect = effectsObject:Get(e);
165 Thurallor-7095
        AddActorEffect(effectsObject, effect);
166 Thurallor-7095
    end
167 Thurallor-7095
end
168 Thurallor-7095
 
169 Thurallor-7095
local function GetEquipment()
170 Thurallor-7095
    local eq = Watcher.playerEquipmentObject;
171 Thurallor-7095
    eq.cache = { byName = {}; bySlot = {}; };
172 Thurallor-7095
    for slot = 1, eq:GetSize() do
173 Thurallor-7095
        local item = eq:GetItem(slot);
174 Thurallor-7095
        if (item) then
175 Thurallor-7095
            local name = item:GetItemInfo():GetName();
176 Thurallor-7095
            eq.cache.byName[name] = { item, slot };
177 Thurallor-7095
            eq.cache.bySlot[slot] = { item, name };
178 Thurallor-7095
        end
179 Thurallor-7095
    end
180 Thurallor-7095
end
181 Thurallor-7095
 
182 Thurallor-7095
local function GetBackpack()
183 Thurallor-7095
    local bp = Watcher.playerBackpackObject;
184 Thurallor-7095
    bp.cache = { byName = {}; bySlot = {}; };
185 Thurallor-7095
    for slot = 1, bp:GetSize() do
186 Thurallor-7095
        local item = bp:GetItem(slot);
187 Thurallor-7095
        if (item) then
188 Thurallor-7095
            local name = item:GetItemInfo():GetName();
189 30 Thurallor-7095
            if (not bp.cache.byName[name]) then
190 Thurallor-7095
                bp.cache.byName[name] = { slot };
191 Thurallor-7095
            else
192 Thurallor-7095
                table.insert(bp.cache.byName[name], slot);
193 Thurallor-7095
            end
194 20 Thurallor-7095
            bp.cache.bySlot[slot] = { item, name };
195 Thurallor-7095
        end
196 Thurallor-7095
    end
197 Thurallor-7095
end
198 Thurallor-7095
 
199 Thurallor-7095
local function ResetTimeChanged(skill, args)
200 Thurallor-7095
    DoCallbacks(self, "ResetTimeChanged", args);
201 Thurallor-7095
end
202 Thurallor-7095
 
203 118 Thurallor-7095
local function StanceChanged()
204 Thurallor-7095
    local stance = Watcher.playerClassAttributes:GetStance();
205 Thurallor-7095
        if (stance ~= Watcher.stance) then
206 120 Thurallor-7095
        -- Lua API bug workaround:  If invalid stance reported, keep the previous value.
207 Thurallor-7095
        local validStance = {
208 Thurallor-7095
            [Turbine.Gameplay.Class.Warden] = {
209 Thurallor-7095
                [Turbine.Gameplay.Attributes.WardenStance.Assailment] = true;
210 Thurallor-7095
                [Turbine.Gameplay.Attributes.WardenStance.Determination] = true;
211 Thurallor-7095
            };
212 Thurallor-7095
            [Turbine.Gameplay.Class.Hunter] = {
213 Thurallor-7095
                [Turbine.Gameplay.Attributes.HunterStance.Endurance] = true;
214 Thurallor-7095
                [Turbine.Gameplay.Attributes.HunterStance.Precision] = true;
215 Thurallor-7095
                [Turbine.Gameplay.Attributes.HunterStance.Strength] = true;
216 Thurallor-7095
            };
217 Thurallor-7095
            [Turbine.Gameplay.Class.Minstrel] = {
218 Thurallor-7095
                [Turbine.Gameplay.Attributes.MinstrelStance.Melody] = true;
219 Thurallor-7095
                [Turbine.Gameplay.Attributes.MinstrelStance.Dissonance] = true;
220 Thurallor-7095
                [Turbine.Gameplay.Attributes.MinstrelStance.Resonance] = true;
221 Thurallor-7095
            };
222 Thurallor-7095
        };
223 Thurallor-7095
        if (validStance[Watcher.playerObject:GetClass()][stance]) then
224 Thurallor-7095
            Watcher.stance = stance;
225 Thurallor-7095
            DoCallbacks(Watcher, "PlayerStanceChanged", { Stance = stance });
226 Thurallor-7095
        end
227 118 Thurallor-7095
    end
228 Thurallor-7095
end
229 Thurallor-7095
 
230 35 Thurallor-7095
local function GetSkills(skills)
231 20 Thurallor-7095
    skills.cache = { names = {}; byName = {}; byIcon = {} };
232 41 Thurallor-7095
    local cache = skills.cache;
233 20 Thurallor-7095
    for c = 1, skills:GetCount(), 1 do
234 Thurallor-7095
        local skill = skills:GetItem(c);
235 Thurallor-7095
        local skillInfo = skill:GetSkillInfo();
236 Thurallor-7095
        local icon = skillInfo:GetIconImageID();
237 Thurallor-7095
        local name = skillInfo:GetName();
238 41 Thurallor-7095
        cache.byName[name] = skill;
239 Thurallor-7095
        cache.byIcon[icon] = skill;
240 Thurallor-7095
        table.insert(cache.names, name);
241 20 Thurallor-7095
    end
242 41 Thurallor-7095
    table.sort(cache.names);
243 20 Thurallor-7095
    return skills.cache;
244 Thurallor-7095
end
245 Thurallor-7095
 
246 34 Thurallor-7095
local function GetGambits()
247 Thurallor-7095
    local gambits = Watcher.playerTrainedGambits;
248 Thurallor-7095
    gambits.cache = { names = {}; byName = {}; byIcon = {} };
249 Thurallor-7095
    if (Watcher.playerObject:GetClass() == Turbine.Gameplay.Class.Warden) then
250 Thurallor-7095
        for c = 1, gambits:GetCount(), 1 do
251 Thurallor-7095
            local skill = gambits:GetItem(c);
252 Thurallor-7095
            local skillInfo = skill:GetSkillInfo();
253 Thurallor-7095
            local icon = skillInfo:GetIconImageID();
254 Thurallor-7095
            local name = skillInfo:GetName();
255 Thurallor-7095
            gambits.cache.byName[name] = skill;
256 Thurallor-7095
            gambits.cache.byIcon[icon] = skill;
257 Thurallor-7095
        end
258 Thurallor-7095
    end
259 Thurallor-7095
    return gambits.cache;
260 Thurallor-7095
end
261 Thurallor-7095
 
262 23 Thurallor-7095
local function GetParty()
263 Thurallor-7095
    local party = Watcher.playerPartyObject;
264 Thurallor-7095
    party.cache = { byName = {}; };
265 Thurallor-7095
    for c = 1, party:GetMemberCount(), 1 do
266 Thurallor-7095
        local member = party:GetMember(c);
267 Thurallor-7095
        local name = member:GetName();
268 Thurallor-7095
        party.cache.byName[name] = member;
269 Thurallor-7095
    end
270 Thurallor-7095
    return party.cache;
271 20 Thurallor-7095
end
272 Thurallor-7095
 
273 23 Thurallor-7095
local function PlayerEffectAdded(effectsObject, args)
274 Thurallor-7095
    local effect = effectsObject:Get(args.Index);
275 Thurallor-7095
    AddActorEffect(effectsObject, effect);
276 Thurallor-7095
    DoCallbacks(Watcher, "PlayerEffectAdded", effect);
277 Thurallor-7095
end
278 Thurallor-7095
 
279 Thurallor-7095
local function PlayerEffectRemoved(effectsObject, args)
280 20 Thurallor-7095
    RemoveActorEffect(effectsObject, args.Effect);
281 23 Thurallor-7095
    DoCallbacks(Watcher, "PlayerEffectRemoved", args.Effect);
282 20 Thurallor-7095
end
283 Thurallor-7095
 
284 23 Thurallor-7095
local function PlayerEffectsCleared(effectsObject, args)
285 20 Thurallor-7095
    GetActorEffects(effectsObject);
286 23 Thurallor-7095
    DoCallbacks(Watcher, "PlayerEffectsCleared", args);
287 20 Thurallor-7095
end
288 Thurallor-7095
 
289 23 Thurallor-7095
local function TargetEffectAdded(effectsObject, args)
290 Thurallor-7095
    local effect = effectsObject:Get(args.Index);
291 Thurallor-7095
    AddActorEffect(effectsObject, effect);
292 Thurallor-7095
    DoCallbacks(Watcher, "TargetEffectAdded", effect);
293 Thurallor-7095
end
294 Thurallor-7095
 
295 Thurallor-7095
function TargetEffectRemoved(effectsObject, args)
296 Thurallor-7095
    RemoveActorEffect(effectsObject, args.Effect);
297 Thurallor-7095
    DoCallbacks(Watcher, "TargetEffectRemoved", args.Effect);
298 Thurallor-7095
end
299 Thurallor-7095
 
300 Thurallor-7095
local function TargetEffectsCleared(effectsObject, args)
301 Thurallor-7095
    GetActorEffects(effectsObject);
302 Thurallor-7095
    DoCallbacks(Watcher, "TargetEffectsCleared", args);
303 Thurallor-7095
end
304 Thurallor-7095
 
305 Thurallor-7095
local function PlayerPartyChanged(sender, args)
306 Thurallor-7095
    Watcher.playerPartyObject = Watcher.playerObject:GetParty();
307 Thurallor-7095
    if (Watcher.playerPartyObject) then
308 Thurallor-7095
        AddCallback(Watcher.playerPartyObject, "MemberAdded", PartyMemberAdded);
309 Thurallor-7095
        AddCallback(Watcher.playerPartyObject, "MemberRemoved", PartyMemberRemoved);
310 Thurallor-7095
        GetParty();
311 Thurallor-7095
    end
312 Thurallor-7095
end
313 Thurallor-7095
 
314 43 Thurallor-7095
local function UpdatePlayerTarget()
315 22 Thurallor-7095
    -- Bug workaround:
316 Thurallor-7095
    -- If the target is a member of the player's party, GetEffects() won't work
317 Thurallor-7095
    -- unless we use the Party object to get the Player object.
318 23 Thurallor-7095
    if (Watcher.targetObject and Watcher.playerPartyObject) then
319 Thurallor-7095
        local name = Watcher.targetObject:GetName();
320 Thurallor-7095
        local member = Watcher.playerPartyObject.cache.byName[name];
321 Thurallor-7095
        if (member) then
322 Thurallor-7095
            Watcher.targetObject = member;
323 22 Thurallor-7095
        end
324 20 Thurallor-7095
    end
325 43 Thurallor-7095
 
326 23 Thurallor-7095
    -- Need to get the effects object now so it can start observing effects.
327 43 Thurallor-7095
-- Target effects currently are too buggy to use.
328 Thurallor-7095
--[[
329 23 Thurallor-7095
    if (Watcher.targetObject and Watcher.targetObject.GetEffects) then
330 Thurallor-7095
        Watcher.targetEffectsObject = Watcher.targetObject:GetEffects();
331 Thurallor-7095
    end
332 43 Thurallor-7095
]]
333 Thurallor-7095
 
334 Thurallor-7095
    DoCallbacks(Watcher, "PlayerTargetChanged", Watcher.targetObject);
335 20 Thurallor-7095
end
336 Thurallor-7095
 
337 43 Thurallor-7095
local function PlayerTargetChanged()
338 Thurallor-7095
    Watcher.targetObject = Watcher.playerObject:GetTarget();
339 Thurallor-7095
    Watcher.targetEffectsObject = nil;
340 Thurallor-7095
 
341 Thurallor-7095
    -- Client may not immediately have information about the target.  When
342 Thurallor-7095
    -- the info arrives, we'll get a BaseMaxPowerChanged event, which seems
343 Thurallor-7095
    -- to occur near the end of the burst of events that will arrive.
344 46 Thurallor-7095
    if (Watcher.targetObject and Watcher.targetObject.GetBaseMaxPower and (Watcher.targetObject:GetBaseMaxPower() == 0)) then
345 43 Thurallor-7095
        Watcher.targetObject.BaseMaxPowerChanged = function()
346 Thurallor-7095
            Watcher.targetObject.BaseMaxPowerChanged = nil;
347 Thurallor-7095
            Watcher.targetObject = Watcher.playerObject:GetTarget();
348 Thurallor-7095
            Watcher.targetEffectsObject = nil;
349 Thurallor-7095
            UpdatePlayerTarget();
350 Thurallor-7095
        end
351 Thurallor-7095
    end
352 Thurallor-7095
 
353 Thurallor-7095
    UpdatePlayerTarget();
354 Thurallor-7095
end
355 Thurallor-7095
 
356 20 Thurallor-7095
local function ItemEquipped(sender, args)
357 Thurallor-7095
--Puts("ItemEquipped: args = " .. Serialize(args));
358 Thurallor-7095
    local slot, item, name = args.Index, args.Item, args.Item:GetItemInfo():GetName();
359 Thurallor-7095
    Watcher.playerEquipmentObject.cache.byName[name] = { item, slot };
360 Thurallor-7095
    Watcher.playerEquipmentObject.cache.bySlot[slot] = { item, name };
361 Thurallor-7095
    DoCallbacks(Watcher, "ItemEquipped", args);
362 Thurallor-7095
end
363 Thurallor-7095
 
364 Thurallor-7095
local function ItemUnequipped(sender, args)
365 Thurallor-7095
--Puts("ItemUnequipped: args = " .. Serialize(args));
366 Thurallor-7095
    local slot, name = args.Index, args.Item:GetItemInfo():GetName();
367 Thurallor-7095
    Watcher.playerEquipmentObject.cache.bySlot[slot] = nil;
368 Thurallor-7095
    Watcher.playerEquipmentObject.cache.byName[name] = nil;
369 Thurallor-7095
    DoCallbacks(Watcher, "ItemUnequipped", args);
370 Thurallor-7095
end
371 Thurallor-7095
 
372 Thurallor-7095
local function ItemAdded(sender, args)
373 Thurallor-7095
--Puts("ItemAdded: args = " .. Serialize(args));
374 30 Thurallor-7095
    -- occurs out-of-combat; efficiency not important
375 Thurallor-7095
    GetBackpack();
376 20 Thurallor-7095
end
377 Thurallor-7095
 
378 Thurallor-7095
local function ItemRemoved(sender, args)
379 Thurallor-7095
--Puts("ItemRemoved: args = " .. Serialize(args));
380 30 Thurallor-7095
    -- occurs out-of-combat; efficiency not important
381 Thurallor-7095
    GetBackpack();
382 20 Thurallor-7095
end
383 Thurallor-7095
 
384 Thurallor-7095
local function ItemMoved(sender, args)
385 30 Thurallor-7095
    -- occurs out-of-combat; efficiency not important
386 Thurallor-7095
    GetBackpack();
387 20 Thurallor-7095
    DoCallbacks(Watcher, "ItemMoved", args);
388 Thurallor-7095
end
389 Thurallor-7095
 
390 30 Thurallor-7095
local function BackpackSizeChanged(sender, args)
391 Thurallor-7095
    -- rare occurrence, out-of-combat; efficiency not important
392 Thurallor-7095
    GetBackpack();
393 Thurallor-7095
end
394 Thurallor-7095
 
395 35 Thurallor-7095
local function ChatReceived(sender, args)
396 Thurallor-7095
    if (args.ChatType == Turbine.ChatType.Advancement) then
397 Thurallor-7095
        if (string.match(args.Message, Watcher.SkillsChangedStr)) then
398 Thurallor-7095
            -- Trait line changed.  Reread skills lists.
399 Thurallor-7095
            Watcher.playerTrainedSkills.cache = nil;
400 Thurallor-7095
            Watcher.playerUntrainedSkills.cache = nil;
401 Thurallor-7095
        elseif (string.match(args.Message, Watcher.TraitTreeChangedStr)) then
402 Thurallor-7095
            DoDelayedCallback(Turbine.Engine.GetGameTime() + 1.5, "TraitTreeChanged", args);
403 Thurallor-7095
        end
404 Thurallor-7095
    end
405 Thurallor-7095
end
406 Thurallor-7095
 
407 20 Thurallor-7095
local function SkillAdded(sender, args)
408 23 Thurallor-7095
    -- rare occurrence, out-of-combat; efficiency not important
409 35 Thurallor-7095
    GetSkills(Watcher.playerTrainedSkills);
410 Thurallor-7095
    GetSkills(Watcher.playerUntrainedSkills);
411 20 Thurallor-7095
end
412 Thurallor-7095
 
413 Thurallor-7095
local function SkillRemoved(sender, args)
414 23 Thurallor-7095
    -- rare occurrence, out-of-combat; efficiency not important
415 35 Thurallor-7095
    GetSkills(Watcher.playerTrainedSkills);
416 Thurallor-7095
    GetSkills(Watcher.playerUntrainedSkills);
417 20 Thurallor-7095
end
418 Thurallor-7095
 
419 23 Thurallor-7095
local function PartyMemberAdded(sender, args)
420 Thurallor-7095
    -- rare occurrence, out-of-combat; efficiency not important
421 Thurallor-7095
    GetParty();
422 Thurallor-7095
end
423 Thurallor-7095
 
424 Thurallor-7095
local function PartyMemberRemoved(sender, args)
425 Thurallor-7095
    -- rare occurrence, out-of-combat; efficiency not important
426 Thurallor-7095
    GetParty();
427 Thurallor-7095
end
428 Thurallor-7095
 
429 21 Thurallor-7095
local function InCombatChanged()
430 Thurallor-7095
        local inCombat = Watcher.playerObject:IsInCombat();
431 Thurallor-7095
    if (inCombat) then
432 Thurallor-7095
                collectgarbage("stop");
433 Thurallor-7095
    else
434 Thurallor-7095
                collectgarbage("restart");
435 Thurallor-7095
    end
436 Thurallor-7095
        DoCallbacks(Watcher, "InCombatChanged", { InCombat = inCombat });
437 Thurallor-7095
end
438 Thurallor-7095
 
439 Thurallor-7095
local function LoadSettings()
440 Thurallor-7095
--Puts("Loading...");
441 Thurallor-7095
    Turbine.PluginData.Load(Turbine.DataScope.Account, "Thurallor_GameInfo", function(loadData, args)
442 Thurallor-7095
        if (not loadData) then
443 Thurallor-7095
            return;
444 Thurallor-7095
        end
445 Thurallor-7095
 
446 Thurallor-7095
        -- Workaround for Turbine localization bug.
447 Thurallor-7095
        local settings = ImportTable(loadData);
448 Thurallor-7095
        if (not settings) then
449 Thurallor-7095
            return;
450 Thurallor-7095
        end
451 Thurallor-7095
 
452 Thurallor-7095
        -- Previously-saved settings override the defaults
453 Thurallor-7095
        DeepTableCopy(settings, Watcher.settings);
454 Thurallor-7095
 
455 Thurallor-7095
        -- Compile loaded functions
456 Thurallor-7095
        for categories, sourceCode in pairs(settings.funcs.AddCategories) do
457 Thurallor-7095
            Watcher.AddCategories[categories] = loadstring(sourceCode);
458 Thurallor-7095
        end
459 Thurallor-7095
        for categories, sourceCode in pairs(settings.funcs.RemoveCategories) do
460 Thurallor-7095
            Watcher.RemoveCategories[categories] = loadstring(sourceCode);
461 Thurallor-7095
        end
462 Thurallor-7095
 
463 23 Thurallor-7095
        -- Lua API bug workaround: Target effects object will not contain valid
464 Thurallor-7095
        -- data until a few ticks after plugin load.
465 Thurallor-7095
        if (Watcher.targetEffectsObject) then
466 Thurallor-7095
            Watcher.targetEffectsObject.cache = nil;
467 Thurallor-7095
        end
468 Thurallor-7095
 
469 21 Thurallor-7095
        -- Allow save operations to proceed.
470 Thurallor-7095
        Watcher.settingsLoaded = true;
471 Thurallor-7095
        SaveSettings();
472 Thurallor-7095
--Puts("Load complete.");
473 Thurallor-7095
    end);
474 Thurallor-7095
end
475 Thurallor-7095
 
476 35 Thurallor-7095
function Watcher.GetTrainedSkillsInfo()
477 20 Thurallor-7095
    local cache = Watcher.playerTrainedSkills.cache;
478 Thurallor-7095
    if (not cache) then
479 35 Thurallor-7095
        cache = GetSkills(Watcher.playerTrainedSkills);
480 20 Thurallor-7095
    end
481 Thurallor-7095
    return cache;
482 Thurallor-7095
end
483 Thurallor-7095
 
484 35 Thurallor-7095
function Watcher.GetUntrainedSkillsInfo()
485 Thurallor-7095
    local cache = Watcher.playerUntrainedSkills.cache;
486 Thurallor-7095
    if (not cache) then
487 Thurallor-7095
        cache = GetSkills(Watcher.playerUntrainedSkills);
488 Thurallor-7095
    end
489 Thurallor-7095
    return cache;
490 Thurallor-7095
end
491 Thurallor-7095
 
492 43 Thurallor-7095
function Watcher.GetSkillsInfo(trainedSkillsFirst)
493 35 Thurallor-7095
    local trainedSkillsCache = Watcher.GetTrainedSkillsInfo();
494 Thurallor-7095
    local untrainedSkillsCache = Watcher.GetUntrainedSkillsInfo();
495 Thurallor-7095
    if (#untrainedSkillsCache.names > 0) then
496 39 Thurallor-7095
        local cache = { names = {}; byName = {}; byIcon = {} };
497 Thurallor-7095
        for c in values({ trainedSkillsCache, untrainedSkillsCache }) do
498 Thurallor-7095
            for k, v in pairs(c.byIcon) do
499 Thurallor-7095
                cache.byIcon[k] = v;
500 Thurallor-7095
            end
501 Thurallor-7095
            for k, v in pairs(c.byName) do
502 Thurallor-7095
                cache.byName[k] = v;
503 Thurallor-7095
            end
504 Thurallor-7095
            for k, v in pairs(c.names) do
505 Thurallor-7095
                table.insert(cache.names, v);
506 Thurallor-7095
            end
507 35 Thurallor-7095
        end
508 43 Thurallor-7095
        if (not trainedSkillsFirst) then
509 Thurallor-7095
            table.sort(cache.names);
510 Thurallor-7095
        end
511 35 Thurallor-7095
        return cache;
512 Thurallor-7095
    else
513 Thurallor-7095
        return trainedSkillsCache;
514 Thurallor-7095
    end
515 Thurallor-7095
end
516 Thurallor-7095
 
517 34 Thurallor-7095
function Watcher.GetGambitsInfo()
518 Thurallor-7095
    local cache = Watcher.playerTrainedGambits.cache;
519 Thurallor-7095
    if (not cache) then
520 Thurallor-7095
        cache = GetGambits();
521 Thurallor-7095
    end
522 Thurallor-7095
    for name in sorted_keys(cache.byName) do
523 Thurallor-7095
        table.insert(cache.names, name);
524 Thurallor-7095
    end
525 Thurallor-7095
    return cache;
526 Thurallor-7095
end
527 Thurallor-7095
 
528 20 Thurallor-7095
function Watcher.GetKnownEffectNames()
529 Thurallor-7095
    local names = {};
530 Thurallor-7095
    for name in sorted_keys(Watcher.settings.knownEffects) do
531 Thurallor-7095
        table.insert(names, name);
532 Thurallor-7095
    end
533 Thurallor-7095
    return names;
534 Thurallor-7095
end
535 Thurallor-7095
 
536 Thurallor-7095
-- If itemName is specified, the equipped item (if any) with the specified name is returned.
537 Thurallor-7095
-- If itemSlot is specified, the equipped item (if any) at the specified slot is returned.
538 Thurallor-7095
-- If neither is specified, a random equipped item (if any) is returned.
539 Thurallor-7095
-- Returns slot, item (or nil).
540 Thurallor-7095
function Watcher.GetEquippedItem(itemName, itemSlot)
541 Thurallor-7095
    if ((not itemSlot) and (not itemName)) then
542 Thurallor-7095
        for name, byName in pairs(Watcher.playerEquipmentObject.cache.byName) do
543 Thurallor-7095
            local item, slot = unpack(byName);
544 Thurallor-7095
            return slot, item;
545 Thurallor-7095
        end
546 Thurallor-7095
    elseif (not itemSlot) then
547 Thurallor-7095
        local byName = Watcher.playerEquipmentObject.cache.byName[itemName];
548 Thurallor-7095
        if (byName) then
549 Thurallor-7095
            local item, slot = unpack(byName);
550 Thurallor-7095
            return slot, item;
551 Thurallor-7095
        end
552 Thurallor-7095
    elseif (not itemName) then
553 Thurallor-7095
        local bySlot = Watcher.playerEquipmentObject.cache.bySlot[itemSlot];
554 Thurallor-7095
        if (bySlot) then
555 Thurallor-7095
            local item, name = unpack(bySlot);
556 Thurallor-7095
            return itemSlot, item;
557 Thurallor-7095
        end
558 Thurallor-7095
    else -- itemName and itemSlot specified
559 Thurallor-7095
        local bySlot = Watcher.playerEquipmentObject.cache.bySlot[itemSlot];
560 Thurallor-7095
        if (bySlot) then
561 Thurallor-7095
            local item, name = unpack(bySlot);
562 Thurallor-7095
            if (name == itemName) then
563 Thurallor-7095
                return itemSlot, item;
564 Thurallor-7095
            end
565 Thurallor-7095
        end
566 Thurallor-7095
    end
567 Thurallor-7095
end
568 Thurallor-7095
 
569 30 Thurallor-7095
function Watcher.GetItemQuantity(itemName)
570 Thurallor-7095
    local quantity = 0;
571 Thurallor-7095
    local slots = Watcher.playerBackpackObject.cache.byName[itemName];
572 Thurallor-7095
    if (slots) then
573 Thurallor-7095
        for i, s in pairs(slots) do
574 Thurallor-7095
            local item = Watcher.playerBackpackObject:GetItem(s);
575 Thurallor-7095
            if (item) then
576 Thurallor-7095
                quantity = quantity + item:GetQuantity();
577 Thurallor-7095
            end
578 Thurallor-7095
        end
579 Thurallor-7095
    end
580 Thurallor-7095
    return quantity;
581 Thurallor-7095
end
582 Thurallor-7095
 
583 43 Thurallor-7095
-- Can accept either an iconID (number) or a skill name (string).
584 Thurallor-7095
function Watcher.SkillReady(arg)
585 20 Thurallor-7095
    local cache = Watcher.playerTrainedSkills.cache;
586 Thurallor-7095
    if (not cache) then
587 35 Thurallor-7095
        cache = GetSkills(Watcher.playerTrainedSkills);
588 20 Thurallor-7095
    end
589 43 Thurallor-7095
    if (type(arg) == "string") then
590 Thurallor-7095
        skill = cache.byName[arg];
591 Thurallor-7095
    elseif (type(arg) == "number") then
592 Thurallor-7095
        skill = cache.byIcon[arg];
593 Thurallor-7095
    end
594 22 Thurallor-7095
--    return (skill and skill:IsUsable() and (skill:GetResetTime() == -1));
595 Thurallor-7095
    return (skill and (skill:GetResetTime() == -1));
596 20 Thurallor-7095
end
597 Thurallor-7095
 
598 41 Thurallor-7095
-- Can accept either an iconID (number) or a skill name (string).
599 48 Thurallor-7095
function Watcher.SkillUsable(arg)
600 Thurallor-7095
    local cache = Watcher.playerTrainedSkills.cache;
601 Thurallor-7095
    if (not cache) then
602 Thurallor-7095
        cache = GetSkills(Watcher.playerTrainedSkills);
603 Thurallor-7095
    end
604 Thurallor-7095
    if (type(arg) == "string") then
605 Thurallor-7095
        skill = cache.byName[arg];
606 Thurallor-7095
    elseif (type(arg) == "number") then
607 Thurallor-7095
        skill = cache.byIcon[arg];
608 Thurallor-7095
    end
609 Thurallor-7095
    return (skill and skill:IsUsable());
610 Thurallor-7095
end
611 Thurallor-7095
 
612 Thurallor-7095
-- Can accept either an iconID (number) or a skill name (string).
613 41 Thurallor-7095
function Watcher.SkillTrained(arg)
614 Thurallor-7095
    local cache, skill = Watcher.playerTrainedSkills.cache;
615 35 Thurallor-7095
    if (not cache) then
616 Thurallor-7095
        cache = GetSkills(Watcher.playerTrainedSkills);
617 Thurallor-7095
    end
618 41 Thurallor-7095
    if (type(arg) == "string") then
619 Thurallor-7095
        skill = cache.byName[arg];
620 Thurallor-7095
    elseif (type(arg) == "number") then
621 Thurallor-7095
        skill = cache.byIcon[arg];
622 Thurallor-7095
    end
623 35 Thurallor-7095
    return (skill ~= nil);
624 Thurallor-7095
end
625 Thurallor-7095
 
626 47 Thurallor-7095
function PlayerHasEffectCategory(category)
627 22 Thurallor-7095
    if (category) then
628 20 Thurallor-7095
        return Watcher.playerEffectsObject.activeCategories[category] > 0;
629 Thurallor-7095
    end
630 Thurallor-7095
end
631 Thurallor-7095
 
632 22 Thurallor-7095
function Watcher.PlayerHasEffectCategory(category)
633 Thurallor-7095
    -- Start watching player effects.
634 Thurallor-7095
    Watcher.playerEffectsObject = Watcher.playerObject:GetEffects();
635 23 Thurallor-7095
    AddCallback(Watcher.playerEffectsObject, "EffectAdded", PlayerEffectAdded);
636 Thurallor-7095
    AddCallback(Watcher.playerEffectsObject, "EffectRemoved", PlayerEffectRemoved);
637 Thurallor-7095
    AddCallback(Watcher.playerEffectsObject, "EffectsCleared", PlayerEffectsCleared);
638 22 Thurallor-7095
    GetActorEffects(Watcher.playerEffectsObject);
639 Thurallor-7095
 
640 Thurallor-7095
    -- Next time this function is called, we don't need to do the above again.
641 Thurallor-7095
    Watcher.PlayerHasEffectCategory = PlayerHasEffectCategory;
642 Thurallor-7095
    Watcher.PlayerHasEffect = PlayerHasEffect;
643 Thurallor-7095
 
644 Thurallor-7095
    return PlayerHasEffectCategory(category);
645 Thurallor-7095
end
646 Thurallor-7095
 
647 47 Thurallor-7095
function PlayerHasEffect(name)
648 22 Thurallor-7095
    if (name) then
649 21 Thurallor-7095
        return Watcher.playerEffectsObject.cache[name];
650 Thurallor-7095
    end
651 20 Thurallor-7095
end
652 Thurallor-7095
 
653 22 Thurallor-7095
function Watcher.PlayerHasEffect(name)
654 Thurallor-7095
    -- Start watching player effects.
655 Thurallor-7095
    Watcher.playerEffectsObject = Watcher.playerObject:GetEffects();
656 23 Thurallor-7095
    AddCallback(Watcher.playerEffectsObject, "EffectAdded", PlayerEffectAdded);
657 Thurallor-7095
    AddCallback(Watcher.playerEffectsObject, "EffectRemoved", PlayerEffectRemoved);
658 Thurallor-7095
    AddCallback(Watcher.playerEffectsObject, "EffectsCleared", PlayerEffectsCleared);
659 22 Thurallor-7095
    GetActorEffects(Watcher.playerEffectsObject);
660 Thurallor-7095
 
661 Thurallor-7095
    -- Next time this function is called, we don't need to do the above again.
662 Thurallor-7095
    Watcher.PlayerHasEffectCategory = PlayerHasEffectCategory;
663 Thurallor-7095
    Watcher.PlayerHasEffect = PlayerHasEffect;
664 Thurallor-7095
 
665 Thurallor-7095
    return PlayerHasEffect(name);
666 Thurallor-7095
end
667 Thurallor-7095
 
668 20 Thurallor-7095
function Watcher.TargetHasEffectCategory(category)
669 23 Thurallor-7095
 
670 Thurallor-7095
    -- Target effects tracking is so buggy as to be useless.  Hoping Turbine addresses this bug soon.
671 Thurallor-7095
    if (true) then
672 Thurallor-7095
        return false;
673 Thurallor-7095
    end
674 Thurallor-7095
 
675 Thurallor-7095
    if (not Watcher.targetEffectsObject) then
676 22 Thurallor-7095
        -- No target, or target isn't one whose effects can be read.
677 Thurallor-7095
        return false;
678 20 Thurallor-7095
    end
679 23 Thurallor-7095
    if (not Watcher.targetEffectsObject.cache) then
680 Thurallor-7095
        -- Bug workaround: Since EffectRemoved event never fires for target
681 Thurallor-7095
        -- effects, we must reread the list every time it is queried.
682 Thurallor-7095
        GetActorEffects(Watcher.targetEffectsObject);
683 Thurallor-7095
        Watcher.window:SetWantsUpdates(true); -- to delete the cache at next Update cycle
684 Thurallor-7095
    end
685 Thurallor-7095
    return Watcher.targetEffectsObject.activeCategories[category] > 0;
686 20 Thurallor-7095
end
687 Thurallor-7095
 
688 Thurallor-7095
function Watcher.TargetHasEffect(name)
689 23 Thurallor-7095
 
690 Thurallor-7095
    -- Target effects tracking is so buggy as to be useless.  Hoping Turbine addresses this bug soon.
691 Thurallor-7095
    if (true) then
692 Thurallor-7095
        return false;
693 Thurallor-7095
    end
694 Thurallor-7095
 
695 Thurallor-7095
    if (not Watcher.targetEffectsObject) then
696 22 Thurallor-7095
        -- No target, or target isn't one whose effects can be read.
697 Thurallor-7095
        return false;
698 21 Thurallor-7095
    end
699 23 Thurallor-7095
    if (not Watcher.targetEffectsObject.cache) then
700 Thurallor-7095
        -- Bug workaround: Since EffectRemoved event never fires for target
701 Thurallor-7095
        -- effects, we must reread the list every time it is queried.
702 Thurallor-7095
        GetActorEffects(Watcher.targetEffectsObject);
703 Thurallor-7095
        Watcher.window:SetWantsUpdates(true); -- to delete the cache at next Update cycle
704 Thurallor-7095
    end
705 Thurallor-7095
    return Watcher.targetEffectsObject.cache[name];
706 20 Thurallor-7095
end
707 Thurallor-7095
 
708 118 Thurallor-7095
function Watcher.GetStance()
709 Thurallor-7095
    return Watcher.stance;
710 Thurallor-7095
end
711 Thurallor-7095
 
712 121 Thurallor-7095
function Watcher.TraitTreeChanged()
713 Thurallor-7095
    -- Trait line changed.  Reread skills lists.
714 Thurallor-7095
    Watcher.playerTrainedSkills.cache = nil;
715 Thurallor-7095
    Watcher.playerUntrainedSkills.cache = nil;
716 Thurallor-7095
end
717 Thurallor-7095
 
718 20 Thurallor-7095
local function Constructor()
719 Thurallor-7095
 
720 Thurallor-7095
    -- Default settings
721 Thurallor-7095
    Watcher.settings = {};
722 Thurallor-7095
    Watcher.settings.knownEffects = {};
723 Thurallor-7095
    Watcher.settings.funcs = {};
724 Thurallor-7095
    Watcher.settings.funcs.AddCategories = {};
725 Thurallor-7095
    Watcher.settings.funcs.RemoveCategories = {};
726 Thurallor-7095
 
727 Thurallor-7095
    -- Optimized functions generated on-the-fly
728 Thurallor-7095
    Watcher.AddCategories = {};
729 Thurallor-7095
    Watcher.RemoveCategories = {};
730 Thurallor-7095
 
731 Thurallor-7095
    -- Object for monitoring display updates:
732 23 Thurallor-7095
    Watcher.window = Turbine.UI.Window();
733 Thurallor-7095
    function Watcher.window:Update()
734 35 Thurallor-7095
        self:SetWantsUpdates(false);
735 23 Thurallor-7095
        if (Watcher.saveRequested) then
736 Thurallor-7095
            DoSave();
737 Thurallor-7095
            Watcher.saveRequested = false;
738 Thurallor-7095
        end
739 Thurallor-7095
        if (Watcher.targetEffectsObject) then
740 Thurallor-7095
            Watcher.targetEffectsObject.cache = nil;
741 Thurallor-7095
        end
742 35 Thurallor-7095
        if (Watcher.delayedCallbacks) then
743 Thurallor-7095
            local notyet = {};
744 Thurallor-7095
            for k, v in pairs(Watcher.delayedCallbacks) do
745 Thurallor-7095
                if (Turbine.Engine.GetGameTime() >= v.time) then
746 Thurallor-7095
                    DoCallbacks(Watcher, v.event, v.args);
747 Thurallor-7095
                else
748 Thurallor-7095
                    table.insert(notyet, v);
749 Thurallor-7095
                end
750 Thurallor-7095
            end
751 Thurallor-7095
            Watcher.delayedCallbacks = nil;
752 Thurallor-7095
            if (#notyet > 0) then
753 Thurallor-7095
                Watcher.delayedCallbacks = notyet;
754 Thurallor-7095
            self:SetWantsUpdates(true);
755 Thurallor-7095
            end
756 Thurallor-7095
        end
757 23 Thurallor-7095
    end
758 Thurallor-7095
 
759 20 Thurallor-7095
    -- Object for monitoring player events
760 Thurallor-7095
    Watcher.playerObject = Turbine.Gameplay.LocalPlayer:GetInstance();
761 21 Thurallor-7095
    AddCallback(Watcher.playerObject, "InCombatChanged", InCombatChanged);
762 23 Thurallor-7095
    AddCallback(Watcher.playerObject, "PartyChanged", PlayerPartyChanged);
763 20 Thurallor-7095
    AddCallback(Watcher.playerObject, "TargetChanged", PlayerTargetChanged);
764 23 Thurallor-7095
    PlayerPartyChanged();
765 20 Thurallor-7095
    PlayerTargetChanged();
766 Thurallor-7095
 
767 Thurallor-7095
    Watcher.playerEquipmentObject = Watcher.playerObject:GetEquipment();
768 Thurallor-7095
    AddCallback(Watcher.playerEquipmentObject, "ItemEquipped", ItemEquipped);
769 Thurallor-7095
    AddCallback(Watcher.playerEquipmentObject, "ItemUnequipped", ItemUnequipped);
770 Thurallor-7095
    GetEquipment();
771 Thurallor-7095
 
772 Thurallor-7095
    Watcher.playerBackpackObject = Watcher.playerObject:GetBackpack();
773 Thurallor-7095
    AddCallback(Watcher.playerBackpackObject, "ItemAdded", ItemAdded);
774 Thurallor-7095
    AddCallback(Watcher.playerBackpackObject, "ItemRemoved", ItemRemoved);
775 Thurallor-7095
    AddCallback(Watcher.playerBackpackObject, "ItemMoved", ItemMoved);
776 30 Thurallor-7095
    AddCallback(Watcher.playerBackpackObject, "SizeChanged", BackpackSizeChanged);
777 20 Thurallor-7095
    GetBackpack();
778 Thurallor-7095
 
779 Thurallor-7095
    Watcher.playerTrainedSkills = Watcher.playerObject:GetTrainedSkills();
780 Thurallor-7095
    AddCallback(Watcher.playerTrainedSkills, "SkillAdded", PlayerSkillAdded);
781 Thurallor-7095
    AddCallback(Watcher.playerTrainedSkills, "SkillRemoved", PlayerSkillRemoved);
782 35 Thurallor-7095
    GetSkills(Watcher.playerTrainedSkills);
783 34 Thurallor-7095
 
784 35 Thurallor-7095
    Watcher.playerUntrainedSkills = Watcher.playerObject:GetUntrainedSkills();
785 Thurallor-7095
    GetSkills(Watcher.playerUntrainedSkills);
786 Thurallor-7095
 
787 34 Thurallor-7095
    Watcher.playerClassAttributes = Watcher.playerObject:GetClassAttributes();
788 Thurallor-7095
    if (Watcher.playerObject:GetClass() == Turbine.Gameplay.Class.Warden) then
789 Thurallor-7095
        Watcher.playerTrainedGambits = Watcher.playerClassAttributes:GetTrainedGambits();
790 Thurallor-7095
    else
791 Thurallor-7095
        Watcher.playerTrainedGambits = {};
792 Thurallor-7095
    end
793 35 Thurallor-7095
 
794 118 Thurallor-7095
    -- Lua API bug workaround:
795 Thurallor-7095
    -- Need to cache the GetStance() result, because it returns incorrect values
796 Thurallor-7095
    -- after the user changes trait trees, until he selects a new stance.
797 Thurallor-7095
    if (Watcher.playerClassAttributes.GetStance) then
798 Thurallor-7095
        Watcher.stance = Watcher.playerClassAttributes:GetStance();
799 120 Thurallor-7095
        Watcher.playerClassAttributes.StanceChanged = StanceChanged;
800 118 Thurallor-7095
    end
801 Thurallor-7095
 
802 35 Thurallor-7095
    -- For monitoring chat messages
803 Thurallor-7095
    AddCallback(Turbine.Chat, "Received", ChatReceived);
804 Thurallor-7095
    local language = Turbine.Engine:GetLanguage();
805 Thurallor-7095
    if ((language == Turbine.Language.EnglishGB) or (language == Turbine.Language.English)) then
806 Thurallor-7095
        Watcher.SkillsChangedStr = "^You have acquired the .* skill%.";
807 Thurallor-7095
        Watcher.TraitTreeChangedStr = "^You have acquired the Class Specialization Bonus Trait";
808 Thurallor-7095
    elseif (language == Turbine.Language.German) then
809 Thurallor-7095
        Watcher.SkillsChangedStr = "^Ihr habt Euch die Fertigkeit .* angeeignet%.";
810 Thurallor-7095
        Watcher.TraitTreeChangedStr = "^Ihr habt diese Bonus-Eigenschaft für Klassenspezialisierung erlangt";
811 Thurallor-7095
    elseif (language == Turbine.Language.French) then
812 Thurallor-7095
        Watcher.SkillsChangedStr = "^Vous avez acquis la compétence .*%.";
813 Thurallor-7095
        Watcher.TraitTreeChangedStr = "^Vous avez obtenu le trait bonus de spécialisation de classe";
814 Thurallor-7095
    end
815 20 Thurallor-7095
end
816 Thurallor-7095
 
817 35 Thurallor-7095
 
818 20 Thurallor-7095
-- Create single instance and load saved settings (if any).
819 Thurallor-7095
Constructor();
820 Thurallor-7095
LoadSettings();
821 22 Thurallor-7095
 
822 Thurallor-7095
 
823 Thurallor-7095
--t = Turbine.UI.Window();
824 Thurallor-7095
--t:SetVisible(true);
825 Thurallor-7095
--t:SetBackColor(Turbine.UI.Color.Red);
826 Thurallor-7095
--t:SetMouseVisible(true);
827 Thurallor-7095
--function t:MouseClick()
828 Thurallor-7095
--    Puts("cache = " .. PrettyPrint(Watcher.playerEffectsObject.cache, ""));
829 Thurallor-7095
--end

All times are GMT -5. The time now is 02:21 PM.


Our Network
EQInterface | EQ2Interface | Minion | WoWInterface | ESOUI | LoTROInterface | MMOUI | Swtorui