vanilla-wow-addons – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | -- 09/04/2005 12:30:49 PIng: Replace hardcoded strings for UI by localized variables |
2 | -- 09/04/2005 12:31:41 PIng: Bug fix. Replace ShM_PrintMessage by SkM_PrintMessage |
||
3 | -- 09/04/2005 15:52:09 PIng: Add guild support |
||
4 | -- 09/04/2005 16:18:34 PIng: Update war info on target frame when status is changed |
||
5 | |||
6 | SKM_UNIT_PLAYER = "player"; |
||
7 | SKM_UNIT_TARGET = "target"; |
||
8 | SKM_UNIT_MOUSEOVER = "mouseover"; |
||
9 | SKM_UNIT_PARTY = "party"; |
||
10 | SKM_UNIT_PET = "pet"; |
||
11 | |||
12 | SKM_UNIT_PARTY_1 = SKM_UNIT_PARTY.."1"; |
||
13 | SKM_UNIT_PARTY_2 = SKM_UNIT_PARTY.."2"; |
||
14 | SKM_UNIT_PARTY_3 = SKM_UNIT_PARTY.."3"; |
||
15 | SKM_UNIT_PARTY_4 = SKM_UNIT_PARTY.."4"; |
||
16 | |||
17 | |||
18 | |||
19 | _RealmName = nil; |
||
20 | _PlayerName = nil; |
||
21 | |||
22 | |||
23 | SKM_MAX_MAP_NOTES = 200; |
||
24 | |||
25 | |||
26 | local TXT_NIL = "nil"; |
||
27 | |||
28 | local SKM_MESSAGE_PREFIX = "SKM: "; |
||
29 | |||
30 | local SKM_TRACE_MODE_NONE = 0; |
||
31 | local SKM_TRACE_MODE_PRINT = 1; |
||
32 | local SKM_TRACE_MODE_CHATMSG = 2; |
||
33 | |||
34 | local SKM_TRACE_NIL = false; |
||
35 | |||
36 | local TXT_NIL = "nil"; |
||
37 | |||
38 | --local SKM_TRACE_MODE = SKM_TRACE_MODE_NONE; |
||
39 | --local SKM_TRACE_MODE = SKM_TRACE_MODE_PRINT; |
||
40 | local SKM_TRACE_MODE = SKM_TRACE_MODE_CHATMSG; |
||
41 | |||
42 | |||
43 | |||
44 | -- number of days in a month for a non leap year |
||
45 | local DaysInMonth = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; |
||
46 | |||
47 | -- list of leap years for the first half of the 21st century |
||
48 | local LeapYears = { 2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036, 2040, 2044, 2048 }; |
||
49 | |||
50 | |||
51 | |||
52 | -- List of ennemy player factions races (alliance and horde) |
||
53 | -- (could easily add more by altering the list, though it probably won't happen !) |
||
54 | SKM_PlayerFaction = { |
||
55 | { Faction = "Alliance", |
||
56 | RaceList = { SKM_RACE.Dwarf, SKM_RACE.Gnome, SKM_RACE.Human, SKM_RACE.NightElf } |
||
57 | }; |
||
58 | |||
59 | { Faction = "Horde", |
||
60 | RaceList = { SKM_RACE.Orc, SKM_RACE.Tauren, SKM_RACE.Troll, SKM_RACE.Undead } |
||
61 | }; |
||
62 | }; |
||
63 | |||
64 | SKM_HonorKillPerDay = 4; |
||
65 | |||
66 | |||
67 | SKM_ToStandardCase = { |
||
68 | ["A"] = { "\195\128", "\195\129", "\195\130", "\195\131", "\195\132", "\195\133" }, |
||
69 | ["E"] = { "\195\136", "\195\137", "\195\138", "\195\139"}, |
||
70 | ["I"] = { "\195\140", "\195\141", "\195\142", "\195\143"}, |
||
71 | ["O"] = { "\195\146", "\195\147", "\195\148", "\195\149", "\195\150", "\195\152" }, |
||
72 | ["U"] = { "\195\153", "\195\154", "\195\155", "\195\156" }, |
||
73 | ["Y"] = { "\195\157", "\195\191", "\197\184" }, |
||
74 | |||
75 | ["C"] = { "\195\135" }, |
||
76 | ["D"] = { "\195\144" }, |
||
77 | ["N"] = { "\195\145" }, |
||
78 | ["S"] = { "\197\160", "\197\161"} |
||
79 | }; |
||
80 | |||
81 | |||
82 | SKM_GuildChannelPrefix = "SKM"; |
||
83 | |||
84 | |||
85 | |||
86 | -- OLD table indexes - before data migration - SKMap 1.4 |
||
87 | -- ----------------------------------------------------- |
||
88 | _SKM_OLD = { |
||
89 | _name = "name"; |
||
90 | _class = "class"; |
||
91 | _guild = "guild"; |
||
92 | _race = "race"; |
||
93 | _level = "level"; |
||
94 | |||
95 | _playerNote = "playerNote"; |
||
96 | |||
97 | _playerKill = "playerKill"; |
||
98 | _playerAssistKill = "playerAssistKill"; |
||
99 | _playerFullKill = "playerFullKill"; |
||
100 | |||
101 | _honorKill = "honorKill"; |
||
102 | _honorCount = "honorCount"; |
||
103 | _honorLastKill = "honorLastKill"; |
||
104 | _rank = "rank"; |
||
105 | |||
106 | _meetCount = "meetCount"; |
||
107 | _atWar = "atWar"; |
||
108 | -- _guildAtWar = "guildAtWar"; |
||
109 | _warDate = "warDate"; |
||
110 | |||
111 | _continent = "continent"; |
||
112 | _zone = "zone"; |
||
113 | _xPos = "xPos"; |
||
114 | _yPos = "yPos"; |
||
115 | _zoneName = "zoneName"; |
||
116 | |||
117 | -- _lastUpdate = "lastUpdate"; |
||
118 | _lastView = "lastView"; |
||
119 | _lastPlayerViewed = "lastPlayerViewed"; |
||
120 | |||
121 | _enemyKillPlayer = "enemyKillPlayer"; |
||
122 | _enemyKillBG = "enemyKillBG"; |
||
123 | _playerBGKill = "playerBGKill"; |
||
124 | |||
125 | _members = "members"; |
||
126 | |||
127 | _type = "type"; |
||
128 | _date = "date"; |
||
129 | _enemyType = "enemyType"; |
||
130 | _enemyPlayer = "enemyPlayer"; |
||
131 | _enemyCreature = "enemyCreature"; |
||
132 | |||
133 | _playerDeath = "playerDeath"; |
||
134 | _playerDeathPvP = "playerDeathPvP"; |
||
135 | _playerDeathPvE = "playerDeathPvE"; |
||
136 | _creatureKill_Target = "creatureKill_Target"; |
||
137 | _creatureKill_Xp = "creatureKill_Xp"; |
||
138 | _levelUp = "levelUp"; |
||
139 | |||
140 | _loneWolfKill = "loneWolfKill"; |
||
141 | |||
142 | _storedInfo = "storedInfo"; |
||
143 | |||
144 | _win = "win"; |
||
145 | _loss = "loss"; |
||
146 | _duel = "duel"; |
||
147 | _lastDuel = "lastDuel"; |
||
148 | -- _score = "score"; |
||
149 | }; |
||
150 | |||
151 | -- new table indexes - after data migration - SKMap 1.4 |
||
152 | -- ---------------------------------------------------- |
||
153 | _SKM = { |
||
154 | _name = "Na"; |
||
155 | _class = "Cl"; |
||
156 | _guild = "Gu"; |
||
157 | _race = "Ra"; |
||
158 | _level = "Lv"; |
||
159 | |||
160 | _playerNote = "PlN"; |
||
161 | |||
162 | _playerKill = "PK"; |
||
163 | _playerAssistKill = "PaK"; |
||
164 | _playerFullKill = "PfK"; |
||
165 | |||
166 | _honorKill = "hK"; |
||
167 | _honorCount = "hC"; |
||
168 | _honorLastKill = "hLK"; |
||
169 | _rank = "Rk"; |
||
170 | |||
171 | _meetCount = "mC"; |
||
172 | _atWar = "Wr"; |
||
173 | _guildAtWar = "gWr"; -- not saved |
||
174 | _warDate = "WD"; |
||
175 | |||
176 | _continent = "Co"; |
||
177 | _zone = "Zo"; |
||
178 | _xPos = "x"; |
||
179 | _yPos = "y"; |
||
180 | _zoneName = "ZN"; |
||
181 | |||
182 | _lastUpdate = "lU"; -- not saved |
||
183 | _lastView = "lV"; |
||
184 | _lastPlayerViewed = "lPV"; |
||
185 | |||
186 | |||
187 | _enemyKillPlayer = "EKP"; |
||
188 | _enemyKillBG = "EKb"; |
||
189 | _playerBGKill = "PbK"; |
||
190 | |||
191 | _members = "Mb"; -- not saved |
||
192 | |||
193 | _type = "Ty"; |
||
194 | _date = "Da"; |
||
195 | _enemyType = "ETy"; |
||
196 | _enemyPlayer = "EPl"; |
||
197 | _enemyCreature = "ECr"; |
||
198 | |||
199 | _playerDeath = "PD"; |
||
200 | _playerDeathPvP = "PDp"; |
||
201 | _playerDeathPvE = "PDc"; |
||
202 | _creatureKill_Target = "CKt"; |
||
203 | _creatureKill_Xp = "CKx"; |
||
204 | _levelUp = "LvU"; |
||
205 | |||
206 | _loneWolfKill = "LwK"; |
||
207 | |||
208 | _storedInfo = "Inf"; |
||
209 | |||
210 | _win = "Win"; |
||
211 | _loss = "Los"; |
||
212 | _duel = "Du"; |
||
213 | _lastDuel = "lDu"; |
||
214 | _score = "Scr"; -- not saved |
||
215 | |||
216 | |||
217 | -- following indexes are for temporary use (ie not saved in SavedVariables.lua, so it's |
||
218 | -- not as important if they're a bit longer) |
||
219 | |||
220 | _noteIndex = "NIn"; |
||
221 | _default = "Def"; |
||
222 | _multiType = "MTy"; |
||
223 | _playerKillAndDeath = "PKaD"; |
||
224 | |||
225 | _totalDamage = "tDm"; |
||
226 | _groupDamage = "gDm"; |
||
227 | _lastHateUpdate = "lHU"; |
||
228 | _hateLevel = "HLv"; |
||
229 | _damage = "Dm"; |
||
230 | _hatePercent = "HPct"; |
||
231 | |||
232 | _time = "Ti"; |
||
233 | |||
234 | _owner = "Own"; |
||
235 | _player = "Ply"; |
||
236 | _other = "Oth"; |
||
237 | |||
238 | _players = "players"; |
||
239 | _guilds = "guilds"; |
||
240 | _duels = "duels"; |
||
241 | |||
242 | _bookCredits = "bookCredits"; |
||
243 | _bookGeneralStat = "bookGeneralStat"; |
||
244 | _bookClassStat = "bookClassStat"; |
||
245 | _bookRaceStat = "bookRaceStat"; |
||
246 | _bookPlayerStat = "bookPlayerStat"; |
||
247 | _bookGuildStat = "bookGuildStat"; |
||
248 | _bookMapStat = "bookMapStat"; |
||
249 | _bookDateStat = "bookDateStat"; |
||
250 | |||
251 | _bookBGDateMapStat = "bookBGDateMapStat"; |
||
252 | _bookBGDateStat = "bookBGDateStat"; |
||
253 | _bookBGMapStat = "bookBGMapStat"; |
||
254 | |||
255 | _checkButton = "CBtn"; |
||
256 | _slider = "Slid"; |
||
257 | |||
258 | }; |
||
259 | |||
260 | |||
261 | |||
262 | SKM_IndexMigr = { |
||
263 | [2] = { |
||
264 | EnemyHistory = { |
||
265 | {Old=_SKM_OLD._name, New=_SKM._name}, |
||
266 | {Old=_SKM_OLD._class, New=_SKM._class}, |
||
267 | {Old=_SKM_OLD._guild, New=_SKM._guild}, |
||
268 | {Old=_SKM_OLD._race, New=_SKM._race}, |
||
269 | {Old=_SKM_OLD._level, New=_SKM._level}, |
||
270 | {Old=_SKM_OLD._playerNote, New=_SKM._playerNote}, |
||
271 | {Old=_SKM_OLD._playerKill, New=_SKM._playerKill}, |
||
272 | {Old=_SKM_OLD._playerAssistKill, New=_SKM._playerAssistKill}, |
||
273 | {Old=_SKM_OLD._playerFullKill, New=_SKM._playerFullKill}, |
||
274 | {Old=_SKM_OLD._honorKill, New=_SKM._honorKill}, |
||
275 | {Old=_SKM_OLD._honorCount, New=_SKM._honorCount}, |
||
276 | {Old=_SKM_OLD._honorLastKill, New=_SKM._honorLastKill}, |
||
277 | {Old=_SKM_OLD._rank, New=_SKM._rank}, |
||
278 | {Old=_SKM_OLD._meetCount, New=_SKM._meetCount}, |
||
279 | {Old=_SKM_OLD._atWar, New=_SKM._atWar}, |
||
280 | {Old=_SKM_OLD._warDate, New=_SKM._warDate}, |
||
281 | {Old=_SKM_OLD._continent, New=_SKM._continent}, |
||
282 | {Old=_SKM_OLD._zone, New=_SKM._zone}, |
||
283 | {Old=_SKM_OLD._xPos, New=_SKM._xPos}, |
||
284 | {Old=_SKM_OLD._yPos, New=_SKM._yPos}, |
||
285 | {Old=_SKM_OLD._zoneName, New=_SKM._zoneName}, |
||
286 | -- {Old=_SKM_OLD._lastUpdate, New=_SKM._lastUpdate}, |
||
287 | {Old=_SKM_OLD._lastView, New=_SKM._lastView}, |
||
288 | {Old=_SKM_OLD._enemyKillPlayer, New=_SKM._enemyKillPlayer}, |
||
289 | {Old=_SKM_OLD._enemyKillBG, New=_SKM._enemyKillBG}, |
||
290 | {Old=_SKM_OLD._playerBGKill, New=_SKM._playerBGKill}, |
||
291 | }; |
||
292 | GuildHistory = { |
||
293 | {Old=_SKM_OLD._name, New=_SKM._name}, |
||
294 | -- {Old=_SKM_OLD._members, New=_SKM._members}, |
||
295 | {Old=_SKM_OLD._meetCount, New=_SKM._meetCount}, |
||
296 | {Old=_SKM_OLD._atWar, New=_SKM._atWar}, |
||
297 | {Old=_SKM_OLD._warDate, New=_SKM._warDate}, |
||
298 | {Old=_SKM_OLD._playerKill, New=_SKM._playerKill}, |
||
299 | {Old=_SKM_OLD._playerAssistKill, New=_SKM._playerAssistKill}, |
||
300 | {Old=_SKM_OLD._playerFullKill, New=_SKM._playerFullKill}, |
||
301 | {Old=_SKM_OLD._enemyKillPlayer, New=_SKM._enemyKillPlayer}, |
||
302 | {Old=_SKM_OLD._lastView, New=_SKM._lastView}, |
||
303 | {Old=_SKM_OLD._lastPlayerViewed, New=_SKM._lastPlayerViewed}, |
||
304 | }; |
||
305 | GlobalMapData = { |
||
306 | {Old=_SKM_OLD._continent, New=_SKM._continent}, |
||
307 | {Old=_SKM_OLD._zone, New=_SKM._zone}, |
||
308 | {Old=_SKM_OLD._xPos, New=_SKM._xPos}, |
||
309 | {Old=_SKM_OLD._yPos, New=_SKM._yPos}, |
||
310 | {Old=_SKM_OLD._storedInfo, New=_SKM._storedInfo}, |
||
311 | }; |
||
312 | StoredInfo = { |
||
313 | {Old=_SKM_OLD._type, New=_SKM._type}, |
||
314 | {Old=_SKM_OLD._date, New=_SKM._date}, |
||
315 | {Old=_SKM_OLD._name, New=_SKM._name}, |
||
316 | {Old=_SKM_OLD._level, New=_SKM._level}, |
||
317 | {Old=_SKM_OLD._enemyType, New=_SKM._enemyType}, |
||
318 | {Old=_SKM_OLD._loneWolfKill, New=_SKM._loneWolfKill}, |
||
319 | {Old=_SKM_OLD._honorKill, New=_SKM._honorKill}, |
||
320 | }; |
||
321 | EnemyType = { |
||
322 | [_SKM_OLD._enemyPlayer] = _SKM._enemyPlayer; |
||
323 | [_SKM_OLD._enemyCreature] = _SKM._enemyCreature; |
||
324 | }; |
||
325 | RecordType = { |
||
326 | |||
327 | [_SKM_OLD._playerKill] = _SKM._playerKill; |
||
328 | [_SKM_OLD._playerAssistKill] = _SKM._playerAssistKill; |
||
329 | [_SKM_OLD._playerFullKill] = _SKM._playerFullKill; |
||
330 | [_SKM_OLD._playerDeath] = _SKM._playerDeath; |
||
331 | [_SKM_OLD._playerDeathPvP] = _SKM._playerDeathPvP; |
||
332 | [_SKM_OLD._playerDeathPvE] = _SKM._playerDeathPvE; |
||
333 | [_SKM_OLD._creatureKill_Target] = _SKM._creatureKill_Target; |
||
334 | [_SKM_OLD._creatureKill_Xp] = _SKM._creatureKill_Xp; |
||
335 | [_SKM_OLD._levelUp] = _SKM._levelUp; |
||
336 | }; |
||
337 | DuelHistory = { |
||
338 | {Old=_SKM_OLD._name, New=_SKM._name}, |
||
339 | {Old=_SKM_OLD._class, New=_SKM._class}, |
||
340 | {Old=_SKM_OLD._guild, New=_SKM._guild}, |
||
341 | {Old=_SKM_OLD._race, New=_SKM._race}, |
||
342 | {Old=_SKM_OLD._level, New=_SKM._level}, |
||
343 | {Old=_SKM_OLD._playerNote, New=_SKM._playerNote}, |
||
344 | {Old=_SKM_OLD._win, New=_SKM._win}, |
||
345 | {Old=_SKM_OLD._loss, New=_SKM._loss}, |
||
346 | {Old=_SKM_OLD._duel, New=_SKM._duel}, |
||
347 | {Old=_SKM_OLD._lastDuel, New=_SKM._lastDuel}, |
||
348 | }; |
||
349 | BGStatDate = { |
||
350 | {Old=_SKM_OLD._enemyKillBG, New=_SKM._enemyKillBG}, |
||
351 | {Old=_SKM_OLD._playerBGKill, New=_SKM._playerBGKill}, |
||
352 | }; |
||
353 | }; |
||
354 | |||
355 | }; |
||
356 | |||
357 | |||
358 | |||
359 | |||
360 | |||
361 | |||
362 | |||
363 | --_time = "time"; |
||
364 | |||
365 | --_type = "type"; |
||
366 | |||
367 | --_name = "name"; |
||
368 | --_class = "class"; |
||
369 | --_guild = "guild"; -- PIng: Add guild support |
||
370 | --_race = "race"; |
||
371 | --_level = "level"; |
||
372 | --_date = "date"; |
||
373 | --_sortdate = "sortdate"; |
||
374 | |||
375 | --_killedBy = "killBy"; |
||
376 | |||
377 | --_playerNote = "playerNote"; |
||
378 | |||
379 | --_noteIndex = "noteIndex"; |
||
380 | |||
381 | --_icon_PlayerKill = "icon_PlayerKill"; |
||
382 | --_icon_PlayerDeath = "icon_PlayerDeath"; |
||
383 | |||
384 | -- type of map events |
||
385 | --_playerKill = "playerKill"; |
||
386 | --_playerAssistKill = "playerAssistKill"; |
||
387 | --_playerFullKill = "playerFullKill"; |
||
388 | --_playerDeath = "playerDeath"; |
||
389 | --_playerDeathPvP = "playerDeathPvP"; |
||
390 | --_playerDeathPvE = "playerDeathPvE"; |
||
391 | --_creatureKill_Target = "creatureKill_Target"; |
||
392 | --_creatureKill_Xp = "creatureKill_Xp"; |
||
393 | --_levelUp = "levelUp"; |
||
394 | |||
395 | --_loneWolfKill = "loneWolfKill"; |
||
396 | |||
397 | --_honorKill = "honorKill"; |
||
398 | --_honorCount = "honorCount"; |
||
399 | --_honorLastKill = "honorLastKill"; |
||
400 | --_rank = "rank"; |
||
401 | |||
402 | --_win = "win"; |
||
403 | --_loss = "loss"; |
||
404 | --_duel = "duel"; |
||
405 | --_lastDuel = "lastDuel"; |
||
406 | --_score = "score"; |
||
407 | |||
408 | --_default = "default"; |
||
409 | --_multiType = "multiType"; |
||
410 | --_playerKillAndDeath = "playerKillAndDeath"; |
||
411 | |||
412 | --_enemyKillPlayer = "enemyKillPlayer"; |
||
413 | |||
414 | --_enemyKillBG = "enemyKillBG"; |
||
415 | --_playerBGKill = "playerBGKill"; |
||
416 | |||
417 | |||
418 | --_meetCount = "meetCount"; |
||
419 | --_atWar = "atWar"; |
||
420 | --_guildAtWar = "guildAtWar"; |
||
421 | --_warDate = "warDate"; |
||
422 | |||
423 | --_continent = "continent"; |
||
424 | --_zone = "zone"; |
||
425 | --_xPos = "xPos"; |
||
426 | --_yPos = "yPos"; |
||
427 | --_icon = "icon"; |
||
428 | --_storedInfo = "storedInfo"; |
||
429 | |||
430 | --_zoneName = "zoneName"; |
||
431 | |||
432 | |||
433 | --_lastUpdate = "lastUpdate"; |
||
434 | --_totalDamage = "totalDamage"; |
||
435 | --_groupDamage = "groupDamage"; |
||
436 | |||
437 | --_lastHateUpdate = "lastHateUpdate"; |
||
438 | --_hateLevel = "hateLevel"; |
||
439 | --_enemyType = "enemyType"; |
||
440 | --_damage = "damage"; |
||
441 | |||
442 | --_lastView = "lastView"; |
||
443 | --_lastPlayerViewed = "lastPlayerViewed"; |
||
444 | |||
445 | --_enemyPlayer = "enemyPlayer"; |
||
446 | --_enemyCreature = "enemyCreature"; |
||
447 | |||
448 | --_owner = "owner"; |
||
449 | --_player = "player"; |
||
450 | --_other = "other"; |
||
451 | |||
452 | --_players = "players"; |
||
453 | --_guilds = "guilds"; |
||
454 | --_duels = "duels"; |
||
455 | --_members = "members"; |
||
456 | |||
457 | --_bookCredits = "bookCredits"; |
||
458 | --_bookGeneralStat = "bookGeneralStat"; |
||
459 | --_bookClassStat = "bookClassStat"; |
||
460 | --_bookRaceStat = "bookRaceStat"; |
||
461 | --_bookPlayerStat = "bookPlayerStat"; |
||
462 | --_bookGuildStat = "bookGuildStat"; |
||
463 | --_bookMapStat = "bookMapStat"; |
||
464 | --_bookDateStat = "bookDateStat"; |
||
465 | |||
466 | --_bookBGDateMapStat = "bookBGDateMapStat"; |
||
467 | --_bookBGDateStat = "bookBGDateStat"; |
||
468 | --_bookBGMapStat = "bookBGMapStat"; |
||
469 | |||
470 | |||
471 | --_checkButton = "checkButton"; |
||
472 | |||
473 | --_slider = "slider"; |
||
474 | |||
475 | |||
476 | |||
477 | |||
478 | |||
479 | function SkM_TableInsertMaxLengthLine(Lines, sLine, iMaxLen, iThreshold, sColorPrefix) |
||
480 | local FName = "SkM_TableInsertMaxLengthLine"; |
||
481 | local sTmp = sLine; |
||
482 | local SeparList = {" ", "-", ".", ",", ":", ";"}; |
||
483 | local sColor = ""; |
||
484 | if (sColorPrefix) then |
||
485 | sColor = sColorPrefix; |
||
486 | end |
||
487 | while (string.len(sTmp) > 0) do |
||
488 | if (string.len(sTmp) <= iMaxLen) then |
||
489 | table.insert(Lines, sColor..sTmp); |
||
490 | sTmp = ""; |
||
491 | else |
||
492 | local iPos = iMaxLen; |
||
493 | local sChar = string.sub(sTmp, iPos, iPos); |
||
494 | while (iPos > iMaxLen - iThreshold) and not (intable(sChar, SeparList)) do |
||
495 | iPos = iPos - 1; |
||
496 | sChar = string.sub(sTmp, iPos, iPos); |
||
497 | end |
||
498 | if (intable(sChar, SeparList)) then |
||
499 | table.insert(Lines, sColor..string.sub(sTmp, 1, iPos)); |
||
500 | sTmp = string.sub(sTmp, iPos+1, string.len(sTmp)); |
||
501 | else |
||
502 | table.insert(Lines, sColor..string.sub(sTmp, 1, iMaxLen)); |
||
503 | sTmp = string.sub(sTmp, iMaxLen+1, string.len(sTmp)); |
||
504 | end |
||
505 | end |
||
506 | end |
||
507 | |||
508 | end |
||
509 | |||
510 | |||
511 | |||
512 | -- -------------------------------------------------------------------------------------- |
||
513 | -- ifnil |
||
514 | -- -------------------------------------------------------------------------------------- |
||
515 | -- Return input value if it's not nil, else return alternative value specified. |
||
516 | -- -------------------------------------------------------------------------------------- |
||
517 | function ifnil( iVal, iNewVal) |
||
518 | if ( iVal == nil) then |
||
519 | return iNewVal; |
||
520 | else |
||
521 | return iVal; |
||
522 | end |
||
523 | end |
||
524 | |||
525 | |||
526 | -- -------------------------------------------------------------------------------------- |
||
527 | -- snil |
||
528 | -- -------------------------------------------------------------------------------------- |
||
529 | -- Return the input string, or the string "nil" if the variable is nil |
||
530 | -- -------------------------------------------------------------------------------------- |
||
531 | function snil_old( Val ) |
||
532 | if ( Val == nil ) then |
||
533 | return TXT_NIL; |
||
534 | else |
||
535 | return Val; |
||
536 | end |
||
537 | end |
||
538 | |||
539 | function snil( Val ) |
||
540 | if ( Val == nil ) then |
||
541 | return TXT_NIL; |
||
542 | else |
||
543 | if ( Val == true) then |
||
544 | return "true"; |
||
545 | elseif ( Val == false) then |
||
546 | return "false"; |
||
547 | else |
||
548 | return Val; |
||
549 | end |
||
550 | end |
||
551 | end |
||
552 | |||
553 | |||
554 | -- -------------------------------------------------------------------------------------- |
||
555 | -- copytable |
||
556 | -- -------------------------------------------------------------------------------------- |
||
557 | -- Make a copy of a table |
||
558 | -- -------------------------------------------------------------------------------------- |
||
559 | function copytable(MyTable) |
||
560 | if (type(MyTable) ~= "table" ) then |
||
561 | return MyTable; |
||
562 | end |
||
563 | local idx, val; |
||
564 | local NewTable = {}; |
||
565 | for idx, val in MyTable do |
||
566 | NewTable[idx] = copytable(val); |
||
567 | end |
||
568 | return NewTable; |
||
569 | end |
||
570 | |||
571 | |||
572 | -- -------------------------------------------------------------------------------------- |
||
573 | -- intable |
||
574 | -- -------------------------------------------------------------------------------------- |
||
575 | -- Return true if "Val" is in table "TheTable" |
||
576 | -- -------------------------------------------------------------------------------------- |
||
577 | function intable( Val, TheTable) |
||
578 | local idx, TableValue; |
||
579 | for idx, TableValue in TheTable do |
||
580 | if Val == TableValue then |
||
581 | return true; |
||
582 | end |
||
583 | end |
||
584 | return false; |
||
585 | end |
||
586 | |||
587 | |||
588 | -- remove "Val" if found in list "TheTable" |
||
589 | -- return resulting list |
||
590 | function removefromlist( Val, TheTable ) |
||
591 | local MyTable = TheTable; |
||
592 | local iSize = table.getn(MyTable); |
||
593 | local i = 1; |
||
594 | while (i <= iSize) do |
||
595 | if (MyTable[i] == Val) then |
||
596 | table.remove(MyTable, i); |
||
597 | iSize = iSize - 1; |
||
598 | else |
||
599 | i = i + 1; |
||
600 | end |
||
601 | end |
||
602 | return MyTable; |
||
603 | end |
||
604 | |||
605 | |||
606 | -- -------------------------------------------------------------------------------------- |
||
607 | -- appendtables |
||
608 | -- -------------------------------------------------------------------------------------- |
||
609 | -- Append several list tables and returns the resulting table. |
||
610 | -- Can take single elements also, in that case convert them to tables. |
||
611 | -- -------------------------------------------------------------------------------------- |
||
612 | function appendtables( ... ) |
||
613 | |||
614 | local TableRes = { }; |
||
615 | local iNbArg = arg.n; |
||
616 | local i; |
||
617 | |||
618 | for i=1, iNbArg do |
||
619 | local MyTable; |
||
620 | local Table = arg[i]; |
||
621 | if (type(Table) ~= "table" ) then |
||
622 | MyTable = { Table }; |
||
623 | else |
||
624 | MyTable = Table; |
||
625 | end |
||
626 | |||
627 | local idx, TableValue; |
||
628 | for idx, TableValue in MyTable do |
||
629 | table.insert(TableRes, TableValue); |
||
630 | end |
||
631 | end |
||
632 | |||
633 | return TableRes; |
||
634 | end |
||
635 | |||
636 | |||
637 | -- -------------------------------------------------------------------------------------- |
||
638 | -- mergetables |
||
639 | -- -------------------------------------------------------------------------------------- |
||
640 | -- Merge two list tables and returns the resulting table. |
||
641 | -- If both tables contain the same indexes, the first tables values will be returned for |
||
642 | -- this index. |
||
643 | -- Recursively merge sub tables if needed. |
||
644 | -- -------------------------------------------------------------------------------------- |
||
645 | function mergetables(Table1, Table2) |
||
646 | |||
647 | if (type(Table1) ~= "table") and (type(Table2) ~= "table") then |
||
648 | return Table1; |
||
649 | end |
||
650 | if (type(Table1) ~= "table") then |
||
651 | return Table2; |
||
652 | end |
||
653 | if (type(Table2) ~= "table") then |
||
654 | return Table1; |
||
655 | end |
||
656 | |||
657 | local idx, TableValue; |
||
658 | local TableRes = Table1; |
||
659 | for idx, TableValue in Table2 do |
||
660 | if (not Table1[idx]) then |
||
661 | TableRes[idx] = TableValue; |
||
662 | else |
||
663 | TableRes[idx] = mergetables(Table1[idx], TableValue); |
||
664 | |||
665 | end |
||
666 | end |
||
667 | |||
668 | return TableRes; |
||
669 | end |
||
670 | |||
671 | |||
672 | -- -------------------------------------------------------------------------------------- |
||
673 | -- revlist |
||
674 | -- -------------------------------------------------------------------------------------- |
||
675 | -- Returns a list in reverse order |
||
676 | -- -------------------------------------------------------------------------------------- |
||
677 | function revlist(ListIn) |
||
678 | local ListOut = {}; |
||
679 | local MyList; |
||
680 | |||
681 | if (type(ListIn) ~= "table" ) then |
||
682 | MyList = { ListIn }; |
||
683 | else |
||
684 | MyList = ListIn; |
||
685 | end |
||
686 | |||
687 | local idx, TableValue; |
||
688 | for idx, TableValue in MyList do |
||
689 | table.insert(ListOut, 1, TableValue); |
||
690 | end |
||
691 | |||
692 | return ListOut; |
||
693 | end |
||
694 | |||
695 | |||
696 | function tablesize(Table) |
||
697 | local idx, val |
||
698 | local iSize = 0 |
||
699 | for idx, val in Table do |
||
700 | iSize = iSize + 1; |
||
701 | end |
||
702 | return iSize; |
||
703 | end |
||
704 | |||
705 | |||
706 | |||
707 | -- ************************************************************************************** |
||
708 | -- Logs, debug and display functions |
||
709 | -- ************************************************************************************** |
||
710 | |||
711 | -- -------------------------------------------------------------------------------------- |
||
712 | -- SkM_Trace |
||
713 | -- -------------------------------------------------------------------------------------- |
||
714 | -- Debug function. Display information on screen, or on the default chat frame. |
||
715 | -- FName = calling function name |
||
716 | -- Level = level of trace, used to check if this debug will be displayed |
||
717 | -- Message = message to trace |
||
718 | -- -------------------------------------------------------------------------------------- |
||
719 | function SkM_Trace( FName, Level, Message ) |
||
720 | local OutMessage; |
||
721 | |||
722 | if (Level <= SKM_Config.DebugLevel) then |
||
723 | |||
724 | if (SKM_Config.DebugMaxFuncLen) and (string.len(FName) > SKM_Config.DebugMaxFuncLen) then |
||
725 | if (SKM_Config.DebugMaxFuncLen < 10) then |
||
726 | OutMessage = string.sub(FName, 1, SKM_Config.DebugMaxFuncLen).."/"..snil(Message); |
||
727 | else |
||
728 | OutMessage = string.sub(FName, 1, SKM_Config.DebugMaxFuncLen - 7)..".." |
||
729 | ..string.sub(FName, string.len(FName)-4, string.len(FName)).."/"..snil(Message); |
||
730 | end |
||
731 | else |
||
732 | OutMessage = FName.."/"..snil(Message); |
||
733 | end |
||
734 | |||
735 | if (SKM_Config.RecordDebug) then |
||
736 | local sDate = SkM_GetDate(); |
||
737 | local sRecordMsg = "["..sDate.."]<"..Level.."> "..snil(FName).."/"..snil(Message); |
||
738 | table.insert(SKM_Debug, sRecordMsg); |
||
739 | |||
740 | SKM_Context.RecLines = SKM_Context.RecLines + 1; |
||
741 | SKM_Context.TmpRecLines = SKM_Context.TmpRecLines + 1; |
||
742 | if (SKM_Context.TmpRecLines >= SKM_Config.RecordIntervalInfo) then |
||
743 | SkM_ChatMessageCol("Lines recorded : "..SKM_Context.RecLines.." (Total : "..table.getn(SKM_Debug)..")"); |
||
744 | SKM_Context.TmpRecLines = 0; |
||
745 | end |
||
746 | |||
747 | return; |
||
748 | end |
||
749 | |||
750 | if (SKM_TRACE_MODE == SKM_TRACE_MODE_PRINT) then |
||
751 | print(OutMessage); |
||
752 | elseif (SKM_TRACE_MODE == SKM_TRACE_MODE_CHATMSG) then |
||
753 | if not DEFAULT_CHAT_FRAME then |
||
754 | return; |
||
755 | end |
||
756 | local r = SKM_Config.RGB_Debug[Level].r; |
||
757 | local g = SKM_Config.RGB_Debug[Level].g; |
||
758 | local b = SKM_Config.RGB_Debug[Level].b; |
||
759 | SkM_PrintMessage(OutMessage, r, g, b); -- PIng: Bug Fix.Replace ShM_PrintMessage by SkM_PrintMessage |
||
760 | end |
||
761 | end |
||
762 | end |
||
763 | |||
764 | |||
765 | -- -------------------------------------------------------------------------------------- |
||
766 | -- SkM_PrintMessage |
||
767 | -- -------------------------------------------------------------------------------------- |
||
768 | -- Display a message in a frame in a specified RGB color, calling Blizz function |
||
769 | -- <frame>:AddMessage. |
||
770 | -- I don't know what the two last parameters stand for :/ |
||
771 | -- -------------------------------------------------------------------------------------- |
||
772 | function SkM_PrintMessage(msg, r, g, b, frame, id, unknown4th) |
||
773 | local OutMessage; |
||
774 | |||
775 | if(unknown4th) then |
||
776 | local temp = id; |
||
777 | id = unknown4th; |
||
778 | unknown4th = id; |
||
779 | end |
||
780 | |||
781 | OutMessage = snil(msg); |
||
782 | |||
783 | if (not r) then r = 1.0; end |
||
784 | if (not g) then g = 1.0; end |
||
785 | if (not b) then b = 1.0; end |
||
786 | if ( frame ) then |
||
787 | frame:AddMessage(OutMessage, r, g, b, id, unknown4th); |
||
788 | else |
||
789 | if ( DEFAULT_CHAT_FRAME ) then |
||
790 | DEFAULT_CHAT_FRAME:AddMessage(OutMessage, r, g, b, id, unknown4th); |
||
791 | end |
||
792 | end |
||
793 | end |
||
794 | |||
795 | |||
796 | -- -------------------------------------------------------------------------------------- |
||
797 | -- SkM_ChatMessageCol |
||
798 | -- -------------------------------------------------------------------------------------- |
||
799 | -- Display a message on the default chat frame, with the module prefix. |
||
800 | -- Color is the module global chat color, if it has been set (default : white). |
||
801 | -- -------------------------------------------------------------------------------------- |
||
802 | function SkM_ChatMessageCol( Message ) |
||
803 | local OutMessage; |
||
804 | local r = SKM_Config.RGB_Msg.r; |
||
805 | |||
806 | local g = SKM_Config.RGB_Msg.g; |
||
807 | local b = SKM_Config.RGB_Msg.b; |
||
808 | |||
809 | if not DEFAULT_CHAT_FRAME then |
||
810 | return; |
||
811 | end |
||
812 | OutMessage = SKM_MESSAGE_PREFIX..snil(Message); |
||
813 | SkM_PrintMessage(OutMessage, r, g, b); |
||
814 | end |
||
815 | |||
816 | |||
817 | -- -------------------------------------------------------------------------------------- |
||
818 | -- SkM_ChatMessageColP |
||
819 | -- -------------------------------------------------------------------------------------- |
||
820 | -- Display a message on the default chat frame, with the module prefix. |
||
821 | -- RBGTriplet specifies the text color. |
||
822 | -- -------------------------------------------------------------------------------------- |
||
823 | function SkM_ChatMessageColP( Message, RGBTriplet ) |
||
824 | local OutMessage; |
||
825 | local r = RGBTriplet.r; |
||
826 | local g = RGBTriplet.g; |
||
827 | local b = RGBTriplet.b; |
||
828 | |||
829 | if not DEFAULT_CHAT_FRAME then |
||
830 | return; |
||
831 | end |
||
832 | OutMessage = SKM_MESSAGE_PREFIX..snil(Message); |
||
833 | SkM_PrintMessage(OutMessage, r, g, b); |
||
834 | end |
||
835 | |||
836 | |||
837 | |||
838 | |||
839 | |||
840 | |||
841 | |||
842 | -- -------------------------------------------------------------------------------------- |
||
843 | -- SkM_Initialize |
||
844 | -- -------------------------------------------------------------------------------------- |
||
845 | -- Module initialization |
||
846 | -- -------------------------------------------------------------------------------------- |
||
847 | function SkM_Initialize() |
||
848 | |||
849 | SKM_Context = { |
||
850 | |||
851 | MapOpen = false; |
||
852 | |||
853 | -- record damage done by player to enemies |
||
854 | EnemyCombat = { }; |
||
855 | |||
856 | -- record damage done by enemies to player |
||
857 | PlayerCombat = { }; |
||
858 | |||
859 | |||
860 | -- record recent enemy kills |
||
861 | RecentEnemyKill = { }; |
||
862 | |||
863 | -- record recent WAR warnings to reduce spam |
||
864 | RecentWarWarning = { }; |
||
865 | |||
866 | --DuelEnemy = nil; |
||
867 | |||
868 | -- list of player names in group |
||
869 | GroupList = { }; |
||
870 | |||
871 | -- list of player names in guild |
||
872 | GuildList = { }; |
||
873 | |||
874 | -- list of notes associated to a physical POI on the world map |
||
875 | WorldMapPOINotes = { }; |
||
876 | |||
877 | PlayerAlive = true; |
||
878 | |||
879 | DataInit = false; |
||
880 | |||
881 | -- parse patterns |
||
882 | Pattern = { }; |
||
883 | |||
884 | }; |
||
885 | |||
886 | SKM_Context.Continents = { GetMapContinents() } ; |
||
887 | SKM_Context.Zones = { }; |
||
888 | |||
889 | for idx, val in SKM_Context.Continents do |
||
890 | SKM_Context.Zones[idx] = { GetMapZones(idx) } ; |
||
891 | end |
||
892 | |||
893 | SkM_BuildParsePatterns(); |
||
894 | |||
895 | SKM_Context.Race = { |
||
896 | IndexToString = { |
||
897 | [1] = SKM_RACE.Dwarf; |
||
898 | [2] = SKM_RACE.Gnome; |
||
899 | |||
900 | [3] = SKM_RACE.Human; |
||
901 | [4] = SKM_RACE.NightElf; |
||
902 | [5] = SKM_RACE.Orc; |
||
903 | [6] = SKM_RACE.Tauren; |
||
904 | |||
905 | [7] = SKM_RACE.Troll; |
||
906 | [8] = SKM_RACE.Undead; |
||
907 | }; |
||
908 | StringToIndex = { |
||
909 | [SKM_RACE.Dwarf] = 1; |
||
910 | [SKM_RACE.Gnome] = 2; |
||
911 | [SKM_RACE.Human] = 3; |
||
912 | [SKM_RACE.NightElf] = 4; |
||
913 | [SKM_RACE.Orc] = 5; |
||
914 | [SKM_RACE.Tauren] = 6; |
||
915 | [SKM_RACE.Troll] = 7; |
||
916 | [SKM_RACE.Undead] = 8; |
||
917 | }; |
||
918 | }; |
||
919 | |||
920 | |||
921 | SKM_Context.Class = { |
||
922 | IndexToString = { |
||
923 | [1] = SKM_CLASS.Druid; |
||
924 | [2] = SKM_CLASS.Hunter; |
||
925 | [3] = SKM_CLASS.Mage; |
||
926 | [4] = SKM_CLASS.Paladin; |
||
927 | [5] = SKM_CLASS.Priest; |
||
928 | [6] = SKM_CLASS.Rogue; |
||
929 | [7] = SKM_CLASS.Shaman; |
||
930 | [8] = SKM_CLASS.Warrior; |
||
931 | [9] = SKM_CLASS.Warlock; |
||
932 | }; |
||
933 | StringToIndex = { |
||
934 | [SKM_CLASS.Druid] = 1; |
||
935 | [SKM_CLASS.Hunter] = 2; |
||
936 | [SKM_CLASS.Mage] = 3; |
||
937 | [SKM_CLASS.Paladin] = 4; |
||
938 | [SKM_CLASS.Priest] = 5; |
||
939 | [SKM_CLASS.Rogue] = 6; |
||
940 | [SKM_CLASS.Shaman] = 7; |
||
941 | [SKM_CLASS.Warrior] = 8; |
||
942 | [SKM_CLASS.Warlock] = 9; |
||
943 | }; |
||
944 | }; |
||
945 | |||
946 | SkM_InitData(false); |
||
947 | end |
||
948 | |||
949 | |||
950 | -- -------------------------------------------------------------------------------------- |
||
951 | -- SkM_InitData |
||
952 | |||
953 | -- -------------------------------------------------------------------------------------- |
||
954 | -- Initialization of data saved across sessions |
||
955 | -- -------------------------------------------------------------------------------------- |
||
956 | function SkM_InitData(bForceInit) |
||
957 | local FName = "SkM_InitData"; |
||
958 | |||
959 | -- context not yet created |
||
960 | if (not SKM_Context) then |
||
961 | return false; |
||
962 | end |
||
963 | |||
964 | -- initialization already performed |
||
965 | if (SKM_Context.DataInit == true) and (not bForceInit) then |
||
966 | return true; |
||
967 | end |
||
968 | |||
969 | _PlayerName = SkM_UnitName(SKM_UNIT_PLAYER); |
||
970 | _RealmName = GetCVar("realmName"); |
||
971 | |||
972 | -- if player name or realm name can't be retrieved yet, abort initialization |
||
973 | if (not _PlayerName) or (not _RealmName) then |
||
974 | return false; |
||
975 | end |
||
976 | |||
977 | SKM_Context.PlayerName = _PlayerName; |
||
978 | SKM_Context.RealmName = _RealmName; |
||
979 | |||
980 | -- store player current level, because we get old level upon event "level up", but I'm |
||
981 | -- not sure it would always be the case. |
||
982 | --SKM_Context.PlayerLevel = UnitLevel(SKM_UNIT_PLAYER); |
||
983 | -- since 1.5 it returns 0 at this point... have to do it later. |
||
984 | |||
985 | -- global module data |
||
986 | if (not SKM_Data) then |
||
987 | SKM_Data = { } ; |
||
988 | end |
||
989 | |||
990 | -- for recording debug messages |
||
991 | if (not SKM_Debug) then |
||
992 | SKM_Debug = { }; |
||
993 | end |
||
994 | |||
995 | -- module data for current realm |
||
996 | if (not SKM_Data[_RealmName]) then |
||
997 | SKM_Data[_RealmName] = { }; |
||
998 | end |
||
999 | |||
1000 | -- module data for current player of current realm |
||
1001 | if (not SKM_Data[_RealmName][_PlayerName]) then |
||
1002 | SKM_Data[_RealmName][_PlayerName] = { }; |
||
1003 | SKM_Data[_RealmName][_PlayerName].PlayerName = SKM_Context.PlayerName; |
||
1004 | |||
1005 | local sDate = SkM_GetDate(); |
||
1006 | SKM_Data[_RealmName][_PlayerName].InitDate = sDate; |
||
1007 | end |
||
1008 | |||
1009 | -- dunno when it happenned, but some chars do not have a "PlayerName". Fix it... |
||
1010 | if (not SKM_Data[_RealmName][_PlayerName].PlayerName) then |
||
1011 | SKM_Data[_RealmName][_PlayerName].PlayerName = _PlayerName; |
||
1012 | end |
||
1013 | |||
1014 | -- sub maps of player data |
||
1015 | |||
1016 | if (not SKM_Data[_RealmName][_PlayerName].GlobalMapData) then |
||
1017 | SKM_Data[_RealmName][_PlayerName].GlobalMapData = { }; |
||
1018 | end |
||
1019 | if (not SKM_Data[_RealmName][_PlayerName].MapData) then |
||
1020 | SKM_Data[_RealmName][_PlayerName].MapData = { }; |
||
1021 | |||
1022 | local idx_c, val_c; |
||
1023 | for idx_c, val_c in SKM_Context.Continents do |
||
1024 | SKM_Data[_RealmName][_PlayerName].MapData[idx_c] = { }; |
||
1025 | |||
1026 | local idx_z, val_z |
||
1027 | for idx_z, val_z in SKM_Context.Zones[idx_c] do |
||
1028 | SKM_Data[_RealmName][_PlayerName].MapData[idx_c][idx_z] = { }; |
||
1029 | end |
||
1030 | end |
||
1031 | end |
||
1032 | |||
1033 | if (not SKM_Data[_RealmName][_PlayerName].EnemyHistory) then |
||
1034 | SKM_Data[_RealmName][_PlayerName].EnemyHistory = { }; |
||
1035 | end |
||
1036 | |||
1037 | -- 09/04/2005 16:28:31 PIng: Add Guild support |
||
1038 | if (not SKM_Data[_RealmName][_PlayerName].GuildHistory) then |
||
1039 | SKM_Data[_RealmName][_PlayerName].GuildHistory = { }; |
||
1040 | end |
||
1041 | |||
1042 | if (not SKM_Data[_RealmName][_PlayerName].UnknownEnemy) then |
||
1043 | SKM_Data[_RealmName][_PlayerName].UnknownEnemy = { }; |
||
1044 | end |
||
1045 | |||
1046 | if (not SKM_Data[_RealmName][_PlayerName].DuelHistory) then |
||
1047 | SKM_Data[_RealmName][_PlayerName].DuelHistory = { }; |
||
1048 | end |
||
1049 | |||
1050 | if (not SKM_Data[_RealmName][_PlayerName].BGStats) then |
||
1051 | SKM_Data[_RealmName][_PlayerName].BGStats = { }; |
||
1052 | end |
||
1053 | |||
1054 | |||
1055 | local sGuildName = GetGuildInfo(SKM_UNIT_PLAYER); |
||
1056 | SkM_Trace(FName, 3, "Player guild = "..snil(sGuildName)); |
||
1057 | if (sGuildName) and (sGuildName ~= "") and (false) then |
||
1058 | -- build guild list : open guild roster to retrieve guild players list |
||
1059 | GuildRoster(); |
||
1060 | --SetGuildRosterShowOffline(1); |
||
1061 | SkM_BuildGuildList(); |
||
1062 | --FriendsFrame:Hide(); |
||
1063 | HideUIPanel(FriendsFrame); |
||
1064 | end |
||
1065 | |||
1066 | -- Global settings |
||
1067 | if (not SKM_Settings) then |
||
1068 | SKM_Settings = { }; |
||
1069 | end |
||
1070 | SkM_LoadDefaultSettings(false); |
||
1071 | |||
1072 | SkM_RecordVersionHistory(); |
||
1073 | |||
1074 | SKM_Context.DataInit = true; |
||
1075 | SkM_Trace(FName, 3, "Done"); |
||
1076 | return true; |
||
1077 | end |
||
1078 | |||
1079 | |||
1080 | -- -------------------------------------------------------------------------------------- |
||
1081 | -- SkM_LoadDefaultSettings |
||
1082 | -- -------------------------------------------------------------------------------------- |
||
1083 | -- Load (or reload) setting default values from configuration file |
||
1084 | -- -------------------------------------------------------------------------------------- |
||
1085 | function SkM_LoadDefaultSettings(bForceReload) |
||
1086 | local FName = "SkM_LoadDefaultSettings"; |
||
1087 | |||
1088 | if (not SKM_Settings) then |
||
1089 | SKM_Settings = { }; |
||
1090 | end |
||
1091 | |||
1092 | if (bForceReload) then |
||
1093 | |||
1094 | SkM_Trace(FName, 3, "Force reload default settings"); |
||
1095 | |||
1096 | for i=1, table.getn(SKM_OPTION_LIST), 1 do |
||
1097 | local key = SKM_OPTION_LIST[i]; |
||
1098 | SKM_Settings[key] = SKM_Config[key]; |
||
1099 | end |
||
1100 | |||
1101 | else |
||
1102 | SkM_Trace(FName, 3, "Load missing default settings"); |
||
1103 | |||
1104 | for i=1, table.getn(SKM_OPTION_LIST), 1 do |
||
1105 | local key = SKM_OPTION_LIST[i]; |
||
1106 | SkM_Trace(FName, 3, "key = "..key); |
||
1107 | if (SKM_Settings[key] == nil) then |
||
1108 | SKM_Settings[key] = SKM_Config[key]; |
||
1109 | end |
||
1110 | end |
||
1111 | |||
1112 | end |
||
1113 | |||
1114 | if (SKM_Settings.CreatureKillRecordsByZone > SKM_MAX_CREEP_RECORD_BY_ZONE) then |
||
1115 | SKM_Settings.CreatureKillRecordsByZone = SKM_MAX_CREEP_RECORD_BY_ZONE; |
||
1116 | end |
||
1117 | |||
1118 | |||
1119 | -- for management of data migration. No use for now, but might be needed later on. |
||
1120 | if (SKM_Settings.DataModel == nil) then |
||
1121 | SKM_Settings.DataModel = SKM_VERSION; |
||
1122 | else |
||
1123 | SKM_Settings.DataModel = SKM_VERSION; |
||
1124 | end |
||
1125 | |||
1126 | end |
||
1127 | |||
1128 | |||
1129 | -- -------------------------------------------------------------------------------------- |
||
1130 | -- SkM_ResetData |
||
1131 | -- -------------------------------------------------------------------------------------- |
||
1132 | -- Warning : this deletes ALL module data (for all players and realms) |
||
1133 | -- Use with caution ! |
||
1134 | -- -------------------------------------------------------------------------------------- |
||
1135 | function SkM_ResetData() |
||
1136 | SKM_Data = nil; |
||
1137 | SkM_InitData(true); |
||
1138 | end |
||
1139 | |||
1140 | |||
1141 | -- -------------------------------------------------------------------------------------- |
||
1142 | -- SkM_ResetPlayerData |
||
1143 | -- -------------------------------------------------------------------------------------- |
||
1144 | -- Delete all current player data |
||
1145 | -- -------------------------------------------------------------------------------------- |
||
1146 | function SkM_ResetPlayerData() |
||
1147 | SKM_Data[_RealmName][_PlayerName] = nil; |
||
1148 | SkM_InitData(true); |
||
1149 | end |
||
1150 | |||
1151 | |||
1152 | -- -------------------------------------------------------------------------------------- |
||
1153 | -- SkM_ResetPlayerData |
||
1154 | -- -------------------------------------------------------------------------------------- |
||
1155 | -- Delete current player map data only |
||
1156 | -- -------------------------------------------------------------------------------------- |
||
1157 | function SkM_ResetPlayerMapData() |
||
1158 | SKM_Data[_RealmName][_PlayerName].GlobalMapData = nil; |
||
1159 | SKM_Data[_RealmName][_PlayerName].MapData = nil; |
||
1160 | SkM_InitData(true); |
||
1161 | end |
||
1162 | |||
1163 | |||
1164 | -- -------------------------------------------------------------------------------------- |
||
1165 | -- SkM_ResetAccountMapData |
||
1166 | -- -------------------------------------------------------------------------------------- |
||
1167 | -- Delete all map data on a given account |
||
1168 | -- USE WITH CAUTION !!! |
||
1169 | -- -------------------------------------------------------------------------------------- |
||
1170 | function SkM_ResetAccountMapData() |
||
1171 | local FName = "SkM_ResetAccountMapData"; |
||
1172 | |||
1173 | local idx_realm, val_realm, idx_char, val_char, idx_enemy, val_enemy; |
||
1174 | |||
1175 | for idx_realm, val_realm in SKM_Data do |
||
1176 | for idx_char, val_char in SKM_Data[idx_realm] do |
||
1177 | |||
1178 | if (SKM_Data[idx_realm][idx_char].PlayerName == idx_char) then |
||
1179 | SkM_Trace(FName, 1, "Cleaning for "..idx_realm.." / "..idx_char); |
||
1180 | |||
1181 | -- clean up map data |
||
1182 | SKM_Data[idx_realm][idx_char].GlobalMapData = nil; |
||
1183 | SKM_Data[_RealmName][_PlayerName].MapData = nil; |
||
1184 | |||
1185 | -- clean up zone stored in enemy information |
||
1186 | for idx_enemy, val_enemy in SKM_Data[idx_realm][idx_char].EnemyHistory do |
||
1187 | SKM_Data[idx_realm][idx_char].EnemyHistory[idx_enemy][_SKM._continent] = nil; |
||
1188 | SKM_Data[idx_realm][idx_char].EnemyHistory[idx_enemy][_SKM._zone] = nil; |
||
1189 | SKM_Data[idx_realm][idx_char].EnemyHistory[idx_enemy][_SKM._xPos] = nil; |
||
1190 | SKM_Data[idx_realm][idx_char].EnemyHistory[idx_enemy][_SKM._yPos] = nil; |
||
1191 | end |
||
1192 | end |
||
1193 | end |
||
1194 | end |
||
1195 | |||
1196 | SkM_InitData(true); |
||
1197 | end |
||
1198 | |||
1199 | |||
1200 | -- -------------------------------------------------------------------------------------- |
||
1201 | -- SkM_GetOption |
||
1202 | -- -------------------------------------------------------------------------------------- |
||
1203 | -- Get a player option value |
||
1204 | -- -------------------------------------------------------------------------------------- |
||
1205 | function SkM_GetOption(sConfigKey) |
||
1206 | local FName = "SkM_GetOption"; |
||
1207 | if (SKM_Settings == nil) then |
||
1208 | SkM_Trace(FName, 1, "Settings not initialized, can't get value for "..snil(sConfigKey)); |
||
1209 | return; |
||
1210 | end |
||
1211 | if (sConfigKey == nil) then |
||
1212 | SkM_Trace(FName, 1, "received nil param"); |
||
1213 | return; |
||
1214 | end |
||
1215 | --return (SKM_Data[_RealmName][_PlayerName].Settings[sConfigKey]); |
||
1216 | return (SKM_Settings[sConfigKey]); |
||
1217 | end |
||
1218 | |||
1219 | |||
1220 | -- -------------------------------------------------------------------------------------- |
||
1221 | -- SkM_SetOption |
||
1222 | -- -------------------------------------------------------------------------------------- |
||
1223 | -- Set a player option to a given value |
||
1224 | -- -------------------------------------------------------------------------------------- |
||
1225 | function SkM_SetOption(sConfigKey, Value) |
||
1226 | local FName = "SkM_SetOption"; |
||
1227 | if (SKM_Settings == nil) then |
||
1228 | SkM_Trace(FName, 1, "Settings not initialized, can't set value for "..snil(sConfigKey)); |
||
1229 | return; |
||
1230 | end |
||
1231 | if (sConfigKey == nil) then |
||
1232 | SkM_Trace(FName, 1, "received nil param"); |
||
1233 | return; |
||
1234 | end |
||
1235 | --SKM_Data[_RealmName][_PlayerName].Settings[sConfigKey] = Value; |
||
1236 | SKM_Settings[sConfigKey] = Value; |
||
1237 | end |
||
1238 | |||
1239 | |||
1240 | function SkM_GetRaceText(Index) |
||
1241 | return SKM_Context.Race.IndexToString[Index]; |
||
1242 | end |
||
1243 | |||
1244 | function SkM_GetRaceIndex(Text) |
||
1245 | return SKM_Context.Race.StringToIndex[Text]; |
||
1246 | end |
||
1247 | |||
1248 | function SkM_GetClassText(Index) |
||
1249 | return SKM_Context.Class.IndexToString[Index]; |
||
1250 | end |
||
1251 | |||
1252 | function SkM_GetClassIndex(Text) |
||
1253 | return SKM_Context.Class.StringToIndex[Text]; |
||
1254 | end |
||
1255 | |||
1256 | |||
1257 | -- -------------------------------------------------------------------------------------- |
||
1258 | -- SkM_ExtractParam |
||
1259 | -- -------------------------------------------------------------------------------------- |
||
1260 | -- Extract parameters from a string. Delimiter is the blank character (space). |
||
1261 | -- Return the first parameter and the rest of the string ("" if empty). |
||
1262 | -- -------------------------------------------------------------------------------------- |
||
1263 | function SkM_ExtractParam(msg) |
||
1264 | local params = msg; |
||
1265 | local command = params; |
||
1266 | local index = strfind(command, " "); |
||
1267 | |||
1268 | if ( index ) then |
||
1269 | command = strsub(command, 1, index-1); |
||
1270 | params = strsub(params, index+1); |
||
1271 | else |
||
1272 | params = ""; |
||
1273 | end |
||
1274 | return command, params; |
||
1275 | end |
||
1276 | |||
1277 | |||
1278 | -- -------------------------------------------------------------------------------------- |
||
1279 | -- SkM_IdentifyCommand |
||
1280 | -- -------------------------------------------------------------------------------------- |
||
1281 | -- Check if the given command matches a module command. |
||
1282 | -- it's the case if the passed in command starts with the module command |
||
1283 | -- eg. : module command "fort" allows to type in "fortitude". |
||
1284 | -- -------------------------------------------------------------------------------------- |
||
1285 | function SkM_IdentifyCommand(sCmd, sModuleCommand) |
||
1286 | |||
1287 | if ((not sModuleCommand) or (sModuleCommand == "")) then |
||
1288 | return false; |
||
1289 | end |
||
1290 | if ((not sCmd) or (sCmd == "")) then |
||
1291 | return false; |
||
1292 | end |
||
1293 | |||
1294 | local iLen = string.len(sModuleCommand); |
||
1295 | |||
1296 | if ( string.sub(sCmd, 1, iLen) == sModuleCommand) then |
||
1297 | return true; |
||
1298 | else |
||
1299 | return false; |
||
1300 | end |
||
1301 | end |
||
1302 | |||
1303 | |||
1304 | -- -------------------------------------------------------------------------------------- |
||
1305 | -- SkM_SetDebugLevel |
||
1306 | -- -------------------------------------------------------------------------------------- |
||
1307 | -- Set the module debug level (-1, 0, 1, 2, 3) |
||
1308 | -- -------------------------------------------------------------------------------------- |
||
1309 | function SkM_SetDebugLevel( iLevel ) |
||
1310 | local iNewLevel = ifnil(iLevel, -1); |
||
1311 | |||
1312 | SKM_Config.DebugLevel = iNewLevel; |
||
1313 | SkM_ChatMessageCol("Debug level set to "..iNewLevel); |
||
1314 | end |
||
1315 | |||
1316 | |||
1317 | function SkM_StartDebugRecord() |
||
1318 | SKM_Context.RecLines = 0; |
||
1319 | SKM_Context.TmpRecLines = 0; |
||
1320 | SKM_Config.RecordDebug = true; |
||
1321 | SkM_ChatMessageCol("Started recording debug messages"); |
||
1322 | end |
||
1323 | |||
1324 | |||
1325 | function SkM_StopDebugRecord() |
||
1326 | SKM_Config.RecordDebug = false; |
||
1327 | SKM_Context.RecLines = nil; |
||
1328 | SKM_Context.TmpRecLines = nil; |
||
1329 | SkM_ChatMessageCol("Stopped recording debug messages"); |
||
1330 | end |
||
1331 | |||
1332 | |||
1333 | function SkM_ClearDebugRecord() |
||
1334 | SKM_Debug = { }; |
||
1335 | SKM_Context.RecLines = 0; |
||
1336 | SKM_Context.TmpRecLines = 0; |
||
1337 | SkM_ChatMessageCol("Recorded debug messages cleared"); |
||
1338 | end |
||
1339 | |||
1340 | |||
1341 | |||
1342 | -- -------------------------------------------------------------------------------------- |
||
1343 | -- SkM_GetDate |
||
1344 | -- -------------------------------------------------------------------------------------- |
||
1345 | -- Get current date in two formats : |
||
1346 | -- DD/MM/YYYY HH:MI:SS |
||
1347 | -- YYYY/MM/DD HH:MI:SS (this is a sortable date) |
||
1348 | -- -------------------------------------------------------------------------------------- |
||
1349 | function SkM_GetDate() |
||
1350 | -- date is a shortcut to "os.date" (os package is not available, but Blizz provided |
||
1351 | -- us the date function :) |
||
1352 | local CurDate = date("*t"); |
||
1353 | local sYear = string.format("%0.04d", CurDate.year); |
||
1354 | local sMonth = string.format("%0.02d", CurDate.month); |
||
1355 | local sDay = string.format("%0.02d", CurDate.day); |
||
1356 | local sHour = string.format("%0.02d", CurDate.hour); |
||
1357 | local sMin = string.format("%0.02d", CurDate.min); |
||
1358 | local sSec = string.format("%0.02d", CurDate.sec); |
||
1359 | |||
1360 | -- date in format DD/MM/YYYY HH:MI:SS |
||
1361 | local StrDate1 = sDay.."/"..sMonth.."/"..sYear.." "..sHour..":"..sMin..":"..sSec; |
||
1362 | |||
1363 | -- date in format YYYY/MM/DD HH:MI:SS (useful for sorting !) |
||
1364 | local StrDate2 = sYear.."/"..sMonth.."/"..sDay.." "..sHour..":"..sMin..":"..sSec; |
||
1365 | |||
1366 | return StrDate1, StrDate2; |
||
1367 | end |
||
1368 | |||
1369 | |||
1370 | function SkM_GetDay() |
||
1371 | local sDate1, sDate2 = SkM_GetDate(); |
||
1372 | local sDay1, sDay2; |
||
1373 | sDay1 = string.sub(sDate1, 1, 10); |
||
1374 | sDay2 = string.sub(sDate2, 1, 10); |
||
1375 | return sDay1, sDay2; |
||
1376 | end |
||
1377 | |||
1378 | |||
1379 | -- -------------------------------------------------------------------------------------- |
||
1380 | -- SkM_GetSortableDate |
||
1381 | -- -------------------------------------------------------------------------------------- |
||
1382 | -- Convert date to sortable format : |
||
1383 | -- from DD/MM/YYYY HH:MI:SS format to YYYY/MM/DD HH:MI:SS format |
||
1384 | -- or, from DD/MM/YYYY format to YYYY/MM/DD format |
||
1385 | -- -------------------------------------------------------------------------------------- |
||
1386 | function SkM_GetSortableDate(sDate) |
||
1387 | if (not sDate) then |
||
1388 | return nil; |
||
1389 | end |
||
1390 | |||
1391 | local sMonth, sDay, sYear, sHour, sMin, sSec; |
||
1392 | local sSortDate; |
||
1393 | |||
1394 | sDay = string.sub(sDate, 1, 2); |
||
1395 | sMonth = string.sub(sDate, 4, 5); |
||
1396 | sYear = string.sub(sDate, 7, 10); |
||
1397 | |||
1398 | if (string.len(sDate) == 19) then |
||
1399 | sHour = string.sub(sDate, 12, 13); |
||
1400 | sMin = string.sub(sDate, 15, 16); |
||
1401 | sSec = string.sub(sDate, 18, 19); |
||
1402 | |||
1403 | SortDate = sYear.."/"..sMonth.."/"..sDay.." "..sHour..":"..sMin..":"..sSec; |
||
1404 | else |
||
1405 | SortDate = sYear.."/"..sMonth.."/"..sDay; |
||
1406 | end |
||
1407 | |||
1408 | -- sortable date |
||
1409 | return SortDate; |
||
1410 | end |
||
1411 | |||
1412 | |||
1413 | function SkM_GetZoneText() |
||
1414 | local sText = GetZoneText(); |
||
1415 | -- apply fix if needed. |
||
1416 | for idx, val in SKM_ZoneFix do |
||
1417 | if sText == val.Val_ZoneText then |
||
1418 | return val.Val_MapZones; |
||
1419 | end |
||
1420 | end |
||
1421 | return sText; |
||
1422 | end |
||
1423 | |||
1424 | |||
1425 | -- Return continent and zone number shifted to english order |
||
1426 | function SkM_GetCurrentMapZone_Shift() |
||
1427 | local FName = "SkM_GetCurrentMapZone_Shift"; |
||
1428 | |||
1429 | local iCont = GetCurrentMapContinent(); |
||
1430 | local iZone = GetCurrentMapZone(); |
||
1431 | if (iCont) and (iCont ~= 0) and (iZone) and (iZone ~= 0) and (SKM_ZoneShift) then |
||
1432 | if (SKM_ZoneShift[iCont]) and (SKM_ZoneShift[iCont][iZone]) then |
||
1433 | iZone = SKM_ZoneShift[iCont][iZone]; |
||
1434 | else |
||
1435 | SkM_Trace(FName, 1, "Undefined shift : cont = "..iCont.." / zone = "..iZone); |
||
1436 | end |
||
1437 | end |
||
1438 | return iCont, iZone; |
||
1439 | end |
||
1440 | |||
1441 | |||
1442 | -- -------------------------------------------------------------------------------------- |
||
1443 | -- SkM_GetZone |
||
1444 | -- -------------------------------------------------------------------------------------- |
||
1445 | -- Return continent and zone number |
||
1446 | -- or (nil, nil) if GetZoneText() does not match any known zone |
||
1447 | -- -------------------------------------------------------------------------------------- |
||
1448 | function SkM_GetZone() |
||
1449 | for i=1, getn(SKM_Context.Continents), 1 do |
||
1450 | for j=1, getn(SKM_Context.Zones[i]), 1 do |
||
1451 | --if (SKM_Context.Zones[i][j] == GetZoneText()) then |
||
1452 | if (SKM_Context.Zones[i][j] == SkM_GetZoneText()) then |
||
1453 | return i, j; |
||
1454 | end |
||
1455 | end |
||
1456 | end |
||
1457 | return nil, nil; |
||
1458 | end |
||
1459 | |||
1460 | |||
1461 | function SkM_GetZone_Shift(p_iCont, p_iZone) |
||
1462 | local iCont, iZone; |
||
1463 | if (p_iCont) and (p_iZone) then |
||
1464 | iCont = p_iCont; |
||
1465 | iZone = p_iZone; |
||
1466 | else |
||
1467 | iCont, iZone = SkM_GetZone(); |
||
1468 | end |
||
1469 | |||
1470 | if (iCont) and (iZone) and (SKM_ZoneShift) then |
||
1471 | iZone = SKM_ZoneShift[iCont][iZone]; |
||
1472 | end |
||
1473 | return iCont, iZone; |
||
1474 | end |
||
1475 | |||
1476 | |||
1477 | -- get zone text from shifted zone index (english order) |
||
1478 | function SkM_GetZoneTextFromIndex(p_iCont, p_iZone) |
||
1479 | return ifnil(SKM_ZoneText[p_iCont][p_iZone], ""); |
||
1480 | end |
||
1481 | |||
1482 | |||
1483 | function SkM_IsInBattleground() |
||
1484 | local FName = "SkM_IsInBattleground"; |
||
1485 | local sZone = SkM_GetZoneText(); |
||
1486 | if (intable(sZone, SKM_BATTLEGROUNDS)) then |
||
1487 | return true; |
||
1488 | else |
||
1489 | return false; |
||
1490 | end |
||
1491 | end |
||
1492 | |||
1493 | |||
1494 | -- -------------------------------------------------------------------------------------- |
||
1495 | -- SkM_CheckNearNotes |
||
1496 | -- -------------------------------------------------------------------------------------- |
||
1497 | -- Check if there are notes nearby given location |
||
1498 | -- OBSOLETE. I don't use it any more. |
||
1499 | -- -------------------------------------------------------------------------------------- |
||
1500 | function SkM_CheckNearNotes(idx_c, idx_z, xPos, yPos, icon) |
||
1501 | local iNoteCount = getn(SKM_Data[_RealmName][_PlayerName].MapData[idx_c][idx_z]); |
||
1502 | |||
1503 | for i=1, iNoteCount, 1 do |
||
1504 | local idx_gn = SKM_Data[_RealmName][_PlayerName].MapData[idx_c][idx_z][i]; |
||
1505 | local Note = SKM_Data[_RealmName][_PlayerName].GlobalMapData[idx_gn]; |
||
1506 | |||
1507 | if (abs(Note[_SKM._xPos] - xPos) <= 0.0009765625 * SKM_Config.MapNotes_MinDiff) |
||
1508 | and (abs(Note[_SKM._yPos] - yPos) <= 0.0013020833 * SKM_Config.MapNotes_MinDiff) |
||
1509 | then |
||
1510 | return true; |
||
1511 | end |
||
1512 | end |
||
1513 | return false; |
||
1514 | end |
||
1515 | |||
1516 | |||
1517 | -- -------------------------------------------------------------------------------------- |
||
1518 | -- SkM_FindNotePOINum |
||
1519 | -- -------------------------------------------------------------------------------------- |
||
1520 | -- Retrieve which POI object is associated to a given map note |
||
1521 | -- -------------------------------------------------------------------------------------- |
||
1522 | function SkM_FindNotePOINum(idx_n) |
||
1523 | for idx_poi, val_poi in SKM_Context.WorldMapPOINotes do |
||
1524 | if (intable(idx_n, val_poi)) then |
||
1525 | return idx_poi; |
||
1526 | end |
||
1527 | end |
||
1528 | return nil; |
||
1529 | end |
||
1530 | |||
1531 | |||
1532 | -- -------------------------------------------------------------------------------------- |
||
1533 | -- SkM_CheckNearNotesPOI |
||
1534 | -- -------------------------------------------------------------------------------------- |
||
1535 | -- For a given map note, try and find nearby allocated POI so that we may group |
||
1536 | -- current note to the notes associated to this POI. |
||
1537 | -- -------------------------------------------------------------------------------------- |
||
1538 | function SkM_CheckNearNotesPOI(idx_c, idx_z, xPos, yPos, index, DiscardedNotes) |
||
1539 | local iNoteCount = getn(SKM_Data[_RealmName][_PlayerName].MapData[idx_c][idx_z]); |
||
1540 | |||
1541 | local i; |
||
1542 | for i=1, iNoteCount, 1 do |
||
1543 | -- don't check notes > current note, because they've not been treated yet |
||
1544 | if (i == index) then |
||
1545 | return nil; |
||
1546 | end |
||
1547 | |||
1548 | if (intable(i, DiscardedNotes)) then |
||
1549 | -- that note has been discarded, so don't check if it's too close ! |
||
1550 | else |
||
1551 | local idx_gn = SKM_Data[_RealmName][_PlayerName].MapData[idx_c][idx_z][i]; |
||
1552 | local Note = SKM_Data[_RealmName][_PlayerName].GlobalMapData[idx_gn]; |
||
1553 | |||
1554 | if (abs(Note[_SKM._xPos] - xPos) <= 0.0009765625 * SKM_Config.MapNotes_MinDiff) |
||
1555 | and (abs(Note[_SKM._yPos] - yPos) <= 0.0013020833 * SKM_Config.MapNotes_MinDiff) |
||
1556 | then |
||
1557 | -- we're close to another note that has an associated POI |
||
1558 | -- find this POI number and return it |
||
1559 | local iPOINum = SkM_FindNotePOINum(i); |
||
1560 | return iPOINum; |
||
1561 | end |
||
1562 | end |
||
1563 | end |
||
1564 | return nil; |
||
1565 | end |
||
1566 | |||
1567 | |||
1568 | -- -------------------------------------------------------------------------------------- |
||
1569 | -- SkM_AddMapNote |
||
1570 | -- -------------------------------------------------------------------------------------- |
||
1571 | -- Add a new player map note |
||
1572 | -- -------------------------------------------------------------------------------------- |
||
1573 | function SkM_AddMapNote(idx_c, idx_z, Note) |
||
1574 | local FName = "SkM_AddMapNote"; |
||
1575 | |||
1576 | -- insert note to global data in last position |
||
1577 | table.insert(SKM_Data[_RealmName][_PlayerName].GlobalMapData, Note); |
||
1578 | |||
1579 | -- retrieve index of inserted note |
||
1580 | local idx_gn = table.getn(SKM_Data[_RealmName][_PlayerName].GlobalMapData); |
||
1581 | |||
1582 | -- insert new global note index to map note list |
||
1583 | table.insert(SKM_Data[_RealmName][_PlayerName].MapData[idx_c][idx_z], idx_gn); |
||
1584 | end |
||
1585 | |||
1586 | |||
1587 | -- -------------------------------------------------------------------------------------- |
||
1588 | -- SkM_AddMapData |
||
1589 | -- -------------------------------------------------------------------------------------- |
||
1590 | -- Create a new note from input stored data and store it in current zone records |
||
1591 | -- -------------------------------------------------------------------------------------- |
||
1592 | function SkM_AddMapData(p_StoreInfo) |
||
1593 | local FName = "SkM_AddMapData"; |
||
1594 | |||
1595 | local idx_c, idx_z = SkM_GetZone(); |
||
1596 | |||
1597 | SkM_Trace(FName, 3, "idx_c = "..snil(idx_c)..", idx_z = "..snil(idx_z)); |
||
1598 | |||
1599 | if (idx_z) then |
||
1600 | SetMapZoom(idx_c, idx_z); |
||
1601 | local xPos, yPos = GetPlayerMapPosition(SKM_UNIT_PLAYER); |
||
1602 | |||
1603 | local cont_shift, zone_shift = SkM_GetZone_Shift(idx_c, idx_z); |
||
1604 | |||
1605 | SkM_Trace(FName, 3, "Player Position : x = "..snil(xPos)..", y = "..snil(yPos)); |
||
1606 | |||
1607 | --if ((not SkM_CheckNearNotes(idx_c, idx_z, xPos, yPos, icon)) and xPos ~= 0 and yPos ~= 0 ) then |
||
1608 | if (xPos ~= 0 and yPos ~= 0) then |
||
1609 | |||
1610 | local Note = { }; |
||
1611 | --Note[_SKM._continent] = idx_c; |
||
1612 | --Note[_SKM._zone] = idx_z; |
||
1613 | Note[_SKM._continent] = cont_shift; |
||
1614 | Note[_SKM._zone] = zone_shift; |
||
1615 | Note[_SKM._xPos] = xPos; |
||
1616 | Note[_SKM._yPos] = yPos; |
||
1617 | Note[_SKM._storedInfo] = p_StoreInfo; |
||
1618 | |||
1619 | -- DOH !! forgot this one in 1.4. Now all records are messed up :( |
||
1620 | --SkM_AddMapNote(idx_c, idx_z, Note); |
||
1621 | SkM_AddMapNote(cont_shift, zone_shift, Note); |
||
1622 | SKM_Context.RecordingDisabled = false; |
||
1623 | return true; |
||
1624 | end |
||
1625 | end |
||
1626 | |||
1627 | if (not SKM_Context.RecordingDisabled) then |
||
1628 | -- 1.5 : removed message that is of no use ! |
||
1629 | --SkM_ChatMessageCol("Event recording is disabled in this location"); |
||
1630 | SKM_Context.RecordingDisabled = true; |
||
1631 | end |
||
1632 | |||
1633 | return false; |
||
1634 | end |
||
1635 | |||
1636 | |||
1637 | -- -------------------------------------------------------------------------------------- |
||
1638 | -- SkM_RecordPlayerDeath |
||
1639 | -- -------------------------------------------------------------------------------------- |
||
1640 | -- Record player death event. |
||
1641 | -- Find if it's a PvE or PvP or unknown death, determine responsibilities for this |
||
1642 | -- death, and create a record of the appropriate type. |
||
1643 | -- -------------------------------------------------------------------------------------- |
||
1644 | function SkM_RecordPlayerDeath() |
||
1645 | local FName = "SkM_RecordPlayerDeath"; |
||
1646 | |||
1647 | local StoreInfo = { }; |
||
1648 | |||
1649 | StoreInfo[_SKM._type] = _SKM._playerDeath; |
||
1650 | |||
1651 | local sDate1, sDate2 = SkM_GetDate(); |
||
1652 | StoreInfo[_SKM._date] = sDate1; |
||
1653 | --StoreInfo[_sortdate] = sDate2; |
||
1654 | |||
1655 | local sKiller, KillerType, HateList = SkM_PlayerDeathResp(); |
||
1656 | |||
1657 | -- check if in battleground |
||
1658 | local bBattleground = SkM_IsInBattleground(); |
||
1659 | |||
1660 | -- if killer is known, and if its type (player or creature) is also known, record |
||
1661 | -- specific death event |
||
1662 | |||
1663 | -- note : it's possible that we determined that a given unit is responsible for our |
||
1664 | -- death, but we don't know if it's a player or a creature. It can happen if this |
||
1665 | -- unit killed us with dots only. In that case, the death type will be undetermined. |
||
1666 | |||
1667 | -- addition : it can happen also because pets and players trigger the same events, thus |
||
1668 | -- if we never targetted or mouse-overed a given player, we will not know if he is |
||
1669 | -- a player or a pet. |
||
1670 | |||
1671 | if (sKiller) and (KillerType == nil) then |
||
1672 | -- try to target to see if this is a player |
||
1673 | TargetByName(sKiller); |
||
1674 | SkM_UpdateUnitData(); |
||
1675 | |||
1676 | -- if this is an enemy player, then he should have been stored ! |
||
1677 | if (SKM_Data[_RealmName][_PlayerName].EnemyHistory[sKiller]) then |
||
1678 | KillerType = _SKM._enemyPlayer; |
||
1679 | end |
||
1680 | end |
||
1681 | |||
1682 | if (sKiller) and (KillerType) then |
||
1683 | StoreInfo[_SKM._name] = sKiller; |
||
1684 | StoreInfo[_SKM._enemyType] = KillerType; |
||
1685 | |||
1686 | if (KillerType == _SKM._enemyPlayer) then |
||
1687 | SkM_UpdateEnemyLastView(sKiller, sDate1, false); |
||
1688 | |||
1689 | StoreInfo[_SKM._type] = _SKM._playerDeathPvP; |
||
1690 | |||
1691 | SkM_UpdateEnemy_IncrKillPlayer(sKiller, 1, bBattleground); |
||
1692 | |||
1693 | if (bBattleground) then |
||
1694 | SkM_BGStats_AddDeath(); |
||
1695 | end |
||
1696 | |||
1697 | -- update target info if needed |
||
1698 | SkM_SetTargetInfo(); |
||
1699 | |||
1700 | else |
||
1701 | StoreInfo[_SKM._type] = _SKM._playerDeathPvE; |
||
1702 | end |
||
1703 | end |
||
1704 | |||
1705 | -- check if world record are disabled, if it's the case return |
||
1706 | if (StoreInfo[_SKM._type] == _SKM._playerDeathPvP) then |
||
1707 | if (not SkM_GetOption("RecordPlayerDeath")) then |
||
1708 | return; |
||
1709 | end |
||
1710 | else |
||
1711 | if (not SkM_GetOption("RecordPlayerDeathNonPvP")) then |
||
1712 | return; |
||
1713 | end |
||
1714 | end |
||
1715 | |||
1716 | |||
1717 | if (SkM_AddMapData(StoreInfo)) then |
||
1718 | |||
1719 | if (SkM_GetOption("DisplayDeathRecord")) then |
||
1720 | if (sKiller) and (KillerType) then |
||
1721 | if (KillerType == _SKM._enemyPlayer) then |
||
1722 | SkM_ChatMessageColP(string.format(SKM_UI_STRINGS.RecordMessage_PlayerPvPDeath, sKiller), SKM_Config.RGB_PlayerPvPDeath); |
||
1723 | else |
||
1724 | SkM_ChatMessageColP(string.format(SKM_UI_STRINGS.RecordMessage_PlayerPvEDeath, sKiller), SKM_Config.RGB_PlayerPvEDeath); |
||
1725 | end |
||
1726 | else |
||
1727 | SkM_ChatMessageColP(SKM_UI_STRINGS.RecordMessage_PlayerDeath, SKM_Config.RGB_PlayerDeath); |
||
1728 | end |
||
1729 | end |
||
1730 | |||
1731 | end |
||
1732 | |||
1733 | if (SkM_GetOption("ReportPlayerDeath")) then |
||
1734 | local iNbLine = math.min(SKM_Config.ReportDeathMaxLines, table.getn(HateList)); |
||
1735 | if (iNbLine > 0) then |
||
1736 | SkM_ChatMessageColP(string.format(SKM_UI_STRINGS.ReportMessage_PlayerDeath, iNbLine), |
||
1737 | SKM_Config.RGB_ReportDeath); |
||
1738 | |||
1739 | for i=1, iNbLine, 1 do |
||
1740 | SkM_ChatMessageColP(string.format("%d. %s (%d %%)", i, HateList[i][_SKM._name], HateList[i][_SKM._hatePercent]), |
||
1741 | SKM_Config.RGB_ReportDeath); |
||
1742 | end |
||
1743 | end |
||
1744 | end |
||
1745 | |||
1746 | end |
||
1747 | |||
1748 | |||
1749 | -- -------------------------------------------------------------------------------------- |
||
1750 | -- SkM_PlayerAlive |
||
1751 | -- -------------------------------------------------------------------------------------- |
||
1752 | -- Player is back to life, remember it. |
||
1753 | -- -------------------------------------------------------------------------------------- |
||
1754 | function SkM_PlayerAlive() |
||
1755 | SKM_Context.PlayerAlive = true; |
||
1756 | end |
||
1757 | |||
1758 | |||
1759 | -- -------------------------------------------------------------------------------------- |
||
1760 | -- SkM_PlayerDeath |
||
1761 | -- -------------------------------------------------------------------------------------- |
||
1762 | -- Handle player death event. |
||
1763 | -- -------------------------------------------------------------------------------------- |
||
1764 | function SkM_PlayerDeath() |
||
1765 | local FName = "SkM_PlayerDeath"; |
||
1766 | |||
1767 | -- check if player was alive because in some cases we get two death messages for the |
||
1768 | -- same death |
||
1769 | if (SKM_Context.PlayerAlive == false) then |
||
1770 | SkM_Trace(FName, 3, "Not alive, discard death event"); |
||
1771 | return; |
||
1772 | end |
||
1773 | |||
1774 | SKM_Context.PlayerAlive = false; |
||
1775 | |||
1776 | -- if (not SkM_GetOption("RecordPlayerDeath")) then |
||
1777 | -- return; |
||
1778 | -- end |
||
1779 | |||
1780 | SkM_RecordPlayerDeath(); |
||
1781 | end |
||
1782 | |||
1783 | |||
1784 | -- -------------------------------------------------------------------------------------- |
||
1785 | -- SkM_WorldMapUpdate |
||
1786 | -- -------------------------------------------------------------------------------------- |
||
1787 | -- Handle World Map Update event |
||
1788 | -- -------------------------------------------------------------------------------------- |
||
1789 | function SkM_WorldMapUpdate() |
||
1790 | local FName = "SkM_WorldMapUpdate"; |
||
1791 | |||
1792 | if (WorldMapFrame:IsVisible()) then |
||
1793 | -- world map is visible, draw all that need to be ! |
||
1794 | |||
1795 | --local serverTime = GetTime(); |
||
1796 | SKM_Context.MapOpen = true; |
||
1797 | --local mapContinent = GetCurrentMapContinent(); |
||
1798 | --local mapZone = GetCurrentMapZone(); |
||
1799 | local mapContinent, mapZone = SkM_GetCurrentMapZone_Shift(); |
||
1800 | SKM_Context.CloseMap = { continent = mapContinent, zone = mapZone, time = GetTime() }; |
||
1801 | SkM_MainDraw(); |
||
1802 | |||
1803 | elseif (SKM_Context.MapOpen) then |
||
1804 | -- Map is not visible, but recorded as opened. Close it. |
||
1805 | SKM_Context.MapOpen = false; |
||
1806 | SkM_MainDraw(); |
||
1807 | --SkM_ChangeMap(); |
||
1808 | else |
||
1809 | -- Map not visible, probably closed |
||
1810 | end |
||
1811 | |||
1812 | end |
||
1813 | |||
1814 | |||
1815 | -- -------------------------------------------------------------------------------------- |
||
1816 | -- SkM_CloseWorldMap |
||
1817 | -- -------------------------------------------------------------------------------------- |
||
1818 | -- Handle Close World Map event |
||
1819 | -- -------------------------------------------------------------------------------------- |
||
1820 | function SkM_CloseWorldMap() |
||
1821 | local FName = "SkM_CloseWorldMap"; |
||
1822 | |||
1823 | SKM_Context.MapOpen = false; |
||
1824 | SkM_MainDraw(); |
||
1825 | --SkM_ChangeMap(); |
||
1826 | end |
||
1827 | |||
1828 | |||
1829 | -- -------------------------------------------------------------------------------------- |
||
1830 | -- SkM_MainDraw |
||
1831 | -- -------------------------------------------------------------------------------------- |
||
1832 | -- Display our records as custom POI on the world map, and hide unused POI. |
||
1833 | -- -------------------------------------------------------------------------------------- |
||
1834 | function SkM_MainDraw() |
||
1835 | local FName = "SkM_MainDraw"; |
||
1836 | |||
1837 | SKM_Context.WorldMapPOINotes = { }; |
||
1838 | |||
1839 | local lastUnused = 1; |
||
1840 | local maxNotes = SKM_MAX_MAP_NOTES; |
||
1841 | local iNbNotes = 0; |
||
1842 | |||
1843 | --local idx_c = GetCurrentMapContinent(); |
||
1844 | --local idx_z = GetCurrentMapZone(); |
||
1845 | local idx_c, idx_z = SkM_GetCurrentMapZone_Shift(); |
||
1846 | |||
1847 | if (idx_c ~= 0) and (idx_z ~= 0) |
||
1848 | and (SKM_Data[_RealmName][_PlayerName].MapData[idx_c]) |
||
1849 | and (SKM_Data[_RealmName][_PlayerName].MapData[idx_c][idx_z]) |
||
1850 | then |
||
1851 | iNbNotes = table.getn(SKM_Data[_RealmName][_PlayerName].MapData[idx_c][idx_z]); |
||
1852 | end |
||
1853 | |||
1854 | if (SKM_Context.MapOpen) and (SkM_GetOption("MapDisplayRecords")) then |
||
1855 | |||
1856 | if (idx_c ~= 0) and (idx_z ~= 0) |
||
1857 | and (SKM_Data[_RealmName][_PlayerName].MapData[idx_c]) |
||
1858 | and (SKM_Data[_RealmName][_PlayerName].MapData[idx_c][idx_z]) |
||
1859 | then |
||
1860 | |||
1861 | --iNbNotes = table.getn(SKM_Data[_RealmName][_PlayerName].MapData[idx_c][idx_z]); |
||
1862 | |||
1863 | local DiscardedNotes = { }; |
||
1864 | |||
1865 | for idx_n, val_n in SKM_Data[_RealmName][_PlayerName].MapData[idx_c][idx_z] do |
||
1866 | |||
1867 | local idx_gn = SKM_Data[_RealmName][_PlayerName].MapData[idx_c][idx_z][idx_n]; |
||
1868 | local Note = SKM_Data[_RealmName][_PlayerName].GlobalMapData[idx_gn]; |
||
1869 | |||
1870 | if (Note[_SKM._xPos]) and (Note[_SKM._yPos]) and (lastUnused <= maxNotes) then |
||
1871 | local iPOINum = SkM_CheckNearNotesPOI(idx_c, idx_z, Note[_SKM._xPos], Note[_SKM._yPos], idx_n, DiscardedNotes); |
||
1872 | if (iPOINum) then |
||
1873 | SkM_Trace(FName, 3, "Already too close POI, discard this one : "..snil(idx_n)); |
||
1874 | |||
1875 | table.insert(DiscardedNotes, idx_n); |
||
1876 | |||
1877 | -- and insert it in the close POI list |
||
1878 | table.insert(SKM_Context.WorldMapPOINotes[iPOINum], idx_n); |
||
1879 | else |
||
1880 | local mainNote = getglobal("SKMapPOI"..lastUnused); |
||
1881 | |||
1882 | SKM_Context.WorldMapPOINotes[lastUnused] = { }; |
||
1883 | table.insert(SKM_Context.WorldMapPOINotes[lastUnused], idx_n); |
||
1884 | |||
1885 | local mnX,mnY; |
||
1886 | mnX = Note[_SKM._xPos] * WorldMapDetailFrame:GetWidth(); |
||
1887 | mnY = -Note[_SKM._yPos] * WorldMapDetailFrame:GetHeight(); |
||
1888 | mainNote:SetAlpha(0.8); |
||
1889 | |||
1890 | -- SkM_Trace(FName, 3, "Attach position : x = "..snil(mnX)..", y = "..snil(mnY)); |
||
1891 | |||
1892 | |||
1893 | mainNote:SetPoint("CENTER", "WorldMapDetailFrame", "TOPLEFT", mnX, mnY); |
||
1894 | mainNote:SetFrameLevel(WorldMapPlayer:GetFrameLevel() - 1); |
||
1895 | mainNote.toolTip = idx_n; |
||
1896 | |||
1897 | -- icon is determined below |
||
1898 | |||
1899 | lastUnused = lastUnused + 1; |
||
1900 | end |
||
1901 | |||
1902 | end |
||
1903 | end -- for map notes |
||
1904 | |||
1905 | for i=1, getn(SKM_Context.WorldMapPOINotes), 1 do |
||
1906 | local mainNote = getglobal("SKMapPOI"..i); |
||
1907 | local mainNoteTexture = getglobal("SKMapPOI"..i.."Texture"); |
||
1908 | |||
1909 | local iNbNotes = getn(SKM_Context.WorldMapPOINotes[i]); |
||
1910 | local icon; |
||
1911 | |||
1912 | local iNumOfTypes, iNumOfPlayerKillTypes, iNumOfPlayerDeathTypes, |
||
1913 | iNumOfCreatureKillTypes, TypeCount = SkM_CountPOIEventType(idx_c, idx_z, i); |
||
1914 | |||
1915 | SkM_Trace(FName, 3, "Number of different types = "..iNumOfTypes..", of player kill = "..iNumOfPlayerKillTypes..", of death = "..iNumOfPlayerDeathTypes); |
||
1916 | |||
1917 | if (iNumOfTypes == 1) then |
||
1918 | -- several notes, but of a single type. Pick the first ! |
||
1919 | |||
1920 | local idx_n = SKM_Context.WorldMapPOINotes[i][1]; |
||
1921 | local idx_gn = SKM_Data[_RealmName][_PlayerName].MapData[idx_c][idx_z][idx_n]; |
||
1922 | local Note = SKM_Data[_RealmName][_PlayerName].GlobalMapData[idx_gn]; |
||
1923 | |||
1924 | local noteType = Note[_SKM._storedInfo][_SKM._type]; |
||
1925 | SkM_Trace(FName, 3, "Single type = "..noteType); |
||
1926 | |||
1927 | icon = SKM_Config.IconsByType[noteType]; |
||
1928 | if (not icon) then |
||
1929 | icon = SKM_Config.IconsByType[_SKM._default]; |
||
1930 | end |
||
1931 | |||
1932 | else |
||
1933 | |||
1934 | if (iNumOfPlayerDeathTypes == iNumOfTypes) then |
||
1935 | icon = SKM_Config.IconsByType[_SKM._playerDeath]; |
||
1936 | elseif (iNumOfPlayerKillTypes == iNumOfTypes) then |
||
1937 | icon = SKM_Config.IconsByType[_SKM._playerKill]; |
||
1938 | elseif (iNumOfCreatureKillTypes == iNumOfTypes) then |
||
1939 | icon = SKM_Config.IconsByType[_SKM._creatureKill_Target]; |
||
1940 | elseif (iNumOfPlayerDeathTypes + iNumOfPlayerKillTypes == iNumOfTypes) then |
||
1941 | icon = SKM_Config.IconsByType[_SKM._playerKillAndDeath]; |
||
1942 | else |
||
1943 | icon = SKM_Config.IconsByType[_SKM._multiType]; |
||
1944 | end |
||
1945 | |||
1946 | end |
||
1947 | |||
1948 | local texture = SKM_Config.IconPath .. "\\" .. icon; |
||
1949 | SkM_Trace(FName, 3, "texture = "..texture); |
||
1950 | |||
1951 | mainNoteTexture:SetTexture(texture); |
||
1952 | mainNote:Show(); |
||
1953 | end |
||
1954 | |||
1955 | end -- if known zone info |
||
1956 | end -- if display map |
||
1957 | |||
1958 | -- hide unused notes |
||
1959 | for i=lastUnused, maxNotes, 1 do |
||
1960 | local mainNote = getglobal("SKMapPOI"..i); |
||
1961 | mainNote:Hide(); |
||
1962 | end |
||
1963 | |||
1964 | |||
1965 | |||
1966 | if (not SkM_GetOption("ShowWorldMapControl")) then |
||
1967 | SKMapWorldMapControl:Hide(); |
||
1968 | else |
||
1969 | |||
1970 | if (SKM_Context.MapOpen) and (idx_z ~= 0) and (iNbNotes > 0) then |
||
1971 | local idx=1; |
||
1972 | local MyButton = getglobal("SKMapWorldMapControl_CheckButton"..idx); |
||
1973 | local ButtonText = getglobal("SKMapWorldMapControl_CheckButton"..idx.."Text"); |
||
1974 | ButtonText:SetText(SKM_UI_STRINGS.WorldMap_Button_ShowRecords); |
||
1975 | |||
1976 | if (SkM_GetOption("MapDisplayRecords")) then |
||
1977 | MyButton:SetChecked(1); |
||
1978 | else |
||
1979 | MyButton:SetChecked(0); |
||
1980 | end |
||
1981 | |||
1982 | SKMapWorldMapControl:Show(); |
||
1983 | else |
||
1984 | SKMapWorldMapControl:Hide(); |
||
1985 | end |
||
1986 | end |
||
1987 | |||
1988 | end |
||
1989 | |||
1990 | |||
1991 | -- -------------------------------------------------------------------------------------- |
||
1992 | -- SkM_CountPOIEventType |
||
1993 | -- -------------------------------------------------------------------------------------- |
||
1994 | -- Count the different types of records attached to a given POI. |
||
1995 | -- Will be useful to allocate an icon to this POI. |
||
1996 | -- -------------------------------------------------------------------------------------- |
||
1997 | function SkM_CountPOIEventType(idx_c, idx_z, iPOINum) |
||
1998 | local FName = "SkM_CountPOIEventType"; |
||
1999 | |||
2000 | local iNbNotes = getn(SKM_Context.WorldMapPOINotes[iPOINum]); |
||
2001 | local TypeCount = { }; |
||
2002 | |||
2003 | local iPlayerDeathTypes = 0; |
||
2004 | local iPlayerKillTypes = 0; |
||
2005 | local iCreatureKillTypes = 0; |
||
2006 | |||
2007 | for i=1, iNbNotes, 1 do |
||
2008 | local idx_n = SKM_Context.WorldMapPOINotes[iPOINum][i]; |
||
2009 | local idx_gn = SKM_Data[_RealmName][_PlayerName].MapData[idx_c][idx_z][idx_n]; |
||
2010 | local Note = SKM_Data[_RealmName][_PlayerName].GlobalMapData[idx_gn]; |
||
2011 | |||
2012 | local noteType = Note[_SKM._storedInfo][_SKM._type]; |
||
2013 | |||
2014 | |||
2015 | if (not TypeCount[noteType]) then |
||
2016 | TypeCount[noteType] = 0; |
||
2017 | end |
||
2018 | TypeCount[noteType] = TypeCount[noteType] + 1; |
||
2019 | end |
||
2020 | local iTypes = 0; |
||
2021 | for idx, val in TypeCount do |
||
2022 | iTypes = iTypes + 1; |
||
2023 | if (idx == _SKM._playerAssistKill) or (idx == _SKM._playerKill) or (idx == _SKM._playerFullKill) then |
||
2024 | iPlayerKillTypes = iPlayerKillTypes + 1; |
||
2025 | elseif (idx == _SKM._playerDeath) or (idx == _SKM._playerDeathPvE) or (idx == _SKM._playerDeathPvP) then |
||
2026 | iPlayerDeathTypes = iPlayerDeathTypes + 1; |
||
2027 | elseif (idx == _SKM._creatureKill_Xp) or (idx == _SKM._creatureKill_Target) then |
||
2028 | iCreatureKillTypes = iCreatureKillTypes + 1; |
||
2029 | end |
||
2030 | |||
2031 | SkM_Trace(FName, 3, "Type = "..idx..", Count = "..val); |
||
2032 | end |
||
2033 | return iTypes, iPlayerKillTypes, iPlayerDeathTypes, iCreatureKillTypes, TypeCount; |
||
2034 | end |
||
2035 | |||
2036 | |||
2037 | -- -------------------------------------------------------------------------------------- |
||
2038 | -- SkM_GetNoteMessage |
||
2039 | -- -------------------------------------------------------------------------------------- |
||
2040 | -- Build a note string message from a pattern and an information structure |
||
2041 | -- -------------------------------------------------------------------------------------- |
||
2042 | function SkM_GetNoteMessage(Info, sMessagePattern) |
||
2043 | local FName = "SkM_GetNoteMessage"; |
||
2044 | |||
2045 | if (not Info) then |
||
2046 | SkM_Trace(FName, 3, "Info is nil"); |
||
2047 | return nil; |
||
2048 | end |
||
2049 | if (not sMessagePattern) then |
||
2050 | SkM_Trace(FName, 3, "Pattern is nil"); |
||
2051 | return nil; |
||
2052 | end |
||
2053 | |||
2054 | local sMessage = sMessagePattern; |
||
2055 | |||
2056 | local sVal_Name = ifnil(Info[_SKM._name], "??"); |
||
2057 | local sVal_Guild = ifnil(Info[_SKM._guild], "??"); |
||
2058 | local sVal_Class = ifnil(Info[_SKM._class], "??"); |
||
2059 | local sVal_Race = ifnil(Info[_SKM._race], "??"); |
||
2060 | local sVal_Level = ifnil(Info[_SKM._level], "??"); |
||
2061 | local sVal_Player = ifnil(_PlayerName, "??"); |
||
2062 | local sVal_Date = ifnil(Info[_SKM._date], "??"); |
||
2063 | |||
2064 | if (sVal_Level == -1) then |
||
2065 | sVal_Level = "++"; |
||
2066 | end |
||
2067 | |||
2068 | sMessage = string.gsub(sMessage, "%%name", sVal_Name); |
||
2069 | sMessage = string.gsub(sMessage, "%%race", sVal_Race); |
||
2070 | sMessage = string.gsub(sMessage, "%%guild", sVal_Guild); |
||
2071 | sMessage = string.gsub(sMessage, "%%class", sVal_Class); |
||
2072 | sMessage = string.gsub(sMessage, "%%level", sVal_Level); |
||
2073 | sMessage = string.gsub(sMessage, "%%player", sVal_Player); |
||
2074 | sMessage = string.gsub(sMessage, "%%date", sVal_Date); |
||
2075 | |||
2076 | return sMessage; |
||
2077 | end |
||
2078 | |||
2079 | |||
2080 | -- -------------------------------------------------------------------------------------- |
||
2081 | -- SkM_FillWorldMapToolTip |
||
2082 | -- -------------------------------------------------------------------------------------- |
||
2083 | -- Builds the ToolTip for one of our custom POI that just got mouse focus. |
||
2084 | -- -------------------------------------------------------------------------------------- |
||
2085 | function SkM_FillWorldMapToolTip(idx_c, idx_z, idx_n, idx_poi) |
||
2086 | local FName = "SkM_FillWorldMapToolTip"; |
||
2087 | |||
2088 | SkM_Trace(FName, 3, "idx_n = "..snil(idx_n)..", idx_poi = "..snil(idx_poi)); |
||
2089 | local iLineCount = 0; |
||
2090 | |||
2091 | local idx, val; |
||
2092 | |||
2093 | if (not SKM_Context.WorldMapPOINotes[idx_poi]) then |
||
2094 | SkM_Trace(FName, 3, "WorldMapPOINotes not defined for POI "..idx_poi); |
||
2095 | return; |
||
2096 | end |
||
2097 | for idx, val in SKM_Context.WorldMapPOINotes[idx_poi] do |
||
2098 | |||
2099 | local idx_gn = SKM_Data[_RealmName][_PlayerName].MapData[idx_c][idx_z][val]; |
||
2100 | local Note = SKM_Data[_RealmName][_PlayerName].GlobalMapData[idx_gn]; |
||
2101 | |||
2102 | SkM_Trace(FName, 4, "idx_gn = "..snil(idx_gn)); |
||
2103 | |||
2104 | --local StoredInfo = Note[_SKM._storedInfo]; |
||
2105 | local StoredInfo = copytable(Note[_SKM._storedInfo]); |
||
2106 | |||
2107 | iLineCount = iLineCount + 1; |
||
2108 | if (iLineCount > SKM_Config.MapNotes_MaxLines) then |
||
2109 | return false; |
||
2110 | end |
||
2111 | |||
2112 | local sPattern; |
||
2113 | local sName = StoredInfo[_SKM._name]; |
||
2114 | |||
2115 | SkM_Trace(FName, 3, "Type = "..snil(StoredInfo[_SKM._type])); |
||
2116 | SkM_Trace(FName, 3, "Name = "..snil(sName)..", Enemy Type = "..snil(StoredInfo[_SKM._enemyType])); |
||
2117 | |||
2118 | local Enemy; |
||
2119 | if (sName) then |
||
2120 | if not (StoredInfo[_SKM._enemyType] == _SKM._enemyCreature |
||
2121 | or StoredInfo[_SKM._type] == _SKM._creatureKill_Target |
||
2122 | or StoredInfo[_SKM._type] == _SKM._creatureKill_Xp) then |
||
2123 | Enemy = SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName]; |
||
2124 | end |
||
2125 | end |
||
2126 | |||
2127 | |||
2128 | local bNoEnemyData = true; |
||
2129 | if (Enemy) then |
||
2130 | StoredInfo[_SKM._class] = SkM_GetClassText(Enemy[_SKM._class]); |
||
2131 | StoredInfo[_SKM._race] = SkM_GetRaceText(Enemy[_SKM._race]); |
||
2132 | StoredInfo[_SKM._level] = Enemy[_SKM._level]; |
||
2133 | |||
2134 | if (StoredInfo[_SKM._class]) or (StoredInfo[_SKM._race]) or (StoredInfo[_SKM._level]) then |
||
2135 | bNoEnemyData = false; |
||
2136 | end |
||
2137 | |||
2138 | SkM_Trace(FName, 3, "Class = "..snil(Enemy[_SKM._class])..", Race = "..snil(Enemy[_SKM._race])..", Level = "..snil(Enemy[_SKM._level])); |
||
2139 | end |
||
2140 | |||
2141 | |||
2142 | local RGB; |
||
2143 | local sPattern; |
||
2144 | |||
2145 | if (StoredInfo[_SKM._type] == _SKM._playerAssistKill) then |
||
2146 | sPattern = SKM_Config.Message_PlayerKill; |
||
2147 | RGB = SKM_Config.RGB_PlayerAssistKill; |
||
2148 | |||
2149 | elseif (StoredInfo[_SKM._type] == _SKM._playerKill) then |
||
2150 | sPattern = SKM_Config.Message_PlayerKill; |
||
2151 | RGB = SKM_Config.RGB_PlayerKill; |
||
2152 | |||
2153 | |||
2154 | elseif (StoredInfo[_SKM._type] == _SKM._playerFullKill) then |
||
2155 | sPattern = SKM_Config.Message_PlayerKill; |
||
2156 | |||
2157 | if (StoredInfo[_SKM._loneWolfKill]) then |
||
2158 | RGB = SKM_Config.RGB_LoneWolfKill; |
||
2159 | else |
||
2160 | RGB = SKM_Config.RGB_PlayerFullKill; |
||
2161 | end |
||
2162 | |||
2163 | elseif (StoredInfo[_SKM._type] == _SKM._playerDeath) then |
||
2164 | sPattern = SKM_Config.Message_PlayerDeath; |
||
2165 | RGB = SKM_Config.RGB_PlayerDeath; |
||
2166 | |||
2167 | elseif (StoredInfo[_SKM._type] == _SKM._playerDeathPvE) then |
||
2168 | sPattern = SKM_Config.Message_PlayerDeath_PvE; |
||
2169 | RGB = SKM_Config.RGB_PlayerPvEDeath; |
||
2170 | |||
2171 | elseif (StoredInfo[_SKM._type] == _SKM._playerDeathPvP) then |
||
2172 | if (bNoEnemyData == false) then |
||
2173 | sPattern = SKM_Config.Message_PlayerDeath_PvP; |
||
2174 | else |
||
2175 | sPattern = SKM_Config.Message_PlayerDeath_PvP_NoData; |
||
2176 | end |
||
2177 | RGB = SKM_Config.RGB_PlayerPvPDeath; |
||
2178 | |||
2179 | elseif (StoredInfo[_SKM._type] == _SKM._creatureKill_Target) then |
||
2180 | if (StoredInfo[_SKM._class]) then |
||
2181 | sPattern = SKM_Config.Message_CreatureKill_RareDetail; |
||
2182 | else |
||
2183 | sPattern = SKM_Config.Message_CreatureKill_Detail; |
||
2184 | end |
||
2185 | RGB = SKM_Config.RGB_CreatureKill; |
||
2186 | |||
2187 | elseif (StoredInfo[_SKM._type] == _SKM._creatureKill_Xp) then |
||
2188 | sPattern = SKM_Config.Message_CreatureKill_Basic; |
||
2189 | RGB = SKM_Config.RGB_CreatureKill; |
||
2190 | |||
2191 | elseif (StoredInfo[_SKM._type] == _SKM._levelUp) then |
||
2192 | sPattern = SKM_Config.Message_LevelUp; |
||
2193 | RGB = SKM_Config.RGB_LevelUp; |
||
2194 | end |
||
2195 | |||
2196 | if (StoredInfo[_SKM._honorKill]) then |
||
2197 | sPattern = sPattern.." "..SKM_Config.SubMessage_HonorKill; |
||
2198 | end |
||
2199 | |||
2200 | local sLine = SkM_GetNoteMessage(StoredInfo, sPattern); |
||
2201 | WorldMapTooltip:AddLine(sLine, RGB.r, RGB.g, RGB.b); |
||
2202 | end |
||
2203 | |||
2204 | return true; |
||
2205 | end |
||
2206 | |||
2207 | |||
2208 | -- -------------------------------------------------------------------------------------- |
||
2209 | -- SkM_WorldMapEnterPOI |
||
2210 | -- -------------------------------------------------------------------------------------- |
||
2211 | -- Handle POI "OnEnter" event : |
||
2212 | -- Acquire and prepare ToolTip, then display it. |
||
2213 | -- -------------------------------------------------------------------------------------- |
||
2214 | function SkM_WorldMapEnterPOI(id) |
||
2215 | local FName = "SkM_WorldMapEnterPOI"; |
||
2216 | |||
2217 | SkM_Trace(FName, 3, "id = "..id); |
||
2218 | |||
2219 | --if ((not MapNotesPOIMenuFrame:IsVisible()) and (not MapNotesNewMenuFrame:IsVisible()) and MapNotes_BlockingFrame()) then |
||
2220 | if (true) then |
||
2221 | local x, y = this:GetCenter(); |
||
2222 | local x2, y2 = WorldMapButton:GetCenter(); |
||
2223 | local anchor = ""; |
||
2224 | if (x > x2) then |
||
2225 | anchor = "ANCHOR_LEFT"; |
||
2226 | else |
||
2227 | anchor = "ANCHOR_RIGHT"; |
||
2228 | end |
||
2229 | |||
2230 | --local idx_z = GetCurrentMapZone(); |
||
2231 | --local idx_c = GetCurrentMapContinent(); |
||
2232 | local idx_c, idx_z = SkM_GetCurrentMapZone_Shift(); |
||
2233 | |||
2234 | local idx_n = this.toolTip; |
||
2235 | |||
2236 | local idx_gn = SKM_Data[_RealmName][_PlayerName].MapData[idx_c][idx_z][idx_n]; |
||
2237 | local Note = SKM_Data[_RealmName][_PlayerName].GlobalMapData[idx_gn]; |
||
2238 | |||
2239 | |||
2240 | SkM_Trace(FName, 3, "this.toolTip = "..this.toolTip); |
||
2241 | |||
2242 | WorldMapTooltip:SetOwner(this, anchor); |
||
2243 | |||
2244 | --WorldMapTooltip:SetText(""); -- doesn't display if no title |
||
2245 | WorldMapTooltip:SetText(SKM_UI_STRINGS.Map_Window_Title); |
||
2246 | |||
2247 | local xPos = Note[_SKM._xPos]; |
||
2248 | local yPos = Note[_SKM._yPos]; |
||
2249 | |||
2250 | |||
2251 | --SkM_FillWorldMapToolTip(idx_c, idx_z, xPos, yPos); |
||
2252 | SkM_FillWorldMapToolTip(idx_c, idx_z, idx_n, id); |
||
2253 | |||
2254 | WorldMapTooltip:Show(); |
||
2255 | else |
||
2256 | WorldMapTooltip:Hide(); |
||
2257 | end |
||
2258 | |||
2259 | end |
||
2260 | |||
2261 | |||
2262 | -- -------------------------------------------------------------------------------------- |
||
2263 | -- SkM_WorldMapLeavePOI |
||
2264 | -- -------------------------------------------------------------------------------------- |
||
2265 | -- Handle POI "OnLeave" event : |
||
2266 | -- Hide ToolTip. |
||
2267 | -- -------------------------------------------------------------------------------------- |
||
2268 | function SkM_WorldMapLeavePOI(id) |
||
2269 | local FName = "SkM_WorldMapLeavePOI"; |
||
2270 | WorldMapTooltip:Hide(); |
||
2271 | end |
||
2272 | |||
2273 | |||
2274 | -- -------------------------------------------------------------------------------------- |
||
2275 | -- SkM_FormatParsePattern |
||
2276 | -- -------------------------------------------------------------------------------------- |
||
2277 | -- Format a parsing pattern. |
||
2278 | -- Input pattern is a readable string that contains %s and %d for substitutions. |
||
2279 | -- Return value is a regular expression, with special characters escaped by '%'. |
||
2280 | -- -------------------------------------------------------------------------------------- |
||
2281 | function SkM_FormatParsePattern(sTemplate) |
||
2282 | local FName = "SkM_FormatParsePattern"; |
||
2283 | |||
2284 | local sPattern = sTemplate; |
||
2285 | |||
2286 | sPattern = string.gsub(sPattern, "%(", "%%("); |
||
2287 | sPattern = string.gsub(sPattern, "%)", "%%)"); |
||
2288 | sPattern = string.gsub(sPattern, "%.", "%%."); |
||
2289 | sPattern = string.gsub(sPattern, "%+", "%%+"); |
||
2290 | sPattern = string.gsub(sPattern, "%[", "%%["); |
||
2291 | sPattern = string.gsub(sPattern, "%]", "%%]"); |
||
2292 | |||
2293 | sPattern = string.gsub(sPattern, "%%d", "([0-9]+)"); |
||
2294 | sPattern = string.gsub(sPattern, "%%s", "(.+)"); |
||
2295 | |||
2296 | return sPattern; |
||
2297 | end |
||
2298 | |||
2299 | |||
2300 | -- -------------------------------------------------------------------------------------- |
||
2301 | -- SkM_BuildParsePatterns |
||
2302 | -- -------------------------------------------------------------------------------------- |
||
2303 | -- Format as regular expressions all the parsing patterns that we need. |
||
2304 | -- -------------------------------------------------------------------------------------- |
||
2305 | function SkM_BuildParsePatterns() |
||
2306 | local FName = "SkM_BuildParsePatterns"; |
||
2307 | |||
2308 | for idx, val in SKM_PATTERN do |
||
2309 | local sPattern = SkM_FormatParsePattern(val); |
||
2310 | SKM_Context.Pattern[idx] = sPattern; |
||
2311 | end |
||
2312 | end |
||
2313 | |||
2314 | |||
2315 | -- -------------------------------------------------------------------------------------- |
||
2316 | -- SkM_ParseCombatChat_XpGain |
||
2317 | -- -------------------------------------------------------------------------------------- |
||
2318 | -- Handle "player receives combat xp" chat event. |
||
2319 | -- If we can match one of the "creature kill" messages, then record the creature kill. |
||
2320 | -- -------------------------------------------------------------------------------------- |
||
2321 | function SkM_ParseCombatChat_XpGain(sMsg) |
||
2322 | local FName = "SkM_ParseCombatChat_XpGain"; |
||
2323 | |||
2324 | SkM_Trace(FName, 3, "You gain combat xp"); |
||
2325 | |||
2326 | for sFoe, iXpGain, iBaseXp, iRestXp in string.gfind(sMsg, SKM_Context.Pattern.XpGain_Rested_Solo) do |
||
2327 | if (sFoe and iXpGain and iBaseXp and iRestXp) then |
||
2328 | SkM_Trace(FName, 3, "XpGain_Rested_Solo : Foe = "..sFoe..", Xp = "..iXpGain); |
||
2329 | |||
2330 | SkM_RecordCreatureKill_Xp(sFoe); |
||
2331 | return; |
||
2332 | end |
||
2333 | end |
||
2334 | |||
2335 | for sFoe, iXpGain, iBaseXp, iRestXp, iGroupBonus in string.gfind(sMsg, SKM_Context.Pattern.XpGain_Rested_Group) do |
||
2336 | if (sFoe and iXpGain and iBaseXp and iRestXp and iGroupBonus) then |
||
2337 | SkM_Trace(FName, 3, "XpGain_Rested_Group : Foe = "..sFoe..", Xp = "..iXpGain); |
||
2338 | |||
2339 | SkM_RecordCreatureKill_Xp(sFoe); |
||
2340 | return; |
||
2341 | end |
||
2342 | end |
||
2343 | |||
2344 | for sFoe, iXpGain, iBaseXp, iRestXp, iRaidPenalty in string.gfind(sMsg, SKM_Context.Pattern.XpGain_Rested_Raid) do |
||
2345 | if (sFoe and iXpGain and iBaseXp and iRestXp and iRaidPenalty) then |
||
2346 | SkM_Trace(FName, 3, "XpGain_Rested_Raid : Foe = "..sFoe..", Xp = "..iXpGain); |
||
2347 | |||
2348 | SkM_RecordCreatureKill_Xp(sFoe); |
||
2349 | return; |
||
2350 | end |
||
2351 | end |
||
2352 | |||
2353 | for sFoe, iXpGain in string.gfind(sMsg, SKM_Context.Pattern.XpGain_Solo) do |
||
2354 | if (sFoe and iXpGain) then |
||
2355 | SkM_Trace(FName, 3, "XpGain_Solo : Foe = "..sFoe..", Xp = "..iXpGain); |
||
2356 | |||
2357 | SkM_RecordCreatureKill_Xp(sFoe); |
||
2358 | return; |
||
2359 | end |
||
2360 | end |
||
2361 | |||
2362 | for sFoe, iXpGain, iGroupBonus in string.gfind(sMsg, SKM_Context.Pattern.XpGain_Group) do |
||
2363 | if (sFoe and iXpGain and iGroupBonus) then |
||
2364 | SkM_Trace(FName, 3, "XpGain_Group : Foe = "..sFoe..", Xp = "..iXpGain); |
||
2365 | |||
2366 | SkM_RecordCreatureKill_Xp(sFoe); |
||
2367 | return; |
||
2368 | end |
||
2369 | end |
||
2370 | |||
2371 | for sFoe, iXpGain, iRaidPenalty in string.gfind(sMsg, SKM_Context.Pattern.XpGain_Raid) do |
||
2372 | if (sFoe and iXpGain and iRaidPenalty) then |
||
2373 | SkM_Trace(FName, 3, "XpGain_Raid : Foe = "..sFoe..", Xp = "..iXpGain); |
||
2374 | |||
2375 | SkM_RecordCreatureKill_Xp(sFoe); |
||
2376 | return; |
||
2377 | end |
||
2378 | end |
||
2379 | |||
2380 | end |
||
2381 | |||
2382 | |||
2383 | -- -------------------------------------------------------------------------------------- |
||
2384 | -- SkM_ParseCombatChat_SelfCombatHit |
||
2385 | -- -------------------------------------------------------------------------------------- |
||
2386 | -- Handle "Player hits something" chat event. |
||
2387 | -- Record damage done to this enemy. |
||
2388 | -- Note that this may be a player or a creature. We don't check it yet as enemy player |
||
2389 | -- may not be yet known, it's better to check on death event. |
||
2390 | -- -------------------------------------------------------------------------------------- |
||
2391 | function SkM_ParseCombatChat_SelfCombatHit(sMsg) |
||
2392 | local FName = "SkM_ParseCombatChat_SelfCombatHit"; |
||
2393 | |||
2394 | SkM_Trace(FName, 3, "You do physical damage to something"); |
||
2395 | |||
2396 | for sFoe, iDamage in string.gfind(sMsg, SKM_Context.Pattern.Player_HitDamage) do |
||
2397 | if (sFoe and iDamage) then |
||
2398 | SkM_Trace(FName, 3, "Player_HitDamage : Foe = "..sFoe..", Damage = "..iDamage); |
||
2399 | |||
2400 | SkM_LogDamage_OnPvpEnemy(iDamage, _PlayerName, sFoe); |
||
2401 | return; |
||
2402 | end |
||
2403 | end |
||
2404 | |||
2405 | for sFoe, iDamage in string.gfind(sMsg, SKM_Context.Pattern.Player_HitCritDamage) do |
||
2406 | if (sFoe and iDamage) then |
||
2407 | SkM_Trace(FName, 3, "Player_HitDamage : Foe = "..sFoe..", Damage = "..iDamage); |
||
2408 | |||
2409 | SkM_LogDamage_OnPvpEnemy(iDamage, _PlayerName, sFoe); |
||
2410 | return; |
||
2411 | end |
||
2412 | end |
||
2413 | |||
2414 | end |
||
2415 | |||
2416 | |||
2417 | -- -------------------------------------------------------------------------------------- |
||
2418 | -- SkM_ParseCombatChat_SelfCombatSpell |
||
2419 | -- -------------------------------------------------------------------------------------- |
||
2420 | -- Handle "Player does spell damage on something" chat event. |
||
2421 | -- Record damage done to this enemy. |
||
2422 | -- Note that this may be a player or a creature. We don't check it yet as enemy player |
||
2423 | -- may not be yet known, it's better to check on death event. |
||
2424 | -- -------------------------------------------------------------------------------------- |
||
2425 | function SkM_ParseCombatChat_SelfCombatSpell(sMsg) |
||
2426 | local FName = "SkM_ParseCombatChat_SelfCombatSpell"; |
||
2427 | |||
2428 | SkM_Trace(FName, 3, "You do spell damage to something"); |
||
2429 | |||
2430 | for sSpell, sFoe, iDamage in string.gfind(sMsg, SKM_Context.Pattern.Player_SpellDamage) do |
||
2431 | if (sSpell and sFoe and iDamage) then |
||
2432 | SkM_Trace(FName, 3, "Player_SpellDamage : Spell = "..sSpell..", Foe = "..sFoe..", Damage = "..iDamage); |
||
2433 | |||
2434 | SkM_LogDamage_OnPvpEnemy(iDamage, _PlayerName, sFoe); |
||
2435 | return; |
||
2436 | end |
||
2437 | end |
||
2438 | |||
2439 | for sSpell, sFoe, iDamage in string.gfind(sMsg, SKM_Context.Pattern.Player_SpellCritDamage) do |
||
2440 | if (sSpell and sFoe and iDamage) then |
||
2441 | SkM_Trace(FName, 3, "Player_SpellCritDamage : Spell = "..sSpell..", Foe = "..sFoe..", Damage = "..iDamage); |
||
2442 | |||
2443 | SkM_LogDamage_OnPvpEnemy(iDamage, _PlayerName, sFoe); |
||
2444 | return; |
||
2445 | end |
||
2446 | end |
||
2447 | |||
2448 | end |
||
2449 | |||
2450 | |||
2451 | -- -------------------------------------------------------------------------------------- |
||
2452 | -- SkM_ParseCombatChat_FriendCombatHit |
||
2453 | -- -------------------------------------------------------------------------------------- |
||
2454 | -- Handle "Friendly player hits something" chat event. |
||
2455 | -- Record damage done to this enemy. |
||
2456 | -- Note that this may be a player or a creature. We don't check it yet as enemy player |
||
2457 | -- may not be yet known, it's better to check on death event. |
||
2458 | -- -------------------------------------------------------------------------------------- |
||
2459 | function SkM_ParseCombatChat_FriendCombatHit(sMsg) |
||
2460 | local FName = "SkM_ParseCombatChat_FriendCombatHit"; |
||
2461 | |||
2462 | SkM_Trace(FName, 3, "A friend do physical damage to something"); |
||
2463 | |||
2464 | for sAttacker, sFoe, iDamage in string.gfind(sMsg, SKM_Context.Pattern.Other_HitDamage) do |
||
2465 | if (sAttacker and sFoe and iDamage) then |
||
2466 | SkM_Trace(FName, 3, "Other_HitDamage : Attacker = "..sAttacker..", Foe = "..sFoe..", Damage = "..iDamage); |
||
2467 | |||
2468 | SkM_LogDamage_OnPvpEnemy(iDamage, sAttacker, sFoe); |
||
2469 | return; |
||
2470 | end |
||
2471 | end |
||
2472 | |||
2473 | for sAttacker, sFoe, iDamage in string.gfind(sMsg, SKM_Context.Pattern.Other_HitCritDamage) do |
||
2474 | if (sAttacker and sFoe and iDamage) then |
||
2475 | SkM_Trace(FName, 3, "Other_HitCritDamage : Attacker = "..sAttacker..", Foe = "..sFoe..", Damage = "..iDamage); |
||
2476 | |||
2477 | |||
2478 | SkM_LogDamage_OnPvpEnemy(iDamage, sAttacker, sFoe); |
||
2479 | return; |
||
2480 | end |
||
2481 | end |
||
2482 | |||
2483 | end |
||
2484 | |||
2485 | |||
2486 | -- -------------------------------------------------------------------------------------- |
||
2487 | -- SkM_ParseCombatChat_FriendCombatSpell |
||
2488 | -- -------------------------------------------------------------------------------------- |
||
2489 | -- Handle "Friendly player does spell damage to something" chat event. |
||
2490 | -- Record damage done to this enemy. |
||
2491 | -- Note that this may be a player or a creature. We don't check it yet as enemy player |
||
2492 | -- may not be yet known, it's better to check on death event. |
||
2493 | -- -------------------------------------------------------------------------------------- |
||
2494 | function SkM_ParseCombatChat_FriendCombatSpell(sMsg) |
||
2495 | local FName = "SkM_ParseCombatChat_FriendCombatSpell"; |
||
2496 | |||
2497 | SkM_Trace(FName, 3, "A friend do spell damage to something"); |
||
2498 | |||
2499 | -- PIng: Patch for French version where attacker and spell are inversed |
||
2500 | |||
2501 | if ( GetLocale() == "frFR" ) then |
||
2502 | |||
2503 | for sSpell, sAttacker, sFoe, iDamage in string.gfind(sMsg, SKM_Context.Pattern.Other_SpellDamage) do |
||
2504 | if (sAttacker and sSpell and sFoe and iDamage) then |
||
2505 | SkM_Trace(FName, 3, "Other_SpellDamage : Attacker = "..sAttacker..", Spell = "..sSpell..", Foe = "..sFoe..", Damage = "..iDamage); |
||
2506 | |||
2507 | if (SkM_IsTotem(sAttacker)) then |
||
2508 | -- ignore totem damage |
||
2509 | return; |
||
2510 | end |
||
2511 | |||
2512 | SkM_LogDamage_OnPvpEnemy(iDamage, sAttacker, sFoe); |
||
2513 | return; |
||
2514 | end |
||
2515 | end |
||
2516 | else |
||
2517 | |||
2518 | for sAttacker, sSpell, sFoe, iDamage in string.gfind(sMsg, SKM_Context.Pattern.Other_SpellDamage) do |
||
2519 | if (sAttacker and sSpell and sFoe and iDamage) then |
||
2520 | SkM_Trace(FName, 3, "Other_SpellDamage : Attacker = "..sAttacker..", Spell = "..sSpell..", Foe = "..sFoe..", Damage = "..iDamage); |
||
2521 | |||
2522 | if (SkM_IsTotem(sAttacker)) then |
||
2523 | -- ignore totem damage |
||
2524 | return; |
||
2525 | end |
||
2526 | |||
2527 | SkM_LogDamage_OnPvpEnemy(iDamage, sAttacker, sFoe); |
||
2528 | return; |
||
2529 | end |
||
2530 | end |
||
2531 | end |
||
2532 | |||
2533 | for sAttacker, sSpell, sFoe, iDamage in string.gfind(sMsg, SKM_Context.Pattern.Other_SpellCritDamage) do |
||
2534 | if (sAttacker and sSpell and sFoe and iDamage) then |
||
2535 | SkM_Trace(FName, 3, "Other_SpellCritDamage : Attacker = "..sAttacker..", Spell = "..sSpell..", Foe = "..sFoe..", Damage = "..iDamage); |
||
2536 | |||
2537 | SkM_LogDamage_OnPvpEnemy(iDamage, sAttacker, sFoe); |
||
2538 | return; |
||
2539 | end |
||
2540 | end |
||
2541 | |||
2542 | end |
||
2543 | |||
2544 | |||
2545 | -- -------------------------------------------------------------------------------------- |
||
2546 | -- SkM_ParseCombatChat_PetCombatHit |
||
2547 | -- -------------------------------------------------------------------------------------- |
||
2548 | -- Handle "Our pet hits something" chat event. |
||
2549 | -- Record damage (for pet owner !) done to this enemy. |
||
2550 | -- Note that this may be a player or a creature. We don't check it yet as enemy player |
||
2551 | -- may not be yet known, it's better to check on death event. |
||
2552 | -- -------------------------------------------------------------------------------------- |
||
2553 | function SkM_ParseCombatChat_PetCombatHit(sMsg) |
||
2554 | local FName = "SkM_ParseCombatChat_PetCombatHit"; |
||
2555 | |||
2556 | SkM_Trace(FName, 3, "Your pet does physical damage to something"); |
||
2557 | |||
2558 | for sAttacker, sFoe, iDamage in string.gfind(sMsg, SKM_Context.Pattern.Other_HitDamage) do |
||
2559 | if (sAttacker and sFoe and iDamage) then |
||
2560 | SkM_Trace(FName, 3, "Other_HitDamage : Attacker = "..sAttacker..", Foe = "..sFoe..", Damage = "..iDamage); |
||
2561 | |||
2562 | SkM_LogDamage_OnPvpEnemy(iDamage, _PlayerName, sFoe); |
||
2563 | return; |
||
2564 | end |
||
2565 | end |
||
2566 | |||
2567 | for sAttacker, sFoe, iDamage in string.gfind(sMsg, SKM_Context.Pattern.Other_HitCritDamage) do |
||
2568 | if (sAttacker and sFoe and iDamage) then |
||
2569 | SkM_Trace(FName, 3, "Other_HitCritDamage : Attacker = "..sAttacker..", Foe = "..sFoe..", Damage = "..iDamage); |
||
2570 | |||
2571 | SkM_LogDamage_OnPvpEnemy(iDamage, _PlayerName, sFoe); |
||
2572 | return; |
||
2573 | end |
||
2574 | end |
||
2575 | |||
2576 | end |
||
2577 | |||
2578 | |||
2579 | -- -------------------------------------------------------------------------------------- |
||
2580 | -- SkM_ParseCombatChat_PetCombatSpell |
||
2581 | -- -------------------------------------------------------------------------------------- |
||
2582 | -- Handle "Our pet does spell damage to something" chat event. |
||
2583 | -- Record damage (for pet owner !) done to this enemy. |
||
2584 | -- Note that this may be a player or a creature. We don't check it yet as enemy player |
||
2585 | -- may not be yet known, it's better to check on death event. |
||
2586 | -- -------------------------------------------------------------------------------------- |
||
2587 | function SkM_ParseCombatChat_PetCombatSpell(sMsg) |
||
2588 | local FName = "SkM_ParseCombatChat_PetCombatSpell"; |
||
2589 | |||
2590 | SkM_Trace(FName, 3, "Your pet does spell damage to something"); |
||
2591 | |||
2592 | -- Note : it may be your totem if you are a shaman |
||
2593 | -- in this case, we don't ignore it : we count it as player damage also. |
||
2594 | |||
2595 | |||
2596 | |||
2597 | for sAttacker, sSpell, sFoe, iDamage in string.gfind(sMsg, SKM_Context.Pattern.Other_SpellDamage) do |
||
2598 | if (sAttacker and sSpell and sFoe and iDamage) then |
||
2599 | SkM_Trace(FName, 3, "Other_SpellDamage : Attacker = "..sAttacker..", Spell = "..sSpell..", Foe = "..sFoe..", Damage = "..iDamage); |
||
2600 | |||
2601 | SkM_LogDamage_OnPvpEnemy(iDamage, _PlayerName, sFoe); |
||
2602 | return; |
||
2603 | end |
||
2604 | |||
2605 | end |
||
2606 | |||
2607 | for sAttacker, sSpell, sFoe, iDamage in string.gfind(sMsg, SKM_Context.Pattern.Other_SpellCritDamage) do |
||
2608 | if (sAttacker and sSpell and sFoe and iDamage) then |
||
2609 | SkM_Trace(FName, 3, "Other_SpellCritDamage : Attacker = "..sAttacker..", Spell = "..sSpell..", Foe = "..sFoe..", Damage = "..iDamage); |
||
2610 | |||
2611 | SkM_LogDamage_OnPvpEnemy(iDamage, _PlayerName, sFoe); |
||
2612 | return; |
||
2613 | end |
||
2614 | end |
||
2615 | |||
2616 | end |
||
2617 | |||
2618 | |||
2619 | -- -------------------------------------------------------------------------------------- |
||
2620 | -- SkM_ParseCombatChat_EnemyDot |
||
2621 | -- -------------------------------------------------------------------------------------- |
||
2622 | -- Handle "Enemy player suffers from DoT" chat event. |
||
2623 | -- Record damage done (by either self of another player) to this enemy. |
||
2624 | -- -------------------------------------------------------------------------------------- |
||
2625 | function SkM_ParseCombatChat_EnemyDot(sMsg) |
||
2626 | local FName = "SkM_ParseCombatChat_EnemyDot"; |
||
2627 | |||
2628 | SkM_Trace(FName, 3, "An enemy suffers from DoT damage"); |
||
2629 | |||
2630 | -- PIng: Patch for French version |
||
2631 | |||
2632 | if ( GetLocale() == "frFR" ) then |
||
2633 | for sSpell, iDamage, sDamageType, sFoe in string.gfind(sMsg, SKM_Context.Pattern.Player_DotDamage) do |
||
2634 | if (sFoe and iDamage and sDamageType and sSpell) then |
||
2635 | SkM_Trace(FName, 3, "Player_DotDamage : Foe = "..sFoe..", Damage = "..iDamage..", Damage type = "..sDamageType..", Spell = "..sSpell); |
||
2636 | |||
2637 | SkM_LogDamage_OnPvpEnemy(iDamage, _PlayerName, sFoe); |
||
2638 | return; |
||
2639 | end |
||
2640 | end |
||
2641 | for sSpell, sAttacker, sFoe, iDamage, sDamageType in string.gfind(sMsg, SKM_Context.Pattern.Other_DotDamage) do |
||
2642 | if (sFoe and iDamage and sDamageType and sAttacker and sSpell) then |
||
2643 | SkM_Trace(FName, 3, "Other_DotDamage : Attacker = "..sAttacker..", Foe = "..sFoe..", Damage = "..iDamage..", Damage type = "..sDamageType..", Spell = "..sSpell); |
||
2644 | |||
2645 | SkM_LogDamage_OnPvpEnemy(iDamage, sAttacker, sFoe); |
||
2646 | return; |
||
2647 | end |
||
2648 | end |
||
2649 | |||
2650 | else |
||
2651 | for sFoe, iDamage, sDamageType, sSpell in string.gfind(sMsg, SKM_Context.Pattern.Player_DotDamage) do |
||
2652 | if (sFoe and iDamage and sDamageType and sSpell) then |
||
2653 | SkM_Trace(FName, 3, "Player_DotDamage : Foe = "..sFoe..", Damage = "..iDamage..", Damage type = "..sDamageType..", Spell = "..sSpell); |
||
2654 | |||
2655 | SkM_LogDamage_OnPvpEnemy(iDamage, _PlayerName, sFoe); |
||
2656 | return; |
||
2657 | end |
||
2658 | end |
||
2659 | for sFoe, iDamage, sDamageType, sAttacker, sSpell in string.gfind(sMsg, SKM_Context.Pattern.Other_DotDamage) do |
||
2660 | if (sFoe and iDamage and sDamageType and sAttacker and sSpell) then |
||
2661 | SkM_Trace(FName, 3, "Other_DotDamage : Attacker = "..sAttacker..", Foe = "..sFoe..", Damage = "..iDamage..", Damage type = "..sDamageType..", Spell = "..sSpell); |
||
2662 | |||
2663 | SkM_LogDamage_OnPvpEnemy(iDamage, sAttacker, sFoe); |
||
2664 | return; |
||
2665 | end |
||
2666 | end |
||
2667 | end |
||
2668 | |||
2669 | end |
||
2670 | |||
2671 | |||
2672 | -- -------------------------------------------------------------------------------------- |
||
2673 | |||
2674 | -- SkM_ParseCombatChat_SelfDot |
||
2675 | -- -------------------------------------------------------------------------------------- |
||
2676 | -- Handle "Self suffers from DoT" chat event. |
||
2677 | -- Record damage done to self, without any "enemy type" as we don't know if the enemy |
||
2678 | |||
2679 | -- is a player or a creep. |
||
2680 | -- -------------------------------------------------------------------------------------- |
||
2681 | function SkM_ParseCombatChat_SelfDot(sMsg) |
||
2682 | local FName = "SkM_ParseCombatChat_SelfDot"; |
||
2683 | |||
2684 | SkM_Trace(FName, 3, "Self suffers from DoT damage"); |
||
2685 | |||
2686 | -- We suffered from a DoT : in this case, log damage without enemy type, because |
||
2687 | -- we do *not* know from the event if it's a player or a creature that cast the DoT ! |
||
2688 | |||
2689 | if ( GetLocale() == "frFR" ) then |
||
2690 | -- 0.09.1 Begin of modification Fix ? |
||
2691 | for sSpell, sAttacker, iDamage, sDamageType in string.gfind(sMsg, SKM_Context.Pattern.Self_DotDamage) do |
||
2692 | if (iDamage and sDamageType and sAttacker and sSpell) then |
||
2693 | SkM_Trace(FName, 3, "Self_DotDamage : Attacker = "..sAttacker..", Damage = "..iDamage..", Damage type = "..sDamageType..", Spell = "..sSpell); |
||
2694 | |||
2695 | SkM_LogDamage_OnSelf(iDamage, sAttacker, nil); |
||
2696 | return; |
||
2697 | end |
||
2698 | end |
||
2699 | -- 0.09.1 End of modification |
||
2700 | |||
2701 | else |
||
2702 | |||
2703 | for iDamage, sDamageType, sAttacker, sSpell in string.gfind(sMsg, SKM_Context.Pattern.Self_DotDamage) do |
||
2704 | if (iDamage and sDamageType and sAttacker and sSpell) then |
||
2705 | SkM_Trace(FName, 3, "Self_DotDamage : Attacker = "..sAttacker..", Damage = "..iDamage..", Damage type = "..sDamageType..", Spell = "..sSpell); |
||
2706 | |||
2707 | SkM_LogDamage_OnSelf(iDamage, sAttacker, nil); |
||
2708 | return; |
||
2709 | end |
||
2710 | end |
||
2711 | |||
2712 | end |
||
2713 | |||
2714 | end |
||
2715 | |||
2716 | |||
2717 | -- -------------------------------------------------------------------------------------- |
||
2718 | -- SkM_ParseCombatChat_EnemyCombatHit |
||
2719 | -- -------------------------------------------------------------------------------------- |
||
2720 | -- Handle "Enemy player hits something" chat event. |
||
2721 | -- If we are the victim, record damage done to self by that enemy. |
||
2722 | -- -------------------------------------------------------------------------------------- |
||
2723 | function SkM_ParseCombatChat_EnemyCombatHit(sMsg) |
||
2724 | local FName = "SkM_ParseCombatChat_EnemyCombatHit"; |
||
2725 | |||
2726 | SkM_Trace(FName, 3, "A player enemy does physical damage to something"); |
||
2727 | |||
2728 | -- that may be an enemy PET also ! so we need to check if we know this enemy |
||
2729 | -- if not, log it without "enemy type" filled... |
||
2730 | |||
2731 | for sAttacker, iDamage in string.gfind(sMsg, SKM_Context.Pattern.Self_HitDamage) do |
||
2732 | if (sAttacker and iDamage) then |
||
2733 | SkM_Trace(FName, 3, "Self_HitDamage : Attacker = "..sAttacker..", Damage = "..iDamage); |
||
2734 | |||
2735 | SkM_LogDamage_OnSelf(iDamage, sAttacker, SkM_GetKnownEnemyType(sAttacker)); |
||
2736 | return; |
||
2737 | end |
||
2738 | end |
||
2739 | |||
2740 | for sAttacker, iDamage in string.gfind(sMsg, SKM_Context.Pattern.Self_HitCritDamage) do |
||
2741 | if (sAttacker and iDamage) then |
||
2742 | SkM_Trace(FName, 3, "Self_CritHitDamage : Attacker = "..sAttacker..", Damage = "..iDamage); |
||
2743 | |||
2744 | SkM_LogDamage_OnSelf(iDamage, sAttacker, SkM_GetKnownEnemyType(sAttacker)); |
||
2745 | return; |
||
2746 | end |
||
2747 | end |
||
2748 | |||
2749 | -- Self is not the target |
||
2750 | -- we don't care who the hostile player hits and for which amount ! |
||
2751 | SkM_Trace(FName, 3, "Hostile picks on other player or mob : do nothing"); |
||
2752 | end |
||
2753 | |||
2754 | |||
2755 | -- -------------------------------------------------------------------------------------- |
||
2756 | -- SkM_ParseCombatChat_EnemyCombatSpell |
||
2757 | -- -------------------------------------------------------------------------------------- |
||
2758 | -- Handle "Enemy player does spell damage to something" chat event. |
||
2759 | -- If we are the victim, record damage done to self by that enemy. |
||
2760 | -- -------------------------------------------------------------------------------------- |
||
2761 | function SkM_ParseCombatChat_EnemyCombatSpell(sMsg) |
||
2762 | local FName = "SkM_ParseCombatChat_EnemyCombatSpell"; |
||
2763 | |||
2764 | SkM_Trace(FName, 3, "A player enemy does spell damage to something"); |
||
2765 | |||
2766 | -- that may be an enemy PET also ! so we need to check if we know this enemy |
||
2767 | -- if not, log it without "enemy type" filled... |
||
2768 | |||
2769 | -- Is Self the target ? |
||
2770 | |||
2771 | -- PIng: Patch for French version |
||
2772 | |||
2773 | if ( GetLocale() == "frFR" ) then |
||
2774 | |||
2775 | for sSpell, sAttacker, iDamage in string.gfind(sMsg, SKM_Context.Pattern.Self_SpellDamage) do |
||
2776 | if (sAttacker and sSpell and iDamage) then |
||
2777 | SkM_Trace(FName, 3, "Self_SpellDamage : Attacker = "..sAttacker..", Spell = "..sSpell..", Damage = "..iDamage); |
||
2778 | |||
2779 | if (SkM_IsTotem(sAttacker)) then |
||
2780 | |||
2781 | -- ignore totem damage |
||
2782 | return; |
||
2783 | end |
||
2784 | |||
2785 | SkM_LogDamage_OnSelf(iDamage, sAttacker, SkM_GetKnownEnemyType(sAttacker)); |
||
2786 | return; |
||
2787 | end |
||
2788 | end |
||
2789 | else |
||
2790 | |||
2791 | for sAttacker, sSpell, iDamage in string.gfind(sMsg, SKM_Context.Pattern.Self_SpellDamage) do |
||
2792 | if (sAttacker and sSpell and iDamage) then |
||
2793 | SkM_Trace(FName, 3, "Self_SpellDamage : Attacker = "..sAttacker..", Spell = "..sSpell..", Damage = "..iDamage); |
||
2794 | |||
2795 | if (SkM_IsTotem(sAttacker)) then |
||
2796 | -- ignore totem damage |
||
2797 | return; |
||
2798 | end |
||
2799 | |||
2800 | SkM_LogDamage_OnSelf(iDamage, sAttacker, SkM_GetKnownEnemyType(sAttacker)); |
||
2801 | return; |
||
2802 | end |
||
2803 | end |
||
2804 | end |
||
2805 | |||
2806 | for sAttacker, sSpell, iDamage in string.gfind(sMsg, SKM_Context.Pattern.Self_SpellCritDamage) do |
||
2807 | if (sAttacker and sSpell and iDamage) then |
||
2808 | SkM_Trace(FName, 3, "Self_SpellCritDamage : Attacker = "..sAttacker..", Spell = "..sSpell..", Damage = "..iDamage); |
||
2809 | |||
2810 | SkM_LogDamage_OnSelf(iDamage, sAttacker, SkM_GetKnownEnemyType(sAttacker)); |
||
2811 | return; |
||
2812 | end |
||
2813 | end |
||
2814 | |||
2815 | |||
2816 | |||
2817 | -- Self is not the target |
||
2818 | -- we don't care who the hostile player hits and for which amount ! |
||
2819 | SkM_Trace(FName, 3, "Hostile picks on other player or mob : do nothing"); |
||
2820 | end |
||
2821 | |||
2822 | |||
2823 | -- -------------------------------------------------------------------------------------- |
||
2824 | -- SkM_ParseCombatChat_CreatureCombatHit |
||
2825 | -- -------------------------------------------------------------------------------------- |
||
2826 | -- Handle "Creature hits something" chat event. |
||
2827 | -- If we are the victim, record damage done to self by that creature. |
||
2828 | -- -------------------------------------------------------------------------------------- |
||
2829 | function SkM_ParseCombatChat_CreatureCombatHit(sMsg) |
||
2830 | local FName = "SkM_ParseCombatChat_CreatureCombatHit"; |
||
2831 | |||
2832 | SkM_Trace(FName, 3, "A creature does physical damage to something"); |
||
2833 | |||
2834 | for sAttacker, iDamage in string.gfind(sMsg, SKM_Context.Pattern.Self_HitDamage) do |
||
2835 | if (sAttacker and iDamage) then |
||
2836 | SkM_Trace(FName, 3, "Self_HitDamage : Attacker = "..sAttacker..", Damage = "..iDamage); |
||
2837 | |||
2838 | SkM_LogDamage_OnSelf(iDamage, sAttacker, _SKM._enemyCreature); |
||
2839 | return; |
||
2840 | end |
||
2841 | end |
||
2842 | |||
2843 | for sAttacker, iDamage in string.gfind(sMsg, SKM_Context.Pattern.Self_HitCritDamage) do |
||
2844 | if (sAttacker and iDamage) then |
||
2845 | SkM_Trace(FName, 3, "Self_CritHitDamage : Attacker = "..sAttacker..", Damage = "..iDamage); |
||
2846 | |||
2847 | SkM_LogDamage_OnSelf(iDamage, sAttacker, _SKM._enemyCreature); |
||
2848 | return; |
||
2849 | end |
||
2850 | end |
||
2851 | |||
2852 | -- Self is not the target |
||
2853 | -- we don't care who the creature hits and for which amount ! |
||
2854 | SkM_Trace(FName, 3, "Creature picks on other player or mob : do nothing"); |
||
2855 | end |
||
2856 | |||
2857 | |||
2858 | -- -------------------------------------------------------------------------------------- |
||
2859 | -- SkM_ParseCombatChat_CreatureCombatSpell |
||
2860 | -- -------------------------------------------------------------------------------------- |
||
2861 | -- Handle "Creature does spell damage to something" chat event. |
||
2862 | -- If we are the victim, record damage done to self by that creature. |
||
2863 | -- -------------------------------------------------------------------------------------- |
||
2864 | function SkM_ParseCombatChat_CreatureCombatSpell(sMsg) |
||
2865 | local FName = "SkM_ParseCombatChat_CreatureCombatSpell"; |
||
2866 | |||
2867 | SkM_Trace(FName, 3, "A creature does spell damage to something"); |
||
2868 | |||
2869 | -- 0.08.1 Begin of modification: Patch for French version |
||
2870 | |||
2871 | if ( GetLocale() == "frFR" ) then |
||
2872 | |||
2873 | for sSpell, sAttacker, iDamage in string.gfind(sMsg, SKM_Context.Pattern.Self_SpellDamage) do |
||
2874 | if (sAttacker and sSpell and iDamage) then |
||
2875 | SkM_Trace(FName, 3, "Self_SpellDamage : Attacker = "..sAttacker..", Spell = "..sSpell..", Damage = "..iDamage); |
||
2876 | |||
2877 | if (SkM_IsTotem(sAttacker)) then |
||
2878 | -- ignore totem damage |
||
2879 | |||
2880 | return; |
||
2881 | end |
||
2882 | |||
2883 | SkM_LogDamage_OnSelf(iDamage, sAttacker, _SKM._enemyCreature); |
||
2884 | return; |
||
2885 | end |
||
2886 | end |
||
2887 | else |
||
2888 | |||
2889 | for sAttacker, sSpell, iDamage in string.gfind(sMsg, SKM_Context.Pattern.Self_SpellDamage) do |
||
2890 | if (sAttacker and sSpell and iDamage) then |
||
2891 | SkM_Trace(FName, 3, "Self_SpellDamage : Attacker = "..sAttacker..", Spell = "..sSpell..", Damage = "..iDamage); |
||
2892 | |||
2893 | if (SkM_IsTotem(sAttacker)) then |
||
2894 | -- ignore totem damage |
||
2895 | return; |
||
2896 | end |
||
2897 | |||
2898 | SkM_LogDamage_OnSelf(iDamage, sAttacker, _SKM._enemyCreature); |
||
2899 | return; |
||
2900 | end |
||
2901 | end |
||
2902 | end |
||
2903 | -- 0.08.1 End of modification |
||
2904 | |||
2905 | for sAttacker, sSpell, iDamage in string.gfind(sMsg, SKM_Context.Pattern.Self_SpellCritDamage) do |
||
2906 | if (sAttacker and sSpell and iDamage) then |
||
2907 | SkM_Trace(FName, 3, "Self_SpellCritDamage : Attacker = "..sAttacker..", Spell = "..sSpell..", Damage = "..iDamage); |
||
2908 | |||
2909 | SkM_LogDamage_OnSelf(iDamage, sAttacker, _SKM._enemyCreature); |
||
2910 | return; |
||
2911 | end |
||
2912 | end |
||
2913 | |||
2914 | -- Self is not the target |
||
2915 | -- we don't care who the creature hits and for which amount ! |
||
2916 | SkM_Trace(FName, 3, "Creature picks on other player or mob : do nothing"); |
||
2917 | end |
||
2918 | |||
2919 | |||
2920 | -- -------------------------------------------------------------------------------------- |
||
2921 | -- SkM_ParseCombatChat_HostileDeath |
||
2922 | -- -------------------------------------------------------------------------------------- |
||
2923 | -- Handle "Enemy player dies" chat event. |
||
2924 | -- Find out from information previously gathered if we can be awarded this kill, |
||
2925 | -- and if so record it. |
||
2926 | -- -------------------------------------------------------------------------------------- |
||
2927 | function SkM_ParseCombatChat_HostileDeath(sMsg) |
||
2928 | local FName = "SkM_ParseCombatChat_HostileDeath"; |
||
2929 | |||
2930 | for sFoe in string.gfind(sMsg, SKM_Context.Pattern.Other_Death) do |
||
2931 | if (sFoe) then |
||
2932 | SkM_Trace(FName, 3, "Other_Death : Foe = "..sFoe); |
||
2933 | |||
2934 | |||
2935 | SkM_Trace(FName, 2, "Enemy player death detected (from chat msg) : "..snil(sFoe)); |
||
2936 | SkM_PvpEnemyDeath(sFoe); |
||
2937 | return; |
||
2938 | end |
||
2939 | end |
||
2940 | |||
2941 | end |
||
2942 | |||
2943 | |||
2944 | -- -------------------------------------------------------------------------------------- |
||
2945 | -- SkM_ParseCombatChat_HonorKill |
||
2946 | -- -------------------------------------------------------------------------------------- |
||
2947 | -- Handle "Enemy player dies and is worth honor" chat event. |
||
2948 | -- Find out from information previously gathered if we can be awarded this kill, |
||
2949 | -- and if so record it. |
||
2950 | |||
2951 | -- -------------------------------------------------------------------------------------- |
||
2952 | function SkM_ParseCombatChat_HonorKill(sMsg) |
||
2953 | local FName = "SkM_ParseCombatChat_HonorKill"; |
||
2954 | |||
2955 | for sFoe, sRank in string.gfind(sMsg, SKM_Context.Pattern.Honor_Kill) do |
||
2956 | if (sFoe and sRank) then |
||
2957 | SkM_Trace(FName, 3, "Honor_Kill : Foe = "..sFoe..", Rank = "..sRank); |
||
2958 | |||
2959 | SkM_Trace(FName, 2, "Enemy player death detected (from chat, honor) : "..snil(sFoe)); |
||
2960 | SkM_PvpEnemyDeath(sFoe, true, sRank); |
||
2961 | end |
||
2962 | end |
||
2963 | |||
2964 | end |
||
2965 | |||
2966 | |||
2967 | -- -------------------------------------------------------------------------------------- |
||
2968 | -- SkM_RecordCreatureKill_Xp |
||
2969 | -- -------------------------------------------------------------------------------------- |
||
2970 | -- Record a creature kill by "combat xp message". |
||
2971 | -- -------------------------------------------------------------------------------------- |
||
2972 | function SkM_RecordCreatureKill_Xp(sName) |
||
2973 | local FName = "SkM_RecordCreatureKill_Xp"; |
||
2974 | |||
2975 | if (not SkM_GetOption("RecordCreatureKill")) then |
||
2976 | return; |
||
2977 | end |
||
2978 | |||
2979 | |||
2980 | local curTime = GetTime(); |
||
2981 | |||
2982 | SkM_Trace(FName, 3, "Creature by xp kill : "..sName.." (time = "..curTime..")"); |
||
2983 | |||
2984 | -- check if we're already processed this kill on health change |
||
2985 | if (SKM_Context.LastCreatureKill) then |
||
2986 | |||
2987 | SkM_Trace(FName, 3, "Recent creature kill : "..snil(SKM_Context.LastCreatureKill[_SKM._name]).." (time = "..snil(SKM_Context.LastCreatureKill[_SKM._time])..")"); |
||
2988 | |||
2989 | if (SKM_Context.LastCreatureKill[_SKM._name] == sName) and (curTime < SKM_Context.LastCreatureKill[_SKM._time] + 1) then |
||
2990 | SkM_Trace(FName, 2, "Already processed kill : "..sName); |
||
2991 | |||
2992 | -- clear last creature kill and return |
||
2993 | SKM_Context.LastCreatureKill = nil; |
||
2994 | return; |
||
2995 | end |
||
2996 | end |
||
2997 | |||
2998 | -- kill not recorded by target kill, process it |
||
2999 | local StoreInfo = { }; |
||
3000 | |||
3001 | StoreInfo[_SKM._type] = _SKM._creatureKill_Xp; |
||
3002 | |||
3003 | local sDate1, sDate2 = SkM_GetDate(); |
||
3004 | StoreInfo[_SKM._date] = sDate1; |
||
3005 | --StoreInfo[_sortdate] = sDate2; |
||
3006 | |||
3007 | StoreInfo[_SKM._name] = sName; |
||
3008 | |||
3009 | if (not SkM_AddMapData(StoreInfo)) then |
||
3010 | return; |
||
3011 | end |
||
3012 | |||
3013 | |||
3014 | if (SkM_GetOption("DisplayCreatureKillRecord")) then |
||
3015 | SkM_ChatMessageColP(string.format(SKM_UI_STRINGS.RecordMessage_CreatureKill, sName), SKM_Config.RGB_CreatureKill); |
||
3016 | end |
||
3017 | |||
3018 | -- memorize killed mob to that we don't count it again when receiving xp message |
||
3019 | SKM_Context.LastCreatureKill = { }; |
||
3020 | SKM_Context.LastCreatureKill[_SKM._name] = sName; |
||
3021 | SKM_Context.LastCreatureKill[_SKM._time] = GetTime(); |
||
3022 | |||
3023 | --local idx_c, idx_z = SkM_GetZone(); |
||
3024 | local idx_c, idx_z = SkM_GetZone_Shift(); |
||
3025 | if (idx_z) then |
||
3026 | SkM_CleanZoneCreatureKill(idx_c, idx_z); |
||
3027 | end |
||
3028 | |||
3029 | end |
||
3030 | |||
3031 | |||
3032 | -- -------------------------------------------------------------------------------------- |
||
3033 | -- SkM_RecordCreatureKill_Target |
||
3034 | -- -------------------------------------------------------------------------------------- |
||
3035 | -- Record a creature kill by target (the creature we are currently targetting dies, |
||
3036 | -- and it was tapped by us). |
||
3037 | -- -------------------------------------------------------------------------------------- |
||
3038 | function SkM_RecordCreatureKill_Target(sName, iLevel, sCreatureClass) |
||
3039 | local FName = "SkM_RecordCreatureKill_Target"; |
||
3040 | |||
3041 | if (not SkM_GetOption("RecordCreatureKill")) then |
||
3042 | return; |
||
3043 | end |
||
3044 | |||
3045 | |||
3046 | local curTime = GetTime(); |
||
3047 | |||
3048 | SkM_Trace(FName, 3, "Creature by target kill : "..sName.." (time = "..curTime..")"); |
||
3049 | |||
3050 | -- check if we're already processed this kill on combat xp message |
||
3051 | if (SKM_Context.LastCreatureKill) then |
||
3052 | |||
3053 | SkM_Trace(FName, 3, "Recent creature kill : "..snil(SKM_Context.LastCreatureKill[_SKM._name]).." (time = "..snil(SKM_Context.LastCreatureKill[_SKM._time])..")"); |
||
3054 | |||
3055 | if (SKM_Context.LastCreatureKill[_SKM._name] == sName) and (curTime < SKM_Context.LastCreatureKill[_SKM._time] + 1) then |
||
3056 | SkM_Trace(FName, 2, "Already processed kill : "..sName); |
||
3057 | |||
3058 | -- clear last creature kill and return |
||
3059 | SKM_Context.LastCreatureKill = nil; |
||
3060 | return; |
||
3061 | end |
||
3062 | end |
||
3063 | |||
3064 | local StoreInfo = { }; |
||
3065 | |||
3066 | StoreInfo[_SKM._type] = _SKM._creatureKill_Target; |
||
3067 | |||
3068 | local sDate1, sDate2 = SkM_GetDate(); |
||
3069 | StoreInfo[_SKM._date] = sDate1; |
||
3070 | --StoreInfo[_sortdate] = sDate2; |
||
3071 | |||
3072 | StoreInfo[_SKM._name] = sName; |
||
3073 | StoreInfo[_SKM._level] = iLevel; |
||
3074 | StoreInfo[_SKM._class] = SKM_Config.CreatureClassLabel[sCreatureClass]; |
||
3075 | |||
3076 | if (not SkM_AddMapData(StoreInfo)) then |
||
3077 | return; |
||
3078 | end |
||
3079 | |||
3080 | if (SkM_GetOption("DisplayCreatureKillRecord")) then |
||
3081 | SkM_ChatMessageColP(string.format(SKM_UI_STRINGS.RecordMessage_CreatureKill, sName), SKM_Config.RGB_CreatureKill); |
||
3082 | end |
||
3083 | |||
3084 | |||
3085 | -- memorize killed mob to that we don't count it again when receiving xp message |
||
3086 | SKM_Context.LastCreatureKill = { }; |
||
3087 | SKM_Context.LastCreatureKill[_SKM._name] = sName; |
||
3088 | SKM_Context.LastCreatureKill[_SKM._time] = GetTime(); |
||
3089 | |||
3090 | --local idx_c, idx_z = SkM_GetZone(); |
||
3091 | local idx_c, idx_z = SkM_GetZone_Shift(); |
||
3092 | if (idx_z) then |
||
3093 | SkM_CleanZoneCreatureKill(idx_c, idx_z); |
||
3094 | end |
||
3095 | |||
3096 | end |
||
3097 | |||
3098 | |||
3099 | -- -------------------------------------------------------------------------------------- |
||
3100 | -- SkM_DeleteNote |
||
3101 | -- -------------------------------------------------------------------------------------- |
||
3102 | -- Delete a global note. Remove this note from global and zone map data, and recompute |
||
3103 | -- indexes of more recent notes. |
||
3104 | -- -------------------------------------------------------------------------------------- |
||
3105 | function SkM_DeleteNote(RealmName, PlayerName, idx_gn) |
||
3106 | local FName = "SkM_DeleteNote"; |
||
3107 | |||
3108 | SkM_Trace(FName, 3, "Removing note ("..RealmName.." / "..PlayerName..") : global index = "..idx_gn); |
||
3109 | |||
3110 | local idx_c, idx_z, idx_n; |
||
3111 | local val_c, val_z, val_n; |
||
3112 | |||
3113 | local cont_rem, zone_rem, note_rem; |
||
3114 | |||
3115 | for idx_c = 1,getn(SKM_Data[RealmName][PlayerName].MapData),1 do |
||
3116 | for idx_z = 1,getn(SKM_Data[RealmName][PlayerName].MapData[idx_c]) do |
||
3117 | for idx_n = 1,getn(SKM_Data[RealmName][PlayerName].MapData[idx_c][idx_z]) do |
||
3118 | local val_n = SKM_Data[RealmName][PlayerName].MapData[idx_c][idx_z][idx_n]; |
||
3119 | if (val_n == idx_gn) then |
||
3120 | cont_rem = idx_c; |
||
3121 | zone_rem = idx_z; |
||
3122 | note_rem = idx_n; |
||
3123 | elseif (val_n > idx_gn) then |
||
3124 | SKM_Data[RealmName][PlayerName].MapData[idx_c][idx_z][idx_n] = val_n - 1; |
||
3125 | end |
||
3126 | end |
||
3127 | end |
||
3128 | end |
||
3129 | |||
3130 | |||
3131 | SkM_Trace(FName, 3, "Removing note : continent = "..snil(cont_rem)..", zone = "..snil(zone_rem)..", note = "..snil(note_rem)); |
||
3132 | |||
3133 | table.remove(SKM_Data[RealmName][PlayerName].MapData[cont_rem][zone_rem], note_rem); |
||
3134 | table.remove(SKM_Data[RealmName][PlayerName].GlobalMapData, idx_gn); |
||
3135 | end |
||
3136 | |||
3137 | |||
3138 | -- -------------------------------------------------------------------------------------- |
||
3139 | -- SkM_CleanZoneCreatureKill |
||
3140 | -- -------------------------------------------------------------------------------------- |
||
3141 | -- A creature kill has been recorded, clean older creature kill records if necessary |
||
3142 | -- (from configurable maximum number of creature records by zone). |
||
3143 | -- -------------------------------------------------------------------------------------- |
||
3144 | function SkM_CleanZoneCreatureKill(idx_c, idx_z) |
||
3145 | local FName = "SkM_CleanZoneCreatureKill"; |
||
3146 | |||
3147 | |||
3148 | SkM_Trace(FName, 3, "Continent = "..idx_c..", Zone = "..idx_z); |
||
3149 | |||
3150 | local iZoneNoteCount = getn(SKM_Data[_RealmName][_PlayerName].MapData[idx_c][idx_z]); |
||
3151 | --iZoneNoteCount = tablesize(SKM_Data[_RealmName][_PlayerName].MapData[idx_c][idx_z]); |
||
3152 | |||
3153 | SkM_Trace(FName, 3, "Notes in zone = "..iZoneNoteCount); |
||
3154 | |||
3155 | local iCreatureKill = 0; |
||
3156 | local i; |
||
3157 | |||
3158 | for i=iZoneNoteCount, 1, -1 do |
||
3159 | local idx_gn = SKM_Data[_RealmName][_PlayerName].MapData[idx_c][idx_z][i]; |
||
3160 | local Note = SKM_Data[_RealmName][_PlayerName].GlobalMapData[idx_gn]; |
||
3161 | |||
3162 | if ((Note) and (Note[_SKM._storedInfo])) |
||
3163 | and ((Note[_SKM._storedInfo][_SKM._type] == _SKM._creatureKill_Target) or (Note[_SKM._storedInfo][_SKM._type] == _SKM._creatureKill_Xp)) then |
||
3164 | if (iCreatureKill >= SkM_GetOption("CreatureKillRecordsByZone")) then |
||
3165 | |||
3166 | -- already reached the max count of creature kill notes by zone |
||
3167 | -- have to delete this one. |
||
3168 | |||
3169 | -- remove from GlobalMapData and from MapData |
||
3170 | SkM_Trace(FName, 3, "Removing note : global index = "..idx_gn..", map index = "..i); |
||
3171 | |||
3172 | SkM_DeleteNote(_RealmName, _PlayerName, idx_gn); |
||
3173 | |||
3174 | else |
||
3175 | iCreatureKill = iCreatureKill + 1; |
||
3176 | end |
||
3177 | end |
||
3178 | end |
||
3179 | |||
3180 | end |
||
3181 | |||
3182 | |||
3183 | -- -------------------------------------------------------------------------------------- |
||
3184 | -- SkM_CheckForgetEnemy |
||
3185 | -- -------------------------------------------------------------------------------------- |
||
3186 | -- Check if we can forget an enemy that has engaged in combat against us. |
||
3187 | -- If no update has been received in a given time frame, then forget him. |
||
3188 | -- -------------------------------------------------------------------------------------- |
||
3189 | function SkM_CheckForgetEnemy(sName) |
||
3190 | local Name = "SkM_CheckForgetEnemy"; |
||
3191 | |||
3192 | local curTime = GetTime(); |
||
3193 | |||
3194 | if (SKM_Context.EnemyCombat[sName]) then |
||
3195 | -- there exists information about that enemy. |
||
3196 | -- check when last updated |
||
3197 | if (curTime - SKM_Context.EnemyCombat[sName][_SKM._lastUpdate] > SKM_Config.ForgetEnemyTimer) then |
||
3198 | SKM_Context.EnemyCombat[sName] = nil; |
||
3199 | end |
||
3200 | end |
||
3201 | |||
3202 | end |
||
3203 | |||
3204 | |||
3205 | -- -------------------------------------------------------------------------------------- |
||
3206 | -- SkM_BuildGroupList |
||
3207 | -- -------------------------------------------------------------------------------------- |
||
3208 | -- Build a list of players currently in the group. Called each time the group members |
||
3209 | -- change. |
||
3210 | -- -------------------------------------------------------------------------------------- |
||
3211 | function SkM_BuildGroupList() |
||
3212 | local FName = "SkM_BuildGroupList"; |
||
3213 | |||
3214 | SkM_Trace(FName, 2, "Party changed, rebuild group list"); |
||
3215 | |||
3216 | |||
3217 | SKM_Context.GroupList = { }; |
||
3218 | |||
3219 | local i; |
||
3220 | for i=1,GetNumPartyMembers() do |
||
3221 | local sUnit = SKM_UNIT_PARTY .. i; |
||
3222 | local sName = SkM_UnitName(sUnit); |
||
3223 | |||
3224 | if (sName) then |
||
3225 | table.insert(SKM_Context.GroupList, sName); |
||
3226 | end |
||
3227 | end |
||
3228 | |||
3229 | end |
||
3230 | |||
3231 | |||
3232 | -- -------------------------------------------------------------------------------------- |
||
3233 | -- SkM_IsNameInGroup |
||
3234 | -- -------------------------------------------------------------------------------------- |
||
3235 | -- Check if given player name is in party. |
||
3236 | -- -------------------------------------------------------------------------------------- |
||
3237 | function SkM_IsNameInGroup(sName) |
||
3238 | return ( (sName == _PlayerName) |
||
3239 | or (intable(sName, SKM_Context.GroupList)) |
||
3240 | ); |
||
3241 | end |
||
3242 | |||
3243 | |||
3244 | -- -------------------------------------------------------------------------------------- |
||
3245 | -- SkM_LogDamage_OnPvpEnemy |
||
3246 | -- -------------------------------------------------------------------------------------- |
||
3247 | -- Keep track of damage done on an enemy, and who did this damage (self or our group, |
||
3248 | -- or someone else). |
||
3249 | -- -------------------------------------------------------------------------------------- |
||
3250 | function SkM_LogDamage_OnPvpEnemy(iDamage, sFriendName, sName) |
||
3251 | local FName = "SkM_LogDamage_OnPvpEnemy"; |
||
3252 | |||
3253 | local curTime = GetTime(); |
||
3254 | |||
3255 | -- first check if we remember this enemy and if no update was received for a long time, |
||
3256 | -- then forget him and start anew. |
||
3257 | SkM_CheckForgetEnemy(sName); |
||
3258 | |||
3259 | if (not SKM_Context.EnemyCombat[sName]) then |
||
3260 | SKM_Context.EnemyCombat[sName] = { }; |
||
3261 | SKM_Context.EnemyCombat[sName][_SKM._name] = sName; |
||
3262 | SKM_Context.EnemyCombat[sName][_SKM._totalDamage] = 0; |
||
3263 | SKM_Context.EnemyCombat[sName][_SKM._groupDamage] = 0; |
||
3264 | end |
||
3265 | |||
3266 | SKM_Context.EnemyCombat[sName][_SKM._lastUpdate] = curTime; |
||
3267 | |||
3268 | SKM_Context.EnemyCombat[sName][_SKM._totalDamage] = SKM_Context.EnemyCombat[sName][_SKM._totalDamage] + iDamage; |
||
3269 | |||
3270 | if (SkM_IsNameInGroup(sFriendName)) then |
||
3271 | SKM_Context.EnemyCombat[sName][_SKM._groupDamage] = SKM_Context.EnemyCombat[sName][_SKM._groupDamage] + iDamage; |
||
3272 | end |
||
3273 | |||
3274 | SkM_Trace(FName, 3, "EnemyCombat updated for "..sName.." : Total damage = ".. SKM_Context.EnemyCombat[sName][_SKM._totalDamage] ..", Group damage = ".. SKM_Context.EnemyCombat[sName][_SKM._groupDamage]); |
||
3275 | end |
||
3276 | |||
3277 | |||
3278 | function SkM_UpdateEnemyHistory() |
||
3279 | SKM_Context.PlayerDataChanged = true; |
||
3280 | end |
||
3281 | |||
3282 | |||
3283 | -- -------------------------------------------------------------------------------------- |
||
3284 | -- SkM_UpdateEnemy_IncrCounter |
||
3285 | -- -------------------------------------------------------------------------------------- |
||
3286 | -- Increment enemy counter for a given type, and enemy guild counter if applicable |
||
3287 | -- -------------------------------------------------------------------------------------- |
||
3288 | function SkM_UpdateEnemy_IncrCounter(sName, sType, iValue, bPropagateToGuild) |
||
3289 | SkM_UpdateEnemyHistory(); |
||
3290 | |||
3291 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][sType] = ifnil(SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][sType], 0) + iValue; |
||
3292 | |||
3293 | if (bPropagateToGuild) then |
||
3294 | local sGuildName = SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._guild]; |
||
3295 | if ((sGuildName ~= nil) and (sGuildName ~= "")) then |
||
3296 | SkM_UpdateGuild_IncrCounter(sGuildName, sType, iValue); |
||
3297 | end |
||
3298 | end |
||
3299 | end |
||
3300 | |||
3301 | |||
3302 | -- -------------------------------------------------------------------------------------- |
||
3303 | -- SkM_UpdateEnemy_IncrPlayerKill |
||
3304 | -- -------------------------------------------------------------------------------------- |
||
3305 | -- Increment enemy kill count, and enemy guild kill count if applicable |
||
3306 | -- -------------------------------------------------------------------------------------- |
||
3307 | function SkM_UpdateEnemy_IncrPlayerKill(sName, iValue) |
||
3308 | SkM_UpdateEnemy_IncrCounter(sName, _SKM._playerKill, iValue, true); |
||
3309 | end |
||
3310 | |||
3311 | |||
3312 | -- -------------------------------------------------------------------------------------- |
||
3313 | -- SkM_UpdateEnemy_IncrPlayerFullKill |
||
3314 | -- -------------------------------------------------------------------------------------- |
||
3315 | -- Increment enemy full kill count, and enemy guild full kill count if applicable |
||
3316 | -- -------------------------------------------------------------------------------------- |
||
3317 | function SkM_UpdateEnemy_IncrPlayerFullKill(sName, iValue) |
||
3318 | SkM_UpdateEnemy_IncrCounter(sName, _SKM._playerFullKill, iValue, true); |
||
3319 | end |
||
3320 | |||
3321 | |||
3322 | -- -------------------------------------------------------------------------------------- |
||
3323 | -- SkM_UpdateEnemy_IncrPlayerAssistKill |
||
3324 | -- -------------------------------------------------------------------------------------- |
||
3325 | -- Increment enemy assist kill count, and enemy guild assist kill count if applicable |
||
3326 | -- -------------------------------------------------------------------------------------- |
||
3327 | function SkM_UpdateEnemy_IncrPlayerAssistKill(sName, iValue) |
||
3328 | SkM_UpdateEnemy_IncrCounter(sName, _SKM._playerAssistKill, iValue, true); |
||
3329 | end |
||
3330 | |||
3331 | |||
3332 | -- -------------------------------------------------------------------------------------- |
||
3333 | -- SkM_UpdateEnemy_IncrKillPlayer |
||
3334 | -- -------------------------------------------------------------------------------------- |
||
3335 | -- Increment enemy kill player count, and enemy guild kill player count if applicable |
||
3336 | -- -------------------------------------------------------------------------------------- |
||
3337 | function SkM_UpdateEnemy_IncrKillPlayer(sName, iValue, bBattleground) |
||
3338 | local sType; |
||
3339 | if (bBattleground) then |
||
3340 | sType = _SKM._enemyKillBG; |
||
3341 | else |
||
3342 | sType = _SKM._enemyKillPlayer; |
||
3343 | end |
||
3344 | SkM_UpdateEnemy_IncrCounter(sName, sType, iValue, true); |
||
3345 | end |
||
3346 | |||
3347 | -- -------------------------------------------------------------------------------------- |
||
3348 | -- SkM_UpdateEnemy_IncrHonorKill |
||
3349 | -- -------------------------------------------------------------------------------------- |
||
3350 | -- Increment enemy honor kill count, and enemy guild kill count if applicable |
||
3351 | -- -------------------------------------------------------------------------------------- |
||
3352 | function SkM_UpdateEnemy_IncrHonorKill(sName, iValue) |
||
3353 | SkM_UpdateEnemy_IncrCounter(sName, _SKM._honorKill, iValue, true); |
||
3354 | end |
||
3355 | |||
3356 | function SkM_UpdateEnemy_IncrLoneWolfKill(sName, iValue) |
||
3357 | SkM_UpdateEnemy_IncrCounter(sName, _SKM._loneWolfKill, iValue, true); |
||
3358 | end |
||
3359 | |||
3360 | |||
3361 | |||
3362 | -- -------------------------------------------------------------------------------------- |
||
3363 | -- SkM_UpdateEnemy_IncrMeet |
||
3364 | -- -------------------------------------------------------------------------------------- |
||
3365 | -- Increment enemy meet count |
||
3366 | -- -------------------------------------------------------------------------------------- |
||
3367 | function SkM_UpdateEnemy_IncrMeet(sName, iValue) |
||
3368 | SkM_UpdateEnemy_IncrCounter(sName, _SKM._meetCount, iValue, false); |
||
3369 | end |
||
3370 | |||
3371 | |||
3372 | -- -------------------------------------------------------------------------------------- |
||
3373 | -- SkM_UpdateEnemy_SetLastView |
||
3374 | -- -------------------------------------------------------------------------------------- |
||
3375 | -- Update enemy last view date/time |
||
3376 | -- -------------------------------------------------------------------------------------- |
||
3377 | function SkM_UpdateEnemy_SetLastView(sName, sDate) |
||
3378 | SkM_UpdateEnemyHistory(); |
||
3379 | |||
3380 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._lastView] = sDate; |
||
3381 | end |
||
3382 | |||
3383 | |||
3384 | -- -------------------------------------------------------------------------------------- |
||
3385 | -- SkM_UpdateEnemy_SetLastUpdate |
||
3386 | |||
3387 | -- -------------------------------------------------------------------------------------- |
||
3388 | -- Update enemy last update date/time |
||
3389 | -- -------------------------------------------------------------------------------------- |
||
3390 | function SkM_UpdateEnemy_SetLastUpdate(sName, sDate) |
||
3391 | SkM_UpdateEnemyHistory(); |
||
3392 | |||
3393 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._lastUpdate] = sDate; |
||
3394 | end |
||
3395 | |||
3396 | |||
3397 | -- -------------------------------------------------------------------------------------- |
||
3398 | -- SkM_UpdateEnemy_SetLevel |
||
3399 | -- -------------------------------------------------------------------------------------- |
||
3400 | -- Update enemy level |
||
3401 | -- -------------------------------------------------------------------------------------- |
||
3402 | function SkM_UpdateEnemy_SetLevel(sName, iLevel) |
||
3403 | SkM_UpdateEnemyHistory(); |
||
3404 | |||
3405 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._level] = iLevel; |
||
3406 | end |
||
3407 | |||
3408 | |||
3409 | -- -------------------------------------------------------------------------------------- |
||
3410 | -- SkM_UpdateEnemy_SetClass |
||
3411 | -- -------------------------------------------------------------------------------------- |
||
3412 | -- Update enemy class |
||
3413 | -- -------------------------------------------------------------------------------------- |
||
3414 | function SkM_UpdateEnemy_SetClass(sName, sClass) |
||
3415 | SkM_UpdateEnemyHistory(); |
||
3416 | |||
3417 | if (not SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._class]) then |
||
3418 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._class] = sClass; |
||
3419 | end |
||
3420 | end |
||
3421 | |||
3422 | |||
3423 | -- -------------------------------------------------------------------------------------- |
||
3424 | -- SkM_UpdateEnemy_SetRace |
||
3425 | -- -------------------------------------------------------------------------------------- |
||
3426 | -- Update enemy race |
||
3427 | -- -------------------------------------------------------------------------------------- |
||
3428 | function SkM_UpdateEnemy_SetRace(sName, sRace) |
||
3429 | SkM_UpdateEnemyHistory(); |
||
3430 | |||
3431 | if (not SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._race]) then |
||
3432 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._race] = sRace; |
||
3433 | end |
||
3434 | end |
||
3435 | |||
3436 | |||
3437 | -- -------------------------------------------------------------------------------------- |
||
3438 | -- SkM_UpdateEnemy_SetLocation |
||
3439 | -- -------------------------------------------------------------------------------------- |
||
3440 | -- Update enemy last seen location |
||
3441 | -- -------------------------------------------------------------------------------------- |
||
3442 | function SkM_UpdateEnemy_SetLocation(sName, idx_c, idx_z, xPos, yPos) |
||
3443 | SkM_UpdateEnemyHistory(); |
||
3444 | |||
3445 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._zoneName] = nil; |
||
3446 | |||
3447 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._continent] = idx_c; |
||
3448 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._zone] = idx_z; |
||
3449 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._xPos] = xPos; |
||
3450 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._yPos] = yPos; |
||
3451 | end |
||
3452 | |||
3453 | function SkM_UpdateEnemy_SetLocationName(sName, sZoneName) |
||
3454 | SkM_UpdateEnemyHistory(); |
||
3455 | |||
3456 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._continent] = nil; |
||
3457 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._zone] = nil; |
||
3458 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._xPos] = nil; |
||
3459 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._yPos] = nil; |
||
3460 | |||
3461 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._zoneName] = sZoneName; |
||
3462 | end |
||
3463 | |||
3464 | |||
3465 | -- -------------------------------------------------------------------------------------- |
||
3466 | -- SkM_UpdateEnemy_SetWar |
||
3467 | -- -------------------------------------------------------------------------------------- |
||
3468 | -- Update enemy 'at war' status, and war date |
||
3469 | -- -------------------------------------------------------------------------------------- |
||
3470 | function SkM_UpdateEnemy_SetWar(sName, bWar, sDate) |
||
3471 | SkM_UpdateEnemyHistory(); |
||
3472 | |||
3473 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._atWar] = bWar; |
||
3474 | if (bWar) then |
||
3475 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._warDate] = sDate; |
||
3476 | else |
||
3477 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._warDate] = nil; |
||
3478 | end |
||
3479 | end |
||
3480 | |||
3481 | |||
3482 | -- -------------------------------------------------------------------------------------- |
||
3483 | -- SkM_UpdateEnemyLastView |
||
3484 | -- -------------------------------------------------------------------------------------- |
||
3485 | -- Received some information about an enemy : update this enemy information |
||
3486 | -- -------------------------------------------------------------------------------------- |
||
3487 | function SkM_UpdateEnemyLastView(sName, sDate, bTarget, sUnit) |
||
3488 | local FName = "SkM_UpdateEnemyLastView"; |
||
3489 | |||
3490 | SkM_UpdateEnemyHistory(); |
||
3491 | |||
3492 | local sTheUnit; |
||
3493 | if (sUnit) then |
||
3494 | sTheUnit = sUnit; |
||
3495 | else |
||
3496 | sTheUnit = SKM_UNIT_TARGET; |
||
3497 | end |
||
3498 | |||
3499 | -- if we have unit on target (or mouseover), check if we should ignore or not |
||
3500 | if (bTarget) then |
||
3501 | |||
3502 | -- if we already have recorded this player, we update his information anyway, |
||
3503 | -- even if he's low level, and even if he has no PvP flag |
||
3504 | |||
3505 | -- if we have added this enemy to the unknown enemy at war, then we record him anyway |
||
3506 | |||
3507 | if (not SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName]) |
||
3508 | and (not SKM_Data[_RealmName][_PlayerName].UnknownEnemy[sName]) |
||
3509 | then |
||
3510 | |||
3511 | if (not SkM_GetOption("StoreEnemyPlayers")) then |
||
3512 | SkM_Trace(FName, 2, "Storing disabled"); |
||
3513 | return; |
||
3514 | end |
||
3515 | |||
3516 | if (SkM_GetOption("IgnoreLowerEnemies")) then |
||
3517 | local iUnitLevel = UnitLevel(sTheUnit); |
||
3518 | if (iUnitLevel == -1) then |
||
3519 | iUnitLevel = 500; |
||
3520 | end |
||
3521 | local iMinLevel = math.floor( UnitLevel(SKM_UNIT_PLAYER) * SkM_GetOption("IgnoreLevelThreshold") / 100 ); |
||
3522 | if ( iUnitLevel < iMinLevel ) then |
||
3523 | SkM_Trace(FName, 1, "Not storing, too low level : "..iUnitLevel..", min. = "..iMinLevel); |
||
3524 | return; |
||
3525 | end |
||
3526 | end |
||
3527 | end |
||
3528 | |||
3529 | if (SkM_GetOption("IgnoreNoPvPFlag")) then |
||
3530 | if not (UnitIsPVP(sTheUnit) or UnitIsPVPFreeForAll(sTheUnit)) then |
||
3531 | SkM_Trace(FName, 1, "Not storing, Unit "..snil(sTheUnit).." is not PvP flagged"); |
||
3532 | return; |
||
3533 | end |
||
3534 | end |
||
3535 | |||
3536 | end |
||
3537 | |||
3538 | if (not SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName]) then |
||
3539 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName] = { }; |
||
3540 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._name] = sName; |
||
3541 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._playerAssistKill] = 0; |
||
3542 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._playerKill] = 0; |
||
3543 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._playerFullKill] = 0; |
||
3544 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._enemyKillPlayer] = 0; |
||
3545 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._enemyKillBG] = 0; |
||
3546 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._playerBGKill] = 0; |
||
3547 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._meetCount] = 1; |
||
3548 | |||
3549 | if (SKM_Data[_RealmName][_PlayerName].UnknownEnemy[sName]) then |
||
3550 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._meetCount] = 1; |
||
3551 | SKM_Data[_RealmName][_PlayerName].UnknownEnemy[sName] = nil; |
||
3552 | |||
3553 | SkM_Trace(FName, 2, snil(sName).."Added with 'at WAR' status"); |
||
3554 | end |
||
3555 | |||
3556 | SkM_Trace(FName, 1, "First encounter of enemy : "..snil(sName)); |
||
3557 | else |
||
3558 | |||
3559 | if ((not SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._meetCount] |
||
3560 | or (not SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._lastView]))) then |
||
3561 | |||
3562 | -- 09/04/2005 18:44:32 PIng Add a check since LastView is updated later now. |
||
3563 | SkM_UpdateEnemy_IncrMeet(sName, 1); |
||
3564 | else |
||
3565 | -- increase number of time player met this enemy if last viewed time is older than |
||
3566 | -- configurable value |
||
3567 | local iDiffTime = SkM_DiffDate(sDate, SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._lastView]); |
||
3568 | if (iDiffTime ~= nil) and (iDiffTime > SKM_Config.TimeRangeForNewMeeting) then |
||
3569 | SkM_UpdateEnemy_IncrMeet(sName, 1); |
||
3570 | end |
||
3571 | end |
||
3572 | |||
3573 | end |
||
3574 | |||
3575 | -- if we have unit on target (or mouseover), update information |
||
3576 | if (bTarget) then |
||
3577 | SkM_UpdateEnemy_SetLevel(sName, UnitLevel(sTheUnit)); |
||
3578 | SkM_UpdateEnemy_SetClass(sName, SkM_GetClassIndex(UnitClass(sTheUnit))); |
||
3579 | SkM_UpdateEnemy_SetRace(sName, SkM_GetRaceIndex(UnitRace(sTheUnit))); |
||
3580 | SkM_UpdateEnemy_SetGuild(sName, ifnil(GetGuildInfo(sTheUnit),"")); -- PIng Add guild support |
||
3581 | --SkM_UpdateEnemy_SetLastUpdate(sName, sDate); |
||
3582 | |||
3583 | -- get/update rank also |
||
3584 | local iRank = UnitPVPRank(sTheUnit); |
||
3585 | if (iRank >= 1) then |
||
3586 | local sRank = GetPVPRankInfo(iRank, sTheUnit); |
||
3587 | if (sRank) then |
||
3588 | SkM_UpdateEnemyRank(sName, sRank); |
||
3589 | end |
||
3590 | end |
||
3591 | |||
3592 | end |
||
3593 | |||
3594 | local idx_c, idx_z = SkM_GetZone(); |
||
3595 | if (idx_z) then |
||
3596 | SetMapZoom(idx_c, idx_z); |
||
3597 | local xPos, yPos = GetPlayerMapPosition(SKM_UNIT_PLAYER); |
||
3598 | |||
3599 | --SkM_UpdateEnemy_SetLocation(sName, idx_c, idx_z, xPos, yPos); |
||
3600 | |||
3601 | local cont_shift, zone_shift = SkM_GetZone_Shift(idx_c, idx_z); |
||
3602 | SkM_UpdateEnemy_SetLocation(sName, cont_shift, zone_shift, xPos, yPos); |
||
3603 | else |
||
3604 | local sZoneName = SkM_GetZoneText(); |
||
3605 | SkM_UpdateEnemy_SetLocationName(sName, sZoneName); |
||
3606 | end |
||
3607 | |||
3608 | -- 09/04/2005 16:46:34 PIng: Add guild support |
||
3609 | |||
3610 | -- Update guild if known |
||
3611 | local sGuildName = SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._guild]; |
||
3612 | -- if ((sGuildName ~= nil) and (sGuildName ~= "not in a guild")) then |
||
3613 | if ((sGuildName ~= nil) and (sGuildName ~= "")) then |
||
3614 | SkM_UpdateGuildHistory(sGuildName, sDate, sName); |
||
3615 | end |
||
3616 | |||
3617 | -- 09/04/2005 16:46:43 End of modification |
||
3618 | |||
3619 | SkM_UpdateEnemy_SetLastView(sName, sDate); -- 09/04/2005 18:30:05 PIng: Moved in order to have the information available for guild update |
||
3620 | |||
3621 | end |
||
3622 | |||
3623 | |||
3624 | function SkM_UpdateEnemyRank(sName, sRank) |
||
3625 | SkM_UpdateEnemyHistory(); |
||
3626 | |||
3627 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._rank] = sRank; |
||
3628 | end |
||
3629 | |||
3630 | |||
3631 | function SkM_UpdateEnemy_SetGuild(sName, sGuild) |
||
3632 | SkM_UpdateEnemyHistory(); |
||
3633 | |||
3634 | --if (not SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._guild]) then |
||
3635 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._guild] = sGuild; |
||
3636 | --end |
||
3637 | end |
||
3638 | |||
3639 | function SkM_UpdateGuild_SetLastView(sGuildName, sDate, sPlayerName) |
||
3640 | SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName][_SKM._lastView] = sDate; |
||
3641 | SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName][_SKM._lastPlayerViewed] = sPlayerName; |
||
3642 | end |
||
3643 | |||
3644 | function SkM_UpdateGuild_IncrCounter(sGuildName, sType, iValue) |
||
3645 | SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName][sType] = ifnil(SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName][sType], 0) + iValue; |
||
3646 | end |
||
3647 | |||
3648 | function SkM_UpdateGuild_IncrPlayerKill(sGuildName, iValue) |
||
3649 | SkM_UpdateGuild_IncrCounter(sGuildName, _SKM._playerKill, iValue); |
||
3650 | end |
||
3651 | |||
3652 | function SkM_UpdateGuild_IncrPlayerFullKill(sGuildName, iValue) |
||
3653 | SkM_UpdateGuild_IncrCounter(sGuildName, _SKM._playerFullKill, iValue); |
||
3654 | end |
||
3655 | |||
3656 | function SkM_UpdateGuild_IncrPlayerAssistKill(sGuildName, iValue) |
||
3657 | SkM_UpdateGuild_IncrCounter(sGuildName, _SKM._playerAssistKill, iValue); |
||
3658 | end |
||
3659 | |||
3660 | function SkM_UpdateGuild_IncrKillPlayer(sGuildName, iValue, bBattleground) |
||
3661 | local sType; |
||
3662 | if (bBattleground) then |
||
3663 | sType = _SKM._enemyKillBG; |
||
3664 | else |
||
3665 | sType = _SKM._enemyKillPlayer; |
||
3666 | end |
||
3667 | SkM_UpdateGuild_IncrCounter(sGuildName, sType, iValue); |
||
3668 | end |
||
3669 | |||
3670 | function SkM_UpdateGuild_IncrHonorKill(sGuildName, iValue) |
||
3671 | SkM_UpdateGuild_IncrCounter(sGuildName, _SKM._honorKill, iValue); |
||
3672 | end |
||
3673 | |||
3674 | function SkM_UpdateGuild_IncrMeet(sGuildName, iValue) |
||
3675 | SkM_UpdateGuild_IncrCounter(sGuildName, _SKM._meetCount, iValue); |
||
3676 | end |
||
3677 | |||
3678 | |||
3679 | -- -------------------------------------------------------------------------------------- |
||
3680 | |||
3681 | -- SkM_UpdateGuildHistory |
||
3682 | -- -------------------------------------------------------------------------------------- |
||
3683 | -- Update guild information when receiving an update of a enemy from this guild |
||
3684 | -- -------------------------------------------------------------------------------------- |
||
3685 | function SkM_UpdateGuildHistory(sGuildName, sDate, sName) |
||
3686 | local FName = "SkM_UpdateGuildHistory"; |
||
3687 | |||
3688 | SkM_Trace(FName, 2, "Guild Name : "..sGuildName..", Date : ".. sDate.. ", Player Name : "..sName); |
||
3689 | |||
3690 | if (not SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName]) then |
||
3691 | SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName] = { }; |
||
3692 | SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName][_SKM._name] = sGuildName; |
||
3693 | SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName][_SKM._playerAssistKill] = 0; |
||
3694 | SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName][_SKM._playerKill] = 0; |
||
3695 | SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName][_SKM._playerFullKill] = 0; |
||
3696 | SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName][_SKM._enemyKillPlayer] = 0; |
||
3697 | SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName][_SKM._enemyKillBG] = 0; |
||
3698 | SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName][_SKM._playerBGKill] = 0; |
||
3699 | SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName][_SKM._meetCount] = 1; |
||
3700 | else |
||
3701 | if ((not SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName][_SKM._meetCount]) |
||
3702 | or (not SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._lastView])) then |
||
3703 | SkM_Trace(FName, 2, "Increment Meet count for Guild for first time"..sGuildName); |
||
3704 | SkM_UpdateGuild_IncrMeet(sGuildName, 1); |
||
3705 | else |
||
3706 | -- increase number of time player met this guild if last viewed time for this enemy is older than |
||
3707 | -- configurable value |
||
3708 | SkM_Trace(FName, 2, "check if we need to increment"); |
||
3709 | local iDiffTime = SkM_DiffDate(sDate, SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._lastView]); |
||
3710 | if (iDiffTime ~= nil) and (iDiffTime > SKM_Config.TimeRangeForNewMeeting) then |
||
3711 | SkM_Trace(FName, 1, "Increment Meet count for Guild "..sGuildName); |
||
3712 | SkM_UpdateGuild_IncrMeet(sGuildName, 1); |
||
3713 | end |
||
3714 | end |
||
3715 | SkM_Trace(FName, 2, "Exit"); |
||
3716 | |||
3717 | end |
||
3718 | |||
3719 | SkM_UpdateGuild_SetLastView(sGuildName, sDate, sName); |
||
3720 | end |
||
3721 | |||
3722 | |||
3723 | |||
3724 | -- -------------------------------------------------------------------------------------- |
||
3725 | -- SkM_UpdateGuild_SetWar |
||
3726 | -- -------------------------------------------------------------------------------------- |
||
3727 | -- Update guild 'at war' status and war date |
||
3728 | -- -------------------------------------------------------------------------------------- |
||
3729 | function SkM_UpdateGuild_SetWar(sName, bWar, sDate) |
||
3730 | SKM_Data[_RealmName][_PlayerName].GuildHistory[sName][_SKM._atWar] = bWar; |
||
3731 | if (bWar) then |
||
3732 | SKM_Data[_RealmName][_PlayerName].GuildHistory[sName][_SKM._warDate] = sDate; |
||
3733 | else |
||
3734 | SKM_Data[_RealmName][_PlayerName].GuildHistory[sName][_SKM._warDate] = nil; |
||
3735 | end |
||
3736 | end |
||
3737 | |||
3738 | |||
3739 | function SkM_GetRecentEnemyKill(sName) |
||
3740 | local bFound = false; |
||
3741 | local iNoteIndex; |
||
3742 | local sDate = SkM_GetDate(); |
||
3743 | local i; |
||
3744 | for i=table.getn(SKM_Context.RecentEnemyKill), 1, -1 do |
||
3745 | if (SKM_Context.RecentEnemyKill[i][_SKM._name] == sName) then |
||
3746 | local iDiffTime = SkM_DiffDate(sDate, SKM_Context.RecentEnemyKill[i][_SKM._date]); |
||
3747 | if (iDiffTime ~= nil) and (iDiffTime <= SKM_Config.RecentEnemyKillDelay) then |
||
3748 | bFound = true; |
||
3749 | iNoteIndex = SKM_Context.RecentEnemyKill[i][_SKM._noteIndex]; |
||
3750 | return bFound, iNoteIndex; |
||
3751 | end |
||
3752 | end |
||
3753 | end |
||
3754 | return bFound, iNoteIndex; |
||
3755 | end |
||
3756 | |||
3757 | |||
3758 | function SkM_AddRecentEnemyKill(sName, sDate, iGlobalNote) |
||
3759 | local FName = "SkM_AddRecentEnemyKill"; |
||
3760 | |||
3761 | SkM_Trace(FName, 2, "Name = "..snil(sName)..", G. Note = "..snil(iGlobalNote)); |
||
3762 | |||
3763 | local Record = { }; |
||
3764 | Record[_SKM._name] = sName; |
||
3765 | Record[_SKM._date] = sDate; |
||
3766 | Record[_SKM._noteIndex] = iGlobalNote; |
||
3767 | table.insert(SKM_Context.RecentEnemyKill, Record); |
||
3768 | |||
3769 | while (table.getn(SKM_Context.RecentEnemyKill) > SKM_Config.MaxRecentEnemyKill) do |
||
3770 | table.remove(SKM_Context.RecentEnemyKill, 1); |
||
3771 | end |
||
3772 | end |
||
3773 | |||
3774 | |||
3775 | function SkM_GetRecentWarWarning(sName) |
||
3776 | local bFound = false; |
||
3777 | local sDate = SkM_GetDate(); |
||
3778 | local i; |
||
3779 | for i=table.getn(SKM_Context.RecentWarWarning), 1, -1 do |
||
3780 | if (SKM_Context.RecentWarWarning[i][_SKM._name] == sName) then |
||
3781 | local iDiffTime = SkM_DiffDate(sDate, SKM_Context.RecentWarWarning[i][_SKM._date]); |
||
3782 | if (iDiffTime ~= nil) and (iDiffTime <= SKM_Config.RecentWarWarningDelay) then |
||
3783 | bFound = true; |
||
3784 | return bFound; |
||
3785 | end |
||
3786 | end |
||
3787 | end |
||
3788 | return bFound; |
||
3789 | end |
||
3790 | |||
3791 | function SkM_AddRecentWarWarning(sName, sDate) |
||
3792 | local Record = { }; |
||
3793 | Record[_SKM._name] = sName; |
||
3794 | Record[_SKM._date] = sDate; |
||
3795 | table.insert(SKM_Context.RecentWarWarning, Record); |
||
3796 | |||
3797 | while (table.getn(SKM_Context.RecentWarWarning) > SKM_Config.MaxRecentWarWarning) do |
||
3798 | table.remove(SKM_Context.RecentWarWarning, 1); |
||
3799 | end |
||
3800 | end |
||
3801 | |||
3802 | |||
3803 | |||
3804 | -- -------------------------------------------------------------------------------------- |
||
3805 | -- SkM_PvpEnemyDeath |
||
3806 | -- -------------------------------------------------------------------------------------- |
||
3807 | -- An enemy dies... |
||
3808 | -- Check from his name if we know him as an enemy player. If it's the case, check how |
||
3809 | -- much relative damage did the group to this enemy, and record appropriate kill event. |
||
3810 | -- -------------------------------------------------------------------------------------- |
||
3811 | function SkM_PvpEnemyDeath(sName, bHonorKill, sRank) |
||
3812 | local FName = "SkM_PvpEnemyDeath"; |
||
3813 | |||
3814 | SkM_Trace(FName, 3, "Name = "..snil(sName)); |
||
3815 | if (not sName) then |
||
3816 | SkM_Trace(FName, 1, "nil parameter received !"); |
||
3817 | return; |
||
3818 | end |
||
3819 | |||
3820 | SkM_CheckForgetEnemy(sName); |
||
3821 | |||
3822 | -- if (not SkM_GetOption("RecordPlayerKill")) then |
||
3823 | -- return; |
||
3824 | -- end |
||
3825 | |||
3826 | |||
3827 | -- check if in battleground |
||
3828 | local bBattleground = SkM_IsInBattleground(); |
||
3829 | |||
3830 | if (not SKM_Context.EnemyCombat[sName]) and (not bHonorKill) then |
||
3831 | -- no information about this enemy |
||
3832 | return; |
||
3833 | end |
||
3834 | |||
3835 | if (not SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName]) then |
||
3836 | -- if this is a honor kill, then we *know* it is a player |
||
3837 | -- also check that "store enemy players" is enabled. |
||
3838 | |||
3839 | if (not bHonorKill) or (not SkM_GetOption("StoreEnemyPlayers")) then |
||
3840 | -- we have no information about the enemy just killed. |
||
3841 | -- maybe he's a player that has never been targeted, but maybe not... |
||
3842 | -- in doubt we do nothing |
||
3843 | SkM_Trace(FName, 3, sName.." : type unknown..."); |
||
3844 | |||
3845 | SKM_Context.EnemyCombat[sName] = nil; |
||
3846 | return; |
||
3847 | end |
||
3848 | |||
3849 | end |
||
3850 | |||
3851 | local sDate1, sDate2 = SkM_GetDate(); |
||
3852 | |||
3853 | SkM_UpdateEnemyLastView(sName, sDate1, false); |
||
3854 | if (sRank) then |
||
3855 | SkM_UpdateEnemyRank(sName, sRank); |
||
3856 | end |
||
3857 | |||
3858 | -- check if we have already recorded this kill |
||
3859 | local bRecorded, iNoteIndex; |
||
3860 | bRecorded, iNoteIndex = SkM_GetRecentEnemyKill(sName); |
||
3861 | if (bRecorded) then |
||
3862 | -- already recorded |
||
3863 | SkM_Trace(FName, 3, "Kill already recorded : idx_gn = "..snil(iNoteIndex)); |
||
3864 | |||
3865 | if (bHonorKill) then |
||
3866 | SkM_Trace(FName, 3, "Adjust as honor kill"); |
||
3867 | |||
3868 | -- we received an "honor kill", it means the kill was previously recorded due to |
||
3869 | -- a event that was not an "honor kill" : now take honor info into account |
||
3870 | -- SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._honorKill] = ifnil(SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._honorKill], 0) + 1; |
||
3871 | SkM_UpdateEnemy_IncrHonorKill(sName, 1); |
||
3872 | |||
3873 | SkM_SetHonorFlags(sName); |
||
3874 | |||
3875 | -- local sGuildName = SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._guild]; |
||
3876 | -- if ((sGuildName ~= nil) and (sGuildName ~= "")) then |
||
3877 | -- SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName][_SKM._honorKill] = ifnil(SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName][_SKM._honorKill], 0) + 1; |
||
3878 | -- end |
||
3879 | |||
3880 | if (iNoteIndex) then |
||
3881 | SKM_Data[_RealmName][_PlayerName].GlobalMapData[iNoteIndex][_SKM._storedInfo][_SKM._honorKill] = true; |
||
3882 | end |
||
3883 | |||
3884 | end |
||
3885 | |||
3886 | return; |
||
3887 | end |
||
3888 | |||
3889 | SkM_Trace(FName, 3, "Kill not yet recorded"); |
||
3890 | |||
3891 | local KillType; |
||
3892 | |||
3893 | if (not SKM_Context.EnemyCombat[sName]) then |
||
3894 | -- did not receive any combat information about this player, but |
||
3895 | -- we received an "honor" kill : award an "assist kill" by default |
||
3896 | SkM_Trace(FName, 3, "No combat info, but honor kill : award Assist Kill"); |
||
3897 | |||
3898 | KillType = _SKM._playerAssistKill; |
||
3899 | |||
3900 | elseif (SKM_Context.EnemyCombat[sName][_SKM._groupDamage] == 0) then |
||
3901 | SkM_Trace(FName, 3, "Group didn't do any damage"); |
||
3902 | |||
3903 | if (bHonorKill) then |
||
3904 | -- no damage recorded by our group, but we received an "honor kill" : |
||
3905 | -- award an "assist kill" by default |
||
3906 | KillType = _SKM._playerAssistKill; |
||
3907 | end |
||
3908 | |||
3909 | else |
||
3910 | local iPercent = SKM_Context.EnemyCombat[sName][_SKM._groupDamage] / SKM_Context.EnemyCombat[sName][_SKM._totalDamage]; |
||
3911 | |||
3912 | if (iPercent < 0.50) then |
||
3913 | SkM_Trace(FName, 3, "Group damage < 50% : award Assist Kill"); |
||
3914 | KillType = _SKM._playerAssistKill; |
||
3915 | elseif (iPercent < 1.00) then |
||
3916 | SkM_Trace(FName, 3, "Group damage >= 50% and < 100% : award Kill"); |
||
3917 | KillType = _SKM._playerKill; |
||
3918 | else |
||
3919 | SkM_Trace(FName, 3, "Group damage = 100% : award Full Kill"); |
||
3920 | KillType = _SKM._playerFullKill; |
||
3921 | end |
||
3922 | |||
3923 | end |
||
3924 | |||
3925 | if (KillType ~= nil) then |
||
3926 | |||
3927 | if (bBattleground == true) then |
||
3928 | KillType = _SKM._playerBGKill; |
||
3929 | end |
||
3930 | |||
3931 | if (SkM_GetOption("DisplayKillRecord")) then |
||
3932 | if (KillType == _SKM._playerAssistKill) then |
||
3933 | SkM_ChatMessageColP(string.format(SKM_UI_STRINGS.RecordMessage_AssistKill, sName), SKM_Config.RGB_PlayerAssistKill); |
||
3934 | elseif (KillType == _SKM._playerKill) then |
||
3935 | SkM_ChatMessageColP(string.format(SKM_UI_STRINGS.RecordMessage_Kill, sName), SKM_Config.RGB_PlayerKill); |
||
3936 | elseif (KillType == _SKM._playerFullKill) then |
||
3937 | SkM_ChatMessageColP(string.format(SKM_UI_STRINGS.RecordMessage_FullKill, sName), SKM_Config.RGB_PlayerFullKill); |
||
3938 | end |
||
3939 | end |
||
3940 | |||
3941 | --SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][KillType] = ifnil(SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][KillType], 0) + 1; |
||
3942 | SkM_UpdateEnemy_IncrCounter(sName, KillType, 1, true); |
||
3943 | |||
3944 | if (bBattleground == true) then |
||
3945 | SkM_BGStats_AddKill(); |
||
3946 | end |
||
3947 | |||
3948 | |||
3949 | if (bHonorKill) then |
||
3950 | --SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._honorKill] = ifnil(SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._honorKill], 0) + 1; |
||
3951 | SkM_UpdateEnemy_IncrHonorKill(sName, 1); |
||
3952 | |||
3953 | SkM_SetHonorFlags(sName); |
||
3954 | end |
||
3955 | |||
3956 | -- asked by Fumus : record special count for solo kills for which player did full damage |
||
3957 | if (KillType == _SKM._playerFullKill) and (getn(SKM_Context.GroupList) == 1) then |
||
3958 | SkM_Trace(FName, 3, "Group damage = 100% + solo : lone wolf kill"); |
||
3959 | --SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._loneWolfKill] = ifnil(SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._loneWolfKill], 0) + 1; |
||
3960 | SkM_UpdateEnemy_IncrLoneWolfKill(sName, 1); |
||
3961 | end |
||
3962 | |||
3963 | -- local sGuildName = SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._guild]; |
||
3964 | -- if ((sGuildName ~= nil) and (sGuildName ~= "")) then |
||
3965 | -- SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName][KillType] = ifnil(SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName][KillType], 0) + 1; |
||
3966 | -- |
||
3967 | -- if (bHonorKill) then |
||
3968 | |||
3969 | -- SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName][_SKM._honorKill] = ifnil(SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName][_SKM._honorKill], 0) + 1; |
||
3970 | -- end |
||
3971 | -- |
||
3972 | -- -- asked by Fumus : record special count for solo kills for which player did full damage |
||
3973 | -- if (KillType == _SKM._playerFullKill) and (getn(SKM_Context.GroupList) == 1) then |
||
3974 | -- SkM_Trace(FName, 3, "Group damage = 100% + solo : lone wolf kill"); |
||
3975 | -- SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName][_SKM._loneWolfKill] = ifnil(SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName][_SKM._loneWolfKill], 0) + 1; |
||
3976 | -- end |
||
3977 | -- end |
||
3978 | |||
3979 | --local Enemy = SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName]; |
||
3980 | |||
3981 | local StoreInfo = { }; |
||
3982 | |||
3983 | StoreInfo[_SKM._type] = KillType; |
||
3984 | StoreInfo[_SKM._name] = sName; |
||
3985 | StoreInfo[_SKM._date] = sDate1; |
||
3986 | --StoreInfo[_sortdate] = sDate2; |
||
3987 | |||
3988 | -- asked by Fumus : record special count for solo kills for which player did full damage |
||
3989 | if (KillType == _SKM._playerFullKill) and (getn(SKM_Context.GroupList) == 1) then |
||
3990 | StoreInfo[_SKM._loneWolfKill] = true; |
||
3991 | end |
||
3992 | |||
3993 | if (bHonorKill) then |
||
3994 | StoreInfo[_SKM._honorKill] = true; |
||
3995 | end |
||
3996 | |||
3997 | StoreInfo[_SKM._enemyType] = _SKM._enemyPlayer; |
||
3998 | |||
3999 | if (SkM_GetOption("RecordPlayerKill")) then |
||
4000 | local idx_gn; |
||
4001 | if (SkM_AddMapData(StoreInfo)) then |
||
4002 | idx_gn = table.getn(SKM_Data[_RealmName][_PlayerName].GlobalMapData); |
||
4003 | end |
||
4004 | |||
4005 | SkM_AddRecentEnemyKill(sName, sDate1, idx_gn); |
||
4006 | end |
||
4007 | |||
4008 | -- update target info if needed |
||
4009 | SkM_SetTargetInfo(); |
||
4010 | end |
||
4011 | |||
4012 | SKM_Context.EnemyCombat[sName] = nil; |
||
4013 | end |
||
4014 | |||
4015 | |||
4016 | function SkM_SetHonorFlags(sName) |
||
4017 | local FName = "SkM_SetHonorFlags"; |
||
4018 | |||
4019 | if (not sName) then |
||
4020 | SkM_Trace(FName, 1, "Name is nil"); |
||
4021 | return; |
||
4022 | end |
||
4023 | if (not SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName]) then |
||
4024 | SkM_Trace(FName, 1, "Enemy "..snil(sName).." not known"); |
||
4025 | return; |
||
4026 | end |
||
4027 | |||
4028 | local sDate = SkM_GetDate(); |
||
4029 | local sDateLast = SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._honorLastKill]; |
||
4030 | |||
4031 | if (not sDateLast) then |
||
4032 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._honorLastKill] = sDate; |
||
4033 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._honorCount] = 1; |
||
4034 | elseif (string.sub(sDate, 1, 10) ~= string.sub(sDateLast, 1, 10)) then |
||
4035 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._honorLastKill] = sDate; |
||
4036 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._honorCount] = 1; |
||
4037 | else |
||
4038 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._honorCount] = ifnil(SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._honorCount], 0) + 1; |
||
4039 | end |
||
4040 | |||
4041 | end |
||
4042 | |||
4043 | |||
4044 | function SkM_GetHonorRemainingKills(sName) |
||
4045 | local FName = "SkM_GetHonorRemainingKills"; |
||
4046 | |||
4047 | if (not sName) then |
||
4048 | SkM_Trace(FName, 1, "Name is nil"); |
||
4049 | return; |
||
4050 | end |
||
4051 | if (not SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName]) then |
||
4052 | SkM_Trace(FName, 1, "Enemy "..snil(sName).." not known"); |
||
4053 | return; |
||
4054 | end |
||
4055 | |||
4056 | local iCount; |
||
4057 | local sDate = SkM_GetDate(); |
||
4058 | local sDateLast = SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._honorLastKill]; |
||
4059 | |||
4060 | if (not sDateLast) then |
||
4061 | iCount = SKM_HonorKillPerDay; |
||
4062 | elseif (string.sub(sDate, 1, 10) ~= string.sub(sDateLast, 1, 10)) then |
||
4063 | iCount = SKM_HonorKillPerDay; |
||
4064 | else |
||
4065 | iCount = SKM_HonorKillPerDay - ifnil(SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName][_SKM._honorCount], 0); |
||
4066 | if (iCount < 0) then |
||
4067 | iCount = 0; |
||
4068 | end |
||
4069 | end |
||
4070 | return iCount; |
||
4071 | end |
||
4072 | |||
4073 | |||
4074 | function SkM_StoreDuelEnemyInfo(sUnit) |
||
4075 | local FName = "SkM_StoreDuelEnemyInfo"; |
||
4076 | |||
4077 | local sName = UnitName(sUnit); |
||
4078 | if (not sName) then |
||
4079 | return; |
||
4080 | end |
||
4081 | |||
4082 | if (SKM_Context.DuelEnemy) and (SKM_Context.DuelEnemy[_SKM._name] == sName) then |
||
4083 | -- already stored |
||
4084 | return; |
||
4085 | end |
||
4086 | |||
4087 | SKM_Context.DuelEnemy = { }; |
||
4088 | SKM_Context.DuelEnemy[_SKM._name] = sName; |
||
4089 | SKM_Context.DuelEnemy[_SKM._race] = SkM_GetRaceIndex(UnitRace(sUnit)); |
||
4090 | SKM_Context.DuelEnemy[_SKM._class] = SkM_GetClassIndex(UnitClass(sUnit)); |
||
4091 | SKM_Context.DuelEnemy[_SKM._level] = UnitLevel(sUnit); |
||
4092 | SKM_Context.DuelEnemy[_SKM._guild] = GetGuildInfo(sUnit); |
||
4093 | |||
4094 | end |
||
4095 | |||
4096 | |||
4097 | -- -------------------------------------------------------------------------------------- |
||
4098 | -- SkM_UpdateUnitData |
||
4099 | -- -------------------------------------------------------------------------------------- |
||
4100 | -- Target unit has been updated. If it's an enemy, update that player information. |
||
4101 | -- If it's a creep, store creature information. |
||
4102 | -- -------------------------------------------------------------------------------------- |
||
4103 | function SkM_UpdateUnitData() |
||
4104 | local FName = "SkM_UpdateUnitData"; |
||
4105 | |||
4106 | local sName = SkM_UnitName(SKM_UNIT_TARGET); |
||
4107 | |||
4108 | if (not sName) then |
||
4109 | -- clear target info |
||
4110 | SKM_Context.TargetInfo = nil; |
||
4111 | else |
||
4112 | if (SkM_UnitIsEnemyPlayer(SKM_UNIT_TARGET)) then |
||
4113 | local sDate1, sDate2 = SkM_GetDate(); |
||
4114 | SkM_UpdateEnemyLastView(sName, sDate1, true, SKM_UNIT_TARGET); |
||
4115 | end |
||
4116 | |||
4117 | if (not UnitIsPlayer(SKM_UNIT_TARGET)) then |
||
4118 | SkM_StoreTargetInfo(_SKM._enemyCreature); |
||
4119 | elseif (SkM_UnitIsEnemyPlayer(SKM_UNIT_TARGET)) then |
||
4120 | SkM_StoreTargetInfo(_SKM._enemyPlayer); |
||
4121 | else |
||
4122 | SKM_Context.TargetInfo = nil; |
||
4123 | end |
||
4124 | |||
4125 | if (SkM_GetOption("StoreDuels")) then |
||
4126 | if (SkM_UnitIsDuelingPlayer(SKM_UNIT_TARGET)) then |
||
4127 | SkM_StoreDuelEnemyInfo(SKM_UNIT_TARGET); |
||
4128 | end |
||
4129 | end |
||
4130 | |||
4131 | end |
||
4132 | |||
4133 | |||
4134 | end |
||
4135 | |||
4136 | |||
4137 | -- -------------------------------------------------------------------------------------- |
||
4138 | -- SkM_MouseOverUnitData |
||
4139 | -- -------------------------------------------------------------------------------------- |
||
4140 | -- Get information on enemy player on mouse-over |
||
4141 | -- -------------------------------------------------------------------------------------- |
||
4142 | function SkM_MouseOverUnitData() |
||
4143 | local FName = "SkM_MouseOverUnitData"; |
||
4144 | |||
4145 | local sName = SkM_UnitName(SKM_UNIT_MOUSEOVER); |
||
4146 | |||
4147 | if (sName) then |
||
4148 | if (SkM_UnitIsEnemyPlayer(SKM_UNIT_MOUSEOVER)) then |
||
4149 | local sDate1, sDate2 = SkM_GetDate(); |
||
4150 | SkM_UpdateEnemyLastView(sName, sDate1, true, SKM_UNIT_MOUSEOVER); |
||
4151 | |||
4152 | --local iLevel = UnitLevel(SKM_UNIT_MOUSEOVER); |
||
4153 | --local sClass = UnitClass(SKM_UNIT_MOUSEOVER); |
||
4154 | --local sRace = UnitRace(SKM_UNIT_MOUSEOVER); |
||
4155 | --local sGuild = GetGuildInfo(SKM_UNIT_MOUSEOVER); |
||
4156 | --SkM_Trace(FName, 1, "Name = "..snil(sName)..", Level = "..snil(iLevel)..", Class = "..snil(sClass)..", Race = "..snil(sRace)..", Guild = "..snil(sGuild)); |
||
4157 | |||
4158 | elseif (SkM_GetOption("StoreDuels")) and (SkM_UnitIsDuelingPlayer(SKM_UNIT_MOUSEOVER)) then |
||
4159 | SkM_StoreDuelEnemyInfo(SKM_UNIT_MOUSEOVER); |
||
4160 | end |
||
4161 | |||
4162 | end |
||
4163 | |||
4164 | end |
||
4165 | |||
4166 | |||
4167 | -- -------------------------------------------------------------------------------------- |
||
4168 | -- SkM_ForgetPlayerHate |
||
4169 | -- -------------------------------------------------------------------------------------- |
||
4170 | -- For all enemies in player hate list, recompute hate level from time elapsed since |
||
4171 | -- last update. |
||
4172 | -- "forget" enemy if hate reaches zero or if no update has been |
||
4173 | -- received for a given time. |
||
4174 | -- -------------------------------------------------------------------------------------- |
||
4175 | function SkM_ForgetPlayerHate() |
||
4176 | local FName = "SkM_ForgetPlayerHate"; |
||
4177 | |||
4178 | local curTime = GetTime(); |
||
4179 | |||
4180 | for sName, Enemy in SKM_Context.PlayerCombat do |
||
4181 | |||
4182 | if (curTime - Enemy[_SKM._lastUpdate] > SKM_Config.ForgetAggressorTimer) then |
||
4183 | -- no update since given time interval, forget, whatever the hate level may be |
||
4184 | SKM_Context.PlayerCombat[sName] = nil; |
||
4185 | else |
||
4186 | -- don't forget, but reduce hate from time elapsed |
||
4187 | local iTime = curTime - Enemy[_SKM._lastHateUpdate]; |
||
4188 | |||
4189 | nHateReduction = Enemy[_SKM._hateLevel] * (iTime / 100) * SKM_Config.HateReductionCoeff; |
||
4190 | |||
4191 | SKM_Context.PlayerCombat[sName][_SKM._hateLevel] = Enemy[_SKM._hateLevel] - nHateReduction; |
||
4192 | SKM_Context.PlayerCombat[sName][_SKM._lastHateUpdate] = curTime; |
||
4193 | |||
4194 | -- if hate is reduced to zero (or less), forget |
||
4195 | if (SKM_Context.PlayerCombat[sName][_SKM._hateLevel] <= 0) then |
||
4196 | SKM_Context.PlayerCombat[sName] = nil; |
||
4197 | end |
||
4198 | end |
||
4199 | end |
||
4200 | |||
4201 | end |
||
4202 | |||
4203 | |||
4204 | -- -------------------------------------------------------------------------------------- |
||
4205 | -- SkM_LogDamage_OnSelf |
||
4206 | -- -------------------------------------------------------------------------------------- |
||
4207 | -- Keep track of damage done on self and update "hate level" associated to the damage |
||
4208 | -- dealer. |
||
4209 | -- -------------------------------------------------------------------------------------- |
||
4210 | function SkM_LogDamage_OnSelf(iDamage, sName, EnemyType) |
||
4211 | local FName = "SkM_LogDamage_OnSelf"; |
||
4212 | |||
4213 | local curTime = GetTime(); |
||
4214 | |||
4215 | SkM_ForgetPlayerHate(); |
||
4216 | |||
4217 | if (not SKM_Context.PlayerCombat[sName]) then |
||
4218 | SKM_Context.PlayerCombat[sName] = { }; |
||
4219 | SKM_Context.PlayerCombat[sName][_SKM._name] = sName; |
||
4220 | SKM_Context.PlayerCombat[sName][_SKM._enemyType] = EnemyType; |
||
4221 | SKM_Context.PlayerCombat[sName][_SKM._hateLevel] = 0; |
||
4222 | SKM_Context.PlayerCombat[sName][_SKM._damage] = 0; |
||
4223 | SKM_Context.PlayerCombat[sName][_SKM._lastHateUpdate] = curTime; |
||
4224 | SKM_Context.PlayerCombat[sName][_SKM._lastUpdate] = curTime; |
||
4225 | end |
||
4226 | |||
4227 | -- store enemy type if we have it now and it was not previously stored |
||
4228 | if (not SKM_Context.PlayerCombat[sName][_SKM._enemyType]) and (EnemyType ~= nil) then |
||
4229 | SKM_Context.PlayerCombat[sName][_SKM._enemyType] = EnemyType; |
||
4230 | end |
||
4231 | |||
4232 | SKM_Context.PlayerCombat[sName][_SKM._damage] = SKM_Context.PlayerCombat[sName][_SKM._damage] + iDamage; |
||
4233 | SKM_Context.PlayerCombat[sName][_SKM._hateLevel] = SKM_Context.PlayerCombat[sName][_SKM._hateLevel] + iDamage; |
||
4234 | |||
4235 | SkM_Trace(FName, 3, "PlayerCombat updated for "..sName.." : damage = ".. SKM_Context.PlayerCombat[sName][_SKM._damage] ..", hate level = ".. SKM_Context.PlayerCombat[sName][_SKM._hateLevel]); |
||
4236 | end |
||
4237 | |||
4238 | |||
4239 | -- -------------------------------------------------------------------------------------- |
||
4240 | -- SkM_HateList_Dump |
||
4241 | -- -------------------------------------------------------------------------------------- |
||
4242 | -- Debug function. Dump content of "PlayerCombat" (hate list). |
||
4243 | -- -------------------------------------------------------------------------------------- |
||
4244 | function SkM_HateList_Dump() |
||
4245 | local FName = "SkM_HateList_Dump"; |
||
4246 | |||
4247 | local curTime = GetTime(); |
||
4248 | |||
4249 | |||
4250 | SkM_ForgetPlayerHate(); |
||
4251 | |||
4252 | for idx, Elem in SKM_Context.PlayerCombat do |
||
4253 | local iTime = math.ceil(curTime - Elem[_SKM._lastUpdate]); |
||
4254 | local sReport = Elem[_SKM._name].." (last update : "..iTime.." s ago) -> damage = "..Elem[_SKM._damage]..", hate = "..Elem[_SKM._hateLevel]; |
||
4255 | |||
4256 | SkM_ChatMessageCol(sReport); |
||
4257 | end |
||
4258 | end |
||
4259 | |||
4260 | |||
4261 | -- -------------------------------------------------------------------------------------- |
||
4262 | -- SkM_SortPlayerCombat_ByHate |
||
4263 | -- -------------------------------------------------------------------------------------- |
||
4264 | -- Sort "PlayerCombat" list by hate level. |
||
4265 | -- -------------------------------------------------------------------------------------- |
||
4266 | function SkM_SortPlayerCombat_ByHate(e1, e2) |
||
4267 | if (not e2[_SKM._hateLevel]) then |
||
4268 | return true; |
||
4269 | end |
||
4270 | if (not e1[_SKM._hateLevel]) then |
||
4271 | return false; |
||
4272 | end |
||
4273 | return (e1[_SKM._hateLevel] > e2[_SKM._hateLevel]); |
||
4274 | end |
||
4275 | |||
4276 | |||
4277 | -- -------------------------------------------------------------------------------------- |
||
4278 | -- SkM_PlayerDeathResp |
||
4279 | -- -------------------------------------------------------------------------------------- |
||
4280 | -- Find who is responsible for your death, if any. This is the most hated enemy player |
||
4281 | -- or creature from "PlayerCombat" list. |
||
4282 | -- Also reset hate list afterwards. |
||
4283 | -- -------------------------------------------------------------------------------------- |
||
4284 | function SkM_PlayerDeathResp() |
||
4285 | local FName = "SkM_PlayerDeathResp"; |
||
4286 | |||
4287 | SkM_ForgetPlayerHate(); |
||
4288 | |||
4289 | local HateList = {}; |
||
4290 | local EnemyName, EnemyType; |
||
4291 | local iTotal = 0; |
||
4292 | |||
4293 | local idx, val; |
||
4294 | for idx, val in SKM_Context.PlayerCombat do |
||
4295 | local Elem = copytable(val); |
||
4296 | iTotal = iTotal + Elem[_SKM._hateLevel]; |
||
4297 | table.insert(HateList, Elem); |
||
4298 | end |
||
4299 | |||
4300 | table.sort(HateList, SkM_SortPlayerCombat_ByHate); |
||
4301 | |||
4302 | if (table.getn(HateList) > 0) then |
||
4303 | EnemyName = HateList[1][_SKM._name]; |
||
4304 | EnemyType = HateList[1][_SKM._enemyType]; |
||
4305 | end |
||
4306 | |||
4307 | for idx, val in HateList do |
||
4308 | val[_SKM._hatePercent] = math.floor(100 * val[_SKM._hateLevel] / iTotal); |
||
4309 | end |
||
4310 | |||
4311 | SkM_Trace(FName, 2, "Most hated = "..snil(EnemyName)..", type = "..snil(EnemyType)); |
||
4312 | |||
4313 | SKM_Context.PlayerCombat = { }; |
||
4314 | |||
4315 | return EnemyName, EnemyType, HateList; |
||
4316 | end |
||
4317 | |||
4318 | |||
4319 | -- -------------------------------------------------------------------------------------- |
||
4320 | -- SkM_DumpEnemyCombat |
||
4321 | -- -------------------------------------------------------------------------------------- |
||
4322 | -- Debug function. Dump content of "EnemyCombat" list. |
||
4323 | -- -------------------------------------------------------------------------------------- |
||
4324 | function SkM_DumpEnemyCombat() |
||
4325 | local FName = "SkM_DumpEnemyCombat"; |
||
4326 | local curTime = GetTime(); |
||
4327 | |||
4328 | for idx, val in SKM_Context.EnemyCombat do |
||
4329 | local iTime = math.ceil(curTime - val[_SKM._lastUpdate]); |
||
4330 | |||
4331 | sReport = val[_SKM._name] .. " (last update : "..iTime.." s ago) -> total damage = ".. val[_SKM._totalDamage] .. ", group damage = " .. val[_SKM._groupDamage]; |
||
4332 | SkM_ChatMessageCol(sReport); |
||
4333 | end |
||
4334 | end |
||
4335 | |||
4336 | |||
4337 | -- -------------------------------------------------------------------------------------- |
||
4338 | -- SkM_IsLeapYear |
||
4339 | -- -------------------------------------------------------------------------------------- |
||
4340 | -- Is given year a leap year ? |
||
4341 | -- -------------------------------------------------------------------------------------- |
||
4342 | function SkM_IsLeapYear(iYear) |
||
4343 | return intable(iYear, LeapYears); |
||
4344 | end |
||
4345 | |||
4346 | |||
4347 | -- -------------------------------------------------------------------------------------- |
||
4348 | -- SkM_DaysInYear |
||
4349 | -- -------------------------------------------------------------------------------------- |
||
4350 | -- Return number of days in given year |
||
4351 | -- -------------------------------------------------------------------------------------- |
||
4352 | function SkM_DaysInYear(iYear) |
||
4353 | if (SkM_IsLeapYear(iYear)) then |
||
4354 | return 366; |
||
4355 | else |
||
4356 | return 365; |
||
4357 | end |
||
4358 | end |
||
4359 | |||
4360 | |||
4361 | -- -------------------------------------------------------------------------------------- |
||
4362 | -- SkM_DaysInMonth |
||
4363 | -- -------------------------------------------------------------------------------------- |
||
4364 | -- Return number of days in given month of a given year |
||
4365 | -- -------------------------------------------------------------------------------------- |
||
4366 | function SkM_DaysInMonth(iMonth, iYear) |
||
4367 | local iDays = DaysInMonth[iMonth]; |
||
4368 | if (iMonth == 2) and SkM_IsLeapYear(iYear) then |
||
4369 | iDays = 29; |
||
4370 | end |
||
4371 | return iDays; |
||
4372 | end |
||
4373 | |||
4374 | |||
4375 | -- -------------------------------------------------------------------------------------- |
||
4376 | -- SkM_TimeSinceEpoch |
||
4377 | -- -------------------------------------------------------------------------------------- |
||
4378 | -- Return the number of seconds since "epoch", fixed at 01/01/2004 00:00:00. |
||
4379 | -- (we do not need to handle time periods prior to WoW release, so this does not need |
||
4380 | -- to be less than this time) |
||
4381 | -- -------------------------------------------------------------------------------------- |
||
4382 | function SkM_TimeSinceEpoch(sDate) |
||
4383 | local FName = "SkM_TimeSinceEpoch"; |
||
4384 | |||
4385 | SkM_Trace(FName, 3, "Date = "..snil(sDate)); |
||
4386 | |||
4387 | local iDay, iMonth, iYear, iHour, iMin, iSec; |
||
4388 | |||
4389 | iDay = tonumber( string.sub(sDate, 1, 2) ); |
||
4390 | iMonth = tonumber( string.sub(sDate, 4, 5) ); |
||
4391 | iYear = tonumber( string.sub(sDate, 7, 10) ) ; |
||
4392 | |||
4393 | iHour = tonumber( string.sub(sDate, 12, 13) ); |
||
4394 | iMin = tonumber( string.sub(sDate, 15, 16) ); |
||
4395 | iSec = tonumber( string.sub(sDate, 18, 19) ); |
||
4396 | |||
4397 | if (iDay == nil) or (iMonth == nil) or (iYear == nil) or (iHour == nil) or (iMin == nil) or (iSec == nil) then |
||
4398 | return nil; |
||
4399 | end |
||
4400 | |||
4401 | local iTime = 0; |
||
4402 | |||
4403 | iIndYear = 2004; |
||
4404 | while (iIndYear < iYear) do |
||
4405 | iTime = iTime + SkM_DaysInYear(iIndYear); iIndYear = iIndYear + 1; |
||
4406 | end |
||
4407 | |||
4408 | iIndMonth = 1; |
||
4409 | while (iIndMonth < iMonth) do |
||
4410 | iTime = iTime + SkM_DaysInMonth(iIndMonth, iYear); iIndMonth = iIndMonth + 1; |
||
4411 | end |
||
4412 | |||
4413 | iTime = (iTime + (iDay - 1)) * 24; |
||
4414 | iTime = (iTime + (iHour - 1)) * 60; |
||
4415 | iTime = (iTime + (iMin - 1)) * 60; |
||
4416 | iTime = iTime + iSec; |
||
4417 | |||
4418 | SkM_Trace(FName, 3, "Sec num since 01/01/2004 = "..snil(iTime)); |
||
4419 | return iTime; |
||
4420 | end |
||
4421 | |||
4422 | |||
4423 | -- -------------------------------------------------------------------------------------- |
||
4424 | -- SkM_DiffDate |
||
4425 | -- -------------------------------------------------------------------------------------- |
||
4426 | -- Return the difference in seconds between two dates in format DD/MM/YYYY HH:MI:SS |
||
4427 | -- -------------------------------------------------------------------------------------- |
||
4428 | function SkM_DiffDate(sDate1, sDate2) |
||
4429 | local FName = "SkM_DiffDate"; |
||
4430 | |||
4431 | if (sDate1 == nil) or (sDate2 == nil) then |
||
4432 | return nil; |
||
4433 | end |
||
4434 | |||
4435 | local iTime1, iTime2, iTime; |
||
4436 | |||
4437 | iTime1 = SkM_TimeSinceEpoch(sDate1); |
||
4438 | iTime2 = SkM_TimeSinceEpoch(sDate2); |
||
4439 | |||
4440 | if (iTime1 == nil) or (iTime2 == nil) then |
||
4441 | return nil; |
||
4442 | end |
||
4443 | |||
4444 | iTime = iTime1 - iTime2; |
||
4445 | SkM_Trace(FName, 3, "Time difference = "..snil(iTime)); |
||
4446 | return iTime; |
||
4447 | end |
||
4448 | |||
4449 | |||
4450 | -- -------------------------------------------------------------------------------------- |
||
4451 | -- SkM_SetTargetInfoText |
||
4452 | -- -------------------------------------------------------------------------------------- |
||
4453 | -- Set a line of text of SKMapTargetInfoButton |
||
4454 | -- -------------------------------------------------------------------------------------- |
||
4455 | function SkM_SetTargetInfoText(id, sLabel, sValue, sDetail) |
||
4456 | local FName = "SkM_SetTargetInfoText"; |
||
4457 | |||
4458 | local TextLabe, ValueLabel, DetailLabel; |
||
4459 | if (sLabel) then |
||
4460 | TextLabel = getglobal("SKMapTargetInfoButton"..id.."Label"); |
||
4461 | if (not TextLabel) then return false; end |
||
4462 | end |
||
4463 | if (sValue) then |
||
4464 | ValueLabel = getglobal("SKMapTargetInfoButton"..id.."Value"); |
||
4465 | if (not ValueLabel) then return false; end |
||
4466 | end |
||
4467 | if (sDetail) then |
||
4468 | DetailLabel = getglobal("SKMapTargetInfoButton"..id.."Detail"); |
||
4469 | if (not DetailLabel) then return false; end |
||
4470 | end |
||
4471 | |||
4472 | if (sLabel) then |
||
4473 | TextLabel:SetText(sLabel); |
||
4474 | end |
||
4475 | if (sValue) then |
||
4476 | ValueLabel:SetText(sValue); |
||
4477 | end |
||
4478 | if (sDetail) then |
||
4479 | DetailLabel:SetText(sDetail); |
||
4480 | end |
||
4481 | |||
4482 | return true; |
||
4483 | end |
||
4484 | |||
4485 | |||
4486 | -- -------------------------------------------------------------------------------------- |
||
4487 | -- SkM_SetSmallTargetInfoText |
||
4488 | -- -------------------------------------------------------------------------------------- |
||
4489 | -- Set a line of text of SKMapSmallTargetInfoButton |
||
4490 | -- -------------------------------------------------------------------------------------- |
||
4491 | function SkM_SetSmallTargetInfoText(id, sLabel, sValue) |
||
4492 | local FName = "SkM_SetTargetInfoText"; |
||
4493 | |||
4494 | local TextLabe, ValueLabel; |
||
4495 | if (sLabel) then |
||
4496 | TextLabel = getglobal("SKMapSmallTargetInfoButton"..id.."Label"); |
||
4497 | if (not TextLabel) then return false; end |
||
4498 | end |
||
4499 | if (sValue) then |
||
4500 | ValueLabel = getglobal("SKMapSmallTargetInfoButton"..id.."Value"); |
||
4501 | if (not ValueLabel) then return false; end |
||
4502 | end |
||
4503 | |||
4504 | if (sLabel) then |
||
4505 | TextLabel:SetText(sLabel); |
||
4506 | end |
||
4507 | if (sValue) then |
||
4508 | ValueLabel:SetText(sValue); |
||
4509 | end |
||
4510 | |||
4511 | return true; |
||
4512 | end |
||
4513 | |||
4514 | |||
4515 | -- -------------------------------------------------------------------------------------- |
||
4516 | -- SkM_ShowTargetGuildInfo |
||
4517 | -- -------------------------------------------------------------------------------------- |
||
4518 | -- Display or hide guild info mini frame |
||
4519 | -- -------------------------------------------------------------------------------------- |
||
4520 | function SkM_ShowTargetGuildInfo(bShow, sGuildName, bGuildWar) |
||
4521 | |||
4522 | if (not SkM_GetOption("ShowTargetGuildInfo")) then |
||
4523 | SKMapTargetGuildInfo:Hide(); |
||
4524 | else |
||
4525 | if (bShow ~= true) or (sGuildName == nil) or (sGuildName == "") then |
||
4526 | SKMapTargetGuildInfo:Hide(); |
||
4527 | else |
||
4528 | local id=1; |
||
4529 | TextValue = getglobal("SKMapTargetGuildInfoButton"..id.."Value"); |
||
4530 | |||
4531 | local sText; |
||
4532 | if (bGuildWar) then |
||
4533 | sText = SKM_Config.Col_PlayerWar; |
||
4534 | else |
||
4535 | sText = SKM_Config.Col_Label; |
||
4536 | end |
||
4537 | sText = sText..sGuildName; |
||
4538 | TextValue:SetText(sText); |
||
4539 | |||
4540 | SKMapTargetGuildInfo:Show(); |
||
4541 | end |
||
4542 | end |
||
4543 | end |
||
4544 | |||
4545 | |||
4546 | -- -------------------------------------------------------------------------------------- |
||
4547 | -- SkM_ShowTargetClassInfo |
||
4548 | -- -------------------------------------------------------------------------------------- |
||
4549 | -- Display or hide class info mini frame |
||
4550 | -- -------------------------------------------------------------------------------------- |
||
4551 | function SkM_ShowTargetClassInfo(bShow, sClass) |
||
4552 | |||
4553 | if (not SkM_GetOption("ShowTargetClassInfo")) then |
||
4554 | SKMapTargetClassInfo:Hide(); |
||
4555 | else |
||
4556 | if (bShow ~= true) or (sClass == nil) or (sClass == "") then |
||
4557 | SKMapTargetClassInfo:Hide(); |
||
4558 | else |
||
4559 | local id=1; |
||
4560 | TextValue = getglobal("SKMapTargetClassInfoButton"..id.."Value"); |
||
4561 | |||
4562 | sText = SKM_Config.Col_Label; |
||
4563 | sText = sText..sClass; |
||
4564 | TextValue:SetText(sText); |
||
4565 | |||
4566 | SKMapTargetClassInfo:Show(); |
||
4567 | end |
||
4568 | end |
||
4569 | |||
4570 | end |
||
4571 | |||
4572 | |||
4573 | -- -------------------------------------------------------------------------------------- |
||
4574 | -- SkM_SetTargetInfo |
||
4575 | -- -------------------------------------------------------------------------------------- |
||
4576 | -- Fill and display or hidel TargetInfo frame(s) according to current target |
||
4577 | -- -------------------------------------------------------------------------------------- |
||
4578 | function SkM_SetTargetInfo() |
||
4579 | local FName = "SkM_SetTargetInfo"; |
||
4580 | |||
4581 | local sName = SkM_UnitName(SKM_UNIT_TARGET); |
||
4582 | --local sName = "Abaddon"; |
||
4583 | if (not sName) then |
||
4584 | -- no target |
||
4585 | SkM_HideTargetInfoFrame(); |
||
4586 | SkM_ShowTargetGuildInfo(false, nil, nil); |
||
4587 | SkM_ShowTargetClassInfo(false, nil); |
||
4588 | SkM_SetWarDragon(false, false); |
||
4589 | return false; |
||
4590 | end |
||
4591 | |||
4592 | local sClass = UnitClass(SKM_UNIT_TARGET); |
||
4593 | |||
4594 | if (SkM_UnitIsEnemyPlayer(SKM_UNIT_TARGET)) then |
||
4595 | --if (true) then |
||
4596 | |||
4597 | local bWar = false; |
||
4598 | local bGuildWar = false; |
||
4599 | |||
4600 | local Enemy = SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName]; |
||
4601 | if (not Enemy) then |
||
4602 | SkM_HideTargetInfoFrame(); |
||
4603 | SkM_SetWarDragon(false, false); |
||
4604 | return false; |
||
4605 | end |
||
4606 | |||
4607 | -- 09/04/2005 17:23:14 PIng Add guild support |
||
4608 | local sGuildName = Enemy[_SKM._guild]; |
||
4609 | if (sGuildName == "") then sGuildName = nil; end |
||
4610 | local Guild = SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName]; |
||
4611 | -- 09/04/2005 17:24:33 End of modification |
||
4612 | |||
4613 | if (Enemy[_SKM._atWar]) then |
||
4614 | bWar = true; |
||
4615 | end |
||
4616 | if (Guild) and (Guild[_SKM._atWar]) then |
||
4617 | bGuildWar = true; |
||
4618 | end |
||
4619 | |||
4620 | SkM_ShowTargetGuildInfo(true, sGuildName, bGuildWar); |
||
4621 | SkM_ShowTargetClassInfo(true, sClass); |
||
4622 | |||
4623 | local iKill = ifnil(Enemy[_SKM._playerKill], 0); |
||
4624 | local iAssistKill = ifnil(Enemy[_SKM._playerAssistKill], 0); |
||
4625 | local iFullKill = ifnil(Enemy[_SKM._playerFullKill], 0); |
||
4626 | local iTotalKill = iKill + iAssistKill + iFullKill; |
||
4627 | local iHonorKill = ifnil(Enemy[_SKM._honorKill], 0); |
||
4628 | |||
4629 | local iRemaining = SkM_GetHonorRemainingKills(sName); |
||
4630 | |||
4631 | -- 09/04/2005 17:25:03 PIng Add guild support |
||
4632 | local gKill = ""; |
||
4633 | local gAssistKill = ""; |
||
4634 | local gFullKill = ""; |
||
4635 | local gTotalKill = ""; |
||
4636 | local gDeath = ""; |
||
4637 | local gMet = ""; |
||
4638 | if (sGuildName ~= nil) then |
||
4639 | gKill = ifnil(Guild[_SKM._playerKill], 0); |
||
4640 | gAssistKill = ifnil(Guild[_SKM._playerAssistKill], 0); |
||
4641 | gFullKill = ifnil(Guild[_SKM._playerFullKill], 0); |
||
4642 | gTotalKill = gKill + gAssistKill + gFullKill; |
||
4643 | gDeath = ifnil(Guild[_SKM._enemyKillPlayer], 0); |
||
4644 | gMet = ifnil(Guild[_SKM._meetCount], 0); |
||
4645 | end |
||
4646 | -- 09/04/2005 17:25:12 End of modification |
||
4647 | |||
4648 | local iDeath = ifnil(Enemy[_SKM._enemyKillPlayer], 0); |
||
4649 | local iMet = ifnil(Enemy[_SKM._meetCount], 0); |
||
4650 | |||
4651 | SkM_Trace(FName, 3, "Kill = "..iKill..", AssistKill = "..iAssistKill..", FullKill = "..iFullKill..", Met = "..iMet); |
||
4652 | -- 09/04/2005 17:25:03 PIng Add guild support |
||
4653 | if (sGuildName ~= nil) then |
||
4654 | SkM_Trace(FName, 3, "Guild Kill = "..gKill..", Guild AssistKill = "..gAssistKill..", Guild FullKill = "..gFullKill..", Guild Met = "..gMet); |
||
4655 | end |
||
4656 | -- 09/04/2005 17:25:12 End of modification |
||
4657 | |||
4658 | local sKill = SKM_Config.Col_PlayerTotalKill .. iTotalKill; |
||
4659 | local sKillDetail; |
||
4660 | -- only display detail kill count if there's at least one kill |
||
4661 | -- if (iTotalKill == 0) then |
||
4662 | -- sKillDetail = ""; |
||
4663 | -- else |
||
4664 | -- sKillDetail = SKM_Config.Col_Label .. "( " .. SKM_Config.Col_PlayerFullKill .. iFullKill .. SKM_Config.Col_Label .. " + " .. SKM_Config.Col_PlayerKill .. iKill .. SKM_Config.Col_Label .. " + " .. SKM_Config.Col_PlayerAssistKill .. iAssistKill .. SKM_Config.Col_Label .. " )"; |
||
4665 | -- end |
||
4666 | |||
4667 | sKillDetail = SKM_UI_STRINGS.Small_Target_Honor..SKM_Config.Col_HonorKill..iHonorKill.." "; |
||
4668 | --local FrameColor; |
||
4669 | local LabelColor; |
||
4670 | if (iRemaining == 0) then |
||
4671 | |||
4672 | sKillDetail = sKillDetail..SKM_Config.Col_Label.."( "..SKM_Config.Col_Honorless..SKM_UI_STRINGS.Small_Target_NoHonor..SKM_Config.Col_Label.." )"; |
||
4673 | --FrameColor = { r = 0.0, g = 0.0, b = 0.0 }; |
||
4674 | LabelColor = SKM_Config.Col_LabelTitle; |
||
4675 | else |
||
4676 | sKillDetail = sKillDetail..SKM_Config.Col_Label.."( "..SKM_Config.Col_HonorKill..iRemaining..SKM_Config.Col_Label.." )"; |
||
4677 | --FrameColor = { r = 0.3, g = 1.0, b = 1.0 }; |
||
4678 | LabelColor = SKM_Config.Col_HonorKill; |
||
4679 | end |
||
4680 | |||
4681 | local sDeath = SKM_Config.Col_PlayerDeath .. iDeath; |
||
4682 | local sMet = SKM_Config.Col_PlayerMet .. iMet; |
||
4683 | |||
4684 | local sWar1 = ""; |
||
4685 | local sWar2 = ""; |
||
4686 | |||
4687 | if (Enemy[_SKM._atWar] == true) then |
||
4688 | sWar1 = SKM_Config.Col_PlayerWar.. SKM_UI_STRINGS.Small_Target_War; |
||
4689 | sWar2 = ""; |
||
4690 | if (Enemy[_SKM._warDate]) then |
||
4691 | local sDisplayDate = string.sub(Enemy[_SKM._warDate], 1, 10); |
||
4692 | sWar2 = SKM_Config.Col_PlayerWar .. SKM_UI_STRINGS.Since .. sDisplayDate; |
||
4693 | end |
||
4694 | end |
||
4695 | |||
4696 | local bRes1, bRes2, bRes3, bRes4; |
||
4697 | |||
4698 | if (SkM_GetOption("SmallTargetInfo")) then |
||
4699 | bRes1 = SkM_SetSmallTargetInfoText(1, LabelColor..SKM_UI_STRINGS.Small_Target_Info_Kill, sKill); |
||
4700 | bRes2 = SkM_SetSmallTargetInfoText(2, SKM_UI_STRINGS.Small_Target_Info_Death, sDeath); |
||
4701 | bRes3 = SkM_SetSmallTargetInfoText(3, SKM_UI_STRINGS.Small_Target_Info_Met, sMet); |
||
4702 | bRes4 = SkM_SetSmallTargetInfoText(4, sWar1); |
||
4703 | else |
||
4704 | bRes1 = SkM_SetTargetInfoText(1, SKM_UI_STRINGS.Small_Target_Info_Kill, sKill, sKillDetail); |
||
4705 | bRes2 = SkM_SetTargetInfoText(2, SKM_UI_STRINGS.Small_Target_Info_Death, sDeath, ""); |
||
4706 | bRes3 = SkM_SetTargetInfoText(3, SKM_UI_STRINGS.Small_Target_Info_Met, sMet, ""); |
||
4707 | bRes4 = SkM_SetTargetInfoText(4, sWar1, "", sWar2); |
||
4708 | end |
||
4709 | |||
4710 | SkM_ShowTargetFrameWarButtons(Enemy[_SKM._atWar]); |
||
4711 | |||
4712 | SkM_SetWarDragon(bWar, bGuildWar); |
||
4713 | |||
4714 | if (bRes1 and bRes2 and bRes3 and bRes4) then |
||
4715 | SkM_ShowTargetInfoFrame(); |
||
4716 | return true; |
||
4717 | else |
||
4718 | SkM_HideTargetInfoFrame(); |
||
4719 | return false; |
||
4720 | end |
||
4721 | |||
4722 | else |
||
4723 | SkM_HideTargetInfoFrame(); |
||
4724 | SkM_SetWarDragon(false, false); |
||
4725 | |||
4726 | if (UnitIsPlayer(SKM_UNIT_TARGET)) then |
||
4727 | local sGuildName = GetGuildInfo(SKM_UNIT_TARGET); |
||
4728 | SkM_ShowTargetGuildInfo(true, sGuildName, false); |
||
4729 | SkM_ShowTargetClassInfo(true, sClass); |
||
4730 | else |
||
4731 | SkM_ShowTargetGuildInfo(false, nil, nil); |
||
4732 | SkM_ShowTargetClassInfo(false, nil); |
||
4733 | end |
||
4734 | |||
4735 | |||
4736 | |||
4737 | -- if we switch from a player dragon to an elite mob, we must keep the "elite" frame ! |
||
4738 | --if (UnitIsPlusMob(SKM_UNIT_TARGET)) then |
||
4739 | local sUnitClassification = UnitClassification(SKM_UNIT_TARGET); |
||
4740 | if (UnitIsPlusMob(SKM_UNIT_TARGET)) |
||
4741 | or ( (sUnitClassification ~= nil) and (sUnitClassification ~= "") and (sUnitClassification ~= "normal") ) |
||
4742 | then |
||
4743 | TargetFrameTexture:SetTexture("Interface\\TargetingFrame\\UI-TargetingFrame-Elite"); |
||
4744 | end |
||
4745 | |||
4746 | return false; |
||
4747 | end |
||
4748 | |||
4749 | end |
||
4750 | |||
4751 | |||
4752 | -- -------------------------------------------------------------------------------------- |
||
4753 | -- SkM_SetWarDragon |
||
4754 | -- -------------------------------------------------------------------------------------- |
||
4755 | -- Display or hide the red "elite dragon" around target portrait. |
||
4756 | -- If this enemy or his guild is set "at war", then the dragon is shown |
||
4757 | -- Otherwise, color is reset and the "elite dragon" is hidden |
||
4758 | -- -------------------------------------------------------------------------------------- |
||
4759 | function SkM_SetWarDragon(bWar, bGuildWar) |
||
4760 | local FName = "SkM_SetWarDragon"; |
||
4761 | |||
4762 | if (bWar) or (bGuildWar) then |
||
4763 | --Set Red Dragon Overlay on Texture to Target |
||
4764 | TargetFrameTexture:SetVertexColor(1.0, 200.0, 1.0, TargetFrameTexture:GetAlpha()); |
||
4765 | TargetFrameTexture:SetTexture("Interface\\TargetingFrame\\UI-TargetingFrame-Elite"); |
||
4766 | |||
4767 | else |
||
4768 | -- not at war with target |
||
4769 | TargetFrameTexture:SetVertexColor(1.0, 1.0, 1.0, TargetFrameTexture:GetAlpha()); |
||
4770 | TargetFrameTexture:SetTexture("Interface\\TargetingFrame\\UI-TargetingFrame"); |
||
4771 | end |
||
4772 | end |
||
4773 | |||
4774 | |||
4775 | -- -------------------------------------------------------------------------------------- |
||
4776 | -- SkM_EnemyWar |
||
4777 | -- -------------------------------------------------------------------------------------- |
||
4778 | -- Declare war to an enemy player, or call a truce with this player |
||
4779 | -- -------------------------------------------------------------------------------------- |
||
4780 | function SkM_EnemyWar(bWar, sEnemyName) |
||
4781 | local FName = "SkM_EnemyWar"; |
||
4782 | |||
4783 | SkM_Trace(FName, 3, "War button pressed"); |
||
4784 | |||
4785 | local sName; |
||
4786 | if (sEnemyName) then |
||
4787 | sName = sEnemyName; |
||
4788 | else |
||
4789 | local sTargetName = SkM_UnitName(SKM_UNIT_TARGET); |
||
4790 | sName = sTargetName; |
||
4791 | end |
||
4792 | |||
4793 | if (not sName) then |
||
4794 | SkM_Trace(FName, 1, "No enemy specified"); |
||
4795 | return; |
||
4796 | end |
||
4797 | |||
4798 | local Enemy = SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName]; |
||
4799 | if (not Enemy) then |
||
4800 | SkM_Trace(FName, 1, "Enemy not found : "..snil(sName)); |
||
4801 | return; |
||
4802 | end |
||
4803 | |||
4804 | local sGuildName = Enemy[_SKM._guild]; |
||
4805 | local Guild; |
||
4806 | local bGuildWar = false; |
||
4807 | if (sGuildName) and (sGuildName ~= "") then |
||
4808 | Guild = SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName]; |
||
4809 | end |
||
4810 | if (Guild) and (Guild[_SKM._atWar]) then |
||
4811 | bGuildWar = true; |
||
4812 | end |
||
4813 | |||
4814 | local sDate = SkM_GetDate(); |
||
4815 | |||
4816 | SkM_UpdateEnemy_SetWar(sName, bWar, sDate); |
||
4817 | |||
4818 | SkM_ShowTargetFrameWarButtons(Enemy[_SKM._atWar]); |
||
4819 | |||
4820 | -- 09/04/2005 16:18:34 PIng: Update war info on target frame when status is changed |
||
4821 | local sWar1 = ""; |
||
4822 | local sWar2 = ""; |
||
4823 | |||
4824 | if (Enemy[_SKM._atWar] == true) then |
||
4825 | sWar1 = SKM_Config.Col_PlayerWar.. SKM_UI_STRINGS.Small_Target_War; |
||
4826 | sWar2 = ""; |
||
4827 | if (Enemy[_SKM._warDate]) then |
||
4828 | local sDisplayDate = string.sub(Enemy[_SKM._warDate], 1, 10); |
||
4829 | sWar2 = SKM_Config.Col_PlayerWar .. SKM_UI_STRINGS.Since .. sDisplayDate; |
||
4830 | end |
||
4831 | end |
||
4832 | |||
4833 | local bRes4; |
||
4834 | |||
4835 | if (SkM_GetOption("SmallTargetInfo")) then |
||
4836 | bRes4 = SkM_SetSmallTargetInfoText(4, sWar1); |
||
4837 | else |
||
4838 | bRes4 = SkM_SetTargetInfoText(4, sWar1, "", sWar2); |
||
4839 | end |
||
4840 | -- 09/04/2005 16:18:31 End of modification |
||
4841 | |||
4842 | if (sName == sTargetName) then |
||
4843 | SkM_SetWarDragon(bWar, bGuildWar); |
||
4844 | end |
||
4845 | end |
||
4846 | |||
4847 | |||
4848 | -- -------------------------------------------------------------------------------------- |
||
4849 | -- SkM_UnknownEnemyWar |
||
4850 | -- -------------------------------------------------------------------------------------- |
||
4851 | -- Declare war to an enemy player that can is potentially not known yet |
||
4852 | -- -------------------------------------------------------------------------------------- |
||
4853 | function SkM_UnknownEnemyWar(sName, bWar, bDisplay) |
||
4854 | local FName = "SkM_UnknownEnemyWar"; |
||
4855 | |||
4856 | |||
4857 | SkM_Trace(FName, 3, "Enemy player = "..snil(sName)); |
||
4858 | |||
4859 | local sDate = SkM_GetDate(); |
||
4860 | |||
4861 | if (sName) then |
||
4862 | local Enemy = SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName]; |
||
4863 | if (Enemy) then |
||
4864 | local bWarPrev = Enemy[_SKM._atWar]; |
||
4865 | SkM_UpdateEnemy_SetWar(sName, bWar, sDate); |
||
4866 | if (bDisplay) then |
||
4867 | if (bWar) and (not bWarPrev) then |
||
4868 | SkM_ChatMessageCol("Now at WAR with "..sName); |
||
4869 | elseif (not bWar) and (bWarPrev) then |
||
4870 | SkM_ChatMessageCol("No longer at WAR with "..sName); |
||
4871 | end |
||
4872 | end |
||
4873 | |||
4874 | -- update target info if needed |
||
4875 | SkM_SetTargetInfo(); |
||
4876 | |||
4877 | -- update interface enemy list if needed |
||
4878 | local bVisible, sFrame = SKMap_IsUIVisible(); |
||
4879 | |||
4880 | if (bVisible) and (sFrame == "SKMap_ListFrame") and (SKM_List_ActiveList == _SKM._players) then |
||
4881 | SKMap_ListFrame_UpdateList(); |
||
4882 | if (SKM_List_SelectedPlayer) then |
||
4883 | SKMap_ListFrame_ShowWarButton(bWar); |
||
4884 | end |
||
4885 | end |
||
4886 | if (SKM_List_ActiveList == _SKM._players) and (SKM_List_SelectedPlayer) then |
||
4887 | SKMap_ListFrame_SelectElement(SKM_List_SelectedPlayer); |
||
4888 | end |
||
4889 | |||
4890 | else |
||
4891 | -- unknown enemy |
||
4892 | if (bWar) then |
||
4893 | SKM_Data[_RealmName][_PlayerName].UnknownEnemy[sName] = 1; |
||
4894 | if (bDisplay) then |
||
4895 | SkM_ChatMessageCol("Now at WAR with "..sName.." (not yet known)"); |
||
4896 | end |
||
4897 | else |
||
4898 | if (SKM_Data[_RealmName][_PlayerName].UnknownEnemy[sName]) then |
||
4899 | SKM_Data[_RealmName][_PlayerName].UnknownEnemy[sName] = nil; |
||
4900 | if (bDisplay) then |
||
4901 | SkM_ChatMessageCol("No longer at WAR with "..sName.." (not yet known)"); |
||
4902 | end |
||
4903 | end |
||
4904 | end |
||
4905 | |||
4906 | end |
||
4907 | |||
4908 | end |
||
4909 | end |
||
4910 | |||
4911 | |||
4912 | function SkM_ShowUnknownEnemyWar() |
||
4913 | local sMsg = ""; |
||
4914 | local iCount = 0; |
||
4915 | |||
4916 | local idx, val; |
||
4917 | for idx, val in SKM_Data[_RealmName][_PlayerName].UnknownEnemy do |
||
4918 | sMsg = sMsg..idx.." "; |
||
4919 | iCount = iCount + 1; |
||
4920 | end |
||
4921 | |||
4922 | if (iCount == 0) then |
||
4923 | SkM_ChatMessageCol("Unknown players WAR list is empty"); |
||
4924 | else |
||
4925 | SkM_ChatMessageCol("Unknown players WAR list ("..iCount..") :"); |
||
4926 | SkM_ChatMessageCol(sMsg); |
||
4927 | end |
||
4928 | |||
4929 | end |
||
4930 | |||
4931 | |||
4932 | function SkM_ClearUnknownEnemyWar() |
||
4933 | SKM_Data[_RealmName][_PlayerName].UnknownEnemy = { }; |
||
4934 | SkM_ChatMessageCol("Unknown players WAR list cleared"); |
||
4935 | end |
||
4936 | |||
4937 | |||
4938 | function SkM_FindSharedEnemyWar(sName) |
||
4939 | local FName = "SkM_FindSharedEnemyWar"; |
||
4940 | |||
4941 | -- parse all characters of the same realm |
||
4942 | local idx_char, val_char; |
||
4943 | for idx_char, val_char in SKM_Data[_RealmName] do |
||
4944 | if (SKM_Data[_RealmName][idx_char].PlayerName == idx_char) then |
||
4945 | local Enemy = SKM_Data[_RealmName][idx_char].EnemyHistory[sName]; |
||
4946 | |||
4947 | -- if enemy known to this player, and set "at war", return him |
||
4948 | if (Enemy) and (Enemy[_SKM._atWar]) then |
||
4949 | return Enemy, idx_char; |
||
4950 | end |
||
4951 | end |
||
4952 | end |
||
4953 | |||
4954 | end |
||
4955 | |||
4956 | |||
4957 | -- -------------------------------------------------------------------------------------- |
||
4958 | -- SkM_MouseOverUnit |
||
4959 | -- -------------------------------------------------------------------------------------- |
||
4960 | -- Handle "mouseover unit" event. |
||
4961 | -- If that unit is an enemy player that is "at war", or whose guild is "at war" : |
||
4962 | -- Display floating message (if configured) |
||
4963 | -- Play warning sound (if configured) |
||
4964 | -- If unit is an unknown enemy and we have no current target, target him to store |
||
4965 | -- information, then clear target again. |
||
4966 | -- -------------------------------------------------------------------------------------- |
||
4967 | function SkM_MouseOverUnit() |
||
4968 | local FName = "SkM_MouseOverUnit"; |
||
4969 | |||
4970 | local sDate = SkM_GetDate(); |
||
4971 | |||
4972 | -- store information related to mouse-overed unit |
||
4973 | SkM_MouseOverUnitData(); |
||
4974 | |||
4975 | if (SkM_UnitIsEnemyPlayer(SKM_UNIT_MOUSEOVER)) then |
||
4976 | -- if (true) then |
||
4977 | -- Grab the name of who we've moused-over |
||
4978 | local sName = SkM_UnitName(SKM_UNIT_MOUSEOVER); |
||
4979 | --local sName = "Ledieu"; |
||
4980 | if (not sName) then |
||
4981 | return; |
||
4982 | end |
||
4983 | |||
4984 | local sGuildName = GetGuildInfo(SKM_UNIT_MOUSEOVER); |
||
4985 | |||
4986 | local bWar = false; |
||
4987 | local bGuildWar = false; |
||
4988 | local bSharedWar = false; |
||
4989 | |||
4990 | local Enemy = SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName]; |
||
4991 | local SharedEnemy, SharedChar; |
||
4992 | local Guild; |
||
4993 | |||
4994 | if (Enemy) and (Enemy[_SKM._atWar]) then |
||
4995 | bWar = true; |
||
4996 | end |
||
4997 | |||
4998 | if (sGuildName ~= nil) and (sGuildName ~= "") then |
||
4999 | Guild = SKM_Data[_RealmName][_PlayerName].GuildHistory[sGuildName]; |
||
5000 | if (Guild ~= nil) and (Guild[_SKM._atWar]) then |
||
5001 | bGuildWar = true; |
||
5002 | end |
||
5003 | end |
||
5004 | |||
5005 | if not (bWar or bGuildWar) then |
||
5006 | if (SkM_GetOption("SharedWarMode")) then |
||
5007 | SharedEnemy, SharedChar = SkM_FindSharedEnemyWar(sName); |
||
5008 | if (SharedEnemy) and (SharedEnemy[_SKM._atWar]) then |
||
5009 | bSharedWar = true; |
||
5010 | end |
||
5011 | end |
||
5012 | end |
||
5013 | |||
5014 | if (bWar) or (bGuildWar) or (bSharedWar) then |
||
5015 | local bFilter = false; |
||
5016 | |||
5017 | if (SkM_GetOption("WarEnableFilter")) then |
||
5018 | -- check against global "last warning date" |
||
5019 | if (SKM_Context.LastWarWarning) then |
||
5020 | local iDiffTime = SkM_DiffDate(sDate, SKM_Context.LastWarWarning); |
||
5021 | if (iDiffTime ~= nil) and (iDiffTime <= SkM_GetOption("WarFilterDelay")) then |
||
5022 | -- Filter out to reduce spam |
||
5023 | bFilter = true; |
||
5024 | end |
||
5025 | end |
||
5026 | |||
5027 | end |
||
5028 | |||
5029 | -- check against last warning for given enemy |
||
5030 | -- (independently of filter option) |
||
5031 | if (SkM_GetRecentWarWarning(sName)) then |
||
5032 | -- Filter out to reduce spam |
||
5033 | bFilter = true; |
||
5034 | end |
||
5035 | |||
5036 | if (not bFilter) then |
||
5037 | SKM_Context.LastWarWarning = sDate; |
||
5038 | SkM_AddRecentWarWarning(sName, sDate); |
||
5039 | |||
5040 | SkM_Trace(FName, 3, "Last War Warning = "..snil(SKM_Context.LastWarWarning)); |
||
5041 | |||
5042 | if (SkM_GetOption("WarSoundWarning")) then |
||
5043 | --PlaySound("AuctionWindowClose"); |
||
5044 | PlaySoundFile(SKM_Config.WarSoundFile); |
||
5045 | end |
||
5046 | |||
5047 | if (SkM_GetOption("WarFloatingMessage")) then |
||
5048 | local sWarMessage = ""; |
||
5049 | if (bWar) and (bGuildWar) then |
||
5050 | sWarMessage = sName.." / "..sGuildName; |
||
5051 | elseif (bWar) then |
||
5052 | sWarMessage = sName; |
||
5053 | elseif (bGuildWar) then |
||
5054 | sWarMessage = sGuildName; |
||
5055 | elseif (bSharedWar) then |
||
5056 | sWarMessage = sName..SKM_Config.Col_SharedWar.." ["..SharedChar.."]".."|r"; |
||
5057 | end |
||
5058 | UIErrorsFrame:AddMessage(SKM_UI_STRINGS.War_Floating_Message..sWarMessage, 1.0, 0.0, 0.0, 1.0, UIERRORS_HOLD_TIME); |
||
5059 | end |
||
5060 | |||
5061 | if (SkM_GetOption("WarChatMessage")) then |
||
5062 | local sWarMessage = ""; |
||
5063 | if (bWar) and (bGuildWar) then |
||
5064 | sWarMessage = sName.." / "..sGuildName; |
||
5065 | elseif (bWar) then |
||
5066 | sWarMessage = sName; |
||
5067 | elseif (bGuildWar) then |
||
5068 | sWarMessage = sGuildName; |
||
5069 | elseif (bSharedWar) then |
||
5070 | sWarMessage = sName..SKM_Config.Col_SharedWar.." ["..SharedChar.."]".."|r"; |
||
5071 | end |
||
5072 | if (SkM_GetOption("WarShowNote")) then |
||
5073 | if (not bSharedWar) then |
||
5074 | if (Enemy) and (Enemy[_SKM._playerNote] ~= nil) and (Enemy[_SKM._playerNote] ~= "") then |
||
5075 | sWarMessage = sWarMessage .. SKM_Config.Col_Label.." - " .. SKM_Config.Col_PlayerNote.. Enemy[_SKM._playerNote]; |
||
5076 | end |
||
5077 | else |
||
5078 | if (SharedEnemy) and (SharedEnemy[_SKM._playerNote]) and (SharedEnemy[_SKM._playerNote] ~= "") then |
||
5079 | sWarMessage = sWarMessage .. SKM_Config.Col_Label.." - " .. SKM_Config.Col_PlayerNote .. SharedEnemy[_SKM._playerNote]; |
||
5080 | end |
||
5081 | end |
||
5082 | end |
||
5083 | SkM_PrintMessage(SKM_UI_STRINGS.War_Floating_Message..sWarMessage, 1.0, 0.0, 0.0); |
||
5084 | end |
||
5085 | |||
5086 | end |
||
5087 | |||
5088 | if (SkM_GetOption("WarAutoTarget") and (not UnitName(SKM_UNIT_TARGET))) then |
||
5089 | TargetByName(sName); |
||
5090 | end |
||
5091 | end |
||
5092 | |||
5093 | -- Add information to tooltip (if option enabled) |
||
5094 | if (SkM_GetOption("TooltipTargetInfo")) then |
||
5095 | SKMap_TooltipEnemyInfo(sName); |
||
5096 | end |
||
5097 | |||
5098 | -- Add player note to tooltip (if option enabled) |
||
5099 | if (SkM_GetOption("TooltipPlayerNote")) then |
||
5100 | SKMap_TooltipEnemyNote(sName); |
||
5101 | end |
||
5102 | |||
5103 | end |
||
5104 | |||
5105 | --if (SkM_GetOption("TooltipTargetInfo")) then |
||
5106 | -- SKMap_TooltipEnemyInfo("Ledieu"); |
||
5107 | --end |
||
5108 | --if (SkM_GetOption("TooltipPlayerNote")) then |
||
5109 | -- SKMap_TooltipEnemyNote("Ledieu"); |
||
5110 | --end |
||
5111 | |||
5112 | |||
5113 | end |
||
5114 | |||
5115 | |||
5116 | -- -------------------------------------------------------------------------------------- |
||
5117 | -- SkM_ShowTargetInfoFrame |
||
5118 | -- -------------------------------------------------------------------------------------- |
||
5119 | -- Show one of the SKMap TargetInfo frames (small or normal), and hide the other. |
||
5120 | -- -------------------------------------------------------------------------------------- |
||
5121 | function SkM_ShowTargetInfoFrame() |
||
5122 | local FName = "SkM_ShowTargetInfoFrame"; |
||
5123 | |||
5124 | local bShow = SkM_GetOption("ShowTargetInfo"); |
||
5125 | |||
5126 | if (SkM_GetOption("SmallTargetInfo")) then |
||
5127 | SkM_DisplayTargetInfoFrames(false, bShow); |
||
5128 | else |
||
5129 | SkM_DisplayTargetInfoFrames(bShow, false); |
||
5130 | end |
||
5131 | end |
||
5132 | |||
5133 | |||
5134 | -- -------------------------------------------------------------------------------------- |
||
5135 | -- SkM_HideTargetInfoFrame |
||
5136 | -- -------------------------------------------------------------------------------------- |
||
5137 | -- Hide both SKMap TargetInfo frames. |
||
5138 | -- -------------------------------------------------------------------------------------- |
||
5139 | function SkM_HideTargetInfoFrame() |
||
5140 | local FName = "SkM_HideTargetInfoFrame"; |
||
5141 | |||
5142 | SkM_DisplayTargetInfoFrames(false, false); |
||
5143 | end |
||
5144 | |||
5145 | |||
5146 | -- -------------------------------------------------------------------------------------- |
||
5147 | -- SkM_ShowTargetFrameWarButtons |
||
5148 | -- -------------------------------------------------------------------------------------- |
||
5149 | -- Show/hide war and truce button on the currently active SKMap TargetInfo frame, |
||
5150 | -- according to war status. |
||
5151 | -- -------------------------------------------------------------------------------------- |
||
5152 | function SkM_ShowTargetFrameWarButtons(bWar) |
||
5153 | local FName = "SkM_ShowTargetFrameWarButtons"; |
||
5154 | |||
5155 | if (SkM_GetOption("SmallTargetInfo")) then |
||
5156 | if (bWar == true) then |
||
5157 | SKMapSmallPvPTruceButton:Show(); |
||
5158 | SKMapSmallPvPWarButton:Hide(); |
||
5159 | else |
||
5160 | |||
5161 | SKMapSmallPvPTruceButton:Hide(); |
||
5162 | SKMapSmallPvPWarButton:Show(); |
||
5163 | end |
||
5164 | |||
5165 | else |
||
5166 | if (bWar == true) then |
||
5167 | SKMapPvPTruceButton:Show(); |
||
5168 | SKMapPvPWarButton:Hide(); |
||
5169 | else |
||
5170 | SKMapPvPTruceButton:Hide(); |
||
5171 | SKMapPvPWarButton:Show(); |
||
5172 | end |
||
5173 | end |
||
5174 | |||
5175 | end |
||
5176 | |||
5177 | |||
5178 | -- -------------------------------------------------------------------------------------- |
||
5179 | -- SkM_DisplayTargetInfoFrames |
||
5180 | -- -------------------------------------------------------------------------------------- |
||
5181 | -- Show or Hide the large or small target info frame |
||
5182 | -- -------------------------------------------------------------------------------------- |
||
5183 | function SkM_DisplayTargetInfoFrames(bLarge, bSmall) |
||
5184 | local FName = "SkM_DisplayTargetInfoFrames"; |
||
5185 | |||
5186 | if (bLarge == true) then |
||
5187 | SKMapTargetInfoFrame:Show(); |
||
5188 | elseif (bLarge == false) then |
||
5189 | SKMapTargetInfoFrame:Hide(); |
||
5190 | end |
||
5191 | |||
5192 | if (bSmall == true) then |
||
5193 | SKMapSmallTargetInfoFrame:Show(); |
||
5194 | elseif (bSmall == false) then |
||
5195 | SKMapSmallTargetInfoFrame:Hide(); |
||
5196 | end |
||
5197 | |||
5198 | end |
||
5199 | |||
5200 | |||
5201 | -- -------------------------------------------------------------------------------------- |
||
5202 | -- SkM_TargetInfoResize |
||
5203 | -- -------------------------------------------------------------------------------------- |
||
5204 | -- Switch from one size of the SKMap TargetInfo frame to the other |
||
5205 | -- -------------------------------------------------------------------------------------- |
||
5206 | function SkM_TargetInfoResize() |
||
5207 | local FName = "SkM_TargetInfoResize"; |
||
5208 | |||
5209 | SkM_SetOption("SmallTargetInfo", not (SkM_GetOption("SmallTargetInfo")) ); |
||
5210 | |||
5211 | SkM_SetTargetInfo(); |
||
5212 | end |
||
5213 | |||
5214 | |||
5215 | -- -------------------------------------------------------------------------------------- |
||
5216 | -- SkM_StoreTargetInfo |
||
5217 | -- -------------------------------------------------------------------------------------- |
||
5218 | -- Store currently targetted creature information. |
||
5219 | -- Remember if it's tapped and by who. |
||
5220 | -- -------------------------------------------------------------------------------------- |
||
5221 | function SkM_StoreTargetInfo(sTargetType) |
||
5222 | local sName = SkM_UnitName(SKM_UNIT_TARGET); |
||
5223 | |||
5224 | if (not sName) then |
||
5225 | SKM_Context.TargetInfo = nil; |
||
5226 | else |
||
5227 | if (not SKM_Context.TargetInfo) or (SKM_Context.TargetInfo[_SKM._name] ~= sName) then |
||
5228 | SKM_Context.TargetInfo = { }; |
||
5229 | SKM_Context.TargetInfo[_SKM._name] = sName; |
||
5230 | end |
||
5231 | |||
5232 | SKM_Context.TargetInfo[_SKM._type] = sTargetType; |
||
5233 | |||
5234 | if (sTargetType == _SKM._enemyCreature) then |
||
5235 | |||
5236 | if (UnitIsTapped(SKM_UNIT_TARGET)) then |
||
5237 | if (UnitIsTappedByPlayer(SKM_UNIT_TARGET)) then |
||
5238 | SKM_Context.TargetInfo[_SKM._owner] = _SKM._player; |
||
5239 | else |
||
5240 | SKM_Context.TargetInfo[_SKM._owner] = _SKM._other; |
||
5241 | end |
||
5242 | end |
||
5243 | |||
5244 | end |
||
5245 | |||
5246 | end |
||
5247 | end |
||
5248 | |||
5249 | |||
5250 | -- -------------------------------------------------------------------------------------- |
||
5251 | -- SkM_TargetHealthUpdated |
||
5252 | -- -------------------------------------------------------------------------------------- |
||
5253 | -- Target unit health has changed. |
||
5254 | -- If this is a creature and if it just died, record creature kill if need be. |
||
5255 | -- If this is a creature and it's still alive, update information. |
||
5256 | -- -------------------------------------------------------------------------------------- |
||
5257 | function SkM_TargetHealthUpdated() |
||
5258 | local FName = "SkM_TargetHealthUpdated"; |
||
5259 | |||
5260 | local sName = SkM_UnitName(SKM_UNIT_TARGET); |
||
5261 | if (not sName) then |
||
5262 | return; |
||
5263 | end |
||
5264 | |||
5265 | if (UnitHealth(SKM_UNIT_TARGET) == 0 or UnitIsCorpse(SKM_UNIT_TARGET) or UnitIsDeadOrGhost(SKM_UNIT_TARGET)) then |
||
5266 | |||
5267 | -- we use this event to track pve kills for unit currently targetted |
||
5268 | -- (player kills are tracked by damage done) |
||
5269 | |||
5270 | if (not UnitIsPlayer(SKM_UNIT_TARGET)) then |
||
5271 | |||
5272 | -- award kill to player if : we have previously stored the creature information |
||
5273 | -- in context, and if it was tapped by player |
||
5274 | -- in all cases, clear target info. |
||
5275 | if (SKM_Context.TargetInfo) and (SKM_Context.TargetInfo[_SKM._name] == sName) then |
||
5276 | |||
5277 | if (SKM_Context.TargetInfo[_SKM._owner] == _SKM._player) then |
||
5278 | |||
5279 | SkM_Trace(FName, 3, "Target creature (".. sName ..") kill detected - by player"); |
||
5280 | |||
5281 | local iLevel = UnitLevel(SKM_UNIT_TARGET); |
||
5282 | local bElite = UnitIsPlusMob(SKM_UNIT_TARGET); |
||
5283 | local sClassification = UnitClassification(SKM_UNIT_TARGET); |
||
5284 | |||
5285 | SkM_RecordCreatureKill_Target(sName, iLevel, sClassification); |
||
5286 | else |
||
5287 | SkM_Trace(FName, 3, "Target creature (".. sName ..") kill detected, but by other"); |
||
5288 | end |
||
5289 | end |
||
5290 | |||
5291 | elseif (SkM_UnitIsEnemyPlayer(SKM_UNIT_TARGET)) then |
||
5292 | SkM_Trace(FName, 2, "Enemy player death detected (from target) : "..snil(sName)); |
||
5293 | SkM_PvpEnemyDeath(sName); |
||
5294 | end |
||
5295 | |||
5296 | SKM_Context.TargetInfo = nil; |
||
5297 | |||
5298 | else |
||
5299 | -- unit is alive |
||
5300 | if (not UnitIsPlayer(SKM_UNIT_TARGET)) then |
||
5301 | -- not a player, update owner information |
||
5302 | SkM_StoreTargetInfo(_SKM._enemyCreature); |
||
5303 | end |
||
5304 | end |
||
5305 | |||
5306 | end |
||
5307 | |||
5308 | |||
5309 | -- -------------------------------------------------------------------------------------- |
||
5310 | -- SkM_PlayerLevelUp |
||
5311 | -- -------------------------------------------------------------------------------------- |
||
5312 | -- Handle "player level up" event : record event, and store new level. |
||
5313 | -- -------------------------------------------------------------------------------------- |
||
5314 | function SkM_PlayerLevelUp() |
||
5315 | local FName = "SkM_PlayerLevelUp"; |
||
5316 | |||
5317 | local StoreInfo = { }; |
||
5318 | |||
5319 | StoreInfo[_SKM._type] = _SKM._levelUp; |
||
5320 | |||
5321 | local sDate1, sDate2 = SkM_GetDate(); |
||
5322 | StoreInfo[_SKM._date] = sDate1; |
||
5323 | --StoreInfo[_sortdate] = sDate2; |
||
5324 | |||
5325 | StoreInfo[_SKM._name] = _PlayerName; |
||
5326 | |||
5327 | local iNewLevel; |
||
5328 | if (SKM_Context.PlayerLevel) then |
||
5329 | iNewLevel = SKM_Context.PlayerLevel + 1; |
||
5330 | else |
||
5331 | iNewLevel = UnitLevel(SKM_UNIT_PLAYER) + 1; |
||
5332 | end |
||
5333 | StoreInfo[_SKM._level] = iNewLevel; |
||
5334 | SKM_Context.PlayerLevel = iNewLevel; |
||
5335 | |||
5336 | if (not SkM_AddMapData(StoreInfo)) then |
||
5337 | return; |
||
5338 | end |
||
5339 | |||
5340 | end |
||
5341 | |||
5342 | |||
5343 | -- -------------------------------------------------------------------------------------- |
||
5344 | -- SkM_CountGuildMembers |
||
5345 | -- -------------------------------------------------------------------------------------- |
||
5346 | -- Count number of members known for a given guild. |
||
5347 | -- -------------------------------------------------------------------------------------- |
||
5348 | function SkM_CountGuildMembers(sGuild, sRealm, sPlayer) |
||
5349 | local FName = "SkM_CountGuildMembers"; |
||
5350 | |||
5351 | local sRealmName = sRealm; |
||
5352 | local sPlayerName = sPlayer; |
||
5353 | |||
5354 | SkM_Trace(FName, 4, "Get member count for guild : "..snil(sGuild)); |
||
5355 | |||
5356 | if (sRealmName == nil) then |
||
5357 | sRealmName = _RealmName; |
||
5358 | end |
||
5359 | |||
5360 | if (sPlayerName == nil) then |
||
5361 | sPlayerName = _PlayerName; |
||
5362 | end |
||
5363 | |||
5364 | if (SKM_Data[sRealmName] == nil) then |
||
5365 | return nil; |
||
5366 | end |
||
5367 | if (SKM_Data[sRealmName][sPlayerName] == nil) then |
||
5368 | return nil; |
||
5369 | end |
||
5370 | |||
5371 | local iCount = 0; |
||
5372 | |||
5373 | for idx, val in SKM_Data[sRealmName][sPlayerName].EnemyHistory do |
||
5374 | local sName = val[_SKM._name]; |
||
5375 | if (sName) then |
||
5376 | if (val[_SKM._guild] == sGuild) then |
||
5377 | iCount = iCount + 1; |
||
5378 | end |
||
5379 | end |
||
5380 | end |
||
5381 | |||
5382 | return iCount; |
||
5383 | end |
||
5384 | |||
5385 | |||
5386 | -- -------------------------------------------------------------------------------------- |
||
5387 | -- SkM_ComputeStatistics |
||
5388 | -- -------------------------------------------------------------------------------------- |
||
5389 | -- Compute various statistics that will be used in the report frame. |
||
5390 | -- -------------------------------------------------------------------------------------- |
||
5391 | function SkM_ComputeStatistics() |
||
5392 | local FName = "SkM_ComputeStatistics"; |
||
5393 | |||
5394 | SKM_Context.Statistics = { }; |
||
5395 | |||
5396 | SKM_Context.Statistics.Globals = { }; |
||
5397 | SKM_Context.Statistics.Race = { }; |
||
5398 | SKM_Context.Statistics.Class = { }; |
||
5399 | SKM_Context.Statistics.Zone = { }; |
||
5400 | SKM_Context.Statistics.Date = { }; |
||
5401 | SKM_Context.Statistics.Enemy = { }; |
||
5402 | SKM_Context.Statistics.Guild = { }; |
||
5403 | |||
5404 | SKM_Context.Statistics.BGZone = { }; |
||
5405 | SKM_Context.Statistics.BGDate = { }; |
||
5406 | SKM_Context.Statistics.BGDateZone = { }; |
||
5407 | |||
5408 | local iDeathForLevel = 0; |
||
5409 | local iKillForLevel = 0; |
||
5410 | local iTotalLevelDeath = 0; |
||
5411 | local iTotalLevelKill = 0; |
||
5412 | |||
5413 | -- compute : global, by race, by class, by enemy |
||
5414 | -- statistics from EnemyHistory map |
||
5415 | for idx, val in SKM_Data[_RealmName][_PlayerName].EnemyHistory do |
||
5416 | |||
5417 | SKM_Context.Statistics.Globals.EnemyPlayers = ifnil(SKM_Context.Statistics.Globals.EnemyPlayers, 0) + 1; |
||
5418 | |||
5419 | local iDeath = ifnil(val[_SKM._enemyKillPlayer], 0); |
||
5420 | --local iKill = ifnil(val[_SKM._playerAssistKill], 0) + ifnil(val[_SKM._playerKill], 0) + ifnil(val[_SKM._playerFullKill], 0); |
||
5421 | local iKill = ifnil(val[_SKM._playerKill], 0) + ifnil(val[_SKM._playerFullKill], 0); |
||
5422 | if (SkM_GetOption("AssistKillStat")) then |
||
5423 | iKill = iKill + ifnil(val[_SKM._playerAssistKill], 0) |
||
5424 | end |
||
5425 | |||
5426 | |||
5427 | SKM_Context.Statistics.Globals.Death = ifnil(SKM_Context.Statistics.Globals.Death, 0) + iDeath; |
||
5428 | SKM_Context.Statistics.Globals.Kill = ifnil(SKM_Context.Statistics.Globals.Kill, 0) + iKill; |
||
5429 | |||
5430 | -- for computing averages |
||
5431 | if (val[_SKM._level]) and (val[_SKM._level] ~= -1) then |
||
5432 | iDeathForLevel = iDeathForLevel + iDeath; |
||
5433 | iKillForLevel = iKillForLevel + iKill; |
||
5434 | iTotalLevelDeath = iTotalLevelDeath + ( val[_SKM._level] * iDeath ); |
||
5435 | iTotalLevelKill = iTotalLevelKill + ( val[_SKM._level] * iKill ); |
||
5436 | end |
||
5437 | |||
5438 | local sRace = SkM_GetRaceText(val[_SKM._race]); |
||
5439 | if (sRace) then |
||
5440 | if (SKM_Context.Statistics.Race[sRace] == nil) then |
||
5441 | SKM_Context.Statistics.Race[sRace] = { }; |
||
5442 | end |
||
5443 | SKM_Context.Statistics.Race[sRace].Death = ifnil(SKM_Context.Statistics.Race[sRace].Death, 0) + iDeath; |
||
5444 | SKM_Context.Statistics.Race[sRace].Kill = ifnil(SKM_Context.Statistics.Race[sRace].Kill, 0) + iKill; |
||
5445 | end |
||
5446 | |||
5447 | local sClass = SkM_GetClassText(val[_SKM._class]); |
||
5448 | if (sClass) then |
||
5449 | if (SKM_Context.Statistics.Class[sClass] == nil) then |
||
5450 | SKM_Context.Statistics.Class[sClass] = { }; |
||
5451 | end |
||
5452 | SKM_Context.Statistics.Class[sClass].Death = ifnil(SKM_Context.Statistics.Class[sClass].Death, 0) + iDeath; |
||
5453 | SKM_Context.Statistics.Class[sClass].Kill = ifnil(SKM_Context.Statistics.Class[sClass].Kill, 0) + iKill; |
||
5454 | end |
||
5455 | |||
5456 | sEnemyName = val[_SKM._name]; |
||
5457 | if (sEnemyName) and ( (iDeath > 0) or (iKill > 0) ) then |
||
5458 | SKM_Context.Statistics.Enemy[sEnemyName] = { }; |
||
5459 | SKM_Context.Statistics.Enemy[sEnemyName].Death = iDeath; |
||
5460 | SKM_Context.Statistics.Enemy[sEnemyName].Kill = iKill; |
||
5461 | end |
||
5462 | |||
5463 | end |
||
5464 | |||
5465 | |||
5466 | -- compute : global, by race, by class, by enemy |
||
5467 | -- statistics from EnemyHistory map |
||
5468 | for idx, val in SKM_Data[_RealmName][_PlayerName].GuildHistory do |
||
5469 | --for idx, val in SkM_GetPlayerData("GuildHistory") do |
||
5470 | |||
5471 | SKM_Context.Statistics.Globals.EnemyGuilds = ifnil(SKM_Context.Statistics.Globals.EnemyGuilds, 0) + 1; |
||
5472 | |||
5473 | local iDeath = ifnil(val[_SKM._enemyKillPlayer], 0); |
||
5474 | local iKill = ifnil(val[_SKM._playerAssistKill], 0) + ifnil(val[_SKM._playerKill], 0) + ifnil(val[_SKM._playerFullKill], 0); |
||
5475 | |||
5476 | local sGuildName = val[_SKM._name]; |
||
5477 | if (sGuildName) and ( (iDeath > 0) or (iKill > 0) ) then |
||
5478 | SKM_Context.Statistics.Guild[sGuildName] = { }; |
||
5479 | SKM_Context.Statistics.Guild[sGuildName].Death = iDeath; |
||
5480 | SKM_Context.Statistics.Guild[sGuildName].Kill = iKill; |
||
5481 | end |
||
5482 | end |
||
5483 | |||
5484 | |||
5485 | -- compute averages |
||
5486 | if (iDeathForLevel > 0) then |
||
5487 | SkM_Trace(FName, 3, "iDeathForLevel = "..iDeathForLevel..", iTotalLevelDeath = "..iTotalLevelDeath); |
||
5488 | SKM_Context.Statistics.Globals.DeathAverageLevel = math.floor (iTotalLevelDeath / iDeathForLevel); |
||
5489 | end |
||
5490 | if (iKillForLevel > 0) then |
||
5491 | SkM_Trace(FName, 3, "iKillForLevel = "..iKillForLevel..", iTotalLevelKill = "..iTotalLevelKill); |
||
5492 | SKM_Context.Statistics.Globals.KillAverageLevel = math.floor (iTotalLevelKill / iKillForLevel); |
||
5493 | end |
||
5494 | |||
5495 | SkM_Trace(FName, 3, "Average level of victims : "..snil(SKM_Context.Statistics.Globals.KillAverageLevel)); |
||
5496 | SkM_Trace(FName, 3, "Average level of executioners : "..snil(SKM_Context.Statistics.Globals.DeathAverageLevel)); |
||
5497 | |||
5498 | |||
5499 | -- compute : by zone, by date |
||
5500 | -- statistics from GlobalMapData map |
||
5501 | local i; |
||
5502 | local iNbNotes = getn(SKM_Data[_RealmName][_PlayerName].GlobalMapData); |
||
5503 | |||
5504 | SKM_Context.Statistics.Globals.MapRecords = iNbNotes; |
||
5505 | |||
5506 | SkM_Trace(FName, 3, "Global notes count = "..iNbNotes); |
||
5507 | for i=1, iNbNotes, 1 do |
||
5508 | local Note = SKM_Data[_RealmName][_PlayerName].GlobalMapData[i]; |
||
5509 | |||
5510 | local StoredInfo = Note[_SKM._storedInfo]; |
||
5511 | if (StoredInfo) then |
||
5512 | |||
5513 | local iKill = 0; |
||
5514 | local iDeath = 0; |
||
5515 | |||
5516 | -- if (StoredInfo[_SKM._type] == _SKM._playerAssistKill) |
||
5517 | if (StoredInfo[_SKM._type] == _SKM._playerAssistKill) and (SkM_GetOption("AssistKillStat")) |
||
5518 | or (StoredInfo[_SKM._type] == _SKM._playerKill) |
||
5519 | or (StoredInfo[_SKM._type] == _SKM._playerFullKill) then |
||
5520 | iKill = 1; |
||
5521 | SkM_Trace(FName, 3, "PvP Kill : global note = "..i); |
||
5522 | |||
5523 | elseif (StoredInfo[_SKM._type] == _SKM._playerDeathPvP) then |
||
5524 | iDeath = 1; |
||
5525 | SkM_Trace(FName, 3, "PvP Death : global note = "..i); |
||
5526 | end |
||
5527 | |||
5528 | if (iKill > 0) or (iDeath > 0) then |
||
5529 | |||
5530 | --local sZoneText = SKM_Context.Zones[Note[_SKM._continent]][Note[_SKM._zone]]; |
||
5531 | local sZoneText = SkM_GetZoneTextFromIndex(Note[_SKM._continent], Note[_SKM._zone]); |
||
5532 | if (sZoneText) then |
||
5533 | if (SKM_Context.Statistics.Zone[sZoneText] == nil) then |
||
5534 | SKM_Context.Statistics.Zone[sZoneText] = { }; |
||
5535 | end |
||
5536 | SKM_Context.Statistics.Zone[sZoneText].Death = ifnil(SKM_Context.Statistics.Zone[sZoneText].Death, 0) + iDeath; |
||
5537 | SKM_Context.Statistics.Zone[sZoneText].Kill = ifnil(SKM_Context.Statistics.Zone[sZoneText].Kill, 0) + iKill; |
||
5538 | end |
||
5539 | |||
5540 | local sDate = string.sub(StoredInfo[_SKM._date], 1, 10); |
||
5541 | if (sDate) then |
||
5542 | if (SKM_Context.Statistics.Date[sDate] == nil) then |
||
5543 | SKM_Context.Statistics.Date[sDate] = { }; |
||
5544 | end |
||
5545 | SKM_Context.Statistics.Date[sDate].Death = ifnil(SKM_Context.Statistics.Date[sDate].Death, 0) + iDeath; |
||
5546 | SKM_Context.Statistics.Date[sDate].Kill = ifnil(SKM_Context.Statistics.Date[sDate].Kill, 0) + iKill; |
||
5547 | end |
||
5548 | |||
5549 | end |
||
5550 | end |
||
5551 | end |
||
5552 | |||
5553 | -- compute : battlegrounds by zone, by date, by date and zone |
||
5554 | for idx1, val1 in SKM_Data[_RealmName][_PlayerName].BGStats do |
||
5555 | local sZone = idx1; |
||
5556 | if (SKM_Context.Statistics.BGZone[sZone] == nil) then |
||
5557 | SKM_Context.Statistics.BGZone[sZone] = { }; |
||
5558 | end |
||
5559 | |||
5560 | for idx2, val2 in val1 do |
||
5561 | local sDate = idx2; |
||
5562 | local iDeath = ifnil(val2[_SKM._enemyKillBG], 0); |
||
5563 | local iKill = ifnil(val2[_SKM._playerBGKill], 0); |
||
5564 | |||
5565 | SKM_Context.Statistics.BGZone[sZone].Death = ifnil(SKM_Context.Statistics.BGZone[sZone].Death, 0) + iDeath; |
||
5566 | SKM_Context.Statistics.BGZone[sZone].Kill = ifnil(SKM_Context.Statistics.BGZone[sZone].Kill, 0) + iKill; |
||
5567 | |||
5568 | if (SKM_Context.Statistics.BGDate[sDate] == nil) then |
||
5569 | SKM_Context.Statistics.BGDate[sDate] = { }; |
||
5570 | end |
||
5571 | SKM_Context.Statistics.BGDate[sDate].Death = ifnil(SKM_Context.Statistics.BGDate[sDate].Death, 0) + iDeath; |
||
5572 | SKM_Context.Statistics.BGDate[sDate].Kill = ifnil(SKM_Context.Statistics.BGDate[sDate].Kill, 0) + iKill; |
||
5573 | |||
5574 | local sDateZone = idx2.." - "..idx1; |
||
5575 | if (SKM_Context.Statistics.BGDateZone[sDateZone] == nil) then |
||
5576 | SKM_Context.Statistics.BGDateZone[sDateZone] = { }; |
||
5577 | SKM_Context.Statistics.BGDateZone[sDateZone].Zone = idx1; |
||
5578 | SKM_Context.Statistics.BGDateZone[sDateZone].Date = idx2; |
||
5579 | end |
||
5580 | SKM_Context.Statistics.BGDateZone[sDateZone].Death = ifnil(SKM_Context.Statistics.BGDateZone[sDateZone].Death, 0) + iDeath; |
||
5581 | SKM_Context.Statistics.BGDateZone[sDateZone].Kill = ifnil(SKM_Context.Statistics.BGDateZone[sDateZone].Kill, 0) + iKill; |
||
5582 | end |
||
5583 | end |
||
5584 | |||
5585 | |||
5586 | |||
5587 | -- provide sortable lists |
||
5588 | SKM_Context.Statistics.ClassList = {}; |
||
5589 | for idx, val in SKM_Context.Statistics.Class do |
||
5590 | val.SortKey = idx; |
||
5591 | val.Key = idx; |
||
5592 | table.insert(SKM_Context.Statistics.ClassList, val); |
||
5593 | end |
||
5594 | table.sort(SKM_Context.Statistics.ClassList, SkM_SortStatList); |
||
5595 | |||
5596 | SKM_Context.Statistics.RaceList = {}; |
||
5597 | for idx, val in SKM_Context.Statistics.Race do |
||
5598 | val.SortKey = idx; |
||
5599 | val.Key = idx; |
||
5600 | table.insert(SKM_Context.Statistics.RaceList, val); |
||
5601 | end |
||
5602 | |||
5603 | table.sort(SKM_Context.Statistics.RaceList, SkM_SortStatList); |
||
5604 | |||
5605 | SKM_Context.Statistics.EnemyList = {}; |
||
5606 | for idx, val in SKM_Context.Statistics.Enemy do |
||
5607 | --val.SortKey = string.upper(idx); |
||
5608 | val.SortKey = SkM_NormalizeString(idx); |
||
5609 | val.Key = idx; |
||
5610 | table.insert(SKM_Context.Statistics.EnemyList, val); |
||
5611 | end |
||
5612 | table.sort(SKM_Context.Statistics.EnemyList, SkM_SortStatList); |
||
5613 | |||
5614 | SKM_Context.Statistics.GuildList = {}; |
||
5615 | for idx, val in SKM_Context.Statistics.Guild do |
||
5616 | --val.SortKey = string.upper(idx); |
||
5617 | val.SortKey = SkM_NormalizeString(idx); |
||
5618 | val.Key = idx; |
||
5619 | table.insert(SKM_Context.Statistics.GuildList, val); |
||
5620 | end |
||
5621 | table.sort(SKM_Context.Statistics.GuildList, SkM_SortStatList); |
||
5622 | |||
5623 | SKM_Context.Statistics.ZoneList = {}; |
||
5624 | for idx, val in SKM_Context.Statistics.Zone do |
||
5625 | val.SortKey = idx; |
||
5626 | val.Key = idx; |
||
5627 | table.insert(SKM_Context.Statistics.ZoneList, val); |
||
5628 | end |
||
5629 | table.sort(SKM_Context.Statistics.ZoneList, SkM_SortStatList); |
||
5630 | |||
5631 | SKM_Context.Statistics.DateList = {}; |
||
5632 | for idx, val in SKM_Context.Statistics.Date do |
||
5633 | val.SortKey = SkM_GetSortableDate(idx); |
||
5634 | val.Key = idx; |
||
5635 | table.insert(SKM_Context.Statistics.DateList, val); |
||
5636 | end |
||
5637 | table.sort(SKM_Context.Statistics.DateList, SkM_SortStatList); |
||
5638 | |||
5639 | SKM_Context.Statistics.BGDateList = {}; |
||
5640 | for idx, val in SKM_Context.Statistics.BGDate do |
||
5641 | val.SortKey = SkM_GetSortableDate(idx); |
||
5642 | val.Key = idx; |
||
5643 | table.insert(SKM_Context.Statistics.BGDateList, val); |
||
5644 | end |
||
5645 | table.sort(SKM_Context.Statistics.BGDateList, SkM_SortStatList); |
||
5646 | |||
5647 | SKM_Context.Statistics.BGZoneList = {}; |
||
5648 | for idx, val in SKM_Context.Statistics.BGZone do |
||
5649 | val.SortKey = idx; |
||
5650 | val.Key = idx; |
||
5651 | table.insert(SKM_Context.Statistics.BGZoneList, val); |
||
5652 | end |
||
5653 | table.sort(SKM_Context.Statistics.BGZoneList, SkM_SortStatList); |
||
5654 | |||
5655 | SKM_Context.Statistics.BGDateZoneList = {}; |
||
5656 | for idx, val in SKM_Context.Statistics.BGDateZone do |
||
5657 | val.SortKey = SkM_GetSortableDate(val.Date)..val.Zone; |
||
5658 | val.Key = idx; |
||
5659 | table.insert(SKM_Context.Statistics.BGDateZoneList, val); |
||
5660 | end |
||
5661 | table.sort(SKM_Context.Statistics.BGDateZoneList, SkM_SortStatList); |
||
5662 | |||
5663 | |||
5664 | end |
||
5665 | |||
5666 | |||
5667 | -- -------------------------------------------------------------------------------------- |
||
5668 | -- SkM_SortStatList |
||
5669 | -- -------------------------------------------------------------------------------------- |
||
5670 | -- Statistics sorting function |
||
5671 | -- -------------------------------------------------------------------------------------- |
||
5672 | function SkM_SortStatList(e1, e2) |
||
5673 | if (e1.SortKey < e2.SortKey) then |
||
5674 | return true; |
||
5675 | elseif (e2.SortKey < e1.SortKey) then |
||
5676 | return false; |
||
5677 | end |
||
5678 | return false; |
||
5679 | end |
||
5680 | |||
5681 | |||
5682 | -- -------------------------------------------------------------------------------------- |
||
5683 | -- SkM_GetUnitFaction |
||
5684 | -- -------------------------------------------------------------------------------------- |
||
5685 | -- Find player faction for a given unit |
||
5686 | -- -------------------------------------------------------------------------------------- |
||
5687 | function SkM_GetUnitFaction(sUnit) |
||
5688 | if (sUnit == nil) then |
||
5689 | return nil; |
||
5690 | end |
||
5691 | local sRace = UnitRace(sUnit); |
||
5692 | if (sRace == nil) then |
||
5693 | return nil; |
||
5694 | end |
||
5695 | local i; |
||
5696 | for i=1, getn(SKM_PlayerFaction), 1 do |
||
5697 | if ( intable(sRace, SKM_PlayerFaction[i].RaceList) ) then |
||
5698 | return i, SKM_PlayerFaction[i].Faction; |
||
5699 | end |
||
5700 | end |
||
5701 | return nil; |
||
5702 | end |
||
5703 | |||
5704 | |||
5705 | -- -------------------------------------------------------------------------------------- |
||
5706 | -- SkM_UnitIsEnemyPlayer |
||
5707 | -- -------------------------------------------------------------------------------------- |
||
5708 | -- Is unit an enemy player of the opposite faction ? |
||
5709 | -- -------------------------------------------------------------------------------------- |
||
5710 | function SkM_UnitIsEnemyPlayer(sUnit) |
||
5711 | if (sUnit == nil) then |
||
5712 | return nil; |
||
5713 | end |
||
5714 | return ( (UnitIsPlayer(sUnit)) |
||
5715 | and (UnitIsEnemy(SKM_UNIT_PLAYER, sUnit)) |
||
5716 | and (SkM_UnitIsOppositeFaction(SKM_UNIT_PLAYER, sUnit)) |
||
5717 | ); |
||
5718 | end |
||
5719 | |||
5720 | |||
5721 | -- -------------------------------------------------------------------------------------- |
||
5722 | -- SkM_UnitIsDuelingPlayer |
||
5723 | -- -------------------------------------------------------------------------------------- |
||
5724 | -- Is unit a player you are currently dueling ? |
||
5725 | -- ie, if he is a player, tagged as "enemy" but of your faction. |
||
5726 | -- -------------------------------------------------------------------------------------- |
||
5727 | function SkM_UnitIsDuelingPlayer(sUnit) |
||
5728 | if (sUnit == nil) then |
||
5729 | return nil; |
||
5730 | end |
||
5731 | return ( (UnitIsPlayer(sUnit)) |
||
5732 | and (UnitIsEnemy(SKM_UNIT_PLAYER, sUnit)) |
||
5733 | and (not SkM_UnitIsOppositeFaction(SKM_UNIT_PLAYER, sUnit)) |
||
5734 | ); |
||
5735 | end |
||
5736 | |||
5737 | |||
5738 | -- -------------------------------------------------------------------------------------- |
||
5739 | -- SkM_UnitIsOppositeFaction |
||
5740 | -- -------------------------------------------------------------------------------------- |
||
5741 | -- Check if two units are on opposite faction or not, using their race. |
||
5742 | -- Return true if it's the case, false if not, and nil if indeterminate |
||
5743 | -- -------------------------------------------------------------------------------------- |
||
5744 | function SkM_UnitIsOppositeFaction(sUnit1, sUnit2) |
||
5745 | local FName = "SkM_UnitIsOppositeFaction"; |
||
5746 | |||
5747 | local Faction1 = SkM_GetUnitFaction(sUnit1); |
||
5748 | local Faction2 = SkM_GetUnitFaction(sUnit2); |
||
5749 | |||
5750 | if (Faction1 == nil) then |
||
5751 | SkM_Trace(FName, 1, "Unknown faction for "..snil(sUnit1)); |
||
5752 | return nil; |
||
5753 | end |
||
5754 | if (Faction2 == nil) then |
||
5755 | SkM_Trace(FName, 1, "Unknown faction for "..snil(sUnit2)); |
||
5756 | return nil; |
||
5757 | end |
||
5758 | |||
5759 | if (Faction1 == Faction2) then |
||
5760 | return false; |
||
5761 | else |
||
5762 | return true; |
||
5763 | end |
||
5764 | |||
5765 | end |
||
5766 | |||
5767 | |||
5768 | -- -------------------------------------------------------------------------------------- |
||
5769 | -- SkM_DeleteEnemy |
||
5770 | -- -------------------------------------------------------------------------------------- |
||
5771 | -- Delete an enemy player and all associated map records (kills or deaths). |
||
5772 | -- -------------------------------------------------------------------------------------- |
||
5773 | function SkM_DeleteEnemy(sName) |
||
5774 | local FName = "SkM_DeleteEnemy"; |
||
5775 | |||
5776 | local Enemy = SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName]; |
||
5777 | |||
5778 | if (Enemy == nil) then |
||
5779 | SkM_Trace(FName, 1, "Enemy not found : "..snil(sName)); |
||
5780 | return; |
||
5781 | end |
||
5782 | |||
5783 | SkM_Trace(FName, 1, "Removing Enemy : "..sName); |
||
5784 | |||
5785 | SkM_UpdateEnemyHistory(); |
||
5786 | |||
5787 | -- remove all recorded events associated to this enemy : kills and deaths |
||
5788 | local i; |
||
5789 | local iNbNotes = table.getn(SKM_Data[_RealmName][_PlayerName].GlobalMapData); |
||
5790 | for i=iNbNotes, 1, -1 do |
||
5791 | local Note = SKM_Data[_RealmName][_PlayerName].GlobalMapData[i]; |
||
5792 | |||
5793 | local StoredInfo = Note[_SKM._storedInfo]; |
||
5794 | |||
5795 | if (StoredInfo) and (StoredInfo[_SKM._name] == sName) then |
||
5796 | |||
5797 | -- remove from GlobalMapData and from MapData |
||
5798 | SkM_Trace(FName, 3, "Removing note : global index = "..i); |
||
5799 | |||
5800 | SkM_DeleteNote(_RealmName, _PlayerName, i); |
||
5801 | end |
||
5802 | end |
||
5803 | |||
5804 | -- finally, delete the enemy. Bye bye ! |
||
5805 | SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName] = nil; |
||
5806 | end |
||
5807 | |||
5808 | |||
5809 | -- -------------------------------------------------------------------------------------- |
||
5810 | -- SkM_DeleteDuelEnemy |
||
5811 | -- -------------------------------------------------------------------------------------- |
||
5812 | -- Delete all duel information associated to a given player |
||
5813 | -- -------------------------------------------------------------------------------------- |
||
5814 | function SkM_DeleteDuelEnemy(sName) |
||
5815 | local FName = "SkM_DeleteDuelEnemy"; |
||
5816 | |||
5817 | SKM_Data[_RealmName][_PlayerName].DuelHistory[sName] = nil; |
||
5818 | end |
||
5819 | |||
5820 | |||
5821 | -- -------------------------------------------------------------------------------------- |
||
5822 | -- SkM_GetKnownEnemyType |
||
5823 | -- -------------------------------------------------------------------------------------- |
||
5824 | -- Return _SKM._enemyPlayer if given name matches a known player, otherwise return nil |
||
5825 | -- (ie, we do not know for now if it's a player or not, but we may get the information |
||
5826 | -- later on) |
||
5827 | -- -------------------------------------------------------------------------------------- |
||
5828 | function SkM_GetKnownEnemyType(sName) |
||
5829 | local EnemyType; |
||
5830 | local Enemy = SKM_Data[_RealmName][_PlayerName].EnemyHistory[sName]; |
||
5831 | if (Enemy) then |
||
5832 | EnemyType = _SKM._enemyPlayer; |
||
5833 | end |
||
5834 | return EnemyType; |
||
5835 | end |
||
5836 | |||
5837 | |||
5838 | -- -------------------------------------------------------------------------------------- |
||
5839 | -- SkM_UnitName |
||
5840 | -- -------------------------------------------------------------------------------------- |
||
5841 | -- Call UnitName to get unit name. |
||
5842 | -- Return nil if we get "Unknown Entity". |
||
5843 | -- -------------------------------------------------------------------------------------- |
||
5844 | function SkM_UnitName(sUnit) |
||
5845 | local sName = UnitName(sUnit); |
||
5846 | |||
5847 | -- if we got "unknown entity", try again, maybe it will work this time |
||
5848 | if (sName == SKM_UNKNOWN_ENTITY) then |
||
5849 | sName = UnitName(sUnit); |
||
5850 | end |
||
5851 | |||
5852 | if (sName == "") or (sName == SKM_UNKNOWN_ENTITY) then |
||
5853 | sName = nil; |
||
5854 | end |
||
5855 | return sName; |
||
5856 | end |
||
5857 | |||
5858 | |||
5859 | -- -------------------------------------------------------------------------------------- |
||
5860 | -- SkM_IsTotem |
||
5861 | -- -------------------------------------------------------------------------------------- |
||
5862 | -- Check if given name matches a totem (and *not* a player) |
||
5863 | -- -------------------------------------------------------------------------------------- |
||
5864 | function SkM_IsTotem(sName) |
||
5865 | local FName = "SkM_IsTotem"; |
||
5866 | |||
5867 | if (sName) then |
||
5868 | for sType in string.gfind(sName, SKM_Context.Pattern.Totem) do |
||
5869 | if (sType) then |
||
5870 | SkM_Trace(FName, 2, "Name = "..snil(sName).." : this is a totem. Type = "..sType); |
||
5871 | return true; |
||
5872 | end |
||
5873 | end |
||
5874 | end |
||
5875 | |||
5876 | SkM_Trace(FName, 3, "Name = "..snil(sName).." : not a totem"); |
||
5877 | return false; |
||
5878 | |||
5879 | -- if (string.find(sName, SKM_Context.Pattern.Totem)) then |
||
5880 | -- SkM_Trace(FName, 2, "Name = "..snil(sName).." : this is a totem"); |
||
5881 | -- return true; |
||
5882 | -- else |
||
5883 | -- SkM_Trace(FName, 3, "Name = "..snil(sName).." : not a totem"); |
||
5884 | -- return false; |
||
5885 | -- end |
||
5886 | |||
5887 | end |
||
5888 | |||
5889 | |||
5890 | function SkM_NormalizeString(sName) |
||
5891 | local FName = "SkM_NormalizeString"; |
||
5892 | |||
5893 | if (sName == nil) then |
||
5894 | return nil; |
||
5895 | end |
||
5896 | |||
5897 | local sString = string.upper(sName); |
||
5898 | i=1; |
||
5899 | while (string.sub(sString, i, i) == " ") and (i < string.len(sString)) do |
||
5900 | i = i + 1; |
||
5901 | end |
||
5902 | if (i > 1 ) then |
||
5903 | sString = string.sub(sString, i, string.len(sString)); |
||
5904 | end |
||
5905 | |||
5906 | sString = SkM_NormString(sString, 2); -- only need to normalize the first two chars to provide an accurate sort |
||
5907 | return sString; |
||
5908 | end |
||
5909 | |||
5910 | |||
5911 | function SkM_LogDuel(sWinner, sLoser) |
||
5912 | local FName = "SkM_LogDuel"; |
||
5913 | |||
5914 | local sName; |
||
5915 | local sDate = SkM_GetDate(); |
||
5916 | local bWin; |
||
5917 | |||
5918 | if (sWinner == _PlayerName) then |
||
5919 | sName = sLoser; |
||
5920 | bWin = true; |
||
5921 | else |
||
5922 | sName = sWinner; |
||
5923 | bWin = false; |
||
5924 | end |
||
5925 | |||
5926 | if (SKM_Context.DuelEnemy == nil) or (SKM_Context.DuelEnemy[_SKM._name] ~= sName) then |
||
5927 | -- rare case of a finished duel but we did not see at any time our enemy. |
||
5928 | -- okay, force target him then. |
||
5929 | -- I agree that messing with player target is a bad idea in most cases, but at the end |
||
5930 | -- of a duel it should not matter much. |
||
5931 | |||
5932 | SkM_Trace(FName, 2, "End of duel but no info about enemy "..snil(sName).." : force target"); |
||
5933 | |||
5934 | TargetByName(sName); |
||
5935 | SkM_StoreDuelEnemyInfo(SKM_UNIT_TARGET); |
||
5936 | |||
5937 | if (SKM_Context.DuelEnemy == nil) or (SKM_Context.DuelEnemy[_SKM._name] ~= sName) then |
||
5938 | -- might potentially happen if enemy is too far away. Even more unlikely, but |
||
5939 | -- just in case... |
||
5940 | SkM_Trace(FName, 1, "Still no info about enemy !"); |
||
5941 | SKM_Context.DuelEnemy = nil; |
||
5942 | return; |
||
5943 | end |
||
5944 | |||
5945 | end |
||
5946 | |||
5947 | if (not SKM_Data[_RealmName][_PlayerName].DuelHistory[sName]) then |
||
5948 | SKM_Data[_RealmName][_PlayerName].DuelHistory[sName] = { }; |
||
5949 | SKM_Data[_RealmName][_PlayerName].DuelHistory[sName][_SKM._name] = sName; |
||
5950 | |||
5951 | SKM_Data[_RealmName][_PlayerName].DuelHistory[sName][_SKM._race] = SKM_Context.DuelEnemy[_SKM._race]; |
||
5952 | SKM_Data[_RealmName][_PlayerName].DuelHistory[sName][_SKM._class] = SKM_Context.DuelEnemy[_SKM._class]; |
||
5953 | SKM_Data[_RealmName][_PlayerName].DuelHistory[sName][_SKM._win] = 0; |
||
5954 | SKM_Data[_RealmName][_PlayerName].DuelHistory[sName][_SKM._loss] = 0; |
||
5955 | SKM_Data[_RealmName][_PlayerName].DuelHistory[sName][_SKM._duel] = 0; |
||
5956 | else |
||
5957 | if (not SKM_Data[_RealmName][_PlayerName].DuelHistory[sName][_SKM._race]) then |
||
5958 | SKM_Data[_RealmName][_PlayerName].DuelHistory[sName][_SKM._race] = SKM_Context.DuelEnemy[_SKM._race]; |
||
5959 | end |
||
5960 | if (not SKM_Data[_RealmName][_PlayerName].DuelHistory[sName][_SKM._class]) then |
||
5961 | SKM_Data[_RealmName][_PlayerName].DuelHistory[sName][_SKM._class] = SKM_Context.DuelEnemy[_SKM._class]; |
||
5962 | end |
||
5963 | end |
||
5964 | |||
5965 | SKM_Data[_RealmName][_PlayerName].DuelHistory[sName][_SKM._level] = SKM_Context.DuelEnemy[_SKM._level]; |
||
5966 | SKM_Data[_RealmName][_PlayerName].DuelHistory[sName][_SKM._guild] = SKM_Context.DuelEnemy[_SKM._guild]; |
||
5967 | SKM_Data[_RealmName][_PlayerName].DuelHistory[sName][_SKM._lastDuel] = sDate; |
||
5968 | |||
5969 | SKM_Data[_RealmName][_PlayerName].DuelHistory[sName][_SKM._duel] = ifnil(SKM_Data[_RealmName][_PlayerName].DuelHistory[sName][_SKM._duel], 0) + 1; |
||
5970 | if (bWin) then |
||
5971 | SKM_Data[_RealmName][_PlayerName].DuelHistory[sName][_SKM._win] = ifnil(SKM_Data[_RealmName][_PlayerName].DuelHistory[sName][_SKM._win], 0) + 1; |
||
5972 | SkM_Trace(FName, 1, "Duel won vs "..sName..", Win = "..SKM_Data[_RealmName][_PlayerName].DuelHistory[sName][_SKM._win]..", Loss = "..SKM_Data[_RealmName][_PlayerName].DuelHistory[sName][_SKM._loss]..", Total = "..SKM_Data[_RealmName][_PlayerName].DuelHistory[sName][_SKM._duel]); |
||
5973 | else |
||
5974 | SKM_Data[_RealmName][_PlayerName].DuelHistory[sName][_SKM._loss] = ifnil(SKM_Data[_RealmName][_PlayerName].DuelHistory[sName][_SKM._loss], 0) + 1; |
||
5975 | SkM_Trace(FName, 1, "Duel lost vs "..sName..", Win = "..SKM_Data[_RealmName][_PlayerName].DuelHistory[sName][_SKM._win]..", Loss = "..SKM_Data[_RealmName][_PlayerName].DuelHistory[sName][_SKM._loss]..", Total = "..SKM_Data[_RealmName][_PlayerName].DuelHistory[sName][_SKM._duel]); |
||
5976 | end |
||
5977 | |||
5978 | -- clear duel information |
||
5979 | SKM_Context.DuelEnemy = nil; |
||
5980 | end |
||
5981 | |||
5982 | |||
5983 | function SkM_ParseDuelResult(sMsg) |
||
5984 | local FName = "SkM_ParseDuelResult"; |
||
5985 | |||
5986 | local sWinner, sLoser; |
||
5987 | |||
5988 | if (not SkM_GetOption("StoreDuels")) then |
||
5989 | return; |
||
5990 | end |
||
5991 | |||
5992 | for sWinner, sLoser in string.gfind(sMsg, SKM_Context.Pattern.Duel_Won) do |
||
5993 | if (sWinner and sLoser) then |
||
5994 | if (sWinner == _PlayerName) or (sLoser == _PlayerName) then |
||
5995 | SkM_Trace(FName, 3, "Duel_Won : Winner = "..sWinner..", Loser = "..sLoser); |
||
5996 | |||
5997 | SkM_LogDuel(sWinner, sLoser); |
||
5998 | return; |
||
5999 | end |
||
6000 | end |
||
6001 | end |
||
6002 | |||
6003 | end |
||
6004 | |||
6005 | |||
6006 | function SkM_UpdateBGStats(sZoneName, sDate, iDeath, iKill) |
||
6007 | |||
6008 | if (not SKM_Data[_RealmName][_PlayerName].BGStats[sZoneName]) then |
||
6009 | SKM_Data[_RealmName][_PlayerName].BGStats[sZoneName] = { }; |
||
6010 | end |
||
6011 | |||
6012 | if (not SKM_Data[_RealmName][_PlayerName].BGStats[sZoneName][sDate]) then |
||
6013 | SKM_Data[_RealmName][_PlayerName].BGStats[sZoneName][sDate] = { }; |
||
6014 | SKM_Data[_RealmName][_PlayerName].BGStats[sZoneName][sDate][_SKM._enemyKillBG] = 0; |
||
6015 | SKM_Data[_RealmName][_PlayerName].BGStats[sZoneName][sDate][_SKM._playerBGKill] = 0; |
||
6016 | end |
||
6017 | |||
6018 | if (iDeath) then |
||
6019 | SKM_Data[_RealmName][_PlayerName].BGStats[sZoneName][sDate][_SKM._enemyKillBG] = ifnil(SKM_Data[_RealmName][_PlayerName].BGStats[sZoneName][sDate][_SKM._enemyKillBG], 0) + iDeath; |
||
6020 | end |
||
6021 | |||
6022 | if (iKill) then |
||
6023 | SKM_Data[_RealmName][_PlayerName].BGStats[sZoneName][sDate][_SKM._playerBGKill] = ifnil(SKM_Data[_RealmName][_PlayerName].BGStats[sZoneName][sDate][_SKM._playerBGKill], 0) + iKill; |
||
6024 | end |
||
6025 | end |
||
6026 | |||
6027 | |||
6028 | function SkM_BGStats_AddDeath() |
||
6029 | local sZone = SkM_GetZoneText(); |
||
6030 | local sDate = SkM_GetDay(); |
||
6031 | SkM_UpdateBGStats(sZone, sDate, 1, nil); |
||
6032 | end |
||
6033 | |||
6034 | |||
6035 | function SkM_BGStats_AddKill() |
||
6036 | local sZone = SkM_GetZoneText(); |
||
6037 | local sDate = SkM_GetDay(); |
||
6038 | SkM_UpdateBGStats(sZone, sDate, nil, 1); |
||
6039 | end |
||
6040 | |||
6041 | |||
6042 | function SkM_NormString2(sString) |
||
6043 | local sRes = sString; |
||
6044 | local idx, val, i; |
||
6045 | for idx, val in SKM_ToStandardCase do |
||
6046 | for i=1, table.getn(val), 1 do |
||
6047 | sRes = string.gsub(sRes, val[i], idx); |
||
6048 | end |
||
6049 | end |
||
6050 | return sRes; |
||
6051 | end |
||
6052 | |||
6053 | |||
6054 | function SkM_NormString(sInputString, iNormMinLen) |
||
6055 | local FName = "SkM_NormString"; |
||
6056 | local sString = string.upper(sInputString); |
||
6057 | local iLen = string.len(sString); |
||
6058 | local sRes = ""; |
||
6059 | local sNonStd = ""; |
||
6060 | |||
6061 | local iByte_A = string.byte("A"); |
||
6062 | local iByte_Z = string.byte("Z"); |
||
6063 | local iByte_a = string.byte("a"); |
||
6064 | local iByte_z = string.byte("z"); |
||
6065 | |||
6066 | local i; |
||
6067 | for i=1,iLen,1 do |
||
6068 | --SkM_Trace(FName, 3, i.." Res="..sRes); |
||
6069 | |||
6070 | local sChar = string.sub(sString, i, i); |
||
6071 | local iByte = string.byte(sString, i); |
||
6072 | if ((iByte >= iByte_A) and (iByte <= iByte_Z)) |
||
6073 | or ((iByte >= iByte_a) and (iByte <= iByte_z)) |
||
6074 | or (intable(sChar, { " ", "-" } )) |
||
6075 | then |
||
6076 | if (string.len(sNonStd) > 0) then |
||
6077 | sRes = sRes..SkM_NormString2(sNonStd); |
||
6078 | sNonStd = ""; |
||
6079 | end |
||
6080 | sRes = sRes..sChar; |
||
6081 | if (i<iLen) and (iNormMinLen) and (string.len(sRes) >= iNormMinLen) then |
||
6082 | sRes = sRes..string.sub(sString, i+1, iLen); |
||
6083 | return sRes; |
||
6084 | end |
||
6085 | else |
||
6086 | sNonStd = sNonStd..sChar; |
||
6087 | end |
||
6088 | end |
||
6089 | if (string.len(sNonStd) > 0) then |
||
6090 | sRes = sRes..SkM_NormString2(sNonStd); |
||
6091 | sNonStd = ""; |
||
6092 | end |
||
6093 | |||
6094 | return sRes; |
||
6095 | end |
||
6096 | |||
6097 | |||
6098 | function SkM_GetEnemyList(sName, bNormalize, bPrefix) |
||
6099 | local FName = "SkM_GetEnemyList"; |
||
6100 | local TheList = { }; |
||
6101 | |||
6102 | local sEnemyName = string.upper(sName); |
||
6103 | if (bNormalize) then |
||
6104 | sEnemyName = SkM_NormString(sName); |
||
6105 | end |
||
6106 | local iNameLen = string.len(sEnemyName); |
||
6107 | |||
6108 | SkM_Trace(FName, 3, "Name = "..sName); |
||
6109 | |||
6110 | local ResList = {}; |
||
6111 | for idx, val in SKM_Data[_RealmName][_PlayerName].EnemyHistory do |
||
6112 | local sCurName = string.upper(idx); |
||
6113 | local bMatch = false; |
||
6114 | if (bNormalize) then |
||
6115 | sCurName = SkM_NormString(sCurName, iNameLen); |
||
6116 | end |
||
6117 | SkM_Trace(FName, 3, "CurName = "..sCurName); |
||
6118 | if (not bPrefix) then |
||
6119 | if (sCurName == sEnemyName) then |
||
6120 | bMatch = true; |
||
6121 | end |
||
6122 | else |
||
6123 | if (string.sub(sCurName, 1, iNameLen) == sEnemyName) then |
||
6124 | bMatch = true; |
||
6125 | end |
||
6126 | end |
||
6127 | |||
6128 | if (bMatch) then |
||
6129 | table.insert(TheList, idx); |
||
6130 | end |
||
6131 | end |
||
6132 | |||
6133 | table.sort(TheList, function(e1,e2) return e1<e2; end); |
||
6134 | |||
6135 | return TheList; |
||
6136 | end |
||
6137 | |||
6138 | |||
6139 | function SkM_GetEnemyInfo(sName, bMatchFullName, bMatchSpecialChar) |
||
6140 | local FName = "SkM_GetEnemyInfo"; |
||
6141 | |||
6142 | SkM_Trace(FName, 2, "Name = "..sName..", FullName = "..snil(bMatchFullName)..", MatchSpec = "..snil(bMatchSpecialChar)); |
||
6143 | |||
6144 | local bNormalize = true; |
||
6145 | local bPrefix = true; |
||
6146 | |||
6147 | if (bMatchSpecialChar) then |
||
6148 | bNormalize = false; |
||
6149 | end |
||
6150 | if (bMatchFullName) then |
||
6151 | bPrefix = false; |
||
6152 | end |
||
6153 | |||
6154 | SkM_ChatMessageCol("Looking for : "..sName); |
||
6155 | |||
6156 | local EnemyList = SkM_GetEnemyList(sName, bNormalize, bPrefix); |
||
6157 | local iEnemyCount = table.getn(EnemyList); |
||
6158 | |||
6159 | for i=1,iEnemyCount,1 do |
||
6160 | local Enemy = SKM_Data[_RealmName][_PlayerName].EnemyHistory[EnemyList[i]]; |
||
6161 | if (Enemy) then |
||
6162 | local Lines = {}; |
||
6163 | |||
6164 | local iKill = ifnil(Enemy[_SKM._playerKill], 0); |
||
6165 | local iAssistKill = ifnil(Enemy[_SKM._playerAssistKill], 0); |
||
6166 | local iFullKill = ifnil(Enemy[_SKM._playerFullKill], 0); |
||
6167 | local iTotalKill = iKill + iAssistKill + iFullKill; |
||
6168 | local iDeath = ifnil(Enemy[_SKM._enemyKillPlayer], 0); |
||
6169 | local iMet = ifnil(Enemy[_SKM._meetCount], 0); |
||
6170 | local sDisplayDate = string.sub(Enemy[_SKM._lastView], 1, 10); |
||
6171 | |||
6172 | local Guild; |
||
6173 | local bGuildWar = false; |
||
6174 | if (Enemy[_SKM._guild] ~= nil) and (Enemy[_SKM._guild] ~= "") then |
||
6175 | Guild = SKM_Data[_RealmName][_PlayerName].GuildHistory[Enemy[_SKM._guild]]; |
||
6176 | bGuildWar = Guild[_SKM._atWar]; |
||
6177 | end |
||
6178 | |||
6179 | -- line 1 : <rank> <player> <guild> : level <level> <race> <class> |
||
6180 | |||
6181 | local sLine = ""; |
||
6182 | if (Enemy[_SKM._rank]) then |
||
6183 | sLine = sLine..SKM_Config.Col_Rank..Enemy[_SKM._rank].." "; |
||
6184 | end |
||
6185 | |||
6186 | if (Enemy[_SKM._atWar]) then |
||
6187 | sLine = sLine..SKM_Config.Col_PlayerWar; |
||
6188 | else |
||
6189 | sLine = sLine..SKM_Config.Col_Label; |
||
6190 | end |
||
6191 | sLine = sLine..Enemy[_SKM._name]..SKM_Config.Col_Label; |
||
6192 | |||
6193 | if (Guild) then |
||
6194 | sLine = sLine.." <"; |
||
6195 | if (Guild[_SKM._atWar]) then |
||
6196 | sLine = sLine..SKM_Config.Col_PlayerWar; |
||
6197 | end |
||
6198 | sLine = sLine..Enemy[_SKM._guild]..SKM_Config.Col_Label..">"; |
||
6199 | end |
||
6200 | |||
6201 | if (Enemy[_SKM._level] ~= nil) and (Enemy[_SKM._race] ~= nil) and (Enemy[_SKM._class] ~= nil) then |
||
6202 | sLine = sLine.." : "..SKM_UI_STRINGS.List_Frame_Level..Enemy[_SKM._level].." "..SkM_GetRaceText(Enemy[_SKM._race]).." "..SkM_GetClassText(Enemy[_SKM._class]); |
||
6203 | end |
||
6204 | |||
6205 | table.insert(Lines, sLine); |
||
6206 | |||
6207 | if (iEnemyCount == 1) then |
||
6208 | |||
6209 | -- line 2 : <met> <kill> <death> <last seen date and location> |
||
6210 | sLine = ""; |
||
6211 | |||
6212 | sLine = sLine..SKM_Config.Col_LabelTitle..SKM_UI_STRINGS.List_Frame_Met..SKM_Config.Col_Label..iMet; |
||
6213 | sLine = sLine.." "..SKM_Config.Col_LabelTitle..SKM_UI_STRINGS.List_Frame_Kill..SKM_Config.Col_Label..iTotalKill; |
||
6214 | sLine = sLine.." "..SKM_Config.Col_LabelTitle..SKM_UI_STRINGS.List_Frame_Death..SKM_Config.Col_Label .. iDeath; |
||
6215 | |||
6216 | sLine = sLine.." "..SKM_Config.Col_LabelTitle..SKM_UI_STRINGS.List_Frame_Last_Seen; |
||
6217 | sLine = sLine..SKM_Config.Col_Label..sDisplayDate; |
||
6218 | |||
6219 | if (Enemy[_SKM._continent] ~= nil) and (Enemy[_SKM._zone] ~= nil) then |
||
6220 | local sZoneText = SkM_GetZoneTextFromIndex(Enemy[_SKM._continent], Enemy[_SKM._zone]); |
||
6221 | sLine = sLine.." - "..sZoneText; |
||
6222 | |||
6223 | elseif (Enemy[_SKM._zoneName] ~= nil) then |
||
6224 | sLine = sLine.." - "..Enemy[_SKM._zoneName]; |
||
6225 | end |
||
6226 | |||
6227 | table.insert(Lines, sLine); |
||
6228 | |||
6229 | |||
6230 | if (Enemy[_SKM._playerNote] ~= nil) and (Enemy[_SKM._playerNote] ~= "") then |
||
6231 | |||
6232 | local sLine = ""; |
||
6233 | |||
6234 | sLine = sLine..SKM_Config.Col_LabelTitle..SKM_UI_STRINGS.List_Frame_Note; |
||
6235 | sLine = sLine..SKM_Config.Col_Label..Enemy[_SKM._playerNote]; |
||
6236 | |||
6237 | table.insert(Lines, sLine); |
||
6238 | end |
||
6239 | |||
6240 | |||
6241 | end |
||
6242 | |||
6243 | for i=1,table.getn(Lines),1 do |
||
6244 | DEFAULT_CHAT_FRAME:AddMessage(Lines[i]); |
||
6245 | end |
||
6246 | |||
6247 | end |
||
6248 | end |
||
6249 | |||
6250 | --SkM_ChatMessageCol("Enemy matching : "..iEnemyCount); |
||
6251 | SkM_ChatMessageCol("Found : "..iEnemyCount); |
||
6252 | end |
||
6253 | |||
6254 | |||
6255 | function SkM_DataCleanUp() |
||
6256 | local FName = "SkM_DataCleanUp"; |
||
6257 | if (not SKM_Data) then |
||
6258 | return; |
||
6259 | end |
||
6260 | if (not SKM_Settings) then |
||
6261 | return; |
||
6262 | end |
||
6263 | |||
6264 | if (SkM_GetOption("DataCleanUp")) then |
||
6265 | local sDate = SkM_GetDate(); |
||
6266 | local iDiffTime = SkM_DiffDate(sDate, SKM_Settings.LastDataCleanUp); |
||
6267 | if (SKM_Settings.LastDataCleanUp == nil) or (iDiffTime == nil) or (iDiffTime > SkM_GetOption("DataCleanUpInterval") * 3600 * 24) then |
||
6268 | |||
6269 | SkM_DoCleanUp(); |
||
6270 | |||
6271 | SKM_Settings.LastDataCleanUp = sDate; |
||
6272 | end |
||
6273 | end |
||
6274 | |||
6275 | end |
||
6276 | |||
6277 | |||
6278 | function SkM_DoCleanUp() |
||
6279 | local FName = "SkM_DoCleanUp"; |
||
6280 | |||
6281 | local sDate = SkM_GetDate(); |
||
6282 | |||
6283 | if (SkM_GetOption("CleanInactiveEnemies")) then |
||
6284 | |||
6285 | for idx_realm, val_realm in SKM_Data do |
||
6286 | for idx_char, val_char in SKM_Data[idx_realm] do |
||
6287 | if (SKM_Data[idx_realm][idx_char].PlayerName == idx_char) then |
||
6288 | |||
6289 | SkM_Trace(FName, 1, "Cleaning for "..idx_realm.." / "..idx_char); |
||
6290 | for idx_enemy, val_enemy in SKM_Data[idx_realm][idx_char].EnemyHistory do |
||
6291 | |||
6292 | local iDiffTime = SkM_DiffDate(sDate, val_enemy[_SKM._lastView]); |
||
6293 | if (iDiffTime ~= nil) and (iDiffTime > SkM_GetOption("CleanInactiveEnemiesDelay") * 3600 * 24) then |
||
6294 | -- long time no see. Check if we have to remove him |
||
6295 | if (ifnil(val_enemy[_SKM._playerAssistKill], 0) + ifnil(val_enemy[_SKM._playerKill], 0) + ifnil(val_enemy[_SKM._playerFullKill], 0) == 0) |
||
6296 | and (ifnil(val_enemy[_SKM._enemyKillPlayer], 0) == 0) |
||
6297 | and (ifnil(val_enemy[_SKM._enemyKillBG], 0) == 0) |
||
6298 | and (ifnil(val_enemy[_SKM._playerBGKill], 0) == 0) |
||
6299 | and not (val_enemy[_SKM._atWar]) |
||
6300 | and ( (val_enemy[_SKM._playerNote] == nil) or (val_enemy[_SKM._playerNote] == "") ) |
||
6301 | then |
||
6302 | SkM_Trace(FName, 2, idx_realm.." / "..idx_char.." : remove "..idx_enemy); |
||
6303 | |||
6304 | SKM_Data[idx_realm][idx_char].EnemyHistory[idx_enemy] = nil; |
||
6305 | end |
||
6306 | |||
6307 | end |
||
6308 | end |
||
6309 | end |
||
6310 | end |
||
6311 | end |
||
6312 | end |
||
6313 | |||
6314 | if (SkM_GetOption("CleanEmptyGuilds")) then |
||
6315 | for idx_realm, val_realm in SKM_Data do |
||
6316 | for idx_char, val_char in SKM_Data[idx_realm] do |
||
6317 | if (SKM_Data[idx_realm][idx_char].PlayerName == idx_char) then |
||
6318 | for idx_guild, val_guild in SKM_Data[idx_realm][idx_char].GuildHistory do |
||
6319 | |||
6320 | if (SkM_CountGuildMembers(idx_guild, idx_realm, idx_char) == 0) then |
||
6321 | SkM_Trace(FName, 2, idx_realm.." / "..idx_char.." : remove "..idx_guild); |
||
6322 | SKM_Data[idx_realm][idx_char].GuildHistory[idx_guild] = nil; |
||
6323 | end |
||
6324 | end |
||
6325 | end |
||
6326 | end |
||
6327 | end |
||
6328 | end |
||
6329 | |||
6330 | end |
||
6331 | |||
6332 | |||
6333 | |||
6334 | function SkM_ZoneRematch(RealmName, PlayerName, ZoneShift, minDate, maxDate) |
||
6335 | local FName = "SkM_ZoneRematch"; |
||
6336 | local idx_c, val_c, idx_z, val_z, idx_gn, Note; |
||
6337 | local cont_shift, zone_shift; |
||
6338 | |||
6339 | local iCountShift = 0; |
||
6340 | local iCountNoShift = 0; |
||
6341 | |||
6342 | if (ZoneShift == nil) then |
||
6343 | SkM_Trace(FName, 1, "ZoneShift is nil ! "); |
||
6344 | return; |
||
6345 | end |
||
6346 | |||
6347 | -- reinitialize map data |
||
6348 | SKM_Data[RealmName][PlayerName].MapData = { }; |
||
6349 | |||
6350 | for idx_c, val_c in SKM_Context.Continents do |
||
6351 | SKM_Data[RealmName][PlayerName].MapData[idx_c] = { }; |
||
6352 | |||
6353 | for idx_z, val_z in SKM_Context.Zones[idx_c] do |
||
6354 | SKM_Data[RealmName][PlayerName].MapData[idx_c][idx_z] = { }; |
||
6355 | end |
||
6356 | end |
||
6357 | |||
6358 | |||
6359 | -- parse global map data to rebuild local map data |
||
6360 | if (SKM_Data[RealmName][PlayerName].GlobalMapData) then |
||
6361 | for idx_gn, Note in SKM_Data[RealmName][PlayerName].GlobalMapData do |
||
6362 | local bDoShift = true; |
||
6363 | idx_c = Note[_SKM._continent]; |
||
6364 | idx_z = Note[_SKM._zone]; |
||
6365 | |||
6366 | local StoredInfo = Note[_SKM._storedInfo]; |
||
6367 | |||
6368 | if (StoredInfo) and (StoredInfo[_SKM._date]) then |
||
6369 | if (maxDate) then |
||
6370 | local iDiffTime = SkM_DiffDate(maxDate, StoredInfo[_SKM._date]); |
||
6371 | if (iDiffTime < 0) then |
||
6372 | -- Note generated after max date, skip |
||
6373 | bDoShift = false; |
||
6374 | end |
||
6375 | end |
||
6376 | if (minDate) then |
||
6377 | local iDiffTime = SkM_DiffDate(minDate, StoredInfo[_SKM._date]); |
||
6378 | if (iDiffTime > 0) then |
||
6379 | -- Note generated before min date, skip |
||
6380 | bDoShift = false; |
||
6381 | end |
||
6382 | end |
||
6383 | end |
||
6384 | |||
6385 | if (bDoShift) then |
||
6386 | zone_shift = ZoneShift[idx_c][idx_z]; |
||
6387 | |||
6388 | -- insert new map note |
||
6389 | table.insert(SKM_Data[RealmName][PlayerName].MapData[idx_c][zone_shift], idx_gn); |
||
6390 | |||
6391 | -- update global note zone index |
||
6392 | SKM_Data[RealmName][PlayerName].GlobalMapData[idx_gn][_SKM._zone] = zone_shift; |
||
6393 | |||
6394 | iCountShift = iCountShift + 1; |
||
6395 | else |
||
6396 | -- insert unchanged map note |
||
6397 | table.insert(SKM_Data[RealmName][PlayerName].MapData[idx_c][idx_z], idx_gn); |
||
6398 | |||
6399 | iCountNoShift = iCountNoShift + 1; |
||
6400 | end |
||
6401 | end |
||
6402 | |||
6403 | end |
||
6404 | |||
6405 | |||
6406 | -- parse enemy information and shift zone where last seen |
||
6407 | for idx_enemy, val_enemy in SKM_Data[RealmName][PlayerName].EnemyHistory do |
||
6408 | idx_c = val_enemy[_SKM._continent]; |
||
6409 | idx_z = val_enemy[_SKM._zone]; |
||
6410 | local bDoShift = true; |
||
6411 | |||
6412 | if (idx_c == nil) or (idx_z == nil) then |
||
6413 | bDoShift = false; |
||
6414 | |||
6415 | if (val_enemy[_SKM._lastView]) then |
||
6416 | if (maxDate) then |
||
6417 | local iDiffTime = SkM_DiffDate(maxDate, val_enemy[_SKM._lastView]); |
||
6418 | if (iDiffTime < 0) then |
||
6419 | -- generated after max date, skip |
||
6420 | bDoShift = false; |
||
6421 | end |
||
6422 | end |
||
6423 | if (minDate) then |
||
6424 | local iDiffTime = SkM_DiffDate(minDate, val_enemy[_SKM._lastView]); |
||
6425 | if (iDiffTime > 0) then |
||
6426 | -- generated before min date, skip |
||
6427 | bDoShift = false; |
||
6428 | end |
||
6429 | end |
||
6430 | end |
||
6431 | end |
||
6432 | |||
6433 | if (bDoShift) then |
||
6434 | zone_shift = ZoneShift[idx_c][idx_z]; |
||
6435 | |||
6436 | SKM_Data[RealmName][PlayerName].EnemyHistory[idx_enemy][_SKM._zone] = zone_shift; |
||
6437 | end |
||
6438 | end |
||
6439 | |||
6440 | SkM_Trace(FName, 1, "Realm = "..RealmName.." / Player = "..PlayerName.." : Zone Rematch completed, shift count = "..iCountShift..", 'no shift' count = "..iCountNoShift); |
||
6441 | end |
||
6442 | |||
6443 | |||
6444 | function SkM_AccountZoneRematch(ZoneShift, minDate, maxDate) |
||
6445 | local FName = "SkM_AccountZoneRematch"; |
||
6446 | |||
6447 | if (ZoneShift == nil) then |
||
6448 | SkM_Trace(FName, 1, "ZoneShift is nil ! "); |
||
6449 | return; |
||
6450 | end |
||
6451 | |||
6452 | local idx_realm, val_realm, idx_char, val_char; |
||
6453 | |||
6454 | for idx_realm, val_realm in SKM_Data do |
||
6455 | for idx_char, val_char in SKM_Data[idx_realm] do |
||
6456 | if (SKM_Data[idx_realm][idx_char].PlayerName == idx_char) then |
||
6457 | SkM_ZoneRematch(idx_realm, idx_char, ZoneShift, minDate, maxDate) |
||
6458 | end |
||
6459 | end |
||
6460 | end |
||
6461 | end |
||
6462 | |||
6463 | |||
6464 | function SkM_DoMapShift(Source, Dest, ZoneShift, minDate, maxDate) |
||
6465 | local FName = "SkM_DoMapShift"; |
||
6466 | |||
6467 | local sDate = SkM_GetDate(); |
||
6468 | |||
6469 | if (ZoneShift == nil) then |
||
6470 | SkM_Trace(FName, 1, "ZoneShift is nil ! "); |
||
6471 | return; |
||
6472 | end |
||
6473 | |||
6474 | SkM_Trace(FName, 1, "Do shift ("..snil(Source).." -> "..snil(Dest)..")"); |
||
6475 | SkM_Trace(FName, 1, "Shift interval = ["..snil(minDate).." -> "..snil(maxDate).."]"); |
||
6476 | |||
6477 | SkM_AccountZoneRematch(ZoneShift, minDate, maxDate); |
||
6478 | |||
6479 | if (SKM_Settings.ZoneShifts == nil) then |
||
6480 | SKM_Settings.ZoneShifts = {}; |
||
6481 | end |
||
6482 | local ZoneShiftRecord = { |
||
6483 | Date = sDate; |
||
6484 | Source = Source; |
||
6485 | Dest = Dest; |
||
6486 | minDate = minDate; |
||
6487 | maxDate = maxDate; |
||
6488 | }; |
||
6489 | table.insert(SKM_Settings.ZoneShifts, ZoneShiftRecord); |
||
6490 | |||
6491 | end |
||
6492 | |||
6493 | |||
6494 | function SkM_GetShiftTable(source, dest) |
||
6495 | if (SKM_ShiftTables == nil) then |
||
6496 | return nil; |
||
6497 | end |
||
6498 | if (SKM_ShiftTables[source] == nil) then |
||
6499 | return nil; |
||
6500 | end |
||
6501 | return SKM_ShiftTables[source][dest]; |
||
6502 | end |
||
6503 | |||
6504 | |||
6505 | -- -------------------------------------------------------------------------------------- |
||
6506 | -- SkM_MapShiftMigration |
||
6507 | -- -------------------------------------------------------------------------------------- |
||
6508 | -- Proceed to all map shift migrations, if needed. |
||
6509 | -- If no new zone shift is defined since last migration, nothing will be done. |
||
6510 | -- -------------------------------------------------------------------------------------- |
||
6511 | function SkM_MapShiftMigration() |
||
6512 | local FName = "SkM_MapShiftMigration"; |
||
6513 | |||
6514 | local bShift = false; |
||
6515 | local curTime = GetTime(); |
||
6516 | |||
6517 | -- check if there are map migrations that need be done |
||
6518 | |||
6519 | -- NOTE : the following case is not handled and WILL NOT BE !! |
||
6520 | -- if user changes his locale interface language while there has been a new locale |
||
6521 | -- shift defined on his previous language, before installing the new version of SKMap. |
||
6522 | -- too bad ! |
||
6523 | |||
6524 | |||
6525 | SkM_Trace(FName, 1, "Automatic map migration starting..."); |
||
6526 | |||
6527 | local bNewLocale = false; |
||
6528 | -- if we don't have information of last local language, we assume there were no |
||
6529 | -- language change... otherwise, there's nothing we can do... |
||
6530 | if (SKM_Settings.LastLocale ~= nil) then |
||
6531 | if (SKM_CurrentLocale ~= SKM_Settings.LastLocale) then |
||
6532 | bNewLocale = true; |
||
6533 | end |
||
6534 | else |
||
6535 | SKM_Settings.LastLocale = SKM_CurrentLocale; |
||
6536 | end |
||
6537 | |||
6538 | |||
6539 | -- are there new locale shift defines for previous language ? |
||
6540 | local iNbLocalShift = 0; |
||
6541 | local iNextLocalShift = 0; |
||
6542 | local bNewLocalShift = false; |
||
6543 | if (SKM_Locale[SKM_Settings.LastLocale]) and (SKM_Locale[SKM_Settings.LastLocale].LocalShift) then |
||
6544 | iNbLocalShift = table.getn(SKM_Locale[SKM_Settings.LastLocale].LocalShift); |
||
6545 | end |
||
6546 | if (iNbLocalShift > ifnil(SKM_Settings.LastLocalShift, 0)) then |
||
6547 | bNewLocalShift = true; |
||
6548 | iNextLocalShift = ifnil(SKM_Settings.LastLocalShift, 0) + 1; |
||
6549 | end |
||
6550 | |||
6551 | |||
6552 | if (bNewLocalShift) then |
||
6553 | |||
6554 | if (SKM_Settings.ZoneShiftDest) and (SKM_Settings.ZoneShiftSource) then |
||
6555 | -- apply reverse shift first for all data ulterior to next local shift |
||
6556 | |||
6557 | SkM_DoMapShift( |
||
6558 | SKM_Settings.ZoneShiftDest, SKM_Settings.ZoneShiftSource, |
||
6559 | SkM_GetShiftTable(SKM_Settings.ZoneShiftDest, SKM_Settings.ZoneShiftSource), |
||
6560 | SKM_Locale[SKM_Settings.LastLocale].LocalShift[iNextShift].DateShift, nil); |
||
6561 | |||
6562 | bShift = true; |
||
6563 | end |
||
6564 | |||
6565 | SKM_Settings.LastLocalShift = 0; |
||
6566 | SKM_Settings.LastCurrentShift = 0; |
||
6567 | |||
6568 | -- now perform all new local shifts |
||
6569 | -- each local shift is performed on all data up to the local shift date |
||
6570 | local i; |
||
6571 | for i=iNextLocalShift,iNbLocalShift, 1 do |
||
6572 | |||
6573 | SkM_Trace(FName, 3, "Performing local shift "..i); |
||
6574 | local Source = SKM_Locale[SKM_Settings.LastLocale].LocalShift[i].Source; |
||
6575 | local Dest = SKM_Locale[SKM_Settings.LastLocale].LocalShift[i].Dest; |
||
6576 | local DateShift = SKM_Locale[SKM_Settings.LastLocale].LocalShift[i].DateShift; |
||
6577 | |||
6578 | SkM_DoMapShift(Source, Dest, SkM_GetShiftTable(Source, Dest), nil, DateShift) |
||
6579 | |||
6580 | bShift = true; |
||
6581 | |||
6582 | SKM_Settings.LastLocalShift = i; |
||
6583 | end |
||
6584 | |||
6585 | -- now apply current shift if need be |
||
6586 | -- moved out of if condition, see below |
||
6587 | end |
||
6588 | |||
6589 | -- now apply current shift if need be |
||
6590 | if (ifnil(SKM_Settings.LastCurrentShift, 0) == 0) then |
||
6591 | if (SKM_Locale[SKM_Settings.LastLocale].CurrentShift) then |
||
6592 | |||
6593 | local Source = SKM_Locale[SKM_Settings.LastLocale].CurrentShift.Source; |
||
6594 | local Dest = SKM_Locale[SKM_Settings.LastLocale].CurrentShift.Dest; |
||
6595 | |||
6596 | if (Source == SKM_Settings.ZoneShiftSource) and (Dest == SKM_Settings.ZoneShiftDest) then |
||
6597 | SkM_Trace(FName, 3, "current shift already performed"); |
||
6598 | else |
||
6599 | |||
6600 | SkM_Trace(FName, 3, "Perform final shift (current)"); |
||
6601 | |||
6602 | local DateMin = nil; |
||
6603 | local DateMax = nil; |
||
6604 | |||
6605 | -- fix for 1.4 bug for DE version |
||
6606 | if (SKM_CurrentLocale == "DE") then |
||
6607 | DateMax = SKM_Context.DateIndexBug; |
||
6608 | end |
||
6609 | |||
6610 | SkM_DoMapShift(Source, Dest, SkM_GetShiftTable(Source, Dest), DateMin, DateMax); |
||
6611 | |||
6612 | bShift = true; |
||
6613 | end |
||
6614 | |||
6615 | SKM_Settings.LastCurrentShift = 1; |
||
6616 | |||
6617 | SKM_Settings.ZoneShiftSource = Source; |
||
6618 | SKM_Settings.ZoneShiftDest = Dest; |
||
6619 | else |
||
6620 | -- no current shift |
||
6621 | SKM_Settings.ZoneShiftSource = nil; |
||
6622 | SKM_Settings.ZoneShiftDest = nil; |
||
6623 | end |
||
6624 | end |
||
6625 | |||
6626 | |||
6627 | if (bNewLocale) then |
||
6628 | |||
6629 | if (SKM_Locale[SKM_CurrentLocale]) and (SKM_Locale[SKM_CurrentLocale].CurrentShift) then |
||
6630 | SKM_Settings.ZoneShiftSource = SKM_Locale[SKM_CurrentLocale].CurrentShift.Source; |
||
6631 | SKM_Settings.ZoneShiftDest = SKM_Locale[SKM_CurrentLocale].CurrentShift.Dest; |
||
6632 | else |
||
6633 | -- no current shift |
||
6634 | |||
6635 | SKM_Settings.ZoneShiftSource = nil; |
||
6636 | SKM_Settings.ZoneShiftDest = nil; |
||
6637 | end |
||
6638 | |||
6639 | -- now we can safely store the new language as the current one. |
||
6640 | SKM_Settings.LastLocale = SKM_CurrentLocale; |
||
6641 | |||
6642 | -- also store LastLocalShift as the latest local shift, if any |
||
6643 | if (SKM_Locale[SKM_Settings.LastLocale]) and (SKM_Locale[SKM_Settings.LastLocale].LocalShift) then |
||
6644 | iNbLocalShift = table.getn(SKM_Locale[SKM_Settings.LastLocale].LocalShift); |
||
6645 | SKM_Settings.LastLocalShift = iNbLocalShift; |
||
6646 | else |
||
6647 | SKM_Settings.LastLocalShift = nil; |
||
6648 | end |
||
6649 | |||
6650 | end |
||
6651 | |||
6652 | |||
6653 | SkM_Trace(FName, 3, "Zone Shift performed ? "..snil(bShift)); |
||
6654 | |||
6655 | if (bShift) then |
||
6656 | local endTime = GetTime(); |
||
6657 | local elapsedTime = math.floor(100 * (endTime - curTime)) / 100; |
||
6658 | SkM_ChatMessageCol("Zone order shift(s) performed, elapsed time : "..elapsedTime.." s"); |
||
6659 | end |
||
6660 | |||
6661 | end |
||
6662 | |||
6663 | |||
6664 | function SkM_ReverseZoneShift(ZoneShift) |
||
6665 | local NewShift = { }; |
||
6666 | |||
6667 | local i,j; |
||
6668 | for i=1,table.getn(ZoneShift),1 do |
||
6669 | local Line = { }; |
||
6670 | for j=1,table.getn(ZoneShift[i]),1 do |
||
6671 | Line[ZoneShift[i][j]] = j; |
||
6672 | end |
||
6673 | NewShift[i] = Line; |
||
6674 | end |
||
6675 | return NewShift; |
||
6676 | end |
||
6677 | |||
6678 | |||
6679 | function SkM_CharDataMigration(Ver, RealmName, PlayerName) |
||
6680 | local FName = "SkM_CharDataMigration"; |
||
6681 | |||
6682 | -- Migration of EnemyHistory |
||
6683 | if (SKM_Data[RealmName][PlayerName].EnemyHistory) then |
||
6684 | local idx_enemy, val_enemy; |
||
6685 | for idx_enemy, val_enemy in SKM_Data[RealmName][PlayerName].EnemyHistory do |
||
6686 | local EnemyMigr = {}; |
||
6687 | local idx, val; |
||
6688 | for idx, val in SKM_IndexMigr[Ver].EnemyHistory do |
||
6689 | if (val_enemy[val.Old]) then |
||
6690 | EnemyMigr[val.New] = val_enemy[val.Old]; |
||
6691 | end |
||
6692 | end |
||
6693 | |||
6694 | SKM_Data[RealmName][PlayerName].EnemyHistory[idx_enemy] = nil; |
||
6695 | SKM_Data[RealmName][PlayerName].EnemyHistory[idx_enemy] = EnemyMigr; |
||
6696 | |||
6697 | -- now migration of race and class to indexes |
||
6698 | local sRace = SKM_Data[RealmName][PlayerName].EnemyHistory[idx_enemy][_SKM._race]; |
||
6699 | local sClass = SKM_Data[RealmName][PlayerName].EnemyHistory[idx_enemy][_SKM._class]; |
||
6700 | local id_race = SKM_Context.Race.StringToIndex[sRace]; |
||
6701 | local id_class = SKM_Context.Class.StringToIndex[sClass]; |
||
6702 | SKM_Data[RealmName][PlayerName].EnemyHistory[idx_enemy][_SKM._race] = id_race; |
||
6703 | SKM_Data[RealmName][PlayerName].EnemyHistory[idx_enemy][_SKM._class] = id_class; |
||
6704 | end |
||
6705 | end |
||
6706 | |||
6707 | -- Migration of DuelHistory |
||
6708 | if (SKM_Data[RealmName][PlayerName].DuelHistory) then |
||
6709 | local idx_enemy, val_enemy; |
||
6710 | for idx_enemy, val_enemy in SKM_Data[RealmName][PlayerName].DuelHistory do |
||
6711 | local DuelMigr = {}; |
||
6712 | local idx, val; |
||
6713 | for idx, val in SKM_IndexMigr[Ver].DuelHistory do |
||
6714 | if (val_enemy[val.Old]) then |
||
6715 | DuelMigr[val.New] = val_enemy[val.Old]; |
||
6716 | end |
||
6717 | end |
||
6718 | |||
6719 | SKM_Data[RealmName][PlayerName].DuelHistory[idx_enemy] = nil; |
||
6720 | SKM_Data[RealmName][PlayerName].DuelHistory[idx_enemy] = DuelMigr; |
||
6721 | |||
6722 | -- now migration of race and class to indexes |
||
6723 | local sRace = SKM_Data[RealmName][PlayerName].DuelHistory[idx_enemy][_SKM._race]; |
||
6724 | local sClass = SKM_Data[RealmName][PlayerName].DuelHistory[idx_enemy][_SKM._class]; |
||
6725 | local id_race = SKM_Context.Race.StringToIndex[sRace]; |
||
6726 | local id_class = SKM_Context.Class.StringToIndex[sClass]; |
||
6727 | SKM_Data[RealmName][PlayerName].DuelHistory[idx_enemy][_SKM._race] = id_race; |
||
6728 | SKM_Data[RealmName][PlayerName].DuelHistory[idx_enemy][_SKM._class] = id_class; |
||
6729 | end |
||
6730 | end |
||
6731 | |||
6732 | -- Migration of GuildHistory |
||
6733 | if (SKM_Data[RealmName][PlayerName].GuildHistory) then |
||
6734 | local idx_guild, val_guild; |
||
6735 | for idx_guild, val_guild in SKM_Data[RealmName][PlayerName].GuildHistory do |
||
6736 | local GuildMigr = {}; |
||
6737 | local idx, val; |
||
6738 | for idx, val in SKM_IndexMigr[Ver].GuildHistory do |
||
6739 | if (val_guild[val.Old]) then |
||
6740 | GuildMigr[val.New] = val_guild[val.Old]; |
||
6741 | end |
||
6742 | end |
||
6743 | |||
6744 | SKM_Data[RealmName][PlayerName].GuildHistory[idx_guild] = nil; |
||
6745 | SKM_Data[RealmName][PlayerName].GuildHistory[idx_guild] = GuildMigr; |
||
6746 | end |
||
6747 | end |
||
6748 | |||
6749 | -- Migration of BGStats |
||
6750 | if (SKM_Data[RealmName][PlayerName].BGStats) then |
||
6751 | local idx_zone, val_zone; |
||
6752 | for idx_zone, val_zone in SKM_Data[RealmName][PlayerName].BGStats do |
||
6753 | local idx_date, val_date; |
||
6754 | for idx_date, val_date in SKM_Data[RealmName][PlayerName].BGStats[idx_zone] do |
||
6755 | local StatMigr = {}; |
||
6756 | local idx, val; |
||
6757 | for idx, val in SKM_IndexMigr[Ver].BGStatDate do |
||
6758 | if (val_date[val.Old]) then |
||
6759 | StatMigr[val.New] = val_date[val.Old]; |
||
6760 | end |
||
6761 | end |
||
6762 | |||
6763 | SKM_Data[RealmName][PlayerName].BGStats[idx_zone][idx_date] = nil; |
||
6764 | SKM_Data[RealmName][PlayerName].BGStats[idx_zone][idx_date] = StatMigr; |
||
6765 | end |
||
6766 | end |
||
6767 | end |
||
6768 | |||
6769 | -- Migration of GlobalMapData |
||
6770 | if (SKM_Data[RealmName][PlayerName].GlobalMapData) then |
||
6771 | local iNbNotes = table.getn(SKM_Data[RealmName][PlayerName].GlobalMapData); |
||
6772 | local i; |
||
6773 | for i=1, iNbNotes, 1 do |
||
6774 | local Note = SKM_Data[RealmName][PlayerName].GlobalMapData[i]; |
||
6775 | local NoteMigr = {}; |
||
6776 | local idx, val; |
||
6777 | for idx, val in SKM_IndexMigr[Ver].GlobalMapData do |
||
6778 | if (Note[val.Old]) then |
||
6779 | NoteMigr[val.New] = Note[val.Old]; |
||
6780 | end |
||
6781 | end |
||
6782 | |||
6783 | SKM_Data[RealmName][PlayerName].GlobalMapData[i] = nil; |
||
6784 | |||
6785 | SKM_Data[RealmName][PlayerName].GlobalMapData[i] = NoteMigr; |
||
6786 | |||
6787 | local StoredInfo = NoteMigr[_SKM._storedInfo]; |
||
6788 | if (StoredInfo) then |
||
6789 | local InfoMigr = {}; |
||
6790 | for idx, val in SKM_IndexMigr[Ver].StoredInfo do |
||
6791 | if (StoredInfo[val.Old]) then |
||
6792 | InfoMigr[val.New] = StoredInfo[val.Old]; |
||
6793 | end |
||
6794 | end |
||
6795 | InfoMigr[_SKM._type] = SKM_IndexMigr[Ver].RecordType[InfoMigr[_SKM._type]]; |
||
6796 | InfoMigr[_SKM._enemyType] = SKM_IndexMigr[Ver].EnemyType[InfoMigr[_SKM._enemyType]]; |
||
6797 | |||
6798 | -- fix level if not "level up" event |
||
6799 | if not (InfoMigr[_SKM._type] == _SKM._levelUp |
||
6800 | or InfoMigr[_SKM._type] == _SKM._creatureKill_Target |
||
6801 | or InfoMigr[_SKM._type] == _SKM._creatureKill_Xp |
||
6802 | ) then |
||
6803 | InfoMigr[_SKM._level] = nil; |
||
6804 | end |
||
6805 | |||
6806 | SKM_Data[RealmName][PlayerName].GlobalMapData[i][_SKM._storedInfo] = InfoMigr; |
||
6807 | end |
||
6808 | end |
||
6809 | end |
||
6810 | |||
6811 | -- fix battleground stats bug |
||
6812 | if (SKM_Data[RealmName][PlayerName].BGStats) then |
||
6813 | local idx_bg, val_bg |
||
6814 | for idx_bg, val_bg in SKM_Data[RealmName][PlayerName].BGStats do |
||
6815 | if not (intable(idx_bg, SKM_BATTLEGROUNDS)) then |
||
6816 | SKM_Data[RealmName][PlayerName].BGStats[idx_bg] = nil; |
||
6817 | end |
||
6818 | end |
||
6819 | end |
||
6820 | |||
6821 | -- fix wrong "level up" records |
||
6822 | if (SKM_Data[RealmName][PlayerName].GlobalMapData) then |
||
6823 | local i = 1; |
||
6824 | local iMaxLevel = 0; |
||
6825 | local iNbNotes = table.getn(SKM_Data[RealmName][PlayerName].GlobalMapData); |
||
6826 | while (i < iNbNotes) do |
||
6827 | local Note = SKM_Data[RealmName][PlayerName].GlobalMapData[i]; |
||
6828 | |||
6829 | local StoredInfo = Note[_SKM._storedInfo]; |
||
6830 | if (StoredInfo) and (StoredInfo[_SKM._type] == _SKM._levelUp) then |
||
6831 | |||
6832 | if (StoredInfo[_SKM._level] > 1) and (StoredInfo[_SKM._level] > iMaxLevel) then |
||
6833 | iMaxLevel = StoredInfo[_SKM._level]; |
||
6834 | i = i + 1; |
||
6835 | else |
||
6836 | -- remove from GlobalMapData and from MapData |
||
6837 | SkM_Trace(FName, 3, "Previous max level = "..iMaxLevel..", Note level up = "..StoredInfo[_SKM._level]); |
||
6838 | SkM_Trace(FName, 3, "Removing note for "..PlayerName.." : global index = "..i); |
||
6839 | |||
6840 | SkM_DeleteNote(RealmName, PlayerName, i); |
||
6841 | iNbNotes = iNbNotes - 1; |
||
6842 | end |
||
6843 | |||
6844 | else |
||
6845 | i = i + 1; |
||
6846 | end |
||
6847 | end |
||
6848 | end |
||
6849 | |||
6850 | |||
6851 | |||
6852 | end |
||
6853 | |||
6854 | |||
6855 | function SkM_AccountDataMigration(Ver) |
||
6856 | local FName = "SkM_AccountDataMigration"; |
||
6857 | |||
6858 | local idx_realm, val_realm, idx_char, val_char; |
||
6859 | for idx_realm, val_realm in SKM_Data do |
||
6860 | for idx_char, val_char in SKM_Data[idx_realm] do |
||
6861 | if (SKM_Data[idx_realm][idx_char].PlayerName == idx_char) then |
||
6862 | SkM_CharDataMigration(Ver, idx_realm, idx_char); |
||
6863 | end |
||
6864 | end |
||
6865 | end |
||
6866 | end |
||
6867 | |||
6868 | |||
6869 | function SkM_DataModelMigration() |
||
6870 | local FName = "SkM_DataModelMigration"; |
||
6871 | |||
6872 | local curTime = GetTime(); |
||
6873 | local bMigr = false; |
||
6874 | |||
6875 | if (SKM_Settings.SavedDataVersion == nil) then |
||
6876 | SKM_Settings.SavedDataVersion = 1; |
||
6877 | end |
||
6878 | |||
6879 | if (SKM_Settings.SavedDataVersion < 2) then |
||
6880 | SkM_AccountDataMigration(2); |
||
6881 | SKM_Settings.SavedDataVersion = 2; |
||
6882 | bMigr = true; |
||
6883 | end |
||
6884 | |||
6885 | if (bMigr) then |
||
6886 | local endTime = GetTime(); |
||
6887 | local elapsedTime = math.floor(100 * (endTime - curTime)) / 100; |
||
6888 | SkM_ChatMessageCol("Data migrated to v."..SKM_Settings.SavedDataVersion..", elapsed time : "..elapsedTime.." s"); |
||
6889 | end |
||
6890 | |||
6891 | end |
||
6892 | |||
6893 | |||
6894 | -- function provided to fix MapData indexes from GlobalMapData (which is supposed to be |
||
6895 | -- correct !) |
||
6896 | function SkM_FixMapIndexes(RealmName, PlayerName) |
||
6897 | local FName = "SkM_FixMapIndexes"; |
||
6898 | local idx_c, val_c, idx_z, val_z, idx_gn; |
||
6899 | |||
6900 | SkM_Trace(FName, 3, "Realm = "..snil(RealmName).. " / Player = "..snil(PlayerName)); |
||
6901 | |||
6902 | -- reinitialize map data |
||
6903 | SKM_Data[RealmName][PlayerName].MapData = { }; |
||
6904 | |||
6905 | for idx_c, val_c in SKM_Context.Continents do |
||
6906 | SKM_Data[RealmName][PlayerName].MapData[idx_c] = { }; |
||
6907 | |||
6908 | for idx_z, val_z in SKM_Context.Zones[idx_c] do |
||
6909 | SKM_Data[RealmName][PlayerName].MapData[idx_c][idx_z] = { }; |
||
6910 | end |
||
6911 | end |
||
6912 | |||
6913 | -- parse global map data to rebuild local map data |
||
6914 | if (SKM_Data[RealmName][PlayerName].GlobalMapData) then |
||
6915 | for idx_gn, Note in SKM_Data[RealmName][PlayerName].GlobalMapData do |
||
6916 | idx_c = Note[_SKM._continent]; |
||
6917 | idx_z = Note[_SKM._zone]; |
||
6918 | |||
6919 | -- insert new map note |
||
6920 | table.insert(SKM_Data[RealmName][PlayerName].MapData[idx_c][idx_z], idx_gn); |
||
6921 | end |
||
6922 | end |
||
6923 | |||
6924 | end |
||
6925 | |||
6926 | -- function provided to fix MapData indexes from GlobalMapData (which is supposed to be |
||
6927 | -- correct !) |
||
6928 | function SkM_AccountFixMapIndexes() |
||
6929 | local idx_realm, val_realm, idx_char, val_char; |
||
6930 | |||
6931 | for idx_realm, val_realm in SKM_Data do |
||
6932 | for idx_char, val_char in SKM_Data[idx_realm] do |
||
6933 | if (SKM_Data[idx_realm][idx_char].PlayerName == idx_char) then |
||
6934 | SkM_FixMapIndexes(idx_realm, idx_char); |
||
6935 | end |
||
6936 | end |
||
6937 | end |
||
6938 | end |
||
6939 | |||
6940 | |||
6941 | -- get date of first record affected by the index bug since 1.4 |
||
6942 | -- needed to fix german data ! |
||
6943 | function SkM_GetDateIndexBug(bIgnoreLocale) |
||
6944 | local FName = "SkM_GetDateIndexBug"; |
||
6945 | |||
6946 | SKM_Context.DateIndexBug = nil; |
||
6947 | |||
6948 | local iBug = 0; |
||
6949 | local iOK = 0; |
||
6950 | |||
6951 | if not (bIgnoreLocale) then |
||
6952 | if (SKM_CurrentLocale ~= "DE") then |
||
6953 | SkM_Trace(FName, 1, "Non DE locale"); |
||
6954 | return; |
||
6955 | end |
||
6956 | end |
||
6957 | |||
6958 | local idx_realm, val_realm, idx_char, val_char; |
||
6959 | local idx_c, val_c, idx_z, val_z, idx_n, val_n, Note; |
||
6960 | |||
6961 | local r_c, r_z, r_n, r_gn, r_realm, r_char; |
||
6962 | |||
6963 | for idx_realm, val_realm in SKM_Data do |
||
6964 | for idx_char, val_char in SKM_Data[idx_realm] do |
||
6965 | if (SKM_Data[idx_realm][idx_char].PlayerName == idx_char) then |
||
6966 | for idx_c, val_c in SKM_Data[idx_realm][idx_char].MapData do |
||
6967 | for idx_z, val_z in SKM_Data[idx_realm][idx_char].MapData[idx_c] do |
||
6968 | for idx_n, val_n in SKM_Data[idx_realm][idx_char].MapData[idx_c][idx_z] do |
||
6969 | Note = SKM_Data[idx_realm][idx_char].GlobalMapData[val_n]; |
||
6970 | if not ((Note[_SKM._continent] == idx_c) and (Note[_SKM._zone] == idx_z)) then |
||
6971 | -- bad index ! |
||
6972 | iBug = iBug + 1; |
||
6973 | if (Note[_SKM._storedInfo]) and (Note[_SKM._storedInfo][_SKM._date]) then |
||
6974 | |||
6975 | if (SKM_Context.DateIndexBug == nil) then |
||
6976 | SKM_Context.DateIndexBug = Note[_SKM._storedInfo][_SKM._date]; |
||
6977 | r_c = idx_c; r_z = idx_z; r_n = idx_n; r_gn = val_n; r_realm = idx_realm; r_char = idx_char; |
||
6978 | else |
||
6979 | local iDiffTime = SkM_DiffDate(SKM_Context.DateIndexBug, Note[_SKM._storedInfo][_SKM._date]); |
||
6980 | if (iDiffTime ~= nil) and (iDiffTime > 0) then |
||
6981 | SKM_Context.DateIndexBug = Note[_SKM._storedInfo][_SKM._date]; |
||
6982 | r_c = idx_c; r_z = idx_z; r_n = idx_n; r_gn = val_n; r_realm = idx_realm; r_char = idx_char; |
||
6983 | end |
||
6984 | end |
||
6985 | end |
||
6986 | else |
||
6987 | iOK = iOK + 1; |
||
6988 | end |
||
6989 | end |
||
6990 | end |
||
6991 | end |
||
6992 | |||
6993 | end |
||
6994 | end |
||
6995 | end |
||
6996 | |||
6997 | SkM_Trace(FName, 1, "OK = "..iOK.." / Bugged = "..iBug); |
||
6998 | SkM_Trace(FName, 1, "DateIndexBug = ".. snil(SKM_Context.DateIndexBug)); |
||
6999 | SkM_Trace(FName, 1, "realm = "..snil(r_realm).." / char = "..snil(r_char)); |
||
7000 | SkM_Trace(FName, 1, "cont. = "..snil(r_c).." / zone = "..snil(r_z).." / note = "..snil(r_n).." / gn = "..snil(r_gn)); |
||
7001 | end |
||
7002 | |||
7003 | |||
7004 | function SkM_DataFixMapIndexes() |
||
7005 | if (SKM_Settings.FixMapIndexes == nil) then |
||
7006 | SkM_GetDateIndexBug(); |
||
7007 | |||
7008 | --if (SKM_CurrentLocale ~= "EN") then |
||
7009 | SkM_AccountFixMapIndexes(); |
||
7010 | --end |
||
7011 | local sDate = SkM_GetDate(); |
||
7012 | SKM_Settings.FixMapIndexes = sDate; |
||
7013 | end |
||
7014 | end |
||
7015 | |||
7016 | |||
7017 | -- keep track of history of versions installed. |
||
7018 | function SkM_RecordVersionHistory() |
||
7019 | local sLastVer; |
||
7020 | if (SKM_Settings.VersionHistory == nil) then |
||
7021 | SKM_Settings.VersionHistory = {}; |
||
7022 | else |
||
7023 | local iCount = table.getn(SKM_Settings.VersionHistory); |
||
7024 | if (iCount > 0) then |
||
7025 | sLastVer = SKM_Settings.VersionHistory[iCount].Version; |
||
7026 | end |
||
7027 | end |
||
7028 | if (sLastVer ~= SKM_VERSION) then |
||
7029 | local sDate = SkM_GetDate(); |
||
7030 | local VersionRecord = { |
||
7031 | Date = sDate; |
||
7032 | Version = SKM_VERSION; |
||
7033 | }; |
||
7034 | table.insert(SKM_Settings.VersionHistory, VersionRecord); |
||
7035 | end |
||
7036 | end |
||
7037 | |||
7038 | |||
7039 | |||
7040 | -- nchnch - new |
||
7041 | -- -------------------------------------------------------------------------------------- |
||
7042 | |||
7043 | |||
7044 | |||
7045 | -- -------------------------------------------------------------------------------------- |
||
7046 | -- SkM_GetGuildChannelName |
||
7047 | -- -------------------------------------------------------------------------------------- |
||
7048 | -- Build a unique channel name from the realm name and the player guild name |
||
7049 | -- -------------------------------------------------------------------------------------- |
||
7050 | function SkM_GetGuildChannel() |
||
7051 | local FName = "SkM_GetGuildChannel"; |
||
7052 | |||
7053 | local sName; |
||
7054 | |||
7055 | --if (not SKM_Context.RealmName) then |
||
7056 | -- SkM_Trace(FName, 1, "Realm not known !"); |
||
7057 | -- return nil; |
||
7058 | --end |
||
7059 | |||
7060 | local sGuildName = GetGuildInfo(SKM_UNIT_PLAYER); |
||
7061 | if (not sGuildName) then |
||
7062 | SkM_Trace(FName, 2, "Not in a guild"); |
||
7063 | return nil; |
||
7064 | end |
||
7065 | |||
7066 | sName = SKM_GuildChannelPrefix.." - "..sGuildName; |
||
7067 | |||
7068 | SkM_Trace(FName, 3, "Channel name : "..snil(sName)); |
||
7069 | return sName; |
||
7070 | end |
||
7071 | |||
7072 | |||
7073 | -- -------------------------------------------------------------------------------------- |
||
7074 | -- SkM_IsNameInGuild |
||
7075 | -- -------------------------------------------------------------------------------------- |
||
7076 | |||
7077 | -- Check if given player name is in guild/ |
||
7078 | -- -------------------------------------------------------------------------------------- |
||
7079 | function SkM_IsNameInGuild(sName) |
||
7080 | return ( (sName == _PlayerName) |
||
7081 | or (intable(sName, SKM_Context.GuildList)) |
||
7082 | ); |
||
7083 | end |
||
7084 | |||
7085 | |||
7086 | function SkM_JoinGuildChannel() |
||
7087 | local FName = "SkM_JoinGuildChannel"; |
||
7088 | local sChannel = SkM_GetGuildChannel(); |
||
7089 | |||
7090 | if (not sChannel) then |
||
7091 | SkM_Trace(FName, 1, "Unable to get SKMap guild channel name"); |
||
7092 | return false; |
||
7093 | end |
||
7094 | |||
7095 | JoinChannelByName(sChannel, nil, nil); |
||
7096 | |||
7097 | SKM_Context.GuildChannel = sChannel; |
||
7098 | return true; |
||
7099 | end |
||
7100 | |||
7101 | |||
7102 | function SkM_LeaveGuildChannel() |
||
7103 | local FName = "SkM_LeaveGuildChannel"; |
||
7104 | |||
7105 | if (not SKM_Context.GuildChannel) then |
||
7106 | SkM_Trace(FName, 1, "SKMap guild channel name not defined"); |
||
7107 | return; |
||
7108 | end |
||
7109 | |||
7110 | LeaveChannelByName(SKM_Context.GuildChannel); |
||
7111 | SKM_Context.GuildChannel = nil; |
||
7112 | end |
||
7113 | |||
7114 | |||
7115 | |||
7116 | |||
7117 | function SkM_GetChannelIndex(sName) |
||
7118 | local FName = "SkM_GetChannelIndex"; |
||
7119 | |||
7120 | if (not sName) then |
||
7121 | SkM_Trace(FName, 1, "Channel name not specified"); |
||
7122 | return nil; |
||
7123 | end |
||
7124 | |||
7125 | SkM_Trace(FName, 3, "Looking for index for channel : "..snil(sName)); |
||
7126 | |||
7127 | local MyChannelList = GetChannelList(); |
||
7128 | |||
7129 | local idx, val; |
||
7130 | for idx, val in MyChannelList do |
||
7131 | if (val == sName) then |
||
7132 | SkM_Trace(FName, 3, "Channel number = "..idx); |
||
7133 | return idx; |
||
7134 | end |
||
7135 | end |
||
7136 | SkM_Trace(FName, 2, "Channel not found"); |
||
7137 | return nil; |
||
7138 | end |
||
7139 | |||
7140 | |||
7141 | function SkM_SendGuildChannelMessage(sMsg) |
||
7142 | local FName = "SkM_SendGuildChannelMessage"; |
||
7143 | local iChannelIndex = SkM_GetChannelIndex(SKM_Context.GuildChannel); |
||
7144 | |||
7145 | if (iChannelIndex) then |
||
7146 | SendChatMessage(sMsg, "CHANNEL", nil, iChannelIndex); |
||
7147 | end |
||
7148 | end |
||
7149 | |||
7150 | |||
7151 | function SkM_GuildChannelMessage(iCode, ...) |
||
7152 | local FName = "SkM_GuildChannelMessage"; |
||
7153 | local sMsg; |
||
7154 | local sParam = ""; |
||
7155 | |||
7156 | local i; |
||
7157 | for i=1, arg.n do |
||
7158 | local sField = SkM_FormatMessageField(arg[i]); |
||
7159 | sParam = sParam..sField.." "; |
||
7160 | end |
||
7161 | |||
7162 | sMsg = string.format("<SKM=%d>%s</SKM>", iCode, sParam); |
||
7163 | |||
7164 | SkM_Trace(FName, 3, "Formated message = "..snil(sMsg)); |
||
7165 | |||
7166 | SkM_SendGuildChannelMessage(sMsg); |
||
7167 | end |
||
7168 | |||
7169 | |||
7170 | function SkM_FormatMessageField(sField) |
||
7171 | local sOutput = sField; |
||
7172 | |||
7173 | sOutput = string.gsub(sOutput, "\\", "\\\\"); |
||
7174 | sOutput = string.gsub(sOutput, "\"", "\\\""); |
||
7175 | |||
7176 | return sOutput; |
||
7177 | end |
||
7178 | |||
7179 | |||
7180 | function SkM_GetMessageFields(sMsg) |
||
7181 | local FName = "SkM_GetMessageFields"; |
||
7182 | |||
7183 | local i=1; |
||
7184 | local iLen = string.len(sMsg); |
||
7185 | local iStartField; |
||
7186 | local bSpecial = false; |
||
7187 | local bInField = false; |
||
7188 | local sField = ""; |
||
7189 | local Fields = { }; |
||
7190 | |||
7191 | while (i <= iLen) do |
||
7192 | local sChar = string.sub(sMsg, i, i); |
||
7193 | |||
7194 | if (not bInField) then |
||
7195 | if (sChar == "\"") then |
||
7196 | bInField = true; |
||
7197 | elseif (sChar == " ") then |
||
7198 | -- skip |
||
7199 | else |
||
7200 | -- error |
||
7201 | SkM_Trace(FName, 1, "Unexpected character : '"..sChar.."' at position "..i); |
||
7202 | return nil; |
||
7203 | end |
||
7204 | else |
||
7205 | |||
7206 | if (sChar == "\\") then |
||
7207 | if ( bSpecial) then |
||
7208 | sField = sField..sChar; |
||
7209 | bSpecial = false; |
||
7210 | else |
||
7211 | bSpecial = true; |
||
7212 | end |
||
7213 | else |
||
7214 | if (sChar == "\"") then |
||
7215 | if (bSpecial) then |
||
7216 | sField = sField..sChar; |
||
7217 | bSpecial = false; |
||
7218 | else |
||
7219 | table.insert(Fields, sField); |
||
7220 | sField = ""; |
||
7221 | bInField = false; |
||
7222 | end |
||
7223 | else |
||
7224 | sField = sField..sChar; |
||
7225 | end |
||
7226 | |||
7227 | end |
||
7228 | end |
||
7229 | i = i + 1; |
||
7230 | end |
||
7231 | return Fields; |
||
7232 | end |
||
7233 | |||
7234 | |||
7235 | function SkM_ProcessChannelMessage(iCode, sValue) |
||
7236 | local FName = "SkM_ProcessChannelMessage"; |
||
7237 | |||
7238 | local Fields = SkM_GetMessageFields(sValue); |
||
7239 | |||
7240 | if (iCode == 1) then |
||
7241 | -- message = update player information |
||
7242 | if (table.getn(Fields) == 4) then |
||
7243 | local sName = Fields[1]; |
||
7244 | local sRace = Fields[2]; |
||
7245 | |||
7246 | local sClass = Fields[3]; |
||
7247 | local sLevel = Fields[4]; |
||
7248 | SkM_Trace(FName, 3, "Player update: Name="..sName..", Race="..sRace..", Class="..sClass..", Lvl="..sLevel); |
||
7249 | |||
7250 | |||
7251 | end |
||
7252 | else |
||
7253 | |||
7254 | end |
||
7255 | end |
||
7256 | |||
7257 | |||
7258 | function SkM_HandleChannelMessage(sMsg, sChannel, sSender) |
||
7259 | local FName = "SkM_HandleChannelMessage"; |
||
7260 | |||
7261 | if (sChannel == SKM_Context.GuildChannel) then |
||
7262 | SkM_Trace(FName, 3, "Message = "..snil(sMsg)); |
||
7263 | |||
7264 | |||
7265 | -- check if sender is a guild member, if not he should not be sending |
||
7266 | -- messages on this channel ! |
||
7267 | |||
7268 | if (not SkM_IsNameInGuild(sSender)) then |
||
7269 | SkM_Trace(FName, 2, "Sender : "..snil(sSender)..", not in your guild !"); |
||
7270 | else |
||
7271 | -- now handle the message |
||
7272 | --for iCode, sValue in string.gfind(sMsg, SKM_Context.Pattern.) do |
||
7273 | --"<SKM=%d>%s</SKM>" |
||
7274 | for iCode, sValue in string.gfind(sMsg, "<SKM=([0-9]+)>(.+)</SKM>") do |
||
7275 | if (sCode and sValue) then |
||
7276 | SkM_ProcessChannelMessage(iCode, sValue); |
||
7277 | end |
||
7278 | end |
||
7279 | end |
||
7280 | end |
||
7281 | end |
||
7282 | |||
7283 | |||
7284 | -- -------------------------------------------------------------------------------------- |
||
7285 | -- SkM_BuildGuildList |
||
7286 | -- -------------------------------------------------------------------------------------- |
||
7287 | -- Build a list of players currently in the guild. |
||
7288 | -- -------------------------------------------------------------------------------------- |
||
7289 | function SkM_BuildGuildList() |
||
7290 | local FName = "SkM_BuildGuildList"; |
||
7291 | |||
7292 | SkM_Trace(FName, 2, "Rebuild guild list"); |
||
7293 | |||
7294 | SKM_Context.GuildList = { }; |
||
7295 | |||
7296 | local iNumGuildMembers = GetNumGuildMembers(); |
||
7297 | |||
7298 | local i; |
||
7299 | for i=1, iNumGuildMembers, 1 do |
||
7300 | --Usage: name, rank, rankIndex, level, class, zone, group, note, officernote, online = GetGuildRosterInfo(index); |
||
7301 | local sName = GetGuildRosterInfo(i); |
||
7302 | |||
7303 | if (sName) then |
||
7304 | table.insert(SKM_Context.GuildList, sName); |
||
7305 | end |
||
7306 | end |
||
7307 | |||
7308 | end |
||
7309 | |||
7310 | |||
7311 | |||
7312 | |||
7313 | function SkM_AddGuildMessageToQueue(sMsg, iPriority) |
||
7314 | local FName = "SkM_AddGuildMessageToQueue"; |
||
7315 | |||
7316 | if (SKM_Context.QueueSendMessage == nil) then |
||
7317 | SKM_Context.QueueSendMessage = { }; |
||
7318 | end |
||
7319 | |||
7320 | local iMessagePriority = ifnil(iPriority, 0); |
||
7321 | |||
7322 | if (iMessagePriority == 0) then |
||
7323 | table.insert(SKM_Context.QueueSendMessage, { Message = sMsg; Priority = iMessagePriority } ); |
||
7324 | return; |
||
7325 | end |
||
7326 | |||
7327 | local i; |
||
7328 | local iQueueSize = table.getn(SKM_Context.QueueSendMessage); |
||
7329 | for i=1,iQueueSize,1 do |
||
7330 | if (SKM_Context.QueueSendMessage[i].Priority < iMessagePriority) then |
||
7331 | table.insert(SKM_Context.QueueSendMessage, { Message = sMsg; Priority = iMessagePriority }, i); |
||
7332 | return; |
||
7333 | end |
||
7334 | end |
||
7335 | table.insert(SKM_Context.QueueSendMessage, { Message = sMsg; Priority = iMessagePriority } ); |
||
7336 | |||
7337 | end |
||
7338 | |||
7339 | |||
7340 | |||
7341 | function SkM_ProcessQueue() |
||
7342 | local FName = "SkM_ProcessQueue"; |
||
7343 | |||
7344 | --local sDate = SkM_GetDate(); |
||
7345 | local sTime = GetTime(); |
||
7346 | local bProcess = false; |
||
7347 | |||
7348 | if (SKM_Context.QueueLastSentMessage == nil) then |
||
7349 | bProcess = true; |
||
7350 | else |
||
7351 | local iDiffTime = sTime - SKM_Context.QueueLastSentMessage; |
||
7352 | |||
7353 | --if (iDiffTime > SkM_GetOption("SendMessageMinDelay")) then |
||
7354 | if (iDiffTime > 1) then |
||
7355 | bProcess = true; |
||
7356 | end |
||
7357 | end |
||
7358 | |||
7359 | if (bProcess) then |
||
7360 | local sMsg = SKM_Context.QueueSendMessage[1].Message; |
||
7361 | table.remove(SKM_Context.QueueSendMessage, 1); |
||
7362 | |||
7363 | SkM_SendGuildChannelMessage(sMsg); |
||
7364 | |||
7365 | SKM_Context.QueueLastSentMessage = sTime; |
||
7366 | end |
||
7367 | |||
7368 | end |
||
7369 | |||
7370 | |||
7371 | |||
7372 | function SkM_SendWarList() |
||
7373 | local FName = "SkM_SendWarList"; |
||
7374 | local idx, val; |
||
7375 | for idx, val in SKM_Data[_RealmName][_PlayerName].EnemyHistory do |
||
7376 | -- nchnch |
||
7377 | |||
7378 | if (val[_SKM._atWar]) then |
||
7379 | -- local sMsg = |
||
7380 | |||
7381 | SkM_AddGuildMessageToQueue(sMsg, 0); |
||
7382 | end |
||
7383 | |||
7384 | end |
||
7385 | |||
7386 | end |
||
7387 | |||
7388 | |||
7389 | |||
7390 | |||
7391 | -- TEST functions |
||
7392 | |||
7393 | function SkM_CharCode(sIn) |
||
7394 | --local List = { }; |
||
7395 | local sOut = ""; |
||
7396 | local i; |
||
7397 | for i=1, string.len(sIn), 1 do |
||
7398 | --List.insert(string.byte(sIn, i)); |
||
7399 | sOut = sOut.."\\"; |
||
7400 | sOut = sOut..string.byte(sIn, i); |
||
7401 | end |
||
7402 | --return List; |
||
7403 | return sOut; |
||
7404 | end |
||
7405 | |||
7406 | function SkM_TestHonor() |
||
7407 | local FName = "SkM_TestHonor"; |
||
7408 | local sMsg = "Gorwald dies, honorable kill Rank: First Sergeant (Estimated Honor Points: 67)"; |
||
7409 | |||
7410 | |||
7411 | for sFoe, sRank in string.gfind(sMsg, SKM_Context.Pattern.Honor_Kill) do |
||
7412 | if (sFoe and sRank) then |
||
7413 | SkM_Trace(FName, 0, "Honor_Kill : Foe = "..sFoe..", Rank = "..sRank); |
||
7414 | |||
7415 | SkM_Trace(FName, 0, "Enemy player death detected (from chat, honor) : "..snil(sFoe)); |
||
7416 | --SkM_PvpEnemyDeath(sFoe, true, sRank); |
||
7417 | end |
||
7418 | end |
||
7419 | |||
7420 | end |
||
7421 | |||
7422 | |||
7423 | function SkM_RecMapZones() |
||
7424 | local FName = "SkM_RecMapZones"; |
||
7425 | |||
7426 | SkM_ClearDebugRecord(); |
||
7427 | SkM_SetDebugLevel(1); |
||
7428 | SkM_StartDebugRecord(); |
||
7429 | |||
7430 | local lv_Continents = { GetMapContinents() } ; |
||
7431 | for idx, val in lv_Continents do |
||
7432 | SkM_Trace(FName, 1, "Continent "..idx.." = "..val); |
||
7433 | local lv_Zones = { GetMapZones(idx) }; |
||
7434 | for idx2, val2 in lv_Zones do |
||
7435 | SkM_Trace(FName, 1, "Cont. "..idx..", Zone "..idx2.." = "..val2); |
||
7436 | end |
||
7437 | end |
||
7438 | |||
7439 | SkM_StopDebugRecord(); |
||
7440 | SkM_SetDebugLevel(-1); |
||
7441 | end |
||
7442 | |||
7443 | |||
7444 | |||
7445 | function test() |
||
7446 | local FName = "test"; |
||
7447 | local idx, val; |
||
7448 | for idx, val in getfenv() do |
||
7449 | if (type(val) == "string" ) then |
||
7450 | SkM_Trace(FName, 0, idx.." = "..val); |
||
7451 | end |
||
7452 | end |
||
7453 | end |
||
7454 | |||
7455 | -- OBSOLETE stuff |
||
7456 | |||
7457 | |||
7458 | |||
7459 |