-------------------------------------------------------------------------------------------------------
- Sku Anniversary Addon Release Notes (Deutsch)
-------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v43.10
Ueberblick
Neu
Auren: neue Basis-Aura "Dein Ziel wechselt auf ein Gruppenmitglied". Wendet sich der Gegner, den du im Ziel hast, einem anderen Mitglied zu, gibt es einen Ton und das Mitglied wird mit seiner Tastennummer genannt, in Gruppe und Raid.
Aenderungen
Rollenerkennung: der Gesundheitsmonitor erkennt Tank, Heiler und Schaden jetzt auch fuer Raid-Mitglieder 26 bis 40 automatisch. Bisher nur bis Platz 25.
Fokus: /focus1 bis /focus8 nehmen jetzt alle Raid-Plaetze an (raid1 bis raid40), bisher nur bis raid25.
Auren: neue Einheiten-Werte "gruppen- oder raidmitglieder" und "... ohne dich". Sie gelten fuer den ganzen Raid; die bisherigen Gruppen-Werte erfassen im Raid nur die eigene Untergruppe.
Fehlerbehebungen
Monitor Kampf: die Bedrohungswarnungen loesten seit v43.9 einen Lua-Fehler aus (aqCombat.lua:380, UnitGUID) und blieben stumm, zum Beispiel wenn man in einer Gruppe Aggro zog. Behoben.
Monitor Kampf: Bedrohungswarnungen wieder hoerbar
Einfach: Wer in einer Gruppe Aggro zog oder kurz davor war, bekam seit v43.9 statt der
Warnung einen Fehler. Die Warnungen "Bedrohung hoch" und "Bedrohung niedrig" kommen
wieder. Sie nennen keinen Spieler, das haben sie nie getan; die Notizen zu v43.9
hatten das falsch beschrieben.
Technisch: die vier Ausgaben der beiden Warnungen gaben unit1 = tAllPartyRaidUnits[x] mit,
ohne dass es dort ein x gibt, also immer nil; ihre Vorlagen enthalten kein ${unit1}.
v43.9 schickte den Wert durch tSpokenGroupUnit, und das rief UnitGUID(nil) auf. Das
Argument ist entfernt, tSpokenGroupUnit gibt bei nil jetzt nil zurueck.
Rollenerkennung: Raid-Plaetze 26 bis 40
Einfach: Der Gesundheitsmonitor im Raid spricht seit v43.9 auch die Mitglieder 26 bis 40.
Ihre Rolle wurde aber nicht automatisch erkannt. Das geht jetzt.
Technisch: RoleCheckerIsUnitGUIDInPartyOrRaid kannte nur raid1 bis raid25, die Grenze ist
weg. RoleCheckerGetUnitRole stuerzte ab, wenn das gefragte Mitglied beim Aufraeumen
der Rollendaten als nicht mehr in der Gruppe entfernt wurde, und las am Ende eine
Variable ausserhalb ihres Gueltigkeitsbereichs. Beides behoben.
Fokus: alle 40 Raid-Plaetze
Einfach: "/focus3 raid30" speicherte bisher den Text "raid30" als Namen, die Fokustaste
fand dann niemanden. Jetzt wird wie bei raid1 bis raid25 der Name des Mitglieds
gespeichert.
Technisch: tFocusUnitIds (skuFocus.lua) kannte raid, raidpet und ihre target-Ketten nur
fuer 1 bis 25, jetzt bis MAX_RAID_MEMBERS.
Auren: Basis-Aura "Dein Ziel wechselt auf ein Gruppenmitglied"
Einfach: Fuer Tanks. Unter Neue Aura, Basis-Auren. Wechselt der Gegner, den du im Ziel
hast, auf ein anderes Gruppen- oder Raidmitglied, gibt es einen Ton und Sku sagt, wer
es ist: "party 3" in der Gruppe (die Numblock-Taste), die Dial-Nummer im Raid. Kommt
er zu dir zurueck, bleibt es still. Unter "Wer" laesst sich einschraenken, wer
beobachtet wird. Das ist die Aura aus dem alten Krieger-Schutz-Set, das man seit
Langem nicht mehr laden kann, mit einer genaueren Bedingung.
Technisch: Ereignis UNIT_TARGETCHANGE, Quelle enthaelt target und ist angreifbar, Ziel =
der gewaehlte Wert (vorbelegt raidWoPlayer), Ausgabe Ton plus Zieleinheit. Das alte
Set pruefte nur "Quelle ist kein Gruppenmitglied"; weil Sku die Ziele aller 40
Raid-Plaetze verfolgt, loeste dort auch ein Heiler aus einer anderen Untergruppe aus,
der jemanden anwaehlte. Basis-Auren koennen jetzt einen anderen Wert als einen
Zauber abfragen (valueLabel, emptyValueMessage, defaultValues).
Auren: Werte fuer den ganzen Raid
Einfach: Bei Quelle, Ziel und "Ziel deines Ziels" gibt es zwei neue Werte:
"gruppen- oder raidmitglieder" (mit dir) und "gruppen- oder raidmitglieder ohne
dich". In einer Gruppe verhalten sie sich wie die Gruppen-Werte, im Raid gelten sie
fuer alle Mitglieder. Die alten Gruppen-Werte bleiben wie sie sind: im Raid nur die
eigene Untergruppe.
Technisch: tEvaluateRaidValue (data.lua) prueft die Einheitenmenge auf party1-4 und
raid1-40. "Ohne dich" heisst: kein "player" in der Menge, weil GetBestUnitId fuer
dich im Raid auch deinen raidN-Platz liefert.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v43.9
Ueberblick
Neu
Raid-Untergruppen-Tasten: Alt+Numblock 1 bis 8 nimmt das erste Mitglied der Raid-Gruppe 1 bis 8 ins Ziel. Bei leerer Gruppe heisst es "Gruppe N leer" und nichts passiert; ausserhalb eines Raids "Kein Schlachtzug". Eigenes Untermenue "Raid-Untergruppen Tasten" in der Sku-Tastenbelegung, abschaltbar unter Funktionen.
Aenderungen
Auren: Basis-Auren bieten unter "Ausgabe" jetzt dieselbe Ausgabeliste wie eigene Auren, also alle Toene und alle Datenausgaben (zum Beispiel Zaubername oder Zieleinheit), auch mehrere gleichzeitig. Bisher gab es dort nur einen einzelnen Ton.
Berufs- und Lehrerfenster: nach Herstellen, Lernen oder Auswaehlen wird das Menue leise aufgefrischt, der Cursor bleibt auf demselben Eintrag, und nur ein wirklich anderer Eintrag wird angesagt.
Monitor Kampf: "Tode ansagen" nennt in einer Gruppe jetzt die Numblock-Taste des Gestorbenen: "party 5, dead" heisst, Numblock 5 ist tot. Das aendert einen sehr alten Standard, bisher wurde das vierte Gruppenmitglied als "party 4" angesagt.
Monitor Kampf: im Raid sagt "Tode ansagen" die Dial-Targeting-Nummer des Gestorbenen, also die Taste oder Ziffernfolge, die ihn anwaehlt. Bisher hiess es "party 2" fuer die eigene Untergruppe und "raid 17" fuer alle anderen. Raid-Plaetze 26 bis 40 werden jetzt auch angesagt.
Monitor Kampf: "Tode hochzaehlen" ist entfernt.
Monitor Gesundheit: "Tot bei 0 Prozent anhaengen" ist jetzt standardmaessig aus, fuer Gruppe und Raid, auch bei bestehenden Charakteren.
Dial Targeting: nur noch im Raid. "Aktiviert" ist ein Ein/Aus-Schalter; in einer Gruppe bleiben Numblock 1 bis 5 die normalen Zieltasten (1 = selbst, 2 bis 5 = die anderen).
Dial Targeting: in Raids bis 10 Spieler immer eine Taste pro Mitglied (0 = Mitglied 10), ab 11 Spielern zweistellig. Die Option "Nur ein Tastendruck in Raids bis 10 Spieler" ist weg, das ist jetzt die Regel.
Monitor Gesundheit, Raid: die Nummern sind die Dial-Targeting-Nummern, in Raids bis 10 Spieler also 1 bis 10 in Untergruppenreihenfolge. Bisher immer zweistellig gezaehlt, in einem 10er-Raid mit jemandem in Gruppe 3 hiess Taste 7 darum "11".
Monitor Gesundheit, Raid: Mitglieder mit Nummer 26 bis 40 werden jetzt gesprochen (Nummer, dann Prozent in Zehnern) mit der neuen Einstellung "Stimme fuer Mitglieder ab 26". Tonhoehen-Dateien gibt es nur bis 25, diese Mitglieder waren bisher stumm.
Monitor Debuffs, Raid: die Nummern sind ebenfalls die Dial-Targeting-Nummern.
Monitor Kampf: Bedrohungswarnungen, "Ziel des Ziels" und "ausser Reichweite" nennen Gruppenmitglieder wie die Todesansage, mit der Numblock-Taste in der Gruppe ("party 2" fuer das erste Mitglied) und der Dial-Nummer im Raid. Bisher der rohe Raid-Platz und "party 1" fuer Taste 2; Raid-Plaetze 26 bis 40 fehlten ganz.
Auren: die Ausgaben "Quelleinheit" und "Zieleinheit" nennen Gruppenmitglieder ebenso mit der Tastennummer und Raid-Mitglieder mit der Dial-Nummer.
Fehlerbehebungen
Quest-Menue: "Route" unter einer Kreatur war immer leer, wenn ihr Name einen Bindestrich oder eine Klammer enthaelt (zum Beispiel "Un'Goro-Gorilla", "Goblin-Ingenieur"). Behoben.
Nahe Route: die Suche nach verbundenen Wegpunkten in der Naehe eines Ziels lieferte oft weniger als die zehn naechsten. Hat sehr wahrscheinlich nie jemanden getroffen, reine Korrektheit.
Auren: "Alle Auren loeschen" loeschte mit einem einzigen Tastendruck alle Auren, ohne nachzufragen. Jetzt kommt wie beim Loeschen einer einzelnen Aura zuerst "Wirklich loeschen?".
Berufs- und Lehrerfenster: nach jedem Herstellen oder Lernen wurde der Fenstername angesagt, und der Cursor sprang manchmal auf einen anderen Eintrag. Behoben.
Berufsfenster: Enter auf einem Rezept oder auf "Erstellen" sagte den Eintrag zweimal an. Behoben.
Briefkasten: beim Oeffnen wurde zuerst "Ziel" angesagt, bevor "Neuer Brief" kam. Behoben.
Tastenbelegung: die zweite Taste ("Sekundaere Taste neu belegen") war fuer eine Reihe von Tasten wirkungslos, darunter "Monitor Gruppe fortlaufende Ausgabe ausloesen", Zielentfernung, Panikmodus, Minimap-Scan, Reichweitenpruefung der Gruppe, "Zu Einheit drehen" und die Scan-Tasten. Behoben.
Monitor Kampf: "Tote Gruppenbegleiter ignorieren" sprang nach jedem Neuladen auf "Ja" zurueck. Behoben.
Monitor Debuffs, Raid: die fortlaufende Ausgabe sagte Raid-Platz plus eins, eine Nummer, die niemandem gehoerte. Behoben.
Monitor Kampf: "party 5, dead" (viertes Gruppenmitglied, neu in dieser Version) piepte bei "Nur Nummern" aus, weil es kein Sprachwort "party5" gibt. Es wird jetzt "party" und "5" gesagt.
Quest-Menue: "Route" findet Kreaturen mit Bindestrich im Namen
Einfach: Im Quest-Menue (Annahme, Ziel, Abgabe) bietet eine Kreatur "Route", "Nahe Route"
und "Wegpunkt". "Route" sagte "Liste leer", sobald der Name der Kreatur einen
Bindestrich, eine Klammer oder ein aehnliches Zeichen enthielt, auch wenn die Kreatur
gut an das Wegenetz angebunden ist. Im deutschen Client betraf das 249 Kreaturen,
darunter alle drei Affenarten im Krater von Un'Goro. "Nahe Route" und "Wegpunkt" waren
nicht betroffen.
Technisch: SkuQuest/Options.lua, CreateRtWpSubmenu, Zweig "Route": string.find(i, wpName)
ohne plain-Argument las den Wegpunktnamen als Lua-Muster. Dort ist "-" ein Quantor
("o-" = beliebig viele o), der Name fand sich also nie selbst. Jetzt
string.find(i, wpName, 1, true) an beiden Stellen. Die Routendaten im Krater waren in
Ordnung (geprueft: Links, Spawn-Indizes und Anbindung an das Wegenetz).
Nahe Route: die zehn naechsten verbundenen Wegpunkte werden wirklich gefunden
Einfach: Die meisten Kreaturen sind nicht selbst an das Wegenetz angebunden. Fuer "Nahe
Route" sucht Sku darum bis zu zehn verbundene Wegpunkte im Umkreis von 500 Metern um das
Ziel und nimmt den besten erreichbaren davon. Diese Suche lieferte oft weniger als zehn.
Der naechste Wegpunkt war aber immer dabei, und das Wegenetz ist fast ueberall
zusammenhaengend. Das hat sehr wahrscheinlich nie jemanden getroffen; die Korrektur ist
nur der Korrektheit wegen da. Sichtbar geworden waere der Fehler nur, wenn der naechste
Wegpunkt auf einem abgetrennten Stueck des Wegenetzes liegt: dann "Liste leer" oder ein
kleiner Umweg.
Technisch: SkuNav:GetNearestWpsWithLinksToWp (SkuNav/Core.lua). Das sortierte Einfuegen
kannte keinen Anhaenge-Fall: ein Kandidat, der weiter weg war als alle Eintraege, fiel
weg, obwohl die Liste noch Platz hatte. Der erste Treffer von pairs() setzte damit die
Obergrenze. Das Kuerzen bei mehr als N Eintraegen entfernte schon immer den
entferntesten und bleibt. Offline gegen "die N naechsten" geprueft (20000 Zufallsfaelle):
alt 9059 zu kurz, neu alle richtig. Alle fuenf Aufrufer werten die ganze Liste aus und
nehmen den besten erreichbaren Eintrag, mehr Kandidaten koennen also nur gleich gute oder
bessere Routen ergeben.
Auren: Basis-Auren haben die volle Ausgabeliste
Einfach: Unter "Neue aura", "Basis-Auren" hatte jede Vorlage einen Eintrag "Ton", in dem
man genau einen Ton auswaehlen konnte, sonst nichts. Dieser Eintrag heisst jetzt
"Ausgabe", mit der Anzahl der eingeschalteten Ausgaben dahinter, und oeffnet dieselbe
Liste wie bei einer eigenen Aura: alle Toene und alle Datenausgaben, zum Beispiel
Zaubername oder Zieleinheit. Jeder Eintrag ist ein Schalter, Enter schaltet ihn ein oder
aus, und mehrere duerfen gleichzeitig an sein. Was die Vorlage bisher vorgab (ihr Ton,
bei "Dein Buff auf Gruppenmitglied ausgelaufen" zusaetzlich Zaubername und Zieleinheit),
ist beim Oeffnen schon eingeschaltet und laesst sich jetzt auch abschalten.
Technisch: SkuAuras/Options.lua. tBuildOutputsLevel nimmt einen optionalen Kontext
(outputs, ownerLabel, tooltip); ohne ihn bearbeitet die Liste wie bisher den Entwurf
des Aura-Baukastens, mit ihm die Liste des Basis-Formulars. Das Formular (tBaseForm)
fuehrt statt eines einzelnen sound-Werts eine Liste outputs, vorbelegt aus defaultSound
und defaultOutputs (vorher fixedOutputs, die beim Erstellen fest angehaengt wurden).
Zusammenfassung und tBaseFormCommit lesen diese Liste; ist keine Ausgabe an, bleibt es
bei "Keine Ausgabe festgelegt".
Auren: "Alle Auren loeschen" fragt nach
Einfach: "Alle Auren loeschen" im Auren-Menue hatte keine Unterebene: ein Enter oder Pfeil
rechts, und alle Auren des Charakters waren weg. Jetzt fuehrt der Eintrag, wie beim
Loeschen einer einzelnen Aura, auf "Wirklich loeschen?". Erst Enter dort loescht, Pfeil
links bricht ab.
Technisch: SkuAuras/Options.lua, MenuBuilder: der Eintrag ist jetzt dynamic und legt per
BuildChildren den einen Kindeintrag "Wirklich loeschen?" an. Beim Betreten zeigt
selectTarget auf den Eintrag selbst, Enter auf dem Kind ruft dessen OnAction. Vorher
dynamic = false ohne Kinder, OnPostSelect lief also direkt in den OnAction-Zweig.
Menue: Pfade werden aufgeloest statt durchlaufen
Einfach: Immer wenn Sku das Menue selbst an eine bestimmte Stelle setzt (ein Fenster geht
auf, eine Schnelltaste wie Umschalt-F10, oder ein Fenster hat sich geaendert und sein
Menue wird neu aufgebaut), lief es bisher den Pfad dorthin ab, als wuerde auf jeder
Ebene Enter gedrueckt, und sagte jede Zwischenstation an. Beim leisen Neuaufbau eines
Berufs- oder Lehrerfensters nach Herstellen oder Lernen hoerte man darum den
Fensternamen ("Beruf", "Lehrer"), und der Cursor wurde nach Zeilennummer
zurueckgesetzt, in einer Liste, die sich gerade veraendert hatte. Jetzt wird der
Zielpfad direkt aufgeloest, ohne Ansage der Zwischenstationen, und der Cursor kehrt zu
demselben Eintrag zurueck: dasselbe Rezept (auch mit neuer Anzahl), dieselbe
Faehigkeit, derselbe Knopf. Nur wenn dieser Eintrag weg ist, wird angesagt, wo der
Cursor gelandet ist.
Technisch: SkuOptions:ResolveMenuPath und EnsureLevelBuilt (SkuZOptions/Core.lua) ersetzen
die Schleife in SlashFunc, die auf jedem Pfadsegment OnSelect(true) aufrief. Ebenen auf
dem Weg werden nur gebaut (dynamic: RebuildNodeChildren, sonst einmal BuildChildren,
wenn leer), nie selektiert; nur das Ziel bekommt sein OnSelect wie bisher (Vorbau bei
leerer, nicht dynamischer Ebene, nie auf isSkuToggle). Damit entfallen die
Nebenwirkungen des Durchlaufs: actionOnEnter-Knoten auf dem Weg wurden ausgeloest, alle
Geschwister vor dem Treffer vorgebaut. Der aSilent-Parameter von SlashFunc wirkt jetzt.
Die Wiederherstellung in SkuCore:CheckFrames macht einen stillen Aufruf statt zwei
sprechender und setzt den Cursor direkt: skuIdentity, dann Name, dann die Zeile am
alten Index (begrenzt auf die neue Laenge). Fenster-Eintraege tragen skuIdentity
(SkuIterateGossipList kopiert es): Rezepte "recipe:Name (Rang)", Kategorien "cat:",
Lehrer-Faehigkeiten "skill:", sonst "frame:" fuer jeden Eintrag, der allein auf
seinem Frame steht (SkuCore:PrepareWindowEntries am Ende der drei Builder).
SkuCore:RefreshWindowMenuQuietly (LocalMenu.lua) ist der gemeinsame leise Neuaufbau
fuer TRADE_SKILL_UPDATE/CRAFT_UPDATE und den Lehrer-Knopf; er spricht nur, wenn
Identitaet (oder der Name ohne Anzahl) hinterher eine andere ist. Die Taschen behalten
ihren eigenen Pfad (tFindMenuNodeByPath, tBagAnnounceSuppress).
Berufsfenster: Enter auf Rezept oder "Erstellen" sagte den Eintrag doppelt an
Einfach: Nach Enter auf einem Rezept oder einem Erstellen-Knopf wurde der Eintrag zweimal
gesprochen. Jetzt einmal.
Technisch: Der klassische Klickpfad in SkuIterateGossipList rief nach func ein sprechendes
CheckFrames und 0,35 s spaeter OnUpdate auf, zusaetzlich zur Ansage des Tastenhandlers.
Die dritte Ansage fing meist die Dubletten-Sperre (1 s) ab, die zweite kam 0,9 s spaeter
und nicht. Eintraege mit quietClick (gesetzt von PrepareWindowEntries fuer alle
Klick-Knoepfe ohne containerFrameName) laufen jetzt ueber func plus
RefreshWindowMenuQuietly; Knoepfe mit sicherem /click behalten den alten Pfad.
Briefkasten: "Ziel" vor "Neuer Brief"
Einfach: Beim Oeffnen eines Briefkastens wurde zuerst "Ziel" angesagt und dann erst "Neuer
Brief". Jetzt nur noch "Neuer Brief".
Technisch: Mail:MAIL_SHOW oeffnete den Pfad "Lokal, Post", bevor der MailFrame sichtbar war;
der Post-Eintrag unter Lokal existiert aber nur bei sichtbarem Frame. Der Pfad fand
nichts, und das stille Oeffnen sagte ersatzweise den ersten Wurzeleintrag an ("Ziel",
das Zielmenue); die Taschen holten das Menue kurz darauf ueber CheckFrames in die Post.
Das Debug-Log zeigte "path walk found nothing ... short,lokal,post" bei jedem
Briefkasten seit mindestens v43.6; aufgefallen ist es erst, als die Zwischenansagen weg
waren. Jetzt oeffnet MAIL_SHOW einen Frame spaeter (C_Timer.After(0)), nur bei
sichtbarem MailFrame und nur, wenn der Cursor nicht schon in der Post steht.
Tastenbelegung: zweite Taste fuer Monitor, Scan, Drehen und Co.
Einfach: Unter "Sku Tastenbelegung" hat jede Taste eine erste und eine zweite Belegung.
Fuer eine Reihe von Tasten liess sich die zweite zwar setzen und wurde auch als
"Taste 2" angesagt, tat aber nichts. Betroffen waren "Monitor Gruppe fortlaufende
Ausgabe ausloesen", Zielentfernung, Panikmodus, Minimap-Scan weit und eng,
Reichweitenpruefung der Gruppenmitglieder, "Zu Einheit drehen" 1 bis 6 und 180 Grad,
"Scan fortsetzen", Scan 1 bis 8 und die Ressourcen-Benachrichtigung. Jetzt wirkt die
zweite Taste ueberall. Ausserdem heisst die Monitor-Taste jetzt richtig "fortlaufende"
statt "forlaufende".
Technisch: SkuCore/Core.lua, OnHide-Script von SkuCoreControlOption1: die Bindungen dieses
Frames wurden mit SetOverrideBindingClick nur fuer .key gesetzt (einzige Ausnahme war
SKU_KEY_TAXICANCEL), der Click-Dispatcher prueft per SkuKeyBindsMatchKey aber beide
Felder. Die Tastenbelegungs-Menues in SkuZOptions/Core.lua setzen key2 seit jeher, daher
funktionierte die zweite Taste bei anderen Aktionen. Ein lokaler tArm(aConst)-Helfer
bindet jetzt jede Taste, die SkuKeyBindsGetKeys liefert; die zwanzig handgeschriebenen
Einzelzeilen sind weg.
Monitor Kampf: Todesansage nennt die Numblock-Taste
Einfach: Unter Monitor, Kampf, Freundlich, "Tode ansagen" wird ein gestorbenes
Gruppenmitglied angesagt. Die Nummer darin ist jetzt immer die Taste, die das Mitglied
anwaehlt. In einer Gruppe sind das Skus Standardtasten: Numblock 1 = selbst, 2 bis 5 =
die vier anderen. Das vierte Gruppenmitglied heisst darum jetzt "party 5, dead", nicht
mehr "party 4". So zaehlen der Gesundheitsmonitor und die Uebersicht seit jeher. Im Raid
wird die Dial-Targeting-Nummer angesagt: bis 10 Spieler die eine Taste, ab 11 die
zweistellige Folge. Bisher hiess es dort "party 2" fuer Mitglieder der eigenen
Untergruppe und "raid 17" (der rohe Raid-Platz) fuer alle anderen, zwei Zaehlungen in
einem Kampf, keine davon passte zum Numblock. Raid-Plaetze 26 bis 40 wurden gar nicht
angesagt. "Tode hochzaehlen" ist entfernt: im Modus "nur Nummer" war sein "3, dead"
nicht von "party 3, dead" zu unterscheiden, und der Zaehler ging bei einer
Wiederbelebung nie zurueck.
Technisch: SkuCore/aqCombat.lua, aqCombat_SKU_UNIT_DIED. Neuer Helfer tDeathUnitToken(GUID)
liefert gesprochenes Token und echte Unit-ID getrennt, die Pruefungen UnitIsDeadOrGhost
und Begleiter brauchen den rohen Platz. Gruppe: Token aus aqCombatGroupGuidToUnitId,
Ziffer plus 1. Raid: alle MAX_RAID_MEMBERS Plaetze per GUID durchsucht (die 25 in
tAllPartyRaidUnits reichten nicht), Nummer aus dem Dial-Targeting-Raster gelesen
(SkuSecureTargetingFrame, unitNameSlotGG-SS, Taste = (GG-1)*5+SS; Attribute eines
Secure-Frames darf unsicherer Code lesen), sonst tDTRaidRoster aus aq.lua, sonst live
(Untergruppe-1)*5+Position. Raster und Roster werden nur ausserhalb des Kampfes neu
gebaut, veralten also gemeinsam mit dem Numblock. partyDeadCount samt Zaehler, Menue
und Locale-Schluessel entfernt, der gespeicherte Wert wird beim Login geloescht.
Monitor Kampf: "Tote Gruppenbegleiter ignorieren" bleibt auf Nein
Einfach: Die Einstellung liess sich auf "Nein" stellen, stand nach dem naechsten Neuladen
aber wieder auf "Ja". Behoben.
Technisch: aqCombatOnLogin setzte den Wert mit "x or true"; ein gespeichertes false ist in
Lua falsch und wurde so bei jedem Laden durch true ersetzt. Jetzt nur noch bei nil.
Monitor Gesundheit: "Tot bei 0 Prozent anhaengen" standardmaessig aus
Einfach: Der Tonhoehen-Stil des Gruppen- und Raid-Gesundheitsmonitors haengt an den Ton
eines Mitglieds mit 0 Prozent einen "dead"-Clip an. Das war fuer Gruppe und Raid
eingeschaltet und ist jetzt aus, auch bei bestehenden Charakteren. Wer es will, schaltet
es unter Monitor, Gruppe beziehungsweise Raid, Gesundheit wieder ein. Die Todesansage
des Kampfmonitors (oben) ist damit die einzige Todesmeldung, die von sich aus laeuft.
Technisch: SkuCore/aq.lua, AqOnLogin: Vorgabe false statt true, einmalige Umstellung
bestehender Charaktere ueber addDeadOn0PercentDefaultOff (Muster wie *DefaultOff in
aqCombat).
Dial Targeting: nur noch im Raid, eine Taste bis 10 Spieler
Einfach: "Aktiviert" unter Dial Targeting ist jetzt ein Ein/Aus-Schalter und wirkt nur im
Raid. Die Auswahl "Gruppe" und "Gruppe und Raid" ist weg: in einer Gruppe erreichen
Skus Standardtasten Numblock 1 bis 5 ohnehin jeden, und der Gruppenmodus legte eine
verschobene Zaehlung (0 = selbst, 1 bis 4 = die anderen) darueber und verdeckte die
Standardtasten, solange er aktiv war. Gespeichertes "Gruppe" wird zu Aus, "Raid" und
"Gruppe und Raid" zu Ein. In Raids bis 10 Spieler ist jetzt immer eine Taste pro
Mitglied aktiv (Numblock 1 bis 9, 0 = Mitglied 10, Reihenfolge nach Untergruppen), ab
11 Spielern die zweistellige Eingabe. Die Option "Nur ein Tastendruck in Raids bis 10
Spieler" ist weg, das ist jetzt die Regel.
Technisch: SkuCore/DialTargeting.lua. enabled wird beim Login einmalig auf Aus/Ein
abgebildet, singleKeyinRaid10 geloescht. DialTargetingRosterUpdate und
DialTargeting_EndableDisable pruefen nur noch UnitInRaid und enabled == Ein; der
Gruppenzweig (unitNameSlot01-0x = partyx) und der tote "party"-Zweig im Secure-Snippet
sind entfernt. Raid-Modus: tNumCurMembers > 10 heisst zweistellig, sonst raid10. Drei
Locale-Schluessel entfernt. Alles ungetestet im Spiel.
-------------------------------------------------------------------------------------------------------
Gruppennummern: eine Zaehlung fuer alle Monitore
Einfach: Jede Nummer, die Sku fuer ein Gruppenmitglied sagt, soll die Taste sein, die es
anwaehlt. In der Gruppe ist das Numblock 1 fuer dich und 2 bis 5 fuer die anderen; im
Raid die Dial-Targeting-Nummer, also eine Taste 1 bis 10 bei bis zu 10 Spielern und
zwei Ziffern ab 11. Die Todesansage zaehlt seit dieser Version so. Jetzt tun es auch der
Gesundheitsmonitor und der Debuff-Monitor im Raid, die Bedrohungswarnungen, "Ziel des
Ziels" und "ausser Reichweite" im Kampfmonitor sowie die Auren-Ausgaben "Quelleinheit"
und "Zieleinheit". Der Gesundheits- und der Debuff-Monitor fuer die Gruppe laufen im
Raid weiter mit der Gruppenzaehlung, denn wer im Raid nur seine Untergruppe im Blick
hat, waehlt sie dort mit Numblock 2 bis 5 an.
Der Gesundheitsmonitor im Raid hat Tonhoehen-Dateien nur fuer die Nummern 1 bis 25.
Mitglieder 26 bis 40 waren darum stumm; sie werden jetzt gesprochen, erst die Nummer,
dann die Gesundheit in Zehnerschritten, mit der Stimme aus der neuen Einstellung
"Stimme fuer Mitglieder ab 26" (Monitor, Raid, Gesundheit; Standard Justin).
Technisch: SkuCore/aq.lua: SkuCore.Monitor.RaidMemberNumbersByName() baut die Name-zu-
Nummer-Tabelle nach der Dial-Regel (bis 10 Mitglieder flach 1-10 in
Untergruppenreihenfolge, ab 11 (Untergruppe-1)*5+Position); tDTRaidRoster und das
Dial-Targeting-Raster (DialTargeting.lua) werden daraus gefuellt, bisher rechnete
tDTRaidRoster immer zweistellig. SkuCore.Monitor.GroupMemberNumber(unitId) liefert
die Tastennummer fuer party-/raid-Tokens. Die fortlaufende Debuff-Ausgabe im Raid
sagte string.sub(unitId, 5)+1. MonitorOutputRaidPercent2 spricht Nummern ueber 25
per MonitorOutputPlayerStatus (raid.health2.voice, Standard 1) und gibt die Dauer an
die Warteschlange zurueck; die Warteschlangen-Eintraege tragen dafuer die absolute
Gesundheit. SkuCore/aqCombat.lua: tAllPartyRaidUnits und
tUnitsToTestOnGameRaidTargets enthielten raid1-25 fest; sie werden jetzt bei jedem
Roster-Ereignis an Ort und Stelle aus der echten Raidgroesse neu gefuellt.
tSpokenGroupUnit(unitId) nutzt die Todesansage-Zuordnung fuer alle freundlichen
Ansagen. "party5"/"partypet5" gibt es in den Kampfstimmen nicht als Wort,
SkuCoreAqCombatGetVoiceString zerlegt sie in "party", "pet", "5". SkuAuras/data.lua:
tUnitIdToSpokenName sagt party N als N+1 und raid N als Dial-Nummer.
Raid-Untergruppen-Tasten: mit einer Taste in eine Raid-Gruppe springen
Einfach: Wer im Raid nur seine eigene Gruppe versorgt, braucht einen schnellen Einstieg in
eine Gruppe, ohne die zweistellige Dial-Eingabe. Alt+Numblock 1 bis 8 nimmt das erste
Mitglied der Raid-Gruppe 1 bis 8 ins Ziel (das Mitglied mit Nummer 1 in dieser Gruppe,
dieselbe Reihenfolge wie Dial Targeting und die Monitore). Das Ziel wird wie jedes
Ziel angesagt. Ist die Gruppe leer, sagt Sku "Gruppe N leer" und nichts passiert;
ausserhalb eines Raids "Kein Schlachtzug". Die acht Tasten haben ein eigenes
Untermenue "Raid-Untergruppen Tasten" in der Sku-Tastenbelegung, auch die zweite
Taste funktioniert. Die Funktion laesst sich unter Funktionen abschalten.
Wie bei allen Zieltasten gilt: Gruppenwechsel waehrend eines Kampfes werden erst nach
dem Kampf uebernommen, bis dahin springt die Taste zum alten ersten Mitglied.
Technisch: Neue Datei SkuCore/subgroupTargeting.lua (Untermodul SubgroupTargeting, in
der TOC nach skuFocus.lua). Acht SecureActionButtons SkuSubgroupTarget1-8 mit
type1=macro, macrotext1="/tar ", gebunden per SetOverrideBindingClick OHNE
fuenftes Argument (LeftButton, damit type1/macrotext1 gelesen wird); die Namen werden
aus GetRaidRosterInfo (erster Name je Untergruppe in Roster-Reihenfolge) bei
GROUP_ROSTER_UPDATE, GROUP_FORMED/JOINED/LEFT und PLAYER_ENTERING_WORLD ausserhalb
des Kampfes geschrieben, im Kampf auf PLAYER_REGEN_ENABLED verschoben. PreClick
(unsicher, laeuft auch im Kampf) spricht die Leer-/Kein-Raid-Meldung. Kontroll-Frame
SkuCoreSubgroupControl, Script OnHide, bewaffnet beide Tasten jeder Konstante ueber
SkuOptions:SkuKeyBindsGetKeys. Konstanten SKU_KEY_SUBGROUPTARGET1-8, Standard
ALT-NUMPAD1-8 (SkuZOptions/SkuKeyBinds.lua), Gruppe "Raid Untergruppen Tasten" in
SkuCore/Options.lua.
Aenderungen in Sku v43.8
Ueberblick
Neu
Spieleinstellungen: Kontrollkaestchen mit Regler oder Auswahlliste (zum Beispiel "Maximale Vordergrund-FPS"), Schaltflaechen, der Block "Grafikqualitaet" und die Farbenblindheits-Einstellungen sind jetzt bedienbar; bisher hiess es dort "nicht unterstuetzt".
Spieleinstellungen: Zahlenwerte haben als ersten Eintrag "Wert eingeben" (Textfeld), Ziffern filtern die Werteliste, und die Werte tragen die Beschriftung des Spiels ("60 FPS", "150%").
Spieleinstellungen: Auswahllisten sagen "(empfohlen)" und "(nicht verfuegbar)" wie das Spiel, ausgegraute Eintraege "(deaktiviert)", und Untermenues von AddOn-Einstellungen werden angezeigt.
Aenderungen
Fehlermeldungen des Spiels (zum Beispiel "Ihr habt kein Ziel") werden beim Haemmern auf eine Taste nur noch einmal vorgelesen. Dieselbe Meldung wird erst wieder angesagt, wenn du die Taste etwa zweieinhalb Sekunden in Ruhe gelassen hast oder wenn dazwischen eine andere Fehlermeldung kam.
Zum Beacon, Wegpunkt oder zur Einheit drehen: die Drehung landet jetzt auf jedem Rechner gleich genau und ist deutlich schneller. Bei 20 Bildern pro Sekunde dauerte eine halbe Drehung fast eine halbe Sekunde und jeder vierte Tastendruck ging verloren; jetzt eine Viertelsekunde, und kaum ein Druck geht verloren. Auf schnellen Rechnern treffen grosse Drehungen auf etwa ein Grad statt drei bis fuenf. Die Selbstkalibrierung aus v43.7 entfaellt.
Fehlerbehebungen
Sprachausgabe: dieselbe Zeile stellte sich seit v43.7 bei jedem Tastendruck erneut hinten an und wurde viele Male hintereinander vorgelesen, auch noch nach einer wichtigeren Ansage. Behoben.
Menue: wer direkt nach "Menue geoeffnet" schon eine Taste drueckte (Ende, Pos1, Pfeil), bekam nach dem neuen Eintrag noch den ersten Hauptmenue-Eintrag ("Ziel Menue") nachgesprochen. Behoben.
Sprachausgabe: dieselbe Zeile stellt sich nicht mehr hinter sich selbst an
Einfach: Seit v43.7 konnte eine Meldung, die mehrfach kurz hintereinander ausgeloest wurde,
sich beliebig oft in die Warteschlange stellen. Wer eine Taste haemmerte, die einen
Fehler ausloest, hoerte "Ihr habt kein Ziel" danach zehn- oder zwanzigmal, und nach einer
dazwischengehenden Zielansage kam die Meldung noch einmal. Jetzt gilt: wartet derselbe
Text schon oder wird er gerade gesprochen, wird die neue Kopie verworfen. Menuezeilen
und andere Ansagen, die du per Taste ausdruecklich noch einmal anforderst, sind nicht
betroffen.
Technisch: SkuVoice:OutputStringBTtts (Libs/SkuVoice-1.0). Die Pruefung "wird genau das
gerade gesprochen" lief bisher bei der Uebergabe an den Client. Seit dem Client-Gate aus
v43.7 erreicht eine Kopie die Uebergabe erst, wenn ihr Vorgaenger FINISHED ist - die
Pruefung traf nie mehr (Log: Warteschlange 35 x dieselbe Zeile). Zeilen ohne queuereset
werden darum jetzt beim EINREIHEN gegen mSkuVoiceQueueBTTS und
mSkuVoiceQueueBTTS_Speaking geprueft; Log-Marke "BTTS ENQUEUE-DUP". Neues
Harness-Szenario "errspam" (dev/rework-docs/voice-harness).
Menue: erster Eintrag kam nach einem schnellen Tastendruck verspaetet doch noch
Einfach: Beim Oeffnen des Menues sagt Sku "Menue geoeffnet" und danach den ersten
Eintrag. Wer schon waehrend "Menue geoeffnet" eine Taste drueckte, hoerte den neuen
Eintrag - und danach trotzdem noch "Ziel Menue", den ersten Eintrag, der gar nicht mehr
dran war. Es hing nur davon ab, wie schnell man drueckte, nicht von der Taste oder dem
Menue. Jetzt faellt der alte erste Eintrag weg, sobald ein anderer Menueeintrag angesagt
wird.
Technisch: Zwei Ursachen. (1) Die Regel "wartende Zeile ohne Reset hinter der neuen
Ueberschreibzeile aufheben" aus v43.7 (gedacht fuer Chat, in den eine Warnung
hineinschneidet) galt auch fuer Menuezeilen. Die Keep-Schleife in SkuVoice
(queuereset-Scan, Libs/SkuVoice-1.0) verwirft jetzt eine wartende Zeile, deren Scope mit
dem der neuen Ueberschreibzeile uebereinstimmt: ein Scope ist eine Position in einer
Oberflaeche, nur seine juengste Zeile ist wahr. (2) Die beiden Zeilen beim Oeffnen
("Menu;open" und SkuOptions.Menu[1].name, SkuZOptions/Core.lua) riefen OutputStringBTtts
direkt und OHNE den Scope "menu" auf, den VocalizeCurrentMenuName jeder anderen Menuezeile
gibt - der Scope-Vergleich hatte also nichts zu vergleichen. Beide tragen jetzt "menu";
damit verwirft auch EndScope("menu") beide, wenn das Menue sofort wieder geschlossen wird.
Log vorher: "BTTS queuereset kept 1 waiting line(s) behind the overwrite".
Fehlermeldungen: nur ansagen, wenn sie neu erscheinen
Einfach: Sku richtet sich jetzt nach der Regel, die das Spiel fuer Sehende anwendet. Dort
steht eine Fehlermeldung etwa zweieinhalb Sekunden auf dem Bildschirm; kommt dieselbe
Meldung in dieser Zeit noch einmal, blitzt sie nur kurz auf und bleibt laenger stehen,
statt neu zu erscheinen. Entsprechend liest Sku eine Fehlermeldung vor, wenn sie
erscheint, und schweigt, solange sie noch "auf dem Bildschirm steht". Jeder weitere
Tastendruck verlaengert diese Zeit. Das Klickgeraeusch des Spiels sagt dir weiterhin bei
jedem Druck, dass es noch nicht geht. Laesst du die Taste etwa zweieinhalb Sekunden in
Ruhe und drueckst dann wieder, wird die Meldung erneut angesagt. Eine ANDERE
Fehlermeldung wird immer sofort vorgelesen, und danach gilt auch die erste wieder als
neu: Fehler A, Fehler B, Fehler A sind drei Ansagen. Betrifft nur vorgelesene Fehler,
nicht die Ton- und Sprachhinweise.
Technisch: UIErrors:OutputError (SkuCore/UIErrors.lua), TTS-Zweig. Gemerkt wird nur der
ZULETZT gesprochene Fehler: tSpokenKey plus tSpokenShownUntil = GetTime() + 2.5
(displayDuration 2 + fadeDuration 0.5 aus UIErrorsFrame.xml). Jede Wiederholung setzt die
Zeit neu, wie ResetMessageFadeByID; jeder andere Fehler, auch ein Ton- oder
Sprachhinweis, ersetzt bzw. loescht tSpokenKey. Die erste Fassung fuehrte eine Zeitmarke
PRO Text - dadurch blieb Fehler A stumm, obwohl Fehler B dazwischen lag.
Bewusst eine Zeitmarke und kein Auslesen von UIErrorsFrame: Blizzard drosselt nur rund 20 Meldungstypen, bei den
uebrigen kommt pro Druck eine neue Zeile dazu, und die Reihenfolge der beiden
UI_ERROR_MESSAGE-Handler ist nicht festgelegt.
Spieleinstellungen: alle Bedienelemente der Blizzard-Einstellungen
Einfach: Im Menue Einstellungen, Spieleinstellungen waren viele Eintraege nur mit "(nicht
unterstuetzt)" zu hoeren, zum Beispiel "Maximale Vordergrund-FPS". Jetzt sind sie
bedienbar. Ein Kontrollkaestchen mit Regler wird zu zwei Eintraegen: dem Schalter und
"... Wert". Zahlenwerte sind eine Werteliste mit den Beschriftungen des Spiels ("60 FPS",
"150%"); Ziffern filtern die Liste, und der erste Eintrag "Wert eingeben" oeffnet das
Textfeld. Auswahllisten markieren die Empfehlung mit "(empfohlen)" und Werte, die dieser
Rechner nicht kann, mit "(nicht verfuegbar)". Schaltflaechen wie "Chatposition
zuruecksetzen" fuehren ihre Aktion aus. Der Block "Grafikqualitaet" ist ein Untermenue mit
"Schlachtzug und Schlachtfeld". Die Tastenbelegung verweist auf Skus eigenes Menue. Eine
Einstellung, die vom Spiel gerade ausgegraut ist, sagt "(deaktiviert)". Ausserdem wurden
Grafik-, Anzeige- und UI-Skalierungs-Einstellungen bisher nur vorgemerkt und nie
angewendet - sie greifen jetzt sofort.
Technisch: SkuCore/gameOptions.lua verzweigt jetzt nach dem Frame-Template des Initializers
(Blizzard_SettingControls.lua) statt nach dem Werttyp: Checkbox, Slider, Dropdown,
CheckboxSlider (cbSetting/sliderSetting), CheckboxDropdown, CheckboxWithButton, Button,
AdvancedQualitySection (die Optionslisten sind dort Closures im Frame; Sku leitet sie aus
einer Tabelle je CVar ab und fragt IsGraphicsSettingValueSupported), ColorblindSelector,
Keybinding-Sektionen. setting:SetValue(v) ohne zweites Argument legt bei Settings mit
CommitFlag.Apply nur einen pendingValue an, den erst der Apply-Knopf des Panels schreibt -
Sku oeffnet das Panel nie, darum jetzt SetValue(v, true) plus RestartGx / UpdateWindow /
SaveBindings je nach Commit-Flag. GetAllCategories liefert nur Top-Level-Kategorien,
GetSubcategories wird rekursiv gelaufen. ShouldShow false = Zeile entfaellt,
GetModifyPredicates false = Suffix "(deaktiviert)". Beschriftung der Zahlenwerte ueber
options.formatters[Label.Right]; eine Tippeingabe wird linear durch den Formatter
zurueckgerechnet (Prozent, Qualitaetsregler 1..10). Jeder Schreibzugriff loggt
"gameOptions: set". Ein Offline-Harness gegen gefakte Setting-Objekte lief durch; im Spiel
geprueft: FPS-Schalter und -Wert (Log: PROXY_FOREGROUND_FPS = 20, TurnCal fps 20).
Drehen zum Beacon: bildgenau statt zeitgenau
Einfach: Bisher drehte Sku die Kamera fuer eine berechnete Zeit und hielt sie dann an. Das
Spiel bewegt die Kamera aber nur einmal je Bild, und ein Zeitgeber trifft die Bildgrenze
nur ungefaehr - bei wenig Bildern pro Sekunde daneben. Auf einem langsamen Rechner (20
Bilder pro Sekunde, im Test per FPS-Begrenzung nachgestellt) dauerte darum jede Drehung
ueber 15 Grad fast eine halbe Sekunde, kleine Drehungen blieben ein Drittel zu kurz,
jeder vierte Tastendruck fiel in die Sperrzeit und ging verloren, und beritten kreiste
man wieder um nahe Wegpunkte. Jetzt zaehlt Sku die Bilder und rechnet mit ihrer echten
Dauer: die Drehgeschwindigkeit wird so gewaehlt, dass der Winkel in ganzen Bild-Schritten
aufgeht, und wuerde der letzte Schritt ueber das Ziel hinausschiessen, wird er verkuerzt.
Ergebnis bei 20 Bildern pro Sekunde: halbe Drehung in einer Viertelsekunde, alle Drehungen
innerhalb von zwei Grad, kaum verlorene Druecke, kein Kreisen. Bei 80 bis 120 Bildern:
grosse Drehungen mit etwa einem Grad Fehler statt drei bis fuenf, kleine unter einem
halben Grad. Die Selbstkalibrierung aus v43.7 ist weg - sie lernte Werte, die auf jedem
Rechner gleich sind. /skuturn zeigt nur noch, ob der schnelle Gang auf diesem Rechner
funktioniert; /skuturn reset setzt diese Pruefung zurueck.
Technisch: GameWorldObjects:TurnToWorldPosition (SkuCore/gameWorldObjects.lua). Gemessen an
rund 400 Drehungen bei 20 und 77 bis 125 fps (Restfehler 0.5 ms): die Kamera schreitet
einmal je Frame um Tempo mal ECHTE Framedauer; der Frame, in dessen OnUpdate der Stopp
faellt, schreitet nicht mehr; die im OnUpdate gemessene Framedauer ist genau die des
naechsten Schritts. Planer: n = ceil(Winkel / (1440 * f)) Schritte, v = Winkel / (n * f),
CVar hoechstens 360, Rest als MoveView-Faktor. Stopp aus einem OnUpdate-Zaehler, der die
echten Framedauern aufsummiert und stoppt, sobald die Summe die Bewegungszeit Winkel/v
erreicht; wuerde der letzte Schritt ueberschiessen, wird cameraYawMoveSpeed fuer diesen
einen Frame auf den Rest skaliert und im Folgeframe gestoppt - die CVar wirkt sofort (54
getrimmte Drehungen: Fehler 0.5 Grad statt der 5.3, die eine tote CVar ergeben haette).
C_Timer war die Ursache der alten Streuung: er feuert nur an Framegrenzen und faellt bei
2 Prozent Frame-Streuung um einen ganzen Frame. Das "Nachgleiten" der Kamera aus v43.7
war dieser eine Leerframe, keine Traegheit. Die Kalibrierung (Massstab und Latenz je
Gang, Store v4/v5) lernte 1.00 und einen Frame mit Streuung 0.01 und wurde entfernt;
Store turnCal v6 haelt nur noch noGear2 (Faktor wirkt nicht: Median echtes/verlangtes
Tempo unter 0.7 bei 6+ schnellen Drehungen). Sperrzeit nach dem Stopp 2 Frames bzw.
50 ms statt 3 bzw. 100. Log "TurnCal" je Druck mit n, m, mt, trim, dts (alle
Framedauern), fest/fact/fmax, rest_land, lead_shift; Analyse-Skripte im Scratchpad-Muster
an4.py. Lehren fuer WowVision: dev/rework-docs/TURN-TO-BEACON-LESSONS.md.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v43.7
Ueberblick
Aenderungen
Zum Beacon drehen (T), Zu Einheit drehen und Zum Ziel drehen: grosse Drehungen landen jetzt mit EINEM Druck. Bisher blieb jeder Druck bei etwa 88 Grad haengen, eine Kehrtwende brauchte immer zwei.
Drehungen sind deutlich schneller: eine halbe Drehung dauert auf einem flotten Rechner gut eine Zehntelsekunde statt einer Viertelsekunde.
Wer schon auf den Beacon ausgerichtet ist (innerhalb von 3 Grad), wird nicht mehr gedreht. Das beendet das Hin-und-her-Pendeln um den Beacon-Ping.
Die Drehung misst sich selbst ein: Sku prueft nach jeder Drehung, wie weit du wirklich gedreht hast, und passt sich an deinen Rechner und deine Bildrate an. Die ersten paar Drehungen nach dem Update koennen ungenau sein.
Tastaturecho mit einer echten Windows-Stimme (nicht die NVDA-Bruecke): die lange Pause nach jedem getippten Buchstaben ist weg, die Buchstaben folgen dicht aufeinander.
Text in ein Eingabefeld einfuegen (Strg+V): Sku sagt jetzt einmal "Eingefuegt", statt den eingefuegten Text Buchstabe fuer Buchstabe vorzulesen.
Fehlerbehebungen
Schwimmen und Fliegen: Die Neigungssperre greift jetzt auch im Kampf. Wer kaempfend ins Wasser lief, tauchte bisher bei den ersten Drehungen ab.
Gegenstaende aus einem Ausruestungsset: der Tooltip nannte die Ruestungsart (zum Beispiel "Stoff") zweimal. Jetzt nur noch einmal.
Sprachausgabe mit einer echten Windows-Stimme (nicht die NVDA-Bruecke): Zeilen, die laengst ueberholt waren, kamen Sekunden bis Minuten spaeter doch noch - getippte Filterbuchstaben nach "Menue geschlossen", uebersprungene Listeneintraege nach dem Loslassen der Pfeiltaste, Gildenchat eine Minute zu spaet. Behoben.
Menue: Oeffnete sich das Menue direkt in ein Fenster oder eine Liste (Tasche, Haendler, Umschalt+F10), kam nach dem Inhalt noch "Ziel Menue" hinterher. Behoben.
Echte Windows-Stimme: sprach ein anderes Addon waehrend des Tippens, konnte ein Buchstabe nach "abgebrochen" nachkommen. Behoben.
Drehen: schneller, genauer, selbst eingemessen
Einfach: "Zum Beacon drehen" (T) und die beiden anderen Drehbefehle wurden anhand von
Messungen im Spiel ueberarbeitet. Drei Dinge aendern sich spuerbar. Erstens: grosse
Drehungen kommen mit einem Druck an. Bisher schaffte ein Druck hoechstens etwa 88 Grad,
egal wie weit es gehen sollte - das war ein unbemerkter Fehler seit v43.2. Zweitens: die
Drehung ist schneller, eine Kehrtwende dauert nur noch gut eine Zehntelsekunde. Drittens:
bist du schon auf 3 Grad genau ausgerichtet, passiert bei einem weiteren Druck nichts mehr.
Frueher drehte jeder Druck mindestens 5 Grad, darum pendelte man um den Beacon-Ping herum
und kam nie zur Ruhe. Im Wasser spart das ausserdem unnoetige Tauchstupser.
Sku lernt dabei deinen Rechner: nach jeder Drehung wird gemessen, wie weit der Charakter
wirklich gedreht hat, und die naechste Drehung wird danach berechnet. Bei hoher Bildrate
dreht Sku von selbst flotter, bei niedriger langsamer und dafuer genau. Nach dem Update
sind die ersten paar Drehungen Lernschritte und duerfen danebenliegen. Sehr grosse
Drehungen nahe 180 Grad landen auf etwa 5 Grad genau; ab und zu verfeinert ein zweiter
Druck. Ein Druck waehrend einer laufenden Drehung wird wie bisher verworfen.
Technisch: GameWorldObjects:TurnToWorldPosition (SkuCore/gameWorldObjects.lua). Gemessen
2026-09-21: cameraYawMoveSpeed wirkt nur bis 360 - Werte darueber drehen nicht schneller
(376, 453 und 731 ergaben in 0.25 s alle ~88 Grad). Die Regel max(360, Winkel/0.25) aus
v43.2 deckelte darum jeden Druck still bei ~88 Grad. Mehr Tempo kommt nur ueber das
Argument von MoveViewLeftStart/MoveViewRightStart, das die CVar multipliziert (Technik
aus WowVision). Zwei Gaenge: Gang 1 = CVar allein bis 360 Grad/s, Gang 2 = CVar 360 mal
Faktor bis 1440 Grad/s. Modell je Gang: gedreht = k * Sollgeschwindigkeit * (Timerdauer
+ L); k ab der ersten Messung aus dem Median, ab 8 Messungen mit streuenden Dauern eine
Ausgleichsgerade fuer k und L. Geschwindigkeit nach Bildrate: die Stopp-Streuung ist
eine halbe Framedauer mal Tempo, erlaubt sind 3 Grad bzw. 6 Prozent des Winkels; nie
langsamer als Winkel/0.25 s; gebremst, wenn der Timer kuerzer als 2 Frames waere.
Multipliziert der Faktor auf einem Client nicht, legt Sku Gang 2 dauerhaft still.
Messwerte accountweit in SkuOptions.db.global.SkuCore.turnCal. Die Sperre gegen
Folgedruecke deckt jetzt auch die Nachmess-Wartezeit ab (ein Druck in dieser Luecke
rechnete mit der alten Blickrichtung). Jede Drehung schreibt eine Zeile "TurnCal" ins
Debug-Log. /skuturn zeigt den Stand, /skuturn reset verwirft die Messwerte, /skuturn
legacy schaltet auf das alte Verhalten. Gebaut, getestet und wieder ausgebaut: eine
Nachkorrektur im selben Druck - die Kamera hat Schwung und gleitet nach dem Stopp
weiter, ein Befehl in dieses Gleiten kostete bis zu 35 Grad.
Schwimmen und Fliegen: Neigungssperre greift auch im Kampf
Einfach: Die automatische Neigungssperre, die dich beim Schwimmen und Fliegen waagerecht
haelt, wartete bisher das Ende des Kampfes ab. Wer kaempfend ins Wasser ging, war
solange ungeschuetzt, und jede Beacon-Drehung drueckte ihn tiefer. Die Sperre greift
jetzt sofort. Auch die Taste Strg+Umschalt+N geht jetzt im Kampf.
Technisch: Die InCombatLockdown-Pruefungen in SkuCore:TogglePitchLock und im Automatik-
Tick (SkuCore/Core.lua) beruhten auf der ungeprueften Annahme, pitchlimit sei im Kampf
geschuetzt. Es ist ein Konsolenbefehl und im Kampf setzbar (getestet 2026-09-21). Im
Log desselben Tages lagen zwischen Schwimmbeginn und Sperre 6 Sekunden mit drei
ungeschuetzten Drehungen.
Tooltip von Set-Gegenstaenden: Ruestungsart wurde doppelt vorgelesen
Einfach: Gehoert ein Gegenstand zu einem deiner gespeicherten Ausruestungssets, fuegt Sku
im Tooltip die Zeile "Gehoert zu Set" ein. Bei genau diesen Gegenstaenden war danach
die Ruestungsart zweimal zu hoeren, zum Beispiel "Seelengebunden, Stoff, Kopf, Stoff".
Das erste "Stoff" war ein Rest und gehoerte dort nicht hin. Jetzt kommt es nur noch
einmal, hinter dem Platz: "Seelengebunden, Kopf, Stoff". Bei Waffen betraf das genauso
die Waffenart und das Tempo. Gegenstaende ohne Set waren nie betroffen.
Technisch: tInsertSetLineAtTop (SkuCore/equipmentSets.lua) schiebt alle Tooltip-Zeilen ab
Zeile 2 um eine nach unten. Die rechte Spalte wurde dabei nur geschrieben, wenn die
Quellzeile eine hatte. Die Zeile, aus der "Kopf | Stoff" wegwanderte, bekam links
"Seelengebunden" und behielt rechts ihr altes "Stoff". TooltipLines_helper liest jede
FontString-Region einzeln, darum war der Rest hoerbar. Die rechte Spalte wird jetzt
immer geschrieben: gesetzt und gezeigt, oder geleert und versteckt; ebenso in Zeile 2.
Der Fehler steckte seit v42.00 im Code und fiel erst mit gespeicherten Sets auf.
Sprachausgabe: ueberholte Zeilen kamen verspaetet doch noch (echte Windows-Stimmen)
Einfach: Betrifft nur Spieler, die Sku ueber eine echte Windows-Stimme sprechen lassen,
nicht ueber die NVDA-Bruecke. Dort konnte eine Zeile, die Sku laengst durch eine neuere
ersetzt hatte, im Spiel haengen bleiben und viel spaeter doch noch gesprochen werden:
Wer im Menue schnell einen Filter tippte, hoerte "g r" oder "g r e i f" erst nach
"Menue geschlossen". Wer die Pfeiltaste hielt, hoerte nach dem letzten Eintrag noch
zwei, drei uebersprungene. Und Chatzeilen, die waehrend des Blaetterns eintrafen, kamen
bis zu 70 Sekunden zu spaet und ausser der Reihe. In einem eingeschickten Log waren
das 24 von 524 Ansagen in einer halben Stunde. Das ist behoben: was Sku ersetzt oder
abgebrochen hat, bleibt stumm. An den Regeln, was was unterbrechen darf, aendert sich
nichts. Auch das Mischen bleibt: schiebt sich eine wichtige Ansage in eine Reihe
wartender Zeilen (Chat, Statusmeldungen), spricht sie zuerst, danach geht die Reihe
weiter, die aelteste Zeile zuerst. Nur was dabei aelter als 30 Sekunden geworden ist,
wird verworfen.
Technisch: Libs/SkuVoice-1.0. C_VoiceChat.StopSpeakingText beendet nur die Aeusserung, die
gerade SPIELT. Eine uebergebene, aber noch nicht gestartete erreicht es nicht, und alles,
was uebergeben wird, waehrend eine andere noch im Client ist, wird dort geparkt und
startet erst beim naechsten natuerlichen PLAYBACK_FINISHED - egal wie viele Stopps
dazwischen liegen. Neu: ein gemeinsames Tor (mClientGate) fuer ALLE Uebergaben. Sku
uebergibt dem Client hoechstens EINE Aeusserung; die naechste Zeile wartet in Skus
eigener Warteschlange auf FINISHED/FAILED mit passender ID, wo queuereset, EndScope und
CancelBttsOutput sie noch erreichen. Weil die Zeilen jetzt bei Sku warten, musste die
queuereset-Regel ausgesprochen werden, die bisher der Client nebenbei erledigte: eine
wartende Overwrite-Zeile ist ueberholt und faellt weg (mSkuVoiceQueueBTTS_Overwrite);
eine wartende Zeile ohne queuereset wird hinter die neue Overwrite-Zeile gestellt,
solange sie juenger als tBttsKeptMaxAge (30 s) ist. Alle fuenf Stopp-Stellen laufen ueber BttsStop:
hat die Aeusserung im Client noch nicht gestartet, wird der Stopp vorgemerkt und 0.1 s
nach ihrem STARTED aus OnUpdate zugestellt - nie aus dem STARTED-Handler selbst: ein
StopSpeakingText von dort legte im Test die gesamte Sprachausgabe des Clients bis zum
Neustart lahm (das alte Kill-Fenster tat genau das). Das ersetzt das Kill-Fenster aus v43.5 (dieselbe Idee mit
geschaetzter Zeitspanne, nur an zwei Stellen) und das eigene Tor der Tipp-Echo-Spur.
Sicherungen: 0.5 s ohne STARTED gibt das Tor frei (und schickt einen vorgemerkten Stopp
trotzdem), nach drei Uebergaben ohne jedes STARTED schaltet das Tor ab, bis wieder eines
kommt. Auf der NVDA-Bruecke kommen STARTED und FINISHED im Uebergabe-Frame, das Tor ist
dort nie geschlossen - Verhalten unveraendert. Geprueft mit einem Offline-Nachbau des
Clients (dev/rework-docs/voice-harness): alter Stand 27-33 verspaetete Aeusserungen in
3 Minuten Zufallslast, neuer Stand 0; Bruecken-Modell alt und neu identisch.
Im Log: "stop deferred (handover not started)", "deferred stop fires", "client gate ttl",
"queuereset kept", "STALE-DROP".
Folgefehler, im selben Zug behoben: die Taste "Audio Ausgabe beenden" (Strg+V) brach nur
noch die gerade gesprochene Zeile ab, die wartenden liefen danach weiter - man musste
je Zeile einmal druecken. Frueher lag der ganze Schwall schon im Client, und der eine
Stopp traf alles; seit dem Tor warten die Zeilen bei Sku, und StopOutputEmptyQueue
leerte diese Warteschlange nie. StopOutputEmptyQueue(true, true) ruft jetzt
CancelBttsOutput: wartende Zeilen und wartende Tippzeichen weg, dann der Stopp. Die
Aufrufer mit (true, nil) bleiben, wie sie sind - dort sollen wartende Chatzeilen
ueberleben. Harness-Szenario "stopkey": alter Stand vier hoerbare Zeilen, neuer Stand
eine (abgeschnitten).
Menue: "Ziel Menue" wurde nach dem Inhalt nachgesprochen
Einfach: Oeffnet sich das Menue nicht an der Wurzel, sondern gleich an einer bestimmten
Stelle - beim Oeffnen einer Tasche, eines Haendlers oder Briefkastens, bei Umschalt+F9
und Umschalt+F10, bei den Schnellwahltasten -, dann war nach dem eigentlichen Inhalt
noch "Ziel Menue" zu hoeren, der erste Eintrag der Menuewurzel. Also etwa "Tasche 1,
Ziel Menue". Das ist behoben: du hoerst nur noch, wo du gelandet bist. "Menue
geoeffnet" entfaellt bei diesen Oeffnungen; es wurde ohnehin sofort abgeschnitten, und
der Oeffnen-Ton bleibt. Das normale Oeffnen des Menues ist unveraendert: "Menue
geoeffnet", dann "Ziel Menue".
Technisch: SkuOptions:SlashFunc (SkuZOptions/Core.lua) oeffnet ein geschlossenes Menue
ueber den OnClick von OnSkuOptionsMain und laeuft danach den Pfad ab. Der Oeffnen-Zweig
sprach "Menue geoeffnet" als Overwrite und stellte Menu[1].name als wartende Zeile
dahinter. Die Ansage des Pfadlaufs setzte ein queuereset, und seit dem Client-Tor
dieser Version behaelt queuereset wartende Zeilen ohne Overwrite hinter der neuen Zeile
- gedacht fuer Chat, hier traf es den Wurzeleintrag (Log: "queuereset kept 1 waiting
line(s)"). Behoben an der Quelle statt durch Unterdruecken: mit einem Pfad (mindestens
zwei Felder) setzt SlashFunc SkuOptions.tOpeningForPathWalk um den Oeffnen-Aufruf, der
Oeffnen-Zweig spricht dann nichts. Das Flag wird direkt nach dem Aufruf geloescht, auch
bei einem Fehler (pcall, Fehler wird weitergereicht). Findet der Pfad nichts und das
Menue steht an der Wurzel, holt SlashFunc die Ansage nach und schreibt "menu: path walk
found nothing" ins Debug-Log. Zwischenstationen des Pfads waren schon vorher stumm.
Tastaturecho mit einer echten Windows-Stimme: die lange Pause zwischen den Buchstaben ist weg
Einfach: Wer Sku mit einer echten Windows-Stimme nutzt (nicht mit der NVDA-Bruecke), hoerte
beim Tippen im Chat nach jedem Buchstaben eine Pause von einer halben bis ganzen Sekunde -
etwa ein Buchstabe pro Sekunde, egal wie schnell die Stimme eingestellt war. Eine
langsamere Stimme machte nur den Buchstaben laenger, die Pause blieb gleich. Diese Pause
ist jetzt weg, die Buchstaben folgen dicht aufeinander. Es wird weiterhin jeder Buchstabe
gesprochen, auch doppelte, und nach Escape kommt kein Buchstabe mehr nach. Dieselbe
Pause steckte auch zwischen Zeilen, die hintereinander warten (Teile eines Questtexts,
mehrere Chatzeilen); dort faellt sie kaum auf, ist aber ebenfalls verkuerzt. Auf der
NVDA-Bruecke aendert sich nichts.
Technisch: Der Client meldet VOICE_CHAT_TTS_PLAYBACK_FINISHED fest 0.5 bis 1 s NACH dem Ende
des Tons (Bookmark "End") und startet vorher nichts Neues. Frueher uebergeben hilft
nicht (v43.5e: die Aeusserung wird nur geparkt und ist dann nicht mehr abbrechbar). Was
den Client sofort freigibt, ist ein Stopp. Neu in Libs/SkuVoice-1.0: kam fuer unsere
Aeusserung erst "Start" und dann "End" und wartet etwas (Echo-Spur oder Queue), schickt
OnUpdate nach tTailCutDelay (0.03 s) ein StopSpeakingText und uebergibt nach
tTailCutHold (0.06 s). Nie aus dem Bookmark-Handler. Ein "End" vor "Start" (kommt bei
der ersten Aeusserung nach einem Stopp vor) zaehlt nicht. Wartet nichts, endet die
Zeile wie bisher von selbst. Der Schnitt setzt die Bruecken-Marke nicht, sperrt den
"#queue > 1"-Bypass einmal und raeumt den Dubletten-Eintrag selbst ab (eine gestoppte
Aeusserung meldet kein FINISHED). Gemessen im Nachbau: Buchstabentakt 1.15 s -> 0.73 s.
Zum Probieren, nur fuer die Sitzung: /skudebug tts tail , /skudebug tts
tail off. Im Log: "tail cut -> StopSpeakingText".
Sprache anderer Addons brachte das Tastaturecho durcheinander
Einfach: Sprach ein anderes Addon (oder ein /run-Befehl) ueber die Sprachausgabe des
Spiels, waehrend du getippt hast, konnte danach ein Buchstabe nach "abgebrochen"
nachkommen, also nach dem Schliessen des Chatfelds. Nur mit einer echten
Windows-Stimme. Das ist behoben: solange fremde Sprache laeuft, wartet Sku mit seinen
Buchstaben und Chatzeilen; schliesst du das Feld, werden die wartenden Buchstaben
verworfen. Ansagen, die ohnehin alles unterbrechen (Menue, "abgebrochen",
Prioritaetszeilen), unterbrechen auch die fremde Sprache wie bisher sofort.
Technisch: Das Client-Tor kannte nur Skus eigene Uebergaben. Eine fremde Aeusserung
(Mitschnitt: id 403, geparkt, 11 s spaeter unter dem ersten Buchstaben gestartet)
liess den naechsten Buchstaben ohne STARTED stehen, die 0.5-s-TTL gab ihn auf, ein
zweiter ging in den Client und uebernahm das STARTED des ersten. Neu (mForeign,
tMaxSeenId, tClientGateFreedAt): ein STARTED, auf das niemand wartet, oder eines mit
einer id unter der hoechsten vor unserer Uebergabe gesehenen, ist fremd - wird nie als
unsere id uebernommen, und solange es laeuft, wird nichts uebergeben (Stille-Grenze
8 s; unsere eigenen Stopps beenden es). Auf der Bruecke sind alle ids 0, "aelter" ist
deshalb echt-kleiner und greift dort nie. Im Frame, in dem eine unserer Aeusserungen
FINISHED meldet, wird nichts uebergeben: eine geparkte fremde startet genau auf dieses
FINISHED und muss zuerst gesehen werden. Harness-Szenario "foreign": alter Stand vier
Buchstaben nach "abgebrochen", neuer Stand keiner. Im Log: "BTTS foreign utterance",
"BTTS foreign cleared".
Einfuegen in ein Eingabefeld: "Eingefuegt" statt Buchstabensalat
Einfach: Wer mit Strg+V Text in die Chatzeile oder in ein Eingabefeld von Sku einfuegte,
bekam den ganzen eingefuegten Text Buchstabe fuer Buchstabe vorgelesen. Jetzt sagt Sku
einmal "Eingefuegt". Den Inhalt des Feldes liest du wie gewohnt mit Pfeil hoch oder
Pfeil runter. Normales Tippen ist unveraendert, auch schnelles. Fuegst du nur ein oder
zwei Zeichen ein, werden diese weiterhin als Zeichen gesprochen.
Technisch: Ein Einfuegen liefert die Zwischenablage als einzelne OnChar-Aufrufe, alle im
selben Frame. tSpeakTypedChar (SkuZOptions/Core.lua) zaehlt die Zeichen je Frame
(GetTime() ist innerhalb eines Frames konstant): ab dem dritten gilt die Folge als
Einfuegen - CancelEcho wirft die schon wartenden Zeichen weg (uebergeben ist im selben
Frame noch keines, die Pumpe laeuft im OnUpdate), dann einmal SpeakEcho("Eingefuegt"),
alle weiteren Zeichen des Frames werden ignoriert. Schwelle 3, weil zwei Anschlaege bei
niedriger Bildrate in einen Frame fallen koennen. Gilt fuer AttachInputEcho (Chat) und
das Sku-Eingabefeld. Im Log: "inputEcho paste erkannt".
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v43.6
Ueberblick
Aenderungen
Berufefenster: Die Rezeptliste zeigt jetzt den ganzen Beruf mit auf- und zuklappbaren Kategorien statt einer Bildlaufliste mit 8 Eintraegen.
Berufefenster: Bild auf und Bild ab springen von Kategorie zu Kategorie.
Berufefenster: Der Filter "Ressourcen vorhanden" ist ein normaler Schalter und fuehrt nicht mehr auf leere Seiten.
Fehlerbehebungen
Chat: "absender anfluestern" und "nachricht an kanal senden" im Zeilenmenue (Strg+Enter auf einer Chatzeile) taten auf manchen Rechnern gar nichts - die Chatzeile oeffnete sich nicht.
Fluestern aus dem Zielmenue und aus dem Dungeonbrowser tat auf denselben Rechnern ebenfalls nichts.
Tasten: Wer einmal v43 gestartet, dann wieder v42 benutzt und dort Umschalt+F9 bis F12 neu belegt hatte, stand in v43 ohne Taste fuer Wegpunktliste, Routenziele, Aktionsleisten und "Route beenden" da - die Tasten werden jetzt nachtraeglich uebernommen.
Classic Era: Die Liste der nicht unterbrechbaren Zauber brach beim Laden mit einem Fehler ab; sie laedt jetzt auf jedem Client.
Berufefenster: Im Rezept-Tooltip (Umschalt+Pfeil runter) fehlte bei manchen Materialien der Name, man hoerte nur Zahlen wie "0 2".
Chat: "absender anfluestern" oeffnete keine Chatzeile
Einfach: Wer im Chat mit Strg+Enter das Zeilenmenue oeffnete und dort "absender anfluestern"
waehlte, bekam auf manchen Rechnern nichts: kein Ton, keine Chatzeile mit dem Namen des
Absenders. Dasselbe galt fuer "nachricht an kanal senden" und "gegenstandslink an kanal
senden". "Chatzeile kopieren" und "Absendername kopieren" gingen weiter, weil sie einen
anderen Weg nehmen. Alle drei Eintraege oeffnen die Chatzeile jetzt wieder, und der
Zielkanal wird wie gewohnt angesagt ("An Kai").
Technisch: SkuChat:SetEditboxToCustom rief den globalen ChatEdit_UpdateHeader auf und zeigte
die Editbox erst DANACH. Dieser Name ist auf dem 2.5.6-Client keine echte Funktion mehr,
sondern ein Alias aus Blizzard_DeprecatedChatInfo (Deprecated_ChatFrame.lua), und die
ganze Datei steigt sofort aus, wenn die CVar loadDeprecationFallbacks aus ist. Dann ist
der Name nil, der Aufruf wirft einen Fehler, und Show() und SetFocus() laufen nie. Neu:
SkuChat:UpdateEditboxHeader ruft die echte Frame-Methode ChatFrame1EditBox:UpdateHeader()
und nimmt den globalen Namen nur noch als Rueckfall. SkuChat_CanAddChannel liest
Constants.ChatFrameConstants.MaxChatChannels statt des veralteten MAX_WOW_CHAT_CHANNELS.
Fluestern aus dem Zielmenue und dem Dungeonbrowser tat nichts
Einfach: "Fluestern" im Menue zum aktuellen Ziel und beim Gruppenleiter im Dungeonbrowser
oeffnete auf denselben Rechnern keine Chatzeile - ohne jede Meldung. Beides geht wieder.
Technisch: Beide Stellen riefen ChatFrame_OpenChat hinter einer "wenn vorhanden"-Pruefung.
Auch das ist nur ein Alias aus Blizzard_DeprecatedChatInfo; fehlt er, passierte
stillschweigend nichts. Jetzt wird ChatFrameUtil.OpenChat benutzt, der alte Name nur
noch als Rueckfall (SkuMob/Options.lua, SkuCore/dungeonBrowser.lua).
Tasten: Umschalt+F9 bis F12 fuehrten nach einem Wechsel v43 - v42 - v43 ins Leere
Einfach: Betroffen war, wer v43 einmal gestartet hatte, danach zu v42 zurueckging und dort die
Schnellzugriffe 1 bis 4 wieder auf Umschalt+F9 bis F12 legte. Beim naechsten Start von v43
hatten die festen Aktionen (Wegpunktliste, Routenziele, Aktionsleisten, Route oder Wegpunkt
beenden) keine Taste mehr, und die vier Tasten riefen stattdessen alte Schnellzugriff-Pfade
auf. Einer davon zeigte auf einen Menueeintrag, den es nicht mehr gibt: das Menue ging auf,
der Cursor blieb auf "Ziel Menue" stehen - es sah genauso aus wie der fruehere Haenger
"Wegpunkte werden noch geladen". Sku erkennt diesen Zustand jetzt beim Start und legt die
vier Tasten von selbst auf die festen Aktionen um. Eigene Tasten auf den Schnellzugriffen
bleiben unangetastet. Danke an Kai fuer die genaue Analyse (Issue 7).
Technisch: tMigrateQuickKeys (SkuZOptions/SkuKeyBinds.lua) wertete allein das Vorhandensein
von SKU_KEY_NAVWAYPOINTSQUICK als "schon migriert". v43 hatte den Eintrag beim ersten Start
angelegt, v42 leerte ihn wieder, als es die Tasten fuer MENUQUICK1 bis 4 vergab - vorhanden,
aber leer. Neu ist ein Rettungsdurchlauf: sind NAVWAYPOINTSQUICK, NAVROUTEDESTINATIONSQUICK
und ACTIONBARSOPEN alle drei leer UND traegt mindestens ein MENUQUICK1 bis 4 eine der
v42-Standardtasten SHIFT-F9 bis SHIFT-F12, laeuft die Uebernahme noch einmal - in diesem
Durchlauf nur fuer die Plaetze, die eine solche Standardtaste tragen. Wer die neuen Tasten
absichtlich geleert hat, behaelt so jede eigene Schnellzugriff-Taste. Der Durchlauf ist
einmalig: danach sind die neuen Eintraege nicht mehr leer.
Classic Era: Liste der nicht unterbrechbaren Zauber lud nicht
Einfach: Auf Classic Era brach eine Datendatei von Sku beim Anmelden mit einem Lua-Fehler ab.
Dadurch fehlte die Liste, mit der "Nur unterbrechbare Zauber ansagen" arbeitet. Die Datei
laedt jetzt auf jedem Client vollstaendig. Auf TBC Anniversary aendert sich nichts.
Technisch: SkuDB/uninterruptibleCasts.lua baut seine Namensschluessel mit GetSpellInfo(id)
direkt im Tabellenkonstruktor. Die TBC-Zauber 29121 (Bogenschiessen) und 33808
(Schusswaffe abfeuern) kennt Era nicht, GetSpellInfo liefert nil, und "[nil] = true"
wirft "table index is nil" - der Konstruktor bricht ab, SkuDB.uninterruptibleCasts.spells
und .npcSpells bleiben nil. Die Datei benutzt jetzt einen lokalen Wrapper, der fuer eine
unbekannte ID einen Platzhalter liefert, den kein Zaubername je treffen kann. Der Eintrag
ist auf diesem Client wirkungslos, die Konstruktoren bleiben zeilengleich mit der
Upstream-Quelle (ClassicCastbars), und dasselbe schuetzt die npcSpells-Zeilen, wo ein nil
einen Verkettungsfehler ausgeloest haette.
Berufefenster ueberarbeitet: Kategorien zum Auf- und Zuklappen statt 8 Eintraege pro Seite
Einfach: Die Berufefenster (alle Herstellungsberufe, Verzauberkunst und die Tierausbildung)
verhalten sich jetzt einheitlich. Bisher zeigte das Menue immer nur die 8 Zeilen, die das
Blizzard-Fenster gerade anzeigt, dazu "Hoch blaettern" und "Runter blaettern". Jetzt steht
der ganze Beruf in einer Liste: jede Kategorie als Ueberschrift, darunter ihre Rezepte.
Enter auf einer Kategorie klappt sie zu oder auf, der neue Zustand wird angesagt, und Sku
merkt ihn sich pro Charakter und Beruf. Bild ab und Bild auf springen zur naechsten bzw.
vorigen Kategorie. "Ausgewaehlt" und die Herstellen-Knoepfe stehen weiter am Ende des
Fensters. Gibt es zwei Kategorien mit demselben Namen (Schneiderei hat "Stoff" zweimal),
heisst die zweite "Stoff 2". Der Filter "Ressourcen vorhanden" ist jetzt ein normaler
Schalter: Enter schaltet um, der Cursor bleibt stehen. Mit Filter verschwinden Rezepte
ohne Material und Kategorien, in denen nichts herstellbar ist. Man landet nicht mehr auf
leeren Seiten ohne Ausweg, und in der Verzauberkunst gibt es keine Seiten mehr, auf denen
nur die Ueberschriften uebrig sind. Die Liste aktualisiert sich nach dem Herstellen von
selbst und spricht nur, wenn der Eintrag unter dem Cursor verschwunden ist.
Technisch: Build_TradeSkillFrame und Build_CraftFrame (SkuCore/LocalMenu.lua) lesen die Liste
aus GetTradeSkillInfo bzw. GetCraftInfo statt die Zeilen TradeSkillSkill1-8 und Craft1-8
abzulesen; ausgewaehlt wird ueber TradeSkillFrame_SetSelection bzw.
CraftFrame_SetSelection. Blizzards TradeSkillOnlyShowMakeable wird nicht mehr benutzt: es
setzt den Bildlauf nur zurueck, wenn der AUSWAHL-Index aus der verkuerzten Liste faellt -
sonst stand der Offset hinter dem Listenende, alle 8 Zeilen und die Bildlaufleiste waren
weg. Der Filter prueft jetzt in beiden Fenstern numAvailable; der alte Zwischenspeicher
resFilterApplied (pro Beruf, obwohl Blizzards Schalter global ist) entfaellt. Neu:
TRADE_SKILL_UPDATE und CRAFT_UPDATE bauen das Menue neu auf, entprellt und nur wenn sich
die gezeigte Liste geaendert hat (SkuCore:RefreshProfessionMenu). Der Listen-Builder
kennt zwei neue Felder: "toggle" (ein MakeToggleNode-Schalter in einem Fenster) und
"isSectionHeader" (Sprungziel fuer Bild auf/ab). Der Filterzustand liegt jetzt unter dem
Berufsnamen statt unter dem Fenstertitel; ein alter Wert wird uebernommen.
Berufefenster: Rezept-Tooltip nannte manche Materialien ohne Namen
Einfach: Im Tooltip eines Rezepts (Umschalt+Pfeil runter) stand bei einzelnen Materialien nur
die Anzahl, etwa "0 2" statt "Bleiche 0 von 2". Betroffen waren Gegenstaende, die der
Spielclient noch nie gesehen hat - meist reine Haendlerware wie Bleiche, Farbstoffe oder
Flussmittel. Stoffe und Leder kennt der Client fast immer schon, deshalb sah es zufaellig
aus. Jetzt sagt Sku an dieser Stelle "wird abgerufen" und holt den Namen im Hintergrund.
Tooltip schliessen und noch einmal Umschalt+Pfeil runter druecken: dann steht der Name da.
Das passiert pro Gegenstand nur einmal, danach kennt ihn der Client dauerhaft.
Technisch: GetTradeSkillReagentInfo bzw. GetCraftReagentInfo liefern fuer einen Gegenstand, der
nicht im Item-Cache liegt, keinen Namen, und der Reagenzien-Link traegt dann leere
Klammern "[]". Der Rueckfall schrieb ein "?", das die Sprachausgabe nicht spricht. Dazu
wurde der fertige Text in textFull des Menueknotens abgelegt und nie neu gebaut, der
Fehler blieb also auch nach dem Nachladen. Neu (SkuZOptions/Core.lua, SHIFT-DOWN): fehlt
der Name, wird die Item-ID aus dem Link gelesen und GetItemInfo(id) gerufen, was den
Gegenstand zugleich beim Server anfordert. Ein unvollstaendiger Tooltip wird mit
skuRecipeIncomplete markiert und beim naechsten Tastendruck neu gebaut. Jeder Fall
schreibt eine Zeile "recipeTooltip" ins Debug-Log (Rezeptindex, Material, Link).
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v43.5-tools - Installer 5.2 und Anmelde-Tool 3.4, keine neue Addon-Version
Ueberblick
Neu
Anmelde-Tool 3.4: Blizzards Sozialvertrag wird erkannt, zu Ende gescrollt und akzeptiert - bisher blieb ein neuer blinder Spieler davor haengen.
Anmelde-Tool 3.4: die PvP-Warnung beim Erstellen eines Charakters auf einem PvP-Realm wird vorgelesen und mit Enter oder Escape beantwortet.
Aenderungen
Anmelde-Tool 3.4: Hardcore- und PvP-Warnungen werden bei jeder Bildschirmaufloesung und Fenstergroesse gefunden, nicht nur auf grossen Bildschirmen.
Anmelde-Tool 3.4: jede Stimme wird vor der Uebernahme unhoerbar ausprobiert - eine kaputte Stimme kann das Tool nicht mehr stumm machen.
Installer 5.2: das Log-Buendel enthaelt jetzt eine Liste aller Windows-Stimmen (voices.txt).
Installer 5.2: Massnahmen gegen Fehlalarme von Windows Defender - die Installer-Datei nennt Produkt und Autor, und die mitgelieferte NVDA-Bruecken-Datei kommt ohne uebrig gebliebene Entwickler-Signatur.
Fehlerbehebungen
Anmelde-Tool 3.4: "Stimme auswaehlen" war auf manchen Rechnern leer, und die Ersteinrichtung kam dort nie weiter.
Anmelde-Tool 3.4: Blizzards Sozialvertrag wird automatisch akzeptiert
Einfach: Neue Accounts - und alle anderen, sobald Blizzard den Text aendert - bekommen
auf der Charakterauswahl einen "Sozialvertrag" angezeigt. Das Fenster schluckt jede
Taste, "Akzeptieren" ist gesperrt, bis der Text mit der Maus zu Ende gescrollt wurde,
und "Ablehnen" beendet das Spiel. Das Tool blieb davor stumm und meldete hoechstens
"Unbekannter Bildschirm". Jetzt sagt es "Blizzards Sozialvertrag ist offen. Er wird
akzeptiert, bitte warten.", scrollt den Text zu Ende, drueckt Akzeptieren, prueft, ob
das Fenster weg ist, und baut danach wie gewohnt die Charakterliste auf. Das gilt
auch, wenn der Vertrag mitten in der Sitzung wieder auftaucht. Klappt es nicht, sagt
das Tool, was eine sehende Person einmal tun muss, und versucht es nach einer Minute
erneut. Ablehnen wird nie gedrueckt.
Technisch: Der Dialog ist SocialContractFrame (Blizzard_GlueXML\SocialContract.xml/.lua)
und wird vom SERVER ausgeloest (C_SocialContractGlue.GetShouldShowSocialContract ->
SOCIAL_CONTRACT_STATUS_UPDATE); es gibt keine CVar und keine Einstellung dafuer, man
kann ihn also weder hervorrufen noch vorab beantworten. Der alte Code konnte auf dem
Anniversary-Client nicht greifen: die Helper-Pruefung verlangt das abgedunkelte gelbe
Logo, das der BC-Glue nicht hat, und ihr dritter Messpunkt liegt mitten im
Vertragstext - Pruefung falsch, Bildschirm "unknown", das Tool kam nie in den
Login-Modus; der Klick-Teil war ein blinder Sweep aus 34 Klicks. Neu sind acht
Sc*-Messpunkte in data.ini (aus dem XML abgeleitet: Rahmen 510x632, Buttons bei ui y
706..728, KEIN DefaultScaleFrame) sowie IsSocialContract, AcceptContract und
HandleSocialContract in flows.ahk und zwei CheckMode-Zweige in menu.ahk - ohne neu
gebauten Helper. Geprueft mit /validate, 0 Fehlalarmen auf allen Referenz-Screenshots
und Treffern auf synthetischen Vertragsbildern in drei Aufloesungen. Am echten Dialog
noch ungetestet, weil er sich nicht auf Bestellung erzeugen laesst; jeder Versuch
schreibt seine Messwerte als "SocialContract:"-Zeilen nach log.txt.
Anmelde-Tool 3.4: Hardcore- und PvP-Warnungen bei jeder Aufloesung, PvP-Erstellungswarnung neu
Einfach: Die Hardcore-Warnung in der Realmliste, die Hardcore-Regeln beim Erstellen eines
Charakters und die PvP-Warnungen sind Fenster, die Blizzard in echten Bildschirmpixeln
gleich gross haelt. Ihre Lage haengt deshalb von der Aufloesung ab, und die festen
Messpunkte des Tools stimmten nur auf grossen Bildschirmen (ab 1200 Pixel Hoehe). Auf
einem ueblichen 1080p-Bildschirm oder im kleinen Fenster waere das Tool vor den
Hardcore-Regeln stumm geblieben. Jetzt sucht es diese Fenster selbst und findet sie
bei jeder Aufloesung. Neu dabei ist die PvP-Warnung beim Erstellen eines Charakters
auf einem PvP-Realm: sie wird vorgelesen, Enter stimmt zu, Escape lehnt ab. Die
PvP-Warnung in der Realmliste sieht genauso aus wie die Hardcore-Warnung und wurde
deshalb schon bisher vorgelesen.
Technisch: HardcorePopUpFrame (240 und 580 hoch) und RealmWarningPopUpFrame (240 und 360
hoch) erben von DefaultScaleFrame und werden per GetDefaultScale() skaliert - eine
Client-Funktion ohne Lua-Quelltext. Im Spiel per /wdeval gemessen: 0,64 auf 2880x1800,
wo 768/Hoehe 0,43 waere; es gibt also eine Untergrenze, und bei 1080p waeren es
vermutlich 0,71. Statt den Faktor anzunehmen, findet ihn GlueDialogScan (flows.ahk):
beide Buttons liegen in allen vier Formen auf einer Geraden aus der Bildschirmmitte,
nur der Abstand haengt vom Faktor ab. Ein Bildausschnitt (neue Klasse ScreenGrab in
ui.ahk, 1000 Pixel in 16 ms), dann Faktor 0,60..1,25 je Hoehe: rot an drei Spalten,
nicht rot in der Luecke und knapp ausserhalb, schwarz am Hintergrundpunkt. Die festen
Messpunkte bleiben die erste Pruefung, der Scan die zweite. Klicks (GlueDialogClick)
und OCR-Textbereiche (GlueDialogBand) folgen dem gefundenen Faktor. Geprueft mit einer
Python-Portierung auf 66 synthetischen Dialogen (6 Aufloesungen, 3 Hoehen, 4 Faktoren):
Hoehe immer richtig, Faktor auf 0,012 genau, 0 Fehlalarme. An echten Dialogen noch
ungetestet; jeder Fund steht als "GlueDialog:"-Zeile mit Faktor in log.txt.
Anmelde-Tool 3.4: leere Stimmenauswahl behoben, die Ersteinrichtung bleibt nicht mehr haengen
Einfach: Auf manchen Rechnern kann Windows die Liste der installierten Stimmen nicht
liefern, obwohl die Sprachausgabe selbst funktioniert - etwa nach einer unsauber
entfernten oder nur halb installierten Fremdstimme. Seit 3.3 stuerzt das Tool dabei
nicht mehr ab, aber "Stimme auswaehlen" war dann leer: Pfeil rechts tat nichts, und weil
die Ersteinrichtung erst nach der Stimmenwahl zur Sprache weitergeht, kam man nie
hindurch. Jetzt liest das Tool die Stimmen in diesem Fall selbst aus der
Windows-Registrierung. Findet es auch so keine, steht dort der Eintrag "Keine Stimmen
gefunden, Eingabe druecken, um die Systemstimme zu behalten" - Eingabe behaelt die
Stimme, mit der das Tool gerade spricht, und die Einrichtung geht weiter.
Technisch: Im Log-Buendel des Nutzers stand viermal "GetVoices FAILED, voice list empty:
(0x80045039)" und danach "SwitchToSetup". Nicht ein einzelnes Token war unlesbar (der
Fall von 3.3), sondern schon sap.GetVoices() bzw. .Count wirft SPERR_NO_MORE_ITEMS,
waehrend sap.Voice.GetDescription() funktioniert. Neu: RegistryVoiceTokens() in sapi.ahk
baut je Schluessel unter Speech\Voices\Tokens (HKLM und HKCU) ein SAPI.SpObjectToken per
SetId - nur im Fehlerfall. Gelistet wird nur, was einen Namen und eine CLSID hat, denn
ein kaputter Eintrag wirft hier nicht, GetDescription() liefert einfach "".
AddVoiceNodes() in menu.ahk ersetzt die drei gleichen Schleifen und haengt bei leerer
Liste den Ersatz-Eintrag an. Geprueft mit einem Testgeruest, das die echte sapi.ahk
laedt und GetVoices genau diesen Fehler werfen laesst: dieselben Stimmen wie auf dem
normalen Weg, alle setzbar, zwei absichtlich kaputte Eintraege uebersprungen. Der
eigentliche Fehler liess sich nicht nachstellen; auf dem Rechner des Nutzers noch
ungetestet.
Anmelde-Tool 3.4: eine kaputte Stimme kann das Tool nicht mehr stumm machen
Einfach: Eine Stimme, deren Programm entfernt wurde, deren Eintrag aber in Windows
zurueckblieb, steht weiter in der Stimmenliste. Waehlte man sie, nahm Windows die Wahl
ohne Fehler an - und das Tool war danach stumm, aus dem Hauptmenue heraus sogar
dauerhaft, weil die Wahl gespeichert wird. Jetzt probiert das Tool jede Stimme vor der
Uebernahme unhoerbar aus. Funktioniert sie nicht, bleibt alles, wie es war, und das Tool
sagt "Diese Stimme funktioniert nicht, bitte eine andere waehlen". Auch beim Start wird
eine gespeicherte Stimme, die nicht mehr spricht, nicht mehr gesetzt; es bleibt dann die
Windows-Standardstimme.
Technisch: Gemessen mit einer Registrierung mit Namen und CLSID, aber ohne Engine: sap.Voice
:= token wird angenommen, erst Speak wirft 0x80040154 (Klasse nicht registriert).
VoiceWorks() in sapi.ahk spricht deshalb auf einem eigenen SpVoice in einen
SpMemoryStream, 16 bis 31 ms, die laufende Stimme wird nie angefasst. SetSapiVoiceByName
und SetToolVoiceByName geben jetzt Erfolg zurueck, VoiceSelectAction und ApplyToolVoice
werten ihn aus. SAPI2SR ist ausgenommen: die Bruecke reicht Text unabhaengig vom
Ausgabestrom an den Screenreader weiter, die Probe waere hoerbar. Eine Stimme, die
laedt, aber nur Stille erzeugt, erkennt die Probe nicht.
Installer 5.2: das Log-Buendel listet alle Windows-Stimmen auf
Einfach: "Logs sammeln" im Installer legt jetzt zusaetzlich die Datei voices.txt ins
Buendel. Sie nennt jede in Windows registrierte Stimme und ob das Programm dahinter noch
vorhanden ist. Bei Stimmenproblemen im Anmelde-Tool oder im Spiel laesst sich damit
sofort sehen, welcher Eintrag kaputt ist. Kommt mit dem Installer 5.2.
Technisch: LogCollector.WriteVoiceRegistrations liest Speech\Voices\Tokens,
Speech\Voices\TokenEnums und Speech_OneCore\Voices\Tokens in der 64- und der
32-Bit-Registry-Sicht (das Anmelde-Tool ist 64 Bit und sieht reine 32-Bit-Stimmen nicht)
sowie in HKCU, dazu DefaultTokenId. Je Eintrag: Name, CLSID, die InprocServer32-DLL samt
Pruefung, ob sie registriert ist und auf der Platte liegt, VoicePath/LangDataPath und
die Attribute.
Installer 5.2: Massnahmen gegen Fehlalarme von Windows Defender
Einfach: Einige Spieler haben gemeldet, dass Windows Defender den frisch heruntergeladenen
Installer als gefaehrlich entfernt hat. Der Installer ist nicht gefaehrlich; unser
eigener Defender-Scan mit aktuellen Signaturen findet nichts. Zwei Dinge, die die Datei
verdaechtiger aussehen liessen als noetig, sind behoben: Die Dateieigenschaften sagen
jetzt, was die Datei ist und von wem sie kommt (Produkt "Sku Installer", Firma "Sku",
Autor JeanStiletto, Link zum Projekt) statt leer zu sein, und eine Datei der
mitgelieferten NVDA-Bruecke traegt keine Signatur mehr, die vom PC des Entwicklers
stammte und auf jedem anderen Rechner nichts bedeutete. Ehrlich zur Grenze: Der
Installer ist weiterhin nicht mit einem gekauften Zertifikat signiert. Jeder neue Build
faengt deshalb ohne Download-Reputation an, und Defender kann ihn in den ersten Tagen
trotzdem zurueckhalten. Wenn das passiert: Windows-Sicherheit oeffnen, Schutzverlauf,
den Eintrag waehlen und die Datei zulassen oder wiederherstellen - und uns bitte den
Namen der Erkennung schicken.
Technisch: SkuInstaller.exe war und ist nicht Authenticode-signiert; release.ps1 hat keinen
Signierschritt, signiert werden nur die Bruecken-DLLs, auf dem Rechner des Nutzers,
durch sku-nvda-voice-sign.ps1. Eine unsignierte Exe hat nur Cloud-Reputation je Hash,
und die v43.5-Exe war bei den Meldungen einen Tag alt mit neun Downloads. Der lokale
Scan (Engine 1.1.26080.3, Signaturen 1.459.278.0) ist sauber fuer Exe, Bruecken-Payload
und das mitgelieferte AutoHotkey - das Urteil kommt also aus Cloud/ML oder
Verhaltenserkennung, nicht aus einer statischen Signatur. Geaendert: Company, Product,
AssemblyTitle, Description, Authors und Copyright in SkuInstaller.csproj (bisher stand
ueberall "SkuInstaller", Copyright leer). Und x86\sapi2sr_engine.dll in
payload\sapi2sr-payload.zip war aus dem Program-Files-Ordner des Entwicklers
zurueckkopiert worden und trug noch die Wegwerf-Signatur dieses Rechners (ueberall sonst
"signiert von nicht vertrauenswuerdiger Wurzel"); jetzt liegt die nackte DLL bei,
123320 -> 115712 Bytes. Der Authenticode-PE-Hash schliesst die Signatur aus, beide Pins
im Signierskript passen weiter (5A76A572... x64, 1281E2B9... x86), das Signieren auf dem
Nutzerrechner ist unveraendert. dev\rework-docs\nvda-voice-signing\
strip_payload_signature.py erledigt das Entfernen beim naechsten Payload-Update. Nicht
geaendert, und weiterhin das, was eine Verhaltenserkennung sieht: Start mit
Adminrechten, eingebettete Programme, regsvr32 /s, ein verstecktes PowerShell, das ein
Codesignatur-Zertifikat in den Root-Speicher des Rechners legt, Selbstaustausch.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v43.5
Ueberblick
Fehlerbehebungen
Questdatenbank: das Oeffnen von "Alle" (ebenso "Start in Zone" und "Quests in der Naehe") liess das Spiel sekundenlang einfrieren.
Chat: nach dem Oeffnen der Chatzeile mit "/" wurde der alte Kanal angesagt (etwa "An Kai"), obwohl erst der Befehl danach den Kanal festlegt.
Sprachausgabe: einzelne Zeilen blieben ueber die NVDA/SAPI-Bruecke zufaellig stumm (etwa ein Ausruestungsteil in der Liste), waehrend die Nachbarn gesprochen wurden.
Quest: "Raenes Saeuberung" (Eisenknauf, Eschental) hatte kein Questziel; es fuehrt jetzt zur Rostigen Truhe der Faulenden Bruehschleimer.
Sprachausgabe: getippte Zeichen und abgebrochene Ansagen kamen verspaetet nach - Buchstaben einer laengst geschlossenen Chatzeile tauchten Sekunden spaeter in einem anderen Menue auf.
Anmelde-Tool 3.3: eine beschaedigte Windows-Stimme auf dem Rechner liess das Tool gleich nach der Versionsansage mit einem Fehlerfenster (GetVoices, 0x80045039) abbrechen.
Sprachausgabe: schnelles Blaettern durch lange Eintraege las ueber die NVDA/SAPI-Bruecke erst den vorigen Eintrag zu Ende, bevor der gewaehlte kam.
Questdatenbank: das Oeffnen der Questlisten liess das Spiel einfrieren
Einfach: Wer unter Quest > Questdatenbank die Liste "Alle" oeffnete, bekam seit v43.2 einen
Haenger von mehreren Sekunden. Die Liste oeffnet jetzt wieder sofort; die Eintraege einer
Quest (Annahme, Ziel, Abgabe ...) werden erst gebaut, wenn man die Quest betritt. Gleiches
gilt fuer "Start in Zone" und "Quests in der Naehe".
Technisch: "Alle" baute fuer jede der mehreren tausend Quests der Datenbank sofort das
komplette Untermenue (CreateQuestSubmenu). Seit v43.2 loest dessen Ziel-Zweig fuer Quests
mit einem Ausloese-Ort (triggerEnd) den naechsten Routen-Wegpunkt geometrisch auf
(GetTriggerEndWps) - ein kompletter Scan des Wegpunkt-Caches eines Kontinents - und seit
v43.3 fuer jede solche Quest statt nur fuer die ohne andere Ziele. Ein Oeffnen kostete so
rund 170 Kontinent-Scans in einem einzigen Frame. Die Quest-Eintraege sind jetzt dynamische
Knoten mit eigenem BuildChildren, wie in "Aktuelle Quests" schon immer.
Chat: falsche Kanalansage nach dem Oeffnen mit dem Schraegstrich
Einfach: Wer zuletzt jemandem gefluestert hatte und die Chatzeile mit "/" oeffnete, hoerte
"An Kai" - und nach "/g " gleich darauf "Gilde". Die erste Ansage war falsch: solange die
Zeile mit einem Schraegstrich beginnt, geht nichts an diesen Kanal, erst der Befehl
entscheidet. Die Ansage schweigt jetzt, solange ein Befehl in der Zeile steht, und sagt
den Kanal, sobald er feststeht ("/g " wird zu "Gilde") oder der Schraegstrich wieder
geloescht wird. Ein bewusster Wechsel auf "Sagen" ("/s ") wird jetzt ebenfalls gesagt,
wenn Sagen nicht ohnehin der Standardkanal war. Beim Zurueckholen einer gesendeten Zeile
(Pfeil hoch) entfaellt der Kanal-Vorspann, wenn die Zeile ein Befehl ist.
Technisch: Blizzard zeigt in der Kopfzeile immer das Attribut chatType, und das ist beim
Oeffnen der sticky-Kanal der zuletzt gesendeten Nachricht (auch Fluestern ist sticky,
samt tellTarget). Die Schraegstrich-Taste ruft ChatFrameUtil.OpenChat("/"): dieselbe
Kopfzeile plus ein "/" im Feld, gesetzt erst im naechsten OnUpdate (editBox.setText), die
UpdateHeader-Aufrufe des Oeffnens laufen also noch mit leerem Feld. Ein Text, der mit "/"
beginnt, geht nie an den Kanal der Kopfzeile: erst wenn ParseText den Befehl aufloest
("/g " beim Leerzeichen, "/w Name " hinter dem Namen), setzt Blizzard chatType neu,
SetText(Rest) und dann UpdateHeader. Sku prueft jetzt an allen Ansage-Stellen
(UpdateHeader-Haken, Fokus, verzoegertes Sprechen) den effektiven Text inklusive des
ausstehenden setText (SkuChat:EditboxTextIsCommand); eine neue OnTextChanged-Kante
deckt das Loeschen des Schraegstrichs ab, fuer das Blizzard kein UpdateHeader ruft.
Sprachausgabe: einzelne Zeilen blieben zufaellig stumm
Einfach: Wer schnell durch eine Liste ging, hoerte hin und wieder eine einzelne Zeile nicht -
etwa "Nagakampfhandschuhe" in der Ausruestung, waehrend die Nachbarn gesprochen wurden -
und sie blieb auch beim mehrfachen Darueberfahren stumm. Das betraf die NVDA/SAPI-Bruecke
und konnte ueberall in Sku passieren, meist nach einem /reload. Jede Zeile wird jetzt
wieder zuverlaessig gesprochen.
Technisch: Der WoW-Client speichert gerenderte Sprachausgabe pro Text und spielt sie bei
einer Wiederholung ab, ohne die Stimme erneut aufzurufen - bei der Bruecke ist diese
Wiederholung Stille. Sku haengt darum an jeden Text eine pro Text zaehlende Folge
geschuetzter Leerzeichen (1..64), damit jede Wiederholung ein neuer Text ist. Der Zaehler
lebte aber nur in Lua und begann bei jedem /reload von vorn, waehrend der Cache des
Clients den Reload ueberlebt (die Utterance-IDs laufen ueber den Reload hinweg durch).
Eine nach dem Reload erneut gesehene Zeile konnte so wieder in einen schon gerenderten
Bereich fallen und blieb stumm, bis der Zaehler diesen Bereich verlassen hatte - im
Protokoll sechs Anschlaege in Folge mit sauberem SpeakText + STARTED + FINISHED. Die
Zaehler liegen jetzt in SkuOptionsDB.global (bttsCacheBust) und laufen ueber den Reload
weiter; zudem ist der Raum pro Text 512 Varianten statt 64 (fuehrende geschuetzte
Leerzeichen 1..8 tragen den hohen Teil des Zaehlers).
Quest: "Raenes Saeuberung" (Eisenknauf) hatte kein Questziel
Einfach: Die Quest 1027 "Raenes Saeuberung" im Eschental verlangt das letzte Teil von Dartols
Rute, den Eisenknauf. Sku kannte dafuer keinen Ort, "Questziel" blieb leer. Jetzt fuehrt
das Questziel in das Schleimgebiet suedoestlich von Raynewoods Zuflucht: Dort lassen die
Faulenden Bruehschleimer beim Tod eine Rostige Truhe zurueck, in der der Knauf liegt.
Technisch: Der Gegenstand 5519 (Iron Pommel) verweist in der Datenbank korrekt auf das
Objekt 19021 (Rusty Chest), doch dessen Datensatz hatte keine Spawn-Koordinaten, weder in
objects.lua noch in objects_fixes.lua - der Item-Zweig von GetResultingWps fand nichts.
objects_fixes.lua (TBC und Era) traegt jetzt die 44 Truhenpositionen von Wowhead im
Eschental nach (Zone 331, etwa 68-78 / 68-80); das ist dieselbe Flaeche wie die Spawns
des Faulenden Bruehschleimers (3928), der die Truhe hinterlaesst.
Sprachausgabe: getippte Zeichen und abgebrochene Ansagen kamen verspaetet nach
Einfach: Wer eine laengere Nachricht tippte und die Chatzeile dann schloss, hoerte die
Buchstaben danach weiter - Zeichen fuer Zeichen, waehrend man laengst in einem anderen
Menue navigierte, in einem Mitschnitt fast eine Minute lang. Dasselbe galt fuer eine
abgebrochene Ansage: nach "Abgebrochen" kam noch ein Rest der alten Zeile, etwa eine
Entfernungsangabe aus dem gerade geschlossenen Wegpunktmenue. Was beim Schliessen oder
Abbrechen noch aussteht, wird jetzt verworfen. Die Tastenansage bleibt dabei
vollstaendig - es geht kein Buchstabe verloren.
Technisch: Der Client nimmt jedes SpeakText ohne Begrenzung an, spielt aber nur eines nach
dem anderen ab, und C_VoiceChat.StopSpeakingText bricht nur die gerade LAUFENDE Ausgabe
ab - ein Leeren der Warteschlange wie SAPIs PurgeBeforeSpeak gibt es nicht. Alles
bereits Uebergebene ist damit unwiderruflich. Die Tastenansage gab bisher pro Anschlag
sofort eine Ausgabe ab, drei bis vier pro Sekunde, waehrend der Client etwa eine pro
Sekunde schafft: eine getippte Zeile von 104 Zeichen parkte so rund 80 Ausgaben im
Client, die danach einzeln nachliefen. Aus demselben Grund liefen CancelBttsOutput und
EndScope ins Leere - sie leeren Skus eigene Warteschlange, in der die Zeichen nie lagen
(85 von 93 EndScope-Aufrufen eines Mitschnitts verwarfen nichts). Die Zeichen warten
jetzt in Sku, es geht immer nur eines an den Client, und das naechste erst bei dessen
PLAYBACK_FINISHED - dem Moment, in dem der Client ueberhaupt wieder eine Ausgabe annimmt
(jedes STARTED des Mitschnitts faellt mit einem FINISHED zusammen). Damit ist nie etwas
uebergeben, das noch nicht laeuft, und ein Abbruch erreicht alles. Ein kurzes
Abbruchfenster sichert den Rest ab: nach einem harten Abbruch wird nichts uebergeben und
jede dennoch startende Ausgabe sofort gestoppt. Das entspricht dem Aufbau von NVDA, das
die Warteschlange ebenfalls selbst haelt und der Stimme nur eine Ausgabe auf einmal gibt.
Anmelde-Tool 3.3: Absturz beim Start durch eine beschaedigte Windows-Stimme
Einfach: Nach einer frischen Installation sagte das Tool noch "Version 3.2" an und
brach dann mit einem Fehlerfenster ab ("Error: (0x80045039) Specifically: GetVoices").
Schuld war nicht das Tool allein, sondern eine beschaedigte Stimme in Windows - etwa
eine deinstallierte Stimme, die Reste hinterlassen hat. Das Tool ueberspringt eine
solche Stimme jetzt, vermerkt sie in log.txt und startet normal; sie fehlt dann nur
im Menue "Stimme auswaehlen".
Technisch: 0x80045039 ist SPERR_NO_MORE_ITEMS: SAPI meldet N Stimmen, eine davon laesst
sich aber nicht lesen (kaputter Eintrag unter HKLM\SOFTWARE\Microsoft\Speech\Voices\
Tokens). Das Tool starb beim Aufbau des Stimmen-Menues an der for-Schleife ueber
sap.GetVoices(). GetVoices() und SetSapiVoiceByName() lesen jetzt ueber die neue
Funktion ReadableVoiceTokens() jede Stimme einzeln per Item(i) in einem eigenen try;
eine unlesbare wird uebersprungen und geloggt, scheitert schon die Liste, bleibt sie
leer. SapiInit() liest die Standardstimme ebenfalls geschuetzt. Am Rechner mit
kaputter Stimme noch ungetestet.
Sprachausgabe: schnelles Blaettern las ueber die NVDA-Bruecke den vorigen langen Eintrag zu Ende
Einfach: Mit der NVDA/SAPI-Bruecke als Stimme las Sku beim schnellen Blaettern durch eine
Liste mit langen Eintraegen (Wegpunktliste, Questtexte, Chatverlauf) erst den vorigen
Eintrag ganz zu Ende und dann den, auf dem der Cursor stand. Jetzt wird der alte Eintrag
nach einem kurzen Moment abgebrochen und der gewaehlte gelesen, wie bei einer
Windows-Stimme. Laengere Texte, die in mehreren Teilen kommen, werden weiter vollstaendig
gelesen, und das Tipp-Echo bleibt unveraendert. Die Behebung braucht die neue
NVDA-Bruecke aus dem Sku-Installer 5.1: ueber den Installer aktualisieren (nicht nur das
Addon-Zip) und WoW danach komplett neu starten.
Technisch: StopSpeakingText des Spiels stoppt nur die eigene Wiedergabe des Clients. Auf der
Bruecke steht der Text dann schon in NVDAs Warteschlange, und SAPI reicht "purge before
speak" nie an eine Engine weiter - nichts auf dem Weg konnte NVDA unterbrechen. Bei der
Engine kommt nur die Ausgabe selbst an, Markup eingeschlossen. Deshalb reist die Absicht
jetzt darin mit, wie bei Prisms speak(text, interrupt): jeder Stopp setzt ein Flag, und
die naechste Zeile traegt . Die mit dem Installer
ausgelieferte Engine (SAPI2SR mit Skus Patch C) ruft bei diesem Bookmark
nvdaController_cancelSpeech und reicht dann den Text weiter. Zeilen ohne Stopp davor
tragen keine Marke und reihen sich weiter ein. Echte SAPI-Stimmen verschlucken das
Bookmark lautlos; eine aeltere Engine ueberspringt es.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v43.4
Ueberblick
Neu
Pawn: unter Addons > Pawn stehen Pawns Tooltip-Schalter, und Sku-Tooltips nennen die Verbesserung in Prozent, den Unterschied je Attribut und fehlende Attribute. Von Yennesta.
Neue Taste "damage meter oeffnen" springt direkt zu den Details-Berichten; die Tastenbelegung hat eine eigene Gruppe "Addons".
Aenderungen
Chat: beim Absenden oder Abbrechen wird ein noch laufendes Tastatur-Echo sicher beendet, die Ansage der gesendeten Nachricht aber nie angeschnitten.
Ansagen eines Menues oder Fensters enden mit dem Fenster: was beim Schliessen noch wartet, wird verworfen, was gerade laeuft, gestoppt.
Fehlerbehebungen
Mac: Pfeil-, Funktions- und Bild-Tasten kamen doppelt an - leere Taschen- und Leistenplaetze wurden uebersprungen, der Tooltip-Leser sprang bei jedem Umschalt+Pfeil runter an den Anfang.
Schlachtzug-Lebensmonitor: eine von Hand zugewiesene Rolle landete beim falschen Spieler, und ohne Rollenerkennung blieb der Monitor stumm.
Haendler: der Rueckkauf-Reiter las und kaufte den Gegenstand mit derselben Nummer aus dem normalen Angebot.
Ausruestungsvergleich in Tooltips fehlte manchmal - der Scan-Tooltip hatte seinen Besitzer verloren.
Tooltip-Leser: am Ende eines Textes, etwa in der Freundesliste, wechselte Umschalt+Pfeil runter zwischen Stille und der letzten Zeile.
Per Taste angeforderte Ansagen (Zielleben, Entfernung, Ziel ...) blieben beim zweiten Druck innerhalb einer Sekunde stumm.
Mac: Pfeil- und Funktionstasten kamen doppelt an
Einfach: Auf dem Mac wurden beim schnellen Blaettern leere Taschen- und Aktionsleistenplaetze
uebersprungen, und der Tooltip-Leser fing bei jedem Umschalt+Pfeil runter wieder von vorn
an. Beides ist behoben; Windows war nie betroffen.
Technisch: Der Mac-Client reicht fuer Tasten ohne Zeichen - Pfeile, F-Tasten, Bild auf und ab,
Pos1, Ende, Einfuegen, Entfernen - die Platzhalterzeichen des Betriebssystems aus dem
privaten Unicode-Bereich (U+F700 aufwaerts) an OnChar durch; Windows loest fuer diese
Tasten kein OnChar aus. Jeder Pfeildruck erreichte das Menue deshalb zweimal: als
gebundene Taste und als Phantomzeichen, das ungeprueft in die Tastenauswertung
weitergereicht wurde. Dort zaehlte der Doppeltipp-Zaehler zwei Anschlaege je Druck
(jeder Eintrag "Leer" uebersprungen), und die Regel "jede andere Taste schliesst den
Leser" schloss den Tooltip-Leser nach jedem Umschalt+Pfeil runter. Das Menue reicht aus
OnChar jetzt nur noch Zeichen weiter, die die Buchstabensuche kennt (Positivliste), die
beiden Tastatur-Echo-Hooks verwerfen den ganzen privaten Bereich U+E000 bis U+F8FF,
und ein Doppeltipp verlangt jetzt dieselbe Taste zweimal. Verworfene Zeichen landen
mit ihren Bytes im Debug-Ring, damit ein Tester das Phantom auf seinem Client belegen
kann. Ursache erkannt und zuerst abgefangen von Yennesta (PR 19).
Schlachtzug-Lebensmonitor: Rollen beim richtigen Spieler
Einfach: Wer im Schlachtzug einem Spieler von Hand eine Rolle zuwies, traf oft einen anderen,
sobald die Gruppenreihenfolge von der Beitrittsreihenfolge abwich. Und ohne
automatische Rollenerkennung blieb der Monitor fuer diesen Spieler ganz stumm.
Technisch: Das Zuweisungsmenue zaehlt die Mitglieder in hoerbarer, nach Gruppen sortierter
Nummer und speicherte die Rolle unter dieser Nummer; die Lebensauswertung las sie
ueber den echten raidN-Index. Das Menue behaelt seine Nummerierung und merkt sich je
Eintrag den echten Index, unter dem gespeichert und gelesen wird. Ohne Rolle (SkuAuras
aus, oder keine erkannt) blieb die Rollen-ID nil, und UNIT_HEALTH griff damit in die
Filtertabelle - Abbruch der ganzen Auswertung. Die Rollenaufloesung ist jetzt eine
Funktion: Zuweisung, dann SkuAuras, sonst der Korb "Keine Rolle". Von Yennesta.
Haendler: Rueckkauf kauft wieder das Verkaufte zurueck
Einfach: Im Rueckkauf-Reiter nannte Sku den falschen Gegenstand und kaufte beim Bestaetigen
das Angebot des Haendlers mit derselben Nummer statt des verkauften Stuecks.
Technisch: Der Rueckkauf-Reiter benutzt dieselben Schaltflaechen und Nummern wie das
normale Angebot. Sku las sie mit SetMerchantItem und kaufte mit BuyMerchantItem, beides
bezogen auf das Angebot. Bei aktivem Rueckkauf-Reiter laeuft die Abfrage jetzt ueber
SetBuybackItem und der Kauf ueber BuybackItem; ein Rueckkauf ist ein einzelner Stapel,
daher gibt es dort kein Mengenuntermenue. Von Yennesta.
Pawn: Verbesserung und Wertunterschiede im Tooltip
Einfach: Ist Pawn installiert, nennt der Sku-Tooltip eines Gegenstands direkt unter dem
Namen die Verbesserung in Prozent samt Skala, haengt an jede Attributzeile den
Unterschied zum angelegten Gegenstand an (gesprochen "plus" oder "minus", Schaden pro
Sekunde mit einer Nachkommastelle) und listet Attribute, die der angelegte Gegenstand
hat und der neue nicht. Unter Addons > Pawn stehen die Schalter "Pawn in
Sku-Tooltips" sowie Pawns eigene Tooltip-Einstellungen; ohne Pawn steht dort nur der
Hinweis, dass es fehlt. Von Yennesta.
Technisch: Neue Datei SkuCore/pawnIntegration.lua; alle Pawn-Aufrufe sind abgesichert und
der Tooltip-Durchlauf laeuft in pcall, ohne Pawn wird nichts angehaengt. Gegenueber dem
Beitrag: der Schalter ist eine Vorgabe im SkuCore-Einstellungsschema (an), der
Zeilenabgleich ist unabhaengig von Gross- und Kleinschreibung (auf englischen Clients
heisst die Statistik "Damage Per Second", die Tooltip-Zeile "damage per second" - die
DPS-Differenz fiel dort stumm weg), und ein Fehler im Durchlauf steht im Debug-Ring.
Taste "damage meter oeffnen" und Tastengruppe "Addons"
Einfach: Eine neue, standardmaessig unbelegte Taste springt direkt zu Addons > Damage Meter >
Berichte. In den Tastenbelegungen gibt es jetzt die Gruppe "Addons" mit den Tasten fuer
AtlasLoot und das Damage Meter.
Technisch: Gebunden und ausgewertet wie die Dungeon-Browser-Taste; der Menuepfad laeuft
ueber Knoten-IDs (Addons, DamageMeter, Reports) und damit in jeder Sprache. Die
Berichtseintraege liefern ihren Text erst beim Lesen (Funktion statt Tabelle, wie die
Auktionshaus-Eintraege): frische Details-Daten, keine Kosten fuer ungelesene Kaempfe,
und es funktioniert auch, wenn der Cursor per Taste auf einem Eintrag landet, ohne
OnEnter zu durchlaufen. Taste und IDs von Yennesta.
Ausruestungsvergleich fehlte manchmal
Einfach: Bei Umschalt+Pfeil runter auf einem Gegenstand fehlte gelegentlich der Abschnitt
"aktuell angelegter Gegenstand", scheinbar zufaellig. Er ist jetzt immer da.
Technisch: Sku liest Tooltips ueber einen gemeinsamen, unsichtbaren GameTooltip. Ein
GameTooltip fuellt seine Zeilen nur, solange er einen Besitzer hat, und verliert ihn von
selbst: ein Aufruf ohne Inhalt (leerer Leisten-, Taschen- oder Ausruestungsplatz, noch
nicht geladener Gegenstand) blendet ihn aus und loescht den Besitzer. Danach lieferte
jede Abfrage still nichts, bis ein anderer Weg zufaellig SetOwner rief. Drei Stellen
hatten das bereits fuer sich behoben, was den Fehler zufaellig wirken liess. Alle 18
Abfragestellen setzen den Besitzer jetzt vor jedem Lesen ueber eine Hilfsfunktion neu.
Tooltip-Leser: das Ende eines Textes
Einfach: In der Freundesliste (und ueberall sonst) blieb der Leser mit Umschalt+Pfeil runter
nicht auf der letzten Zeile stehen, sondern wechselte zwischen Stille und der letzten
Zeile - wie eine Endlosschleife. Er liest die letzte Zeile jetzt bei jedem Druck.
Technisch: Am Textende reicht der Leser dieselbe Zeile erneut an die Sprachebene. Deren
Dublettensperre aus v43.2 verwirft eine innerhalb einer Sekunde identische Zeile, sofern
sie nicht als tastenausgeloest markiert ist - und der Leser markierte nie. Jede Zeile
des Lesers, auch Links, traegt die Markierung jetzt.
Per Taste angeforderte Ansagen bleiben nicht mehr stumm
Einfach: Zielleben, Entfernung, Ziel-Ansage, Wuerfelinfo, Zum Beacon drehen, Wegpunkt-Tasten
und aehnliche: ein zweiter Druck innerhalb einer Sekunde mit derselben Antwort blieb
stumm. Jetzt kommt die Antwort bei jedem Druck.
Technisch: Dieselbe Dublettensperre; markiert hatte bisher nur die Tastenauswertung des
Menues. Statt jede Ansage einzeln zu markieren, merken sich die drei Tastenverteiler
(Hauptfenster, SkuCore-Steuerrahmen, SkuNav) den Frame ihres Aufrufs, und die
Sprachebene wertet jede Uebergabe innerhalb von 0,1 Sekunden danach als
tastenausgeloest. Der Nachschlag eines Menue-Neuaufbaus kommt aus einem Timer und
spaeteren Frames und faellt nicht in dieses Fenster; die Tastenauswertung des Menues
markiert weiter ausdruecklich.
Sprachbereiche: Ansagen enden mit ihrem Fenster
Einfach: Zwei Faelle mit langsamen SAPI-Stimmen: Nach Absenden oder Abbrechen im Chat las
die Stimme eine mit Pfeil hoch geholte Zeile zu Ende, und nach dreimal Lernen beim
Lehrer und Escape kam der Lehrer noch dreimal. Beides ist vorbei: das Chat-Echo wird
beim Schliessen abgebrochen - die Ansage der gesendeten Nachricht aber nie -, und was
ein Menue oder Fenster beim Schliessen noch zu sagen hatte, wird verworfen oder
gestoppt. Ansagen aus Kampf, Chat oder Navigation sind davon nicht betroffen.
Technisch: Ein Tastendruck allein bricht weiterhin nichts ab (Regel aus v43.2), und auf der
Screenreader-Bruecke ist das Ende einer Aeusserung nicht feststellbar, weil FINISHED im
Uebergabe-Frame kommt - die Buchfuehrung "spricht gerade etwas" ist dort immer leer,
weshalb selbst der Stop beim Menue-Schliessen als ueberfluessig unterdrueckt wurde.
Bekannt ist aber genau, was zuletzt uebergeben wurde und fuer wen. Eine Zeile kann jetzt
einen Bereich tragen ("menu" fuer Menueansagen, "echo" fuer die Tippspur), und
SkuVoice:EndScope verwirft beim Ende des Bereichs dessen wartende Zeilen und stoppt die
Stimme nur, wenn die laufende Aeusserung dazugehoert. Gerufen wird das beim
Menue-Schliessen und im Hide-Hook jedes beobachteten Fensters, also auch bei Escape im
Spiel. Der weiche Stop des Chatfelds fragt statt der Ein-Sekunden-Regel jetzt
SkuVoice:IsEchoInFlight: Echo wird abgebrochen, egal wie lange es laeuft; wurde seither
etwas anderes uebergeben - vor allem die Antwort des Servers auf die gesendete
Nachricht -, wird nichts gestoppt. Yennesta hatte in PR 19 den unbedingten Abbruch
vorgeschlagen; das hier ist die gezielte Fassung davon.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v43.3
Ueberblick
Neu
Das Installationsprogramm gibt es jetzt auch fuer den Mac - installieren, aktualisieren und Selbst-Update wie unter Windows. Danke an Yennesta.
Installationsprogramm 5.0: sieben bewaehrte Zusatz-Addons wie Questie und Deadly Boss Mods lassen sich mitinstallieren und werden aktuell gehalten - Windows und Mac, Anniversary und Classic Era.
Mac: Installationsprogramm und Anmelde-Tool sprechen Deutsch, Englisch und Franzoesisch; das Anmelde-Tool erkennt auch franzoesische Clients.
Aenderungen
Zu Einheit drehen und Zum Ziel drehen drehen jetzt wie Zum Beacon drehen: kuerzester Weg, hoechstens eine Viertelsekunde.
Fehlerbehebungen
Sprachausgabe: einzelne Ansagen blieben stumm, obwohl der Ton kam - vor allem bei kurzen Zeilen, die man immer wieder hoert.
Interagieren-Taste: nach einem Kill schnappt sie manchmal ein weit entferntes Vieh ins Ziel und laeuft hin statt zu pluendern - Sku warnt jetzt mit einem Ton.
Mac: die Sprachausgabe las an jeder Zeile technisches Steuer-Markup mit vor.
Stallmeister: das Menue zeigte und tauschte die falschen Begleiter-Plaetze, und die Tausch-Ansage meldete zu frueh einen Fehlschlag.
Chat: ein Kampfprotokoll-Tab blieb komplett stumm.
Dial Targeting war auf dem Anniversary-Client komplett tot - funktioniert wieder, getestet im 25er-Schlachtzug.
Franzoesisch: vier Chat-Einstellungstexte sprachen noch Englisch.
Franzoesisch: vier Chat-Texte sprachen noch Englisch
Einfach: Auf einem franzoesischen Client waren die Einstellung der Pfeiltasten in der
Chateingabe, die Kanal-Ansage samt Erlaeuterung und die Meldung fuer einen unbekannten
Slash-Befehl noch auf Englisch zu hoeren. Sie sind jetzt uebersetzt.
Technisch: Die vier Texte aus v43.1 fehlten im Uebersetzungsspeicher, aus dem die
franzoesische Sprachdatei erzeugt wird. Beim Beheben fiel auf, dass 29 fuer v43.2 von
Hand in die erzeugte Datei geschriebene Texte ebenfalls nur dort standen - der
naechste Erzeugungslauf haette sie stillschweigend auf Englisch zurueckgesetzt. Alle
sind jetzt in den Speicher uebernommen, und das Erzeugungswerkzeug schreibt die Datei
nur noch auf ausdrueckliches Kommando statt bei jedem unbekannten Argument.
Sprachausgabe: wiederholte Ansagen bleiben nicht mehr stumm
Einfach: Beim Navigieren in Menues und Tooltips kam ab und zu nur der Ton, die Ansage selbst
blieb aus. Betroffen waren vor allem die kurzen Zeilen, die man den ganzen Abend wieder
und wieder hoert - "menue geschlossen", "annehmen", "buffs" oder ein einzelner getippter
Buchstabe.
Technisch: Der Client merkt sich erzeugte Sprachausgabe zum Text und spielt sie bei einer
Wiederholung aus dem Zwischenspeicher ab, ohne die Stimme erneut aufzurufen. Ueber eine
Bruecke zum Screenreader ist diese Wiederholung stumm. Sku haengt deshalb an jede Zeile
eine unhoerbare Kennung an, damit jeder Aufruf neu erzeugt wird - bisher aus einem
Zaehler, der alle 64 Ansagen von vorn begann. Eine Zeile, die genau 64 Ansagen spaeter
noch einmal kam, war damit zeichengleich und landete wieder im Zwischenspeicher. Der
Zaehler laeuft jetzt pro Text statt fuer alle Ansagen gemeinsam; eine neu gesehene Zeile
bekommt ihren Startwert weiterhin aus dem gemeinsamen Zaehler, damit auch das Leeren der
Tabelle (ab 512 verschiedenen Zeilen) keine Zeile auf ihren eigenen ersten Wert
zurueckwirft. Nachgerechnet an einer Aufzeichnung von 1307 Ansagen: vorher 27
zeichengleiche Wiederholungen, mit einem Zaehler pro Text ohne diesen Startwert 80 -
also schlechter -, in der ausgelieferten Fassung 0.
Mac: die Sprachausgabe liest kein Steuer-Markup mehr vor
Einfach: Auf dem Mac sprach die Stimme zu den Zeilen hoerbar Steuerzeichen mit, die nur
fuer die Technik gedacht sind. Sie sind dort jetzt weg.
Technisch: Fuer den Handschlag mit dem Screenreader haengt Sku eine -Markierung
an jede Zeile; der Mac-Client filtert solches Markup nicht aus der Sprachausgabe und
las es woertlich vor. Auf dem Mac wird die Markierung jetzt weggelassen; die
unhoerbaren Zeichen gegen den Wiederholungs-Zwischenspeicher bleiben, damit auch dort
jede Wiederholung neu erzeugt wird. Idee von Yennesta.
Zu Einheit drehen: schneller und praeziser
Einfach: "Zu Einheit drehen" und "Zum Ziel drehen" drehen jetzt genauso wie "Zum Beacon
drehen": auf kuerzestem Weg, in hoechstens einer Viertelsekunde, statt bis zu
anderthalb Sekunden lang rechts herum zu suchen.
Technisch: Der fuer v43.2 gebaute und ausgiebig getestete Drehkern (Richtungs-Schnapp,
Tempodeckel, Vorhalten in Bewegung, Geradestellen mit der Neigungssperre) ist von der
Wegpunkt-Aufloesung getrennt worden, so dass ihn jetzt auch die Einheiten-Drehung
aufruft, sobald der Client Koordinaten zur Einheit liefert. Die bisherige Suche ueber
Namensplaketten bleibt als Rueckfall fuer Instanzen, wo es keine Koordinaten gibt.
Die Aufloesung des Ziels zu einer Einheit folgt einer Idee von Yennesta.
Stallmeister: der Begleiter-Tausch trifft wieder die richtigen Plaetze
Einfach: Im Stallmeister-Menue des Jaegers waren die Plaetze verschoben - angezeigt und
getauscht wurde der falsche Begleiter. Ausserdem meldete der Tausch bei langsamer
Verbindung faelschlich "Begleiter konnte nicht gewechselt werden", obwohl er geklappt
hatte. Beides ist behoben, und die Ansage nennt jetzt den Namen des neuen Begleiters.
Technisch: Blizzards Stallfenster nutzt die Aktionsindizes 1 bis 3 (aktiver Begleiter
plus zwei Stallplaetze); Sku fragte einen zu niedrig ab. Fix von Yennesta. Die
Erfolgs-Ansage entscheidet ausserdem nicht mehr auf dem ersten Stall-Ereignis (das
schon beim Aufnehmen feuert), sondern wartet, bis der Name des aktiven Begleiters
passt oder zwei Sekunden vergangen sind - und sie ist jetzt in allen drei Sprachen
uebersetzt.
Neu: das Installationsprogramm gibt es auch fuer den Mac
Einfach: Sku laesst sich auf macOS jetzt genauso bequem installieren und aktuell halten
wie unter Windows: ein Installationsprogramm mit Sprachausgabe, Selbst-Update und
denselben Komponenten. Die Download-Seite bietet einen eigenen Link je Plattform.
Beigesteuert von Yennesta - vielen Dank!
Technisch: Der Mac-Zweig haengt am selben Veroeffentlichungs-Ablauf wie Windows: die
Versionserkennung folgt der releases/latest-Weiterleitung von GitHub, statt eine
Webseite zu lesen, und die Dateien samt ihren sha256-Pruefsummen werden beim
Veroeffentlichen lokal geprueft und an dieselbe Veroeffentlichung angehaengt.
Interagieren-Taste: Warnton, wenn sie das falsche Ziel schnappt
Einfach: Direkt nachdem etwas stirbt, nimmt die Interagieren-Taste (Standard G) manchmal
statt der Leiche vor dir ein ganz anderes, angreifbares Vieh ins Ziel - auch eines weit
entfernt - und laeuft per Autolauf dorthin, statt zu pluendern. Sku spielt jetzt in
genau diesem Moment einen Warnton, damit du den Fehlgriff sofort hoerst und den Autolauf
von Hand abbrechen kannst.
Technisch: Die Taste ruft Blizzards InteractUnit("anyinteract") mit lockerer Zielwahl auf;
verschwindet die gerade gepluenderte Leiche unter dem Tastendruck, greift der Client
lose auf die naechste angreifbare Einheit in Tab-Reichweite ueber, macht sie zum
Hartziel und laeuft hin. Die Taste selbst laesst sich nicht ersetzen (InteractUnit ist
geschuetzt), und auch das Ziel laesst sich aus einem Addon nicht zuruecksetzen
(ClearTarget ist ebenfalls geschuetzt, im Kampf wie ausserhalb). Bleibt die Erkennung:
unmittelbar nach dem Verlassen einer Leiche ein lebendes, angreifbares, NICHT mit dir im
Kampf stehendes neues Ziel - dann der Warnton. Ein bewusst per Taste (Alt+H / Strg+H)
gewaehltes Ziel loest ihn nicht aus.
Installationsprogramm 5.0: bewaehrte Zusatz-Addons mitinstallieren
Einfach: Auf der Komponenten-Seite lassen sich jetzt sieben bewaehrte Addons ankreuzen -
Questie, Deadly Boss Mods, AtlasLoot, Details, GTFO, BugSack samt BugGrabber und Pawn.
Was angekreuzt ist, installiert das Installationsprogramm mit und haelt es bei jedem
Lauf aktuell - unter Windows und auf dem Mac, fuer Anniversary und Classic Era,
jeweils mit dem zum Client passenden Stand. Ab Werk ist alles an ausser Pawn.
Technisch: Beide Plattformen lesen denselben Katalog. Addons mit
GitHub-Veroeffentlichungen kommen direkt von dort (aufgeloest ueber die
releases/latest-Weiterleitung, ohne API-Schluessel und ohne Ratenbegrenzung); der
Rest ist mit sha256-Pruefsumme auf gepruefte CurseForge-Dateien festgenagelt. Deadly
Boss Mods ist ein Eintrag aus vier Paketen, und BugSack und BugGrabber sind bewusst
ein gemeinsames Haekchen. Jeder Client bekommt den zu ihm passenden Build - Pawn fuer
Classic Era etwa kommt aus dem Classic-Paket.
Mac: Installationsprogramm und Anmelde-Tool in drei Sprachen
Einfach: Beide sprechen jetzt Deutsch, Englisch und Franzoesisch. Die Sprache laesst sich
im jeweiligen Menue umstellen und folgt sonst der Systemsprache. Das Anmelde-Tool
erkennt ausserdem franzoesische Clients und liest Stufenzeilen woertlich vor - ein
deutscher Client sagt also wieder "Stufe 36" statt "Level 36".
Technisch: App, Installations-Skript und Anmelde-Tool teilen sich eine Sprachwahl
(gespeicherte Einstellung vor Systemsprache vor Englisch); gespeicherte Werte wie die
Sprachpaket-Namen bleiben intern deutsch, damit bestehende Einstellungen weitergelten.
Die Bildschirmerkennung des Anmelde-Tools ist von der Oberflaechensprache unabhaengig.
Chat: das Kampfprotokoll bekommt wieder Ereignisse
Einfach: Ein Chat-Tab "Kampfprotokoll" blieb komplett stumm. Er fuellt sich wieder. Danke
an den Tester aus der Community fuer die Meldung samt Loesung.
Technisch: Der Tab hatte das Ereignis COMBAT_LOG_EVENT abonniert, das auf diesem Client
nicht so feuert, wie der Code es erwartet; jetzt abonniert er
COMBAT_LOG_EVENT_UNFILTERED - dasselbe Ereignis, das die anderen Sku-Module laengst
nutzen.
Dial Targeting funktioniert wieder
Einfach: Die Zielwahl ueber den Ziffernblock (Eintrag "Dial Targeting" im Sku-Menue) war
auf dem Anniversary-Client komplett tot - kein Tastendruck kam an. Sie funktioniert
wieder, getestet im 25er-Schlachtzug. Obendrein: in einer normalen Gruppe (ausserhalb
des Schlachtzugs) hatte sie noch nie jemanden gefunden, die Mitglieder 30 bis 40
waren nicht waehlbar, und eine halb eingegebene Nummer konnte die naechste Eingabe
verderben - alles behoben.
Technisch: Der moderne Client stellt Tastatur-Klicks nur noch zu, wenn der Knopf sie per
RegisterForClicks angemeldet hat - das fehlte, und damit war das ganze Feature stumm.
Die Aktion feuert jetzt ausserdem unabhaengig von der Klick-Einstellung des Nutzers
genau einmal pro Tastendruck. Die Gruppen-Belegung kommt aus party1 bis party4 statt
aus der nur im Schlachtzug gefuellten Abfrage, das Tor fuer die erste Ziffer laesst
auch die Untergruppen 6 bis 8 durch, und die belegte Tastenmatrix steht bei jeder
Aenderung im Debug-Log. Hinweis: die Nummern entsprechen dem Schlachtzugs-Abschnitt
der Uebersichtsseite; der Gruppen-Abschnitt dort zaehlt dich selbst immer als 1 und
verschiebt dadurch die uebrigen - das ist Absicht und kein Fehler der Zielwahl.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v43.2
Ueberblick
Neu
Quests lassen sich im Questmenue verfolgen und wieder abwaehlen - neuer Eintrag "Quest verfolgen" ganz unten in jedem Questmenue, abschaltbar.
Neue Liste "Quests in der Naehe" im Questmenue: das ganze Questlog in einer Liste, sortiert danach, wie weit das Naechste weg ist - mit Entfernung und Himmelsrichtung. Ab Werk aus.
Neuer Tastenbefehl "Naechstes Questziel ins Ziel nehmen" (Alt+H): nimmt eine Kreatur ins Ziel, die zu einem offenen Questziel gehoert - auch eine, die einen benoetigten Gegenstand nur fallen laesst.
Der Tastenbefehl "Naechster Gegner im Kampf" (jetzt ab Werk auf Strg+H) findet deutlich oefter etwas: er ist nicht mehr auf den Blickkegel angewiesen.
Neuer Tastenbefehl "Vollstaendigen Tooltip des Ziels ausgeben" (Strg+Umschalt+V): liest den kompletten Tooltip des aktuellen Ziels vor, inklusive dessen, was die Jaegerfaehigkeit Tierkunde offenlegt.
Taschenmenue: neuer Eintrag "alle bank" direkt hinter "alle taschen", solange die Bank offen ist - alles in der Bank in einer flachen Liste, genau wie "alle taschen" fuer die Taschen. Strg+Eingabe holt einen Gegenstand von dort in die Taschen, wie bisher schon in den einzelnen Bankfaechern.
Chat: die Eingabezeile spricht jetzt wie jedes andere Sku-Eingabefeld - jedes getippte Zeichen, das Zeichen oder Wort unter dem Cursor, und mit Pfeil hoch die zuletzt gesendeten Nachrichten zum erneuten Senden oder Aendern.
Chat: der Zielkanal wird angesagt, sobald er nicht "Sagen" ist - beim Oeffnen und bei jedem Wechsel; abschaltbar in den Chat-Einstellungen ("Kanal der Chateingabe ansagen"), ab Werk an.
Chat: ein unbekannter Slash-Befehl wird angesagt, statt still verworfen zu werden.
Schwimmen und Fliegen: Sku haelt dich waagerecht. Die neue Neigungssperre beendet das schleichende Abtauchen bei den automatischen Drehungen, und nach einem Anflug auf einen NPC oder einem Druck auf Steigen/Sinken wirst du aktiv wieder gerade ausgerichtet. Ab Werk an; abschaltbar unter Einstellungen -> Allgemein.
Neuer Tastenbefehl "Neigungssperre beim Schwimmen und Fliegen umschalten" (Strg+Umschalt+N): sperrt und loest die Neigung manuell - aus- und wieder einschalten richtet dich jederzeit neu waagerecht aus.
Experimentell: Sammelrouten fuer Erze, Kraeuter, Gaswolken und Truhen - Sku fuehrt dich Vorkommen fuer Vorkommen durch die Zone, immer das naechstgelegene zuerst. Unter Einstellungen -> Scan -> ressourcen scan -> Sammelrouten. Neu und im Spiel erst in Ansaetzen erprobt; Rueckmeldungen sind ausdruecklich erwuenscht.
Neues Menue "Namensplaketten" unter Einstellungen -> Visuelle Hilfen: Groesse der Plaketten, Hervorhebung des Ziels, Klassenfarben und Abschwaechung der uebrigen Plaketten - Einstellungen, die das Spiel beherrscht, in seinem eigenen Optionsfenster aber nirgends anbietet.
Das Lesefenster fuer Questtexte, Tooltips, Chatverlauf und Wiki ist einstellbar geworden: Schriftgroesse, Schriftart, Farbkombination, Deckkraft und Umriss unter Einstellungen -> Visuelle Hilfen -> Textfenster.
Aenderungen
Zum Beacon drehen (T): die Drehung sitzt jetzt deutlich genauer. Vorher lief sie so schnell, dass allein das framegenaue Stoppen je nach Bildrate 20 Grad und mehr Ueberdreh kosten konnte; jetzt richtet sich das Tempo nach der Drehgroesse, und keine Drehung dauert laenger als eine Viertelsekunde.
Zum Beacon drehen: in Bewegung wird vorgehalten - gezielt wird dorthin, wo der Wegpunkt am Ende der Drehung liegen wird. Das beendet das Im-Kreis-Laufen um nahe Wegpunkte, das vor allem beritten und im Flug auftrat.
Zum Beacon drehen: ein Druck waehrend einer laufenden Drehung wird verworfen, statt die Drehung mittendrin abzubrechen - gewohntes Mehrfachdruecken verfeinert weiter wie bisher.
Navigation: unter "Direkter Wegpunkt" steht "Aktuelle Karte Entfernung" jetzt an erster Stelle und "Letzte" dahinter.
Questdatenbank: "Start in Zone" zeigt die nach Entfernung sortierte Liste direkt an - die Zwischenebene "Nach Entfernung" ist weg.
Questdatenbank: "Start in Zone" nennt zu jeder Quest jetzt auch die Himmelsrichtung, nicht nur die Entfernung.
Questdatenbank: auf den aktuellen Questie-Datenstand gebracht - 33 Quests ohne Ziel haben jetzt eines, fuenf fehlende ergaenzt, dazu rund 2000 kleinere Korrekturen an Namen, Stufen, Questgebern und Vorquests.
Taschen: nach einem Rechtsklick auf einen Gegenstand bleibt der Cursor auf diesem Gegenstand stehen, statt an den Anfang der Liste zu springen.
Taschen: Aktionen mit Zauberzeit (Verzauberung, Angelkoeder, Waffenoel, Ruestungsset, Entzaubern) melden den Gegenstand nach dem Zauber noch einmal und lassen den Cursor darauf stehen.
Taschen: ein Bestaetigungsdialog wie "Bestehende Verzauberung ersetzen?" kostet nicht mehr die Position - nach "Ja" wie nach "Nein" landet man wieder auf dem Gegenstand.
Chat: "Link zu Chat hinzufuegen" fuegt den Gegenstand an der Cursorposition ein, statt die Zeile zu ersetzen, und laesst den Cursor davor stehen - davor passt jetzt noch ein Kanal wie "/p ".
Chat: ein Gegenstandslink zaehlt beim Lesen als ein einziges Zeichen - Pfeil links und rechts springen ueber den ganzen Link und sagen den Namen.
Chat: "Link zu Chat hinzufuegen" schliesst die Taschen nicht mehr.
Chat: die Pfeiltasten bewegen in der Chateingabe den Textcursor; abschaltbar unter Chateinstellungen.
Auren: eine Waffenverzauberung (Angelkoeder, Gift, Oel) laesst sich jetzt wie ein Zauber ansprechen - Ereignis "Waffenverzauberung abgelaufen" zusammen mit "Zauber name".
Auren: neue Bedingung und neue Ausgabe "Waffenverzauberung Hand" (Haupthand oder Nebenhand).
Menue: das Schliessen eines Fensters baut die Menuedaten nur noch einmal statt bis zu sechsmal neu auf.
Menue: der Tippfilter ignoriert Akzente - auf einem franzoesischen Client findet "general" jetzt "Fournitures generales", und "oe" findet einen Eintrag, der mit "Oe" beginnt. Auf einer franzoesischen AZERTY-Tastatur tippt die Taste ù jetzt auch in den Filter.
Franzoesisch: die Wegpunktkommentare gibt es jetzt auf Franzoesisch - 207 Texte auf 546 Wegpunkten, aus dem deutschen Original uebersetzt.
Installationsprogramm: ein WoW an einem ungewoehnlichen Ort muss nur einmal gezeigt werden - das Installationsprogramm merkt sich, wo jeder Client liegt, und findet ihn bei jedem spaeteren Update von selbst wieder.
Das Lesefenster startet ab Werk serifenlos in 18 Punkt statt in Playfair Display in 12 - die bisherige Voreinstellung war die kleinste und duennste Textflaeche des ganzen Addons.
Auch der Lesebalken laesst sich jetzt in Schriftart und Farbkombination einstellen, mit eigenen Werten getrennt vom Textfenster.
Auktionshaus: "Level absteigend" sortiert jetzt die ganze Trefferliste und nicht mehr nur die erste Seite; bei gleicher Stufe entscheidet der Preis je Stueck.
Auktionshaus: "Stufe" ist ueberall die Stufenanforderung des Gegenstands - und wird nur noch dort vorgelesen, wo sie die Eintraege wirklich unterscheidet.
Fehlerbehebungen
Menue: waehrend man ging, war das geoeffnete Menue wie tot - jede Taste ausser Escape wurde verschluckt, bis man stehen blieb.
Escape schloss das Menue nicht, wenn man direkt auf einem Questobjekt stand - das Questfenster ging endlos wieder auf.
Menue: Enter auf einem Ein/Aus-Eintrag in einer gefilterten Liste sagte den ersten Eintrag der Liste an statt des umgeschalteten Zustands.
Menue: eine Zeile, die man per Tastendruck erneut anfordert, wird wieder vorgelesen statt verschluckt.
Menue: der Tippfilter fasste das Getippte als Suchmuster auf - eine Eingabe wie "50%" oder "(lang" fand nichts oder brach ab.
Tastatur-Echo: getippte Zeichen kommen sofort; verschluckte und verspaetete Buchstaben sind weg.
Sprachausgabe: Ansagen blieben beim Navigieren immer wieder fuer eine Weile still - am zuverlaessigsten bei einem einzelnen Treffer nach dem Filtern.
Sprachausgabe: Gegenstandslinks wurden als Folge von Farbcodes vorgelesen statt als Name - ueberall in Sku, nicht nur im Chat.
Zum Beacon drehen: nach schnell hintereinander ausgeloesten Drehungen konnte die Drehgeschwindigkeit der Kamera-Tasten dauerhaft vervierfacht haengenbleiben.
Das Loeschen eines eigenen Wegpunkts entfernte die falsche interne Kennung, und "/skucheck wp" meldete vier Fehler bei den Schnellwegpunkten, die keine waren.
Questmenue: bei Quests mit gemischten Zielen ("toete X und sammle Y") zeigte "Ziel" nur die erste Zielart - jetzt stehen Gegner, Fundorte und Erkundungspunkt nebeneinander.
Questmenue: bei 174 Quests, deren Ziel ein ORT ist, stand der Ort zwar in den Daten, aber "Questziel" meldete trotzdem nur "Leer" - gesucht wurde ein Wegpunkt unter einem Namen, den nie jemand vergibt. Jetzt wird aus den Koordinaten der naechstgelegene Routenwegpunkt berechnet.
Bei 77 WEITEREN Quests fehlten die Zieldaten dagegen ganz - fuer sie sind Objekte, Kreaturen und 26 Ortskoordinaten neu eingetragen, ein Teil davon aus Webquellen: Rueckmeldungen, ob sie stimmen, sind willkommen.
Questmenue: rund 300 Quests, deren Questgeber, Ziel oder Abgabe in einem Dungeon liegt, zeigten leere Eintraege - jetzt fuehren sie zum Dungeoneingang.
Dreizehn Sprich-mit-Quests (u.a. die alten Priester-Zauberquests) standen ohne Abgabepunkt in den Daten - jetzt fuehrt die Abgabe zu dem NPC, den der Questtext nennt.
Questdatenbank: direkt nach einem /reload konnten Quests inaktiver Weltereignisse (etwa Sonnenwendquests) in "Start in Zone" auftauchen.
Questdatenbank: die Liste "Start in Zone, Nach Entfernung" brach nach der ersten Quest ab.
Taschen: der Tippfilter blieb nach dem Benutzen eines Gegenstands haengen und liess sich nur noch durch Schliessen der Taschen loswerden.
Nach einer Aktion mit Zauberzeit wurde direkt nach dem richtigen Gegenstand noch ein falscher angesagt.
Die Taschenliste fuer den Kampf konnte veralten, wenn man ein Questfenster schloss, waehrend die Taschen offen waren.
Taschenmenue: mit einem Taschen-Ersatz-Addon wie Bagnon, das Blizzards Bankfenster versteckt, verschwanden saemtliche Bankfaecher aus dem Menue.
Auren: der Satt-Buff war in der Zauberauswahl doppelt vorhanden - beide Eintraege klangen gleich, nur einer konnte je ausloesen.
Auren: Eintraege, die es nur als Waffenverzauberung gibt (etwa "Angelfertigkeit +75"), sind in den Auswahllisten jetzt als solche gekennzeichnet.
Auren: "Waffenverzauberung Haupthand enthaelt X" zusammen mit "Waffenverzauberung abgelaufen" konnte nie ausloesen - /skucheck auras meldet diese Kombination jetzt.
Auren: das Ende einer Waffenverzauberung wird auf den Frame genau erkannt statt bis zu eine viertel Sekunde spaeter.
Aktionsleisten: Umschalt+Ab las im Zuweisungsmenue den Zauber-Tooltip nicht mehr vor.
Dungeonbrowser: das Annehmen einer Gruppeneinladung fuehrt nicht mehr von selbst in den Dungeonbrowser.
Franzoesisch: die Wegpunktkommentare blieben seit v42.11 vollstaendig stumm - auch die Warnungen wie "Vorsicht, Abgrund" oder "hier auf den Zeppelin warten".
Franzoesisch: 22 der 94 Ressourcennamen des Minikartenscanners waren falsch, diese Vorkommen wurden nie angesagt.
Franzoesisch: in der Hoehle der Nebel blieb die Wegpunktliste leer.
Die Plaketten-Farben waren nach jedem Login und jedem Neuladen tot: der Schalter stand auf an, gefaerbt wurde aber nichts, bis man ihn von Hand zweimal umlegte.
Der Lesebalken blieb im Kampf unsichtbar - also genau dann, wenn er am dringendsten gebraucht wird.
Der Lesebalken zeigte nur den Namen eines Menueeintrags, nicht den vorgelesenen Wert dahinter - Schalterzustaende und Anzahlen waren hoerbar, aber nicht lesbar.
Ein geschlossenes Fenster konnte spaeter noch einmal angesagt werden - typisch der Lehrer, nachdem man laengst sein Berufsfenster geoeffnet hatte.
Das Menue ging gelegentlich von selbst auf der obersten Ebene auf, statt dort, wo man hinwollte.
Waren zwei Fenster gleichzeitig offen, wurde das Schliessen des zweiten nicht bemerkt.
Nach dem Schliessen eines Fensters konnten dessen Eintraege unter "Lokal" stehenbleiben.
Lehrer: lernte man mehrere Zauber schnell hintereinander und schloss das Fenster gleich danach, sprach es noch weiter.
Auktionshaus: "Nur benutzbare" versteckte in der Komplettscan-Liste ausgerechnet das Hochstufige, nach dem man sucht.
Auktionshaus: die Komplettscan-Liste filterte nach Stufe und Qualitaet, obwohl gar kein Filter gesetzt war - Handelswaren, Materialien und alles Graue fehlten.
Auktionshaus: eine Kategorie ohne Unterkategorien zeigte ausser "Alle" keinen einzigen Gegenstand.
Auktionshaus: ein abgebrochener Kauf konnte die naechste Suche entfuehren und ungefragt einen Kauf scharf schalten.
Auktionshaus: eine Suche, die der Waechter abbricht, sagt das jetzt - vorher sah die halbe Liste wie ein fertiges Ergebnis aus.
Schwimmen und Fliegen: die Neigungssperre beendet das ungewollte Abtauchen
Einfach: Beim Schwimmen oder Fliegen zog jede automatische Drehung zum Funkfeuer ein
kleines Stueck nach unten - ueber eine Strecke summierte sich das, bis man unbemerkt
unter Wasser oder am Boden war. Jetzt sperrt Sku die Neigung, sobald du schwimmst
oder fliegst: du bewegst dich exakt waagerecht, und Leertaste und X tragen dich
weiterhin nach oben und unten. Wenn dich doch etwas schief stellt - etwa der
automatische Anflug beim Interagieren mit einem NPC -, richtet Sku dich aktiv wieder
gerade: beim Oeffnen des NPC-Fensters, kurz nach jeder Drehung und immer, wenn du
Steigen oder Sinken drueckst. Ab Werk an; wer beim Schwimmen mit der Maus per Neigung
tauchen will (Restsehvermoegen), schaltet es unter Einstellungen -> Allgemein ab.
Dazu der neue Tastenbefehl "Neigungssperre" (Strg+Umschalt+N) zum manuellen Sperren
und Loesen.
Technisch: Drei Bausteine. Erstens deckelt die Konsolenvariable pitchlimit 0 die
Bewegungsneigung des Charakters (die Technik der Addons LevelFlight und FlightHUD) -
dauerhaft gesetzt statt um jeden Dreh-Impuls herum, denn genau dieses Umschalt-Rennen
hat fruehere Versuche scheitern lassen. pitchlimit ist beschreibbar, aber nicht
lesbar; bei jedem Login wird deshalb blind der Standard 88 wiederhergestellt, damit
nie eine Sperre haengenbleibt. Zweitens haelt die Sperre nur, was da ist:
engine-gesteuerte Bewegung wie der Interagieren-Anflug neigt den Charakter trotzdem,
und danach gibt es keine Tastatur-Eingabe, die die Neigung wieder anhebt. Das aktive
Geradestellen benutzt genau den Transfer, der urspruenglich den Fehler verursachte:
ResetView/SetView schnappt die Kamera auf die bekannte fast-waagerechte
Voreinstellung, ein Mouselook-Impuls uebertraegt sie auf den Charakter, und die
Sperre deckelt den kleinen Rest auf null. Ausloeser sind das NPC-Fenster, jede
Drehung (um 0,5 s verzoegert, weil die Engine die Gierung erst einen Frame spaeter
anwendet - ein sofortiger zweiter Impuls wuerde die Drehung aufheben) und per
hooksecurefunc die Steig-/Sinkfunktionen JumpOrAscendStart, AscendStop,
SitStandOrDescendStart und DescendStop - unabhaengig davon, auf welchen Tasten sie
liegen. Drittens ein Neigungsmesser fuers Log: gemessene Horizontalgeschwindigkeit
geteilt durch GetUnitSpeed ist der Kosinus der Bahnneigung - der einzige Messweg,
den dieser Client hergibt (GetUnitPitch wurde mit Patch 7.1 entfernt und fehlt auch
hier). Er misst die Bahn, nicht die Koerperneigung, und dient nur der Diagnose.
Der Cursor bleibt in der Tasche auf dem Gegenstand
Einfach: Wer in der Taschenliste einen Gegenstand rechts anklickte - benutzen, anlegen, an
einen Haendler verkaufen, eine Verzauberung anwenden -, stand danach schlagartig auf
dem ersten Eintrag der ganzen Liste. Bei Gegenstaenden, die sofort verschwinden, fiel
das kaum auf, weil die Liste sich ohnehin neu sortiert; bei allem anderen war es
einfach ein Verlust der Position. Jetzt bleibt der Cursor auf dem Gegenstand, auf dem
man gearbeitet hat, und wenn der Gegenstand die Tasche verlaesst, landet man an seinem
Platz - also auf dem, was nachgerueckt ist.
Technisch: Ursache war nie ein Verrutschen von Indizes, sondern die dritte Zeile des
Rechtsklick-Makros, "/script SkuCore:CheckFrames()". Sie stammte aus der Zeit vor der
ereignisgesteuerten Bestaetigung und lief BEIM TASTENDRUCK - also bevor die Aktion
ueberhaupt etwas veraendert hatte, bei einer Aktion mit Zauberzeit sogar Sekunden
davor. Sie baute damit veraltete Daten neu auf und kostete dabei die Position.
Entfernt; die Auffrischung gehoert allein der von BAG_UPDATE getriebenen Bestaetigung,
die erst aufbaut, wenn die Taschen wirklich ruhig sind, und den Cursor dann ueber
Taschen-Fach und Gegenstands-ID wieder anheftet. Zusaetzlich merkt sich CheckFrames
beim Neuaufbau nicht mehr nur die Zeilennummer, sondern auch den Namen des Eintrags,
und sucht ihn in der neu gebauten Liste - die Zeilennummer allein stimmt naemlich
nicht mehr, sobald die Liste zwischendurch eine andere Form hatte.
Verzauberungen, Koeder und Oele: die Liste aktualisiert sich nach dem Zauber
Einfach: Eine Verzauberung, ein Angelkoeder, ein Waffenoel, ein Ruestungsset oder das
Entzaubern veraendern die Taschen erst, wenn der Zauber fertig ist - oft fuenf
Sekunden nach dem Klick. Bis dahin hatte Sku laengst aufgegeben: die Liste blieb
veraltet, und der Cursor stand irgendwo. Jetzt wartet Sku den Zauber ab, meldet danach
den Gegenstand einmal und laesst den Cursor darauf stehen. Wer waehrenddessen selbst
weiterblaettert, behaelt seine eigene Position - dann mischt sich Sku nicht mehr ein.
Technisch: Das beim Rechtsklick geoeffnete Bestaetigungsfenster lief nach 2,5 Sekunden ab.
UNIT_SPELLCAST_START/-CHANNEL_START schieben seine Frist jetzt bis zum Ende des
Zaubers und behalten dabei den beim Klick gemerkten Anker, sodass das Wiederanheften
danach genau den behandelten Gegenstand trifft. Bewusst ohne Zauberliste: dass das
Fenster offen ist, ist bereits der Beleg, dass der Zauber zu dieser Aktion gehoert.
Zwei harte Sperren, beide an einem echten Fall gelernt: der Zauber muss innerhalb
einer Sekunde auf den Klick folgen ("/use" startet ihn im selben Frame), und die
Verlaengerung greift nur ein einziges Mal. Ohne sie schob das 22 Sekunden lange
Angeln die Frist immer weiter vor sich her, und das Fenster starb nie.
Der Bestaetigungsdialog kostet nicht mehr die Position
Einfach: Wer eine Verzauberung auf einen bereits verzauberten Gegenstand anwendet, bekommt
von Blizzard die Rueckfrage "Bestehende Verzauberung ersetzen?". Nach "Ja" oder "Nein"
stand man anschliessend ganz oben in der Taschenhierarchie, also auf "Tasche 1" statt
auf dem Gegenstand. Jetzt fuehrt beide Antworten wieder zum Gegenstand zurueck, und er
wird einmal angesagt.
Technisch: Der Dialog ist ein modales Fenster zwischen dem Klick und seiner Wirkung und
zerstoerte die Position gleich zweifach: die 2,5-Sekunden-Frist lief waehrend des
Dialogs ab, und Sku verankert das Menue IM Dialog, sodass beim Schliessen nichts mehr
da war, wohin zurueckgekehrt werden konnte - der allgemeine Einstieg nahm dann das
einzige offene Fenster und landete oben in der Taschenliste. SkuBagPostActionPopupGate
haelt das Fenster offen, solange der Dialog steht (bis 30 Sekunden), und stoesst beim
Schliessen die Bestaetigung an. Genau die ist das richtige Werkzeug, weil sie beide
Antworten abdeckt: "Nein" erzeugt weder Zauber noch Taschenaenderung, es gaebe also
sonst gar nichts, was den Cursor zuruecklegen koennte. Solange der Dialog steht,
haelt sich die Bestaetigung komplett zurueck - sonst risse eine unbeteiligte
Taschenaenderung (einsammelnde Beute, ein abgeschlossener Handel) den Cursor mitten
aus dem Dialog heraus.
Der Tippfilter in der Taschenliste loest sich wieder
Einfach: Wer in der Taschenliste einen Namen tippt, filtert die Liste auf die Treffer.
Dieser Filter loeste sich bisher nicht mehr, sobald man den gefilterten Gegenstand
benutzt hatte: auch Pfeil links und wieder rechts brachten die volle Liste nicht
zurueck, nur das Schliessen der Taschen half. Jetzt raeumt jede dieser Tasten den
Filter wieder ab, so wie man es gewohnt ist. Passt auf den Filter gar nichts, bleibt
die Liste weiterhin leer und die Pfeiltasten wiederholen nur den getippten Filter -
genau daran hoert man, dass es keinen Treffer gibt.
Technisch: SkuOptions:ClearFilter vergass nur den getippten Text; die von ApplyFilter
eingesetzte gefilterte Kinderliste blieb im Baum stehen, bis irgendetwas sie
vollstaendig ersetzte - und eine aus Spielfenstern gebaute Ebene wie die Taschen kann
sich nicht an Ort und Stelle auffrischen, sie braucht einen kompletten Neuaufbau.
Jahrelang verdeckt vom erzwungenen CheckFrames im Makro (siehe oben), fiel es sofort
auf, sobald eine Aktion die Taschen gar nicht veraendert. ClearFilter stellt die
Liste jetzt wirklich wieder her, samt Vor- und Rueckwaertsverkettung, und zwar an dem
Knoten, den sie gefiltert hat, nicht am gerade aktuellen.
Escape schloss das Menue nicht, wenn man direkt auf einem Questobjekt stand
Einfach: Wer mit ungefaehr null Metern Abstand vor einem Questobjekt stand und das Menue
mit Escape schloss, bekam das Questfenster sofort wieder aufgezogen - und das endlos.
Das Menue liess sich in dieser Lage praktisch nicht mehr schliessen. Jetzt werden erst
die offenen Spielfenster geschlossen und danach das Menue selbst.
Technisch: Das Menue versteckte sich zuerst und arbeitete danach die offenen
Interaktionsfenster ab. Der Quest-Rahmen wurde dadurch geschlossen, waehrend das
Spiel den Gegenstand in Reichweite weiter meldete, und zog sich sofort wieder auf.
Die Reihenfolge ist jetzt umgekehrt und durch einen Zaehler abgesichert, den
"/skucheck menu" ausliest: eine Verletzung dieser Reihenfolge faellt damit auf, ohne
dass jemand zufaellig genau auf diesem Fleck stehen muss.
Weniger doppelte Neuaufbauten beim Fensterschliessen
Einfach: Ein einziges Escape loeste bisher bis zu sechs komplette Neuaufbauten der
Menuedaten aus, weil mehrere Fenster gleichzeitig zugehen und Blizzards Questfenster
allein schon vier Unterbereiche versteckt. Das kostete spuerbar Zeit. Jetzt laeuft pro
Bild genau ein Neuaufbau. Ausserdem konnte die fuer den Kampf vorgehaltene
Taschenliste veralten, wenn ein Questfenster geschlossen wurde, waehrend die Taschen
offen waren - ein Fehler, der erst spaeter im Kampf aufgefallen waere.
Technisch: Die Hide-Pfade laufen ueber SkuCore:CheckFramesCoalesced, dessen Sperre einmal
pro Bild oeffnet; der eigentliche Durchlauf ist ohnehin um 0,01 s verzoegert und liest
den Endzustand, sieht also genau das, was der letzte Aufruf der Serie gesehen haette.
Die OnShow-Seite bleibt bewusst aussen vor. Die Buchhaltung in GENERIC_OnClose hat
eine eigene Sperre bekommen: sie hing vorher am Rueckgabewert derselben geteilten
Sperre, und da die Quest-Unterbereiche zuerst feuern, verbrauchten diese sie und die
Buchhaltung - unter anderem das Auffrischen der Kampf-Taschenliste - fiel aus.
Sprachausgabe: Ansagen bleiben nicht mehr stumm
Einfach: Beim Navigieren blieb die Sprachausgabe immer wieder fuer eine Weile still -
ein Pfeiltastendruck las den Eintrag einfach nicht vor, obwohl es ruhig war und
nichts anderes lief. Besonders zuverlaessig passierte das, wenn man eine Liste auf
einen einzigen Treffer filterte und dann schnell zwischen dem Filter und diesem
Treffer hin und her ging: nach ein paar Wechseln blieb der Treffer dauerhaft stumm,
auch wenn man eine Sekunde wartete. Beides ist behoben.
Technisch: Zwei voneinander unabhaengige Ursachen, beide unterhalb der Warteschlange -
Sku selbst hatte jede Ansage sauber abgeschickt, in einem Mitschnitt ueber
95 Minuten kam auf jeden Tastendruck genau ein SpeakText mit STARTED.
Erstens wurde dieselbe Zeile bis zu viermal innerhalb einer Sekunde erneut
ausgegeben, weil eine ueberfluessige Fensterpruefung den Menueeintrag noch einmal
ansagt; 95 von 1512 Ausgaben waren solche Wiederholungen. Jede bringt ihr eigenes
"queuereset" mit, also ein StopSpeakingText, und das erreicht den Screenreader
wirklich - die Zeile wurde also mitten im Wort abgeschnitten und neu begonnen, und
wenn dabei die Neuausgabe verlorenging, blieb nichts uebrig. Die vorhandene
Dopplungssperre konnte das nicht auffangen: sie haengt an
VOICE_CHAT_TTS_PLAYBACK_FINISHED, und ueber die Screenreader-Bruecke kommen STARTED
und FINISHED noch im selben Bild zurueck - dort ist die Sperre also immer leer und
kann gar nicht greifen. Neu ist eine zeitbasierte Sperre, die eine unmittelbar
folgende identische Zeile innerhalb einer Sekunde verwirft, und zwar samt ihrem
queuereset; nur den Text zu verwerfen wuerde die laufende Ansage trotzdem abschneiden
und nichts an ihre Stelle setzen. Verglichen wird ausschliesslich mit der direkt
davor ausgegebenen Zeile, ein echtes erneutes Vorlesen kann sie also nicht
schlucken, und sie greift nur, wenn die erste Ausgabe wirklich zu spielen begonnen
hatte.
Zweitens war der Cache-Brecher wirkungslos geworden. Der Client legt erzeugte
Sprachdaten nach Text ab und spielt sie bei einer Wiederholung ab, ohne die Stimme
erneut aufzurufen - ueber eine Bruecke ist dieses Abspielen still. Dagegen wurde
bisher ein wechselndes angehaengt, aber der Client entfernt
Auszeichnungen und schluesselt nur ueber den gesprochenen Text: im Mitschnitt trug
jede einzelne Ausgabe ihre eigene Markierung und der Treffer verstummte trotzdem.
Der urspruengliche Brecher hatte echte Zeichen variiert und funktionierte; der
Wechsel auf eine Markierung sollte die Betonung schonen und hat dabei genau den
Fehler wieder hereingeholt, gegen den er geschrieben war. Angehaengt wird jetzt
wieder echter Text: eine wechselnde Folge von 1 bis 64 geschuetzten Leerzeichen
hinter dem letzten Wort, wo sie weder hoerbar ist noch die Betonung faerben kann.
Satt: nur noch ein Eintrag in der Zauberauswahl
Einfach: Wer eine Aura auf den Satt-Buff bauen wollte, fand in der Zauberauswahl zwei
Eintraege, die beide "Satt" gesprochen wurden. Nur einer davon konnte je ausloesen,
der andere war eine Karteileiche - welchen man erwischte, war reine Glueckssache und
nicht hoerbar. Es gibt jetzt nur noch einen Eintrag, und der ist der richtige. Eine
bereits gespeicherte Aura, die auf den falschen zeigte, wird beim naechsten Anmelden
einmalig umgehaengt und funktioniert danach.
Technisch: Auren werden seit v43.0 ueber die englische Identitaet eines Zaubers
gefuehrt, damit dieselbe Aura in jeder Sprache passt. In der mitgelieferten
Zauberdatenbank tragen zehn Zeilen den englischen Namen jedoch in
ANFUEHRUNGSZEICHEN - 44097 bis 44106 sowie 69559 und 65365 fuehren den Namen
einschliesslich zweier Anfuehrungszeichen, wo die anderen 65 Zeilen ihn ohne
fuehren. Damit entstand eine zweite Identitaet
hinter demselben deutschen Namen, und die Menue-Unterscheidung haengt in so einem
Fall die englische Identitaet an: der eine Eintrag hiess "Satt (Well Fed)", der
andere genauso, nur mit zwei zusaetzlichen Anfuehrungszeichen um Well Fed herum.
Anfuehrungszeichen spricht die Sprachausgabe nicht mit, also klangen beide Eintraege
identisch. "Satt" ist der einzige der 26.650 deutschen Namen im Datenbestand, dessen
zwei Identitaeten sich in nichts als diesen Zeichen unterscheiden. Der Name wird jetzt
beim Bilden der Identitaet entklammert, und zwar auf BEIDEN Seiten - in der
Werteliste und bei jeder Aufloesung eines laufenden Ereignisses -, denn nur eine
Seite zu aendern wuerde einen gespeicherten Wert erzeugen, den kein Ereignis mehr
trifft. Entklammert wird ausschliesslich, was an BEIDEN Enden ein Anfuehrungszeichen
traegt; die 17 uebrigen Zeilen mit Anfuehrungszeichen mitten im Namen (etwa
"Goblinbummkiste" oder das Parfuem "TRIUMPH") behalten sie, weil sie dort zum Namen
gehoeren. Eine einmalige Wanderung haengt gespeicherte Auren um.
Waffenverzauberungen sind in der Zauberauswahl erkennbar
Einfach: Ein Angelkoeder, ein Schaerfstein oder ein Waffenoel sind keine Buffs, sondern
eine Verzauberung auf der Waffe. Sie tauchen in keiner Bufliste des Spiels auf und
loesen kein Aura-Ereignis aus - eine Aura auf "Ereignis = Aura verloren und Zauber
name = Angelfertigkeit +75" konnte deshalb nie ausloesen, obwohl der Eintrag in der
Auswahl steht und voellig normal klingt. Solche Eintraege tragen jetzt in allen
Auswahllisten den Zusatz "(Waffenverzauberung)", damit hoerbar ist, worum es sich
handelt. Wer darauf reagieren will, nimmt entweder das Ereignis
"Waffenverzauberung abgelaufen" oder die Bedingung "Deine Waffenverzauberung
Haupthand". In der Ansage einer ausgeloesten Aura wird der Zusatz nicht mitgelesen.
Technisch: Die Werteliste des Attributs "Zauber name" ist die komplette Zauberdatenbank,
also auch Zeilen, die den Spieler nur als temporaere Waffenverzauberung erreichen -
der Koeder ist Zauber 8084 hinter Verzauberungs-ID 265. Die betroffenen Identitaeten
werden jetzt beim Aufbau der Listen ermittelt (jede Zauber-ID der Identitaet wird von
der Verzauberungsdatenbank referenziert) und bekommen den Zusatz. Bewusst
GEKENNZEICHNET statt entfernt: es sind 395 Identitaeten, und sie sind nicht alle
wirkungslos - "Feurige Waffe", "Scharfrichter" und "Unheilige Staerke" sind Prozeduren
von Verzauberungen, die sehr wohl unter genau diesem Namen im Kampfprotokoll
erscheinen. Sie zu entfernen haette funktionierenden Auren ihre einzige
Benennungsmoeglichkeit genommen. Der Zusatz nutzt denselben Mechanismus wie die
englische Unterscheidung, faellt also in der Sprachausgabe einer ausgeloesten Aura
wieder weg.
Waffenverzauberungen werden angesprochen wie Zauber
Einfach: Fuer einen Schadenszauber ueber Zeit schreibt man "Ereignis gleich aura
verloren" und "Zauber name gleich " - das Ereignis sagt selbst, worum es
geht. Bei einer Waffenverzauberung ging das nicht: den Angelkoeder konnte man nur
ueber "Deine Waffenverzauberung Haupthand" benennen, und das ist eine Zustandsfrage,
keine Ereignisfrage. In der Fassung "enthaelt" konnte so eine Aura sogar NIE
ausloesen - wenn das Ereignis kommt, ist die Verzauberung bereits weg, also enthaelt
die Liste sie nicht mehr. Nur die verdrehte Fassung "enthaelt nicht" funktionierte.
Jetzt traegt das Ereignis den Namen der Verzauberung selbst, und die Aura wird genau
wie bei einem Zauber geschrieben: "Ereignis gleich Waffenverzauberung abgelaufen" und
"Zauber name gleich Angelfertigkeit +75". "enthaelt nicht" funktioniert weiter.
Technisch: Die beiden erzeugten Ereignisse WEAPON_ENCHANT_REMOVED und
WEAPON_ENCHANT_UPDATE legten den Namen der HAND in Feld 13 - und Feld 13 ist das
Zauber-name-Feld. Eine Bedingung auf "Zauber name" verglich also gegen "Haupthand",
und eine Ausgabe "Zauber name" sagte "Haupthand" statt der Verzauberung. Dort steht
jetzt die Verzauberung: Feld 12 bekommt ihre Zauber-ID, Feld 13 ihren Namen, beides
ueber dieselben Resolver, aus denen auch die Auswahlliste gebaut wird - der
gespeicherte Wert ist derselbe wie bei der Waffenverzauberungs-Bedingung. Beim
Entfernen wird die Verzauberung gemeldet, die DA WAR; das ist die Identitaet, die
gemeint ist. Bestehende Auren koennen dadurch nicht verstummen: "Haupthand",
"Nebenhand", "Main Hand" und "Off hand" kommen in allen 49.117 Zeilen der
Zauberdatenbank kein einziges Mal als Zaubername vor, eine Bedingung auf "Zauber
name" konnte bei diesem Ereignis also ohnehin nie zutreffen. Die Hand ist nicht
verloren, sie zieht in ein eigenes Feld mit eigener Bedingung und eigener Ausgabe um
("Waffenverzauberung Hand"), gespeichert als sprachneutrale Kennung, damit eine
geteilte Aura in jeder Sprache dieselbe Hand meint. NICHT gemacht wurde der
naheliegende andere Weg - die Zustandsliste beim Entfernen mit der auslaufenden
Verzauberung zu fuellen: die Liste ist geteilt, sie wuerde in diesem Durchlauf JEDE
andere Aura anluegen, ein "enthaelt nicht"-Gatter wieder scharf schalten und damit
doppelte Ansagen erzeugen, und sie wuerde der Restdauer widersprechen, die beim
Entfernen bewusst auf 0 gesetzt wird. Zusaetzlich meldet /skucheck auras die
Kombination "Entfernt-Ereignis plus enthaelt" jetzt als Aura, die nie ausloesen kann.
Nebenbei behoben: aenderte sich nur die Nebenhand, wurde das Ereignis trotzdem als
"Haupthand" gemeldet.
Das Ende einer Waffenverzauberung wird sofort erkannt
Einfach: Dass ein Angelkoeder oder ein Gift ausgelaufen ist, meldet das Spiel nicht -
Sku sieht alle 0,25 Sekunden nach. Die Ansage kam deshalb bis zu eine viertel
Sekunde zu spaet. Jetzt kommt sie im Moment des Ablaufs.
Technisch: Wie lange eine Verzauberung noch haelt, steht in dem Moment fest, in dem man
sie sieht - GetWeaponEnchantInfo liefert die Restzeit in Millisekunden. Der Ticker
merkt sich daraus den naechsten Ablaufzeitpunkt, und der Frame-Treiber vergleicht
eine Zahl pro Frame und ruft dann genau den normalen Spieler-Ticker auf. Das ist
dieselbe Bauart wie der in v43.0 eingefuehrte Dauer-Terminplaner und kostet kein
zusaetzliches Abfragen. Doppelte Ansagen sind ausgeschlossen, weil der Ticker nur
meldet, wenn sich sein gemerkter Stand wirklich geaendert hat. Bewusst NICHT gemacht:
den Ticker auf jeden Frame zu stellen - das waere fuenfzehnmal so viel Abfragerei
fuer denselben Gewinn.
Umschalten in einer gefilterten Liste sagt wieder den neuen Zustand an
Einfach: Grenzt man eine Liste per Tippfilter ein und drueckt dann Enter auf einem
Ein/Aus-Eintrag, wird der Filter entfernt - das ist so gewollt. Der Eintrag wurde
auch richtig umgeschaltet, nur zu hoeren war das nicht: der Cursor sprang dabei an
den Anfang der Liste, und angesagt wurde der erste Eintrag statt des neuen Zustands.
In den Auren-Ausgaben spielte zusaetzlich die Hoerprobe des ersten Eintrags an.
Jetzt bleibt man auf dem Eintrag stehen, den man umgeschaltet hat, und hoert seinen
neuen Zustand.
Technisch: Enter entfernt den Filter, BEVOR es die Aktion ausfuehrt - der Menue-Knoten
ruft dafuer ApplyFilter("") auf. Dessen Aufraeumen endete mit einem pauschalen
OnFirst() auf der Ebene, der Cursor wanderte also in JEDEM Fall an den Listenanfang.
Die Umschaltung selbst war nie betroffen: sie arbeitet auf dem Knoten selbst
(actionInPlace), nicht auf dem Cursor. Falsch war nur, was danach vorgelesen wurde -
und OnFirst loeste beim Landen zusaetzlich das OnEnter des ersten Eintrags aus, was
bei den Auren-Toenen die Hoerprobe ist. ApplyFilter("") folgt jetzt derselben Regel,
der ClearFilter schon folgt: die wiederhergestellte Liste enthaelt dieselben
Knoten-Objekte, ein Cursor auf einem echten Eintrag bleibt also gueltig; nur die
kuenstliche Zeile "Filter;" hat dort keinen Platz mehr, und allein fuer sie
laeuft weiterhin das vollstaendige OnFirst() samt OnEnter, damit die Hoerprobe beim
Landen nicht verloren geht. Ohne aktiven Filter war ApplyFilter("") immer schon
wirkungslos - deshalb hat das Umschalten in einer ungefilterten Liste nie gefehlt;
beide Faelle verhalten sich jetzt gleich. Nebenwirkung derselben Regel: Backspace
laesst den Cursor jetzt auf dem Eintrag stehen, auf dem er stand, statt an den
Listenanfang zu springen.
Dungeonbrowser: eine angenommene Einladung fuehrt nicht mehr in den Browser
Einfach: Wer im Dungeonbrowser angemeldet war und dann eine Gruppeneinladung annahm,
stand danach ohne einen einzigen Tastendruck im Dungeonbrowser: das Menue ging von
selbst wieder auf, der Cursor stand auf "Nicht angemeldet". Fuer sehende Spieler
passiert an dieser Stelle nichts - Blizzards Gruppensuche-Fenster geht beim Annehmen
einer Einladung nie auf. Jetzt bleibt es auch bei Sku still: man bleibt dort, wo man
vorher war.
Technisch: Zwei Wege fuehrten dorthin, beide sind jetzt zu. (1) Sobald der Server die
eigene Anmeldung loescht - genau das tut er, wenn man einer Gruppe beitritt -, kommt
LFG_LIST_ACTIVE_ENTRY_UPDATE, und der Browser baute daraufhin seinen Menuepunkt neu
auf. Dieser Neuaufbau endete mit einem SlashFunc auf den eigenen Menuepfad, und der
oeffnet ein GESCHLOSSENES Menue wieder und steigt hinein. Er laeuft jetzt nur noch,
wenn das Menue offen ist UND der Cursor tatsaechlich im Dungeonbrowser steht - nur
dann muessen die neu gebauten Eintraege ueberhaupt wieder unter den Cursor gelegt
werden. Faellt er aus, kostet das nichts: der Menuepunkt ist "dynamic" und baut sich
beim naechsten Betreten ohnehin neu auf. Damit kann auch keine Anmeldungsaenderung,
die man nicht selbst ausgeloest hat (Ablauf, Aenderung durch den Gruppenanfuehrer),
einen mehr aus den Taschen in den Browser reissen. (2) Eine drittel Sekunde nachdem
das Einladungsfenster verschwunden ist, prueft der Browser, ob er sich wieder oeffnen
soll. Er fragte dabei nur "ist gerade irgendein Gruppensuche-Fenster offen?" und
machte daraus ein Oeffnen. Jetzt wird beim EINTREFFEN der Einladung gemerkt, was
vorher da war, und nur genau das wird wiederhergestellt. Hat die Einladung in eine
Gruppe gefuehrt, geschieht gar nichts mehr - weder oeffnen noch schliessen.
Neuer Tastenbefehl: den vollstaendigen Tooltip des Ziels vorlesen
Einfach: Bei einem Zielwechsel sagt Sku eine feste, kurze Auswahl an - Name, Stufe,
Elite oder Selten, dazu die zweite Tooltip-Zeile mit der Kreaturenart. Alles, was
darunter im Tooltip steht, war bisher gar nicht erreichbar: die Fraktionszeile, die
PvP-Kennzeichnung und vor allem das, was die Jaegerfaehigkeit Tierkunde bei einem
Wildtier offenlegt - Familie, Nahrung und ob es zaehmbar ist. Der neue Tastenbefehl
(Standard: Strg+Umschalt+V) liest auf Wunsch den kompletten Tooltip vor. Er wirkt
ausschliesslich auf Tastendruck: die normale Zielansage bleibt unveraendert kurz, und
wer die Zusatzinformation nicht braucht, hoert nie etwas davon. Genau deshalb gibt es
dafuer auch keine Option - der Tastendruck selbst ist die Nachfrage. Ist kein hartes
Ziel vorhanden, gilt der Befehl dem aktuellen Soft-Ziel, sodass sich auch etwas
beschreiben laesst, auf das man sich noch gar nicht festgelegt hat. Umzubelegen unter
Sku Tastenbelegung, Ziel und Soft Targeting.
Technisch: Idee, Nachweis und Referenzumsetzung stammen von ZenqFR, aus dem Begleit-Addon
SkuBeastLore (github.com/ZenqFR/Sku-BeastLore); die Tierkunde-Ausgabe ist dort an
einem echten Jaeger getestet worden. Hier ist die Funktion nativ gegen Skus eigene
Schnittstellen neu gebaut, damit kein zusaetzliches Addon noetig ist. Die
Tierkunde-Zeilen erzeugt der Client selbst im Unit-Tooltip; kein Lua der
Blizzard-Oberflaeche baut sie, und keine Programmschnittstelle liefert sie einzeln -
den Tooltip zu lesen ist der einzige Weg dorthin. Deshalb ist eine getrennte Option
nur fuer die Jaegerinformation auch nicht moeglich: die Zeilen liessen sich nur ueber
sprachabhaengigen Textvergleich herausloesen. SkuMob:OutputTargetTooltip loest target,
softenemy, softfriend und softinteract der Reihe nach auf und liest ueber Skus
gemeinsam genutzten SkuScanningTooltip. Weil dieser Frame geteilt ist - Taschen,
Auktionshaus, Chatlinks und Questtexte lesen denselben -, wird davor UND danach
geleert und der Besitzer exakt so wiederhergestellt, wie SkuCore ihn beim Anmelden
setzt.
Quests verfolgen und wieder abwaehlen
Einfach: Im Menue jeder Quest steht jetzt als letzter Eintrag "Quest verfolgen". Enter
schaltet ihn um, der Cursor bleibt stehen, und der neue Zustand wird sofort angesagt
- "Quest verfolgen;Ein" oder "Quest verfolgen;Aus". Verfolgt heisst: WoWs eigene
Markierung auf der Mini- und der Weltkarte. Wer noch etwas sieht, findet Questziele
damit schneller; wer nichts sieht, hat von den Markern nichts. Deshalb laesst sich
der Eintrag komplett abschalten - unter Sku Einstellungen, SkuQuest, "Eintrag Quest
verfolgen anzeigen"; ab Werk ist er an. Er erscheint nur bei Quests im eigenen
Questlog, denn eine Quest aus der Questdatenbank hat man noch gar nicht. Zwei
Grenzen setzt das Spiel selbst: in The Burning Crusade lassen sich hoechstens fuenf
Quests gleichzeitig verfolgen, und eine Quest ganz ohne Ziele gar nicht. In beiden
Faellen sagt Sku die Meldung des Spiels an und der Zustand bleibt, wie er war.
Technisch: Idee und Referenzumsetzung stammen von ZenqFR, aus dem Begleit-Addon
SkuQuestNearby (github.com/ZenqFR/Sku-QuestNearby); hier ist die Funktion mit
ZenqFRs Zustimmung nativ gegen Skus eigene Schnittstellen neu gebaut, damit kein
zusaetzliches Addon noetig ist. Der Eintrag haengt im chunk-lokalen
CreateQuestSubmenu statt an einem Hook auf dem oeffentlichen Wrapper - deshalb
bekommt ihn jede Questansicht: Questlog, Questdatenbank und die Questmenues von
SkuChat. Auf 2.5.6 gibt es kein C_QuestLog: AddQuestWatch, RemoveQuestWatch und
IsQuestWatched nehmen einen Questlog-Index, keine Quest-ID, und dieser Index
verschiebt sich bei jeder angenommenen oder abgegebenen Quest. Sku haelt darum eine
Zuordnung Quest-ID auf Index, prueft den gemerkten Index bei jedem Lesen nach und
verwirft die Zuordnung bei den Questereignissen; ohne diesen Zwischenspeicher liefe
die Liste "Questdatenbank, Alle" einen vollen Questlog-Durchlauf pro Quest.
Eingeschaltet wird ueber AutoQuestWatch_Insert mit QUEST_WATCH_NO_EXPIRE, damit die
Quest in QUEST_WATCH_LIST landet und kein Ablauftimer sie wieder herausnimmt; beim
Abwaehlen wird zuerst der Eintrag aus QUEST_WATCH_LIST entfernt und dann
RemoveQuestWatch gerufen - genau wie in Blizzards eigenem Klickpfad, sonst zaehlt
eine laengst nicht mehr verfolgte Quest weiter gegen das Limit von fuenf.
QuestWatch_Update laeuft nur ausserhalb des Kampfes, weil es am Ende geschuetzte
Frames verschiebt; das naechste QUEST_LOG_UPDATE holt es ohnehin nach.
Neuer Tastenbefehl "Naechstes Questziel ins Ziel nehmen" (Alt+H)
Einfach: Ein Druck nimmt eine Kreatur ins Ziel, die zu einem noch offenen Questziel
gehoert - und zwar auch dann, wenn man sie gar nicht toeten muss, sondern sie nur
einen benoetigten Gegenstand fallen laesst. Beispiel: fuer "Essenzen fuer die
Motoren" nennt das Questlog nur den Gegenstand; die Taste nimmt trotzdem das
Managespenst ins Ziel, das ihn fallen laesst. Passt nichts in Reichweite, sagt Sku
"kein Questziel in Reichweite"; ist im Questlog ueberhaupt nichts Passendes,
"kein Questziel im Questlog". Die Taste liegt ab Werk auf Alt+H und laesst sich
unter Sku Tastenbelegung, "Ziel und Soft Targeting" umlegen.
Technisch: Idee und Referenzumsetzung stammen von ZenqFR, aus dem Begleit-Addon
SkuQuestTarget (github.com/ZenqFR/Sku-QuestTarget); hier ist die Funktion mit
ZenqFRs Zustimmung nativ neu gebaut, damit kein zusaetzliches Addon noetig ist.
Die Kandidaten kommen aus dem eigenen Questlog ueber SkuQuest:GetQuestTargetIds;
Gegenstandsziele werden ueber die Fallquelle (npcDrops, eine Ebene tief auch
itemDrops) auf die Kreaturen zurueckgefuehrt, die sie fallen lassen. Gesucht wird
zuerst in der Zone, in der man selbst steht - wer dort keinen Spawnpunkt hat, kann
gar nicht in Zielreichweite sein und darf keinen Platz im Makro belegen; erst wenn
in der eigenen Zone nichts hinterlegt ist, wird ueber den ganzen Kontinent
sortiert. Die Entfernung nimmt den naechstgelegenen aufgezeichneten Spawnpunkt,
nicht den ersten der Liste. Das Makro ist mehrzeilig, und dabei entscheidet eine
Eigenheit des Spiels: jede passende Zeile feuert, und jeder Treffer ueberschreibt
den vorherigen - es gewinnt also die LETZTE. Aufgenommen wird deshalb von nah nach
fern, damit das Laengenbudget nur Weitentferntes kappt, ausgegeben aber umgekehrt,
damit der naechstgelegene Kandidat die letzte Zeile ist. Gebaut wird ausserhalb des
Kampfes bei jedem Tastendruck; im Kampf feuert der zuletzt gebaute Text.
"Naechster Gegner im Kampf" findet auch, was man nicht anschaut (Strg+H)
Einfach: Die Taste konnte bisher nur finden, was man ohnehin anschaut - stand derselbe
Gegner fuenf Meter hinter einem, meldete sie nichts. Das ist keine Einstellung,
sondern das Verhalten der Tabulator-Zielsuche des Spiels. Sku merkt sich deshalb
jetzt die Namen feindlicher Kreaturen, an denen man vorbeikommt, und probiert sie
zusaetzlich ueber den Namen - und ein Name funktioniert in jede Richtung. In der
Praxis heisst das: was man einmal gesehen, angegriffen oder ins Ziel genommen hat,
bleibt zwei Minuten lang von ueberall aus erreichbar, auch weggedreht. Ausserdem
beginnt die Suche jetzt bei jedem Druck beim naechstgelegenen Gegner, statt im
Kreis weiterzuspringen. Die Taste liegt ab Werk auf Strg+H.
Technisch: Die Anregung stammt aus ZenqFRs SkuQuestTarget, das denselben Weg fuer seine
Nebenfunktion benutzt. /targetenemy ist Tabulator und sucht im Sichtkegel - daran
ist nichts zu aendern. "/tar Name" dagegen sucht ueber die Namensliste des Clients
und ist richtungsunabhaengig, braucht aber einen Namen, und es gibt keine
Schnittstelle, die Einheiten hinter einem aufzaehlt. Sku sammelt die Namen deshalb
laufend aus vier Quellen: feindliche Namensplaketten, das eigene Ziel, die Einheit
unter dem Mauszeiger und die Gegnerliste der Kampfueberwachung. Das Einsammeln
laeuft im Sekundentakt, solange die Taste belegt ist, denn eine Plakette gibt es
nur, solange die Kreatur im Blick ist - genau dann braucht man die Taste aber
nicht. Dort werden nur Namen gesammelt; die teure Entfernungsmessung laeuft einmal
pro Tastendruck. Gemerkte Namen halten zwei Minuten. Das Makro ist "/cleartarget",
dann "/targetenemy", dann die gemerkten Namen von fern nach nah - die letzte
passende Zeile gewinnt, also der naechstgelegene.
Neue Liste "Quests in der Naehe"
Einfach: Im Questmenue steht als dritter Eintrag, nach "Aktuelle Quests" und
"Questdatenbank", jetzt "Quests in der Naehe". Darin liegt das ganze Questlog in
EINER Liste - angefangene und fertige gemischt -, sortiert danach, wie weit das
weg ist, worum es bei der jeweiligen Quest gerade geht. Jeder Eintrag nennt zuerst
die Entfernung, dann die Himmelsrichtung, dann die Art und dann den Questnamen,
also etwa "180 Meter; nordost; Questziel; Diebische Kobolde" oder "340 Meter;
sued; Questabgabe; Der Wolfsrudelfuehrer".
Bei einer Quest, die noch offene Ziele hat, ist das die Entfernung zum naechsten
Ziel; bei einer fertig gemeldeten Quest die Entfernung zur Abgabestelle. "Aktuelle
Quests" gruppiert nach den Ueberschriften des Questlogs, sortiert also nach Zone -
die neue Liste beantwortet dagegen die Frage "was ist von hier aus das Naechste".
Enter oeffnet dasselbe Questmenue wie ueberall sonst, samt Wegpunkten und dem
Eintrag "Quest verfolgen". Die Liste ist ab Werk AUS und wird unter Sku
Einstellungen, SkuQuest, "Eintrag Quests in der Naehe anzeigen" eingeschaltet: sie
rechnet bei jedem Oeffnen das ganze Questlog gegen Skus Spawn-Datenbank durch, und
das soll nur zahlen, wer sie auch benutzt. Wo Skus Daten keinen Ort hergeben,
steht statt der Entfernung "Ort unbekannt", und die Quest rutscht ans Ende - sie
verschwindet nicht.
Technisch: Idee und Referenzumsetzung stammen von ZenqFR, aus dem Begleit-Addon
SkuQuestNearby (github.com/ZenqFR/Sku-QuestNearby); hier ist die Funktion mit
ZenqFRs Zustimmung nativ neu gebaut, damit kein zusaetzliches Addon noetig ist -
insbesondere ohne Questie und ohne GatherMate2. Die Rechnung liegt in der neuen
Datei SkuQuest/Proximity.lua und ist zustandslos. Zwei Stufen, und die Reihenfolge
ist der Punkt: zuerst der naechstgelegene aufgezeichnete Spawnpunkt IN DER Zone,
in der man selbst steht - die Auswahl laeuft billig in Kartenkoordinaten, nur der
Gewinner wird einmal in Weltkoordinaten umgerechnet; erst wenn das nichts hergibt,
das Minimum ueber alle Zonen desselben Kontinents. Ein anderer Kontinent ist keine
ungenaue Entfernung, sondern gar keine, und bleibt draussen. Gegenstandsziele
werden ueber die Fallquelle auf Kreaturen und Weltobjekte zurueckgefuehrt,
Erkundungsziele ueber die hinterlegten Koordinaten. Anders als beim Wegpunkt-Pfad
werden ALLE Ziellisten einer Quest gelesen, nicht nur die erste nichtleere - eine
Quest mit "toete acht Woelfe UND sammle fuenf Felle" haette sonst nur die Woelfe.
Gefiltert wird nur nach ZIELART: welche Arten noch offen sind, sagt Blizzards
eigene Fortschrittsanzeige ("monster", "item", "object"), und die passt eins zu
eins auf die drei Listen; ein Abgleich Zeile gegen einzelnen Datenbankeintrag
waere dagegen geraten, weil beide Reihenfolgen nirgends aneinander gebunden sind.
Pro Quest und Art werden hoechstens zwoelf IDs durchgerechnet - die Grenze ist das
Skript-Budget der Hardcore-Realms, nicht die letzte Nachkommastelle. Die
Himmelsrichtung kommt aus denselben Weltkoordinaten, ueber dieselbe Funktion, die
auch die Wegpunktlisten und der Minimap-Scanner benutzen. Bewusst die
Himmelsrichtung und nicht eine Uhrzeit: eine Uhrzeit gilt relativ zur
Blickrichtung und waere falsch, sobald man sich dreht - die Liste wird aber einmal
gebaut und dann durchgelesen.
Questdatenbank: "Start in Zone" ohne Zwischenebene
Einfach: Unter "Questdatenbank, Start in Zone" lag bisher noch genau ein Eintrag,
"Nach Entfernung", und darin erst die Quests. Eine Ebene, in der es nichts zu
waehlen gibt, ist nur ein Tastendruck. Die Liste steht jetzt direkt unter "Start in
Zone". Ausserdem war diese Liste kaputt: sie brach nach der ersten Quest ab, man
bekam also genau einen Eintrag statt aller Quests der Zone.
Technisch: Die Zwischenebene stammte daher, dass daneben einmal eine zweite Sortierung
("Nach Schwierigkeit") stehen sollte; deren Baustelle stand seit Jahren
auskommentiert daneben und wurde nie gebaut. Der Abbruch kam von einer Zeile
"tcount = tcount + 1" im Aufbau der Liste: tcount war dort keine lokale Variable,
sondern eine nie gesetzte globale, das Hochzaehlen also ein Fehler auf nil. Ein
Fehler im Kindaufbau eines Menues wird verschluckt - der Aufbau endete damit
stillschweigend nach dem ersten Eintrag. Der Zaehler wurde von nichts gelesen und
ist ersatzlos entfernt.
Alles in der Bank in einer Liste, und die Bank wird auch unter Bagnon erkannt
Einfach: Im Taschenmenue gab es "alle taschen" - eine flache Liste ueber alle Taschen
hinweg, nach Namen sortiert. Fuer die Bank gab es das nicht: an der offenen Bank
standen zwar "Bank" und "Bank Tasche 1" bis "Bank Tasche 7" im Menue, aber wer
etwas suchte, musste jedes Fach einzeln durchgehen. Jetzt steht direkt hinter
"alle taschen" der Eintrag "alle bank", solange die Bank offen ist: alles, was in
der Bank liegt, in einer Liste, mit demselben Tippfilter. Strg+Eingabe holt einen
Gegenstand von dort in die Taschen - genau wie bisher schon in den einzelnen
Bankfaechern. Ausserdem erkennt Sku jetzt an den Meldungen des Spiels selbst, ob
die Bank offen ist, und nicht mehr am Fenster von Blizzard. Wer ein
Taschen-Ersatz-Addon wie Bagnon benutzt, das dieses Fenster versteckt, hatte
bisher gar keine Bank im Menue - Sku hielt sie fuer geschlossen und liess saemtliche
Bankfaecher verschwinden. Dafuer ist jetzt kein Bruecken-Addon mehr noetig.
Technisch: Die Anregung stammt aus ZenqFRs Begleit-Addon SkuBagnonBridge
(github.com/ZenqFR/Sku-BagnonBridge), das dieselbe Luecke auf seine Weise schliesst
und die Bank ebenfalls ueber die Ereignisse des Spiels erkennt; hier ist mit
ZenqFRs Zustimmung der Teil nativ gebaut, der ohne ein weiteres Addon auskommt. Die
flache Liste war auf die Taschen 0 bis 4 begrenzt; die Bankbehaelter (-1, -3, 5 bis
11) wurden nie in sie kopiert. Sie sammeln sich jetzt in einer eigenen Liste,
absichtlich getrennt von der Taschenliste: aus dieser leitet sich
SkuCore.combatBagOrder ab, die Spiegelung fuer den Kampf, und die kann von Haus aus
nur Taschenfaecher benutzen. Die Eintraege der neuen Liste sind Kopien derselben
Fach-Eintraege und tragen Tasche und Fach mit, also greifen alle vorhandenen
Aktionen unveraendert. Der Zustand der Bank haengt jetzt an BANKFRAME_OPENED und
BANKFRAME_CLOSED: beide kommen aus der Interaktion mit dem Bankier selbst und sind
unabhaengig davon, wer das Fenster zeichnet. Beim Laden und nach /reload wird der
Zustand zurueckgesetzt, und die alte Fensterpruefung bleibt zusaetzlich erhalten -
die Erkennung kann dadurch nur mehr Faelle richtig treffen als vorher, keine
weniger.
Loeschen eines eigenen Wegpunkts raeumte den falschen Eintrag ab
Einfach: Beim Loeschen eines selbst angelegten Wegpunkts wurde intern nicht dessen eigene
Kennung aus einer Nachschlagetabelle entfernt, sondern die eines anderen Wegpunkts.
Ausserdem meldete "/skucheck wp" vier Fehler bei den vier Schnellwegpunkten, obwohl
mit ihnen alles in Ordnung war.
Technisch: Die wpId ist die Identitaet eines Wegpunkts - die Verbindungstabelle ist
ueber sie verschluesselt -, keine Beschreibung seines Ortes. Die in ihr steckende
Gebiets-ID stammt aus dem Moment des Cache-Aufbaus und bleibt stehen, wenn ein
eigener Wegpunkt umzieht; genau das passiert den vier Schnellwegpunkten bei jedem
Ladebildschirm, denn dabei werden sie auf die Spielerposition neu gesetzt. Die
Pruefung baute die Kennung aus dem aktuellen areaId des Datensatzes neu auf und
verglich - sie rechnet jetzt mit der in der Kennung selbst steckenden Gebiets-ID.
Der Loeschpfad baute die Kennung ueber ".areaid" (das Feld heisst areaId), also mit
Gebiet 1 statt des echten, und raeumte damit den Eintrag desjenigen Datensatzes ab,
dem dieser Schluessel wirklich gehoert; er benutzt jetzt die gespeicherte Kennung.
Die Chateingabe ist bedienbar geworden
Einfach: Die Chatzeile war das einzige Eingabefeld in Sku, in das man blind tippte. Es gab
einen Ton beim Oeffnen und einen beim Schliessen, sonst nichts - kein Zeichen-Echo,
kein Vorlesen unter dem Cursor, und keine Auskunft darueber, wohin die Nachricht
eigentlich ginge. Jetzt verhaelt sie sich wie jedes andere Sku-Eingabefeld. Jedes
getippte und geloeschte Zeichen wird gesprochen, Pfeil links und rechts lesen das
Zeichen unter dem Cursor und mit Strg das ganze Wort, Pfeil hoch holt die zuletzt
gesendeten Nachrichten zurueck - zum erneuten Absenden oder zum Aendern - und sagt
dabei den Kanal mit, denn den sieht man einer zurueckgeholten Zeile nicht an.
Angesagt wird der Kanal ausserdem beim Oeffnen und bei jedem Wechsel, aber bewusst
nicht bei "Sagen": das ist der harmlose Fall, und ihn jedes Mal vorzusagen waere nur
Geraeusch. Wem die Kanalansage im eigenen Ablauf nicht passt, schaltet sie in den
Chat-Einstellungen unter "Kanal der Chateingabe ansagen" ab, ab Werk ist sie an;
das nimmt dann auch den Kanal vor der mit Pfeil hoch zurueckgeholten Zeile weg.
Ein Gegenstand im Chat zaehlt beim Lesen als ein einziges Zeichen statt
als fuenfundsechzig Zeichen Steuerkram. Und ein vertippter Befehl wie "/tets" sagt
jetzt "Unbekannter Befehl", statt einfach nichts zu tun.
Technisch: Das Tastatur-Echo der Sku-eigenen Felder haengt ueber
SkuOptions:AttachInputEcho jetzt auch an fremden. Drei Dinge sind dort anders:
angehaengt wird mit HookScript statt SetScript, weil auf Blizzards Feld dessen eigene
Handler fuer Verlauf und Namensvervollstaendigung liegen; die Vorlage traegt
ignoreArrows, weshalb schlichte Pfeile an das Spiel gingen und der Textcursor ALT
brauchte - das wird zurueckgedreht; und scharf geschaltet wird am Fokus, weil ein
fremdes Feld kein Oeffnen-und-Schliessen-Paar hat, an dem das Echo haengen koennte.
Der Kanal wird aus der Kopfzeile der Eingabe gelesen statt aus chatType nachgebaut -
die Kopfzeile ist bereits uebersetzt und deckt Fluesterziele, nummerierte Kanaele und
Blizzards eigene Umschaltungen mitten im Aufruf ab. Ihre Ansage laeuft verzoegert und
in einem einzigen Slot, denn jeder Kanalwechsel wird durch einen Tastendruck
ausgeloest, und dessen Zeichen-Echo hatte die Ansage sonst jedes Mal aus der
Warteschlange geworfen, bevor sie ueberhaupt gesprochen war.
Gegenstandslinks werden als Name gelesen, nicht als Farbcode
Einfach: Ein Gegenstand - im Chat, in der Post, in der Beute - wurde als lange Folge aus
Farbcodes, Kennungen und Doppelpunkten vorgelesen statt schlicht als sein Name.
Technisch: In der Sprachausgabe wurden erst alle senkrechten Striche durch Leerzeichen
ersetzt und DANACH die Funktion gerufen, die Farbcodes, Links und Texturen entfernt.
Deren Muster suchen alle nach einem senkrechten Strich, den es zu dem Zeitpunkt nicht
mehr gab - sie liefen also seit jeher ins Leere. Reihenfolge getauscht; der pauschale
Ersatz ist jetzt nur noch ein Auffangnetz dahinter.
Questdatenbank: "Start in Zone" nennt auch die Himmelsrichtung
Einfach: Die Liste der Quests, die in dieser Zone beginnen, sagte bisher nur, wie weit
der Questgeber entfernt ist. Jetzt sagt sie wie die Liste "Quests in der Naehe" auch,
in welcher Richtung er liegt - erst die Entfernung, dann die Himmelsrichtung.
Technisch: Die Weltkoordinaten des Questgebers lagen in dieser Liste ohnehin schon vor;
die Richtung kommt aus derselben Funktion, die auch die Wegpunktlisten benutzen.
Bewusst die Himmelsrichtung und nicht die Uhrzeit: eine Uhrzeit gilt relativ zur
Blickrichtung und waere falsch, sobald man sich dreht, waehrend diese Liste einmal
gebaut und dann durchgelesen wird. Die Quest-ID eines Eintrags kommt jetzt direkt aus
der Zeile statt aus einer Nachschlagetabelle, deren Schluessel der alte
Beschriftungstext ohne Richtung war.
-------------------------------------------------------------------------------------------------------
Tastatur-Echo: Zeichen kommen sofort
Einfach: Beim Tippen in ein Eingabefeld kamen die Buchstaben nicht im Takt der Finger:
manche wurden verschluckt, andere kamen deutlich zu spaet, und Doppelbuchstaben wie
in "Wasser" oder "alle" waren regelmaessig nur einmal zu hoeren. Jetzt kommt jedes
getippte Zeichen sofort, und ein zweimal gedrueckter Buchstabe wird auch zweimal
gesprochen.
Technisch: Das Echo lief bisher durch dieselbe Warteschlange wie jede Menueansage, und
die ist fuer Ansagen gebaut, nicht fuer Tastendruecke. Sie sammelte Zeichen eine
Zehntelsekunde lang und sprach sie ueberschreibend - und Ueberschreiben heisst hier:
erst StopSpeakingText, dann noch einmal eine Zehntelsekunde warten, damit dieser Stop
nicht ausgerechnet die Ansage abraeumt, fuer die er Platz machen soll. Beides
nacheinander sind rund 0.2 Sekunden je Anschlag, und der Stop des einen Anschlags
landete regelmaessig auf dem naechsten. Dazu kam die in dieser Version neu
eingefuehrte Dublettensperre der Sprachausgabe, fuer die ein einzelnes Zeichen als
Aeusserung mit sich selbst identisch ist - daher die verschluckten Doppelbuchstaben.
Getippte Zeichen laufen jetzt ueber eine eigene Schnellspur: ein einziger Platz, in
dem der neueste Anschlag gewinnt, Ausgabe im selben Frame, der Stop nur noch einmal
zu Beginn einer Tippfolge statt bei jedem Anschlag, und die Dublettensperre sieht
getippte Zeichen gar nicht mehr. Hintergrund: ein Bildschirmleser braucht so etwas
nie, weil seine Schnittstelle das Abbrechen als Teil des Sprechbefehls anbietet -
eine einzige Operation. Die Schnittstelle des Spiels kann das nicht, also muss Sku
sie aus zwei Aufrufen nachbauen, die einander ueberholen koennen. Neu ist, das nur
noch einmal je Tippfolge zu tun.
Eine per Taste erneut angeforderte Zeile wird wieder gesprochen
Einfach: Wer eine Menuezeile per Tastendruck noch einmal hoeren wollte, bekam
gelegentlich Stille - die Sprachausgabe hielt die Wiederholung fuer ueberfluessig.
Technisch: Die Dublettensperre verwirft eine Zeile, die innerhalb einer Sekunde genauso
schon einmal gesprochen wurde. Das ist richtig fuer den ueberfluessigen Nachschlag
eines Menue-Neuaufbaus und falsch fuer denselben Text, den der Nutzer gerade per
Taste angefordert hat. Am Text sind die beiden nicht zu unterscheiden, und keine
Zeitspanne trennt sie - nur der Ausloeser. Die Tastenauswertung des Menues markiert
ihre Ansage deshalb jetzt als tastenausgeloest, und die Sperre laesst markierte
Zeilen immer durch. Ueberfluessige Wiederholungen werden weiterhin verworfen, jetzt
unabhaengig davon, wie schnell sie eintreffen.
Quests mit gemischten Zielen zeigen alle Zielarten
Einfach: Bei einer Quest wie "toete 8 Woelfe UND sammle 5 Felle" zeigte der Eintrag
"Ziel" im Questmenue nur die erste Zielart - meist die Gegner; die Fundorte des
Sammelgegenstands oder ein Erkundungspunkt fehlten still. Betroffen waren 95
Quests. Jetzt stehen alle Zielarten nebeneinander in einer Liste, und auch der
Tastenbefehl "Naechstes Questziel ins Ziel nehmen" kennt bei solchen Quests
beide Haelften. Nebenbei behoben: eine Quest, die nur einen Erkundungspunkt und
sonst keine Zieldaten hat, bekommt ueberhaupt erst einen "Ziel"-Eintrag, und ein
nicht aufloesbarer Erkundungspunkt erzeugt keinen Eintrag mehr, der nur noch
"leer" ansagt.
Technisch: SkuQuest:GetQuestTargetIds war eine elseif-Kette ueber die Ziellisten der
Questdatenbank (Kreaturen, sonst Objekte, sonst Gegenstaende, ...) und konnte
schon per Signatur nur EINE Liste mit EINEM Typ zurueckgeben. Ersetzt durch
GetQuestTargetGroups: ein Feld von Gruppen {targets, type} - Kreaturen samt
deduplizierten Toetungs-Credits, Objekte, Gegenstaende und, nur fuer die
objectives-Aufrufer, der triggerEnd-Punkt der Quest. Alle sieben Aufrufer sind
umgestellt (Questmenue, Wegpunkt-Cache, Questmarker, Questziel-Taste); der alte
Name bleibt als Erste-Gruppe-Wrapper fuer den WowVision-Port stehen. Dazu ist
der item-Zweig von GetResultingWps gegen unbekannte Gegenstands-IDs abgesichert:
der indizierte bisher ungeprueft und liess den verschluckten Menueaufbau als
stilles "Liste leer" sterben.
Questdatenbank auf den aktuellen Questie-Stand gebracht
Einfach: Skus eingebaute Questdatenbank stammt von Questie und war rund zwei Jahre
alt. Nach dem Abgleich haben 33 Quests, deren "Ziel" bisher leer blieb, echte
Ziele (die Dunkelmond-Kartensets, die wiederholbaren Ogri'la- und
Violettes-Auge-Quests, "Den Schluesselmeister finden"), die sechs "Untersucht
die Geissel"-Quests haben jetzt Erkundungspunkte, fuenf fehlende Quests sind
ergaenzt, und rund 2000 Datensaetze tragen kleinere Korrekturen an Namen,
Stufen, Questgebern und Vorquest-Ketten. Geprueft: die Korrekturen sind fuer
Era und TBC identisch, die Aktualisierung ist auf beiden sicher.
Technisch: Semantischer Abgleich statt Byte-Kopie (neues Werkzeug
dev/rework-docs/_refresh_questdata_from_questie.py, danach _db_convert.py):
Questies Schema divergiert ab Feld 27, uebernommen werden nur die Felder 1-26;
Skus eigene Felder extraObjectives und skuData bleiben je Datensatz erhalten.
Die requiredRaces-Konvention (alte Alle-Rassen-Maske 2047, neu 0 - fuer Skus
Logik dasselbe) gilt beim Vergleich als gleich, sonst haetten 2117 Datensaetze
ohne inhaltliche Aenderung im Diff gestanden. Jede referenzierte Kreatur-,
Objekt- und Gegenstands-ID wurde gegen die mitgelieferten Datenbanken (Basis +
WotLK) validiert; ein Datensatz blieb deshalb beim alten Stand.
Ereignisquests tauchen direkt nach dem Laden nicht mehr auf
Einfach: In den ersten Sekunden nach einem /reload konnten in "Start in Zone"
Quests inaktiver Weltereignisse auftauchen - etwa Sonnenwendquests im August.
Sobald Questie fertig geladen war, verschwanden sie von selbst wieder; jetzt
sind sie auch in diesem Zeitfenster ausgeblendet.
Technisch: Die beiden Verfuegbarkeits-Tore fragten Questie erst ab Questie.started,
und das Flag kippt ganz am Ende von Questies Initialisierung. Questies statische
Ausschlussliste QuestieCorrections.hiddenQuests - entfernte Quests plus ALLE
Ereignisquests; die aktiven werden erst nach der Kalender-Antwort des Servers
freigeschaltet - existiert aber viel frueher. IsQuestieUnavailable liest sie
vor started jetzt direkt: das ist ein reiner Tabellenzugriff, die
Memoize-Vergiftungsgefahr hinter dem started-Tor betrifft nur IsDoable. Der
Wert "HIDE_ON_MAP" wird wie bei Questie selbst uebersprungen, und jede
Vor-Start-Ausblendung schreibt eine dprint-Zeile ins Log.
Quests in Dungeons fuehren zum Eingang statt ins Leere
Einfach: Bei rund 300 Quests liegt der Questgeber, das Ziel oder die Abgabe in
einem Dungeon - "Rache fuer Vorrel" beginnt im Scharlachroten Kloster, "Willix
der Importeur" endet im Kral von Rasierklingenfarn. Annahme, Ziel und Abgabe
waren dort bisher leer, weil es in Instanzen keine Weltkarte gibt. Jetzt steht
dort stattdessen der Eintrag "NPC, Eingang, Dungeonname, Zone" mit Route zum
Dungeoneingang - auch bei Schlachtfeldquests (Alteractal je Fraktion am
richtigen Eingang). Fundquellen eines GEGENSTANDS im selben Dungeon werden
dabei zu einem einzigen Eintrag "Dungeonname, Eingang, Zone" zusammengefasst -
"Ramaladnis Schicksal" nannte sonst 29 Naxxramas-Trashmobs einzeln, die alle
zum selben Tor fuehren; Toetungsziele behalten ihre einzelnen Mobnamen.
Technisch: Neue generierte Tabelle SkuDB.InstanceEntrances (aus Questies
Dungeon-Tabelle, Werkzeug dev/rework-docs/_gen_instance_entrances.py):
Instanz-AreaId -> Eingaenge {Elternzone, x, y, ggf. Fraktion}, inklusive der
Nebenfluegel-IDs und einem GetBuildInfo-Tor fuer die WotLK-Verschiebungen.
Die Spawn-Aufloeser (CreatureIdHelper, Objekt- und Gegenstands-Zweig von
GetResultingWps) ueberspringen kartenlose Gebiete nicht mehr, sondern
beantworten sie wie der triggerEnd-Umweg von v43.2: Eingangskoordinaten in
Weltkoordinaten wandeln, naechsten Routen-Wegpunkt nehmen. Memoisiert je
Wegpunktcache-Generation; der Fraktionsfilter liest UnitFactionGroup.
77 Feldziel-Quests haben jetzt ein echtes Questziel
Einfach: Fuer 77 Quests, deren Ziel ein Ort oder Gegenstand im Feld ist (die
Wasserbrunnen von Mulgore, der Mondfederstein der Druiden, die Kristallpylonen
im Krater von Un'Goro, Rolfs Leichnam, die vier Draenei-Totems, die
Tierzaehmungs-Questreihe der Jaeger und viele mehr), gab es bisher keinerlei
Zieldaten - der Eintrag "Ziel" fehlte einfach. Jetzt haben alle ein echtes,
routbares Questziel. Wichtig: Die Objekte und Kreaturen kommen aus Skus
eigenen Spawndaten, aber 26 Ortsangaben stammen aus Webquellen
(warcraft.wiki.gg, Wowhead) und konnten nicht alle im Spiel geprueft werden.
Sie sind mit Bedacht gewaehlt, koennen aber im Einzelfall danebenliegen -
eine Rueckmeldung, ob so ein Ziel stimmt oder nicht, hilft sehr. Auch ein
ungenauer Punkt ist besser als gar keiner: die Route fuehrt in die richtige
Gegend.
Technisch: Ergebnis der Pruefliste dev/rework-docs/QUEST-TARGET-PROPOSALS.txt
(Abschnitte 1-3, von Hand geprueft): 27 Objekt- und 24 Kreaturenziele als
objectives-Eintraege in quests_fixes.lua (IDs gegen die eigenen Datenbanken
validiert, Spawnzonen verifiziert, keine -1,-1-Positionen im Freiland) plus
26 triggerEnd-Koordinaten aus der Webrecherche. Zwei Quests (9410, 10166)
trugen die richtige Objekt-ID schon in extraObjectives, das die Zielmenues
nicht lesen - dort ist das objectives-Feld ergaenzt.
Dreizehn Sprich-mit-Quests haben wieder eine Abgabe
Einfach: Dreizehn Quests - vor allem die alten Priester-Zauberquests (Sterne
Elunes, Elunes Anmut, Furchtlosigkeit, Schwaechungsfluch), dazu unter anderem
"Der Foliant des Adels" und "Verbuendeter des Netherschwingenclans" - standen
ohne Abgabepunkt in den Daten: weder Ziel noch Abgabe, nichts war routbar.
Jetzt fuehrt die Abgabe zu dem NPC, den der Questtext selbst nennt.
Technisch: finishedBy-Eintraege in quests_fixes.lua; die Kreatur-IDs sind aus dem
Questtext gegen die Kreaturdatenbank aufgeloest (jeder Name ist dort eindeutig,
die Spawns liegen in der im Text genannten Zone). Die Kandidaten stammen aus
dem neuen Werkzeug dev/rework-docs/_quest_target_candidates.py, das alle
zielllosen Quests klassifiziert und fuer die restlichen (echte Feldziele ohne
Koordinatenquelle) die Pruefliste QUEST-TARGET-CANDIDATES.txt schreibt.
Experimentell: Sammelrouten
Einfach: Du waehlst eine Ressource - ein Erz, ein Kraut, eine Gaswolke oder eine
Truhensorte - und Sku fuehrt dich durch die Zone, Vorkommen fuer Vorkommen,
immer das naechstgelegene zuerst. Wo Wegedaten vorliegen, geht es ueber eine
echte Route; ist keine da, gibt es einen direkten Peilton, und Sku sagt das
dazu - ein Peilton kann durch eine Wand zeigen, eine Route nicht. Im Flug wird
nie geroutet: dort ist die Gerade der richtige Weg, nicht der Notbehelf.
Am Vorkommen wartet Sku kurz, waehrend du abbaust, und geht dann weiter. Der
Tastenbefehl "naechster Routenwegpunkt" (ab Werk Strg+Umschalt+W) ueberspringt
waehrend einer Sammelroute das aktuelle Vorkommen - es braucht also keine
neue Taste.
Ist die passende Suche aktiv (Mineralien finden, Kraeuter finden), prueft der
Minikartenscanner beim Herangehen, ob das Vorkommen ueberhaupt noch da ist,
und ueberspringt abgebaute mit einer eigenen Ansage. Ohne Suche laeuft die
Route trotzdem, nur eben ohne diese Pruefung.
Zu finden unter Einstellungen -> Scan -> ressourcen scan -> Sammelrouten; dort
liegen auch Pruefradius, Anzahl der Vorkommen je Route und der Schalter fuer
die Pruefung. Fuer Erze, Kraeuter und Truhen muss "Wegpunkte fuer Kraeuter und
Bergbau anzeigen" in den Navigationseinstellungen an sein - sonst liegen diese
Vorkommen gar nicht als Wegpunkte vor, und Sku sagt beim Start genau das,
statt die Zone faelschlich fuer leer zu erklaeren. Gaswolken brauchen die
Einstellung nicht.
Wichtig: Diese Funktion ist ausdruecklich experimentell. Sie ist im Spiel erst in
Ansaetzen erprobt, und die Pruefung "ist das Vorkommen ueberhaupt noch da"
konnte gar nicht unter echten Bedingungen laufen, weil hier kein Charakter
einen Sammelberuf hat - ohne Mineralien finden oder Kraeuter finden gibt es
keine Punkte auf der Minikarte, die der Scanner lesen koennte. Wer Bergbau
oder Kraeuterkunde spielt: bitte ausprobieren und berichten, was schiefgeht.
Technisch: Idee und Referenzumsetzung stammen von ZenqFR, aus dem Begleit-Addon
SkuGatherRoute (github.com/ZenqFR/Sku-GatherRoute); die Routenmechanik ist
dort erdacht und vorgefuehrt worden - eine Wegpunktfamilie unter einem
gemeinsamen Basisnamen, jedes Vorkommen ueber eine nahe Route, eine eigene
Ansage fuer jeden Uebergang, und der vorhandene Tastenbefehl als Ueberspringer.
Hier ist die Funktion mit ZenqFRs Zustimmung nativ neu gebaut, damit kein
zusaetzliches Addon noetig ist.
Ein Unterschied ist bewusst: das Original setzt GatherMate2 voraus, diese
Fassung nicht. Wir sehen darin keinen Vorteil - die Vorkommen stehen samt
Weltkoordinaten laengst in SkuNavs Wegpunkt-Cache, und zwar so benannt, dass
die Ressource der Basisname des Wegpunkts ist; eine zweite Datenquelle und ein
zweites Addon wuerden dem nichts hinzufuegen, kosteten aber jeden Nutzer eine
weitere Installation. Sollte GatherMate2 etwas leisten, das wir uebersehen
haben - das Selbstaufzeichnen tatsaechlich abgebauter Knoten waere der
Kandidat -, dann sagt uns bitte wofuer, und wir sehen es uns an.
Die Praesenzpruefung haengt sich in MinimapScanner:MinimapScanFastStop, den
Punkt, durch den jeder Scan laeuft. Ist "bei Ressourcen benachrichtigen" an,
reicht der ohnehin laufende Scan; sonst scannt die Route selbst, gedrosselt
und nur in Reichweite des Ziels, und diese Scans bleiben stumm. Ein Treffer
bestaetigt, ein Fehlschlag beweist nichts - ein Scan meldet immer nur einen
Namen und kann einen anderen Punkt erwischt haben. Erst nach mehreren
erfolglosen Scans in Reichweite gilt ein Vorkommen als weg. Im Zweifel wird
nie uebersprungen: ein zu Unrecht behaltenes Vorkommen kostet ein paar
Schritte, ein zu Unrecht uebersprungenes faellt gar nicht auf.
Das Menue bleibt beim Gehen bedienbar
Einfach: Oeffnete man das Menue waehrend man lief, stand es zwar da und sagte
"Menue geoeffnet", aber keine Taste tat noch etwas - keine Pfeiltaste, kein
Buchstabe, kein Eingabe. Nur Escape kam durch. Bedienbar wurde es erst, wenn
man stehen blieb. Das ist behoben: ein offenes Menue nimmt Tasten jetzt
entgegen, egal ob man geht, laeuft oder autolaeuft.
Technisch: Es gab zwei Bewegungssperren, nicht eine. Die erste verhindert das
OEFFNEN, waehrend eine Bewegungstaste gedrueckt gehalten wird - die bleibt,
sie ist noetig: die Tastenbelegungen des Menues wuerden das Loslassen
schlucken und man liefe endlos weiter. Autolaufen ist davon seit v42.00
ausgenommen (eigenes Flag AutoRun, das IsPlayerMoving bewusst nicht liest).
Die zweite sass im Tastenhandler des Menues selbst und liess, solange eine
Bewegungssperre stand, jeden Tastendruck ausser Escape verfallen. Diese
zweite Sperre kauft nichts: ist das Menue erst offen, gehoeren ihm die Tasten
ohnehin schon, das Verwerfen stoppt keine Bewegung - es macht nur das Menue
taub und setzt zu allem Ueberfluss das Merkzeichen "spaeter oeffnen" auf ein
laengst offenes Menue, das die Wiederoeffnungs-Schleife dann wieder abraeumen
muss. Sie greift jetzt nur noch, wenn das Menue NICHT offen ist. Die vier
verbliebenen Oeffnungssperren schreiben ausserdem eine Zeile ins Debug-Log,
die die haltende Bewegungstaste beim Namen nennt - vorher waren sie stumm,
und ein Bericht "das Menue ging beim Laufen nicht auf" hatte keinerlei Spur.
Navigation: "Aktuelle Karte Entfernung" steht jetzt vorn
Einfach: Unter "Direkter Wegpunkt" stand "Letzte" an erster und "Aktuelle Karte
Entfernung" an zweiter Stelle. Die beiden sind getauscht - die Liste der
Wegpunkte in der aktuellen Zone ist der haeufigere Einstieg und liegt jetzt
direkt unter dem Cursor.
Technisch: Reine Reihenfolge der Injektionen in SkuNav:MenuBuilder. "Letzte"
bleibt an eine nicht leere Liste zuletzt benutzter Wegpunkte gebunden; ist
sie leer, steht "Aktuelle Karte Entfernung" ohnehin an erster Stelle, wie
vorher auch.
Der Tippfilter ignoriert Akzente
Einfach: In jeder Liste, die sich durch Tippen einengen laesst, wurden Akzente
wie Zeichen einer anderen Sprache behandelt. Auf einem franzoesischen Client
fand "general" nichts, obwohl "Fournitures generales" dastand, und
"ingenieur" fand "Ingenieur" nicht - "ing" dagegen schon. Das traf auch
Deutsch: ein Eintrag, der mit einem grossen Umlaut beginnt, war ueber den
Filter nie erreichbar. Jetzt zaehlt der Buchstabe, nicht der Akzent. Dazu
tippt auf einer franzoesischen AZERTY-Tastatur die Taste ù jetzt ebenfalls in
den Filter - sie ist der einzige akzentuierte Buchstabe, den diese Tastatur
als echtes Tastenereignis liefert.
Technisch: string.lower ist in Lua bytweise und bildet ausschliesslich A-Z ab, es
faltet also auf keiner Seite des Vergleichs je ein akzentuiertes Zeichen.
SkuMenuFilterMatch (benutzt von ApplyFilter und JumpToFilterMatch) und
SettingsSearchMatch falten Eintragsnamen und Suchtext jetzt vorher auf
akzentfreies ASCII; nur 2-Byte-Sequenzen aus Latin-1 Supplement und Latin
Extended-A werden angefasst, reines ASCII nimmt den schnellen Weg. Streng
durchlaessiger als vorher: was frueher passte, passt weiterhin. Ausserdem
laufen die beiden string.find jetzt mit plain=true - der Suchtext wurde als
Lua-Suchmuster gelesen, weshalb eine Eingabe wie "50%" oder "(lang" nichts
fand oder mit einem Fehler abbrach.
Die Akzentfaltung stammt aus PR #9 (ZenqFR), die ù-Taste aus PR #13
(Naxedim).
Aktionsleisten: der Zauber-Tooltip wird wieder vorgelesen
Einfach: Im Aktionsleisten-Menue (Umschalt+F11) las Umschalt+Ab auf einem Zauber
der Zuweisungsliste gar nichts mehr vor. Jetzt kommt der Tooltip wieder -
ebenso bei der aktuellen Belegung einer Taste und bei den beiden
Begleiter-Faehigkeiten daneben, die dieselbe Schwaeche hatten.
Technisch: Zwei unabhaengige Ursachen, beide behoben, weil sich aus dem Code
keine ausschliessen liess. Erstens wird SkuScanningTooltip einmalig beim
Login ohne Vorlage erzeugt und von jedem Modul geteilt; wer ihn zuletzt
benutzt hat, kann ihn ohne brauchbaren Besitzer zuruecklassen, und danach
fuellt jeder Set*-Aufruf nichts mehr - lautlos, ohne Fehler. Er wird jetzt
unmittelbar vor dem Fuellen neu in Besitz genommen. Zweitens bekam
SetSpellByID den dritten Rueckgabewert von GetSpellBookItemName, der auf
diesem Client der Classic-Signatur folgt und nur (name, rank) liefert - die
Id ist eine Retail-Ergaenzung und war nil. Die Id kommt jetzt aus
GetSpellBookItemInfo, gefuellt wird mit SetSpellBookItem, das gar keine Id
braucht. Der Lesevorgang laeuft zusaetzlich in einem pcall, weil er bei jeder
Cursorbewegung ausgeloest wird. Aus PR #10 (ZenqFR).
Questziel: der Ort stand in den Daten, gefunden wurde er nie
Einfach: 174 Quests, bei denen man einen Ort erkunden oder dort etwas benutzen
soll, antworteten unter "Questziel" nur "Leer". Jetzt fuehrt der Eintrag zum
naechstgelegenen Routenwegpunkt an diesem Ort.
Technisch: GetTriggerEndWps setzte einen Wegpunkt-NAMEN zusammen
(";;;;") und liess ihn ueber die exakte
Namenssuche im Wegpunkt-Cache aufloesen. Einen Wegpunkt unter diesem Namen
erzeugt aber nichts - anders als bei Kreaturen- und Objektvorkommen -, er
traf also nur, wenn jemand ihn von Hand in die Routendaten geschrieben hatte:
genau einer existiert (Quest 10211, Shattrath). Der zusammengesetzte Name
wird weiter benutzt, wenn er aufloest; sonst uebernimmt jetzt die Geometrie -
Kartenkoordinaten in Weltkoordinaten, dann der naechste echte ROUTEN-Wegpunkt.
GetNearestWpToCoords2 bekam dafuer einen optionalen typeId-Filter, damit die
Ersatzsuche nicht in den rund 145000 erzeugten Vorkommenspunkten landet, und
eine Absicherung gegen einen fehlenden Kontinent-Eimer, wo pairs(nil) warf.
Ausserdem werden jetzt alle Koordinatenpaare jeder Zone gelesen statt nur des
ersten, und das Ergebnis wird pro Cache-Generation gemerkt.
Franzoesisch: die Wegpunktkommentare sprechen wieder - und jetzt franzoesisch
Einfach: Die Kommentare an Wegpunkten - darunter die sicherheitsrelevanten wie
"Vorsicht, ab hier fuehrt die Route am Rand einer Schlucht entlang", "hier auf
den Zeppelin warten" oder "dieser NPC bewegt sich" - blieben auf einem
franzoesischen Client seit v42.11 restlos stumm. Sie sprechen wieder, und sie
sprechen jetzt Franzoesisch: 207 Texte, die auf 546 Wegpunkten sitzen.
Technisch: Die Routendaten fuehren lComments nur fuer enUS und deDE (rund 296
Wegpunkte). SkuNav:PlayWpComments las comments[Sku.Loc] ohne Rueckfall. Bis
v42.11 war Sku.Loc auf einem franzoesischen Client "enUS", weil es keine
frFR-Locale gab, und man hoerte die englischen Texte; seit locales/frFR.lua
existiert, ist Sku.Loc "frFR", die Suche liefert nil, und die Funktion kehrt
wortlos zurueck. Neu ist Sku.locList (SkuUtil.lua), das Listengegenstueck zu
Sku.locStr: es liefert die erste NICHT LEERE Liste aus Sku.Loc / enUS / deDE.
"Nicht leer" ist entscheidend, weil SkuMM.lua an jedem gezeichneten Wegpunkt
ein leeres comments[Sku.Loc] anlegt - eine einfache oder-Kette bliebe daran
haengen. Die Uebersetzung ist aus dem DEUTSCHEN Original gemacht, nicht ueber
das Englische: das Englische hat auf genau diesen Sicherheitstexten Details
verloren (die Schlucht-Warnung ohne "du gehst am Rand" und ohne Laufrichtung,
"extrem schmale Bruecke mit Schlucht" zu "extrem schmale Bruecke"), und
mehrere englische Eintraege sind leer, darunter die Warnung vor toedlichen
Aufzuegen auf acht Wegpunkten.
Franzoesisch: Ressourcennamen und die Hoehle der Nebel
Einfach: Zwei Fehler, die nur einen franzoesischen Client trafen. Erstens waren 22
der 94 Ressourcennamen des Minikartenscanners falsch - der Scanner vergleicht
sie mit dem Tooltip des Spiels, ein falscher Name heisst also, dass dieses
Vorkommen nie angesagt wird, ohne Fehlermeldung. Zweitens blieb in der Hoehle
der Nebel die Wegpunktliste leer, waehrend eine draussen gestartete Route
weiterlief.
Technisch: Die 22 Namen wurden einzeln gegen eine von beiden Addons unabhaengige
Quelle entschieden: 19 ueber SkuDBs eigene frFR-Tabellen (aus Questies
Blizzard-Strings), drei ueber die Tooltip-Schnittstelle von Wowhead. Bei der
Hoehle vergleicht Geo.lua GetMinimapZoneText() woertlich mit L["Hoehle der
Nebel"]; die generierte frFR-Locale trug "Grotte des Brumes", eine freie
Uebersetzung - der Client sagt "Caverne des Brumes". Der Vergleich lief also
ins Leere, uiMap blieb auf dem Kontinent, GetAreaIdFromUiMapId antwortete -1
und GetCurrentAreaId nil, worauf ListWaypoints2 aufgab. Der Wert wurde mit
/szp in der Zone gelesen, nicht uebersetzt, und liegt jetzt sowohl in der
generierten Datei als auch in der TSV-Ablage, aus der sie zusammengebaut wird
- samt der Notiz, dass er nicht frei uebersetzt werden darf.
Aus den PRs #14 und #16 (Naxedim).
Zum Beacon drehen: genauer, und mit Vorhalt
Einfach: Die automatische Drehung zum Funkfeuer (T) sitzt jetzt deutlich genauer.
Vorher lief sie so schnell, dass allein das framegenaue Stoppen je nach
Bildrate zwanzig Grad und mehr Ueberdreh kosten konnte. Jetzt richtet sich das
Tempo nach der Groesse der Drehung, und keine Drehung dauert laenger als eine
Viertelsekunde. Waehrend man sich bewegt, wird ausserdem vorgehalten: gezielt
wird dorthin, wo der Wegpunkt am Ende der Drehung liegen wird - das beendet
das Im-Kreis-Laufen um nahe Wegpunkte, das vor allem beritten und im Flug
auftrat. Und ein Druck waehrend einer laufenden Drehung wird verworfen statt
die Drehung mittendrin abzubrechen; gewohntes Mehrfachdruecken verfeinert
weiter wie bisher.
Technisch: Vier Teile, die zusammen getestet wurden. Der Schnappschuss auf die
Standardkamera vor der Drehung bleibt - er ist fuer die Gierung tragend, ohne
ihn stimmt der Winkel nicht. Die Drehgeschwindigkeit wird aus dem Restwinkel
gedeckelt, statt fest zu laufen. Der Vorhalt rechnet aus der aktuellen
Geschwindigkeit und der voraussichtlichen Dauer der Drehung, wo der Wegpunkt
am Ende steht. Dazu eine Absicherung gegen den Fehler, dass nach schnell
hintereinander ausgeloesten Drehungen die Drehgeschwindigkeit der Kamera-
Tasten dauerhaft vervierfacht haengenblieb.
Das Installationsprogramm merkt sich, wo WoW liegt
Einfach: Das Installationsprogramm sucht das Spiel an den ueblichen Stellen -
Programme, dazu eine Handvoll wahrscheinlicher Ordner auf C, D und E. Wer sein
WoW woanders hat, musste den Ordner von Hand suchen, und das nicht einmal,
sondern bei JEDEM Update: das Installationsprogramm vergass die Antwort in dem
Moment, in dem es sich schloss. Jetzt schreibt es den Ordner auf, sobald eine
Installation durchgelaufen ist, und faengt beim naechsten Mal dort an. Zeigt man
ihm einen Client, findet es auch den zweiten daneben - eine Classic Era neben
einer Anniversary auf demselben ungewoehnlichen Laufwerk wird von selbst
mitgenommen. Zieht das Spiel spaeter um oder wird deinstalliert, wird die Notiz
verworfen und es wird gesucht wie vorher. Das Installationsprogramm steht damit
auf Version 4.5.
Technisch: Neue Datei PathMemory.cs. Das Installationsmanifest taugt dafuer nicht -
SkuInstall.json liegt IM AddOns-Ordner, es zu lesen setzt also voraus, den
Ordner schon gefunden zu haben, den man sich merken will. Der Ordner jedes
Clients wird deshalb als einfache Zeile "produkt=pfad" in SkuPaths.txt
geschrieben, und zwar an zwei Stellen: %LOCALAPPDATA%\SkuUpdater, neben der
dauerhaften Kopie des Updaters, die die Verknuepfung "Sku Updater" startet, und
%ProgramData%\SkuUpdater als maschinenweite Spiegelung. Die Spiegelung ist kein
Selbstzweck: das Installationsprogramm fordert Adminrechte an, ein
Standardbenutzer, der die UAC-Abfrage mit den Adminzugangsdaten eines anderen
beantwortet, laeuft also komplett unter jenem Profil und wuerde die Notiz sonst
in ein LOCALAPPDATA schreiben, das er nie wiedersieht. Beim naechsten Start
schlaegt ein gemerkter Ordner die Erkennung - er ist eine Entscheidung, die
Erkennung nur eine Vermutung ueber eine kurze Laufwerksliste - und sein
Basisverzeichnis wird der Suchliste vorangestellt; genau das macht das Merken
eines Clients fuer den anderen bezahlt. Absicherungen gegen eine veraltete
Notiz: der Ordner muss noch existieren, und seine .flavor.info darf nicht
inzwischen einen anderen Client melden - sonst wird die Notiz ignoriert, statt
eine Installation ins Leere zu schicken. Geschrieben wird erst, nachdem ein
Client sauber installiert wurde, ein abgebrochener oder fehlgeschlagener Lauf
hinterlaesst also nichts. Klartext mit Absicht - die Datei laesst sich vorlesen
und im Editor korrigieren, und wer eine Zeile loescht, bekommt fuer diesen
Client die automatische Erkennung zurueck. Neue Pruefung ohne Oberflaeche,
"SkuSelfTest pathmemory": sie gibt aus, was auf diesem Rechner vermerkt ist, und
spielt Schreiben, Lesen und die Faelle veralteter Notizen gegen einen
Wegwerfspeicher durch, ohne den echten anzufassen.
Das Lesefenster laesst sich einstellen
Einfach: Questtexte, Tooltips, der Chatverlauf und die Wiki-Seiten landen alle im selben
Lesefenster. Wie dieses Fenster aussieht, stand bisher fest im Code: Playfair Display
in 12 Punkt, eine duenne Schrift mit Serifen in der kleinsten Groesse, die das Addon
ueberhaupt verwendet. Fuer jemanden mit Restsehvermoegen war das ausgerechnet die
wichtigste Flaeche im Addon und zugleich die am schlechtesten lesbare. Unter
Einstellungen -> Visuelle Hilfen -> Textfenster stehen jetzt Schriftgroesse von 14 bis
44 Punkt, vier Schriftarten, vier Farbkombinationen (weiss auf schwarz, gelb auf
schwarz, schwarz auf weiss, weiss auf blau), die Deckkraft des Hintergrunds und ein
Umriss zur Wahl. Ab Werk laeuft das Fenster jetzt serifenlos in 18 Punkt. Wer nichts
umstellt, bekommt also trotzdem eine deutlich besser lesbare Flaeche als vorher.
Technisch: Die Flaeche selbst gehoert Libs/SkuTTS-1.0 (Frame SkuTTSMainFrame samt
FontString .FS); dort stand die Darstellung als ein einziger harter SetFont-Aufruf.
Die Einstellungen liegen jetzt in SkuCore VisualAids unter visualAids.textWindow, und
SkuTTS:Output ruft vor jedem Anzeigen VisualAids:TextWindowLayout auf - pcall-
gesichert und in derselben Richtung, in der SkuZOptions schon den Lesebalken fuettert.
Die Lib muss so nichts ueber die Optionen wissen, und ein abgeschaltetes Modul
Visuelle Hilfen laesst das Fenster einfach beim alten Aussehen. Jede Schriftzuweisung
ist geprueft und faellt auf die Client-Standardschrift zurueck, statt eine leere
Flaeche zu hinterlassen - die beiden mitgelieferten Familien Raleway und Playfair
liegen unter Libs/SkuTTS-1.0/fonts und kommen nur ueber das Release-ZIP mit. Die
Groessenstufen sind bewusst kleiner als beim Lesebalken: hier steht ein ganzer
Questtext, und das Fenster hat keinen Rollbalken, schneidet also unten umso frueher
ab, je groesser die Schrift ist. Gesprochen wird weiterhin alles, die Anzeige ist die
Zweitspur.
Der Lesebalken zeigt, was Sku sagt - und er funktioniert im Kampf
Einfach: Zwei Dinge auf einmal. Erstens blieb der Balken im Kampf leer, also genau dann,
wenn Vorlesen und Mitlesen am wichtigsten sind. Zweitens zeigte er nur den Namen eines
Menueeintrags: bei einem Ein/Aus-Schalter stand dort der Name, aber nicht der Zustand,
bei einer Taschenzeile der Name, aber nicht die Anzahl - alles, was Sku zusaetzlich
vorliest, fehlte auf dem Balken. Beides ist behoben; der Balken zeigt jetzt dieselbe
Zeile, die Sku spricht, und er tut es auch mitten im Kampf. Ausserdem sind Schriftart
und Farbkombination jetzt auch fuer ihn waehlbar, mit eigenen Werten neben denen des
Textfensters.
Technisch: Die Kampf-Sperre war eine Verwechslung von sichtbar und offen: die Pruefung
haengte an SkuOptions:IsMenuOpen(), und das testet OnSkuOptionsMain:IsVisible().
Dieser Frame ist Vorfahr der sicheren ENTER-Buttons und damit geschuetzt, sein Show()
ist im Kampf blockiert - das Kampfmenue laeuft absichtlich headless und meldet sich
stattdessen ueber SkuOptions.combatMenuActive. Genau dieses Paar pruefen templates.lua
und SkuZOptions ohnehin schon; der Lesebalken kannte es nur nicht. Er selbst ist ein
gewoehnlicher Frame ohne sichere Kinder, sein Show() war im Kampf nie das Problem.
Weil das Kampfmenue nur logisch schliesst (der Frame-Hide ist dort geschuetzt) und das
an sechs Stellen tut, blendet sich der Balken jetzt selbst aus: ein OnUpdate prueft
alle 0,25 s, ob das Menue noch offen ist - WoW ruft OnUpdate ausschliesslich bei
sichtbaren Frames auf, im ausgeblendeten Zustand kostet das also nichts. Der Inhalt
war schlicht ein weggeworfener Parameter: der Aufrufer uebergab immer schon den
vollstaendigen Sprechstring, angezeigt wurde trotzdem currentMenuPosition.name. Jetzt
hat der uebergebene String Vorrang, die Semikolons der Sprechtrennung werden fuer die
Anzeige zu Bindestrichen.
Namensplaketten: die Einstellungen, die das Spiel versteckt
Einfach: Der Client kann seine Namensplaketten laengst groesser, farbiger und
kontrastreicher darstellen - er bietet es nur nirgends an. Blizzards eigenes
Optionsfenster zeigt in Classic keine einzige dieser Einstellungen; die Checkbox fuer
groessere Plaketten, die es im aktuellen WoW gibt, ist in Classic ausdruecklich leer
gelassen. Ohne Sku kaeme man nur ueber Konsolenbefehle heran. Das neue Menue unter
Einstellungen -> Visuelle Hilfen -> Namensplaketten macht sie zugaenglich:
Plakettengroesse, Hervorhebung des Ziels, Abschwaechung aller uebrigen Plaketten,
Klassenfarben fuer Gegner und Verbuendete sowie nur Namen bei freundlichen Spielern.
Anders als die aelteren Plaketten-Farben faerbt das nicht etwas hinter die Plakette,
sondern veraendert die echte Plakette selbst. Ab Werk steht alles so, wie der Client
es ausliefert - wer nichts auswaehlt, sieht keine Veraenderung.
Technisch: Reine CVar-Einstellungen, kein eigener Frame, kein Taint. Plakettengroesse
setzt nameplateMinScale und nameplateMaxScale gemeinsam (getrennt ergaebe das eine
entfernungsabhaengige Skalierung, die hier niemand will), Hervorhebung setzt
nameplateSelectedScale, Abschwaechung nameplateMinAlpha, dazu nameplateShowClassColor,
nameplateShowFriendlyClassColor und nameplateShowOnlyNameForFriendlyPlayerUnits. Alle
Werte und die Existenz jeder einzelnen CVar wurden am lebenden Client 2.5.6.69546
gemessen, die Obergrenze 2.0 gegen die Klemmung des Clients geprueft. Wichtig fuer
kuenftige Arbeit: die entpackte BlizzardInterfaceCode im Client-Ordner ist ein Abzug
von Maerz/April 2026 und damit aelter als die Plaketten-Umstellung vom Juli; sie nennt
Retail-Namen wie NamePlateVerticalScale oder ShowClassColorInNameplate, die es in
dieser exe gar nicht gibt. Massgeblich sind die Strings der exe. Schreibzugriffe auf
CVars sind im Kampf gesperrt und scheitern still, eine dort gemachte Aenderung wird
deshalb vorgemerkt und bei PLAYER_REGEN_ENABLED nachgeholt. Beim Login zieht Sku die
Werte nach, aber erst, nachdem im Menue wirklich einmal etwas ausgewaehlt wurde - wer
seine Plaketten frueher von Hand per Konsole eingestellt hat, behaelt sie
unangetastet.
Die Plaketten-Farben ueberleben einen Neustart
Einfach: Wer die Plaketten-Faerbung einschaltete, hatte sie genau so lange, bis er sich
neu einloggte oder die Oberflaeche neu lud. Danach stand der Schalter weiter auf an,
gefaerbt wurde aber nichts mehr. Wieder in Gang brachte man es nur, indem man den
Schalter von Hand aus- und wieder einschaltete - und das in jeder Sitzung erneut. Das
ist behoben; die Einstellung wirkt jetzt einfach.
Technisch: Das Scharfschalten des Ereignis-Treibers (NAME_PLATE_UNIT_ADDED, _REMOVED und
PLAYER_TARGET_CHANGED) haengte ausschliesslich am OnAction des Menue-Schalters. Der
gespeicherte Wert wurde beim Laden zwar gelesen, aber nirgends angewandt, also war
nach jedem Login kein einziges Ereignis registriert. Das Armieren sitzt jetzt in
VisualAids:OnEnable, wo die Folgen-Warnung und der Naechster-Gegner-Button schon immer
armiert wurden, mit einem verzoegerten zweiten Versuch fuer den Fall, dass das Profil
beim ersten Durchlauf noch nicht steht.
Ein geschlossenes Fenster wird nicht mehr nachtraeglich angesagt
Einfach: Wer beim Lehrer schnell mehrere Zauber lernte, das Fenster zuegig schloss und
dann sein Berufsfenster oeffnete, hoerte nach einer Weile wieder das Lehrerfenster -
manchmal erst, nachdem er einen Tooltip gelesen hatte. Sku merkte sich, wohin es im
Menue eigentlich noch springen wollte, und holte das spaeter nach, ohne zu pruefen,
ob es dieses Fenster ueberhaupt noch gibt.
Technisch: Der aufgeschobene Menuesprung besteht aus drei Feldern (openMenuAfterCombat,
openMenuAfterMoving, openMenuAfterPath), die bisher unabhaengig voneinander
beschrieben wurden. SlashFunc setzt Merker UND Pfad gemeinsam; andere Stellen setzten
nur den Merker - und erbten damit den Pfad, der noch herumlag. Geloescht wurde der
Pfad ausserdem nur im verzoegerten Teil von CheckFrames, der in Bewegung abbricht und
erst eine halbe Sekunde spaeter nachfasst, waehrend die Freigabe im Bild-Takt genau in
dem Moment feuert, in dem man stehen bleibt - ein Rennen, das die Freigabe gewann.
Die drei Felder sind jetzt eine Einheit (SkuCore:ClearDeferredMenuOpen), das Setzen
eines Merkers loescht den Pfad, und geleert wird im Hide-Hook des Fensters
(SkuCore:GENERIC_OnClose) - also genau dann, wenn der Sprung ungueltig wird. Bewusst
ohne Verfallszeit und ohne Sichtbarkeitspruefung: der Zustand wird dort geloescht, wo
er falsch wird, statt einem Fehler davonzulaufen.
Das Menue oeffnet nicht mehr von selbst die oberste Ebene
Einfach: Ab und zu ging das Menue von allein auf - und dann auch noch ganz oben, statt
dort, wo man hinwollte.
Technisch: SkuCoreControlOption1 haelt Tastenbelegungen (Zielentfernung, Panikmodus,
Minikartenscan, Flug abbrechen, zu Einheit drehen) und hat mit dem Menue nichts zu
tun. Sein OnShow bricht ab, solange man sich bewegt oder im Kampf ist, weil
SetOverrideBindingClick dort nicht erlaubt ist und einer gehaltenen Bewegungstaste das
Loslassen wegnehmen wuerde - es brach aber ab, indem es openMenuAfterMoving setzte,
und die Freigabe machte daraus mangels Pfad ein Menue-Oeffnen auf der Wurzel. Der
Frame hat jetzt seinen eigenen Merker (rebindControlKeysAfterBlock) und bekommt nur
noch seine Tasten zurueck.
Das Schliessen eines zweiten offenen Fensters wird wieder bemerkt
Einfach: Waren zwei Fenster gleichzeitig offen - etwa Haendler und Taschen -, wurde nur
das erste Schliessen bemerkt. Beim zweiten baute sich das Menue nicht neu auf und
schloss sich nicht.
Technisch: Einer der beiden Hook-Installateure klammerte Show und Hide um einen einzigen
gemeinsamen Schalter (SkuDropdownlistGenericFlag): jedes Show setzte ihn, und nur das
erste Hide danach verbrauchte ihn. Welcher Installateur ein Fenster erwischte, war
reine Zeitfrage - dieser nimmt alles, was eine Sekunde nach dem Betreten der Welt
existiert, waehrend Fenster wie Lehrer, Beruf und Auktionshaus erst spaeter entstehen
und dem anderen zufallen. Der Schalter ist weg; GENERIC_OnClose fasst ohnehin selbst
zusammen.
Kein Inhalt eines geschlossenen Fensters mehr unter "Lokal"
Einfach: Nach dem Schliessen eines Fensters konnten dessen Eintraege unter "Lokal"
stehenbleiben und beim naechsten Oeffnen des Menues noch einmal auftauchen.
Technisch: SkuCore.GossipList ist die Datenquelle des Lokal-Menues, wurde aber nur
geleert, wenn das Menue in genau diesem Moment offen war. Beim Schliessen per Escape
ist es das nie: der Menue-Frame geht absichtlich vor den Fenstern zu, und der
zustaendige Programmteil laeuft ein Bild spaeter. Jetzt wird geleert, sobald kein
Fenster mehr offen ist.
Lehrer: nach dem Schliessen ist Ruhe
Einfach: Wer mehrere Zauber schnell hintereinander lernte und das Fenster gleich danach
schloss, hoerte die Ansagen des Lehrers noch weiter.
Technisch: Jeder Klick auf "Erlernen" stellte eine Neuerfassung nach einer halben Sekunde
und eine Ansage nach 0,85 Sekunden in die Warteschlange, ohne Abbruchmoeglichkeit.
Beide Schritte pruefen jetzt, ob ClassTrainerFrame ueberhaupt noch sichtbar ist. Die
Sperre aus v43.1, die nicht in ein geschlossenes Menue hineinspricht, half hier nicht:
sobald das naechste Fenster das Menue wieder oeffnete, war sie offen. Ausserdem verlor
die Wiederholung stiller Neuerfassungen in Bewegung ihren Stumm-Auftrag und wurde je
Klick einmal eingeplant - sie traegt ihre Argumente jetzt mit und laeuft nur noch
einmal.
Auktionshaus: die Trefferliste ist wirklich sortiert
Einfach: Wer nach "Level absteigend" sortierte, bekam trotzdem eine Liste, die mit
niedrigstufigem Kram anfing. Sortiert wurde naemlich nur innerhalb einer Seite - und
eine Seite sind die 50 billigsten Auktionen. Ganz oben stand also das Hoechststufige
unter dem billigsten Graugut, waehrend die Stufe-70-Sachen Hunderte Eintraege weiter
unten lagen. Auch nach dem Fertig-Ton, denn nachsortiert wurde nie. Jetzt sortiert der
Server die Trefferliste selbst nach Stufe; bei gleicher Stufe entscheidet der Preis je
Stueck.
Technisch: Jede Abfrage ging mit fest verdrahteter Server-Sortierung "unitprice" raus, und
die Ergebnisliste wird seitenweise und nur anhaengend aufgebaut (neue Gegenstaende
kommen ans Ende, damit der Cursor des Nutzers nicht springt). Die Reihenfolge der Liste
ist damit immer die des Servers, die eigene Sortierung wirkt nur je Seite. Bei "Level
auf-" und "absteigend" wird die Server-Antwort jetzt nach der Spalte "level" sortiert -
genau die Spalte, die auch Blizzards eigener Stufen-Sortierknopf setzt. Kauf und
Strategiekauf bleiben auf "unitprice", die brauchen den guenstigsten Treffer auf Seite
0. Eine Namenssuche ebenfalls: dort haben alle Treffer dieselbe Stufe, der Server
haette nach einem Feld sortiert, in dem sich nichts unterscheidet, und die Seiten
kaemen in seiner Zufallsreihenfolge statt der billigsten zuerst. Zusaetzlich haben die
Stufen-Vergleiche jetzt den Stueckpreis als zweiten Schluessel; Nur-Gebot-Auktionen
zaehlen dabei mit ihrem Gebot je Stueck statt mit einem Kaufpreis von 0.
Auktionshaus: "Stufe" heisst ueberall Stufenanforderung
Einfach: Die Stufe in den Ergebnissen war mal die Stufenanforderung, mal die
Gegenstandsstufe - je nachdem, aus welcher Liste sie kam und ob der Gegenstand
ueberhaupt eine Anforderung hat. Ein Stapel Netherstoff (Anforderung 0,
Gegenstandsstufe 55) stand damit ueber einem Stufe-40-Schwert. Jetzt ist es immer die
Stufenanforderung, also die Spalte, die auch das Auktionshaus selbst "Stufe" nennt. Und
sie wird nur noch dort vorgelesen, wo sie die Eintraege unterscheidet: in einer
Kategorie oder in der Komplettscan-Liste. Eine Suche nach einem Gegenstandsnamen
liefert lauter Auktionen desselben Gegenstands - dort war es 800 Mal dieselbe Zahl. Wer
nach Stufe filtert, bekommt sie weiterhin ueberall angesagt.
Technisch: Ein gemeinsamer Leser fuer beide Ergebnislisten: Feld 6 der Server-Antwort,
sonst der Wert aus SkuDB. Feld 7 wird beachtet - bei Rezepten steht in Feld 6 der
geforderte Berufs-Skill, bei Behaeltern die Zahl der Taschenplaetze, beides keine
Stufe. Die Gegenstandsstufe wird nie mehr ersatzweise eingesetzt. 0 heisst jetzt "keine
Anforderung" statt "unbekannt", weshalb auch kein "Level 0" mehr angesagt wird (0 ist
in Lua wahr, deshalb kam es ueberhaupt heraus).
Auktionshaus: "Nur benutzbare" versteckt nichts mehr
Einfach: In der Komplettscan-Liste liess dieser Filter in manchen Kategorien nur noch
niedrigstufiges Zeug uebrig - ausgerechnet das Hochstufige, nach dem man sucht, war
weg. In der normalen Suche war das nie so.
Technisch: In der Live-Liste filtert der Server. Der Komplettscan holt alles ungefiltert,
Sku entscheidet selbst - bisher stur nach dem Feld canUse aus der Scan-Antwort. Das
kann der Client nur fuellen, wenn er die Gegenstandsdaten der Zeile schon hatte; beim
Komplettscan hat er sie fuer den Grossteil der Zeilen nicht. Es sind genau dieselben
Zeilen, fuer die Name, Stufe und Qualitaet nachgetragen werden muessen - nur fuer
canUse gab es keine Nachbesserung. Damit verschwand, was der Spieler noch nie gesehen
hat, und das ist ueberwiegend das Hochstufige. Jetzt zaehlt ein "nicht benutzbar" nur
bei vollstaendiger Zeile; sonst entscheidet die Stufenanforderung aus SkuDB. Klassen-
und Rassenbeschraenkungen kennt die Datenbank nicht - im Zweifel wird lieber ein
Gegenstand zu viel gezeigt als der gesuchte verschwiegen.
Auktionshaus: ohne Filter wird nicht gefiltert
Einfach: Die Komplettscan-Liste liess auch ohne gesetzten Filter alles weg, was keine
Stufenanforderung hat - Handelswaren, Materialien, viele Rezepte - und ausserdem alles
Graue, obwohl das Qualitaetsmenue unveraendert "Arm" anzeigte, also "keine
Einschraenkung".
Technisch: Die Vorgaben der ungesetzten Filter waren je eine 1 statt einer 0, und die Stufe
wurde roh aus der Scan-Antwort gelesen. Eine Zeile, deren Stufe der Client beim Scan
nicht kannte, kam als 0 zurueck und fiel damit unter die Mindeststufe 1; die Reparatur
aus der Datenbank sprang nur bei einem fehlenden, nicht bei einem 0-Wert an. Beide
Vorgaben sind jetzt 0, die Stufe kommt aus dem gemeinsamen Leser, und die Nachbesserung
beim Einlesen behandelt 0 als "fehlt". Der frueher als letzter Ausweg eingesetzte
eigene Mindeststufen-Wert ist weg: eine Zeile bestand damit immer ihren eigenen Filter
und wurde auch noch mit dieser Stufe angesagt.
Auktionshaus: Kategorien ohne Unterkategorien zeigen wieder Gegenstaende
Einfach: Unter "Auktionen nach Gegenstand" gab es Kategorien, die ausser "Alle" nichts
enthielten - zum Beispiel Questgegenstaende.
Technisch: Die Gegenstandsliste verglich die Unterklasse auch dann, wenn es gar keine gibt.
Eine Kategorie ohne Unterkategorien wird ohne Unterklasse aufgebaut, und der Vergleich
ist dann fuer jeden Gegenstand falsch. Der Komplettscan-Zwilling hatte die Absicherung
von Anfang an, die Gegenstandsliste jetzt auch.
Auktionshaus: ein abgebrochener Kauf bleibt abgebrochen
Einfach: Wer einen Kauf abbrach und danach etwas anderes tat, konnte aus dem Nichts wieder
den Kauf-Dialog bekommen - und die naechste Eingabetaste, die eigentlich das Suchfeld
oeffnen sollte, kaufte. Gekauft wurde immerhin das Richtige, aber ungefragt.
Technisch: Der Abbruch loeste Timer und Tastenbelegungen, loeschte aber das Kaufziel nicht.
Die Abfragefunktion erkennt ihren Modus genau daran - es gibt ein Kaufziel, also ist
das eine Kauf-Abfrage -, und so lief die naechste, voellig fremde Abfrage des Nutzers
in den Kauf-Pfad: der fand das alte Ziel in der frischen Liste wieder, baute den Dialog
auf und schaltete die Eingabetaste scharf. Im Log vom 01.09.2026 liegen Abbruch
(18:45:40), neue Suche (18:46:12, sofort "MATCH FOUND, showing popup") und der Kauf
(18:46:16, "Gebot akzeptiert") nur vier Menue-Tastendruecke auseinander. Das Kaufziel
wird jetzt an den drei Stellen geloescht, an denen der Kaufwunsch endet: Abbruch des
Dialogs (auch durch die 30-Sekunden-Sicherung), Start einer neuen Suche oder Liste, und
Schliessen des Auktionshauses. Der Kaufweg selbst bleibt unangetastet - er laeuft nicht
ueber den Sucheinstieg, und die Wiederholung nach einem verlorenen Wettlauf behaelt ihr
Ziel.
Auktionshaus: eine abgebrochene Suche sagt es
Einfach: Bricht eine Suche ab, weil der Server nicht mehr antwortet, blieb die halb
gefuellte Trefferliste stehen und sah aus wie ein fertiges Ergebnis. Jetzt kommt
"Suche abgebrochen, Liste unvollstaendig".
Technisch: Der Waechter beendet eine seitenweise Suche nach 60 Sekunden ohne Server-Antwort
bzw. nach 180 Sekunden Gesamtdauer - bisher lautlos. Der Fertig-Ton ist das Signal fuer
"vollstaendig", sein Ausbleiben aber hoert man nicht. Angesagt wird nur, wenn der
Nutzer auch wirklich in dieser Ergebnisliste steht; laeuft die Suche im Hintergrund,
bleibt es still.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v43.1
Ueberblick
Aenderungen
Der Kauf mehrerer Stuecke im Auktionshaus laeuft jetzt durch, solange es weitere Angebote zum gleichen hoerbaren Preis gibt.
Jeder gelungene Kauf wird sofort mit "Gekauft, n von m" bestaetigt.
Ist ein Preis ausverkauft, meldet Sku "Keine weiteren Angebote zu diesem Preis" samt Bilanz und bleibt in der Ergebnisliste stehen.
Neue Einstellung "Tastatur-Echo ansagen" (Einstellungen -> Allgemein, standardmaessig an): das zeichenweise Vorlesen beim Tippen in Eingabefeldern laesst sich abschalten.
Auktionshaus: der Komplettscan bestaetigt sich schon nach 5 Sekunden zum ersten Mal, danach wie bisher alle 10 Sekunden.
Questmenue: der Eintrag "Gruppenmitglieder" steht jetzt an dritter Stelle statt in der Mitte, "Aktuelle Quests" und "Questdatenbank" behalten dadurch immer ihren Platz.
Fehlerbehebungen
Auktionshaus: der Kauf mehrerer Stuecke brach nach fast jedem gelungenen Kauf faelschlich mit "Auktion vergriffen" ab und warf aus der Suche.
Nach dem Schliessen des Menues sprachen verzoegerte Ansagen weiter ("Neuer Brief plus", "Betreff: ", "Gesendet", "Alle geoeffnet" aus dem laengst geschlossenen Briefkasten).
Auktionshaus: eine unvollstaendige Server-Antwort beendet die Suche nicht mehr faelschlich mit "leer" - eine echte Suche ohne Treffer antwortet weiterhin sofort.
Auktionshaus: eine Suche, die gar nicht erst starten kann, nennt jetzt den Grund ("Nicht moeglich, scan laeuft" bzw. "Auktionshaus beschaeftigt") statt "leer" zu sagen.
Auktionshaus: eine Suche ohne Treffer sagt jetzt "keine Ergebnisse" statt "leer" - und das Suchfeld bleibt in der Liste, der Cursor landet direkt darauf.
Auktionshaus: ein per Schliessen abgebrochener Komplettscan blockierte danach jede Suche mit "Nicht moeglich, scan laeuft", obwohl kein Scan mehr lief.
Auktionshaus: der Komplettscan brach manchmal direkt nach der Startansage stillschweigend ab; die 16-Minuten-Sperre war trotzdem verbraucht.
Franzoesische Clients: in mehreren Zonen war die Wegpunktliste leer (Korrektur von Naxedim).
Neue Einstellung: Tastatur-Echo ansagen
Einfach: In Eingabefeldern (Brief schreiben, Suche, Profilname...) liest Sku jedes getippte
Zeichen vor, ebenso Ruecktaste und die Cursor-Lesungen mit den Pfeiltasten. Wer das
nicht mag oder es doppelt hoert, schaltet es jetzt unter Einstellungen -> Allgemein,
"Tastatur-Echo ansagen" ab (direkt neben "Menuenummern ansagen" und "Untermenues
ansagen"). Standard ist AN, es aendert sich also nichts, wer nichts umstellt.
Statusansagen wie "Abgebrochen" oder die Feld-Bestaetigung nach ENTER bleiben immer.
Keine Ansagen mehr in ein geschlossenes Menue hinein
Einfach: Wer ein Eingabefeld mit ENTER bestaetigte und gleich darauf das Menue schloss,
hoerte trotzdem noch "Betreff: " - als kaeme das Tastatur-Echo nach dem
Schliessen hinterher. Genauso sprachen aus dem laengst geschlossenen Briefkasten noch
"Neuer Brief plus", "Gesendet" oder "Alle geoeffnet". Jetzt gilt: was einen
Menue-Eintrag ansagen will, prueft erst, ob das Menue ueberhaupt noch offen ist -
und die Briefkasten-Quittungen pruefen, ob der Briefkasten noch offen ist. Die
Server-Systemzeile "Post verschickt." im Chat bleibt davon unberuehrt.
Technisch: Die Nachzuegler waren nie die Sprach-Queue (das Schliessen leert sie schon
per queuereset + StopSpeakingText), sondern Erzeuger, die NACH dem Schliessen erst
einspeisen: C_Timer-Bestaetigungen (0,3 s nach Anhaengen/Feldeingabe/Senden, 0,5 s
nach "Alle oeffnen") und Server-Events (MAIL_SEND_SUCCESS). Eine weitere pauschale
Queue-Leerung beim Fensterschliessen wuerde sie deshalb nicht erwischen, aber
legitime Ansagen (Chat, Kampf, Navigation) mitten im Wort abschiessen. Stattdessen:
zentrales Gate in SkuOptions:VocalizeCurrentMenuName (kein offenes Menue, kein
kopfloses Kampfmenue und kein SkuChat-Zeilenmenue -> stumm; der String-Modus
liefert weiter Text), plus drei
Erzeuger-Gates in der Post (MailboxOpenFlag fuer "Gesendet", IsMenuOpen fuer die
Feld-Bestaetigung, MailFrame-Sichtbarkeit fuer "Alle geoeffnet"). MAIL_FAILED bleibt
bewusst ungefiltert - ein Fehlschlag muss auch nach dem Schliessen hoerbar sein.
Auktionshaus: der Kauf mehrerer Stuecke brach nach fast jedem Kauf faelschlich mit "Auktion vergriffen" ab
Einfach: Wer in der Ergebnisliste einen Eintrag wie "14 mal Sphaere der Leere" waehlte und
davon fuenf Stueck kaufen wollte, hoerte fast nach jedem Kauf "Auktion vergriffen" und
stand wieder ausserhalb der Suche - obwohl der Kauf gelungen war und das Geld korrekt
abging. Da der Erfolg selbst nie angesagt wurde, klang das nach lauter Fehlschlaegen,
waehrend die Stuecke laengst im Beutel lagen. Die Ursache: Verkaeufer unterbieten sich
um je 1 Kupfer. Die Ergebnisliste fasst alle Auktionen zusammen, deren Preis GLEICH
KLINGT - ab 1 Gold wird der Kupferanteil nicht mitgesprochen -, der Weiterkauf suchte
das naechste Stueck aber zum exakten Kupferbetrag, und den gab es nach dem Kauf des
billigsten meist nicht mehr. Jetzt kauft der Weiterkauf eine solche Gruppe Stueck fuer
Stueck durch: das naechste Angebot darf sich nur im Kupfer unterscheiden, also im nicht
hoerbaren Teil des Preises. Ein hoerbar teureres Angebot - egal ob 1 Silber oder
100 Gold teurer - wird NIE automatisch angeboten, und jedes einzelne Stueck verlangt
weiterhin seine eigene Eingabe.
Technisch: Belegt im Debug-Log vom 2026-08-25: fuenf Kaeufe zu 52g99s81k bis 52g99s84k,
jeder Lauf kaufte genau ein Stueck und brach dann ab. Die Fortsetzung (_ABReQueryBuy →
Match-Scan) verglich Item-ID + Stueckzahl + EXAKTEN Sofortkaufpreis; die Ergebnisliste
gruppiert aber nach dem formatierten Label (SkuGetCoinText very-short laesst Kupfer ab
1 Gold weg), eine Gruppe umfasst also einen 1-Silber-Eimer. Der Scan merkt sich jetzt
das billigste kaufbare Angebot mit gleicher Item-ID und Stueckzahl im gleichen Eimer
(floor(buyout/100) identisch, nur ab 10000 Kupfer) und uebernimmt dessen Preisfelder
(8/9/10/11) in QueryBuyData; der failCount startet fuer die neue Preisgruppe bei 0.
Unter 1 Gold spricht das Label den Kupfer mit - dort bleibt das alte exakte Verhalten.
Gebots-Kaeufe behalten den strengen 17-Feld-Vergleich.
Auktionshaus: jeder Kauf wird bestaetigt, das Ende einer Preisgruppe meldet die Bilanz und bleibt in der Liste
Einfach: Nach jedem gelungenen Stueck sagt Sku jetzt sofort "Gekauft, n von m" - vorher war
das einzige Erfolgssignal der naechste Kaufprompt. Sind alle Angebote zum gleichen
hoerbaren Preis weg, heisst es "Keine weiteren Angebote zu diesem Preis" mit der
Bilanz, etwa "2 von 5 gekauft", und der Cursor bleibt auf dem Eintrag in der
Ergebnisliste stehen, statt wie bisher mehrere Ebenen nach oben auf "Auktionen" zu
springen. Von dort laesst sich direkt zum naechsten, teureren Eintrag navigieren und
dort neu kaufen.
Technisch: Die Erfolgsansage sitzt in _ABContinueOrFinish, direkt nach dem
Server-"Gebot akzeptiert.". Der Vergriffen-Pfad positioniert zuerst
(AuctionStayOnResultsEntry; schlaegt das Pruning fehl, weil der Datensatz nach dem
Kauf bereits entfernt war, haelt ein Fallback ueber AuctionResultsItemEntryFromCursor
den Cursor auf dem Item-Eintrag) und spricht die Meldung 0,4 s spaeter ohne
Unterbrechung - dasselbe Muster wie beim bestehenden "Fertig. Alle gekauft".
Auktionshaus: unvollstaendige Server-Antwort gilt nicht mehr als "keine Treffer"
Einfach: Antwortet der Server widerspruechlich - er meldet Treffer, liefert aber keine
einzige Zeile -, dann beendete Sku die Suche bisher sofort mit "leer". Jetzt wartet
es in diesem Fall auf die vollstaendige Antwort und fragt die Seite noch einmal an.
Eine Suche, die wirklich nichts findet (Tippfehler im Suchfeld, leere Kategorie),
antwortet unveraendert sofort - mit der Trefferzahl 0 und "keine Ergebnisse".
Technisch: In AUCTION_ITEM_LIST_UPDATE_LIST gilt eine leere Seite nur dann als
verfrueht, wenn der Server sich widerspricht: tBatch == 0 (keine Zeile auf dieser
Seite) bei tCount > 0 (Gesamttrefferzahl groesser 0). Dann zaehlt
QueryListEmptyWaits hoch, der Scan bleibt auf "waiting" und der Ticker fragt
dieselbe Seite erneut an; nach 10 solchen Antworten wird das Ergebnis doch
akzeptiert (Notausstieg). tCount == 0 ist dagegen die ehrliche Antwort "keine
Treffer" und muss ohne Verzoegerung durchlaufen: der Kauf-Pfad zaehlt an dieser
Stelle JEDE leere Antwort (QueryBuyEmptyWaits), weil er eine womoeglich noch
lebende Auktion wiederfinden will - fuer die Suche waere dieselbe Regel falsch.
Im Debug-Log vom 2026-08-26 beantwortet der Server die Suche "feuerpartiekel" in
derselben Sekunde mit 0 von 0; das ist die echte Antwort, keine Spuk-Antwort.
Auktionshaus: eine Suche, die gar nicht erst starten kann, nennt jetzt den Grund
Einfach: Es gibt Momente, in denen das Auktionshaus eine Suche nicht annimmt:
waehrend im Hintergrund ein Komplettscan laeuft, waehrend ein Kauf scharf ist,
oder wenn der Server gerade drosselt. Bisher merkte Sku das nicht - es baute die
Liste trotzdem auf und sagte "leer", als haette die Suche nichts gefunden. Beim
ersten Aufruf in einer Sitzung klang das nach einer leeren Kategorie, spaeter
zeigte die Liste sogar die Treffer der VORIGEN Suche.
Jetzt nennt Sku den Grund. Laeuft ein Komplettscan, steht sofort beim Oeffnen
"Nicht moeglich, scan laeuft" in der Liste - dieselbe Meldung, die das
Verkaufen-Menue in dieser Lage schon immer gibt. Warten hat dort keinen Sinn: ein
Komplettscan belegt das Auktionshaus minutenlang. Bei den kurzen Huerden
(scharfer Kauf, Drossel) bleibt Sku auf "Warten" stehen und versucht es von
selbst weiter; kommt die Suche innerhalb von 5 Sekunden durch, laeuft alles wie
gewohnt weiter, sonst heisst es "Auktionshaus beschaeftigt, Suche nicht
gestartet". Faengt waehrend dieser Versuche ein Komplettscan an, bricht Sku sie
gleich ab und sagt es. Mit Pfeil links und wieder rechts startet man jederzeit
einen neuen Versuch.
Technisch: AuctionHouseStartQuery liefert an drei Stellen false und seit dieser
Version den GRUND als zweiten Rueckgabewert ("secureBuy", "getAllRunning",
"getAllCooldown", "queryThrew"). Die drei Browse-Aufrufer - Suchfeld, "Alle" und
Einzel-Item in AuctionHouseBuildItemDBMenu - hatten den Rueckgabewert ignoriert
und trotzdem QueryResultsHost gesetzt, children geleert und neu gebaut; der
ResultsMenuBuilder fand state == "idle", uebersprang seinen "Warten"-Zweig und
fiel auf die Leer-Pruefung durch. Sie laufen jetzt ueber AuctionBrowseStart, das
am Grund entscheidet: getAll-Gruende sofort melden, alles andere als
Wiederholversuch einreihen (QueryStartPending). AuctionBrowseRetryTick haengt am
bestehenden AH-OnUpdate-Ticker - bewusst frame-getrieben und nicht als
C_Timer-Kette, weil eine abgewuergte Kette ihre Re-Arm-Zeile nie erreicht -,
steht ganz vorn vor dessen fruehen Returns (sonst fror er waehrend des
getAll-Ingests ein), versucht hoechstens alle 0,25 s und nur bei
CanSendAuctionQuery, prueft den Grund erneut und reiht sich nach einem
Fehlversuch explizit wieder ein - StartQuery ruft intern ResetQuery auf und
loescht dabei den Merker, auch wenn es danach doch false liefert. Nach Erfolg
wird QueryResultsHost neu gesetzt, weil der frische Query-Aufbau ihn nilt.
QueryStartFailed traegt den anzuzeigenden TEXT (AH_QueryBusy bzw. die
Scan-Meldung des Verkaufen-Menues) und wird VOR der "Warten"-Bedingung geprueft:
der blockierende Scan haelt AuctionScan.state selbst auf "waiting"/"paging", also
gewaenne sonst immer "Warten" und die Begruendung waere unerreichbar. Der
Sofort-Pfad spricht bewusst NICHT selbst - die Meldung ist der einzige
Listeneintrag und wird beim Oeffnen ohnehin vorgelesen, waehrend eine eigene
Ansage vom folgenden Vocalize abgeschnitten wuerde und bei jedem
Vorbeinavigieren erneut feuerte (OnEnter laeuft schon beim Ankommen).
ResetQuery raeumt beide Merker ab.
Auktionshaus: "keine Ergebnisse" statt "leer", und das Suchfeld bleibt erreichbar
Einfach: Eine Suche ohne Treffer - etwa mit einem Tippfehler - sagte bisher "leer".
Das klingt nach einer leeren Liste, gemeint ist aber "nichts gefunden": jetzt
heisst es "keine Ergebnisse". Ausserdem war das Suchfeld nach einer Suche aus der
Liste verschwunden; fuer eine zweite Suche musste man erst raus- und wieder
reinnavigieren. Es steht jetzt weiterhin als "Suchbegriff eingeben" in der Liste,
und bei null Treffern springt der Cursor gleich darauf - einmal ENTER und man
tippt den naechsten Begriff. Gibt es Treffer, landet der Cursor wie gewohnt auf
dem ersten Treffer.
Technisch: Der inkrementelle Aufbau rief den ResultsMenuBuilder direkt auf und
umging damit BuildChildren des Suchfeld-Eintrags - genau dort wird
"Suchbegriff eingeben" eingehaengt, deshalb war es nach der ersten Seite weg. Er
ruft jetzt aHost:BuildChildren(aHost) (fuer "Alle"/Einzel-Item IST das der
ResultsMenuBuilder). Damit der Suchfeld-Eintrag dabei nicht auf "Warten"
zurueckfaellt, prueft sein Gate zusaetzlich QueryResultsPartialReady. Die
Cursor-Wahl uebernimmt AuctionFocusAfterResults: erster Eintrag, der weder
Eingabefeld noch "keine Ergebnisse" noch "Warten" ist; gibt es keinen, das
Eingabefeld. Die Nulltreffer-Ansage laeuft als EINE Ausgabe
("keine Ergebnisse;Suchbegriff eingeben") - ein zweites OutputStringBTtts haette
das erste abgeschnitten. In der Komplettscan-Kategorieliste heisst der
Nulltreffer-Eintrag ebenfalls "keine Ergebnisse"; der Zweig ohne jegliche
Scan-Daten bleibt "leer", weil das eine andere Aussage ist.
Auktionshaus: abgebrochener Komplettscan blockierte danach jede Suche
Einfach: Wer einen laufenden Komplettscan abbricht, indem er das Auktionshaus
schliesst, bekam danach bei JEDER Suche und jeder Kategorie "Nicht moeglich,
scan laeuft" zu hoeren - obwohl gar kein Scan mehr lief. Das blieb so, bis man
einen neuen Komplettscan startete und ihn auch durchlaufen liess. Jetzt raeumt
das Schliessen den Scan richtig ab, und die naechste Suche laeuft normal. (Die
16-Minuten-Sperre des Servers fuer den naechsten Komplettscan bleibt davon
unberuehrt - die ist serverseitig und auch nach einem Abbruch aktiv.)
Technisch: AuctionHouseResetQuery verweigert den Reset, solange ein getAll-Scan
laeuft, ausser der Aufrufer besteht mit force darauf - das schuetzt einen
laufenden Komplettscan davor, von einem beilaeufigen Reset (Verkaufen-Menue,
Browse-Pfade) abgewuergt zu werden. AUCTION_HOUSE_CLOSED rief
AuctionScanFinish OHNE force auf, also blieb nach dem Schliessen mitten im Scan
state = "waiting" mit QueryData.getAll = true stehen; genau das prueft die
Verweigerungslogik der Suche, also wurde ab da jede Query mit "getAllRunning"
abgewiesen. Das Schliessen forciert jetzt - es IST das Scan-Ende, danach kommen
ohnehin keine Events mehr. Zwei Log-Luecken, die den Fehler versteckt haben,
sind mit gefixt: die Verweigerung in AuctionHouseResetQuery schreibt jetzt eine
eigene Zeile (vorher sah man nur den Aufruf davor und hielt den Zustand fuer
geraeumt), und AuctionScanFinish meldet "finished" erst NACH dem Reset, mit
reset=true/false - vorher behauptete das Log ein Scan-Ende, das nie stattfand.
Auktionshaus: erste Komplettscan-Ansage schon nach 5 Sekunden
Einfach: Waehrend der Komplettscan auf die Antwort des Servers wartet, meldet Sku
alle 10 Sekunden "voller Scan, n Sekunden". Die allererste dieser Ansagen kam
damit auch erst nach 10 Sekunden - zehn Sekunden, in denen man nach dem Start
nicht wusste, ob der Scan ueberhaupt laeuft. Die erste Bestaetigung kommt jetzt
nach 5 Sekunden, die zweite 10 Sekunden spaeter, danach weiter im
10-Sekunden-Takt (also bei 5, 15, 25 ... Sekunden). Am Ende aendert sich nichts:
die 25-Prozent-Meldungen der Einlesephase und die Abschlussansage bleiben.
Technisch: Der Takt im AH-OnUpdate-Ticker liegt jetzt in tFullScanSpeakNext, das mit
tFullScanSpeakFirst (5) startet und nach der ersten Ansage auf
tFullScanSpeakEvery (10) umschaltet. Der Zaehler wird um den jeweils gueltigen
Schwellwert vermindert statt fest um 10, damit die Phase stimmt. Endet die
Arbeitsphase, faellt der Schwellwert wieder auf 5 zurueck - sonst haette der
naechste Scan erst nach 10 Sekunden seine erste Bestaetigung gegeben.
Auktionshaus: der Komplettscan brach manchmal direkt nach der Startansage stillschweigend ab
Einfach: Manchmal folgte auf "Komplettscan gestartet" einfach nichts mehr: keine
10-Sekunden-Fortschrittsansage, keine Fertigmeldung, und die Menues, die waehrend
eines Scans gesperrt sein sollten, waren es nicht - die 16-Minuten-Sperre war
trotzdem verbraucht. Das traf vor allem, wer die Wartezeit bis zum naechsten Scan
direkt am offenen Auktionshaus absass. Der Scan wurde intern sofort nach dem Start
wieder abgewuergt; jetzt startet er immer mit frisch genullter Uhr.
Technisch: Belegt im Debug-Log vom 2026-08-26: QueryAuctionItems und "watchdog: getAll
timeout 600s" in DERSELBEN Sekunde. Die Watchdog-Zaehler des Scan-Tickers waren
schon vor dem Start voll: tTime sammelte die komplette Leerlauf-Standzeit am
offenen AH (der Idle-Zweig setzte es nie zurueck - die 16-Minuten-Wartezeit
> 600 s reichte allein), und tFullScanElapsed ueberlebte jedes Scan-Ende, weil sein
Reset hinter dem 0,2-s-Tick-Gate des Serialize-Zweigs liegt, das eine schnelle
Serialisierung nie passiert. Der erste Watchdog-Tick nach dem Start addierte beides
und wuergte den frischen Scan ab; dabei nullte der Watchdog sich selbst, weshalb
die naechsten Versuche wieder liefen - daher das "meistens geht es". Jetzt nullt
SkuCore.AuctionScanWatchdogReset beide Zaehler nach jedem wirklich abgesetzten
QueryAuctionItems, und der Idle-Zweig setzt tTime selbst zurueck (schuetzt auch den
Stall-Watchdog der paginierten Suchen). Verifiziert 2026-08-26: Scan nach ~28 min
Standzeit am AH lief durch, 173841 Auktionen eingelesen.
Franzoesische Clients: in mehreren Zonen war die Wegpunktliste leer (Korrektur von Naxedim)
Einfach: In den Hoehlen des Wehklagens, in der Tiefenbahn, in der Holzschlundfeste und in
Onyxias Hort meldete Sku eine leere Wegpunktliste, obwohl die Zone vollstaendig
kartiert ist. Zwei Beobachtungen grenzten es ein: eine bereits laufende Route lief
weiter, und von ausserhalb der Zone liessen sich dieselben Wegpunkte anwaehlen. Es
fehlten also keine Daten - Sku wusste nur nicht, in welcher Zone der Charakter steht.
Auf deutschen und englischen Clients trat das nie auf.
Technisch: Zwei unabhaengige Ursachen mit demselben Symptom, beide von Naxedim auf einem
franzoesischen Client gefunden, behoben und im Spiel geprueft (PR #8). Erstens
vergleicht SkuNav/Geo.lua eine Handvoll Zonennamen WOERTLICH mit
GetMinimapZoneText(); vier davon waren in locales/frFR.lua frei uebersetzt worden,
also traf kein Vergleich mehr, und GetBestMapForUnit lieferte die Kontinentkarte
statt der Zonenkarte. Die neuen Werte stammen aus C_Map.GetAreaInfo() auf einem
franzoesischen Client, nicht aus einer Uebersetzung. Zweitens haengen Instanzen,
deren echte Area-Zeile in SkuDB/assets/maps.lua auskommentiert ist, an einer
synthetischen Zeile (id ab 100000), fuer die C_Map nichts aufloesen kann; sie blieb
englisch, waehrend der letzte Fallback von GetCurrentAreaId sie gegen den
lokalisierten KARTENnamen prueft - kein Treffer, keine AreaId, kein Kontinent, leere
Liste. Diese Zeilen bekommen ihren Namen jetzt von der uiMap mit demselben
englischen Namen; auf franzoesisch sind das genau zwei, Onyxias Hort und die Hoehlen
des Wehklagens. Danach ergaenzt: eine Sperre, damit dabei keine synthetische Zeile
einen Namen erhaelt, den eine echte Zeile schon traegt (Tausendwinter), die
Markierung "nicht frei uebersetzen" an allen woertlich verglichenen Zonennamen in
locales/enUS.lua, und ein franzoesischer Uebersetzungsspeicher, der ueber den
Schluessel statt ueber die Zeilennummer gefuehrt wird - er war um eine Zeile
verrutscht und haette bei der naechsten Neugenerierung fast die ganze Tabelle
verschoben.
Nebenbei fuer englische Clients: L["Die Hoehlen des Wehklagens"] stand auf "The Wailing
Caverns", was kein Client so sagt. Derselbe Sonderfall war dort also ebenfalls tot
und ist jetzt korrigiert.
Questmenue: "Gruppenmitglieder" haengt sich hinten an
Einfach: Mit geladenem Questie zeigt Sku in einer Gruppe zusaetzlich die Quests der
Mitspieler an. Dieser Eintrag stand bisher zwischen "Aktuelle Quests" und
"Questdatenbank" - und weil er mit der Gruppe kommt und geht, rutschte die
Questdatenbank je nach Gruppenstatus zwischen Platz zwei und Platz drei hin und
her. Wer den Weg dorthin im Muskelgedaechtnis hat, landete solo woanders als in
der Gruppe. Jetzt steht "Gruppenmitglieder" immer ganz hinten an dritter Stelle;
die ersten beiden Eintraege bleiben an derselben Stelle, allein wie in der Gruppe.
Technisch: In SkuQuest:MenuBuilder wandert der bedingte tSpecs-Block (showGroupQuests +
QuestieReady + IsInGroup) hinter den "Questdatenbank"-Block. SkuMenu:Build rendert
die Specs in Array-Reihenfolge ohne jede Sortierung, die Reihenfolge im Quellcode
ist also die Reihenfolge im Menue. Am Eintrag selbst, an seiner Bedingung und an
seinen Untermenues aendert sich nichts.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v43.0
Ueberblick
Neu
Shift-F9 bis Shift-F12 haben jetzt eigene Eintraege in der Tastenbelegung, die Schnellzugriffe 1 bis 4 sind wieder frei.
Die Ansagen im Taxiflug lassen sich abschalten, und sie nennen nie mehr den Start- oder Zielpunkt als Landemoeglichkeit.
Neue Aura-Bedingung "Buff Debuff nur selbst gewirkte" filtert die Buff- und Debufflisten auf Effekte, die du selbst gewirkt hast.
Neuer Befehl /skucheck prueft feste Regeln gegen den laufenden Spielzustand; er hat auch die Datenbank-Werkzeuge als Unterbefehle uebernommen (wp, db, mem).
Der Installer sammelt auf Knopfdruck alle Logdateien fuer eine Fehlermeldung.
Der Anmeldebildschirm ist mit dem Anmelde-Tool jetzt bedienbar.
Wegpunktlisten sagen an, wie weit das Laden fortgeschritten ist.
Aenderungen
Auren-Ablaufwarnungen kommen puenktlich statt erst beim naechsten Kampfereignis.
Die Aurenauswertung pro Kampfereignis ist deutlich billiger geworden.
Navigation abbrechen liegt nur noch auf einer Taste.
Der Energiemonitor kann der Ressourcenleiste folgen, die das Spiel gerade zeigt - ein Druide bekommt so je nach Gestalt Mana, Wut oder Energie.
Das Protokoll des Anmelde-Tools ueberlebt einen Neustart des Tools.
Die Wegpunktdaten der Routen sind nach dem Anmelden deutlich frueher benutzbar, der eigene Kontinent zuerst, und brauchen rund 22 MB weniger Arbeitsspeicher; der Teil der Routendaten, den die eigene Spielversion nicht liest, wird gar nicht mehr aufgebaut.
Auren sind jetzt international austauschbar: eine Aura wirkt auf jedem Sprachclient.
Geteilte Aurensets kommen bei Mitspielern anderer Sprache benutzbar an.
Alle Raenge eines Zaubers zaehlen fuer eine Aura als ein Eintrag.
Zaubernamen, die im Spiel mehrfach vergeben sind, lassen sich in den Auswahllisten jetzt unterscheiden.
Die mitgelieferten Aurensets gibt es nicht mehr nur auf deutschen Clients.
Das Menue zum Anlegen einer Aura ist neu aufgebaut: nach Namen sortierte Attributliste, Bedingungen mit zwei Werten als Schalter, Zauber auch tippbar statt nur waehlbar, und alle Wertelisten oeffnen schneller.
Jeder Menueeintrag im ganzen Addon wird rund 13 mal guenstiger erzeugt; die grossen Zauberlisten oeffnen dadurch etwa dreimal so schnell.
Eine Liste, deren Aufbau vom Server abgebrochen wurde, wird im naechsten Frame weitergebaut statt unbemerkt unvollstaendig zu bleiben.
Einstellungen mit zwei Werten sagen ihren Wert gleich mit und schalten mit Enter um; Pfeil rechts und das Untermenue entfallen.
Die Lautstaerkeregler im Sku-Menue stellen die Spieleinstellung direkt ein; Sku speichert keine eigene Kopie mehr.
Fehlerbehebungen
Franzoesische Clients: alle Aura-Sounds und aufgenommenen Sprachclips waren stumm (Korrektur von Naxedim).
Franzoesische Clients: die Entfernungspruefung sagte nichts an und ihr Menue warf einen Fehler (Korrektur von Naxedim).
Franzoesische Clients: zwei Nachzuegler aus demselben Bericht behoben.
Neun Uebersetzungstexte bedeuteten je nach Sprache etwas anderes (Korrektur von ZenqFR).
Auren: manche Gruppenplaetze wurden als Piepser statt als Wort angesagt.
Auren: eine Aura mit "einmal" konnte im dichten Kampf mehrfach hintereinander feuern.
Menue: die Wegpunktliste auf Shift-F9 oeffnete sich auf grossen Karten erst beim zweiten Versuch.
Die Schluessel im Schluesselbund wurden als "Leer" angesagt.
Auf Hardcore-Realms baut Sku seine Wegpunktdaten jetzt fertig statt still stehenzubleiben.
Navigation: die Routenliste konnte leer und stumm bleiben, wenn die Wegpunktdaten waehrend eines offenen Menues neu aufgebaut wurden.
Fehlende Routendaten werden jetzt gemeldet, statt als leere Liste zu erscheinen.
Ein Popup, das im Kampf aufging (Gruppeneinladung, Beschwoerung, Wiederbeleben), liess sich lesen, aber nicht beantworten.
Eine Route liess sich nicht starten, wenn ihre Liste waehrend des Ladens fertig wurde.
Das Anmelde-Tool hielt den Anmeldebildschirm faelschlich fuer die Charakterauswahl.
Anmelde-Tool: Auf Realms mit zehn oder mehr Charakteren war die Charakterliste unvollstaendig, falsch nummeriert oder liess sich nicht zurueckblaettern.
Energiemonitor: die Ressourcenauswahl "nichts" warf laufend Lua-Fehler.
Energiemonitor: ein im Funktionsmenue abgeschalteter Monitor sagte Ressourcenaenderungen trotzdem an.
Franzoesische Clients: die Liste der Waffenverzauberungen fuer Auren war leer.
Der Bereitschaftscheck sprang nicht direkt auf "Bereit", wie es jedes andere Popup tut.
Eine im Sku-Menue gesetzte Spiel-Lautstaerke konnte auf einem anderen Charakter wieder auf einem alten Wert stehen.
Die vier Standardprofile werden angelegt, ohne dazwischen das Profil zu wechseln - auf Hardcore-Realms konnte man dabei in einem fremden Profil landen.
Mit Dank an Naxedim und ZenqFR
Die naechsten vier Korrekturen sind die ersten direkten Code-Beitraege zum inzwischen
oeffentlichen Sku-Repository. Naxedim hat die beiden Fehler gefunden, analysiert und
behoben, die auf franzoesischen Spielclients grosse Teile der Sku-Audioausgabe stumm
geschaltet hatten; ZenqFR hat die Uebersetzungsdateien geprueft, alle widerspruechlichen
Duplikate auf der englischen und franzoesischen Seite aufgeloest und das Werkzeug
verbessert, das vor neuen schuetzt. Die volle Anerkennung fuer diese Korrekturen gebuehrt
den beiden.
Franzoesische Clients: alle Aura-Sounds und aufgenommene Sprachclips waren stumm (Korrektur von Naxedim)
Einfach: Auf einem franzoesischen Spielclient spielte seit v42.11 jede Aura, deren Ausgabe
ein Sound ist, gar nichts mehr ab - kein Fehler, keine Logzeile, einfach Stille - und
jeder aufgenommene Sprachclip fiel unbemerkt auf reines TTS zurueck. Die Ursache: Seit
Sku franzoesisch spricht, sucht es auch ein FRANZOESISCHES Sprachpaket, und ein solches
Paket gibt es nicht, also fand die Suche nichts und alles, was das Sprachpaket
bereitstellt, verstummte. Sprachausgaben wurden nur zu TTS herabgestuft, aber ein
Soundeffekt hat nichts, worauf er zurueckfallen koennte - deshalb fuehlte es sich an
wie "meine Auren gehen nicht mehr" statt "die Audioausgabe hat sich geaendert". Die
Paketsuche nutzt jetzt denselben englischen Rueckfall, den der Rest des Audiosystems
seit v42.09 verwendet. Deutsche und englische Clients sind vollstaendig unberuehrt.
Technisch: Der Sprachpaket-Resolver in Core.lua verglich die Paket-Locales mit Sku.Loc;
seit v42.11 locales/frFR.lua mitliefert, ist Sku.Loc auf franzoesischen Clients
"frFR", kein Paket konnte das deklarieren, Sku.AudiodataPath blieb "" und
VoicePackAudioDir() lieferte nil - stumm wurden damit alle 64 Eintraege von
SkuCore.outputSoundFiles (Aura-Sounds, SkuMob-Kampfsound, SkuChat-Zeilensound) plus
jeder Sprachclip des Pakets. Verglichen wird jetzt Sku.LocAudio oder Sku.Loc, exakt
die "auf welche aufgenommene Sprache falle ich zurueck"-Regel, die
IntegratedAudioDir() bereits nutzt; Sku.LocAudio ist auf jedem nicht-deutschen Client
"enUS", deDE/enUS verhalten sich also byte-identisch. Auf einem echten franzoesischen
Client gefunden, behoben und im Spiel verifiziert von Naxedim (PR #5).
Franzoesische Clients: die Entfernungspruefung sagte keine Distanzen mehr an und ihr Menue warf einen Fehler (Korrektur von Naxedim)
Einfach: Auf einem franzoesischen Client sagte die Entfernungspruefung keinerlei Distanz
mehr an, egal bei welchem Ziel, und das Oeffnen des Entfernungs-Menues erzeugte einen
Fehler statt des Menues. Zwei Ursachen, beide nur franzoesisch: Erstens wird die
Einstellung "Distanz sprechen" als uebersetztes WORT fuer "Gesprochen" in der
Konfiguration gespeichert - eine Konfiguration, die geschrieben wurde, als Sku noch
englisch lief (vor v42.11), enthaelt das englische Wort, das der jetzt franzoesische
Client nicht mehr erkennt. Zweitens existieren die Zahlenclips nur auf Deutsch und
Englisch, und der Code zaehlte genau diese beiden Sprachen auf - ein franzoesischer
Client bekam also selbst mit frisch geschriebener franzoesischer Konfiguration
Stille. Der gespeicherte Marker wird jetzt in allen drei Sprachen akzeptiert, ein
unbekannter Wert kann das Menue nicht mehr zerlegen, und die Clips fallen wie der
Rest des Audiosystems auf die englischen Aufnahmen zurueck. Deutsche und englische
Clients sind unveraendert: gleicher Marker, gleiche Clips, gleiche Audioausgabe.
Technisch: Ein neues RangeCheck:IsSpokenSound() akzeptiert "Gesprochen"/"Spoken"/"Parlé"
(plus das live uebersetzte L["vocalized"]), genutzt von DoRangeCheck und dem
Menuebauer in Options.lua - letzterer lief bei unbekanntem Wert bisher in den
else-Zweig und verkettete nil aus SkuCore.RangeCheckSounds, was den Fehler warf. Der
Clip-Ordner kommt jetzt aus Sku.LocAudio (hans_de-de fuer deDE, sonst hans_en-us)
statt aus einer Sku.Loc-Kette, die auf frFR keinen Zweig traf. Neue Eintraege
schreiben weiter L["vocalized"]; keine Datenmigration. Auf einem echten
franzoesischen Client gefunden und verifiziert von Naxedim (PR #6).
Uebersetzungen: neun Texte bedeuteten je nach Sprache etwas anderes (Korrektur von ZenqFR)
Einfach: Neun Texte standen doppelt mit zwei VERSCHIEDENEN Bedeutungen in den
Uebersetzungsdateien, und jede Sprache konnte am Ende eine andere der beiden
erwischen. Am hoerbarsten auf englischen Clients, wo mehrfach der falsche Zwilling
gewann: Die Haltungs-Aktionsleiste wurde als "Special Action bar" angesagt (eine ganz
andere Leiste), die Debug-Taste als "debug mode" statt "debug output", eine
Menuekategorie als "Features" statt "Values". Fuer jedes Paar wurde anhand der
Verwendung im Code die tatsaechlich richtige Bedeutung bestimmt und der falsche
Zwilling in allen drei Sprachen geloescht - Englisch, Deutsch und Franzoesisch sind
sich bei allen neun jetzt einig. Sechs rein deutsche Duplikate bleiben bewusst offen,
bis ein deutscher Muttersprachler entscheidet.
Technisch: AceLocale loest doppelte Schluessel fuer die Standardsprache (enUS) nach
"erster gewinnt" auf, ueberall sonst nach "letzter gewinnt" - ein Duplikat mit zwei
Werten bedeutet also still etwas anderes pro Sprache. ZenqFR hat fuer jeden Schluessel
die echten Aufrufstellen verfolgt, um den ueberlebenden Wert zu bestimmen (PR #3),
und dev/rework-docs/_locale_dupes.py beigebracht, nur das geparste
Lua-String-Literal statt der rohen Zeile zu vergleichen, damit angehaengte
"--"-Kommentare nicht mehr als Konflikt zaehlen (PR #4) - von 64 gemeldeten
Konflikten waren nur 30 echt; enUS und frFR linten jetzt auf null, deDE auf die sechs
deutschen Formulierungspaare, die einem Muttersprachler ueberlassen bleiben.
Franzoesische Clients: zwei Nachzuegler aus Naxedims Sprachpaket-Bericht
Einfach: Der Sound namens "bring" - eine Glocke, benannt nach ihrem Klang - stand in
franzoesischen Menues als "apporter": Die Uebersetzung hatte ihn als das englische
Verb "to bring" gelesen. Es ist ein Name, kein Wort, und bleibt jetzt wie seine
unuebersetzten Geschwister "brang", "dang" und "drmm" einfach "bring". Ausserdem
nennt die interne Diagnose, die festhaelt, welches Sprachpaket gefunden wurde, jetzt
die tatsaechlich gesuchte Sprache statt der Client-Sprache - vorher haette ein
franzoesischer Client ohne installiertes englisches Paket "no voice pack found for
frFR" behauptet und damit auf ein Paket gezeigt, das es gar nicht geben kann.
Technisch: locales/frFR.lua setzt L["bring"] auf die Onomatopoesie zurueck. Core.lua
setzt Sku.AudiodataPathInfo jetzt in einem else-Zweig des Resolvers aus tWantedLoc
(dem Sku.LocAudio-basierten Suchschluessel) plus der Client-Locale; auslesbar per
/wdeval Sku.AudiodataPathInfo. Der dritte Punkt aus dem PR-#5-Bericht - frFR
uebersetzt das Ausgabe-Label-Praefix zu "aura;son" - wurde geprueft und bewusst
BEHALTEN: Jede Vergleichsstelle baut das Praefix zur Laufzeit aus der aktiven
Locale-Tabelle, und gespeicherte Einstellungen/Auren halten Identifier-Schluessel
("sound-brass1"), nie das Label - die Uebersetzung ist also sicher; franzoesisches
TTS fuer ein franzoesisches Label ist besser als ein englischer Clip.
Taschen: die Schluessel im Schluesselbund wurden als "Leer" angesagt
Einfach: Seit v42.13 sprach jeder Platz im Schluesselbund "Leer", obwohl die Schluessel da
waren und sich weiter benutzen liessen - aufgefallen ist es erst, als jemand den
Schluesselbund wirklich brauchte. Ausgeloest hat es die Bankkorrektur aus v42.13: Der
Schluesselbund hat im Spielclient dieselbe Eigenheit wie das Bankhauptfach und brauchte
dieselbe Sonderbehandlung, die damals nur die Bank bekommen hat. Jetzt werden die
Schluessel wieder mit Namen angesagt. Ausserdem zeigt der Schluesselbund nur noch so
viele Plaetze, wie er wirklich nutzt, statt stur alle 32 - vorher kamen nach den
Schluesseln Dutzende leere Plaetze.
Technisch: GameTooltip:SetBagItem(-2, slot) befuellt auf dem Client nichts, genau wie beim
Bankcontainer -1. Die Schluesselnamen funktionierten nur ueber den generischen
SetHyperlink-Rueckfall aus 67f2132; als v42.13 diesen Rueckfall absichtlich entfernte
und nur die Bank (-1) auf SetInventoryItem umstellte, fiel der Schluesselbund still auf
das leere SetBagItem zurueck. tSetTooltipContainerItem liest -2 jetzt ueber
SetInventoryItem("player", KeyRingButtonIDToInvSlotID(slot)) - exakt das, was Blizzards
eigenes ContainerFrameItemButton_OnEnter fuer den Schluesselbund tut. Build_BagsFrame
begrenzt die Platzzahl von -2 zusaetzlich mit GetKeyRingSize() (belegte Plaetze auf
volle Viererreihen gerundet), so wie Blizzards Schluesselbund-Fenster, statt die rohen
32 aus GetContainerNumSlots zu uebernehmen.
Diagnose: neuer Befehl /skucheck prueft feste Regeln gegen den laufenden Spielzustand
Einfach: /skucheck geht alle Taschendaten durch und prueft, ob jeder belegte Platz einen
ansagbaren Namen liefert; das Ergebnis kommt als eine gesprochene Zeile, etwa
"Taschenpruefung: 64 geprueft, keine Probleme", bei Problemen mit Verweis auf das Log.
Der Befehl prueft die Daten selbst, nicht die Menues - er haette den
Schluesselbund-Fehler also auch gemeldet, wenn man den Schluesselbund nie oeffnet. Die
Pruefliste waechst nur mit behobenen Fehlern: Jede Korrektur bringt kuenftig ihre
eigene Stolperdraht-Regel mit, damit eine spaetere Aenderung denselben Fehler nicht
unbemerkt wieder einbauen kann. Seit dieser Version ist /skucheck ausserdem der
einzige Pruefbefehl: Die drei Datenbank-Werkzeuge sind Unterbefehle geworden -
/skucheck wp prueft die Wegpunktdaten und laeuft bei einem blossen /skucheck
automatisch mit, /skucheck db und /skucheck mem sind Messungen und laufen nur auf
Anforderung. Die alten Namen /skudbwpcheck, /skudbcheck und /skudbmem funktionieren
weiter.
Technisch: Am Ende von LocalMenu.lua; laeuft ueber tBagSlotListSorted mit derselben
Container-API und derselben Namensaufloesung wie das Taschenmenue. Regel 1: Platz mit
Item-Id, aber leerem Tooltiptext = Verstoss; jeder Verstoss landet als "skucheck"-Zeile
mit Tasche, Platz, Item-Id und Link im SkuDebugLog-Ring. Die geschlossene Bank wird mit
Logzeile uebersprungen (nicht still), der Schluesselbund absichtlich mit allen rohen 32
Plaetzen geprueft, und noch nicht vom Server geladene Items zaehlen als "ausstehend"
statt als Fehler. Die Domaenen wp/db/mem rufen
SkuDBTools.RunWpCheck/RunDbCheck/RunMem (SkuDBTools.lua); sie laufen als
Hintergrundjob und sagen ihr Ergebnis selbst an, schreiben es aber zusaetzlich als
"skucheck"-Zeilen in den Ring - die Wegpunkt-Verstoesse einzeln, die vorher nur in
den SavedVariables lesbar waren. /skucheck db meldet zusaetzlich, wie viele
Datensaetze sich gegenueber der vorherigen Aufnahme geaendert haben. Grund fuer die
Zusammenlegung: Mit drei getrennten Befehlen liess sich "die Pruefung" laufen
lassen und die Wegpunktregeln dabei komplett verfehlen.
Auren: Ablauf-Warnungen kommen puenktlich, nicht erst beim naechsten Kampfereignis
Einfach: Zwei alte Beschwerden hatten dieselbe Ursache: Eine Aura wie "Debuff auf dem Ziel
unter 3 Sekunden" oder "mein Debuff ist vom Ziel abgefallen" wurde nur dann neu
geprueft, wenn irgendein anderes Kampfereignis eintraf. In einem reinen Nahkampf kam
die Warnung deshalb bis zu einem ganzen Waffenschlag zu spaet, ausserhalb des Kampfes
um Minuten - oder gar nicht vor dem Ablauf. Jetzt merkt sich Sku beim Pruefen des
Effekts, WANN die Schwelle erreicht sein wird, und weckt die Pruefung genau in diesem
Moment; auch das Erscheinen oder Wegfallen eines Effekts selbst stoesst die Pruefung
direkt an. Ausserdem duerfen die gesprochenen Woerter einer Aura jetzt wie die
Signaltoene an wartenden Ansagen vorbeiziehen - sie unterbrechen nichts und
ueberlappen nichts, sie stellen sich nur nicht mehr hinten an.
Waffenverzauberungs-Warnungen profitieren mit: statt bis zu einer Sekunde Verzug
feuern sie jetzt auf den Frame genau.
Technisch: Drei Mechanismen: (1) Termin-Planer in SkuAuras/Core.lua - jeder
Auswertungslauf merkt sich in tNextDurationDeadline den fruehesten
Schwellen-Zeitpunkt (expirationTime minus Schwelle) aller aktiven Dauer-Bedingungen
(kleiner-Operator); der Frame-Treiber vergleicht pro Frame eine Zahl und feuert dann
EINEN synthetischen DURATION_DEADLINE-Lauf. Ersetzt die sekuendliche
Naeherungs-Neupruefung der Waffenverzauberungen. (2) UNIT_AURA stoesst bei echter
Mengen-Aenderung der Effekte (dazu/weg, nicht bei Stapel- oder Dauer-Updates) eine
Auswertung an - Namens-Diff gegen einen Schnappschuss, entprellt gegen
Kampflog-Laeufe im selben Frame und gegen Zielwechsel. (3) Die Wort-Ausgaben nutzen
den vorhandenen, aber nie angeschlossenen aInstant-Pfad von OutputString (Einfuegen
vorne statt hinten); ein Frame-Cursor haelt mehrteilige Ausgaben in Sprechreihenfolge.
Auren: Auswertung pro Kampfereignis deutlich verbilligt
Einfach: Im Schlachtzug wertet Sku Auren hunderte Male pro Sekunde aus. Mehrere
versteckte Kostentreiber sind raus: Bedingungen wurden doppelt geprueft, Restdauern
bei jedem Ereignis neu vom Client erfragt, und fuer jedes Ereignis wurde die komplette
Gruppe per Einzelabfrage durchsucht. Nebenbei zwei stille Fehler behoben: Eine Aura
ohne "Zauber auf Abklingzeit"-Bedingung konnte den Abklingzeit-Namen einer ANDEREN
Aura ansagen, und Gegenstands-Abklingzeiten wurden bei jeder Taschenaenderung neu
gestempelt. /skucheck kennt dafuer jetzt die Domaene "auras" und prueft, dass die
Auswertung keine Globals mehr schreibt.
Technisch: Einmal auswerten statt doppelt (der einwertige Zweig der Attributschleife lief
versehentlich zweimal; dazu zwei geleakte Globals, tSpellNameOnCdValue injizierte
veraltete Werte quer ueber Auren). Restdauern kommen aus einer
expirationTime-Erweiterung des Tier-2-Listencaches statt aus UnitAura-Neuscans
(/skuauracache verify prueft jetzt auch die exp-Werte, /skuauracache off schaltet
beides ab). Gruppen-GUIDs loesen ueber eine bei Roster-Ereignissen invalidierte Karte
auf statt ueber raid1..40-Schleifen pro Ereignis (Ergebnis-Reihenfolge und das
historische raid1..25-Fenster des RoleCheckers bleiben exakt erhalten).
targetUnitDistance und targetTargetUnitId sind lazy, LogRecorder macht einen
Settings-Zugriff statt vier, und der UNIT_INVENTORY_CHANGED-Wachausdruck prueft die
echte itemID statt eines nil-Globals.
Installer: eine Taste sammelt alle Logdateien fuer eine Fehlermeldung
Einfach: Der Installer hat auf seinem Startbildschirm eine neue Taste "Alle Protokolle
sammeln". Sie legt EINE ZIP-Datei im Downloads-Ordner an, die alles enthaelt, was zur
Fehlersuche gebraucht wird - und zwar fuer ALLE gefundenen Spielversionen auf einmal,
nicht nur fuer eine: Skus Debug- und Fehlerprotokoll, die Aufzeichnungen von
BugGrabber/BugSack und WVDebug, die Protokolle des Spiels selbst samt seiner
Lua-Fehler, die CVar-Datei Config.wtf, eine Liste aller installierten Addons mit
Version, das Protokoll des Anmelde-Tools und das des Installers. Bisher musste man
diese Dateien einzeln aus drei verschiedenen Verzeichnisbaeumen zusammensuchen, und wer
eine davon vergass, bekam eine Rueckfrage statt einer Antwort. Die Datei heisst
Sku-Logs-.zip, der Installer nennt den vollstaendigen Pfad und oeffnet den
Ordner mit der bereits ausgewaehlten Datei, so dass sie sich direkt an eine
Fehlermeldung anhaengen laesst. Eine typische Sammlung sind rund 7 MB.
Technisch: Neue Datei LogCollector.cs im Installer, angestossen von einer vierten Taste in
UpdatePromptForm (Beschriftung und Vorlesetext in allen drei Sprachen). Gesammelt wird
pro Client in einen eigenen Unterordner: SavedVariables aus der Konto- UND der
Charakterebene (Sku legt beides an) einschliesslich der .bak-Zweitkopien - die sind der
Stand der VORIGEN Sitzung und damit oft die einzige noch vorhandene Fassung des
Debug-Rings, ueber den berichtet wird -, dazu Logs, Errors, Config.wtf, Sku.toc,
.build.info und eine Addon-Liste mit TOC-Versionen und Symlink-Markierung. Dazu kommen
system-info.txt (Betriebssystem, Sprache, ein Block je Client und eine Liste dessen,
was NICHT mitkam und warum - eine Auslassung soll als Auslassung lesbar sein und nicht
als Abwesenheit) sowie das Installerprotokoll, das dafuer erst aus Loggers
Speicherpuffer auf die Platte gezwungen wird. Der Ordner Errors ist bewusst von der
30-Tage-Altersgrenze ausgenommen - dort steht nur etwas, wenn wirklich etwas kaputt
ging, und der erste Testlauf lieferte sonst null von 21 vorhandenen Absturzberichten -
und stattdessen auf die 25 neuesten begrenzt. Der Installer traegt damit die Version
4.2.
Anmelde-Tool: das Protokoll ueberlebt jetzt einen Neustart des Tools
Einfach: Das Anmelde-Tool loeschte sein Protokoll bei JEDEM Start. Wer also auf einen
Fehler stiess, das Tool schloss und es noch einmal oeffnete, bevor er die Logdateien
einsammelte, hatte genau den Nachweis geloescht, um den es ging - und das ist der
haeufigste Ablauf einer Fehlermeldung ueberhaupt. Die letzten fuenf Sitzungen bleiben
jetzt als log-1.txt bis log-5.txt neben dem laufenden log.txt liegen, und die neue
Sammeltaste des Installers nimmt sie automatisch mit.
Technisch: log.ahk schreibt jetzt auf einen ABSOLUTEN, aus dem Skriptort abgeleiteten Pfad
statt auf den relativen Namen "log.txt", der gegen das Arbeitsverzeichnis des
Prozesses aufgeloest wird - START.ahk setzt das zwar passend, aber es ist
prozessweiter Zustand, den jede spaetere Stelle aendern kann, und ein Protokoll an
einem Ort, an dem niemand nachsieht, ist so gut wie keines. ClearLogFile() rotiert
jetzt, statt zu loeschen. Verpackung und .gitignore schliessen log-*.txt genauso aus
wie log.txt; die Protokolle einer bestehenden Installation werden bei einem Upgrade
nicht angetastet.
Anmelde-Tool: der Anmeldebildschirm meldete sich als Charakterauswahl
Einfach: Wenn das Spiel beim Start keine Verbindung zum Server bekommt, landet man nicht
in der Charakterauswahl, sondern auf dem Anmeldebildschirm mit Accountname, Passwort
und Login-Knopf. Das Tool fuehrte dort ins Hauptmenue, dessen erster Eintrag
"Charakter auswaehlen" heisst - ausgerechnet der Bildschirm, der beweist, dass es
gerade gar keine Charakterliste gibt, sagte sich also als Charakterauswahl an. Wer ihn
nicht sehen kann, hoerte nichts, was ihn von der echten Charakterauswahl unterschieden
haette. Das Tool sagt jetzt beim Ankommen einmal: nicht angemeldet, entweder besteht
keine Verbindung zum Server oder Accountname und Passwort muessen im Spiel noch
eingegeben werden. Und es merkt jetzt auch, wenn der Bildschirm gewechselt wird: wer
sich von Hand anmeldet, bekommt die Charakterliste sofort gebaut, statt das Tool stumm
auf dem alten Menue stehen zu lassen.
Technisch: "Keine Verbindung" ist KEIN eigener Bildschirm - am laufenden 2.5.6-Client
geprueft, er ist pixel- und OCR-identisch mit einem normalen Anmeldebildschirm
(gleiche Widget-Proben, checks.login = true, kein Popup). Es gibt also nichts zu
markieren; angesagt wird nur, was auf diesem Bildschirm immer stimmt: dieser Client
ist nicht angemeldet. Das Menue ist jetzt ein eigener Baum statt des Hauptmenues, und
InitLogin lief bisher nur beim MODUSwechsel, weshalb ein Bildschirmwechsel unbemerkt
blieb; der Waechter loest jetzt eine volle Neuinitialisierung aus, sobald der
Anmeldebildschirm betreten oder verlassen wird.
Anmelde-Tool: der Anmeldebildschirm ist jetzt bedienbar
Einfach: Das Menue auf dem Anmeldebildschirm fuehrt jetzt mit den Bedienelementen des
Bildschirms selbst: Accountname, Passwort, Anmelden, Accountnamen speichern - und
danach unveraendert Stimme, Sprache, Spieltyp, Region und Version, damit die
Einstellungen auch dann erreichbar bleiben, wenn die Anmeldung scheitert. Das Tool
speichert dabei NICHTS und tippt nichts: es setzt nur den Cursor des Spiels in das
Feld und gibt die Tastatur an den Client weiter, getippt wird von Hand. Einen
Autologin gibt es nicht und wird es nicht geben. Der Accountname wird vorgelesen,
leer als "leer"; das Passwort wird NIE vorgelesen. Solange die Tastatur an einem Feld
haengt, gehen die Pfeiltasten ans Spiel, damit man einen Tippfehler auch erreichen
kann; Enter beendet die Eingabe, Escape verlaesst sie, und keins von beiden wird ans
Spiel weitergereicht - Anmelden ist ein eigener Eintrag, damit nichts versehentlich
abgeschickt wird. Meist ist Battle.net schliessen und neu oeffnen der schnellere Weg;
der manuelle Weg ist fuer die Faelle da, in denen man ihn will.
Technisch: Vier neue Widgets in data.ini ([Classic] und [BurningCrusade]):
LoginAccountField 10000,403, LoginPasswordField 10000,478, LoginSubmitButton
10000,531 und LoginSaveAccountCheckbox 26,662 - am laufenden Client bei 2880x1800
vermessen und in den 768er UI-Raum umgerechnet, also aufloesungsunabhaengig, und
gegen bereits vorhandene Eintraege gegengeprueft ("Account erstellen" gemessen 549
gegen die gespeicherten 550). Der Feldinhalt wird per OCR NUR des Feldes gelesen,
damit kein Label von woanders als Inhalt durchgeht. "Anmelden" verfolgt den Versuch:
einbuttonige Fortschrittsdialoge werden vorgelesen und NICHT geklickt, weil ihr
einziger Knopf Abbrechen ist und die laufende Anmeldung trennt - dieselbe Falle wie
beim Realmbeitritt; zweibuttonige Dialoge werden vorgelesen und beantwortet. Wo die
Widgets fehlen (Cata, Retail), sagen die Eintraege das und tun nichts.
Anmelde-Tool: die Charakterliste auf Realms mit zehn oder mehr Charakteren
Einfach: Die Charakterleiste zeigt genau neun Charaktere gleichzeitig. Ab dem zehnten
blaettert die Liste, und damit ging alles auf einmal schief: Charaktere fehlten, die
Nummerierung passte nicht zur tatsaechlichen Liste, und der Weg zurueck an den Anfang
der Liste klappte nicht zuverlaessig. Alle drei haben dieselbe Ursache. Das Tool
laeuft die Liste mit den Pfeiltasten ab und beobachtet dabei, wie sich die
Auswahlleiste bewegt - sobald die Liste blaettert, bewegt sie sich aber nicht mehr,
und "nichts hat sich geaendert" wurde als "hier endet die Liste" gelesen. Ein vom
Spiel verschluckter Tastendruck sieht genau gleich aus, und der hat die Listen
abgeschnitten. Mit neun Charakteren oder weniger blaettert die Liste nie, deshalb war
davon nie etwas zu sehen. Das Tool fragt jetzt zweimal nach, bevor es ein Listenende
glaubt, und zieht den grossen Charakternamen unter dem Charaktermodell zur
Entscheidung heran - der zeigt den ausgewaehlten Charakter, egal wie weit die Liste
gescrollt ist. Ausserdem sagt es alle zehn Charaktere den Stand an, weil eine lange
Liste sonst eine halbe Minute Stille ist, und das Menue bleibt waehrend des Neuaufbaus
bedienbar statt tot. NICHT GETESTET im Spiel: Hier gibt es keinen Realm mit mehr als
neun Charakteren. Sollte die Liste weiterhin falsch sein, benennt das Log des Tools
jetzt genau die Entscheidung, die schiefging.
Technisch: Gegen den Interface-Quelltext des Clients selbst geprueft. Blizzard_GlueXML_TBC.toc
laedt Vanilla\CharacterSelectConstants.lua mit CHARACTER_SELECT_MAX_CHARACTERS = 9,
und CharacterSelect_OnShow setzt MAX_CHARACTERS_DISPLAYED darauf. Jede Abbruch-
bedingung im Walk, die auf EINER Beobachtung beruhte, braucht jetzt zwei mit
laengerer Wartezeit dazwischen und drueckt erst dann erneut, wenn ein Blick bewiesen
hat, dass sich nichts bewegt hat - ein zweiter Druck auf einen bereits angekommenen
Schritt ueberspringt spurlos einen Charakter. Die Umbruch-Erkennung verlangt jetzt
exakt Slot 1, denn CharacterSelectScrollDown_OnClick setzt nach dem letzten Charakter
CHARACTER_LIST_OFFSET = 0 und dann SelectCharacter(1); ausserdem wird das
Zurueckscrollen abgewartet, bevor bestaetigt wird. Der Notbehelf, der nur den
sichtbaren Ausschnitt liest, faehrt jetzt zuerst nach oben, denn
UpdateCharacterSelection setzt den Offset auf selectedIndex -
MAX_CHARACTERS_DISPLAYED, sobald der zuletzt gespielte Charakter unter der Kante
sitzt - die neun sichtbaren Zeilen waren dann Charakter 6 bis 14, angesagt als 1 bis
9. Die Pixelproben der Auswahlleiste wurden nach links verschoben: ab zehn Charakteren
verbreitert UpdateCharacterList die Leiste von 260 auf 280 und blendet eine Scrollbar
ein, deren Hintergrund schwarz genau auf dem Streifen liegt, den die Auswahlleiste
freigibt. Das Menue wird jetzt wie die Realmliste losgeloest aufgebaut und in einer
einzigen Zuweisung veroeffentlicht.
Hardcore-Realms: Sku baut seine Wegpunktdaten jetzt fertig, statt still stehenzubleiben
Einfach: Auf Hardcore-Realms raeumt der Spielclient Addons deutlich weniger Rechenzeit pro
Bild ein als auf normalen Realms. Sku baut direkt nach dem Anmelden seine Wegpunkt- und
Routendaten auf, und genau dieser Aufbau lief dort in diese Grenze: Der Client brach
den laufenden Vorgang einfach ab, und Sku bekam davon nichts mit. Ergebnis: Jede
Wegpunktliste antwortete die ganze Sitzung lang nur mit "Wegpunkte werden noch geladen"
- ohne Fehlermeldung, ohne Sprachausgabe, ohne Logeintrag, und auch ein Neuladen der
Oberflaeche half nicht. Sku merkt jetzt, wenn der Client bremst, verkleinert seine
Arbeitspakete und macht weiter, statt liegen zu bleiben; wird ein Paket doch
abgeschossen, startet der Aufbau von selbst neu. Der Preis dafuer: Auf solchen Realms
dauert es nach dem Anmelden ein paar Sekunden laenger, bis Routen und Wegpunkte
vollstaendig da sind. Alles andere in Sku ist sofort benutzbar, und die Wegpunktlisten
sagen jetzt an, wie weit der Aufbau ist (naechster Eintrag). Normale Realms sind
unveraendert.
Technisch: Der Client meldet den Abbruch als LUA_WARNING "insecure scripts exceeded
execution limit for addon Sku" oder als "script ran too long" mitten im laufenden
Coroutine-Abschnitt. Auf dem Hardcore-Realm kam das bei jedem einzelnen Anmelden
(52/25/25 Meldungen pro Login), in acht aufgezeichneten Sitzungen auf normalen Era- und
Anniversary-Realms kein einziges Mal - bei identischer Arbeit (1936 ms auf Era
gegenueber 1955 ms auf Hardcore fuer denselben Aufbau). Sku:BuildFrameBudgetMs ist
jetzt adaptiv: Jede solche Meldung halbiert die Frame-Obergrenze (150 -> 75 -> 37,5 ->
20 ms), wovon der gesamte Aufbau nach dem Anmelden profitiert, nicht nur der
Wegpunkt-Cache. Getaktet wird der Cache-Aufbau nicht mehr von einer sich selbst neu
setzenden C_Timer-Kette - genau dieses Neusetzen fiel dem Abbruch zum Opfer, die
Coroutine blieb danach fuer immer angehalten und niemand weckte sie wieder - sondern
von einem OnUpdate-Treiber, den der Client selbst in jedem Bild aufruft; ein
abgeschossenes Paket kostet damit ein Bild statt den ganzen Aufbau. Stirbt die
Coroutine trotzdem, wird bis zu dreimal neu aufgebaut, und der Build-Step legt seine
Anforderung zurueck, statt sie in einem pcall zu verlieren.
Navigation: eine Routenliste konnte leer bleiben, ohne zu sagen warum
Einfach: Ein Tester auf einem Hardcore-Realm meldete, dass die Routenliste auf Shift-F10
nur "Liste leer" sagte, obwohl es dort Routen gibt. Dahinter steckten zwei
verschiedene Wege, auf denen eine Liste leer werden konnte, ohne dass irgendetwas
darauf hinwies.
Erstens: Seit Sku seinen Wegpunktaufbau auf Hardcore-Realms notfalls neu startet
(siehe oben), koennen die Wegpunkte waehrend eines geoeffneten Menues ausgetauscht
werden. Eine Liste, die noch aus dem alten Aufbau stammte, zeigte dann auf einen
Wegpunkt, den es nicht mehr gab. Das warf einen Fehler mitten im Aufbau der
Untereintraege, und weil dieser Fehler abgefangen wurde, blieb einfach eine leere
Ebene stehen: keine Eintraege, kein Hinweis, keine Fehlermeldung, nichts zu hoeren.
Zweitens: Fehlten die Routendaten selbst, meldete Sku trotzdem "fertig geladen", und
dann waren alle Routenlisten leer - auch das ohne jeden Hinweis. Beides faellt jetzt
auf: Die Liste antwortet ordentlich, statt stumm zu bleiben, und fehlende Routendaten
werden angesagt wie jeder andere Datenbankfehler.
Technisch: Drei Stellen, alle nach demselben Muster - ein Fehlschlag darf nicht unsichtbar
sein.
1. SkuNav:GetAllMetaTargetsFromWp5 griff ohne Pruefung auf den Startwegpunkt zu
(.worldX). Nach einem Neuaufbau des Wegpunkt-Cache - neu in v43.0, weil der Aufbau
sich auf Hardcore-Realms selbst neu startet und weil CleanupWaypoints Wegpunkte ohne
Verbindungen loescht - kann dieser Name weg sein. Die Funktion liefert jetzt eine
leere Antwort und schreibt eine Logzeile mit der Cache-Generation.
2. SkuOptions:VocalizeCurrentMenuName und der Pfadlaeufer rufen BuildChildren in einem
pcall auf, damit ein defekter Untermenue-Aufbau nie die Ansage des Eintragsnamens
verschluckt. Das bleibt so - aber der Fehler wird jetzt mit Knotennamen protokolliert
und der Knoten markiert (buildChildrenFailed). Ohne das war eine Ebene mit null
Eintraegen von einer Ebene, die wirklich leer ist, nicht zu unterscheiden.
3. Sku:EnsureData uebersprang ein Builder-Global, das keine Funktion ist, kommentarlos
und meldete den Datensatz danach trotzdem als bereit. Genau das ist die schlimmste
Form: Jede Pruefung im Rest des Codes fragt "ist es bereit", nicht "ist es da". Fuer
die Routen endet das mit leeren Verbindungsdaten, geloeschten Routenwegpunkten und
Menues, die seelenruhig "Liste leer" sagen. Jeder fehlende Builder wird jetzt einzeln
protokolliert; fehlen ALLE, gilt der Datensatz als fehlgeschlagen und wird angesagt.
Dazu kommt eine Logzeile in SkuNav:GetAllLinkedWPsInRangeToCoords: Wenn Sku das
aktuelle Gebiet keinem Kontinent zuordnen kann (Hoehlen, die Tiefenbahn, nicht
kartierte Unterzonen), bricht diese Abfrage leer ab - und die Liste sagte dann "Liste
leer", was sich wie eine Aussage ueber die Daten anhoert und keine ist. /skuzoneprobe
weist denselben Fall vollstaendig aus.
Anmelden: die Wegpunktdaten der Routen stehen deutlich frueher bereit
Einfach: Nach dem Anmelden baut Sku alle Wegpunkte und ihre Verbindungen neu auf; bis das
fertig ist, antworten die Wegpunktlisten mit "Wegpunkte werden noch geladen". Mehr als
die Haelfte dieser Wartezeit ging fuer die Verbindungen drauf, und dieselben Daten
wurden dabei viermal durchlaufen. Jetzt ist es ein Durchlauf, und er beginnt mit dem
Kontinent, auf dem ihr gerade steht: Der ist als erstes fertig, und ab diesem Moment
sind eure Listen benutzbar, waehrend der Rest der Welt noch gebaut wird. Wer dabei auf
dem Wartehinweis steht, bekommt den ersten Eintrag automatisch vorgelesen, ohne eine
Taste zu druecken. Auf demselben Rechner gemessen: Der Verbindungsteil kostet noch
etwa die Haelfte, und die Listen des eigenen Kontinents sind rund 0,7 Sekunden frueher
da. An den Routen selbst aendert sich nichts - dieselben Wegpunkte, dieselben
Verbindungen, nur frueher. Dazu braucht die Wegpunktverwaltung jetzt rund 22 MB
weniger Arbeitsspeicher, weil jede Verbindung nicht mehr doppelt gespeichert wird -
auf schwachen Rechnern ist das der spuerbarere Teil. Und ein weiteres Stueck
Wartezeit faellt ganz weg: Sku liefert zwei grosse Routendateien mit, und von der
zweiten braucht die TBC-Fassung nur die Verbindungen. Deren Wegpunkte wurden bisher
trotzdem bei jedem Anmelden aufgebaut und einen Augenblick spaeter ungelesen wieder
weggeworfen; sie werden jetzt gar nicht erst gebaut. Das spart rund eine viertel
Sekunde und rund 21 MB Spitzenspeicher pro Anmeldung - auf Era-Realms, wo die ganze
Datei ungenutzt ist, rund 0,4 Sekunden. Beide Dateien werden weiter vollstaendig
ausgeliefert: Beim spaeteren Wechsel auf Wrath of the Lich King sind genau diese
Daten die richtigen, dann wird andersherum ausgewaehlt.
Technisch: Der Verbindungsteil des Wegpunkt-Cache-Aufbaus lief als VIER volle Durchlaeufe
ueber ~197.000 gerichtete Kanten: pruefen und symmetrisieren
(CheckAndUpdateProfileLinkData), byId/byName materialisieren, die ganze Tabelle aus dem
Cache zurueckrechnen (SaveLinkDataToProfile) und ein Schlussdurchlauf ueber alle
~145.000 Cache-Eintraege (CleanupWaypoints). Jetzt ist es ein Durchlauf: Das Pruefen
laeuft mit, die Gegenrichtung jeder Kante wird direkt in den Zieleintrag geschrieben -
deshalb ist die Reihenfolge der Kontinente egal -, und das Zurueckrechnen entfaellt,
weil es die Tabelle schrieb, die ohnehin schon dasteht. Der einzige Fall, in dem es
doch etwas aendern koennte (ein Endpunkt, dessen Name im Cache zu einem anderen
Eintrag gehoert), wird gezaehlt und loest den alten Weg aus; in den ausgelieferten
Routendaten kommt er nicht vor. Der Schlussdurchlauf bekommt vom Custom-Pass die Liste
der ueberhaupt loeschbaren Eintraege, nach Kontinent sortiert, und laeuft pro
Kontinent, sobald dieser fertig ist. Nebenbei behoben: Der alte Pruefdurchlauf fuegte
waehrend pairs() neue SCHLUESSEL in genau die Tabelle ein, ueber die er lief - in Lua
undefiniertes Verhalten; die Gegenkanten werden jetzt gesammelt und danach eingetragen.
Ausserdem war die im Juli eingebaute Zweiteilung "eigener Kontinent zuerst" beim
Anmelden nie aktiv: Sie ermittelt die Zone ueber GetMinimapZoneText, und die ist beim
Start des Aufbaus noch leer - der Kontinent wird jetzt vor dem Verbindungsteil erneut
ermittelt. Belegt durch einen Nachbau beider Varianten ueber die echten Routendaten
(dev/rework-docs/simulate_link_build.py: gleicher Cache, gleiche Verbindungstabelle,
fuer jeden Kontinent) und im Spiel durch /skucheck wp, das jetzt auch prueft, dass jede
Verbindung ihre Gegenrichtung hat.
Technisch, zweiter Teil: Jede Verbindung lag doppelt im Speicher - einmal unter der
Nummer des Zielwegpunkts (byId) und einmal unter seinem Namen (byName). byName ist
entfallen, alle 14 Fundstellen arbeiten jetzt mit byId; neu ist dafuer
WaypointCacheGetIdForIndex, das Gegenstueck zu WaypointCacheGetIdForName. Der
Schreibweg in die Verbindungstabelle wurde dadurch sogar billiger: Er hat bisher
jeden Zielnamen wieder in eine Id zurueckuebersetzt, jetzt hat er den Datensatz
schon. Gemessen: rund 70.000 Tabellen und 224.000 Zeichenketten weniger, 22 MB
weniger im Speicherbericht (/skucheck mem), und der Verbindungsteil des Aufbaus
wurde noch einmal etwa 40 ms schneller. Warum das doppelt war: eine nie zu Ende
gefuehrte Umstellung - schon in Sku 32.31 steht auskommentiert der Aufruf, der die
byName-Tabelle direkt in die gespeicherte Verbindungstabelle schreiben sollte;
byId kam spaeter als schneller Weg fuer die Routensuche dazu, und beide blieben.
Drei latente Fehler sind mitgegangen: eine Schleife beim Wegpunktloeschen, die nur
den geloeschten Wegpunkt gegen sich selbst aufraeumte, Ids die aus ".areaid" statt
".areaId" gebaut wurden (also immer mit Gebiet 1) und ein Zugriff auf Links[nil]
bei temporaeren Wegpunkten.
Technisch, dritter Teil: Die beiden Routendateien waren je EIN Builder, der die ganze
Datei aufbaute. Gemessen im Spiel: 375 ms fuer die WotLK-Datei und 355 ms fuer die
Basisdatei, jedes Mal. Auf TBC nutzt die Navigation die Wegpunkte der Basisdatei und
von der WotLK-Datei nur die Verbindungen (die Vereinigung beider Graphen, seit
Juli) - LoadDefaultMapData setzte die WotLK-Wegpunkte, -Level und -Sequenznummern
direkt nach dem Verknuepfen wieder auf nil. Das sind 71% der Bytes dieser Datei,
gebaut und ungelesen weggeworfen. Die Dateien werden jetzt pro ABSCHNITT verpackt
(dev/rework-docs/_wrap_deferred.py, Modus "sections"): ein Builder je
Top-Level-Abschnitt von routedata.global, jeder mit einem byte-genauen Ausschnitt
der Originaldaten - das Werkzeug prueft, dass die Ausschnitte wieder exakt die
Ursprungsdatei ergeben, es wird nichts neu serialisiert. SkuDeferredData.lua waehlt
die Builder nach Spielversion (TBC: alle Abschnitte der Basisdatei plus die
WotLK-Verbindungen; Era: nur die Basisdatei) und setzt die uebersprungenen
Builder-Globals auf nil, sonst haengen ihre Quelltext-Konstanten weiter im Speicher.
Neu: /skucheck routes. Die Pruefung ist absichtlich so gebaut, dass ein falsch
gewaehlter Abschnitt laut wird statt still den halben Graphen zu kosten: Nach
EnsureData darf kein einziges SkuDBBuildRoute*-Global mehr existieren - ein
ueberlebendes bedeutet einen Abschnitt, den die Auswahl nicht kennt -, die Tabellen,
die die Navigation liest, muessen da und nicht leer sein, und pro Spielversion muss
genau die richtige Haelfte fehlen.
Wegpunktlisten sagen jetzt an, wie weit das Laden fortgeschritten ist
Einfach: Die Meldung "Wegpunkte werden noch geladen" war fuer ein, zwei Sekunden Wartezeit
gedacht. Wenn der Client Sku ausbremst (siehe voriger Eintrag), kann sie aber zehn
Sekunden und laenger stehen bleiben, und dann ist sie von einem Haenger nicht mehr zu
unterscheiden. Sie nennt jetzt einen Prozentwert, also zum Beispiel "Wegpunkte werden
noch geladen, 47%". Die Zahl bewegt sich von Anfang an: Die ersten Schritte sind die
Datenbankteile, auf die der Aufbau ueberhaupt erst wartet (0, 20, 40 Prozent), danach
zaehlt der Aufbau selbst bis 99 hoch. Jeder Tastendruck auf dem Eintrag sagt den
aktuellen Stand an, und sobald alles da ist, wird wie bisher automatisch der erste
echte Wegpunkt angesagt.
Technisch: Der Massstab ist die Arbeitszeit eines VOLLSTAENDIGEN Aufbaus, die jeder
erfolgreiche Lauf in den globalen SkuNav-Einstellungen hinterlegt (wpcTotalWorkMs).
Gemessen wird Arbeit, nicht Wanduhrzeit: Die Arbeit ist stabil, die Wanduhrzeit
schwankt jetzt mit der Budget-Drosselung. Damit stimmt der Prozentwert auf jedem
Rechner; nur der allererste Aufbau nach einer Neuinstallation nutzt den Vorgabewert.
Kosten pro Bild: ein Ganzzahlvergleich - nur ein GEAENDERTER Prozentwert baut den Text
neu, und das auch nur fuer einen Eintrag, auf dem der Fokus gerade steht. Der Eintrag
traegt dafuer eine Markierung, weil sein Name kein fester Text mehr ist: Die beiden
Stellen, die ihn bisher am Namen erkannten - die Nicht-auswaehlbar-Sperre und die
automatische Aktualisierung am Ende des Aufbaus - pruefen jetzt die Markierung.
Shift-F9 bis Shift-F12: eigene Tastenbelegungen, und vier Schnellzugriffe zurueck
Einfach: Vier Sku-Aktionen - die beiden Navigations-Schnelllisten (Shift-F9 und Shift-F10),
das Aktionsleisten-Menue (Shift-F11) und das Abbrechen der Routennavigation
(Shift-F12) - haengten direkt auf den Tasten der Audio-Menue-Schnellzugriffe 1 bis 4.
Das hatte zwei Folgen. Diese vier Schnellzugriffe waren tot: Ihre Festlegen-Tasten
(Strg-Shift-F9 bis Strg-Shift-F12) speicherten weiterhin einen Menuepfad und bestaetigten
ihn auch laut, aber keine Taste konnte ihn je wieder aufrufen. Und die vier Aktionen
liessen sich nur auf eine andere Taste legen, indem man einen Eintrag namens
"audio menue schnell zugriff 1" bis "4" neu belegte - dort sucht niemand nach
"Navigation abbrechen". Jede Aktion hat jetzt ihren eigenen Eintrag in der
Tastenbelegung, unter ihrem eigenen Namen, weiterhin auf Shift-F9 bis Shift-F12. Die
Schnellzugriffe 1 bis 4 sind wieder frei und unbelegt, genau wie die Plaetze 5 bis 10.
Bestehende Einstellungen werden beim ersten Anmelden uebernommen: Welche Taste auch
immer heute auf Schnellzugriff 1 bis 4 liegt, sie fuehrt weiterhin genau dieselbe
Aktion aus - sie wandert nur auf den neuen Eintrag, fuer die Finger aendert sich
nichts. Ein Platz, den du absichtlich geleert hattest, bleibt leer.
Technisch: Der OnClick in SkuZOptions/Core.lua fing SKU_KEY_MENUQUICK1..4 ab und kehrte
zurueck, bevor die allgemeine Schnellauswahl-Schleife weiter unten im selben Handler
sie sehen konnte. Die drei verschobenen Aktionen heissen jetzt
SKU_KEY_NAVWAYPOINTSQUICK, SKU_KEY_NAVROUTEDESTINATIONSQUICK und
SKU_KEY_ACTIONBARSOPEN und werden von dem Modul verteilt, dem sie gehoeren; die beiden
Navigationslisten stehen in der Gruppe "Navigation und Wegpunkte". Eine einmalige
Migration in SkuKeyBindsUpdate verschiebt key und key2 vom alten Platz auf die neue
Konstante; erkannt wird sie am Fehlen der neuen Konstante im Profil, laeuft also genau
einmal und vor dem Setzen der Vorgaben. Gespeicherte Schnellauswahl-Pfade bleiben
erhalten - eine Taste auf Platz 1 bis 4 stellt die alte Abkuerzung wieder her. Neue
Stolperdrahtpruefung: /skucheck keys meldet jede Taste, die zwei Sku-Belegungen
gleichzeitig haelt (ausgenommen die transienten Override-Tasten, die sie sich per
Entwurf teilen).
Navigation abbrechen lief ueber zwei verschiedene Tasten
Einfach: Es gab zwei Wege, das Folgen einer Route oder eines Wegpunkts zu beenden, und sie
verhielten sich unterschiedlich. Die richtig benannte Belegung "route oder wegpunkt
folgen beenden" wurde ganz ohne Taste ausgeliefert, und wenn man ihr eine gab, sagte
sie "folgen beendet" - dieselben Worte wie beim automatischen Ankommen, man konnte
beides also nicht unterscheiden - und sie sagte ueberhaupt nichts, wenn man eine Route
statt eines einzelnen Wegpunkts abbrach. Der andere Weg war das fest verdrahtete
Shift-F12, das "Navigation abgebrochen" sagte, aber nur als Schnellzugriff 4
existierte. Beides ist jetzt eine Taste: "route oder wegpunkt folgen beenden",
standardmaessig auf Shift-F12 und frei belegbar, mit dem Bestaetigungston und dem
eindeutigen "Navigation abgebrochen". Sie bleibt vollkommen still, wenn es nichts
abzubrechen gab, und funktioniert weiterhin in Bewegung und im Kampf.
Technisch: Der SkuNav-OnClick-Zweig fuer SKU_KEY_STOPROUTEORWAYPOINT ruft jetzt
SkuNav:CancelNavigationSilent() auf und spricht bzw. spielt Sound 835 nur bei einem
true-Rueckgabewert. Damit faellt der alte ungeschuetzte Pfad weg, der
SKU_NAVIGATION_STOPPED und den Ton auch dann ausloeste, wenn nichts lief, und dessen
Ansage aus EndFollowingWpOrRt kam und an einen ausgewaehlten Wegpunkt gebunden war.
EndFollowingWpOrRt selbst bleibt unveraendert - seine fuenfzehn anderen Aufrufstellen
nutzen es als Abbau vor dem Auswaehlen eines neuen Ziels, wo das Loeschen temporaerer
Wegpunkte falsch waere.
Navigation: Eine Route liess sich nicht starten, wenn ihre Liste waehrend des Ladens fertig wurde
Einfach: Wenn du die Routenliste (Shift-F10) geoeffnet hast, waehrend Sku seine
Wegpunktdaten noch aufgebaut hat, hat sich die Liste in dem Moment aktualisiert, in dem
diese Daten fertig waren - und ab da hat Enter auf einem Routenpunkt die Navigation
nicht mehr gestartet. Stattdessen ist das Menue zurueck auf die Ebene der
Einstiegspunkte gesprungen, so als haette die Taste gar nichts getan. Menue schliessen
und neu oeffnen hat es behoben, was das Ganze zufaellig wirken liess. Die aktualisierte
Liste verhaelt sich jetzt genau wie eine frisch geoeffnete: Enter startet die
Navigation. Das gilt genauso fuer die Liste der Wegpunkte in der Naehe (Shift-F9) und
fuer jede Wegpunktliste, die sich beim Eintreffen der Daten selbst aktualisiert.
Technisch: Die Aktualisierung am Ende des asynchronen Wegpunkt-Cache-Aufbaus hat die Ebene
mit einem blossen children = {} plus BuildChildren neu gebaut. Damit faellt weg, was
OnPostSelect fuer eine Auswahl-Ebene tut: selectTarget auf der Ebene setzen und auf
jedes frisch gebaute Kind kopieren. Ohne das erbt die gesamte Unterebene
selectTarget = nil, also landet das Enter des Blatts im generischen Zweig von
OnPostSelect - es laeuft kein OnAction (RouteFollowOnAction wurde nie aufgerufen) und
der Cursor wird auf self.parent gesetzt, genau der beobachtete Sprung nach oben. Dieser
Neuaufbau liegt jetzt an genau einer Stelle, SkuOptions:RebuildNodeChildren, benutzt von
OnPostSelect selbst, von der Wegpunkt-Aktualisierung und von der Auffrischung
veraenderlicher Listen - letztere im Behalten-Modus, damit eine laufende Auffrischung
kein bereits ausgewaehltes Ziel wegwirft. Zwei Stolperdraehte gehoeren zur Korrektur:
OnPostSelect protokolliert und zaehlt jedes Enter, das auf einem Blatt ohne
selectTarget unterhalb einer Auswahl-Ebene landet, und /skucheck menu baut eine
Wegwerf-Auswahl-Ebene neu auf, prueft die Zusicherung und meldet diese Sitzungszaehlung.
Auren: Gruppenplaetze wurden als Piepser statt als Wort angesagt
Einfach: Sagt eine Aura die Einheit an, die das Ereignis ausgeloest hat, kam bei manchen
Gruppenplaetzen nur ein kurzer Piepser statt eines Wortes - der Ton, den Sku spielt,
wenn ihm die Aufnahme fuer ein Wort fehlt. Betroffen waren Platz 3 und jeder
"Ziel von"-Platz. Diese Angaben werden jetzt in Woerter zerlegt, die das Sprachpaket
sicher enthaelt: "party 3", "ziel party 2". Alle anderen Einheiten sagen weiterhin
ihren uebersetzten Namen.
Technisch: sourceUnitId und destUnitId reichten das rohe Unit-Token als EIN Wort an die
Audioausgabe. Die Pakete liefern party0/1/2/4, aber kein party3 und keine einzige
partyNtarget-Datei, der Rest fiel also auf den missingAudio-Piepser zurueck (allein
party3 zaehlte 129). tUnitIdToSpokenName in SkuAuras/data.lua splittet die
Party-Tokens; andere Tokens fallen auf ihren uebersetzten friendlyName aus den
Wertelisten und erst dann auf das rohe Token zurueck. Nebenbei behoben: notifyChat
druckte die Tabellenreferenz statt der Einheit.
Auren: eine Aura mit "einmal" konnte im dichten Kampf mehrfach hintereinander feuern
Einfach: Eine Aura, die pro Anwendung nur EINMAL melden soll - typisch "Schattenwort:
Schmerz laeuft in einer Sekunde ab" -, konnte im Bosskampf vier Toene in einer
Sekunde abgeben. Das passierte, wenn mehrere Spieler denselben Effekt auf dem Ziel
hatten oder die Restdauer in einem Durchlauf gar nicht ablesbar war: Sku wertete das
faelschlich als "der Effekt ist wieder frisch" und hob die Einmal-Sperre auf. Fehlt
die Ablesung, bleibt die Sperre jetzt zu. Eine echte Auffrischung oder eine neue
Anwendung hebt sie weiterhin sofort auf.
Technisch: Die Reset-Formel der Zaehl-Bedingung armierte used bei jedem Durchlauf neu, in
dem die uebrigen Bedingungen hielten und die kleiner-Dauerbedingung false las - und
ein Durchlauf OHNE Ablesung (Name nicht in der Liste, kein exp-Eintrag, oder die
exp-Karte antwortet mit der gleichnamigen Aura eines anderen Wirkers) erfuellt genau
das. tSmallerDurationNoRead in SkuAuras/Core.lua verhindert das Zuruecksetzen ohne
Ablesung; der neue Logeintrag "aura gate re-armed" haelt jedes Entsperren fest.
Beobachtet wurden vier Feuerungen in 987 ms (DURATION_DEADLINE, dann zweimal
UNIT_POWER und SPELL_PERIODIC_DAMAGE).
Menue: die Wegpunktliste auf Shift-F9 oeffnete sich auf grossen Karten erst beim zweiten Versuch
Einfach: Auf Karten mit sehr vielen Wegpunkten blieb Shift-F9 auf dem obersten Eintrag
stehen, statt die Liste zu oeffnen; ein weiterer Pfeildruck oeffnete sie dann doch.
Grund war Arbeit, die dreimal statt einmal lief: Der Sprung baute dieselbe Liste - auf
manchen Karten rund 1900 Eintraege - drei Mal in einem einzigen Frame, und der
Spielclient brach das mit seiner Skript-Zeitgrenze ab. Der Abbruch passiert
lautlos, deshalb schien einfach nichts zu geschehen. Dazu kam, dass jeder
Tastendruck auf einem Eintrag dessen Unterliste erneut aufbaute und die Eintraege
dabei verdoppelte. Beides ist weg, die Liste wird einmal gebaut. Shift-F10 war nie
betroffen, weil diese Liste auf zehn Ziele begrenzt ist.
Technisch: SlashFunc baute die Kinder dreimal: vor dem Namensvergleich, im OnSelect der
Schleife und noch einmal im Nachlauf. Der Vergleich entscheidet jetzt VOR dem Bau,
und der Nachlauf ueberspringt seine Wiederauswahl, wenn die Schleife denselben Knoten
bereits gewaehlt hat (actionOnEnter-Knoten ausgenommen, dort unterscheiden sich die
beiden Aufrufe wirklich). VocalizeCurrentMenuName baut nur noch, wenn es nichts zu
zaehlen gibt - es braucht die Kinder allein fuer die ";plus"-Markierung, und die
meisten Builder haengen ueber InjectMenuItems an, statt zu ersetzen (gemessen
1859 -> 3718 -> 5577 Eintraege beim Durchpfeilen). Nachtrag aus dem Test:
Fenster-Ebenen unter "Lokal" (Dialog, Haendler, Quest, Flugmeister) bauen ihre Kinder
lazy und tragen kein dynamic-Flag; mit uebersprungenem Vorbau sahen sie aus wie
kinderlose Blaetter, und der Blattzweig ruft CloseMenu - Schliessen klickt aber jeden
Fensterknopf aus interactFramesList, der Sprung zum Flugmeister schloss dessen
Fenster also sofort wieder. Gebaut wird deshalb weiter, wenn die Liste leer ist, es
sei denn der Knoten ist dynamic. Zwei Stolperdraehte in /skucheck menu zaehlen beide
Faelle mit.
Taxiflug: Die Ansagen lassen sich abschalten - und sie nennen nicht mehr den Startpunkt oder das Ziel des Fluges
Einfach: Waehrend eines Taxiflugs sagt Sku "Naechster Flugpunkt X" und rund 800 Meter
vorher "Vorzeitige Landung moeglich bei X", damit man mit der Tastenbelegung frueher
aussteigen kann. Wer viel fliegt, empfindet das als Geschwaetz, deshalb gibt es
jetzt einen Schalter: Einstellungen > Allgemein > "Flugpunkte zum Landen ansagen".
Er steht auf Ja und schaltet ausschliesslich die SPRACHAUSGABE ab - der Flug wird
weiter verfolgt, und die Taste fuer die vorzeitige Landung funktioniert unveraendert
und bestaetigt weiterhin laut, was sie getan hat, denn das ist die Antwort auf einen
gerade gedrueckten Tastendruck. Zweitens gab es Meldungen, Sku habe den Flugpunkt,
an dem der Flug BEGONNEN hat, oder den Zielflugpunkt als Ort fuer eine vorzeitige
Landung genannt. Beides ist keine vorzeitige Landung: das eine ist der Ort, an dem
man ohnehin schon war, das andere ist schlicht das Ankommen. Beides ist jetzt
ausgeschlossen. Drittens haelt Sku den Mund, sobald die vorzeitige Landung
wirklich angefordert wurde. Bisher nannte es den Flugpunkt NACH dem, an dem man
abgesetzt wurde - zehn Sekunden vor der Landung in Ratschet kam noch "Naechster
Flugpunkt Astranaar", was klingt, als ginge der Flug weiter.
Technisch: Die Ansage hatte einen blinden Fleck, den Rueckfall auf den naechstgelegenen
Flugpunkt. Die Route wird beim Start von der Flugkarte erfasst (der einzige Moment,
in dem die Routen-Schnittstelle ueberhaupt antwortet), und alle Ansagen haengen an
dieser Route. Fehlt sie, faellt der Code auf "der naechstgelegene benutzbare
Flugpunkt" zurueck - und der weiss nichts vom Flug: Kurz nach dem Start ist das eine
Weile lang genau der Startpunkt, kurz vor der Landung der Zielpunkt. Die eine
alltaegliche Art, die Route zu verlieren, ist ein /reload mitten im Flug: Der
Erfassungshaken hat vor dem Neuladen ausgeloest und kann kein zweites Mal ausloesen.
Genau deshalb war das fuer die Betroffenen reproduzierbar und hier nie zu sehen.
Drei Aenderungen: (1) Die erfasste Route ueberlebt ein /reload - sie wird zusammen
mit der aktuellen Teilstrecke in die charakterbezogenen Einstellungen geschrieben
und im Flug wieder eingelesen, ein Neuladen fuehrt also gar nicht mehr in den
Rueckfall; (2) der Startpunkt des Fluges wird jetzt ebenfalls aus der
Routenerfassung gelesen (der Quellplatz der ersten Teilstrecke), damit sind Start
und Ziel namentlich bekannt und koennen in keinem Modus mehr angesagt werden; (3) im
Rueckfallbetrieb muss ein Flugpunkt NAEHER kommen, bevor er als Landemoeglichkeit
angeboten wird - ein Punkt, von dem man wegfliegt, liegt hinter einem; (4) eine bewilligte Anforderung beendet die Route
auch fuer den Streckenzeiger: Der angeforderte Halt ist das Flugende, ihn zu
passieren ist Ankommen und keine Zwischenstation. Der Ausweg dafuer ist Geometrie
statt Zeitschaltung - wer tausend Meter dahinter immer noch fliegt, dessen
Anforderung hat der Server ignoriert, und die Route lebt sofort wieder auf. Die neue
Pruefung "/skucheck taxi" haelt die Regel fest: Eine vorzeitige Landung ist nie der
Start- oder Zielpunkt des eigenen Fluges. Der Schalter liegt pro Profil unter
taxiAnnounceLandingPoints.
Energiemonitor: aus "nichts" wird "Aktuelle Ressource", und die folgt der Leiste, die du siehst
Einfach: Der Lebens- & Energiemonitor beobachtet genau eine Ressource, und die war fest
eingestellt: Mana, Wut, Energie - oder "nichts". "Nichts" war aber kein Ausschalter,
sondern ein Loch: es warf laufend Lua-Fehler, und was der Monitor stattdessen
beobachtete, hatte niemand ausgewaehlt. Der Eintrag heisst jetzt "Aktuelle
Ressource" und steht als erster in der Liste. Er folgt der Leiste, die das Spiel
dir gerade zeigt: ein Druide bekommt in Normalgestalt Mana, im Baeren Wut und in
der Katze Energie, ohne je wieder ins Menue zu muessen. Alle anderen Klassen haben
nur eine Leiste - fuer sie ist es einfach ihre Ressource. Eine feste Ressource
auszuwaehlen funktioniert unveraendert weiter. Zum Abschalten ist "Aktiviert: Nein"
da, dafuer ist der Schalter gedacht. Wer bisher "nichts" eingestellt hatte, findet
den Monitor jetzt abgeschaltet und die Ressource auf "Aktuelle Ressource" - wer ihn
hoeren will, schaltet ihn wieder ein.
Technisch: "NOTHING" gab den Energie-Index -1 (Enum.PowerType.None) direkt an UnitPower
und UnitPowerMax weiter - einen Wert, nach dem der Monitor gar nicht fragen sollte.
An seine Stelle tritt GetMonitoredPowerType(), das den gespeicherten Wert erst beim
Lesen aufloest: eine feste Auswahl auf ihren Index, "Aktuelle Ressource" ueber
UnitPowerType("player") auf die gerade angezeigte Leiste. Beide Lesepfade gehen
darueber, auch der Token-Vergleich in UNIT_POWER_UPDATE - mit der automatischen
Auswahl ist das Token, auf das reagiert werden muss, eben nicht das gespeicherte.
Beide Pfade pruefen jetzt ausserdem auf nil und auf ein Maximum von 0, statt
dadurch zu teilen; das war die eigentliche Fehlerquelle, und weil einer der beiden
Pfade im OnUpdate-Treiber liegt, kam nicht ein Fehler, sondern einer pro Tick.
Weil die beobachtete Ressource jetzt unter dem Monitor wechseln kann, wird der
vorige Prozentwert beim Wechsel des Tokens zurueckgesetzt - sonst wuerde die erste
Ansage nach einem Gestaltwechsel entweder verschluckt oder bekaeme die falsche
Richtung (steigend/fallend). Zusaetzlich: der Handler steigt aus, wenn das Modul
abgeschaltet ist. Er haengt an zwei Registrierungen (eigenes AceEvent-Objekt und
der Dispatcher in Core.lua), OnDisable loeste aber nur die erste - ein im
Funktionsmenue abgeschalteter Monitor sagte deshalb weiter an. Neue Pruefung
"/skucheck power" haelt die Regel fest: die eingestellte Ressource muss sich immer
zu etwas aufloesen, das der Client lesen kann; eine bewusst gewaehlte Ressource,
die die eigene Klasse nicht hat, zaehlt als "ausstehend", nicht als Fehler. Der
gespeicherte Wert "NOTHING" wird beim Anmelden einmalig auf "ACTIVE" umgestellt und
der Monitor dabei abgeschaltet.
Auren erkennen Zauber an ihrer Identitaet, nicht mehr am uebersetzten Namen
Einfach: Eine Aura, die du angelegt hast, war bisher an deine Spielsprache gebunden. Der
gespeicherte Wert war der uebersetzte Zaubername - "Frostblitz" - und ein englischer
Client kennt nur "Frostbolt", also feuerte dieselbe Aura dort nie. Aus demselben Grund
kam ein in der Gruppe geteiltes Aurenset bei einem Mitspieler mit anderer Sprache tot
an, und die mitgelieferten Aurensets gab es ueberhaupt nur auf deutschen Clients. Sku
merkt sich jetzt die sprachunabhaengige Identitaet des Zaubers. Zu sehen und zu hoeren
bekommst du weiterhin genau den Namen, den dein Spiel benutzt - im Menue, im Namen der
Aura und in der Ansage, wenn sie feuert. Deine bestehenden Auren werden beim ersten
Anmelden einmalig umgestellt, ohne dass du etwas tun musst; ihre Namen aendern sich
dabei nicht.
Ein zweiter Gewinn nebenbei: alle Raenge eines Zaubers und auch die Varianten, die
Gegner wirken, gehoeren zu einem Eintrag. "Sag mir, wenn mein Ziel Frostblitz wirkt"
deckt damit alle 103 Frostblitz-Varianten ab, statt nur die eine, die zufaellig in
der Liste stand. Ob DU oder ein Gegner den Zauber gewirkt hat, entscheidet weiterhin
die eigene Bedingung "Ereignis Quelle", nicht der Zauber selbst.
Wo ein deutscher Zaubername fuer mehrere verschiedene englische steht - "Verblassen"
ist sowohl "Fade" als auch "Fade Out" - nennt die Liste den englischen Namen in
Klammern dazu, damit die Eintraege unterscheidbar bleiben. Nur die Liste; die Ansage
beim Feuern bleibt kurz. Waehlst du so einen Eintrag, gewinnt die aelteste Variante -
bei "Verblassen" also der Priesterzauber und nicht "Fade Out". Bereits gespeicherte
Auren mit so einem Namen bleiben unveraendert und reagieren weiter auf jede Variante,
wie bisher.
Technisch: Identitaet ist der enUS-Zaubername aus SkuDB.SpellDataTBC, das ohnehin
ausgeliefert und gepflegt wird - keine neue Datei, keine generierte ID-Tabelle (eine
solche muesste mit spells.lua synchron gehalten werden, und eine Neugenerierung wuerde
gespeicherte Auren still verwaisen lassen). Gespeicherte Werte tragen die Marke
"spellgroup:", angezeigt wird weiter SkuAuras.values[key].friendlyName. Die Live-Liste
aus UnitAura wird ueber Rueckgabewert 10 (spellId) auf den Gruppennamen abgebildet;
auf einem nicht-englischen Client steht der lokalisierte Name als Kompatibilitaets-
Alias daneben, damit ein nicht umgestellter Altwert weiter matcht. Auf einem
englischen Client sind Gruppen- und Live-Name identisch, der Alias entfaellt und die
Kosten sind exakt null. Kennt SpellDataTBC eine ID nicht - die Population, die mit dem
Anniversary-Zyklus am ehesten driftet -, faellt die Zuordnung auf den lokalisierten
Namen zurueck, also auf das bisherige Verhalten. 838 der 26.603 deutschen Namen (3,15
Prozent) decken mehr als einen englischen ab. Zur Laufzeit gewinnt die Gruppe mit der
niedrigsten Zauber-ID - die kollidierenden Varianten sind ausnahmslos spaeter
hinzugekommen; geprueft an den Faellen mit bekannter Antwort (Verblassen 586 gegen
5543, Geschwaechte Seele 6788 gegen 36788, Schattenwort: Schmerz 589 gegen 37603,
Erneuerung 139 gegen 37563, Gedankenkontrolle 605 gegen 7645). GESPEICHERTE Werte mit
so einem Namen werden trotzdem NICHT umgestellt, weil sie heute auf jede Variante
passen und eine Umstellung die anderen still wegnehmen wuerde; ihre Menueeintraege
bekommen den englischen Namen angehaengt. Der Anzeigename einer Gruppe stammt immer von der niedrigsten ID
darin, damit er sich zwischen Sitzungen nicht aendert. Neue Pruefungen unter
"/skucheck auren": es gibt ueberhaupt Gruppeneintraege, alle IDs eines Zaubers loesen
zu EINER Gruppe auf, und die einmalige Umstellung hat keinen Wert liegen lassen.
Aurensets teilen: neues Format ohne Sprachkennzeichen
Einfach: Ein geteiltes Aurenset traegt kein Sprachkennzeichen mehr und die Warnung "Set
ist fuer eine andere Sprache" entfaellt - die Bedingungen sind jetzt sprachfrei. Beim
Annehmen bekommt jede Aura ausserdem ihren Namen in DEINER Sprache, statt den Satz
des Absenders zu behalten. Auren, denen du selbst einen Namen gegeben hast, behalten
ihn.
Technisch: SkuAuraSetV2 (Nutzlast "AURASET2", ohne loc-Feld) wird gesendet; V1 wird
weiterhin empfangen, samt bisheriger Sprachwarnung, weil solche Pakete noch
lokalisierte Werte tragen. Bewusst wird nur V2 gesendet: ein zusaetzliches V1-Paket
wuerde bei aelteren Clients Auren mit Gruppenwerten ablegen, die sie nicht aufloesen
koennen. Der Name wird beim Import ueber BuildAuraName neu abgeleitet
(SkuAuras:RelocalizedAuraName); customName-Auren sind ausgenommen, und das sind genau
die, auf die andere Auren verweisen koennen - die Querverweise bleiben also heil.
Auren anlegen: das Menue zum Bauen einer Aura ist neu aufgebaut
Einfach: Eine Aura besteht weiterhin aus Bedingungen, und alles, was du schon gebaut hast,
rechnet unveraendert weiter - aber der Weg zu einer Bedingung ist an vielen Stellen
kuerzer geworden, und die Listen, durch die man dabei laeuft, sind sortiert, kurz und
schnell. Der Reihe nach, wie eine Aura jetzt entsteht:
Die Attributliste ist durchgehend nach Namen sortiert - auch die Gruppeneintraege, die
frueher immer oben standen. Ein Eintrag liegt also da, wo sein Name ihn hinstellt, und
ist ueber die ersten Buchstaben erreichbar. Die 35 Ereignisse liegen hinter zwei
Eintraegen, "Ereignisse allgemein" und "Ereignisse Zauber"; Gesundheit, Ressource,
Mana, Wut, Energie, Runenmacht und Combopunkte liegen zusammen in "Eigene Gesundheit
oder Ressource"; und alle Auren, denen du selbst einen Namen gegeben hast, stehen als
Bedingung unter "Selbsterstellte Auren" statt einzeln zwischen den echten Attributen -
frueher wuchs die oberste Liste mit jeder benannten Aura um einen Eintrag mehr, der
sich in jeden Buchstaben des Alphabets einsortierte. Jeder Gruppeneintrag sagt beim
Vorlesen selbst, was in ihm ausgewaehlt ist; hineingehen muss man dafuer nicht.
Eine Bedingung mit nur zwei Werten - "wahr" und "falsch", oder "buff" und "debuff" -
ist jetzt ein Schalter statt drei Ebenen. Der Wert steht am Eintrag, Enter schaltet
um: "Im Kampf; wahr", Enter, "Im Kampf; falsch". Beim Anlegen geht Enter einen Schritt
weiter auf "nicht festgelegt" und wieder zurueck, damit ein versehentlich gesetzter
Schalter auch wieder wegzunehmen ist. Wichtig zum Verstaendnis: "nicht festgelegt" ist
kein dritter Wert, sondern heisst, dass es die Bedingung gar nicht gibt - das ist der
neutrale Zustand, nicht "falsch". "falsch" ist ein Vergleich wie jeder andere: "Im
Kampf gleich falsch" loest NUR ausserhalb des Kampfes aus.
Zauber waehlst du weiter aus einer Liste, kannst sie aber auch tippen: ganz oben in
jeder Zauber-Werteliste steht "Zauber eingeben", Enter, Name oder Nummer, Enter, und
Sku sagt an, welchen Zauber es daraus gemacht hat. Die beiden Bedingungen "zauber nr"
und "gegenstand nr" stehen dafuer nicht mehr in der Attributliste: sie meinten einen
EINZELNEN Zauberrang und bedeuteten damit direkt neben "zauber name" das Gegenteil von
dem, was derselbe getippte Wert dort tut. Neu dazugekommen ist "Buff Debuff nur selbst
gewirkte" - steht sie auf wahr, sehen die Buff- und Debufflisten dieser Aura nur noch
Effekte, die DU gewirkt hast, sodass "mein Schattenwort: Schmerz laeuft ab" nicht mehr
das eines anderen Priesters auf demselben Ziel meldet. Und weil "Quelle (L)" und
"ziel (L)" regelmaessig fuer das eigene Ziel gehalten wurden, heissen sie jetzt
"Ereignis Quelle (L)" und "Ereignis Ziel (L)": sie filtern das ausloesende EREIGNIS.
Zuletzt das Verhalten der Listen selbst: alle Wertelisten oeffnen spuerbar schneller,
"zauber benutzbar" friert das Spiel beim Aufklappen nicht mehr ein, ein Zauberwechsel
in einer Dauer-Bedingung geht ohne Haenger und ohne den vorherigen Zauber weiter als
ausgewaehlt vorzulesen, und "Loeschen" fragt jetzt nach, bevor eine Aura weg ist - es
war der einzige Eintrag der Liste, der das nicht tat, direkt neben "Duplizieren", das
immer gefragt hat.
Technisch: Ein Attribut wird als Schalter gebaut, wenn sein Typ BINARY ist, es genau zwei
Werte hat und der Typ genau einen Operator erlaubt (tBinaryValuesForAttribute in
SkuAuras/Options.lua); geschrieben wird exakt das, was die alte Werteliste geschrieben
hat, eine ueber den Schalter gebaute Aura ist von einer alt gebauten also nicht zu
unterscheiden, und eine leere values-Liste faellt aus dem Entwurf - das ist "nicht
festgelegt". Die Bedingungszeile paart actionInPlace mit actionOnEnter, das ist es,
was Enter und Pfeil rechts auf demselben Knoten auseinanderhaelt. Die Attributliste
sammelt Gruppen und Attribute mit ihrem Anzeigenamen ein und fuegt beides in
Namensreihenfolge ein. Die zwei Ereignisfamilien sind EIN Attribut und EINE
gespeicherte Bedingung: jede Familienliste bietet die andere als einen Eintrag an, und
beide zeigen auf die Bedingung, die der Entwurf schon haelt - sonst hinterliesse ein
Gang durch beide zwei Bedingungen auf event, die der Speichern-Lauf zu einer immer
wahren ODER-Gruppe verschmilzt. listsOwnOnly ist ein binaerer Modifikator: getAuraList
faengt im selben Scan den Wirker (7. Rueckgabewert von UnitAura) ab und fuellt
parallele own-Mengen, die EvaluateAllAuras pro markierter Aura eintauscht. Die
Wertelisten sortieren mit einem Sortierschluessel pro Eintrag statt zweien pro
Vergleich (27.057 statt rund 800.000 neue Zeichenketten pro Zauberliste), "zauber
benutzbar" fragt die 132 Aktionsplaetze statt aller 49.000 Zauber der Datenbank, und
die Dauer-Bedingung laesst jeden Eintrag beim Vorlesen selbst sagen, wie er steht
(tValueToggleRefreshLiveName, EINE per Referenz geteilte Funktion), statt bei jedem
Enter 27.000 Eintraege zurueckzusetzen. "zauber nr"/"gegenstand nr" werden weiter
ausgewertet und sind nur ueber ein retired-Flag aus dem Builder ausgeblendet, damit
eine importierte oder alte Aura nicht auf ein nil laeuft; mit ihnen entfallen ihre
Wertelisten, rund 49.000 Zauber- und 25.000 Gegenstands-IDs, die bei jedem Laden
aufgebaut wurden. Die Locale-SCHLUESSEL der umbenannten Bedingungen sind unveraendert,
es verschiebt sich also keine gespeicherte Aura. Beim Loeschen musste zusaetzlich der
aName-Zweig des Verwalten-Menues weichen: selectTarget wird erst umgehaengt, wenn die
Ebene betreten ist, bis dahin waere die Rueckfrage kosmetisch gewesen. Loeschen
frischt jetzt auch die Aura-Pseudoattribute auf - eine geloeschte Aura blieb vorher
als Bedingung waehlbar.
Franzoesische Clients: die Liste der Waffenverzauberungen fuer Auren war leer
Einfach: Auf einem franzoesischen Client bot die Aura-Bedingung fuer Waffenverzauberungen
keinen einzigen Eintrag an, sodass sich so eine Bedingung gar nicht anlegen liess.
Technisch: SkuAuras:ResolveWeaponEnchantName las Spalte 1 der Enchant-Datenbank fuer
enUS und Spalte 2 fuer deDE und liess den Namen sonst nil - fuer jede andere Sprache
gab die Funktion damit fuer JEDE Verzauberung nil zurueck, und die Werteliste kam
leer heraus. Sie nimmt jetzt die Spalte der eigenen Sprache, sonst die englische,
wie der Rest des Namenssystems seit v42.09. Gefunden beim Umbau auf Gruppen-
Identitaet, nicht aus einem Bericht.
Menue: jeder Eintrag wird jetzt rund 13 mal guenstiger erzeugt
Einfach: Lange Listen bauen sich deutlich schneller auf. Am staerksten faellt es bei den
Zauberlisten einer Aura-Bedingung auf: die haben 27.057 Eintraege, und auf einem
Hardcore-Realm liessen sie sich zuletzt gar nicht mehr oeffnen - der Server bricht dort
zu lange laufende Addon-Skripte hart ab, und der Aufbau kam nur etwa bis zur Haelfte.
Betroffen ist nicht nur die Aurenliste: jedes Menue in Sku baut sich aus denselben
Eintraegen auf.
Technisch: Ein Menueeintrag war eine tiefe Kopie der Vorlage SkuGenericMenuItem - pro
Eintrag eine Hilfstabelle, ein pairs()-Durchlauf ueber alle 28 Felder mit je einem
type()-Aufruf und drei Schluesselvergleichen, 28 Schreibzugriffe und eine rekursive
Kopie der children-Tabelle. Jetzt ist ein Eintrag eine fast leere Tabelle, deren
Metatabelle per __index auf die Vorlage zeigt: zwei Tabellen und ein Schreibzugriff.
Gemessen an 27.057 Eintraegen: das Erzeugen der Knoten faellt von 78 auf 6 ms (13x),
der komplette Listenaufbau von 100 auf 31 ms (3,2x, und 2,7x schneller als vor dem
Aurenumbau). Ein Schreibzugriff auf einen Eintrag ueberdeckt die Vorlage wie bisher;
children bleibt bewusst eine eigene Tabelle pro Eintrag, sonst teilten sich alle
Menuepunkte des Addons EINE Kinderliste. Einzige Stelle, die einen Eintrag kopiert
(der Filtereintrag in SkuOptions:ApplyFilter), haengt die Metatabelle wieder an.
/skucheck menu prueft beides an Wegwerf-Eintraegen.
Zum Vergleich nachgemessen: der Aurenumbau selbst hat diese Listen kaum verlangsamt. Die
Umstellung auf Gruppen hat die Zauberliste um 460 von 26.597 Eintraegen wachsen lassen
(+1,7 %), und Umschalter statt einfacher Eintraege kosten rund 19 % mehr Aufbauzeit. Teuer
war der Aufbau schon vorher; auf einem Hardcore-Realm ist eine Skriptgrenze aber eine
Kante und keine Schraege, und dafuer reichten die 19 %.
Menue: eine abgebrochene Liste blieb still unvollstaendig
Einfach: Auf einem Hardcore-Realm bricht der Server ein zu lang laufendes Addon-Skript ab.
Traf das den Aufbau einer langen Liste, dann liess sich die Liste beim ZWEITEN
Pfeil-rechts zwar oeffnen - aber es war nicht etwa ein neuer Versuch, sondern der halb
fertige Rest vom ersten. Bei den Zauberlisten hiess das rund 6.900 von 27.000
Zaubern, ohne jeden Hinweis: wer seinen Zauber nicht fand, musste glauben, es gebe ihn
nicht. Jetzt wird der Aufbau im naechsten Frame dort fortgesetzt, wo er abgebrochen
wurde, und die Liste ist nach wenigen Frames vollstaendig, ohne dass man etwas druecken
muss.
Technisch: Das Skript-Budget gilt pro Ausfuehrung, der naechste Frame hat also wieder
eines - genau wie beim Aufbau der Routendaten, der aus demselben Grund in Scheiben
laeuft. SkuOptions:ContinueInterruptedBuild ruft BuildChildren auf einem
Null-Timer erneut auf, solange die Ebene unvollstaendig ist. Fortgesetzt wird nur ein
Builder, der sich ueber `resumableBuild` dazu bekennt und einen eigenen Cursor
fuehrt: ein gewoehnliches BuildChildren HAENGT AN, ein zweiter Aufruf wuerde also
jeden Eintrag doppelt erzeugen - deshalb gab es die alte Sperre ueberhaupt. Der Cursor
wird erst NACH einem Eintrag gesetzt, nicht davor, sonst gilt ein Eintrag als gebaut,
den der Abbruch verhindert hat. Macht ein Durchlauf keinen Fortschritt, wird
aufgegeben statt endlos zu wiederholen. /skucheck menu prueft an einer Wegwerf-Ebene,
dass ein abgebrochener Aufbau fortgesetzt und nicht neu begonnen wird.
Einstellungen mit zwei Werten sind jetzt Schalter statt Untermenues
Einfach: Eine Einstellung, die nur zwei Zustaende kennt - "Ein" und "Aus", "Ja" und
"Nein" -, sagt ihren Wert jetzt gleich beim Vorlesen mit: du hoerst zum Beispiel
"Sku Menue im Kampf; ein". Enter schaltet um, der Fokus bleibt stehen, und du hoerst
den Eintrag sofort im neuen Zustand. Pfeil rechts brauchst du dafuer nicht mehr, denn
das Untermenue mit den beiden Werten gibt es nicht mehr. Vorher waren es drei Tasten -
rechts, Pfeil, Enter -, und man musste ueberhaupt erst hineingehen, um zu erfahren,
wie die Einstellung gerade steht. Das betrifft die gesamten Einstellungen, den
Gesundheits- und Kampfmonitor, die Filter von Chat- und Kampfprotokoll, das
Funktionsmenue, das Kameramenue und die Einstellungen fremder Addons: rund 150
Eintraege. Einstellungen mit MEHR als zwei Werten behalten ihre Liste, dort gibt es
ja etwas auszuwaehlen.
Technisch: Neues gemeinsames Menue-Element SkuOptions:MakeToggleNode in
SkuZOptions/templates.lua; SkuOptions:MakeInPlaceToggle stellt eine vorhandene
isSelect-Stelle mit EINER Zeile darauf um und benutzt deren eigenes GetCurrentValue
und OnAction weiter, damit jede Besonderheit einer Einstellung bleibt, wie sie war.
Welcher der beiden Werte dabei als "ein" uebergeben wird, ist egal, und genau das
machte die Umstellung der rund 50 vorhandenen Ja/Nein-Stellen mechanisch. Ein Schalter
ist ein Blatt (actionInPlace, kein dynamic, keine Kinder) - deshalb tut Pfeil rechts
nichts mehr -, und ein RefreshLiveName liest den Zustand unmittelbar vor jeder Ansage
neu; das alte Untermenue bekam das umsonst, weil es bei jedem Abstieg GetCurrentValue
aufrief. Drei Fallen dabei: der Pfadlauf von SkuOptions:SlashFunc und die
Einstellungssuche waehlen mit aEnterFlag = true aus und haetten einen so benannten
Schalter UMGELEGT, statt ihn anzusteuern - beide setzen jetzt nur den Fokus, und die
Suche vergleicht gegen toggleLabel, weil der Name den Zustand traegt. Auf den
Filtereintrag einer Liste wird RefreshLiveName nicht angewandt: SkuOptions:ApplyFilter
baut ihn als Kopie des ersten Kindes, und die Kopie wuerde sonst den getippten Text
ueberschreiben. Und ein Schalter, dessen Leser einen Fehler wirft, wird in
/skucheck menu gezaehlt - er klaenge sonst wie eine Einstellung ohne Wert statt wie
ein Defekt.
Bereitschaftscheck: das Fenster landete nicht auf der Antwort, wie es jedes andere Popup tut
Einfach: Startet jemand in der Gruppe einen Bereitschaftscheck, oeffnet Sku wie bei jedem
Popup das Menue und springt hinein. Bei diesem einen Fenster kam der Cursor aber nicht
auf "Bereit" an, sondern eine Ebene darueber, sodass es zwei weitere Tastendruecke bis
zur Antwort waren. Jetzt stehst du sofort auf "Bereit", darunter liegt "Nicht bereit",
und Pfeil links fuehrt zurueck auf "Bereitschaft check". Wer den Check gestartet hat,
steht an beiden Eintraegen als Volltext.
Technisch: ReadyCheckFrame ist nur eine Huelle um ReadyCheckListenerFrame, das die Meldung
und die beiden Knoepfe traegt; generisch abgelaufen wurde diese Huelle eine eigene
Menueebene, und der Absprung von SkuCore:CheckFrames landete auf ihr. Es gibt jetzt
einen eigenen Bauplan (SkuCore:Build_ReadyCheckFrame in SkuCore/LocalMenu.lua,
eingetragen in interactFramesListManual), der die beiden Antworten flach als
directAction-Eintraege baut - dasselbe Muster wie Build_RolePollPopup fuer die
Rollenabfrage. Die Beschriftungen kommen von den Knoepfen selbst, die Blizzard in
ReadyCheckFrame_OnLoad uebersetzt, es braucht also keinen neuen Locale-Eintrag.
Gelistet werden nur sichtbare Knoepfe: hast du den Check selbst gestartet, blendet
Blizzard die Antwortseite aus und es gibt nichts zu beantworten.
Spiel-Lautstaerken: ein gesetzter Wert kam auf einem anderen Charakter wieder laut zurueck
Einfach: Wer die Gesamtlautstaerke im Sku-Menue leiser stellte, fand sie auf einem anderen
Charakter wieder auf dem alten Wert. Sku hatte die fuenf Lautstaerken und die fuenf
Sound-Schalter naemlich zusaetzlich selbst gespeichert und bei jedem Anmelden wieder
ins Spiel zurueckgeschrieben. Diese Kopie haengt am Sku-Profil, die Spieleinstellung
aber am Konto: zwei Charaktere in verschiedenen Profilen hoerten deshalb zwei
verschiedene Lautstaerken, und eine Aenderung in Blizzards eigenen Soundoptionen war
beim naechsten Anmelden stillschweigend wieder weg. Sku stellt die Werte jetzt nur
noch ein, merken tut sie sich das Spiel selbst - wie bei jedem anderen Spieler auch.
Die Regler im Menue zeigen ab sofort den echten Wert des Spiels, auch wenn du ihn
woanders geaendert hast. Was wegfaellt: Lautstaerken folgen keinem Sku-Profil mehr.
Technisch: SkuOptions:OnEnable schrieb soundChannels und soundSettings bei jedem Anmelden
aus dem Profil in die CVars zurueck, davor eine Sonderregel, die einen gespeicherten
Wert von 0 oder -1 als defektes Profil ansah und dann alle fuenf Kanaele neu aus den
CVars uebernahm. Der ganze Block ist raus. Die Menueknoten in SkuZOptions/Options.lua
lesen und schreiben die CVars direkt (tGetSoundCVarPercent, tSetSoundCVarPercent,
tGetSoundCVarBool); die zehn Schluessel sind aus SkuOptions.defaults und aus dem
Schema entfernt, und ein einmaliger Durchlauf in OnInitialize raeumt sie aus jedem
gespeicherten Profil - nicht nur aus dem aktiven, denn ohne Defaults-Eintrag wuerde
AceDB sie nie wieder abraeumen. soundChannels selbst bleibt: SkuChannel, der Kanal
fuer Skus eigene Ausgabe, ist eine echte Sku-Einstellung. Beim Lesen wird jetzt
gerundet statt abgeschnitten - tonumber("0.35") * 100 ergibt 34,999... und waere als
34 zurueckgekommen. Neue Profile bringen keine Lautstaerke-Vorgaben mehr mit; es
gelten die Standardwerte des Spiels.
Die vier Standardprofile werden angelegt, ohne dazwischen das Profil zu wechseln
Einfach: Beim ersten Anmelden legt Sku die vier Standardprofile an, falls sie fehlen. Das
geschah bisher, indem Sku der Reihe nach in jedes fehlende Profil wechselte und danach
in deines zurueck. Auf einem Hardcore-Realm bricht der Server lange Addon-Skripte ab,
und traf das diesen Ablauf, blieb der Charakter in einem fremden Profil stehen - mit
allen Einstellungen dieses Profils statt deinen. Ein Profil entsteht aber schon
dadurch, dass es seinen Namen bekommt; gewechselt werden muss dafuer gar nichts. Aus
zehn schweren Schritten sind vier kurze geworden, die mittendrin nicht schiefgehen
koennen.
Technisch: Die vier SetProfile-Aufrufe plus der Rueckwechsel in SkuCore/Core.lua sind
durch vier Zuweisungen in SkuOptions.db.sv.profiles ersetzt. AceDBs GetProfiles zaehlt
genau diese Tabelle auf, und ein Profil wird ohnehin erst beim ersten Hineinwechseln
per copyDefaults gefuellt - der gespeicherte Endzustand ist derselbe wie vorher, vier
leere Tabellen. Jeder SetProfile-Aufruf dagegen feuerte OnProfileShutdown und lief mit
removeDefaults und copyDefaults ueber den kompletten Defaults-Baum aller acht Module,
rund zehn Durchlaeufe in einem einzigen Frame. Mit dem Wechseln entfaellt auch das
Flag SkuCore.AutoChange, das OnProfileChanged solange stummschaltete und bei einem
Abbruch auf true stehen blieb - danach kam fuer den Rest der Sitzung kein
Profilwechsel mehr durch. Der Dispatcher pcallt diesen Handler, der Abbruch war also
unsichtbar.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v42.13
Kampf: "Unterbrechungen bei deinem Ziel ansagen" ist jetzt standardmaessig aus
Einfach: Auch der zweite der beiden Unterbrechungs-Schalter startet nun ausgeschaltet.
Beide Haelften der Aufteilung - dein aktuelles Ziel und alle Gegner - sind ab sofort
zuschaltbar statt vorgegeben, denn eine Unterbrechungs-Ansage draengt sich in alles
andere, was Sku gerade sagt, und die meisten Spieler wollen sie nicht von allein
laufen haben. An der Ansage selbst aendert sich nichts, nur daran, ob sie an ist, wenn
du die Einstellung nie angefasst hast. Wieder einschalten unter Kampf, Gegner,
"Unterbrechungen bei deinem Ziel ansagen". Wie beim Schalter fuer alle Gegner wird das
einmalig auch auf bestehende Profile angewandt, damit ein aus dem alten Einzelschalter
uebernommener Wert ihn nicht stillschweigend anlaesst.
Technisch: Der Migrationsblock in aqCombat.lua belegt yourTargetInterrupts nicht mehr aus
dem frueheren outputInterrupts-Schalter vor; der Standard ist false wie bei
allEnemiesInterrupts, und eine einmalige Marke yourTargetInterruptsDefaultOff raeumt
Profile auf, die fruehere 42.13-Builds bereits aus dem alten Wert gefuellt hatten.
AceDB-Defaults fuellen nur nil, deshalb braucht es die Marke und nicht bloss einen
geaenderten Standard. tOldOutputInterrupts faellt mit seinem letzten Leser weg.
Auktionshaus: der Komplettscan meldete sich als "Auktion gestartet"
Einfach: Der Start eines vollen Auktionshaus-Scans sagte "Auktion gestartet, bitte warten"
- das verraet nicht, welche der beiden Scan-Arten laeuft, und eine Suche klingt damit
viel zu aehnlich wie ein Komplettscan, der das Auktionshaus danach minutenlang
belegt. Jetzt heisst es "Voller Auktionshaus Scan gestartet, bitte warten", passend
zur Abschlussmeldung, die schon immer "Voller Auktionshaus Scan abgeschlossen" lautet.
Technisch: Der Locale-Eintrag "Full scan started" wurde in deDE, enUS und frFR neu
formuliert. Kein Codepfad hat sich geaendert; die Ansagestelle in auctionHouse.lua
bleibt unberuehrt.
Sku Fokus: der Aufruf eines Fokus kam verzoegert und stotterte
Einfach: Wer eine Fokus-Taste drueckt, um den gespeicherten Fokus ins Ziel zu nehmen,
hoerte den Namen mit einer spuerbaren Verzoegerung - haeufig kurz angerissen und dann
noch einmal von vorn. Ein Tastendruck liefert zwei Ereignisse, eines beim
Herunterdruecken und eines beim Loslassen, und Sku hat das hinterlegte Ziel-Makro auf
beiden ausgefuehrt. Der zweite Durchlauf nahm dasselbe Ziel noch einmal, und weil jede
Zielansage die laufende Sprachausgabe zuerst abraeumt, wurde die gerade begonnene
Ansage gestoppt und neu gestartet - verzoegert um genau die Zeit, die die Taste
gehalten wurde. Jetzt laeuft das Makro einmal pro Druck. Aufgefallen ist das gerade
jetzt, weil die Fokus-Tasten seit v42.13 in der Voreinstellung auf dem Ziffernblock
liegen und damit ueberhaupt erst benutzt werden.
Technisch: Die acht Fokus-Knoepfe in skuFocus.lua meldeten sich mit
RegisterForClicks("AnyUp", "AnyDown") an, fuehrten das Makro also auf beiden Flanken
aus. Das Steuerungsfenster der SET-Tasten hatte denselben Fehler und war bereits auf
eine Flanke umgestellt worden; die GET-Knoepfe waren dabei ausdruecklich ausgenommen
worden. Sie melden sich jetzt ebenfalls nur noch mit "AnyDown" an. Im Log bleiben pro
Druck zwei PLAYER_TARGET_CHANGED und genau eine Sprachausgabe uebrig; diese zwei
Ereignisse stammen aus /target Name selbst, das erst das alte Ziel leert und dann das
neue setzt - erkennbar daran, dass die Soft-Target-Sperre zwei verschiedene Werte
schreibt (0, dann 2) und nicht zweimal denselben.
Zielwechsel: doppelte Reichweitenpruefung und leerlaufende Gruppenschleifen
Einfach: Bei jedem Zielwechsel hat Sku Gruppe und Schlachtzug vollstaendig abgefragt, um
zu erkennen, ob das Ziel schon gegen jemanden aus der eigenen Gruppe kaempft - auch
allein unterwegs, wo es weder das eine noch das andere gibt. Das waren 88 Abfragen ins
Leere, und mit der Einstellung "Spielergesteuerte Einheiten mit allgemeinen
Beschreibungen ansagen" wurden ueber zweitausend daraus. Ausserdem lief die
Entfernungspruefung bei jedem Zielwechsel zweimal: der zweite Aufruf steckte in einem
Programmteil, der sein Ergebnis nie bekommen konnte und deshalb nie etwas angesagt
hat. Beides ist entfernt. An dem, was Sku sagt, aendert sich nichts, und die
Kampfstatus-Erkennung bleibt vollstaendig - in Gruppe und Schlachtzug werden weiterhin
alle Mitglieder geprueft, dazu immer Begleiter und man selbst, und die Frage "wen
greift mein Ziel gerade an" wird unveraendert gestellt.
Technisch: In SkuMob PLAYER_TARGET_CHANGED sind die Schleifen ueber party1-4 und raid1-40
jetzt mit IsInGroup() / IsInRaid() abgesichert, und der Schlachtzug laeuft nur bis
GetNumGroupMembers() - dieselbe Schreibweise wie in SkuAuras und SkuQuest. Die
Reihenfolge bleibt erhalten (Gruppe vor Schlachtzug), damit ein Mitglied der eigenen
Untergruppe weiterhin als "party N" angesagt wird. In SkuNav ist der aForTarget-Zweig
von GetNonAutoLevel entfallen: er begann mit DoRangeCheck, das gar keinen Wert
zurueckgibt, womit seine erste Bedingung nie erfuellt war - geblieben war nur die
Nebenwirkung, eine zweite erzwungene Reichweitenpruefung samt moeglichem zweitem
Entfernungston pro Zielwechsel. Sein Aufrufer in SkuMob und die nur dort benutzte
Hilfsfunktion GetCreatureIdFromCreatureGUID sind mit entfallen.
Gegner im Kampf: die Anzeige war fuer einen Teil der Nutzer dauerhaft an
Einfach: Betroffen ist nur, wer "Spielergesteuerte Einheiten mit allgemeinen
Beschreibungen ansagen" eingeschaltet hat (Voreinstellung: aus). Dann meldete jedes
angepeilte Ziel "im Kampf" - Ton oder Ansage -, auch ein voellig unbeteiligtes Tier
auf der Wiese. Fuer eine Einheit, die Sku nicht einordnen kann, und dazu zaehlt auch
eine, die gar nicht existiert, liefert die Namensfunktion eine leere Zeichenkette. Die
landete als Eintrag in der Namensliste der eigenen Gruppe. Der Vergleich danach -
"greift mein Ziel jemanden aus meiner Gruppe an?" - bekam fuer "mein Ziel greift
niemanden an" ebenfalls eine leere Zeichenkette, und die passte auf genau diesen
Eintrag. Die Antwort war damit immer ja. Leere Namen werden jetzt weder eingetragen
noch verglichen. Fuer Betroffene heisst das: der Kampf-Ton kommt deutlich seltener,
naemlich nur noch, wenn das Ziel wirklich gegen einen selbst, den Begleiter oder die
Gruppe kaempft. Dieselbe Ursache traf "Private Sku-Schlachtzugszeichen automatisch auf
Ziele im Kampf setzen": dort bekam praktisch jedes Ziel ein Zeichen.
Technisch: GetTtsAwareUnitName liefert mit vocalizePlayerNamePlaceholdersSkuTts = true ""
fuer jede Einheit, die weder man selbst noch Begleiter noch Gruppenmitglied ist.
tRosterNames bekam diesen leeren Schluessel, und die Abfrage von targettarget traf ihn
wieder. Beide Seiten pruefen jetzt zusaetzlich auf name ~= "".
Auren: eine Messhilfe aus der Umbauphase lief im Auslieferungszustand mit
Einfach: Der Zwischenspeicher fuer Aurenlisten hat jede Liste zusaetzlich ein zweites Mal
komplett neu aufgebaut, um beide Ergebnisse gegeneinander zu pruefen. Das war eine
Kontrolle aus der Umbauphase, die versehentlich eingeschaltet ausgeliefert wurde - und
sie kostete genau die Arbeit, die der Zwischenspeicher einspart. Sie ist jetzt aus;
mit /skuauracache verify on laesst sie sich fuer eine Fehlersuche wieder einschalten.
Atlas Loot: Ruckler beim Anmelden und beim Oeffnen
Einfach: Seit kurzem hing das Spiel ein paar Sekunden nach dem Ladebildschirm fuer
vier bis fuenf Sekunden komplett, und danach dauerte es rund zwanzig statt acht
Sekunden, bis alles ruhig lief. Schuld war die Atlas-Loot-Anbindung: Sku hat bei
jeder Anmeldung und jedem Neuladen die komplette Atlas-Loot-Datenbank durchgearbeitet
- rund 40.000 Eintraege in einem Stueck - auch dann, wenn man Atlas Loot in der
ganzen Sitzung nie geoeffnet hat. Das passiert jetzt nicht mehr beim Anmelden,
sondern erst, wenn man Atlas Loot tatsaechlich oeffnet, und es laeuft in kleinen
Haeppchen im Hintergrund, statt das Bild anzuhalten. Wer Atlas Loot nicht benutzt,
zahlt gar nichts mehr dafuer - auch die Datenpakete von Atlas Loot werden dann nicht
mehr unnoetig geladen. Zweiter Teil: auch das Aufklappen der Suchliste in Atlas Loot
hing spuerbar. Diese Liste hat rund 20.000 Eintraege, und fuer jeden einzelnen wurde
beim Aufbauen der Name neu ermittelt und beim Server nach Gegenstandsdaten gefragt -
fuer 20.000 Eintraege, die man noch gar nicht angesehen hat. Der Name ist an dieser
Stelle laengst bekannt, und die Daten braucht nur der Eintrag, auf dem man gerade
steht. Die Liste oeffnet sich jetzt entsprechend schneller.
Technisch: alIntegrationQueryAll baut zwei Umkehr-Verzeichnisse ueber die Atlas-Loot-
Daten auf: "welcher Boss laesst diesen Gegenstand fallen" und die Namensliste fuer
die Suche. Der Lauf hing an einer PLAYER_LOGIN-Wiederholungsleiter (5/10/20/35/60 s)
plus einem Netz an PLAYER_ENTERING_WORLD/ZONE_CHANGED_NEW_AREA und lief damit etwa
drei Sekunden nach dem Betreten der Welt - ungeteilt, in einem einzigen Frame. Die
Begruendung dafuer war ueberholt: sie sollte dem Strg+Shift+L-Sprung die kalte
Wartezeit ersparen, doch dieser Sprung hat seine Kontexterkennung laengst verloren
und oeffnet nur noch den Menuepunkt, was den Aufbau selbst anstoesst. Drei der vier
Tabellen, die der Lauf fuellte, hatte ohnehin niemand gelesen: alLookupBosses und
alLookupInstances wurden nur geschrieben und dienten allein als "schon gelaufen?"-
Merker fuer genau die Leiter, die den Lauf ausloeste; alDropsByBoss und
alDropsByInstance wurden nur hinter einer Bedingung gelesen, die nie wahr sein kann,
seit das Kontext-Flag ausschliesslich auf nil gesetzt wird. Alle vier sind entfernt,
zusammen mit dem Flag, seinem 120-Sekunden-Timer und BuildContextualWishlistEntry.
Der verbliebene Lauf ist eine Koroutine mit 30-ms-Budget pro Frame: das Menue
startet ihn im Hintergrund (QueryAllStart), und wer ein vollstaendiges Verzeichnis
braucht - Suche, Wunschliste nach Dungeon, "Faellt bei" - wartet an seiner eigenen
Stelle darauf (alIntegrationQueryAll, ein Nichts-Tun, sobald es steht). Pro Eintrag
wurde es ausserdem billiger: die Namensaufloesung fragt jetzt zuerst Skus eigene
Gegenstandstabelle statt GetItemInfo, was pro unbekannter ID eine Server-Anfrage
ausgeloest hat, und spart die sechs Ersetzungslaeufe fuer Namen, die aus dieser
Tabelle kommen und ohnehin keine Markup-Zeichen enthalten. Der Menueaufbau der
Suchliste war der zweite Brennpunkt: alIntegrationItemMenuBuilder nimmt jetzt
optional den bereits bekannten Namen entgegen (die Suchliste ist nach genau diesem
Namen verschluesselt), und ueberspringt damit pro Eintrag die Namensaufloesung, den
Unescape-Lauf und vor allem SkuCore:RequestItemData - also ein ItemMixin samt
registriertem Lade-Rueckruf und eine Server-Abfrage je nicht zwischengespeicherter
ID, rund 20.000 Mal in einem Frame. Die Beutelisten eines Bosses (ein paar Dutzend
Zeilen) fordern die Daten weiterhin vorab an, damit sich unbekannte Namen dort
weiter selbst nachtragen, und der Eintrag, auf dem der Cursor steht, fordert sie in
seinem OnEnter ohnehin an - der gesprochene Text aendert sich also nicht.
Kollisionswarnung: Toene ohne Hindernis
Einfach: Der "du haengst fest"-Ton konnte auftauchen, waehrend man einfach von einem NPC
zum naechsten lief, ohne dass irgendetwas im Weg stand. Der Zaehler hinter der
Warnung wurde nie zurueckgesetzt, also sammelten sich harmlose Einzelmessungen ueber
Minuten an, und jede sechste loeste einen Ton aus.
Technisch: Die Warnung vergleicht die in einem 0,15-Sekunden-Takt zurueckgelegte Strecke
mit der, die das aktuelle Tempo haette schaffen muessen, und gibt nach sechs zu
langsamen Takten einen Ton. Nur hatte der Zaehler ausser beim Ausloesen keinerlei
Ruecksetzung - nicht bei einem guten Takt, nicht wenn die Warnung gar nicht scharf
war - er war also ein Lebenszeit-Sammler statt einer Sechserserie. Der erste Takt
nach jedem PLAYER_STARTED_MOVING misst ein angeschnittenes Fenster, weil die vorige
Messung noch im Stand erfolgte, und faellt damit zwangslaeufig als "zu langsam" aus:
etwa jeder sechste Bewegungsstart ergab einen Ton, Minuten auseinander und ohne
jeden Zusammenhang. Das steckt schon lange drin, zaehlte aber nur, solange man
selbst eine Bewegungstaste hielt; seit in dieser Version auch motorgetriebene Wege
mitwarnen, zaehlt jeder automatische Weg zum Ziel mit - deshalb faellt es beim
Abarbeiten von NPCs auf. Der Zaehler wird jetzt bei jedem guten Takt und immer, wenn
die Warnung nicht scharf ist, zurueckgesetzt, genau wie es die Folgen-Variante der
Warnung schon tat. Diese Variante bleibt unveraendert: sie wird von AUTOFOLLOW_END
entschaerft, und der Ton beim Ende des Folgens kommt aus genau diesem Weg - wer ihn
hoert, hat den Beweis, dass der Status zurueckgesetzt wurde. Die Warnung
hinterlaesst beim Ausloesen jetzt ausserdem eine Zeile im Debug-Log, damit sich
"Toene aus dem Nichts" dem Weg zuordnen lassen, aus dem sie kamen.
Taxiflug: zwei falsche Flugansagen
Einfach: Zwei Dinge wurden angesagt, die nicht stimmten. Erstens sagte Sku kurz
vor der Ankunft "Vorzeitige Landung moeglich bei X" - und X war das Ziel,
das man ohnehin gerade anflog; dort vorzeitig zu landen heisst schlicht
anzukommen. Zweitens kam "Flug beendet" (oder "Flug gestartet") gelegentlich
lange nach dem Flug, typischerweise in dem Moment, in dem man das naechste
Mal auf- oder abgesessen ist, mitunter Minuten spaeter und ohne jeden Bezug
zu einem Flugpunkt. Die erste Ansage bleibt jetzt aus, die zweite kommt
genau dann, wenn der Flug wirklich beginnt oder endet, und sonst nie.
Technisch, das Ziel als Landepunkt: Den Ausschluss des letzten Punktes gab es
bereits, nur rutschte der Routen-Zeiger im entscheidenden Moment darunter
weg. Die Route wird beim Start abgegriffen, und ein Zwischenstopp gilt als
passiert, sobald er naeher
als 250 Yards ist. Das Taxi fliegt aber direkt in seinen letzten Punkt
hinein, also wurde auch dieser "passiert": der Zeiger lief hinter das
Routenende, der naechste Halt war nil, und die Zielbestimmung fiel still auf
die Notloesung "naechstgelegener Flugpunkt" zurueck. Die kennt die Route
nicht, damit wechselte die Quelle von "route" auf "nearest" - und genau
daran haengt die Bedingung, die den letzten Punkt stummschaltet. Das Ziel
war zu dem Zeitpunkt laengst innerhalb der 800-Yard-Schwelle, also kam die
Ansage. Der Zeiger bleibt jetzt auf dem Ziel stehen, statt darueber
hinauszulaufen: das Ziel ist kein Halt, den man passiert, sondern der Ort,
an dem der Flug endet. Damit greift die Stummschaltung bis zur Landung, und
die Taste kann das Ziel weiterhin benennen.
Technisch, die verspaetete Ansage: Sie hing an zwei Merkern, die
PLAYER_CONTROL_LOST bzw.
PLAYER_CONTROL_GAINED auf 1 setzten und die AUSSCHLIESSLICH das naechste
PLAYER_MOUNT_DISPLAY_CHANGED wieder abgeraeumt hat. Blieb dieses Ereignis aus
- oder kam es an der Landung vor dem Kontroll-Ereignis - dann wartete die 1
einfach weiter, und der naechste Reittier-Wechsel loeste sie aus.
PLAYER_CONTROL_GAINED feuert ausserdem fuer allerlei, was keine Landung ist
(Gedankenkontrolle endet, Zwischensequenz, Rueckstoss, Fahrzeug), sodass der
Merker auch voellig ohne Flug gesetzt werden konnte. Der Zustand wird jetzt
aus UnitOnTaxi ABGELEITET statt gemerkt: gesprochen wird nur bei einem echten
Wechsel falsch->wahr bzw. wahr->falsch, jedes beteiligte Ereignis fuehrt
denselben idempotenten Test aus (Kontroll-Ereignisse zusaetzlich zeitversetzt,
weil der Client-Merker dem Ereignis hinterherhinkt), und Login/Neuladen
uebernimmt den laufenden Zustand stumm.
Technisch, zur Sicherheit obendrauf: Im Taxi-Modul ("Vorzeitige Landung
moeglich bei X")
konnte dieselbe Klasse Fehler nicht auftreten - die Ansage haengt hinter
UnitOnTaxi UND dem sichtbaren Abbruch-Knopf. Trotzdem abgesichert, weil beide
Merkmale Client-Zustand sind: Kontrolle zurueckerhalten heisst jetzt "Flug
vorbei, Punkt" - der Beobachter wird abgeraeumt und kein Ereignis darf ihn
wieder starten, bis wirklich ein neuer Flug angetreten wird. Zusaetzlich
loescht ein kurzzeitig unsichtbarer Abbruch-Knopf (z.B. bei einem Zonenwechsel
im Flug) nicht mehr die Ansage-Merker, was denselben Flugpunkt sonst ein
zweites Mal ansagen konnte. "/skutaxi" zeigt den neuen Zustand als "landed=".
Gruppeneinladung und Beschwoerung: der Ablehnen-Knopf ist zurueck
Einfach: Bei einer Gruppeneinladung oder einer Beschwoerung ("Port") bot das
Menue nur noch "Annehmen" an - der Knopf zum Ablehnen fehlte, und er fehlte
so lange, wie der Dialog offen war. Beide Knoepfe stehen wieder in der Liste.
Technisch: Blizzard sperrt genau bei diesen Abfragen den Ablehnen-Knopf fuer
einen Moment nach dem Erscheinen des Dialogs (SetupLockOnDeclineButtonAndEscape,
dieselbe Hilfsfunktion, die dort auch Escape abschaltet) - als Schutz gegen
versehentliches Wegklicken bei Einladungs- und Beschwoerungsspam. Skus
generischer Fensterleser ueberspringt jedes ausgegraute Bedienelement, und er
liest ein Popup genau EINMAL aus, 0.1 s nach dem Anzeigen (GENERIC_OnOpen) -
mitten in dieser Sperrzeit. Der Ablehnen-Knopf fiel also heraus, und da nichts
das Menue neu aufbaut, solange der Dialog einfach nur dasteht, kam er nie
wieder. SkuCore:IterateChildren nimmt Knoepfe von StaticPopup-Dialogen jetzt
von der Regel "nie ein deaktiviertes Element auflisten" aus: einen Menuepunkt
anzusteuern und Enter zu druecken ist eine bewusste Handlung, kein Verklicken.
Diese Knoepfe behalten ausserdem ihren OnClick-Handler, auch wenn das
deaktivierte Element keine Mausklick-Eingabe meldet - sonst stuende der
Eintrag zwar in der Liste, waere aber wirkungslos.
Kampf: ein Popup liess sich lesen, aber nicht beantworten
Einfach: Ging waehrend eines Kampfes ein Popup auf - eine Gruppeneinladung, eine
Beschwoerung, die Frage nach dem Wiederbeleben -, dann konnte Sku es vorlesen und man
konnte darin navigieren, aber die Eingabetaste tat nichts: Der Eintrag wurde nur noch
einmal vorgelesen. Man musste warten, bis der Kampf vorbei war, und eine Einladung
lief in der Zwischenzeit ab. Die Knoepfe eines Popups lassen sich jetzt auch im Kampf
druecken, alle vier, nicht nur Annehmen und Ablehnen.
Technisch: Im Kampf erreicht die Aktivierungstaste den sicheren Menue-Knopf gar nicht:
PLAYER_REGEN_DISABLED blendet OnSkuOptionsMain aus, dessen OnHide loescht die
Override-Bindings dieses Knopfes noch waehrend des Gnadenfensters, und die Taste
laeuft stattdessen ueber das Snippet von SkuCombatMenuKey, das die Eingabetaste als
"nur Route" behandelt und sie direkt an den unsicheren Verteiler gibt
(SkuCore/combatMenuKeys.lua). Ergebnis: lesbar, navigierbar, tot bei Enter.
Anders als bei den Taschen- und Handelspfaden braucht es dafuer keinen Spiegel und
kein sicheres Vorbereiten: Ein StaticPopup-Knopf ist KEIN geschuetzter Frame, sein
OnClick ist gewoehnliches Lua (StaticPopup_OnClick ruft OnAccept/OnCancel des Dialogs
auf: AcceptGroup, DeclineGroup, ResurrectAccept, RepopMe, ConfirmSummon). Nichts davon
haengt am Hardware-Ereignis, also wirkt der direkte Aufruf im Kampf genau wie
ausserhalb. Bewusst auf die Popup-Knoepfe beschraenkt - jede andere Klick-Nutzlast in
diesem Menue braucht das echte Hardware-Ereignis und gehoert in den Spiegel.
Abgesichert: nur im Kampf, nur solange der Knopf da ist, und nur solange Blizzard ihn
AKTIV hat (der Ablehnen-Knopf ist in seiner ersten Sekunde gesperrt, dort ist auch
"/click" wirkungslos). Neu ist ausserdem, dass alle vier Knoepfe so behandelt werden;
Knopf 3 und 4 fielen vorher auf den allgemeinen Klickpfad ohne jede unsichere Aktion
zurueck. /skucheck menu zaehlt die Faelle mit, in denen im Kampf aktiviert wurde und
gar kein Knopf mehr da war.
Tippen in Eingabefeldern: kein Nachplappern mehr nach dem Schliessen
Einfach: Beim Tippen in ein Sku-Eingabefeld (Brief schreiben, Suchfeld,
Auktionshaus) hinkte die Ansage der Zeichen dem Tippen hinterher, ueberschlug
sich, und Buchstaben kamen noch, wenn das Feld laengst geschlossen war -
besonders deutlich mit SAPI-Stimmen, die ein Tastendruck bisher nicht
abgebrochen hat. Sku tippt jetzt so, wie es ein Screenreader tut: Der naechste
Anschlag bricht die Ansage des vorigen ab, statt sich dahinter zu stellen. Was
waehrend einer laufenden Ansage getippt wurde, wird zu EINER Ansage
zusammengefasst, sodass auch Einfuegen mit Strg+V oder eine gedrueckt
gehaltene Pfeiltaste keinen Schwall mehr ausloest. Und beim Schliessen des
Feldes - mit Enter, mit OK, mit Escape oder auf jedem anderen Weg - wird nicht
mehr nur das Wartende verworfen, sondern auch die gerade laufende Ausgabe
abgebrochen. Nebenbei behoben: die Zeichen ( und % wurden beim Tippen gar
nicht angesagt.
Technisch: Das Echo in SkuOptions:EditBoxShow haengte je getipptem Zeichen eine
eigene Aeusserung an die BTTS-Queue. Der Rueckstau-Deckel aus v42.11
(GetBttsQueueDepth / TrimBttsQueue) griff dabei ins Leere: Die Pumpe in
SkuVoice ueberspringt ihre 0.1-s-Taktung, sobald mehr als ein Eintrag wartet
(`#mSkuVoiceQueueBTTS > 1`), und schiebt den ganzen Schwall binnen weniger
Bilder per C_VoiceChat.SpeakText in die Queue des CLIENTS. Skus eigene Queue
ist danach leer, die gemessene Tiefe praktisch immer 0, der Deckel loest nie
aus, und beim Schliessen findet Trim nichts mehr zum Wegwerfen - der Rueckstau
steht zu dem Zeitpunkt in der Client-/SAPI-Queue, an die nur ein echtes
StopSpeakingText herankommt. Das Echo laeuft jetzt ueber genau einen Slot:
Zeichen werden bis zum naechsten Flush gesammelt (hoechstens 6, die neuesten
gewinnen), als EINE ueberschreibende Aeusserung gesprochen und auf 0.1 s
Mindestabstand begrenzt; ein Generationszaehler verwirft Flush-Timer und
verzoegerte Pfeil-Lesungen, sobald das Feld zu ist. Neu ist
SkuVoice:CancelBttsOutput - leert die BTTS-Queue, ruft StopSpeakingText und
setzt die Nachsperre der Pumpe auf 0.15 s, damit die unmittelbar folgende
Bestaetigung nicht vom asynchron eintreffenden Stop erschlagen wird; es haengt
an ENTER, OK, ESCAPE und am OnHide des Rahmens (also auch an einem fremden
:Hide()). Ausserdem: SkuVoice:CheckIgnore vergleicht jetzt mit string.find(...,
plain=true) - getippte Sonderzeichen wie ( oder % waren Lua-Muster und warfen
"unfinished capture" bzw. "malformed pattern", was der pcall des Aufrufers
verschluckte; und das Echo setzt ignoreLinks, denn bisher lief jeder
Tastendruck durch die komplette Wiki-Link-Suche, deren Ergebnis hier ohnehin
verworfen wird.
Leistungsverbesserungen und Korrekturen beim Laden der Zauberdatenbank
Einfach: Beim Anmelden meldeten einige Spieler einen gesprochenen "Sku Datenbank
Fehler, Datensatz spells". Gemeldet wurde das von Era-Spielern, der
gemeinsame Nenner ist aber die Rechenleistung und nicht der Client: auf einem
schnellen Rechner passierte es nie, auf einem schwaecheren jedes Mal, und auf
TBC waere es genauso moeglich gewesen. Die Datenbank selbst war
dabei nie kaputt: Gescheitert ist nur die daraus abgeleitete Auswahlliste fuer
die Auren, die in EINEM Durchgang ueber rund 90.000 Eintraege aufgebaut wurde.
Auf einem langsameren Rechner brach der Client diesen Durchgang mit "script ran
too long" ab - und weil die Liste beim Aufbau direkt beschrieben wurde, blieb sie
danach halb gefuellt: In den Aura-Einstellungen fehlte ein Teil der Zauber, und
Auren, die auf einen fehlenden Eintrag zeigten, sagten nichts mehr an oder
liessen das Menue mit einem Fehler stehen. Der Aufbau laeuft jetzt in kleinen
Haeppchen ueber mehrere Bilder verteilt, genau wie der uebrige Datenbankaufbau
nach dem Anmelden, und wird erst ganz am Ende in einem Stueck uebernommen. Bricht
er trotzdem einmal ab, bleiben die bisherigen Listen unveraendert stehen statt
halb gefuellt, es wird kein Datenbankfehler mehr gesprochen, und der Rest der
Zauberdaten gilt weiterhin als in Ordnung. Zusaetzlich wird die Liste nur noch
einmal pro Sitzung gebaut statt bei jedem Ladebildschirm neu.
Technisch: SkuAuras:BuildAttributeValueLists laeuft ueber itemLookup UND SpellDataTBC
und legt pro Zeile eine Tabelle und ein bis zwei zusammengesetzte Zeichenketten
an. Der Aufruf hing bisher an zwei Stellen, beide synchron: am Build-Step
"auraValueLists" (nach items+spells) und an PLAYER_ENTERING_WORLD. Die Funktion
nimmt jetzt einen optionalen Yield-Callback, den sie alle 1000 Zeilen abfragt,
baut in lokale Tabellen und veroeffentlicht diese am Ende mit je einer Zuweisung
(atomar - ein Abbruch aendert gar nichts mehr). Gefahren wird sie von einer
eigenen Coroutine mit OnUpdate-Pumpe, die sich das gemeinsame Frame-Budget nach
dem Anmelden teilt (Sku:BuildFrameBudgetMs, registriert als Build-Worker
"skuAuraLists") - drei laufende Worker kosten weiterhin zusammen 150 ms pro Bild.
Der Build-Step startet nur noch diesen Treiber und ruft ctx.fail nicht mehr auf:
Ein Fehler der abgeleiteten Liste hatte zuvor die ganze Datenfamilie "spells" als
gescheitert markiert und die Fehleransage ausgeloest, obwohl die Zauberdaten
vollstaendig waren. Fehler landen jetzt in SkuErrorLog ("skuAuraLists") und im
Debug-Log. PLAYER_ENTERING_WORLD startet denselben Treiber, der nach einem
erfolgreichen Aufbau ein No-Op ist - der bisherige komplette Neuaufbau bei jedem
Zonenwechsel und jedem Instanzbetritt entfaellt damit. Ausserdem ueberspringt der
Aufbau eine Zauberzeile ohne Namen fuer die aktive Sprache, statt an ihr
auszusteigen, und die drei ungeschuetzten friendlyName-Zugriffe im Aura-Menue
fallen auf den Rohschluessel zurueck.
Ein Gegner, der euch vor seinem Tod vergiftet hat, wird nicht mehr weitergezaehlt
Einfach: Die Ansage der Gegnerzahl war seit v42.10 in normalen Kaempfen zuverlaessig,
hatte aber einen Fall uebrig: Wenn ein Gegner euch kurz vor seinem Tod ein Gift
oder einen anderen anhaltenden Effekt verpasst hat, fiel die Zahl bei seinem Tod
korrekt, sprang kurz darauf wieder um eins hoch und fiel erst dann endgueltig,
wenn das Gift ablief - der Gegner war da laengst tot. Das ist behoben, ohne dass
an der Erkennung selbst etwas veraendert wurde: es wird nichts Neues gezaehlt,
eine Sache hoert nur auf, faelschlich mitgezaehlt zu werden.
Technisch: Ein gestorbener Gegner wird per GUID gemerkt, damit ihn eine nachlaufende
Kampf-Log-Zeile nicht wiederbeleben kann. Diese Markierung wurde bisher in
PLAYER_REGEN_ENABLED komplett geleert - also genau in dem Moment, in dem euch der
Tod des letzten Gegners aus dem Kampf nimmt, und damit unmittelbar bevor der
erste Gifttick eintrifft. Jeder Tick ist eine Kampf-Log-Zeile mit dem toten
Gegner als Quelle und euch als Ziel; die Aufnahme-Logik liest das als "ein Gegner
kaempft gegen uns" und nahm die Leiche ueber ihre GUID wieder auf. Die zweite
Null kam danach nur noch ueber den 6-Sekunden-Leerlauf-Sweep nach dem letzten
Tick zustande. Die Markierung traegt jetzt einen Zeitstempel und wird am
Kampfende nicht mehr pauschal geloescht, sondern nur noch, wenn sie aelter als 60
Sekunden ist. Innerhalb eines Kampfes aendert sich damit gar nichts - dort galt
die Markierung ohnehin bis zum Kampfende, weshalb der Fall "einer von zwei
Gegnern stirbt vergiftet, der zweite lebt weiter" schon vorher richtig gezaehlt
wurde. Es kommt kein neuer Zustand und keine neue Sonderregel dazu, nur eine
Lebensdauer fuer eine Markierung, die es schon gab. Die vorhandene Ausnahme
bleibt: taucht dieselbe GUID nachweislich lebend an einem Unit-Token auf, wird
die Markierung sofort aufgehoben, ein echter Gegner kann also nie dauerhaft aus
der Zaehlung verschwinden.
Ein erfolgreich abgeschlossener Handel wurde als zurueckgezogene Bestaetigung gemeldet
Einfach: Kam ein Handel wirklich zustande, endete er trotzdem mit " hat die
Bestaetigung zurueckgezogen". Es war nichts schiefgegangen: der Server raeumt
beim Abschluss erst beide Bestaetigungshaken ab und schliesst danach das Fenster,
und dieses Abraeumen sah genauso aus wie ein echter Rueckzug. Die falsche Zeile
entfaellt jetzt. Eine "Handel abgeschlossen"-Ansage gibt es dafuer bewusst nicht:
der Client 2.5.6 liefert kein Signal, das Abschluss von Abbruch unterscheidet,
und eine geratene Meldung waere schlechter als keine.
Technisch: Mitgeschnitten fuer eine erfolgreiche Verzauberung im Handel, alles
innerhalb einer Sekunde: TRADE_ACCEPT_UPDATE(1,1) -> (0,1) -> (0,0) ->
TRADE_CLOSED. TRADE_ACCEPT_UPDATE las diese 1->0-Uebergaenge als echten Rueckzug.
Unterscheiden laesst sich das nicht: TRADE_CLOSED traegt keine Nutzdaten, und
ERR_TRADE_COMPLETE / ERR_TRADE_CANCELLED existieren auf 2.5.6 nicht (gegen die
mitgelieferte TradeInfoDocumentation.lua geprueft). Die beiden Rueckzugs-Ansagen
warten jetzt 0,5 s hinter einem Generationszaehler, den ResetTradeAcceptState()
an jeder Handelsgrenze hochzaehlt, und entfallen, wenn der Handel beendet ist,
das Fenster weg ist oder die Seite wieder auf bestaetigt steht.
"Handel bestaetigt" wurde jedes Mal verschluckt
Einfach: Wer den Handel aus dem Menue heraus bestaetigt hat, hat die eigene
Bestaetigung nie gehoert. Und von mehreren Handelsansagen kurz hintereinander
wurde ueberhaupt nur die letzte gesprochen - also ausgerechnet die falsche. Jetzt
kommen sie alle, in der richtigen Reihenfolge.
Technisch: OutputStringBTtts haengt mit aOverwrite=true einen "queuereset" an, und
die Pumpe loescht alles, was VOR diesem Marker in der Warteschlange steht - in
einem Schwung frass also jede Handelsansage ihre Vorgaengerin. Alle
Handelsansagen uebergeben jetzt false. Das allein rettet die eigene Bestaetigung
noch nicht: bestaetigt man aus dem Menue, steht die Serverantwort schon in der
Schlange, bevor das Menue seine eigene Zeile fuer den Tastendruck anhaengt, deren
Reset sie dann loescht. Die Bestaetigungsansagen laufen deshalb ueber tSayAccept
mit 0,35 s Verzoegerung hinter die Menuezeile. Reine Reihenfolge, kein
Zustandsraten - und bewusst ohne Generationspruefung, denn ein unmittelbar danach
schliessender Handel ist genau der Fall, in dem diese Bestaetigung zaehlt.
Enter entzaubert bzw. verzaubert einen Taschengegenstand wieder - in beiden Reihenfolgen
Einfach: Wer Entzaubern wirkt (oder eine Verzauberung, einen Ruestungsflicken, ein
Waffenoel aufnimmt), waehrend er in der Taschenliste bereits auf dem Zielobjekt
steht, und dann Enter drueckt, bei dem passierte bisher gar nichts - nur
Strg+Enter half. Die andere Reihenfolge ging: erst wirken, dann zum Gegenstand
navigieren. Enter wendet jetzt in beiden Reihenfolgen an. Der Linksklick ist
dafuer tatsaechlich der spieleigene Weg: im Taschen-Code von Blizzard benutzt ein
Linksklick auf einen Gegenstand diesen fuer den Zauber, solange ein Zauber auf
ein Gegenstandsziel wartet. In v41 lief das ueber den alten Eintrag
"Linksklick"; der Menue-Umbau in v42.00 hat ihn verloren, und v42.04 hat das
Anwenden nur fuer die Reihenfolge "erst wirken" zurueckgeholt.
Technisch: Der sichere Linksklick-Knopf wird beim FOKUSSIEREN eines Eintrags
bestueckt, und das Anwenden-Makro eines Taschengegenstands ("/use Tasche Slot")
nur, solange in diesem Moment SpellIsTargeting() wahr ist. Wird danach gewirkt,
trug der Knopf weiter die Bestueckung von vorher - bei einem Taschengegenstand
also gar keine -, und der in PreClick genommene Targeting-Schnappschuss laesst
zusaetzlich den insecure PickupContainerItem-Rueckfall aussetzen: der Tastendruck
tat buchstaeblich nichts. Die Bestueckung ist aus dem generischen OnEnter nach
SkuOptions:StageClickMacros gewandert (beide sicheren Knoepfe) und wird von zwei
Stellen erneut ausgefuehrt: CURRENT_SPELL_CAST_CHANGED, dessen Handler leer war
und dessen Dispatcher-Signatur um eine Stelle verschoben war, und dem PreClick
des Linksklick-Knopfes selbst, der laeuft, bevor der sichere Handler die
Attribute liest - der Tausch zaehlt also noch fuer genau diesen Tastendruck.
Neu bestueckt werden nur Eintraege mit Anwenden-Makro, nur bei offenem Menue und
nur ausserhalb des Kampfes.
Strg+Enter auf einem Haendlergegenstand oeffnete die Anprobe, statt zu kaufen
Einfach: Beim Haendler soll Strg+Enter (Rechtsklick) auf einem Gegenstand einen
davon kaufen. Stattdessen ging die Anprobe auf. Der Kauf ueber das Untermenue
des Gegenstands hat immer funktioniert und bleibt unveraendert; die Taste kauft
jetzt ebenfalls, im Rueckkauf-Reiter auch.
Technisch: Die Rechtsklick-Taste traegt standardmaessig STRG, ein Makro "/click
RightButton" liest den LIVE-Tastaturzustand, und das XML jedes nativen
Gegenstandsknopfes leitet JEDEN modifizierten Klick auf *_OnModifiedClick ->
HandleModifiedItemClick -> DressUpLink um - der einfache Rechtsklick-Zweig wird
nie erreicht. Das ist dieselbe Falle, die seinerzeit die Oele auf angelegten
Waffen kaputtgemacht hat, dort mit "/use " geloest. Haendlergegenstaende
rufen jetzt direkt Blizzards unverpacktes MerchantItemButton_OnClick auf, womit
die Abfragen fuer Sonderwaehrung und hohen Preis erhalten bleiben. Taschen, Bank
und Ausruestungsslots waren schon immun, weil sie ueber "/use" bzw. die
Container-API laufen. Ueberall sonst, wo Sku einen nativen Knopf klickt (Beute,
Handel, Post, Zauberbuch, Gildenbank), hat die Rechtsklick-Taste keine eigene
Aktion zu verlieren - dort passiert bei Strg+Enter nichts oder es kommt die
Anprobe, waehrend Enter die eigentliche Aktion ausloest.
Der Linksklick darf jetzt auf eine Taste mit Umschalt, Strg oder Alt gelegt werden
Einfach: Die Aktivieren-Taste laesst sich auf eine Kombination wie Strg+Enter
umbelegen und funktioniert trotzdem. Vorher haette so eine Taste beim Haendler
oder auf einem angelegten Gegenstand die Anprobe geoeffnet statt zu handeln -
aus demselben Grund wie beim Rechtsklick auf einen Haendlergegenstand.
Technisch: Eintraege, deren Klick von einem Modifikator verschluckt wuerde, tragen
jetzt eine zweite, modifikatorfeste Bestueckung (plainMacrotext), die die Aktion
direkt aufruft, statt den nativen Knopf zu klicken: Haendlergegenstaende ueber
Blizzards unverpacktes MerchantItemButton_OnClick, Ausruestungsslots ueber
PickupInventoryItem, Handelsplaetze ueber ClickTradeButton bzw.
ClickTargetTradeButton. Gestaged wird sie nur, solange ein Modifikator
tatsaechlich gedrueckt ist - entschieden im PreClick des sicheren Knopfes, weil
nur dort der Tastaturzustand lesbar ist und er noch vor dem Lesen der Attribute
laeuft. Mit dem modifikatorfreien Standard-Enter bleibt die Bestueckung
byte-gleich wie bisher, dort kann also nichts kaputtgehen. Taschen, Bank,
Questbelohnungen, Gildenbank, Popups und Reiter brauchten keinen Eintrag: sie
laufen entweder ueber die Container-API oder haben gar keinen
Modifikator-Zweig. Beute-Knoepfe, Postanhaenge und Zauberbuch-Knoepfe haben
diesen Zweig zwar, werden von Sku aber nie geklickt - Beute hat eine eigene
Behandlung, Anhaenge laufen ueber TakeInboxItem, und das Zauberbuch gehoert
nicht zu den Fenstern, die Sku oeffnet. Kaeme es dazu, braucht es dort
"/cast " statt dieses Verfahrens, denn Zaubern ist geschuetzt und kann
von keinem Direktaufruf ausgeloest werden.
Die Klick-Tasten des Menues liessen sich ueberhaupt nicht belegen
Einfach: In der Tastenbelegung antworteten "Menue; Linksklick/aktivieren" und
"Menue; Rechtsklick" auf jedes gedrueckte Enter mit "Ungueltig. Andere Taste
druecken." - mit und ohne Modifikator - und liessen sich damit gar nicht
setzen, nicht einmal auf ihren eigenen Standard zurueck. Beide sind jetzt
belegbar.
Technisch: Die Liste der gesperrten Tasten wird als TEILSTRING geprueft, "ENTER"
trifft also auch NUMPADENTER und CTRL-ENTER. Sie schuetzt die
Navigationstasten des Menues - genau auf dieser Familie leben aber diese
beiden Belegungen: Enter ist der Standard der einen, Strg+Enter der der
anderen. Sie sind jetzt von der Sperre ausgenommen, und zwar nur fuer
Enter-Tasten; Pfeile, Rueckschritt und Tabulator bleiben auch dort gesperrt,
weil sie die Navigation steuern, die nicht Teil dieser Belegung ist. Fuer die
Kampfmenue-Tasten gab es so eine Ausnahme bereits. Umgesetzt an beiden
Stellen, die eine Taste abfangen: im Tastenbelegungs-Menue und im
Einzeleintrag-Helfer.
Die Menue-Klicktaste loescht die Spielbelegung derselben Taste nicht mehr
Einfach: Wer "Menue; Linksklick/aktivieren" wieder auf Enter legte, bekam die
Warnung "bereits belegt mit Chat oeffnen" und, nach dem Bestaetigen, genau
das: Enter oeffnete den Chat nicht mehr. Zurueck ging es auch nicht, denn
fuer Spielbefehle lehnte die Tastenbelegung jedes Enter als ungueltig ab.
Dabei haben sich diese beiden Belegungen nie gestoert - sie lagen jahrelang
zusammen auf Enter: solange das Menue offen ist, aktiviert Enter den
Eintrag, sonst oeffnet es den Chat. Genau so ist es wieder. Wird eine Taste
auf diese Weise geteilt, sagt Sku es jetzt an ("Hinweis! Diese Taste wird
auch benutzt von ... Beide Belegungen bleiben erhalten."), statt die andere
Belegung zu entfernen. Wem der Chat schon abhanden gekommen ist: "Chat
oeffnen" im Tastenbelegungs-Menue einfach wieder auf Enter legen, das geht
jetzt. Am uebrigen Konfliktverhalten aendert sich nichts - zwei Sku-Tasten
auf derselben Taste werden weiterhin gemeldet und die alte geloest.
Technisch: Die Klicktasten des Menues sind nie eine echte Belegung, sondern eine
Override-Bindung auf dem sicheren Menue-Knopf, die dessen OnShow aufzieht und
dessen OnHide wieder abraeumt - sie existiert also nur, solange das Menue
offen ist, und uebertoent den Spielbefehl genau in dieser Zeit. Dasselbe gilt
fuer die Kampfmenue-Tasten, die nur waehrend eines Kampfes aufgezogen sind.
Die Konfliktpruefung kannte diesen Unterschied nicht: sie vergleicht blanke
Tastennamen, meldete deshalb einen Konflikt und rief beim Bestaetigen
SetBinding(Taste) samt SaveBindings auf - was OPENCHAT dauerhaft von Enter
entfernte. Erreichbar wurde das erst dadurch, dass diese Belegungen seit dem
Fix darueber ueberhaupt auf Enter gesetzt werden koennen. Die betroffenen
Eintraege tragen jetzt in skuDefaultKeyBindings ein Merkmal
transientOverride, abgefragt ueber SkuOptions:SkuKeyBindsIsTransientOverride;
fuer sie entfaellt die Konfliktbehandlung gegen SPIELBEFEHLE (keine
Rueckfrage, kein Entbinden) und wird durch den gesprochenen Hinweis ersetzt.
Gegen andere Sku-Belegungen bleibt sie vollstaendig erhalten, denn die sind
gleichzeitig aufgezogen und verdraengen sich wirklich. Dieselbe Regel gilt in
der Gegenrichtung, damit ein Spielbefehl die Menuetaste nicht loest, und die
Enter-Familie ist beim Belegen von Spielbefehlen nicht mehr gesperrt -
Pfeile, Rueckschritt und Tabulator bleiben es. Der Hinweis haengt an derselben
Ansage wie die neue Taste, weil ein eigener Aufruf mit aOverwrite die
Warteschlange leert und sich selbst wieder verschluckt haette.
Gegenstaende in der Bank heissen wieder so, wie sie heissen
Einfach: In der Bank - und gelegentlich auch anderswo - stand bei manchen
Gegenstaenden statt des Namens der Satz "Frage Gegenstandsinformationen ab".
Das ist keine Fehlermeldung des Addons, sondern ein Platzhalter des Spiels: der
Client zeigt ihn, solange er die Daten eines Gegenstands noch vom Server holt.
Betroffen waren vor allem Gegenstaende mit einem umfangreichen Tooltip - Rezepte,
Setteile, gesockelte Ausruestung -, weil deren Anzeige erst dann vollstaendig
ist, wenn ALLE darin erwaehnten Daten eingetroffen sind. Bisher uebernahm Sku
diesen Platzhalter als NAMEN des Eintrags, und blieb dabei: er verschwand nicht
mehr, auch nicht nach mehrfachem Anlaufen oder nach Verlassen und Wiederbetreten
des Menues. Doppelt aergerlich, weil der Satz fuer jeden betroffenen Platz gleich
lautet - mehrere wartende Gegenstaende klangen identisch, waren nicht
auseinanderzuhalten und nicht gezielt anzusteuern, und beim Sortieren nach Namen
wie beim Anspringen ueber die Anfangsbuchstaben zaehlte ebenfalls dieser Satz.
Jetzt nimmt Sku den Namen aus der eigenen mitgelieferten Gegenstandsliste, wenn
der Client ihn noch nicht hat, haengt nur ein kurzes "(laedt)" an, fordert die
Daten beim Server aktiv an und liest den Eintrag neu vor, sobald sie da sind.
Beim Oeffnen der Bank werden die Daten aller Bankplaetze ausserdem schon vorab
angefordert, sodass der erste Durchgang meist gar nicht erst wartet.
Technisch: Der Satz ist die Spielkonstante RETRIEVING_ITEM_INFO. Gegen sie gab es im
Addon keine einzige Pruefung - die einzige Erwaehnung im Quelltext stand in einem
Entwicklerwerkzeug und verglich einen fest verdrahteten deutschen Text. Dauerhaft
blieb der Zustand aus drei Gruenden: es gab nirgends einen Empfaenger fuer
GET_ITEM_INFO_RECEIVED, es wurde nie ein Ladeauftrag gestellt (das Beschreiben
eines Tooltips ist keine Anforderung, die man verfolgen kann), und es gab keinen
zweiten Weg zu einem Namen. Neu sind SkuUtil:IsRetrievingItemInfo (erkennt den
Platzhalter ueber die Spielkonstante statt ueber deutschen Text),
SkuCore:ResolveItemName (Client-Cache, dann SkuDB.itemLookup, dann der Name im
Link), SkuCore:PendingItemLabel, SkuCore:RequestItemData und
SkuCore:ContinueOnItemData ueber Item:CreateFromItemID():ContinueOnItemLoad. Ein
eigener Ereignis-Rahmen sammelt GET_ITEM_INFO_RECEIVED und loest daraus einen
einzigen, gebuendelten stillen Neuaufbau aus; BANKFRAME_OPENED fordert Fach -1
und die Bankbeutel 5 bis 11 vorab an. Dass ausgerechnet die Bank betroffen war,
hat einen eigenen Grund: SetBagItem(-1, Platz) liefert auf 2.5.6 nichts, weshalb
der Beutel-Umbau dort auf SetHyperlink(GetContainerItemLink(...)) auswich -
ausgerechnet den Weg, der vom Gegenstands-Cache abhaengt. Bankplaetze sind echte
Ausruestungsplaetze (Platz n = Ausruestungsplatz n + 39), also liest
SetInventoryItem sie genauso oertlich, wie SetBagItem einen Beutel liest; das ist
kein Rueckschritt zu den ausgelesenen Fensterelementen, die der Umbau abgeloest
hat - kein Rahmen, kein OnEnter, kein Aufklappen der Beutel. Ein Ausweichweg
dahinter wurde bewusst nicht stehen gelassen: er wuerde nur verdecken, ob der
richtige Weg funktioniert.
Gegenstaende verschwinden nicht mehr aus den Beutelisten von AtlasLoot
Einfach: In den Beutelisten fehlten Eintraege - ohne Luecke, ohne Hinweis. Eine Liste
mit zwoelf moeglichen Beutestuecken zeigte sieben und las sich wie eine
vollstaendige Liste mit sieben. Die Ursache ist dieselbe wie beim Punkt davor:
Gegenstaende, deren Daten der Client noch nicht vom Server hat, wurden nicht als
Gegenstand erkannt und ganz weggelassen. Das traf ausgerechnet die Eintraege, um
die es hier geht, denn eine Beuteliste besteht fast nur aus Gegenstaenden, die man
noch nie erbeutet oder angesehen hat - je unbekannter der Gegner, desto mehr
fehlte. Wiederholbar war es auch nicht: dieselbe Liste ein zweites Mal geoeffnet
konnte laenger sein, und die Nummern der Eintraege verschoben sich. Jetzt sind
alle Eintraege da, und die Suche nach einem Namen findet auch Gegenstaende, die
man noch nie in der Hand hatte. Die Listen werden dadurch laenger als gewohnt,
und die Nummern der Eintraege verschieben sich einmalig entsprechend.
Technisch: An vier Stellen entschied ein Verteiler anhand von
C_Item.GetItemNameByID(id), ob eine Beutezeile ein Gegenstand oder ein Zauber ist
- eine Pruefung, die "kein Gegenstand" und "vom Server noch nicht geliefert"
vermischt. Ein noch nicht geladener Gegenstand fiel in den Zauber-Zweig,
GetSpellInfo lieferte fuer ihn nichts, und die Zeile wurde verworfen. Die Absicht
der Pruefung ist richtig (keine unsinnigen Kennzahlen im Menue), nur war die
Frage falsch gestellt: GetItemInfoInstant beantwortet sie oertlich aus der
Gegenstandsdatenbank des Clients. Dafuer gibt es jetzt den Helfer tIsItemId; an
einer der vier Stellen war das Problem schon einmal einzeln mit einem
SkuDB-Zusatz umgangen worden, der damit entfaellt. Die Reihenfolge der Zweige
bleibt unveraendert. Ausserdem entfaellt der fruehe Ausstieg im "item"-Zweig des
Menuebauers; der Eintrag heisst SkuCore:ResolveItemName oder - stabil -
"Gegenstand ", bewusst nicht die "(laedt)"-Form, die den Eintrag beim
Nachladen unter dem Cursor verschieben wuerde. tItemNameTable fuer die Suche nach
Namen wird ebenfalls ueber ResolveItemName gefuellt, und der beim Anmelden ins
Leere laufende GetItemNameByID-Aufruf auf die Favoriten ist jetzt ein echter
Ladeauftrag.
Der Dungeonbrowser bot alle Dungeons an statt nur der passenden
Einfach: Unter "Eintrag erstellen" stand die vollstaendige Liste aller Dungeons der
Kategorie - auf jeder Stufe dieselbe. Ein Charakter der Stufe zwanzig bekam die
heroischen Instanzen der Scherbenwelt genauso angeboten wie ein Siebziger die
Todesminen, und beides liess sich anhaken und anmelden, obwohl man dort gar nicht
hineinkommt. Im sichtbaren Fenster war das nie so: dort grenzt das Spiel die Liste
auf das ein, was zur eigenen Stufe passt, und genau diese Eingrenzung fehlte bei
uns - wir haben schlicht die ungefilterte Liste gelesen. Jetzt zeigt Sku dieselbe
Auswahl wie das Fenster. Wer trotzdem die ganze Liste braucht, etwa um sich fuer
einen Dungeon weit unter der eigenen Stufe anzubieten, schaltet den neuen Eintrag
"Nur passende Dungeons" ab; er steht direkt ueber den Dungeon-Gruppen und nennt
eingeschaltet, wie viele Eintraege er gerade ausblendet. Bereits angehakte
Dungeons bleiben immer sichtbar, auch wenn die Eingrenzung sie sonst verstecken
wuerde - sonst haettest du etwas angemeldet, das du im Menue nicht mehr
wiederfindest.
Technisch: tGetCategoryActivities rief C_LFGList.GetAvailableActivities(categoryID)
ohne das filters-Argument auf und bekam damit den kompletten Kategorieinhalt; die
Stufen aus GetActivityInfoTable wurden nur fuer die Beschriftung gelesen, nie zum
Filtern. Gefiltert wird jetzt in zwei UND-verknuepften Lagen: einmal ueber den Satz
des Spiels selbst (GetAvailableActivities(categoryID, nil,
Enum.LFGListFilter.Recommended)) und einmal lokal gegen UnitLevel("player") anhand
von minLevelSuggestion/maxLevelSuggestion - auf 2.5.x sind das die einzigen Felder
mit echten Stufen. Der Satz des Spiels wird nur uebernommen, wenn er nicht leer und
eine echte Teilmenge der ungefilterten Liste ist, damit eine abweichende Signatur
das Menue niemals leer machen kann; fehlende Stufenangaben lassen einen Eintrag
durch. Neu sind die Einstellung dungeonBrowser.showAllActivities (char), der
Umschalter SkuCoreDungeonToggleShowAll (baut den Reiter neu auf, weil sich die
Kinderliste aendert), die Zaehler in DungeonBrowser.tFilterStats und eine
dprint-Zeile "activity filter" mit den Einzelzahlen beider Lagen.
Schnellmenue: Lua-Fehler bei einigen Einstellungen
Einfach: Im Schnellmenue warfen mehrere Einstellungen einen Lua-Fehler, sobald man
sie mit Pfeil rechts aufklappte - besonders unter "Sprachausgabe", aber auch die
Beacon-Lautstaerke unter "Lautstaerken" und die Ja/Nein-Schalter unter
"Sonstiges". Dieselben Einstellungen ueber ihren normalen Weg im
Einstellungsmenue funktionierten einwandfrei. Das Schnellmenue baut naemlich
keine eigenen Einstellungen, es zeigt dieselben Eintraege noch einmal an einer
zweiten Stelle - und bei dieser Zweitanzeige fehlte eine Angabe, ohne die Sku
den gespeicherten Wert nicht finden konnte. Jetzt zeigen beide Wege denselben
Wert und schreiben in dieselbe Einstellung. Ausserdem tauchen unter "Sonstiges"
wieder alle vier vorgesehenen Eintraege auf: "Tooltip nicht ausblenden" und
"NPC Begruessungen abspielen" waren dort still verschwunden, als sie an anderer
Stelle im Einstellungsmenue einen neuen Platz bekamen.
Technisch: SkuOptions:IterateOptionsArgs entscheidet an seinem vierten Argument
(aModule), ob ein Knoten schema-verwaltet ist: skuManaged = (v.get == nil and
v.set == nil and aModule ~= nil). Ist er das nicht, liest GetCurrentValue ueber
self.optionsPath[self.profileIndex]:get(). Genau diese get/set-Closures haben
die schema-verwalteten Knoten aber nicht - sie leben von aModule. Die sechs
Spiegel-Aufrufe des Schnellmenues in SkuZOptions/Core.lua gaben aModule nicht
mit, also lief jeder Aufklappvorgang eines solchen Knotens in "attempt to call
method 'get' (a nil value)". Betroffen waren WowTtsVoice/-Speed/-Volume
(SkuChat), beaconVolume (SkuNav), readAllTooltips/interactMove (SkuCore) und
vocalizeMenuNumbers/vocalizeSubmenus (SkuOptions); die Audiokanaele und
Soundeinstellungen blieben heil, weil sie eigene get/set mitbringen. Alle sechs
Aufrufe geben jetzt Modul und keyPrefix genau so mit wie die Original-Menuestelle
("SkuOptions"/"soundChannels.", "SkuNav"/"", "SkuOptions"/"soundSettings.",
"SkuChat"/"", "SkuCore"/"", "SkuOptions"/""), womit die gespeicherten Werte
unveraendert bleiben. Der Sonstiges-Aufruf bekommt zusaetzlich aIncludeHidden =
true, weil doNotHideTooltip und playNPCGreetings inzwischen forAudioMenu = false
tragen und deshalb wortlos herausgefiltert wurden. Zusaetzlich lesen und
schreiben alle von IterateOptionsArgs erzeugten Knoten jetzt ueber zwei zentrale
Helfer (tOptGet/tOptSet) mit drei Stufen - SkuSettings, eigene get/set-Closure,
direkter Tabellenzugriff -, sodass eine kuenftige Spiegelstelle ohne aModule
hoechstens den Wert direkt liest statt einen Fehler zu werfen.
Zwei Umzuege im Menue: Beacon Soundeinstellungen und "Sonstiges"
Einfach: Die Beacon-Einstellungen (Beacon-Lautstaerke, Klick bei Beacons samt Winkel
und Ton, sowie die Toene fuer schmale, breite und letzte Beacons) lagen bisher
unter Monitor. Sie sind jetzt dort, wo auch alle uebrigen
Navigationseinstellungen liegen: Einstellungen, Navigation, Beacon
Soundeinstellungen. Der Punkt heisst also nicht mehr nur "Beacon", sondern sagt
jetzt, worum es geht; unter Monitor gibt es ihn nicht mehr. Ausserdem ist
"Sonstiges" im Schnellmenue wieder der letzte Eintrag - "Dial Targeting" und
"Soft Targeting" stehen jetzt davor statt dahinter.
Technisch: Der Beacon-Block wandert unveraendert aus Aq:MonitorMenuBuilder
(SkuCore/aq.lua) in den Navigation-Zweig von SkuCore:MenuBuilder
(SkuCore/Options.lua) und haengt dort als Unterpunkt "Beacon
Soundeinstellungen" (englisch "Beacon sound settings", franzoesisch "Réglages
de son des balises") unter den Navigationseinstellungen. Es sind dieselben
Options-Knoten aus SkuNav.options.args, durchgereicht per IterateOptionsArgs
gegen SkuSettings:Sub("SkuNav") mit gleichem Modul und keyPrefix - gespeicherte
Werte bleiben also unveraendert, und die Ton-Knoten behalten ihr OnAction, das
ein Beispiel-Beacon abspielt. Wie zuvor ist die Liste eine ausdrueckliche
Auswahl, kein Durchreichen der ganzen args-Tabelle: ein neuer Beacon-Knoten muss
dort mit eingetragen werden. Im Schnellmenue (SkuZOptions/Core.lua) sind Dial
Targeting und Soft Targeting vor den 7.4-Block gezogen; die Kinderliste traegt
kein sorting-Flag, die Einfuegereihenfolge ist also die Anzeigereihenfolge.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v42.12
Im Charakterfenster werden die Beschreibungen der Werte wieder vorgelesen
Einfach: Unter "Eigenschaften" hatte jeder Wert - Zauberschaden,
Zaubertrefferwertung, Ausdauer, Waffengeschwindigkeit und alle uebrigen - nur
seinen Namen und seine Zahl. Die Beschreibung, die das Spiel dazu anzeigt, war
leer: was der Wert bewirkt, die Aufschluesselung nach Zauberschulen, Haupt- und
Nebenhand. Die Taste fuer den vollstaendigen Text sagte an diesen Eintraegen
nichts. Nur die Widerstaende und die Ausruestung hatten eine Beschreibung.
Jetzt hat jeder Wert seine, und sie wird bei jedem Anlaufen frisch gelesen, ist
also auch nach einem Buff oder einem Ausruestungswechsel aktuell.
Technisch: Der Tooltip-Abruf war an dieser Stelle auskommentiert, und jeder Eintrag
wurde mit leerem textFull gebaut - unveraendert schon in v41.06, das ist also
kein Rueckschritt aus dem Umbau, sondern hat nie funktioniert. Zwei Gruende,
warum er so auch nicht funktionieren konnte: GetButtonTooltipLines wurde mit
GameTooltip als zweitem Argument aufgerufen, was genau den Schritt
ueberspringt, der den Tooltip erst fuellt; und ohne dieses Argument haette der
Helfer trotzdem abgebrochen, weil er ein OnEnter nur fuer Objekte ausloest, die
eine .type-Markierung tragen - die haben die Werte-Frames nicht, und genau
deshalb setzt die Widerstands-Schleife sie vor ihrem Abruf. Dazu kam ein
dritter Grund, an dem eine naive Reparatur falsch geworden waere: TBC schickt
alle 29 Werte durch EIN gemeinsames Widget (PlayerStatFrameLeft1), und die
Blizzard-Setter lassen ihren Zustand darauf liegen - .tooltip/.tooltip2 sowie
.bonusDamage/.spellCrit/.damage fuer die vier Werte, die ein eigenes OnEnter
setzen. Keiner raeumt hinter dem vorherigen auf, vier tauschen OnEnter aus und
nie zurueck; Blizzards eigenes UpdatePaperdollStats macht vor jeder Gruppe
genau deshalb einen Reset. Ohne den haette Wert N die Beschreibung von Wert N-1
vorgelesen. Der Abruf setzt das Widget jetzt vor jedem Setter zurueck und liest
den Tooltip ueber NumLines/GameTooltipTextLeft|Right statt ueber GetRegions -
letzteres liefert linke und rechte Spalte als zwei getrennte Bloecke, die
Aufschluesselung nach Zauberschulen waere also als sechs Schulnamen gefolgt von
sechs Zahlen vorgelesen worden. Der Live-Getter, der den Wert bei jedem
Anlaufen neu bestimmt, gibt die Beschreibung jetzt als zweiten Rueckgabewert
mit; danach wird das Widget ueber PaperDollFrame_UpdateStats in den Zustand
zurueckversetzt, den Blizzard erwartet.
Sku ist nicht mehr darauf angewiesen, dass interne Kennwoerter unuebersetzt bleiben
Einfach: Auf einem franzoesischen Client tat die Taste fuer das Quest-Log gar
nichts - kein Fokus, kein Ton, keine Fehlermeldung. Schuld war ein einziges
uebersetztes Wort in der franzoesischen Sprachdatei. Manche Eintraege dort sind
naemlich keine Beschriftung, sondern ein internes Kennwort, mit dem Sku seine
eigenen Menuepfade bildet und wiedererkennt; wird so eines uebersetzt, findet
das Addon seinen eigenen Pfad nicht mehr. Das ist behoben, und zwar so, dass es
sich nicht wiederholen kann: das Kennwort ist gar kein uebersetzbarer Text
mehr. Wer sich einen franzoesischen Pfad angewoehnt hat, kommt damit weiterhin
ans Ziel. Ein zweiter Fund derselben Art haette jeden franzoesischen Client
beim naechsten Sortieren der Sprachdatei lautlos auf englische Namen fuer
Gegner, Objekte und Quests umgestellt - auch das ist beseitigt.
Technisch: Gefunden, auf die Ursache zurueckverfolgt und behoben hat das ZenqFR
(Games-Access) auf einem echten franzoesischen Client, als PR #2 in diesem
Repo. Die weiteren Aenderungen bauen darauf auf. L["short"] trug zwei
unabhaengige Bedeutungen: an rund 25 Stellen war es das erste Feld eines
SkuOptions:SlashFunc-Pfads, also ein Protokoll-Kennwort, das der Code gegen
sich selbst vergleicht, an genau einer Stelle (SkuCore/aq.lua) echter
Anzeigetext. Ein Uebersetzer sieht immer nur die zweite Bedeutung. Beide sind
jetzt getrennt: Sku.MENU_ROOT ist das Kennwort und wird von allen 23
pfadbildenden Stellen benutzt, dazu von den sechs, die das Literal "short,"
fest verdrahtet hatten - eine davon war die Quest-Log-Taste. Der Vergleich
akzeptiert weiterhin auch L["short"], damit gelernte lokalisierte Pfade
weiterlaufen. Nebenbei behoben: der Ersatzwert in SkuCore/dungeonBrowser.lua
war "sku" und damit ueberhaupt kein gueltiges Kennwort. Zweitens definierte
frFR.lua L["locale"] doppelt - "enUS" im sortierten Rumpf und "frFR" am Ende
angehaengt. Richtig aufgeloest wurde das nur durch AceLocales Reihenfolge: eine
Nicht-Standardsprache wird ueber einen Proxy registriert, der bedingungslos
rawsetzt, also gewinnt die LETZTE Zuweisung. Aus diesem Schluessel liest Sku
Sku.Loc, und daran haengt, welche SkuDB-Namenstabellen der gesamte Client
benutzt: ein Neuerzeugen oder Sortieren der Datei haette jeden franzoesischen
Client stumm auf englische DATEN umgestellt - kein Fehler, keine Logzeile, nur
ueberall die falschen Namen. Die verlierende Zeile ist geloescht, die
ueberlebende dokumentiert, und dev/rework-docs/_locale_dupes.py meldet ab jetzt
doppelte Schluessel je Sprachdatei. Der Linter macht nebenbei sichtbar, dass
enUS als AceLocale-Standardsprache umgekehrt ERSTE-gewinnt: derselbe doppelte
Schluessel kann pro Sprache auf verschiedene Eintraege zeigen. 64 solcher
Konflikte gibt es heute, fast alles alter Uebersetzungsstaub; sie sind bewusst
stehen geblieben und jetzt wenigstens sichtbar. Drittens haelt
SkuDBEnsureActiveLocaleTables sein Versprechen nun auch wirklich - es laeuft
zusaetzlich bei ADDON_LOADED (vorher erst einen OnUpdate nach PLAYER_LOGIN,
wer also in seinem eigenen PLAYER_LOGIN-Handler auf [Sku.Loc] zugriff, sah fuer
einen Moment nil) und steigt bei unbrauchbarem Sku.Loc nicht mehr wortlos aus,
sondern prueft, meldet den wahrscheinlichen Verursacher ins Log und baut die
Tabellen trotzdem.
Die Sprache verstummt nicht mehr, wenn du schnell durch eine Liste gehst
Einfach: Schnelles Blaettern durch ein Menue, durch die Liste der Objekte in der
Naehe oder durch die Taschen konnte die Sprachausgabe ganz zum Schweigen
bringen - uebrig blieben nur die Klick- und Bakengeraeusche - bis du ein paar
Sekunden gewartet oder einen anderen Teil der Oberflaeche angesteuert hast.
Jeder Eintrag, an dem du vorbeigelaufen bist, wurde verschluckt, oft auch der,
auf dem du stehen geblieben bist. Jetzt geht jeder Eintrag, ueber den du
laeufst, an die Stimme, und der Eintrag, auf dem du stehen bleibst, wird
gesprochen. An der Frage, welche Ansage gewinnt, wurde nichts geaendert: eine
neue ersetzt weiterhin die vorherige, schnelles Blaettern liest also nach wie
vor nur das vor, wo du landest, und das Abbrechen der Sprache im Kampf bleibt
unveraendert.
Technisch: Die Blizzard-TTS-Pumpe hat sich mit einem Countdown getaktet, der je
Durchlauf nur die Dauer EINES Bildes abgezogen hat - ihr Rumpf laeuft aber nur
alle 0,01 s. Oberhalb von rund 100 fps zog sie damit deutlich weniger ab als
tatsaechlich vergangen war, und die beabsichtigte Pause von 0,1 s vor der
naechsten Ausgabe wurde real zu 0,2-0,3 s. Da ein Queue-Reset die noch wartende
Zeile loescht, bedeutet eine laengere Pause mehr verlorene Ansagen: der Fehler
wurde schlimmer, je hoeher die Bildrate war. Die Pause ist jetzt eine
GetTime-Frist - bei 60 fps identisch, darueber korrekt. Gemessen an einer
Aufzeichnung mit 6-7 Tastendruecken pro Sekunde: vorher ergaben 7 Resets 2
gesprochene Zeilen, nachher ergeben 7 Resets 7. Eine zweite Absicherung
unterdrueckt ein StopSpeakingText, wenn nichts unterwegs ist und innerhalb der
letzten 0,15 s bereits eines gesendet wurde - der Client verarbeitet Stopps
asynchron, ein nachlaufender konnte die naechste Ausgabe abbrechen, bevor sie
begonnen hatte. Beim Navigieren greift diese Absicherung jetzt nicht mehr; sie
bleibt fuer ereignisgetriebene Schuebe (Post, Chat), die in einer Sekunde 17
Stopps und gar keine Sprache erzeugt haben.
Weniger Arbeit je gesprochener Zeile
Einfach: Sku leistet fuer jede gesprochene Zeile und jeden abgespielten Ton spuerbar
weniger Arbeit, was sich als fluessigeres Blaettern bemerkbar macht.
Technisch: Zwei voruebergehende [SOUND-PROBE]-Diagnosen wurden entfernt. Beide haben
debugstack(...) als Argument an dprint uebergeben, und dprint prueft das
Debug-Flag erst in sich selbst - ein vollstaendiger Stack-Walk lief also bei
jedem Ton, auch bei ausgeschaltetem Log, und die Variante in Sku/Core.lua hing
am globalen PlaySound, sodass auch Blizzards eigene Aufrufe dafuer bezahlt
haben. Sie machten ein Viertel aller aufgezeichneten Log-Zeilen aus. Die
Queue-Pumpe ueberspringt ihre Durchlaeufe jetzt vollstaendig, solange beide
Warteschlangen leer sind, statt sie rund hundertmal pro Sekunde auszufuehren,
und die Wiki-Linksuche steigt vor dem Normalisieren der Zeichenkette aus statt
danach: sie wird aus OutputStringBTtts fuer jede gesprochene Zeile aufgerufen,
ihr Ergebnis wird dort ohnehin verworfen, und ohne Wiki-Index liefen rund 19
string.gsub-Durchgaenge, nur um eine Abfrage zu erreichen, die nichts tat.
Der Installer und die Downloadseite sprechen jetzt auch Franzoesisch
Einfach: Sku selbst spricht seit v42.11 Franzoesisch, alles drumherum aber nicht.
Der Sku-Installer laeuft jetzt auf Franzoesisch - er nimmt seine Sprache von
Windows, und umstellen laesst er sich jederzeit in der Liste "Sprache dieses
Installers" - und die Downloadseite gibt es in einer franzoesischen Fassung,
erreichbar ueber die Sprachlinks oben auf beiden Seiten. Auch diese Patchnotes
gibt es auf Franzoesisch, beginnend mit v42.11. Ein franzoesisches Sprachpaket
gibt es weiterhin nicht: auf einem franzoesischen Client spricht Sku ueber den
Screenreader, weshalb der Installer dort das englische Paket anbietet. Der
Installer traegt damit die Version 4.1.
Technisch: Eine franzoesische Tabelle in Loc.cs des Installers (Lang.Fr, derselbe
Schluesselsatz wie Englisch und Deutsch, "fr" aus der UI-Kultur des Systems;
die Sprachauswahl wird aus ComponentsForm._langOrder aufgebaut, sodass kein
Index-Literal mehr nachgezogen werden muss), docs/index-fr.html und
"Patch Notes Sku FR.txt", das release.ps1 auf die Webseite spiegelt. Die
Docs-Ersetzungen in release.ps1 laufen jetzt ueber eine LISTE von Seiten und
greifen auf sprachneutrale Fragmente, damit eine uebersetzte Seite keine
veraltete Versionsnummer behalten kann - genau der Fehler, um den es beim
Ueberschriften-Fix in v42.11 ging, eine Seite weiter; dabei faellt auch die
SkuMapper-Ueberschrift mit ab, die unbemerkt veraltet war. Die
Discord-Ankuendigung geht jetzt pro Kanal: eine Webhook-Zeile darf die Sprachen
dieses Kanals nennen, ein rein deutscher Server bekommt also eine deutsche
Zeile mit deutschen Links statt drei Sprachen, die er nicht wollte.
Zwei Menues, die nur ein Zwischenschritt waren, sind weg
Einfach: Unter "Einstellungen" stand der Punkt "Kampf", und darin genau ein
Eintrag: "Sku Menue im Kampf". Dieser Eintrag steht jetzt direkt in
"Einstellungen, Allgemein", das leere "Kampf" darueber gibt es nicht mehr.
Dasselbe im Hauptmenue: "Werkzeuge" enthielt nur "Dial Targeting" und
"Soft Targeting"; beide stehen jetzt im "Schnellmenue", und "Werkzeuge" ist
aus dem Hauptmenue verschwunden. An den Einstellungen selbst aendert sich
nichts, alle bisher gespeicherten Werte bleiben erhalten.
Technisch: Die drei Eintraege behalten ihre bisherigen Builder, ihre db und ihr
keyPrefix, es aendert sich nur, wo sie eingehaengt werden - gespeicherte
Werte sind damit unberuehrt. "Werkzeuge" ist als SkuMenu-Modul und aus
SkuMenu:SetRootLayout entfernt (SkuZOptions/SkuMenu.lua); DialTargetingMenuBuilder
und die softTargeting-Gruppe (weiter ueber IterateOptionsArgs mit
aIncludeHidden=true, da forAudioMenu=false) haengen jetzt in den
BuildChildren des Schnellmenues (SkuZOptions/Core.lua). Die "Kampf"-Spezifikation
faellt aus tSpecs in SkuCore/Options.lua weg; CombatMenuOpenMenuBuilder wird
jetzt am Ende des Allgemein-Builders aufgerufen, mit derselben Einstellung
combatMenuOpen. Kein SlashFunc-Pfad zeigte auf eines der beiden Menues, es
musste also nichts weiter nachgezogen werden.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v42.11
Taxi: Sku nennt den naechsten Flugpunkt und laesst dich dort landen
Einfach: Auf einem Flug beim Flugmeister sagt Sku jetzt an, welcher Flugpunkt als
naechstes kommt, und du kannst dort aussteigen, statt bis zum eigentlichen Ziel
weiterzufliegen. Die Taste dafuer ist ab Werk Strg-Umschalt-E; sie steht wie
jede andere Sku-Taste unter "Navigation und Wegpunkte" zum Umbelegen bereit.
Es gibt zwei Ansagen je Teilstrecke, weil sie verschiedene Fragen beantworten:
den naechsten Halt beim Abflug und nach jedem Zwischenstopp, und "vorzeitige
Landung moeglich" rund 800 Meter davor. Vor dem letzten Halt bleibt Sku still -
dort vorzeitig zu landen waere schlicht Ankommen. Abschalten laesst sich das
Ganze unter "Taxiflug". Nur Flugmeister-Taxis, niemals Fahrzeuge.
Technisch: Neues Modul SkuCore/taxi.lua. Die Route wird mitgeschrieben, nicht
geraten: hooksecurefunc auf TakeTaxiNode greift, solange die Taxikarte noch
offen ist - das einzige Zeitfenster, in dem GetNumRoutes, TaxiGetNodeSlot und
TaxiNodeName ueberhaupt noch antworten. Damit ist die Haltestellenliste exakt,
und jeder Halt darauf ist fuer diesen Charakter auch wirklich anfliegbar. Ein
Naeherungszeiger schiebt sie weiter, waehrend das Taxi ueber die Knoten fliegt;
die Suche nach dem naechstgelegenen Knoten bleibt nur als gekennzeichneter
Rueckfall fuer einen /reload mitten im Flug, gefiltert nach Fraktion und
Entdeckungsstand. Drei Eigenheiten des Clients stehen im Dateikopf, damit sie
nicht neu erarbeitet werden muessen: die Anforderung landet immer am NAECHSTEN
Flugpunkt (so steht es auch in TAXI_CANCEL_DESCRIPTION), weshalb der
Routenzeiger die richtige Antwort ist; IsPossessBarVisible meldet false,
waehrend PossessButton2 sichtbar ist - verlaesslich ist allein
MainMenuBarVehicleLeaveButton, gelesen mit IsVisible, und der steht den ganzen
Flug ueber; PLAYER_CONTROL_LOST feuert, waehrend UnitOnTaxi noch false ist,
weshalb jedes daran haengende Aufraeumen frisch erfasste Daten geloescht haette.
Jeder Einstiegspunkt prueft UnitOnTaxi erneut - dieselbe Weiche, mit der
Blizzard TaxiRequestEarlyLanding von VehicleExit trennt. Diagnose: "taxi:"-Zeilen
im SkuDebugLog und /skutaxi.
Gruppeneinladungen werden nicht mehr stillschweigend abgelehnt
Einfach: Das Schliessen des Sku-Menues - aus welchem Grund auch immer: Escape aus
den Taschen, ein anderes Fenster, ein Wechsel in den Kampf - hat eine offene
Gruppeneinladung abgelehnt, und der Einladende bekam eine Absage zu sehen. Fuer
einen sehenden Spieler passiert an dieser Stelle gar nichts, der Dialog steht
einfach seine 60 Sekunden lang da. Das war also ein Verlust, den es nur mit Sku
gab. Die Einladung wird beim Schliessen jetzt nicht mehr beantwortet; sie
verschwindet nur vom Bildschirm und ist unter "Local" wieder erreichbar.
Technisch: StaticPopupDialogs["PARTY_INVITE"].OnHide ruft DeclineGroup auf, sofern
dialog.inviteAccepted nicht gesetzt ist - und OnHide feuert auch bei einem
schlichten frame:Hide() (XML-OnHide -> GameDialogMixin:OnHide ->
StaticPopup_OnHide -> dialogInfo.OnHide). Das OnHide des Sku-Menues ruft genau
dieses StaticPopup1:Hide(). Neu ist SkuCore:NeutralizePopupHide(frame), direkt
davor aufgerufen: fuer PARTY_INVITE setzt es inviteAccepted, so dass Blizzards
OnHide das Ablehnen ueberspringt, und markiert den Frame, damit der eigene Hook
ein neutralisiertes Verstecken von einer echten Antwort unterscheiden kann -
schlichte Felder auf einem unsicheren Frame, kein Taint; OnShow setzt
inviteAccepted zurueck, ein spaeteres echtes Anzeigen bleibt also unberuehrt.
Eine Abfrage-API fuer offene Einladungen gibt es auf diesem Client nicht, der
Merker ist also unserer: gesetzt bei PARTY_INVITE_REQUEST, verworfen bei
PARTY_INVITE_CANCEL, bei jedem nicht neutralisierten Verstecken (echtes
Annehmen, Ablehnen, Zeitablauf) und durch die eigene Frist. Fuer das Protokoll
wurden alle Dialoge mit zerstoerendem OnHide geprueft: PARTY_INVITE (hier
behoben), LEVEL_GRANT_PROPOSED (DeclineLevelGrant), EQUIP_BIND und Verwandte
(CancelPendingEquip - ohne Ueberspring-Flag, braucht eine andere Loesung) und
QUIT (CancelLogout, harmlos).
Ausstehende Aufforderungen bleiben im Local-Menue erreichbar
Einfach: Wenn du mit Escape aus dem Sku-Menue gehst, verschwindet ein offener
Dialog vom Bildschirm - eine Beschwoerung, die Frage nach dem Geist, eine
Wiederbelebung, eine Bereitschaftspruefung. Bisher war er damit bis zum
naechsten /reload weg, obwohl er auf dem Server die ganze Zeit gueltig blieb.
Solche Aufforderungen stehen jetzt als eigener Punkt direkt unter "Local", nach
der Aufforderung benannt; RECHTS oder EINGABE zeigt das echte Fenster wieder an,
und Sku steigt hinein, so dass du die gewohnten Schaltflaechen bedienst.
Technisch: Neues Modul SkuCore/pendingPrompts.lua. Die Aufforderungen werden aus dem
ZUSTAND wiederhergestellt, nicht aus dem Frame: Beschwoerung ueber C_SummonInfo,
Wiederbelebung ueber ResurrectGetOfferer, Geist-Freigabe ueber
GetReleaseTimeRemaining plus die Selbstwiederbelebungs-Optionen aus C_DeathInfo,
Bereitschaftspruefung ueber GetReadyCheckTimeLeft/Status. Ein rohes :Hide()
erreicht nur StaticPopup_OnHide und nie OnCancel, es wurde also nie etwas
abgelehnt oder freigegeben - nur PLAYER_ENTERING_WORLD zeigt DEATH und
CONFIRM_SUMMON von sich aus wieder an, daher "weg bis zum /reload". Solange der
zugehoerige Dialog auf dem Bildschirm steht, wird der Punkt unterdrueckt, es
gibt ihn also nie doppelt neben dem Popup-Eintrag. Wichtig ist, dass diese
Punkte PASSIV sind: das "ist ueberhaupt etwas offen"-Kriterium in CheckFrames
haelt einerseits ein offenes Menue am Leben und reisst andererseits ueber
SlashFunc das Menue auf. Ausstehende Aufforderungen speisen nur das Erste
(tPendingOnly), sonst wuerde eine dauerhaft erreichbare Aufforderung bei jedem
Taschen-Update das Menue aufziehen; aus demselben Grund bleiben sie aus
combatMenuHasWindow heraus. Zuerst gab es eine verschachtelte Form mit eigenen
Aktionspunkten - funktionsfaehig, aber zu viel Navigation. Jetzt ist es ein
einziger flacher Punkt je Aufforderung: kind="action" mit dynamic=true, damit
RECHTS ueberhaupt auf OnSelect geht, plus eine OnSelect-Umleitung, die die
uebliche Abstiegsmechanik umgeht; die echten Schaltflaechen kommen ueber das
normale Auslesen des wieder angezeigten Fensters.
Handel: was im Handelsfenster liegt, wird jetzt live angesagt
Einfach: Einen Gegenstand per Rechtsklick in das Handelsfenster zu legen war voellig
still, und sein Eintrag im Taschenmenue blieb unveraendert stehen. Jetzt sagt Sku
" in Handelsplatz N" beziehungsweise "Handelsplatz N geleert", und
das auch fuer die Seite deines Handelspartners, die vorher weder sicht- noch
hoerbar war. Die Listen "Deine Gegenstaende" und "Gegenstaende des Partners"
aktualisieren sich von selbst, der Punkt "Aktualisieren" wird dafuer nicht mehr
gebraucht. Solange ein Gegenstand im Handel liegt, steht "im Handel" VOR seinem
Taschen-Eintrag, wird also vor dem Gegenstandsnamen gesprochen; und sobald der
Zusatz an dem Eintrag auftaucht, auf dem du gerade stehst, sagt Sku nur "im
Handel" - der ganze Gegenstandsname wird dir nicht noch einmal vorgelesen. Und
nach einem abgeschlossenen Handel verschwindet der weggegebene Gegenstand jetzt
zuverlaessig aus der Taschenliste statt nur manchmal.
Technisch: Die vorhandene Verkaufs- und Bank-Mechanik konnte hier nicht greifen:
einen Gegenstand ins Handelsfenster zu legen entfernt ihn nicht aus der Tasche.
Der Client setzt lediglich isLocked auf den Platz (Blizzards eigenes
ContainerFrame reagiert auf ITEM_LOCK_CHANGED nur mit einem blassen Symbol), es
feuert also kein BAG_UPDATE, auf das die bestehenden Handler haetten reagieren
koennen. Aus den Taschen verschwinden die Gegenstaende erst, wenn der Handel
ABGESCHLOSSEN ist - und dieses BAG_UPDATE liefert sich ein Rennen mit dem
CheckFrames aus TRADE_CLOSED, waehrend Sku.tBagPostAction schon 2,5 Sekunden
nach dem Rechtsklick abgelaufen war. Dieses verlorene Rennen war das "manchmal
bleibt es stehen". Neu ist Sku.tBagSettleWindow, ein zweites, engeres Fenster in
SkuCore:BAG_UPDATE_DELAYED, von TRADE_CLOSED fuer 3 Sekunden scharfgestellt, das
den STILLEN SkuBagIdleRefresh ausloest - nicht die sprechende Bestaetigung, denn
am getauschten Gegenstand haengt kein Cursor -, plus 1 Sekunde Rueckfall fuer das
umgekehrte Rennen. TRADE_PLAYER_ITEM_CHANGED und TRADE_TARGET_ITEM_CHANGED
werden erstmals registriert, pro Platz nach Gegenstand und Anzahl entdoppelt und
auf TradeFrame:IsVisible begrenzt, damit die Salven am Handelsende still bleiben.
Beide teilen sich SkuCore:TradeMenuRefresh, einen entprellten stillen Neuaufbau.
Der Zusatz "im Handel" steht vorn: in einer Taschenliste direkt hinter der
Positionsnummer, in "alle Gegenstaende" erst NACH dem Sortieren davorgesetzt
(wie der "neu"-Zusatz), damit der voruebergehende Zusatz keinen Gegenstand aus
seiner alphabetischen Position schiebt. Die Ansage haengt am stillen Neu-Anheften
in SkuBagIdleRefresh: es vergleicht den Zusatz am fokussierten Eintrag vor und
nach dem Neuaufbau und spricht nur, wenn er neu dazugekommen ist - das entdoppelt
sich von selbst, weil die nachfolgenden Refreshes ihn auf beiden Seiten sehen.
SkuCore:TradePartnerName ist jetzt die einzige Quelle fuer den
Partnernamen, auch fuer die bestehende Goldansage.
Kampf: Sku sagt an, wenn ein Zauber unterbrochen wurde
Einfach: Unter Feindlich -> Zauber gibt es "Unterbrechungen ansagen" jetzt getrennt
fuer dein aktuelles Ziel und fuer alle Gegner - genau wie die Zauberansagen
selbst. So kannst du Unterbrechungen auf deinem eigenen Ziel hoeren, ohne jede
Unterbrechung im ganzen Schlachtzug mitzubekommen. Unterbrichst du selbst oder
dein Begleiter, heisst es "Du hast den Zauber unterbrochen" mit dem Zaubernamen;
unterbricht jemand aus deiner Gruppe, heisst es "Zauber unterbrochen". Ab Werk
ist nur die Ansage fuer dein aktuelles Ziel an, alle Gegner schaltest du bei
Bedarf selbst dazu; wer die Ansage schon einmal ausgeschaltet hatte, bleibt still.
Technisch: SPELL_INTERRUPT aus dem Kampflog ueber das neue Dispatcher-Ereignis
SKU_SPELL_INTERRUPT. Der frueher einzelne Schalter outputInterrupts ist durch
yourTargetInterrupts und allEnemiesInterrupts ersetzt; nur yourTargetInterrupts
wird aus dem alten Wert vorbelegt, allEnemiesInterrupts startet aus. Steht der
globale Schalter aus, wird nur angesagt, wenn die
destGUID des unterbrochenen Zaubers dein aktuelles Ziel ist; stehen beide an,
gibt es trotzdem nur eine Ansage. Als "du" gilt die Quellzugehoerigkeit MINE, was
den eigenen Begleiter einschliesst (Teufelsjaeger-Zauberblockade und Aehnliches).
Kampf: Zauberansagen lassen sich auf unterbrechbare Zauber beschraenken
Einfach: Neue Einstellung "Nur unterbrechbare Zauber ansagen" (ab Werk aus) unter
Feindlich -> Zauber. Ist sie an, meldet Sku Zauber nicht mehr, gegen die ein
Unterbrechen ohnehin nichts ausrichtet.
Technisch: Der Rueckgabewert notInterruptible von UnitCastingInfo und
UnitChannelInfo ist auf dem Anniversary-Client 2.5.6 tote Datenlage - er kam bei
jedem Zauber als nil zurueck, waehrend Rueckgabe 9 die richtige spellId
lieferte; Blizzards eigene Zauberleiste setzt das Flag fuer BC und aelter fest
auf false. Die Unterbrechbarkeit stammt daher aus einer statischen Liste, neu
unter SkuDB/uninterruptibleCasts.lua, uebernommen aus ClassicCastbars
(MIT-Lizenz). Sie deckt die alte Welt ab; fuer eigene TBC-Funde stehen leere
SkuTbcAdditions-Tabellen zum Nachtragen bereit. Abgeglichen wird ueber spellID,
lokalisierten Namen oder npcID plus Name.
Weiches Zielen: "wenn kein hartes Ziel gewaehlt ist" wirkt jetzt wirklich
Einfach: Die Einstellung, ob weiches Zielen fuer das Interagieren verwendet werden
soll, hat nie etwas bewirkt. Der Interagieren-Taste war es egal, ob du ein Ziel
hart angewaehlt hattest - eine Leiche oder ein Stuhl daneben hat den Tastendruck
trotzdem abgefangen. Das ist behoben, und zwar im Client statt in einer
Nachbildung.
Zu beachten: Diese Client-Einstellungen sind im Kampf gesperrt. Sku haelt sie
deshalb im Ruhezustand so, dass die Unterdrueckung schon steht, wenn dich etwas
anspringt und du erst im Kampf anvisierst. Zwei Ecken bleiben: Toetest du dein
Ziel, bleibt der Zustand bis zum naechsten Zielwechsel bestehen - in diesem
Moment sind Objekte in der Naehe nicht ansprechbar (die anvisierte Leiche selbst
pluenderst du normal). Und geraetst du mit einem nicht angreifbaren Ziel in den
Kampf, bleibt es fuer diesen Kampf beim weichen Zielen. Das braucht einen
Schreibzugriff im Kampf und ist aus einem Addon heraus nicht zu schliessen.
Technisch: Alle 32 SoftTarget-CVars sind in 2.5.6 weiterhin registriert (in
WowClassic.exe nachgeschlagen) - am Client liegt es also nicht. Beide Zweige des
alten if/else schrieben SoftTargetMatchLocked = 0, identisch toter Code in
v32.31 wie in v41.04; die Einstellung verliess Lua nie. 41.05 schrieb dann 1,
legte aber Option 2 mit Option 1 zusammen, und SoftTargetWithLocked - die CVar,
die das tatsaechlich steuert - hat nie eine Sku-Version geschrieben. Gemessen auf
2.5.6.68575, ausserhalb des Kampfes, Leiche und lebender Gegner in Reichweite,
Interagieren-Taste bei hart angewaehltem Gegner: WithLocked 0 wirkt auf den
Gegner und ignoriert die Leiche, 1 und 2 pluendern beide die Leiche. Nur 0
unterdrueckt weiches Zielen bei gewaehltem Ziel, und einen "nur wenn
angreifbar"-Zwischenwert gibt es nicht. Die Option bildet das jetzt direkt ab:
0 (immer) -> WithLocked 2, MatchLocked 0; 1 (wenn kein hartes Ziel) ->
WithLocked 0, MatchLocked 1; 2 (kein angreifbares Ziel) -> MatchLocked 2, und
WithLocked wird bei PLAYER_TARGET_CHANGED zwischen 0 und 2 umgelegt. Der
Ruhezustand ist 0, weil WithLocked ohnehin nur wirkt, solange ein Ziel gewaehlt
ist - dort zu ruhen kostet nichts und deckt den Fall ab, den die CVars sonst nie
erreichen. 2 wird nur noch fuer den einen Zustand geschrieben, der weiches Zielen
MIT gewaehltem Ziel wirklich braucht: ein Ziel, das du nicht angreifen kannst -
eine Leiche beim Pluendern, ein NPC im Gespraech, ein Spieler, dem du folgst.
Entfernt: der SkuMob-Ticker, der SoftTargetInteract viermal pro Sekunde neu
schrieb, sein Duplikat in PLAYER_TARGET_CHANGED und der Schattenzustand
interactTempDisabled - diese Nachbildung konnte gar nicht funktionieren, weil die
CVars im Kampf geschuetzt sind. tSetSoftTargetCVar liest jeden Schreibvorgang
jetzt zurueck (numerischer Vergleich, damit ein normalisiertes "15.000000" kein
Fehlalarm ist) und stellt bei Ablehnung die Wiederholung auf
PLAYER_REGEN_ENABLED scharf, statt sich einen Wert zu merken, der nie ankam. Ein
Schreibversuch im Kampf protokolliert "softTarget refused ... {want=3, got=0}"
und loest ADDON_ACTION_BLOCKED aus.
Menue: die Eingabetaste wirkte nach dem Schliessen ins unsichtbare Menue weiter
Einfach: Nach dem Auswaehlen eines Wegpunkts - und in aehnlichen Faellen - schloss
sich das Menue korrekt, aber jede weitere Eingabetaste klickte noch im
unsichtbaren Menue weiter: Es ertoente das Navigationsgeraeusch, die Auswahl
wurde erneut ausgefuehrt ("neue Navigation"), und das Chatfenster liess sich mit
der Eingabetaste nicht mehr oeffnen. Ausserdem konnte das Menue beim Schliessen
haengenbleiben, wenn im selben Moment eine Bewegungstaste gedrueckt wurde: Der
Wegpunkt wurde gesetzt, das Menue blieb aber offen und blockierte die Tasten.
Beides ist behoben.
Technisch: Zwei getrennte Ursachen. Erstens laeuft OnPostSelect nach der Aktion
weiter, die das Menue geschlossen hat: Es richtete currentMenuPosition wieder auf
das selectTarget aus - und ueberschrieb damit die Wurzel-Ruecksetzung des
Schliessens - und feuerte dessen OnEnter; das allgemeine OnEnter legte die
SKU_KEY_MENULEFTCLICK-Override-Bindings auf dem sicheren Button bedingungslos neu
auf. Override-Bindings auf einem VERSTECKTEN Frame sind voll aktiv, die
Eingabetaste wurde also unmittelbar nach dem Aufraeumen im OnHide wiederbelebt.
Jetzt legt das allgemeine OnEnter die Klick-Tasten nur auf, solange der sichere
Button sichtbar ist, und OnPostSelect bricht vor dem abschliessenden Neu-Fokus
ab, wenn das Menue nicht mehr offen ist (das kopflose Kampfmenue ist ueber
combatMenuActive ausgenommen). Zweitens laeuft CloseMenu ueber denselben
Umschalt-Handler wie das Oeffnen, dessen zwei Bewegungs-Sperren das Schliessen
stillschweigend abbrachen - die eine liest die LIVE-Bewegungsflags, die andere
das zwischengespeicherte SkuCore.isMoving, weshalb der eine Weg durchkam und der
andere abbrach. Schliess-Anforderungen umgehen diese Sperren jetzt; Hide und
ClearOverrideBindings sind waehrend der Bewegung unbedenklich, und ein
erfolgreiches Schliessen erreicht wieder die openMenuAfter-Ruecksetzungen.
Zusaetzlich entschaerft der Wiederoeffnen-Ticker Flags, die ohnehin nicht mehr
feuern koennen, und stellt die Navigationstasten nur dann neu her, wenn das Menue
sichtbar offen, aber tastentot ist (neu: SkuOptions.menuNavKeysBound).
Kollisionswarnung auch beim automatischen Hinlaufen zum Ziel
Einfach: Die Warnung, dass du gegen etwas laeufst, kam nur, wenn du selbst eine
Bewegungstaste gedrueckt hieltest. Beim "Mit Ziel interagieren" der
Spielsteuerung laeuft die Spielengine dich hin, ohne dass eine Taste gehalten
wird - dort konntest du unbemerkt an einem Hindernis haengenbleiben. Diese Laeufe
sind jetzt mit abgedeckt.
Technisch: Neues EngineMoving-Flag aus PLAYER_STARTED_MOVING und
PLAYER_STOPPED_MOVING, das die koordinatenbasierte Warnung auch fuer
engine-getriebene Laeufe scharfstellt. PLAYER_STOPPED_MOVING feuert nicht,
waehrend man gegen eine Wand drueckt - genau der Fall, den die Warnung braucht
(nachgewiesen ueber das Aufraeumen des stehengebliebenen AutoRun-Flags). Reines
Drehen, Fallen und Autofolgen sind ausgenommen; fuer das Folgen gibt es die
eigene Folge-Kollisionswarnung.
Weniger Fehler in Instanzen und Schlachtzuegen
Einfach: Zwei Fehlerquellen, die in Instanzen laufend Lua-Fehler erzeugt haben, sind
behoben - spuerbar an ausbleibenden Fehlermeldungen und ruhigeren Bosskaempfen.
Technisch: Erstens liefert UnitPosition("player") in Instanzen, Schlachtzuegen und
Schlachtfeldern nil, weshalb SkuNav:Distance nil zurueckgab und
GetUnsortedAvailableQuestsTable bei jedem QUEST_LOG_UPDATE beim Verketten
abstuerzte (24-mal in einer einzigen Schlachtzugssitzung). Es gilt jetzt die
bestehende 99999-Meter-Konvention: Die Quest bleibt gelistet und sortiert
zuletzt. Zweitens sind ClearOverrideBindings und SetOverrideBindingClick im Kampf
geschuetzt, und das umgebende pcall unterdrueckt das ADDON_ACTION_BLOCKED-Ereignis
nicht (84-mal in einem einzigen Kampf, dazu BugGrabber-Warnungen wegen
Ausfuehrungslimits). Das Setzen der AtlasLoot-Tastenbelegung wird im Kampf jetzt
uebersprungen und einmalig ueber PLAYER_REGEN_ENABLED nachgeholt.
"Folgen beim Zaubern temporaer beenden" ist zu Testzwecken wieder aktiv
Einfach: Diese Einstellung stand im Menue, ihre Funktion war aber seit dem
Upstream-Stand v41.06 abgeschaltet. Sie ist wieder eingeschaltet, ab Werk aus,
damit sich klaeren laesst, ob dieser Client das automatische Wiederaufnehmen des
Folgens ueberhaupt zulaesst. Wer sie einschaltet, sollte damit rechnen, dass das
Folgen nach einem Zauber nicht von selbst zurueckkommt.
Technisch: Die Ruempfe von UnfollowOnCast und FollowOnCast waren auskommentiert, der
Grund ist nicht ueberliefert. Sie beantworten jetzt eine Frage: Fuehrt dieser
Client FollowUnit aus einem Server-Ereignis heraus aus, also ohne
Hardware-Ereignis, oder wird das still unterbunden? Beweiskanal sind die
Sprachausgaben zu AUTOFOLLOW_END/BEGIN und "followcast"-Zeilen im SkuDebugLog
samt einer Zustandspruefung 0,5 Sekunden nach dem Aufruf. Nebenbei behoben: In
den Handlern fuer CHANNEL_START/STOP passten unitTarget und aUnitTarget nicht
zusammen, weshalb Beenden und Wiederaufnehmen bei Kanalzaubern nie ausgeloest
wurden.
Post: Sku las nach dem Absenden eines Briefes das Getippte noch einmal vor
Einfach: Eine Weile nachdem ein Brief abgeschickt war, fing Sku an, die
eingegebenen Buchstaben zu wiederholen - teilweise lange nachdem der Briefkasten
schon geschlossen war. Dahinter steckten zwei voneinander unabhaengige Fehler.
Erstens galt der Briefkasten intern bis zum naechsten /reload als offen, sobald
man ihn einmal geoeffnet hatte; jede spaeter eintreffende Post baute daraufhin
das Menue neu auf und sagte den aktuellen Eintrag erneut an - egal, wo im Menue
man gerade war. Stand man dabei auf einem Brieffeld, war dieser Eintrag der
gerade eingegebene Text. Zweitens haengte das zeichenweise Vorlesen beim Tippen
jedes Zeichen hinten an die Sprachschlange an: Wer schneller tippt, als die
Stimme spricht, baute damit einen Rueckstau auf, den das Schliessen des
Eingabefelds nicht beendete - er wurde einfach weiter abgearbeitet.
Jetzt folgt die Ansage dem Tippen: Faellt sie zu weit zurueck, wird das noch
nicht Gesprochene verworfen, statt hinterherzulaufen. "Gesendet" und die
Bestaetigung eines Feldes kommen sofort, nicht mehr hinter allem Getippten. Und
eine Posteingangs-Aktualisierung wirkt nur noch, solange der Briefkasten
wirklich offen ist und man sich im Post-Zweig des Menues befindet. Zwei
Kleinigkeiten am selben Ort: Das Einfuegefeld fuehrte seine OK-Aktion beim
n-ten Oeffnen n-mal aus, und beide Sku-Eingabefelder geben beim Schliessen jetzt
zuverlaessig die Tastatur wieder frei.
Technisch: MailboxOpenFlag wurde in MAIL_SHOW gesetzt, aber nirgends
zurueckgesetzt; MAIL_CLOSED loescht es jetzt. MAIL_INBOX_UPDATE kommt nicht nur
am geoeffneten Briefkasten - der Server schickt es auch, wenn spaeter Post
eintrifft - und lief ungebremst in den generischen OnUpdate
(SkuZOptions/templates.lua). Der ist kein stiller Refresh: Er verwirft die
Kinder der aktuellen Ebene, baut sie neu auf und ruft VocalizeCurrentMenuName.
Zusaetzlich zur Flagge pruefen wir jetzt MailFrame:IsVisible() und laufen die
Elternkette bis zum Local-Beitragsknoten L["Mail"] hoch - nur dort ist ein
Neuaufbau ein Refresh und kein Fremdeingriff. Der SlashFunc-Zwangsaufruf ohne
Menue-Position bleibt allein fuer den echten Fall am offenen Briefkasten; ein
Hintergrundereignis darf das Menue nie aufzwingen.
Das Tipp-Vorlesen aus v42.08 haengt bewusst an, statt zu ueberschreiben, sonst
verschluckt schnelles Tippen Zeichen - aber es hatte keine Obergrenze. Bei rund
0,4 Sekunden je Zeichen gegen vier bis fuenf Anschlaege pro Sekunde waechst die
Schlange unbegrenzt, und die Abarbeitung schiebt einen Rueckstau mit etwa 100
Eintraegen je Sekunde in C_VoiceChat.SpeakText, wo Sku ihn nicht mehr einholt.
Neu in SkuVoice-1.0 sind deshalb GetBttsQueueDepth und TrimBttsQueue(aKeep):
Verworfen wird ausschliesslich, was noch in Skus eigener Schlange WARTET, nie
etwas bereits Uebergebenes - deshalb kann dabei kein Wort zerschnitten werden,
und deshalb ist das auch mit "Warteschlangen nie zuruecksetzen" zulaessig, denn
diese Einstellung meint das Abwuergen laufender Sprache. Der Deckel liegt bei
drei wartenden Zeichen. Vor dem OK-Rueckruf wird der Rueckstau verworfen, und
MAIL_SEND_SUCCESS wie die Feldbestaetigung in MailEditor sprechen jetzt
ueberschreibend statt anhaengend. EditBoxPasteShow haengte sein OnEnterPressed
bei JEDEM Aufruf per HookScript an - HookScript ersetzt nicht, es kettet -,
weshalb der OK-Rueckruf beim n-ten Oeffnen n-mal lief; er steht jetzt im
Einmal-Zweig. Beide Eingabefelder rufen beim Ausblenden ClearFocus, da das Feld
ein Enkel des versteckten Rahmens ist und der Tastaturfokus sonst an einem
unsichtbaren Eingabefeld haengen bleibt.
Gegenstandslevel: bei jedem Gegenstand kam dieselbe Zahl
Einfach: Das Gegenstandslevel in den Gegenstandsbeschreibungen war falsch, solange
es das gibt. Es gehoerte gar nicht zu dem Gegenstand, den du gerade gelesen
hast, sondern zu irgendeinem, der irgendwann vorher in Sku nachgeschlagen wurde
- meist Stunden frueher -, und dabei blieb es die ganze Sitzung lang. Deshalb
kam bei jedem Gegenstand dieselbe Zahl, und deshalb war es so oft eine 1: ein
Schluessel oder ein Questgegenstand, also genau das, was frueh nachgeschlagen
wird und tatsaechlich Gegenstandslevel 1 hat. Ein /reload half nicht, denn die
falsche Zahl war kein veralteter Wert, der sich auffrischen laesst - es wurde
schlicht der falsche Gegenstand gefragt. Derselbe falsche Gegenstand bestimmte
auch die Qualitaet, die an Gegenstandsnamen angehaengt wird. Beides stimmt jetzt.
Angesagt wird das Gegenstandslevel ausserdem nur noch bei Ausruestung, die du
wirklich anlegen kannst: Schluessel, Questgegenstaende, Reagenzien und
Verbrauchbares haben grundsaetzlich Gegenstandslevel 1, die Zeile sagte darueber
also nichts aus und faellt weg. Auch dort, wo sie nie hingehoerte, ist sie
verschwunden - etwa in Buff-Beschreibungen und bei den Widerstaenden im
Charakterfenster.
Technisch: Das GetItem() eines Tooltips ist ein haftender Zwischenspeicher und keine
Auskunft darueber, was der Rahmen gerade anzeigt: ClearLines() setzt es nicht
zurueck, und ein SetX(), das nichts fuellt, ebenso wenig - ein nicht
zwischengespeicherter Gegenstand, Bankbehaelter -1, oder jeder Zauber-, Aura-
und Wertetooltip, hinter dem gar kein Gegenstand steht. SkuScanningTooltip wird
einmal bei PLAYER_LOGIN erzeugt und nie neu vergeben, sein GetItem() antwortet
also weiter mit dem letzten Gegenstand, der jemals darueber aufgeloest wurde.
Dazu kam, dass TooltipLines_helper den Link aus SkuScanningTooltip las,
gleichgueltig wessen Regionen ihm uebergeben worden waren - und die meisten
Aufrufer uebergeben die des GameTooltip. Zwei kleinere Fehler kamen hinzu: der
zweite Rueckgabewert von GetSpell(), der kein Link ist, wurde nach ItemLink
geschrieben und an GetDetailedItemLevelInfo gereicht; und ein nicht
zwischengespeicherter Gegenstand liefert einen LEEREN Link, der in Lua wahr ist
und die Pruefung "if ItemLink then" damit ungehindert passierte. Die Aufloesung
liegt jetzt in SkuUtil - TooltipFirstLine, TooltipItemLink, ItemQualityString,
ItemLevel - und traut GetItem() nur dann, wenn der gemeldete Name zur tatsaechlich
angezeigten ersten Tooltipzeile passt; das ist der einzige verlaessliche
Anhaltspunkt. Die drei doppelten Bloecke in LocalMenu und utilities gehen darin
auf; tScanTooltipRegions ermittelt Link, Qualitaet und Gegenstandslevel selbst
und gibt den geprueften Link zurueck, damit nachgelagerte Aufrufer genau den
bekommen, den der Text beschreibt. Die Ausruestungspruefung liest equipLoc aus
GetItemInfo und faellt auf C_Item.GetItemInventoryTypeByID zurueck, solange der
Gegenstandsspeicher noch kalt ist.
Franzoesisch: Sku gibt es jetzt auf Franzoesisch
Einfach: Sku laesst sich jetzt auf Franzoesisch benutzen - getestet auf einem
franzoesischen Client. Rund 95 Prozent der Menue- und Ansagetexte sind uebersetzt (3063 von 3220
Eintraegen), alles Uebrige faellt automatisch auf Englisch zurueck, so dass nie
eine Luecke oder ein leerer Eintrag entsteht. Dazu kommen zwei Dinge, die frueher
noch fehlten: Die Routen- und Wegpunktnamen der Uebersetzungsstrecke haben eine
eigene franzoesische Tabelle mit 153 Eintraegen, deren Ortsnamen aus einer echten
Aufnahme eines franzoesischen Clients importiert und nicht geraten sind, und alle
158 zweisprachig im Code stehenden Texte fuehren jetzt auch eine franzoesische
Fassung. Die
SPIELnamen - Kreaturen, Quests, Gegenstaende, Objekte - sind vollstaendig aus
Questie uebernommen, also Blizzards eigene franzoesische Zeichenketten und nicht
maschinell uebersetzt; sie stimmen mit dem ueberein, was ein franzoesischer
Client anzeigt, was fuer die Suche nach Routen- und Wegpunktnamen entscheidend
ist. Zonennamen kommen direkt vom Client. Sprachausgabe gibt es weiterhin nur auf
Deutsch und Englisch; jede andere Clientsprache benutzt die englischen
Audiodateien.
Fuer deutsche und englische Spieler aendert sich am Text nichts, wohl aber am
Speicherbedarf: Sku baut jetzt nur noch die Namenstabellen der eigenen Sprache
auf, plus Englisch als Rueckfall, statt wie bisher immer alle.
Technisch: Sku.Locs ist jetzt eine GEORDNETE Liste von drei Sprachen, und die
gepackten Routennamen in SkuNav:LoadDefaultMapData werden positionsweise dagegen
aufgeteilt statt ueber ein string.match mit dem Muster "(.+)" links und rechts
vom Trennzeichen. Dieser alte Ausdruck war nicht nur zweisprachig gedacht:
".+" ist gierig, bei drei Feldern "a", "b", "c" waeren die ersten beiden als ein
einziges englisches Feld angekommen und nur das letzte als deutsches. Dateien
mit weniger Feldern als Sprachen bleiben
gueltig und fallen auf enUS zurueck. Sku.LocAudio trennt die AUDIO-Sprache von
der Datensprache; dabei sind zwei alte Fehler mit aufgefallen und behoben:
SkuAudioFileIndexIntegrated[Sku.Loc] war ungeschuetzt und lief bei jeder
Clientsprache ohne eigene Untertabelle in einen nil-Zugriff, und GetAudiodata
hatte keinen Gross-/Kleinschreibungs-Rueckfall, waehrend der enUS-Index seine
Bezeichner kleingeschrieben ablegt und die Aufrufer sie gross uebergeben - das
ist der Grund, warum die Drinnen/Draussen-Ansage auf englischen Clients bisher
still war. Der ChunkLoader hat jetzt eine Sprachschranke: Er baute bisher JEDEN
registrierten Chunk unabhaengig von der Clientsprache, ein deutscher Client
materialisierte also auch die vollstaendigen englischen Namenstabellen und
umgekehrt. Die Regel ist nun "aktive Sprache plus enUS", mit objectLookup.deDE
als struktureller Ausnahme, weil das englische objectLookup aus dessen
Schluesselmenge ABGELEITET wird - eine naive Schranke haette englische Clients
ganz ohne Objektnamen zurueckgelassen. Die vier fest verdrahteten .deDE-Merges
sind zu SkuDBMergeLocales geworden, was einen latenten Fehler mit erledigt: Ein
franzoesischer Client haette Basis-TBC-Namen bekommen, aber stillschweigend keine
WotLK-Namen. Nach dem Zusammenfuehren werden Luecken der aktiven Sprache aus enUS
aufgefuellt (Questie kennt fuer rund 2700 Sku-IDs keinen franzoesischen Namen);
bewusst als Build-Schritt und nicht als __index-Metatabelle, weil pairs() ein
__index nicht durchlaeuft und mehrere Verbraucher diese Tabellen AUFZAEHLEN statt
zu indizieren - eine Metatabelle haette die Nachschlagevorgaenge repariert und die
Menues still verkuerzt. deDE und enUS sind vom Auffuellen ausgenommen, damit der
deutsche Aufbau byteweise identisch bleibt (nachgewiesen, 37 von 37 Datensaetzen).
Die Sprachdatei selbst ist Sku/locales/frFR.lua, erzeugt aus Teil-Dateien: Nicht
uebersetzte Eintraege behalten ihren englischen Wert, die Tabelle ist also immer
vollstaendig und gueltiges Lua, und AceLocale liefert fuer de/en ohnehin nil
zurueck - die Datei kostet dort nur einen Parse. Fuehrende und abschliessende
Leerzeichen sind in dieser Tabelle bedeutungstragend, ueberleben aber keine
TSV-Runde: Sie werden beim Zusammenbauen aus dem englischen Original neu
angesetzt, und die Pruefung kontrolliert am FERTIGEN String Platzhalterzahl,
Randleerzeichen und Semikolonzahl. Zum Testen ohne zweiten Client gibt es
/skudebug locale , das die DATEN-Sprache erzwingt und dauerhaft merkt;
es greift auf ADDON_LOADED, nicht auf PLAYER_LOGIN, weil der verzoegerte
Routenaufbau (Messung: 1,87 s gegen 2,01 s bis PLAYER_LOGIN) bereits entscheidet,
welche Namensfelder ueberhaupt aufgebaut werden. Drei harte Fehler auf einem
erzwungen franzoesischen Client sind behoben: maps.lua ist eine einfache, nicht
gechunkte Tabelle und trug AreaName_lang/Name_lang nur fuer deDE und enUS - die
fehlende Sprache wird jetzt einmalig auf ADDON_LOADED aus C_Map gefuellt
(GetAreaInfo und GetMapInfo; 2819 Eintraege, davon 1672 vom Client), also mit den
echten Blizzard-Namen und ohne eigene Zonennamensdaten; SkuDB.SpellDataTBC legt
seine Sprachen INNERHALB jedes Eintrags ab, weshalb sie nie lokalisiert wurden
und elf Fundstellen auf frFR abstuerzten - die aktive Sprache zeigt dort jetzt
als Referenz auf die englische Untertabelle (kein Kopieren, keine zusaetzlichen
Zeichenketten), was fuer diese ueberwiegend als Aura-Schluessel genutzten Namen
genuegt; SkuDB.objectResourceNames ist nach Objektnamen je Sprache verschluesselt
und wurde beim Aufbau des Wegpunkt-Caches ungeschuetzt gelesen - hier waere ein
englischer Rueckfall falsch gewesen (er haette nie gepasst und jedes Erz und Kraut
still zu einem gewoehnlichen Wegpunkt gemacht), die Menge wird deshalb ueber die
Objekt-IDs abgeleitet.
Der gesamte franzoesische Zweig ist inzwischen auf einem franzoesischen Client
durchgespielt worden und laeuft: Menues, Namen und Routen erscheinen
franzoesisch, und wo keine Uebersetzung vorliegt, greift der englische Rueckfall
ohne Luecke. Die Routentabelle routeOverrides_frFR.lua und das dritte Argument
an allen Sku.deEn-Stellen sind Teil davon. Da zhCN und ruRU auf Sku.Loc = enUS
laufen, deckt derselbe Durchlauf sie mit ab.
Downloadseite: die Ueberschrift nannte eine veraltete Version
Einfach: Auf der Downloadseite stand in der Ueberschrift zum Haupt-Addon noch
"Version 42.06", waehrend der Link darunter korrekt auf 42.10 zeigte. Da man mit
dem Screenreader ueber Ueberschriften navigiert, war das Erste, was in diesem
Abschnitt angesagt wurde, die falsche Version - es klang, als liefere die Seite
ein veraltetes Sku aus. Ueberschrift und Link stimmen jetzt ueberein.
Technisch: release.ps1 hat bei jedem Release href und Linktext neu geschrieben, aber
nie die Ueberschrift; sie stand seit 42.06 (17.07.2026) ueber vier Releases
hinweg still. Die Ueberschrift ist jetzt Teil von Set-DocsSkuLink und kann nicht
mehr auseinanderlaufen. Die verlinkte Zip war die ganze Zeit korrekt (geprueft:
Sku-42.10.zip enthaelt "## Version: 42.10").
Beacons: ein eigener Ton fuer den letzten Wegpunkt einer Route
Einfach: Neben den Toenen fuer kleine und grosse Beacons gibt es jetzt einen
dritten: den Ton fuer den letzten Beacon einer Route. Er erklingt nur beim
letzten Wegpunkt einer Metaroute, so dass hoerbar ist, ob der Punkt, auf den du
zulaeufst, das Ziel ist oder nur eine weitere Etappe. Die Einstellung steht
unter Monitor -> Beacon direkt unter den Toenen fuer kleine und grosse Beacons
und ist ab Werk Beacon 3. Beim Verfolgen eines einzelnen Wegpunkts aendert sich
nichts - dort gilt weiterhin der kleine oder grosse Ton je nach Groesse des
Wegpunkts.
Technisch: Neue Profil-Einstellung SkuNav beaconSoundSetLast (Vorgabe "Beacon 3"),
im SkuNav-Schema deklariert und in die ausdrueckliche Knotenliste des
Beacon-Untermenues in SkuCore/aq.lua aufgenommen - diese Liste ist nicht die
gesamte args-Tabelle, ein neuer Optionsknoten muss also auch dort stehen, sonst
taucht er im Menue nie auf. GetBeaconSoundSetName nimmt ein zweites Argument
und liefert damit den Ton fuer den letzten Beacon; das Verhalten fuer
schmal/breit und die einarmigen Aufrufer (Panikbeacon, TomTom-Hook) bleiben
unberuehrt. Das neue SkuNav:IsLastMetaRouteWp vergleicht den NAMEN des
Wegpunkts mit dem letzten Eintrag von
metapathFollowingMetapaths[target].pathWps, statt metapathFollowingCurrentWp
zu lesen: SelectWP laeuft, bevor dieser Index weitergesetzt wird - eine
Indexpruefung waere um eins daneben. Ueber den Namen sind auch das
Vorwaertsspringen per MoveToWp und der Start einer Rueckwaertsroute abgedeckt,
die alle den Metapfad-Zustand vor dem SelectWP-Aufruf setzen.
Bessere Vorgaben fuer neue Spieler
Einfach: Wer Sku neu einrichtet, faengt jetzt mit einer brauchbaren
Grundeinstellung an, statt sich das Wichtigste erst zusammensuchen zu muessen.
Ein paar Tasten sind ab Werk belegt, der Chat ist sinnvoll aufgeteilt und
einzelne Ansagen sind von Anfang an eingeschaltet - im Wesentlichen so, wie
erfahrene Spieler es sich sowieso einstellen. Jede dieser Vorgaben steht
weiterhin an ihrem gewohnten Platz im Menue und laesst sich wie immer aendern.
An bestehenden Profilen und Charakteren aendert sich dabei nichts: eine Vorgabe
greift nur dort, wo noch nie etwas gespeichert wurde. Die neuen Tasten holt man
sich unter Sku Tastenbelegung -> Alles zuruecksetzen; das setzt allerdings
wirklich ALLE Tasten zurueck, auch die selbst belegten.
Technisch: Reine Vorgabenaenderungen in SkuZOptions/SkuKeyBinds.lua
(skuDefaultKeyBindings), SkuChat/Core.lua und Options.lua (ChatFrameDefaultTabs
plus die Standard-Registerkarten), SkuCore/Options.lua (SkuCore.defaults) und
SkuCore/aqCombat.lua (aqCombatOnLogin). Bestehende Werte bleiben unberuehrt,
weil jede Stelle nur bei nil schreibt bzw. AceDB Vorgaben nur in Luecken fuellt.
Zwei echte Verhaltensaenderungen haengen daran: der Binder in
SkuNav:CreateSkuNavMain hat immer nur .key gesetzt, eine vom Benutzer
vergebene ZWEITE Taste blieb fuer alle Navigationsaktionen also wirkungslos
(SkuKeyBindsMatchKey kannte sie laengst) - er laeuft jetzt ueber
SkuKeyBindsGetKeys und belegt beide. Und weil SkuChat eine Nachricht je
Registerkarte ausgibt, die den Typ aktiviert hat, muss ein Nachrichtentyp mit
eigener Registerkarte in allen anderen stumm sein, sonst wird er doppelt
vorgelesen.
Auktionshaus: Mehrfachkauf desselben Gegenstands geht wieder
Einfach: Wer mehrere Auktionen desselben Gegenstands kaufte, bekam den ersten
Stapel und danach "Interner Auktionsfehler"; der zweite Kauf wurde nie mehr
angeboten. Beides ist behoben - die Folgekaeufe laufen durch, und die
grundlose Fehlermeldung des Servers wird waehrend einer Suche nicht mehr
vorgelesen.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v42.10
Navigation: Wegpunkte in Gebieten ohne eigene Karte funktionieren wieder
Einfach: In der Tiefenbahn meldeten Shift+F9 und Shift+F10 keine Wegpunkte, obwohl
das Gebiet vollstaendig kartiert und verknuepft ist. Dieselbe Ursachenfamilie
traf Orte am Rand von Instanzen - den Eingangsbereich von Uldaman, den Vorplatz
von Karazhan und aehnliche Stellen in Hoehlen und Tunneln: auch dort blieben
beide Listen einfach leer, ohne Fehlermeldung. Das ist behoben, Wegpunktliste
und Routenfuehrung arbeiten an diesen Orten wieder.
Zu beachten: an solchen Stellen kann die Liste auch Wegpunkte des Gebiets
enthalten, das ueber oder neben dir liegt. Wenn du in einer Hoehle unter einem
anderen Gebiet stehst, pruefe vor dem Auswaehlen kurz, ob der Wegpunkt wirklich
zu deiner Umgebung gehoert - sonst laeuft die Fuehrung gegen die Decke.
In den Instanzen selbst (Uldaman innen, Karazhan innen) gibt es weiterhin keine
Wegpunkte. Dort ist nichts kartiert, und das bleibt auch so.
Technisch: Zwei getrennte Ursachen, beide in SkuNav/Geo.lua. Erstens hat areaId 2257
(Die Tiefenbahn) keine ExternalMapID-Zeile, GetUiMapIdFromAreaId liefert dafuer
also nil, und die strenge Namens-plus-uiMap-Schleife in GetCurrentAreaId kann
solche Gebiete nie treffen. Bis v41 verglich diese Schleife gegen eine nie
deklarierte globale Variable und traf genau sie zufaellig; seit der Deklaration
lieferte GetCurrentAreaId dort nil, und mit nil als Kontinent brechen
ListWaypoints2 und GetAllLinkedWPsInRangeToCoords wortlos ab. Der Namensabgleich
wird jetzt bewusst als zweiter Durchgang wiederholt, beschraenkt auf Gebiete
ohne uiMap - genau die Menge, die die strenge Schleife ohnehin nie treffen
konnte, weshalb kein normales Gebiet anders ausgewertet werden kann.
Zweitens gibt der Client in Hoehlen, Tunneln und vor Instanztueren oft die
Kontinent-uiMap (1415/1414) zurueck. Die Rettung dafuer in GetBestMapForUnit
glich den Namen der UNTERzone gegen InternalAreaTable ab - dort sind aber alle
285 Instanzzeilen auskommentiert, ein Unterzonenname wie "Uldaman" trifft also
nichts, die Kontinent-ID ueberlebt, GetAreaIdFromUiMapId macht daraus AreaId -1,
und GetCurrentAreaId bleibt ohne Ausweg (eine Zeile namens "Oestliche
Koenigreiche" gibt es nicht). Es gibt jetzt einen Rueckfall auf GetRealZoneText,
den Zonennamen, der immer eine Zeile hat; er greift nur, wenn die bisherigen
Wege nichts Brauchbares geliefert haben.
Ausserdem meldet /skuzoneprobe (/szp) jetzt beide Gebiets-Aufloeser
nebeneinander, die Cache-Aufteilung nach Wegpunkttyp, die Groesse des
Kontinent-Eimers und was die beiden Schnelllisten an Ort und Stelle
zurueckgeben. Ein Fehler darin ist mitbehoben: die Sonde las WaypointCache als
globale Tabelle, obwohl sie eine Dateilokale von SkuNav/Core.lua ist - die Zahl
"im Cache ueberlebt" war deshalb immer 0 und meldete faelschlich, alles sei
weggeraeumt worden.
Kampf: Die Zaehlung der Gegner im Kampf ist deutlich ruhiger und genauer
Einfach: Die Ansage der Gegnerzahl sprang staendig hoch und runter, obwohl sich an
der Lage nichts geaendert hatte - in einem Bosskampf mit drei Gegnern kamen so
in gut einer Minute vierzehn Ansagen zusammen, von denen die meisten falsch
waren. Vier Ursachen sind behoben:
Erstens wurde ein Gegner, der sechs Sekunden lang nichts tat - waehrend einer
Furcht, in einer Zauberphase, wenn ihn gerade niemand angriff -, aus der
Zaehlung geworfen und beim naechsten Schlag wieder aufgenommen. Sku erkennt
jetzt an viel mehr Anzeichen, dass ein Gegner noch mitkaempft. Gegner, die
wirklich zurueckkehren oder verschwinden, verschwinden weiterhin aus der Zahl.
Zweitens hoertest du nach einem Kill richtig "0", kurz darauf faelschlich "1"
und dann wieder "0". Tote Gegner koennen nicht mehr zurueckkommen.
Drittens fiel die Zahl mitten im Kampf auf 0 und kletterte danach wieder hoch,
wenn du selbst kurz aus dem Kampf warst - etwa weil du gefuerchtet weggelaufen
bist oder dein letzter Angreifer starb. In den Gruppen-Modi ("Gegner, die die
Gruppe oder dich angreifen") zaehlt jetzt, ob noch jemand in der Gruppe kaempft.
Viertens wurden freundliche NPCs mitgezaehlt, sobald ein Gruppenmitglied sie
geheilt oder gestaerkt hat - etwa Begleit-NPCs in Instanzen. Sie zaehlen nicht
mehr mit.
Technisch: Alles in SkuCore/aqCombat.lua. (1) lastUpdate wird jetzt von jeder
Kampflog-Zeile aufgefrischt, die einen erfassten Gegner als Quelle ODER Ziel
nennt, und zusaetzlich von blosser Sichtbarkeit in einem abgefragten Unit-Slot -
letzteres nur, solange UnitAffectingCombat fuer den Slot wahr ist. Genau diese
Bedingung erhaelt den Zweck der 6-Sekunden-Bereinigung: ein zurueckkehrender
Gegner bleibt zwar sichtbar, verliert aber die Kampfmarkierung, wird also nicht
aufgefrischt und faellt weiterhin heraus. (2) Ein Todesfall wird in tDeadGuids
vermerkt, der Eintrag aus dem Sammelfenster tPendingAdds entfernt, und
aqCombat_CREATURE_ADDED_TO_COMBAT weist tote GUIDs ab - vorher machte
"false or {}" aus der Totenmarkierung wieder einen lebenden Eintrag. Aufgehoben
wird die Markierung nur, wenn ein Unit-Token den Gegner wieder als lebend meldet.
(3) PLAYER_REGEN_ENABLED (= "DU hast den Kampf verlassen") leerte die ganze
threatTable; in den Modi 2 und 3 wird das jetzt aufgeschoben, solange ein
Gruppenmitglied noch UnitAffectingCombat ist, mit einer 2-Sekunden-Nachfrage.
Modus 4 ("greifen dich an") raeumt weiterhin sofort auf. (4) Die Feindlichkeit
wird aus den Reaktions-Flags der Kampflog-Zeile (COMBATLOG_OBJECT_REACTION_*)
und aus UnitReaction <= 4 bestimmt, einmal pro Gegner und danach nie neu -
bewusst NICHT ueber UnitCanAttack, denn Bosse werden mitten im Kampf
unangreifbar oder immun gesetzt und wuerden genau dann aus der Zahl fallen.
Auktionshaus: Auktionen lassen sich wieder einstellen, ohne vorher die Taschen zu oeffnen
Einfach: Beim Einstellen einer Auktion passierte manchmal schlicht nichts - der
Verkaufsslot blieb leer und die Auktion ging still nicht raus. Wer vorher am
Briefkasten, beim Haendler oder an der Bank war, bei dem ging es, denn diese
Fenster oeffnen alle Taschen automatisch. Deshalb wirkte der Fehler zufaellig
und traf nur manche Sitzungen. Das Einstellen braucht die Taschen jetzt nie
mehr geoeffnet.
Nebenbei wird das Item im Moment des Einstellens frisch in den Taschen gesucht:
hat sich der Stapel seit dem Aufbau des Menues verschoben, wird trotzdem das
richtige Item eingestellt. Gerade gesperrte und seelengebundene Kopien derselben
Item-ID werden uebersprungen, statt das Einstellen still scheitern zu lassen.
Technisch: SkuCore/auctionHouse.lua. Der Verkaufspfad zog das Item ueber das Skript
des Taschen-FENSTERS in den Slot:
_G["ContainerFrame(bag+1)Item(numSlots-slot+1)"]:GetScript("OnDragStart").
Diese Buttons entstehen erst, wenn eine Tasche wirklich einmal dargestellt
wurde, und die Zuordnung ContainerFrame[N] <-> Taschen-ID wird beim OEFFNEN
vergeben - die feste Annahme N = bag + 1 stimmt nur, wenn alle Taschen der
Reihe nach geoeffnet wurden. Ohne das griff der Zug ins Leere und PostAuction
lief ohne Wirkung durch. Das war ein Rueckfall in den Stand vor dem 25.06.2026:
die v42-Ueberarbeitung des Verkaufens hat den "originalen v41.06-Pfad"
wiederhergestellt und den Fensterzug damit zurueckgeholt.
Gelesen und aufgenommen wird jetzt ueber die Container-API - denselben Weg, den
Taschensortierung und Sockeln schon nehmen: neue Helfer _ASBagNumSlots,
_ASBagSlotInfo, _ASFindBagSlot und _ASPickupBagItem, jeweils zweigleisig ueber
C_Container und die klassischen Globalen. Tasche und Platz werden beim Klick neu
ueber die Item-ID aufgeloest (der beim Menueaufbau gemerkte Platz ist nur noch
ein Hinweis und wird nachgeprueft), dann PickupContainerItem gefolgt von
ClickAuctionSellItemButton; im Abbruchzweig raeumt ClearCursor auf, damit ein
fehlgeschlagenes Aufnehmen das Item nicht am Cursor liegen laesst. Auch die
Verfeinerung ueber _G[containerFrameName].info.id in der Preisvorgabe entfaellt:
sie lieferte ohne dargestellte Taschen nichts, und die Item-ID aus dem
Container-Durchlauf ist ohnehin die verlaessliche Quelle.
Auktionshaus: Der niedrigste Preis wird nicht mehr faelschlich als 0 Kupfer gemeldet
Einfach: Bei manchen Items nannte Sku als niedrigsten Sofortkaufpreis "0 Kupfer",
obwohl mehrere Auktionen mit ganz gewoehnlichen Preisen im Haus lagen - eine
Suche von Hand nach demselben Item fand die richtigen Preise sofort. Aus
derselben Ursache war der angesagte Durchschnitt zu niedrig, die Zahl der
Datenpunkte zu hoch, und der beim Verkaufen vorgeschlagene Preis konnte auf 0
stehen. Bei anderen Items hiess es umgekehrt "Keine Sofortkaufdaten vorhanden",
obwohl es Sofortkaeufe gab. Beides ist behoben. Die aktuellen Preisdaten sind
nach dem naechsten vollstaendigen Scan wieder richtig; gespeicherte historische
Daten heilen pro Item, sobald es erneut gescannt wurde, und bis dahin werden
alte Null-Preise als "keine Daten" behandelt statt vorgelesen.
Technisch: SkuCore/auctionHouse.lua. Zwei Fehler, die zusammenwirkten. Erstens
steuerte in AuctionBuildPriceData jede Auktionszeile immer ZWEI Datenpunkte bei,
einen Gebots- und einen Sofortkaufpreis. Auktionen ohne Sofortkauf
(buyoutPrice == 0, im TBC-Auktionshaus der Normalfall) wurden dabei als glatte 0
in die Sofortkaufliste geschrieben. Zweitens band die Bedingung in
AuctionUpdateAuctionDBHistory - "not tLow or (tPrice > 0 and tPrice < tLow)" -
den Schutz tPrice > 0 nur an den ZWEITEN Zweig. Der zuerst gesehene Preis
besetzte das Minimum also unabhaengig von seinem Wert, auch mit 0; danach war
kein Preis mehr kleiner als 0, das Minimum blieb also 0. Deshalb schlug es nur
manchmal zu - naemlich wenn die erste Auktion dieses Items im Scan keinen
Sofortkauf hatte. Die Nullen zogen ausserdem den Median nach unten, und lag mehr
als die Haelfte der Auktionen ohne Sofortkauf, wurde der Median 0, worauf der
Ausreisserfilter tPrice < Median * 10 samt aller echten Preise alles verwarf -
das war der Fall "keine Daten trotz vorhandener Sofortkaeufe".
Jetzt werden nur echte Preise > 0 ueberhaupt zu Datenpunkten (eine Auktion ohne
Sofortkauf liefert schlicht keinen Sofortkauf-Datenpunkt), tPrice > 0 gilt fuer
beide Zweige, und ein Median <= 0 umgeht den Ausreisserfilter, statt alles
wegzufiltern. Beim Auslesen in AuctionHouseGetAuctionPriceHistoryData gilt ein
gespeichertes Minimum <= 0 als "keine Daten" - noetig, weil in bereits
gespeicherter AuctionDBHistory noch Null-Minima aus der alten Rechnung stehen
koennen, bis das Item wieder gescannt wird.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v42.09
Classic Era: Spiel-Tastenbelegungen lassen sich wieder setzen
Einfach: Auf dem Classic-Era-Client liess sich eine Spiel-Tastenbelegung zwar
loeschen, aber nie eine neue vergeben - das Menue meldete die Taste danach
einfach als "nichts". Das Belegen funktioniert jetzt genauso wie auf dem
Anniversary-Client, fuer die erste wie fuer die zweite Taste eines Befehls.
Technisch: Die Binding-Hilfsfunktionen in SkuCore riefen im Nicht-TBC-Zweig
SetBinding(key, command, 1) auf. Das dritte Argument bindingMode wird von Era
1.15 abgelehnt, der Aufruf lieferte false und belegte nichts, waehrend die
einargumentige Loesch-Form weiter funktionierte - daher "Loeschen geht,
Belegen nicht". Sku.isTBC ist fuer jeden Client ab Interface 20505 wahr, dieser
Zweig wurde also ausschliesslich auf Era erreicht. Alle fuenf Aufrufstellen
(SetBinding, SetBinding2, DeleteBinding2 und beide Tasten in ResetBindings)
nutzen jetzt die zweiargumentige Form, die auf beiden Clients korrekt ist.
Classic Era: Beitritt zum Sku-Chat-Kanal schlaegt nicht mehr fehl
Einfach: "Sku Chat Channel beitreten" funktionierte auf Classic Era nicht richtig -
der Kanal wurde dem Chatfenster nie hinzugefuegt. Der Beitritt klappt jetzt.
Technisch: SkuChat:JoinOrLeaveSkuChatChannel verzweigte ueber Sku.isTBC und rief ein
globales ChatFrame_AddChannel auf, das es im Anniversary-Interface-Code gar
nicht gibt. Die echte API ist ChatFrameMixin:AddChannel, die auf jeder Variante
inklusive Era geladen wird - der Zweig entfaellt.
"Sku Chat Channel beitreten" ist wieder auffindbar
Einfach: Die Einstellung war nach Einstellungen -> Sprachausgabe verschoben worden,
direkt neben die Sprachausgabe-Optionen. Weil ein zweites Menue gleichen Namens
(unter Audio) nur die drei TTS-Regler zeigt, wirkte die Einstellung, als gaebe
es sie gar nicht. Sie steht wieder dort, wo sie hingehoert: unter Sku Chat ->
Optionen.
Technisch: Gerendert mit keyPrefix "" - demselben Praefix, den das
Sprachausgabe-Menue verwendet hat - damit gespeicherte Werte unveraendert
uebernommen werden. Die uebrigen verschobenen SkuChat-Optionen (TTS-Stimme,
-Tempo und -Lautstaerke, Audiowarteschlangen niemals zuruecksetzen, alle
Sprachausgabe ueber Blizzard-TTS, Emojis nicht vorlesen) bleiben unter
Sprachausgabe.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v42.08
Mit Dank an Naxedim
Fast jede Verbesserung dieser Version wurde von den Begleit-Addons angeregt, die
Naxedim unter https://naxedim.github.io/sku-addons/ entwickelt und geteilt hat -
SkuMoneyReplacement, SkuMailboxReplacement, SkuAuctionHouseReplacement und
SkuMinimapScannerFR. Sie wurden hier nativ in Sku uebernommen, mit Skus eigenem
Menuesystem. Die Ideen und die funktionierenden Loesungen stammen von Naxedim.
Post: Anhaenge, Versand und grosse Betraege
Einfach: Einen Gegenstand an einen Brief anzuhaengen klappt jetzt zuverlaessig - der
Gegenstand landet wirklich am Brief und bleibt nie am Cursor haengen. Ein neuer
Punkt "Angehaengte Gegenstaende" zeigt, was angehaengt ist; mit ENTER schickst du
einen Gegenstand in die Taschen zurueck. Kann ein Brief nicht gesendet werden
(z. B. unbekannter Empfaenger), hoerst du jetzt "Senden fehlgeschlagen" mit Grund,
und Empfaenger, Betreff und Text bleiben erhalten, damit du nur den Namen
korrigieren und erneut senden musst. Du kannst jetzt auch mehr als 999 Gold
anhaengen: jede Muenzliste hat oben einen neuen Punkt "Betrag eingeben".
Technisch: Der Anhang-Pfad sucht einen freien Sende-Slot und verifiziert mit
GetSendMailItem (ClearCursor bei Fehlschlag); der alte OnDropAny-Pfad ist auf
Anniversary wirkungslos. MAIL_FAILED wird nun behandelt (Ansage + Entwurf bleibt),
der Entwurf wird erst bei MAIL_SEND_SUCCESS geleert. Muenzlisten erhielten einen
Editbox-Eintrag; die Anhang-Liste nutzt GetSendMailItem und ClickSendMailItemButton.
Textfelder: jedes Zeichen wird beim Tippen und Bearbeiten vorgelesen
Einfach: Wenn du in ein Sku-Textfeld tippst (Post, Auktionssuche, Betraege,
Ausruestungsset-Namen usw.), hoerst du jetzt jedes getippte und jedes geloeschte
Zeichen. Die Pfeiltasten lesen das Zeichen am Cursor (Strg + Pfeil das ganze Wort),
Hoch/Runter den ganzen Text, und Escape sagt "Abgebrochen".
Technisch: SkuOptions:EditBoxShow liest jetzt ueber OnChar/OnKeyDown (UTF-8-sicher).
Getippte Zeichen werden in die Queue gehaengt, damit schnelles Tippen auf langsamen
Stimmen jedes Zeichen spricht; Cursor-Lesen ueberschreibt. Schlichte Pfeile sind
frei (Menue-Navigation liegt auf Umschalt-Pfeilen).
Auktionshaus: Addon-Tooltip-Infos, keine haengenden Tasten, Item-Namen in jeder Sprache
Einfach: Item-Tooltips im Auktionshaus zeigen jetzt auch Infos, die andere Addons
hinzufuegen (z. B. Pawn-Wertungen), als zusaetzliche Sektion "Addon-Infos" am Ende
- ohne Skus eigenen Tooltip zu veraendern. Das Schliessen des Auktionshauses laesst
Enter und Escape nicht mehr haengen (Escape oeffnet wieder das Spielmenue). Im
Strategiekauf kannst du den Item-Namen jetzt in deiner eigenen Sprache tippen.
Technisch: AuctionBuildItemTooltip bespielt einmal unsichtbar den echten GameTooltip,
liest die Zeilen fremder OnTooltipSetItem-Hooks und haengt die Nicht-Basiszeilen
als Sektion an (der SkuScanningTooltip wird nicht umgehaengt). Beim Menue-Schliessen
werden die Override-Bindings des Kauf-Binders und beider Menue-Buttons mehrfach
geleert (nur bei geschlossenem Menue / ausser Kampf). Der Strategiekauf erhielt eine
Freitext-Eingabe (Sku liefert nur deutsche/englische Namenstabellen). Komplettscan
250 -> 400 Zeilen pro Frame.
Gildenbank: Gold lesen und bewegen
Einfach: Das Gildenbank-Menue hat einen neuen Punkt "Gildenbank-Geld": lies, wie viel
Gold in der Bank ist, wie viel du heute noch abheben kannst und wie viel du bei dir
traegst, und zahle Gold ein oder hebe es ab, indem du einen Betrag eingibst. Ein-
und Auszahlungen werden vorher geprueft (genug Gold, Tageslimit) und per Stimme
bestaetigt.
Technisch: Das Geld-TODO in Build_GuildBankFrame ist mit rohen Gossip-Eintraegen
gefuellt; Ein-/Auszahlung nutzt die GetGuildBankWithdrawMoney-Limitpruefung und
sagt die Vorher/Nachher-Differenz an.
Handel: das Handelsfenster-Geld wird vorgelesen
Einfach: Beim Handeln sagt Sku jetzt an, wenn der andere Spieler Gold in den Handel
legt, es aendert oder zurueckzieht, und liest dein eigenes Angebot vor, waehrend du
es einstellst. (Gold aus einem Addon in einen Handel zu LEGEN ist von Blizzard
gesperrt, daher nur die Lese-Seite.)
Technisch: TRADE_MONEY_CHANGED wird ueber den Dispatcher behandelt; eigenes und
Partner-Geld werden gegen die letzten Werte verglichen und mit Partnernamen angesagt.
Ressourcen-Scanner: native franzoesische Knotennamen
Einfach: Der Minimap- und Boden-Ressourcenscanner kennt jetzt die franzoesischen Namen
von Erzadern, Kraeutern, Gaswolken und Truhen und funktioniert damit nativ auf
einem franzoesischen Spielclient.
Technisch: frFR-Ressourcennamen wurden zu SkuCore.RessourceTypes ergaenzt und frFR zu
Sku.LocsPartly, damit Sku.LocP auf einem frFR-Client frFR bleibt, mit enUS-Fallback.
Navigation: ein Flugmeister-Flug bricht eine aktive Route ab
Einfach: Wenn du bei einem Flugmeister einen Flug nimmst, waehrend gerade eine Route
verfolgt wird, wird die Route jetzt automatisch abgebrochen - sie beizubehalten
ergibt keinen Sinn, waehrend der Taxiflug dich woandershin bringt. Selbst auf
einem Reittier zu fliegen oder ein Flugfahrzeug zu steuern bricht die Route nicht ab.
Technisch: Der Taxi-Start-Zweig (PLAYER_CONTROL_LOST gefolgt von
PLAYER_MOUNT_DISPLAY_CHANGED) ruft jetzt SkuNav:CancelNavigationSilent auf, abgesichert
mit UnitOnTaxi("player"), damit es nur bei Flugmeister-Fluegen ausloest - Selbstfliegen
loest nie PLAYER_CONTROL_LOST aus, und in einem Flugfahrzeug bleibt UnitOnTaxi false.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v42.07
AddOn-Einstellungen: Einstellungen anderer Addons lesen und aendern
Einfach: Ein neuer Punkt "AddOn-Einstellungen" im Addons-Menue (und ueber den
Knopf "AddOns" im Escape-Spielmenue) macht die Einstellungen anderer
Addons mit dem Screenreader lesbar und aenderbar - Questie, Deadly Boss
Mods, AtlasLoot, Extended Character Stats und weitere. Ihre Optionen
erscheinen als normale Sku-Menues: Ein/Aus-Schalter, Auswahllisten,
Schieberegler und Textfelder. Laesst sich im Features-Menue abschalten.
Technisch: SkuCore/addonOptions.lua liest die AceConfig-Optionstabelle eines
beliebigen Addons ueber die prozessweite AceConfigRegistry
(IterateOptionsTables / GetOptionsTable) mit AceConfig-Vererbungssemantik
und stellt sie mit denselben Menueformen wie gameOptions.lua dar.
Kuratierte oberste Liste; Konfig-Addons, die nur bei Bedarf laden, werden
beim Oeffnen geladen. Fuer Deadly Boss Mods eigene Adapter: Optionen je
Boss-Mod aus DBM.Mods sowie die Kernoptionen ueber einen
DBM-GUI-Widget-Durchlauf.
Entfernungspruefung: Baender bleiben erhalten und sind schnell verfuegbar
Einfach: Bei den Entfernungsansagen (den "Entfernung"-Pruefungen) gab es einen
Fehler, durch den eingestellte Entfernungsbaender sich selbst abschalten
konnten und die Liste leer erscheinen konnte. Behoben: eingestellte
Baender bleiben erhalten, die Liste fuellt sich zuverlaessig, und neu
verfuegbare Baender werden angesagt. Nach einem frischen Login sind die
Baender ausserdem deutlich schneller bereit, und das 100-Yard-Band
funktioniert auf TBC wieder. Hinweis: Sie hoeren jetzt deutlich mehr
Entfernungsansagen als gewohnt, weil jedes verfuegbar werdende Band
angesagt wird - unerwuenschte koennen Sie unter Monitor -> Entfernung
abschalten.
Technisch: RangeCheck entfernt gespeicherte Baender nicht mehr anhand
voruebergehender LibRangeCheck-Verfuegbarkeit; das Menue fuellt sich
synchron beim Aktivieren mit zeitlich gestaffelten stillen Wiederholungen
und aktualisiert aus der laufenden Bibliothek. LibRangeCheck-3.0 wurde von
v31 auf v35 aktualisiert (Zauber-Baender aktualisieren sich beim Leveln
via LEARNED_SPELL_IN_TAB). Ein paralleles Vorwaermen der Item-Daten beim
Aktivieren fuellt Item-Baender im Schwung statt seriell. Fuenf permanente
DM-Elixiere wurden in die TBC-100er-Tabellen ergaenzt, damit sich das
100-Band bildet. Ein Kampf-Schutz ueberspringt nicht angreifbare Ziele,
deren Interaktionsdistanz-Pruefer im Kampf falsche Werte liefern.
Fokus: Aenderungen des Spiel-Fokus werden vorgelesen
Einfach: Das Festlegen oder Entfernen des Spiel-Fokus wird jetzt per Stimme
angesagt ("Fokus festgelegt auf " / "Fokus entfernt"). Die acht
Sku-Fokus-Tastenbelegungen und ihre Menuegruppe heissen jetzt "Sku Fokus",
damit sie klar vom Spiel-eigenen Fokus zu unterscheiden sind. Das
Festlegen eines Sku-Fokus sagt die Bestaetigung nicht mehr doppelt.
Technisch: PLAYER_FOCUS_CHANGED laeuft ueber die Blizzard-TTS (Engine 2,
globale Stimme des Nutzers) und ist mit dem SkuFocus-Modulschalter
registriert. Die "Set"-Taste reagiert nur noch auf AnyDown (vorher
AnyUp+AnyDown, wodurch sie auf beiden Tastenflanken ausloeste).
Menue: ueberfluessiger Ton beim Oeffnen/Schliessen entfernt
Einfach: Beim Oeffnen oder Schliessen des Menues wurde manchmal ein
zusaetzlicher "Aus"-Ton aus einer internen Aufraeumung abgespielt. Jetzt
ertoent nur noch das Menue-Wisch-Geraeusch; alle anderen Aktionen behalten
ihren gewohnten Ton.
Technisch: SkuTTS:Hide bekam einen Still-Schalter, den der Menue-Auf/Zu-
Umschalter nutzt, um den sound-off2-Ping aus dem defensiven Ausblenden
eines uebrig gebliebenen Lese-Frames zu unterdruecken.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v42.06
Verzauberkunst: Absturz beim Oeffnen des Fensters behoben
Einfach: Das Verzauberkunst-Fenster konnte beim Oeffnen einen Fehler
ausloesen. Das ist behoben.
Technisch: Die in 42.05 ergaenzten Craft-Menuepunkte (Filter und Tooltip)
sind jetzt vollstaendig pcall-geschuetzt, sodass unerwartetes
API-Verhalten auf diesem Backport das Menue nicht mehr crasht.
Auktionshaus: klarere Ansage beim Scan-Start
Einfach: Beim Starten des Auktionshaus-Scans wird jetzt "Auktion gestartet,
bitte warten" gesagt.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v42.05
Berufe: Rezept-Tooltip mit Shift+Pfeil-runter (alle Berufe)
Einfach: Steht der Fokus in der Rezeptliste auf einem Rezept, liest
Shift+Pfeil-runter jetzt einen Tooltip vor: Name des Ergebnisses, die
Materialien je Zeile als "vorhanden Schraegstrich benoetigt", und den
Tooltip des fertigen Gegenstands. Er zeigt das FOKUSSIERTE Rezept, auch
wenn gerade ein anderes ausgewaehlt ist. Gilt fuer alle normalen Berufe
und fuer Verzauberkunst. Der bisherige Tooltip auf dem ausgewaehlten
Rezept bleibt erhalten.
Technisch: Jede Rezeptzeile traegt ihren echten Index (Knopf-GetID). Der
Tooltip wird ueber diesen Index aus GetTradeSkillReagentInfo bzw.
GetCraftReagentInfo (vorhanden/benoetigt) und dem Ergebnis-Item-Link
gebaut, ohne die Auswahl zu veraendern.
Berufe: Filter "Ressourcen vorhanden" (alle Berufe)
Einfach: Ganz oben im Berufefenster ein Umschalter. Enter schaltet Ein/Aus
und sagt den neuen Zustand. Bei Ein bleiben nur herstellbare Rezepte in
der Liste. Standard Aus, gemerkt pro Beruf und Charakter. Die
Tierausbildung bekommt keinen Filter (dort gibt es keine Materialien).
Technisch: Normale Berufe ueber Blizzards TradeSkillOnlyShowMakeable;
Verzauberkunst filtert selbst ueber GetCraftInfo.numAvailable.
Auren-Sets: accountweit verfuegbar
Einfach: Angelegte und empfangene Auren-Sets stehen jetzt auf allen
Charakteren des Accounts zur Verfuegung, nicht mehr nur auf einem.
Technisch: Speicher von char- auf global-Scope umgestellt; der Login-Reset
der globalen SkuAuras-Tabelle leert jetzt nur noch das Debug-Log und
erhaelt die Sets und empfangenen Sets.
Auren-Sets: Umbenennen und Aktivieren
Einfach: Im Untermenue eines Sets gibt es jetzt zusaetzlich Umbenennen und
Aktivieren. Aktivieren ersetzt die aktuellen Auren durch die des Sets und
fragt vorher nach (Enter bestaetigt, Escape bricht ab).
Auren-Menue aufgeraeumt
Einfach: Der tote Punkt "Auren Sets importieren" ist entfernt. Die alte
Set-Verwaltung mit den drei Test-Sets ist raus. Der Teilen-Punkt heisst
jetzt "Set Verwaltung".
Auren: Absturz beim Anlegen einer neuen Aura behoben
Einfach: Beim Anlegen einer neuen Aura (neue Aura, wenn, dann, nach rechts auf
Aktion) kam ein Fehler. Er ist behoben.
Duale Talentspezialisierung: Umskillen ohne Reload
Einfach: Nach dem Wechsel der aktiven Spezialisierung wird der Talentbaum
sofort korrekt angezeigt; ein /reload ist nicht mehr noetig.
Technisch: Beim ACTIVE_TALENT_GROUP_CHANGED wird der Blizzard-Talentrahmen auf
die neue aktive Gruppe gezogen und neu gezeichnet, bevor Sku sein Menue baut.
Talent: richtige Namen der Registerkarten in der inaktiven Spezialisierung
Einfach: In der nicht aktiven Spezialisierung hiessen die Talentbaeume bei
manchen Klassen "Registerkarte 201", "281" und aehnlich statt richtig.
Jetzt stehen die echten Baumnamen.
Technisch: Name vom Blizzard-Reiterknopf PlayerTalentFrameTab statt vom
gruppen-parametrisierten API-Wert, mit Zahl-Fallback.
Trainer: Preis im Bestaetigungsdialog
Einfach: Beim Zuruecksetzen der Talentpunkte, beim Kauf der dualen
Talentspezialisierung und bei anderen Gold-Bestaetigungen steht jetzt oben
ein Eintrag "Kosten" mit dem Goldbetrag.
Technisch: Der StaticPopup-Leser nimmt jetzt StaticPopup1MoneyFrame.staticMoney
als ersten Kind-Eintrag mit auf (ueber SkuGetCoinText).
Questie: Chatmitteilungen fernbedienen
Einfach: Unter Addons gibt es jetzt Questie (wenn Questie geladen ist). Dort
laesst sich der Kanal der Chatmitteilungen einstellen (Aus / Gruppe /
Schlachtzug / Beides) und einzeln an- und ausschalten: Quest angenommen,
abgebrochen, Fortschritt, abgeschlossen, Quest-Gegenstand.
Technisch: Setzt Questie.db.profile.questAnnounce* direkt; Questie persistiert selbst.
Begleiter: nicht verwendete Trainingspunkte werden angezeigt
Einfach: Auf der Uebersichtsseite stand bei den Trainingspunkten des Begleiters
immer 0. Jetzt steht dort die echte Zahl.
Technisch: GetPetTrainingPoints statt UnitCharacterPoints("pet") (TBC hat keine
Pet-Talentpunkte).
Freundesliste: "Entfernen" ganz nach unten
Einfach: Im Untermenue eines Freundes steht "Entfernen" jetzt als letzter
Eintrag statt weit oben.
Monitor: "Tier Hunger ansagen" richtig einsortiert
Einfach: Der Punkt lag eine Ebene zu tief. Er liegt jetzt unter Monitor,
Gesundheit und Status, Tier, als Geschwister von Gesundheit.
Post: Schluesselbund-Gegenstaende anhaengbar
Einfach: Beim Brief verfassen zeigt "Gegenstand hinzufuegen" jetzt auch
Gegenstaende aus dem Schluesselbund (z.B. einen nicht seelengebundenen
Silberdietrich) und laesst sie versenden. Seelengebundene Schluessel
bleiben ausgeblendet. Die Schluesselbund-Eintraege stehen am Ende der
Liste, die Tascheninhalte davor.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v42.04
Taschen: Verzauberungen und Ruestungssets per Linksklick anwenden geht wieder
Einfach: Wartete eine Verzauberung oder ein Ruestungsset auf ein
Ziel-Item, passierte beim Druck auf Enter (Linksklick) auf dem
Ziel-Item in den Taschen nichts - nur Strg+Enter (Rechtsklick)
wendete an. Enter wendet jetzt an, wie in der Standard-UI. Auf
angelegten Gegenstaenden funktionierten beide Tasten bereits.
Technisch: Die Enter-Aktion eines Taschen-Items war ein blankes insecure
PickupContainerItem; der native Linksklick laeuft bei
SpellCanTargetItem() ueber das Hardware-Event-gegatete
UseContainerItem. Taschen-Items und Ausruestungs-Slots tragen jetzt
ein applyMacrotext ("/use Tasche Slot" bzw. "/use Slot"), das das
Menue beim Fokussieren waehrend SpellIsTargeting() auf den sicheren
Linksklick-Button staged; ein Targeting-only-PreClick-Schnappschuss
laesst den insecure Fallback sein Aufheben ueberspringen, wenn das
Makro schon angewendet hat, ohne das Ablegen/Tauschen eines
gehaltenen Cursor-Items zu brechen. Die /use-Form ist zudem
Modifier-unabhaengig - ein synthetisierter "/click ... LeftButton"
liest den Live-Tastaturzustand, eine umbelegte Linksklick-Taste mit
Modifier wuerde also als modifizierter Klick zaehlen
(Anprobe/Chat-Link) und nie anwenden.
Startgebiete: Strg+Shift+Tab wechselt wieder durch geschuetzte NPCs
Einfach: Seit dem WoW-Client-Update vom 9. Juli wechselte die Spezialtaste
Strg+Shift+Tab nicht mehr durch die geschuetzten (sonst nicht anvisierbaren)
NPCs in den Startgebieten - der Druck hob nur noch das Ziel auf. Sie
funktioniert wieder.
Technisch: Client-Build 2.5.6.68575 hat die CVar nameplateShowFriends entfernt
(aufgeteilt in nameplateShowFriendlyPlayers + nameplateShowFriendlyNpcs).
GetCVar auf den entfallenen Namen liefert nil ohne Fehler, Skus
Zwangs-Einschalten lief also stumm ins Leere, freundliche Plaketten
erschienen nie und das Namens-Repo hinter SkuCoreSecureTabButton blieb
leer. Ein neuer gecachter Resolver SkuCore.FriendlyNameplateCVars()
waehlt den CVar-Satz je Client (der Era-Client behaelt den alten
Sammelnamen) und wird vom Zwangs-Einschalten des Wechslers, der
Login-CVar-Basis und dem Kamera-Menue genutzt (der Umschalter fuer
freundliche Plaketten setzt jetzt eine CVar-Liste).
Navigations-Menue: verflacht, Shift+F9/F10-Schnelllisten ueberarbeitet
Einfach: Die Eintraege liegen jetzt direkt unter Navigation (Einheiten Route
oben, dann Direkter Wegpunkt - umbenannt von "Auswaehlen" -, Besuchte
loeschen, Schnellwegpunkt setzen); die alten Huellen "Wegpunkt" / "Route
folgen" und die doppelten Eintraege "Alles abwaehlen" / "Abwaehlen" sind
weg (Shift+F12 bricht die Navigation bereits lautlos ab). Die
Navigations-Einstellungen sind aus dem Nav-Menue ausgezogen: allgemeine
Einstellungen nach Einstellungen -> Navigation, Beacon-Einstellungen nach
Monitor -> Beacon. Shift+F9 / Shift+F10 oeffnen die Listen der nahen
Wegpunkte / nahen Routenziele direkt, und LINKS aus so einer Schnellliste
wechselt in das vollstaendigere Menue, das sie abkuerzt.
Technisch: Die Schnelltasten nutzen einen eigenen Handler plus transienten
Root-Eintrag (wie der Shift+F11-Aktionsleisten-Handler) statt des
fragilen lokalisierten SlashFunc-Label-Laufs; gemeinsame Listen-Builder
auf SkuNav-Modulebene gehoben; die veralteten
MenuQuickSelect1-4-Pfad-Defaults sind stillgelegt und die funktionslose
"Schnellwahl"-Einstellungsgruppe ist versteckt. Gleiche args/db,
gespeicherte Werte bleiben erhalten.
AtlasLoot-Berufe: Classic- und TBC-Rezepte in einer Liste
Einfach: Im AtlasLoot-Berufemenue erschien jeder Beruf doppelt (z.B.
"Verzauberkunst" fuer Classic und noch einmal fuer TBC), und eine
Kategorie wie Armschienen-Verzauberungen zeigte nur die Rezepte einer
Aera. Jeder Beruf ist jetzt ein einzelner Eintrag, und jede Kategorie
listet die Rezepte beider Aeren, sortiert nach benoetigtem Skill.
Technisch: Der Berufe-Zweig fuehrt auf zwei Ebenen zusammen: Crafting-Module
werden nach lokalisiertem Berufsnamen gruppiert (Enchanting +
EnchantingBC -> ein Eintrag), dann werden gleichnamige Kategorien ueber
die Module hinweg vereinigt und das Blatt rendert die Rezepte beider
Module nach Skill sortiert. WotLK-Module sperren sich selbst auf den
WotLK-Client, die TBC-Phase ergibt also genau Classic + BC.
Briefkasten: getippte Feldinhalte werden zuverlaessig vorgelesen
Einfach: Nach dem Eintippen von Empfaenger, Betreff oder Text in ein
Brieffeld wurde die Bestaetigung (z.B. "Empfaenger: Spielername") mit der
Sku-Audio-Stimme gesprochen, die freien Text wie Spielernamen nicht
sprechen kann - die Zeile blieb stumm oder unvollstaendig. Die
Bestaetigung nutzt jetzt immer die Blizzard-TTS-Stimme.
Technisch: Die MailEditor-Bestaetigungen uebergeben engine 2 (Blizzard-TTS)
an OutputStringBTtts statt des Standard-Audiodatenbank-Pfads.
Klassenlehrer: Fokus bleibt auf "Ausbilden"
Einfach: Ein Druck auf "Ausbilden" beim Klassenlehrer sprang mit dem Fokus an
den oberen Rand des Fensters. Er bleibt jetzt auf dem Ausbilden-Knopf,
nachdem sich die Liste beruhigt hat - mehrere Faehigkeiten hintereinander
lernen ist damit je ein Tastendruck.
Technisch: Das Re-Pinnen nach dem Ausbilden suchte den Knopf in den KINDERN
des fokussierten Eintrags statt in dessen Geschwistern; der
Fenster-Neuaufbau verankert per Index, daher traf es nie. Es durchsucht
jetzt die Ebene, auf der der Cursor steht (parent.children, dann
children), und das zwischenzeitliche CheckFrames laeuft stumm, sodass nur
die Endposition angesagt wird.
Flugmeister: "Schliessen" wird nicht mehr gelistet
Einfach: Das Flugmeister-Fenster listete einen Eintrag "Schliessen". Sku
listet Schliessen-Knoepfe nirgends (Escape schliesst jedes Fenster),
daher ist er weg.
Technisch: Das "Schliessen"-Label haengte der Fallback fuer Knoepfe ohne
Schriftzug automatisch an den namenlosen TaxiCloseButton. "Schliessen"
steht jetzt in blockedWidgetStrings, generisch gespiegelte Fenster lassen
Schliessen-Knoepfe damit aus wie die handgebauten Fensterspiegel schon
immer.
Menues umsortiert
Einfach: "Sku Menue im Kampf" ist von Monitor -> Kampf in ein wieder
eingefuehrtes Untermenue Einstellungen -> Kampf gezogen. "Tier Hunger
ansagen" liegt jetzt unter Monitor -> Tier -> Gesundheit. Das Auren-Menue
hat seine doppelte Ebene verloren: einmal RECHTS vom Auren-Eintrag landet
direkt auf "Neue Aura" (der funktionslose Eintrag "Optionen" ist weg).
Technisch: Gleiche Einstellungen und Speicherung (combatMenuOpen,
classes.hunter.petHappyness) - nur die Menueposition hat sich geaendert.
SkuAuras:MenuBuilder baut die Liste direkt in den Modul-Root-Eintrag; die
SlashFunc-Ankerpfade haben das aurenList-Segment verloren.
Dokumentation: Hinweise zur Standard-Tastenbelegung korrigiert
Einfach: Die Hilfedateien "Standard-Tastenbelegung fuer blinde Spieler"
(Deutsch, Englisch, Franzoesisch) nannten mehrere veraltete
Standardtasten. Korrigiert: Kraeuter-/Erz-Scan ist Strg+Shift+F /
Strg+Shift+R, einen Beacon vor/zurueck ist Strg+Shift+W / Strg+Shift+S,
Schnellwegpunkte sind Shift+F5 bis Shift+F8, zum Beacon drehen ist I. Die
README verweist jetzt auf die aktuelle Download-Seite, die diese
Hilfedateien und die Patch Notes auch direkt verlinkt.
Technisch: Gegen skuDefaultKeyBindings in SkuZOptions/SkuKeyBinds.lua
geprueft; die Website-Kopien unter docs/ tragen dieselben Korrekturen.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v42.03
Bankfenster: Item-Namen und Rechtsklick wiederhergestellt
Einfach: Bankplaetze zeigten "Leer", obwohl ein Gegenstand drin lag, und ein
Rechtsklick auf einen Bankplatz tat nichts. Bankplaetze lesen jetzt wieder
ihren Item-Namen vor, und Rechtsklick (Strg+Enter) legt den Gegenstand in
die Taschen.
Technisch: Die Container-API-Umstellung las Namen ueber
GameTooltip:SetBagItem, das fuer den Bank-Hauptcontainer (id -1) auf 2.5.6
nichts liefert; ein Hyperlink-Fallback (SetHyperlink via
GetContainerItemLink) stellt den Namen wieder her. Der Bank-Rechtsklick
nutzt jetzt ein unsicheres UseContainerItem (Bank-Bewegungen sind nicht
hardware-gated) mit Event-basiertem Refresh auf BAG_UPDATE_DELAYED.
Taschen sortieren und aufraeumen: neu gebaut, keine Fehlerschleifen mehr
Einfach: Sortieren oder Aufraeumen konnte interne Taschenfehler ausloesen,
Gegenstaende verlegen oder sich endlos aufhaengen. Das Sortieren ist neu
geschrieben und zuverlaessig, braucht die Taschen nicht mehr offen, und
"alle Taschen sortieren" funktioniert.
Technisch: Der Klick-Simulations-Bubblesort (Coroutine auf 0.01s-Ticker) ist
durch eine C_Container-Engine ersetzt: PickupContainerItem-Tausch,
Selectionsort (garantiertes Ende), ein Tausch pro BAG_UPDATE_DELAYED mit
Watchdog und Schrittlimit je Tasche, alles pcall-geschuetzt und getract.
Behebt zusaetzlich einen Talentfenster-Absturz ("table index is nil").
Fehler-Feedback: pro Fehler waehlen, wie er gemeldet wird
Einfach: Jeder Fehlertyp (nicht in Reichweite, betaeubt, falsche Richtung,
unterbrochen, keine Sichtlinie, ...) hat jetzt ein eigenes Untermenue, in
dem du waehlst, wie er angesagt wird: eine TTS-Stimme, ein gesprochener
Sprachhinweis (Marlene oder Hans, deutsch oder englisch), ein kurzer Ton
oder Stille. Die alten gesprochenen Hinweis-Clips sind wieder waehlbar.
Technisch: SkuCore\UIErrors.lua bekommt einen verschachtelten Menuebauer
(analog zu den Chat-Stimmen pro Kanal); der Wert bleibt ein einzelner
String ("voice" / "voice#" / Clip-Pfad / Ton-Pfad / silent), bestehende
Einstellungen bleiben erhalten. OutputError decodiert "voice#" und gibt
den Stimmindex an OutputStringBTtts; die Fokus-Vorschau spielt die Auswahl
an.
Menues umsortiert
Einfach: Neues Menue "Werkzeuge" mit Dial Targeting und Soft Targeting. Der
Monitor enthaelt jetzt zusaetzlich Entfernung, Fallerkennung,
Fehler-Feedback, Ziel-Optionen und Quest-Benachrichtigungen. Das
Audio-Menue ist verschlankt. Das alte Menue "Barrierefreiheit" heisst jetzt
"Schnellmenue".
Technisch: Verschiebungen in SkuZOptions/SkuMenu und SkuCore\aq.lua
MonitorMenuBuilder; RangecheckMenuBuilder fuer Wiederverwendung freigelegt;
das nun leere Kampf-Untermenue entfernt; gleiche db/keyPrefix, daher
bleiben gespeicherte Werte erhalten.
Gruppenmitglieder-Quests: kein Absturz mehr bei Fortschritt
Einfach: Das Oeffnen einer Quest eines Gruppenmitglieds mit Zielfortschritt
fuehrte manchmal zu einem Fehler und brach das Vorlesen ab. Sie oeffnet
jetzt zuverlaessig.
Technisch: Der Gruppenmitglieder-OnEnter haengte an die Sektionen-TABELLE aus
GetQuestDataStringFromDB an; er baut jetzt eine echte Sektionentabelle
(Live-Fortschritt zuerst) wie der eigene Questpfad.
Installer: funktioniert hinter geteilten / VPN-Verbindungen
Einfach: Der Installer konnte mit "rate limit exceeded" scheitern, bevor
ueberhaupt ein Download begann, bei geteilten oder VPN-Verbindungen. Das
passiert jetzt nicht mehr.
Technisch: Die api.github.com-Release-Abfrage (Limit 60/h/IP) entfaellt; die
(Tag, Dateiname)-Paare sind in Config gepinnt und direkte
github.com/.../releases/download-URLs werden gebaut.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v41.06
Freundesliste: "Einladen" funktioniert wieder
Einfach: Im Fenster Freunde liess sich ein Freund nicht einladen (Fehlerton).
Jetzt klappt die Einladung wieder, auch fuer Battle.net-Freunde.
Technisch: InviteUnit ist in 2.5.5 keine globale Funktion mehr; der normale
Freund-Zweig (SkuCore\friends.lua) nutzt jetzt C_PartyInfo.InviteUnit mit
Fallback, wie der Battle.net-Zweig.
Auren-Sets teilen: besser bedienbar
Einfach: "Sets (teilen)" steht jetzt an 3. Stelle (unter Neue Aura und Auren
verwalten). "Set aus aktuellen Auren anlegen" heisst jetzt "Neues Set aus
aktuellen Auren erstellen". Beim Anlegen kann der Name jetzt direkt getippt
werden (vorher ging nur Einfuegen). Die Ansage ist auf "Set angelegt"
vereinfacht, da der frei gewaehlte Name nicht vertonbar ist.
Technisch: SkuAuras\sharing.lua nutzt jetzt SkuOptions:EditBoxShow (mit
Tastatur-Fokus) statt EditBoxPasteShow; Menue-Reihenfolge in
SkuAuras\Options.lua angepasst; Ansage nur einmal.
Auren-Sets teilen: "Set loeschen" funktioniert jetzt zuverlaessig
Einfach: Beim Loeschen eines Sets blieb der Eintrag manchmal stehen und das
naechste Enter machte nur einen Fehlerton. Jetzt wird das Set geloescht,
das Menue springt zurueck zur Set-Liste und baut sie neu auf.
Technisch: Nach SetsDelete navigiert das Menue zurueck auf "Sets (teilen)"
und ruft OnSelect / VocalizeCurrentMenuName (SkuAuras\sharing.lua); Ansage
auf "Set geloescht" vereinfacht.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v41.05
Gegnerstatus Kampf: Kampf/passiv beim Anvisieren (Aus / Beep / Ansage)
Einfach: Neuer Punkt unter Barrierefreiheit, Sonstiges: "Gegnerstatus Kampf".
"Beep" (Standard) ist das bisherige Verhalten - ein Ton vor dem Gegnernamen,
wenn der Gegner mit dir oder deiner Gruppe kaempft. "Ansage" behaelt den Ton
und sagt zusaetzlich "im Kampf" bzw. "passiv" vor dem Namen. "Aus" schaltet
Ton und Statusansage ab. Der Durchschalt-Knopf bleibt unveraendert.
Technisch: In SkuMob\Core.lua (PLAYER_TARGET_CHANGED) wird der vorhandene
InCombatSound nur noch gespielt, wenn der Modus nicht "aus" ist; im Modus
"Ansage" wird "im kampf" analog zum vorhandenen "passiv" vor den Namen
gehaengt. Neuer DB-Wert profile.SkuMob.enemyCombatStatusMode
(off/beep/announce, Standard beep -> bestehende Charaktere unveraendert).
Menue in SkuZOptions\Core.lua, Locale "im kampf" in deDE/enUS. Reiner
Ansage-Code, kein Taint.
Stabilitaet: Absturz beim freundlichen Lebens-/Heil-Monitor behoben
Einfach: Der Fehler "fatality", der auftreten konnte, wenn man im Kampf auf
sich selbst oder einen Begleiter wechselte (bei aktiver Option "eingehende
Heilung einrechnen"), ist behoben. Die Lebensansagen laufen normal weiter.
Technisch: In SkuCore\aq.lua holte UNIT_HEALTH den Wert
UnitGetIncomingHeals(unit, "player") ohne nil-Absicherung; bei fehlender
eingehender Spielerheilung (Normalfall) ergab die Subtraktion "Zahl minus
nil" einen Lua-Fehler. An vier Stellen "or 0" ergaenzt.
Stabilitaet: seltener Menue-Fehler (Core.lua:4021) behoben
Einfach: Ein Fehlerton, der ganz selten beim Navigieren in bestimmten Menue-
Zustaenden (z.B. offene Chatzeile per Strg+Enter, dann Pfeil) auftrat, ist weg.
Technisch: In SkuOptions:VocalizeMultipartString lief eine Debug-Brotkrumen-Schleife
"while tTable.parent.name do" ohne nil-Schutz; an einem Wurzelknoten ohne parent
-> "attempt to index field 'parent'". Guard ergaenzt (tTable und tTable.parent
geprueft). Reiner Debug-Pfad, keine Funktionsaenderung.
Folgen-Warnung: kein faelschliches "Folgen beendet" beim erneuten Folgen-Druck
Einfach: Wenn du beim Folgen die Folgen-Taste erneut druckst (um es zu pruefen),
unterbricht WoW das Folgen kurz und baut es sofort neu auf. Vorher kam dabei
faelschlich "Folgen beendet". Jetzt bleibt es in diesem Fall beim normalen Bling;
"Folgen beendet" kommt nur noch bei einem ECHTEN Abbruch.
Technisch: Die Ansage bei AUTOFOLLOW_END wird um 0,4 s verzoegert und unterdrueckt,
wenn in der Zwischenzeit ein AUTOFOLLOW_BEGIN kommt (Wieder-Folgen). Generation-
Zaehler gegen veraltete Timer. In SkuCore\visualAids.lua.
Fix: "Ton fuer Klick bei Beacons" - Menue war manchmal leer (Navigation, Optionen)
Einfach: Die Auswahl des Klick-Tons (Beep/Click) war manchmal leer und nicht
umstellbar (der An/Aus-Schalter ging trotzdem). Grund war ein Ladereihenfolge-
Rennen: die Klick-Toene kommen aus dem Zusatz-Addon SkuBeaconSoundsets und werden
erst beim Betreten der Welt registriert - Sku baute die Liste aber manchmal
schon vorher (leer) auf. Jetzt wird die Liste kurz nach dem Laden zuverlaessig
nachgebaut.
Technisch: Additiver, verzoegerter Nachzieher in SkuNav\Options.lua (NICHT in der
geschuetzten SkuNav\Core.lua): auf PLAYER_ENTERING_WORLD + C_Timer.After baut er
SkuNav.ClickClackSoundsets neu aus BeaconLib:GetClickClackSoundSets() und zeigt
die Auswahl (clickClackSoundset.values) darauf um. pcall-geschuetzt, No-Op falls
SkuBeaconSoundsets fehlt. WICHTIG: ist SkuBeaconSoundsets deaktiviert/fehlt,
bleibt die Liste leer (dann fehlen auch die Beacon-Sounds) - haeufige Ursache
von "Audioproblemen" bei Nutzern. Details: Heute\Diagnose - Klick bei Beacon
Tonmenue leer.txt.
Maus: alternative Steuerung ("zum Ziel laufen") sauber abschaltbar + Schalter im Menue
Einfach: Im Barrierefreiheitsmenue unter Sonstiges gibt es jetzt den Schalter
"Bei Interagieren zum Ziel laufen". Sehende koennen die automatische
Lauf-bei-Klick-Steuerung damit abschalten; sie stoert die normale Maus nicht mehr.
Technisch: Der WorldFrame-Maushandler wird nicht mehr per SetScript ueberschrieben,
sondern additiv per HookScript GENAU EINMAL installiert (Guard-Flag, nicht im
100ms-Pfad) und tut nichts, solange interactMove aus ist. Schalter ueber den
vorhandenen Options-Knoten in die Barrierefreiheit (Sonstiges) eingehaengt.
Plaketten an die Kamera gekoppelt
Einfach: Die freundlichen Plaketten werden nur noch erzwungen, solange in der
Kamera der SkuStandard aktiv ist. Bei freigegebenem Kameramenue kannst du die
Plaketten selbst veraendern oder ausschalten.
Technisch: Der Zwang nameplateShowFriends=1 im OnUpdate-Loop wird nur noch
angewendet, wenn cameraOptions.skuStandard ~= false (reiner Read mit voller
and-Kette, Kampf-Gate bleibt erhalten).
Neu: Schwarzer Lesebalken (Barrierefreiheit, fuer Sehbehinderte)
Einfach: Ein schwarzer Balken am oberen oder unteren Bildschirmrand zeigt gross
und kontrastreich NUR den aktuellen Menuepunkt (nicht den ganzen Pfad), der
gerade vorgelesen wird. Nur sichtbar, wenn das Menue offen ist. Standard AUS.
Im neuen Menuepunkt Barrierefreiheit, Visuelle Hilfen, kannst du ihn ein- und
ausschalten und Schriftgroesse (bis sehr gross; groesser wird auch fetter),
Position (oben/unten) und Deckkraft einstellen. Lange Zeilen laufen rechts
heraus - das ist gewollt. Korrektur: bei sehr grosser Schrift waechst der Balken
jetzt nach UNTEN (Text war oben abgeschnitten); er wird nicht mehr oben am
Bildschirmrand abgeschnitten.
Technisch: Neues nicht-secure FontString-Frame an UIParent (EnableMouse(false),
kein Taint), gespeist aus SkuOptions.currentMenuPosition.name (nur die aktuelle
Zeile), event-getrieben (kein OnUpdate, nicht im 100ms-Loop), Text NACH der
Sprachausgabe gesetzt. Schrift via SetFont mit THICKOUTLINE ab mittlerer Groesse
(Fettung). FontString jetzt an TOPLEFT verankert (JustifyV TOP), Balkenhoehe
px+40%+12, damit grosse Schrift nach unten waechst statt am oberen Rand
abzuschneiden. Logik isoliert in SkuCore\visualAids.lua; Werte pro Profil unter
db.profile.SkuCore.visualAids.lineBar. Neuer Menuepunkt "Visuelle Hilfen".
Neu: Plaketten-Farben (Barrierefreiheit, fuer Sehbehinderte)
Einfach: In Barrierefreiheit, Visuelle Hilfen, Plaketten-Farben kannst du die
Plaketten nach Reaktion einfaerben (Feind, Neutral, Freund), jede Farbe selbst
waehlen, dazu Modus (nur Ziel oder alle Plaketten), Groesse und Deckkraft.
Standard AUS. Ein Warnhinweis erklaert, dass die Farben reine Anzeige sind.
Technisch: Eigene Funktion in SkuCore\visualAids.lua, eigener Opt-in-Flag (nicht
testMode), ereignisgesteuert (NAME_PLATE_UNIT_ADDED/REMOVED, PLAYER_TARGET_CHANGED),
kein C_Timer-Fan-out, nicht im 100ms-Loop, keine TOOLTIP-Strata. Volle nil-Guards
(UnitReaction, 4-stufige Frame-Pruefung). Im AUS-Zustand sind die Events abgemeldet.
Neu: Maus-Finder (Barrierefreiheit, fuer Sehbehinderte)
Einfach: In Barrierefreiheit, Visuelle Hilfen, Maus-Finder einschalten. Die Taste
vergibst du jetzt DIREKT im Maus-Finder-Menue (dritter Punkt "maus finden",
nach rechts, Neu belegen) - genau wie in der Sku Tastenbelegung, du musst sie
nicht mehr separat suchen. Der reine Texthinweis ist entfallen. Auf Tastendruck
leuchtet kurz eine kontrastreiche Markierung um die Maus auf (Pulsring oder
Kompass-Striche waehlbar). Standard AUS.
Technisch: Sauber geformter Tasten-Eintrag SKU_KEY_MOUSEFINDER (kein leerer Eintrag,
daher kein Login-Crash), Handler ruft ein nicht-interaktives Overlay
(EnableMouse(false)) zentriert auf GetCursorPosition, etwa ein Viertel Bildschirm,
blendet via C_Timer.After automatisch aus. Kein Secure-Button, kein Taint. Der
Tastenbelegungs-Eintrag im Maus-Finder-Menue ist vollstaendig in
SkuCore\visualAids.lua gekapselt (eigener Capture-Helper, schreibt in dieselbe
SkuKeyBinds-DB wie das Hauptmenue); SkuCore\Options.lua bleibt unangetastet.
Neu: Anzahl der Gegner ansagen (Barrierefreiheit, Sonstiges)
Einfach: Unter Barrierefreiheit, Sonstiges gibt es jetzt "Anzahl der Gegner
ansagen" mit drei Einstellungen: "nur Elitegegner", "alle Gegner" und
"ausgeschaltet". Damit setzt du mit einem Griff die passende Kombination, ohne
die zwei Einzelschalter im Monitor feindlich suchen zu muessen.
Technisch: Komfort-Auswahl, die zwei vorhandene Werte koppelt (in
db.char.SkuCore.aq[talentSet].combat.hostile): relativeNumberUnitsInCombat.value
und ignoreNonElite. Zuordnung: nur Elite -> ignoreNonElite=true, value=3 (Gegner
die dich/Gruppe angreifen); alle Gegner -> ignoreNonElite=false, value=3;
ausgeschaltet -> ignoreNonElite=true, value=1 (aus). Korrektur: bei "alle Gegner"
und "nur Elite" wird jetzt ZUSAETZLICH der Kampfmonitor-Master aktiviert
(db.char.SkuCore.aq[talentSet].combat.enabled=true) - vorher kam auf einem
Charakter, bei dem der Master aus war, trotz "alle Gegner" keine Ansage. Bei
"ausgeschaltet" bleibt der Master bewusst unberuehrt (nur die zwei Einzeloptionen
werden gesetzt), damit anderes Kampfmonitoring nicht angetastet wird.
Neu: Warnton wenn das Folgen abbricht (Barrierefreiheit, Sonstiges)
Einfach: Unter Barrierefreiheit, Sonstiges gibt es jetzt "Warnton wenn Folgen
abbricht" (ein/aus, Standard aus). Wenn du jemandem folgst (Autofollow) und
das Folgen endet - egal ob das Ziel zu weit weg ist, stehen bleibt oder du dich
bewegst -, kommt die Ansage "Folgen beendet". Eine Distanzmessung oder das
Festlegen einer Person ist dafuer nicht noetig.
Technisch: Schlanker Listener auf die oeffentlichen Events AUTOFOLLOW_BEGIN/END in
SkuCore\visualAids.lua; Ansage nur, wenn vorher ein Folgen begann und der
Schalter (db.profile.SkuCore.followBreakWarn) an ist. Kein Taint, keine
Distanzmessung, kein OnUpdate. Hinweis: eine Warnung, wenn JEMAND ANDERES
aufhoert DIR zu folgen, ist technisch nicht moeglich (kein Event dafuer).
Neu: Taste "naechster Gegner im Kampf" (Sku Tastenbelegung)
Einfach: In der Sku Tastenbelegung (Menue Core) gibt es die neue Aktion
"naechster Gegner im Kampf". Belegst du sie mit einer Taste, schaltest du auf
Tastendruck durch die nahen Gegner - auch mitten im Kampf. Sku sagt das neue
Ziel wie gewohnt an. Standard: keine Taste vergeben.
Technisch: SICHERE Umsetzung ueber einen SecureActionButton (Makro /targetenemy),
an den die gewaehlte Taste per SetOverrideBindingClick gebunden wird. Damit ist
der Zielwechsel im Kampf erlaubt (kein ADDON_ACTION_BLOCKED, kein Taint).
SKU_KEY_NEXTCOMBATENEMY -> SkuCore:UpdateNextCombatEnemyBinding (in
SkuCore\visualAids.lua), Bindung wird im Kampf zurueckgestellt und via
PLAYER_REGEN_ENABLED nachgezogen. Hinweis: /targetenemy schaltet durch nahe
angreifbare Gegner, nicht exakt gefiltert nur auf die, die mit dir kaempfen -
eine exakt gefilterte Variante waere ein groesserer, spaeterer Ausbau.
Neu: Auren-Sets anlegen und in der Gruppe teilen (Stufe 1+2)
Einfach: Im Menue Auren gibt es jetzt "Sets (teilen)". Du kannst aus deinen
aktuellen Auren ein benanntes Set anlegen (gleicher Name vorhanden -> es wird
eine Zahl angehaengt), Sets auflisten und loeschen. Ein Set laesst sich "An
Gruppe teilen": deine Gruppe sieht " teilt Aurenset " und am Ende
"Teilen abgeschlossen". Wer Sku hat und in der Gruppe ist, bekommt das Set unter
"Empfangene Sets" und kann es dort annehmen (mit Doubletten-Pruefung) oder
verwerfen. Hinweis: in dieser Stufe nur zwischen gleicher Clientsprache; der
Sprach-Uebersetzer kommt spaeter.
Technisch: Isoliert in NEUER Datei SkuAuras\sharing.lua, pcall-geschuetzt, aendert
das bestehende Auren-System NICHT (Auren bleiben name-basiert). Sets:
db.char.SkuAuras.Sets (Schnappschuss). Transport ueber AceComm-3.0 (Embed in
SkuAuras, Prefix SkuAuraSetV1, automatisches Zerteilen) plus AceSerializer
(SkuOptions:Serialize/Deserialize). Empfang in db.char.SkuAuras.PendingSets;
Annehmen importiert mit Doubletten-Pruefung und ruft
UpdateAttributesListWithCurrentAuras. Sichtbare Gruppen-Ansage via
SendChatMessage, Daten versteckt per Addon-Nachricht. Kein Taint. Spaeter:
Stufe 3 (accountweite Bibliothek), Stufe 4 (Sprach-Uebersetzer ueber
SkuDB.SpellDataTBC). Details im Plan im Heute-Ordner.
Standardwert: Fortlaufend-Lautstaerke der Gesundheits-Monitore jetzt 100
Einfach: Bei einer NEUEN Installation ist die Lautstaerke fuer die fortlaufende
Ausgabe der Gesundheits-Monitore (Spieler, Gruppe, Raid, Pet) jetzt 100 statt
50 - passend zur Ereignis-Lautstaerke (die war schon 100). Bestehende Profile
bleiben unveraendert.
Technisch: Default continouslyVolume in SkuCore\aq.lua von 50 auf 100 (4 Stellen:
player/party/raid/pet health). Greift nur, wenn der Wert noch nil ist (Neuanlage).
Soft-Targeting: "Hardtarget vor Softtarget" wirkt jetzt + kein Kampf-Fehler mehr
Einfach: Die Einstellung "Hardtarget zaehlt vor Softtarget" hatte bisher KEINE
Wirkung - ein Zauber ging trotz festem Ziel auf das Soft-Ziel. Behoben: mit
festem (hard) Ziel zaehlt jetzt das feste Ziel. Ausserdem verschwindet der
"ADDON_ACTION_BLOCKED"-Fehler, der nach Login beim ersten freundlichen Ziel im
Kampf auftrat.
Technisch: In UpdateSoftTargetingSettings (SkuZOptions/Core.lua) setzten frueher
BEIDE Zweige SoftTargetMatchLocked = 0 (Bug) -> bei matchLocked>0 jetzt = 1.
Zudem sind SoftTarget-CVars im Kampf gesperrt: die Funktion ueberspringt im
Kampf alle SetCVar-Aufrufe (InCombatLockdown-Guard) und zieht sie nach
Kampfende (PLAYER_REGEN_ENABLED) einmal nach. Kein Funktionsverlust (CVars sind
im Kampf ohnehin eingefroren), kein ADDON_ACTION_BLOCKED mehr.
Versionsnummer auf 41.05 angehoben.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v41.04
Auktionshaus: Kaufmeldungen jetzt in der richtigen Sprache
Einfach: Wenn beim Kauf etwas schiefgeht (z. B. man drueckt zu frueh
Enter), kommt die Meldung jetzt auf Englisch, wenn man den englischen
Client spielt - vorher kam sie immer auf Deutsch.
Technisch: Drei fest einprogrammierte deutsche Texte im Kaufpfad
(auctionHouse.lua) sind jetzt ueber L[...] lokalisiert; Schluessel in
deDE.lua und enUS.lua ergaenzt.
Auktionshaus: Komplettscan startet zuverlaessig, keine falsche 16-Minuten-Sperre
Einfach: Frueher konnte der Komplettscan stumm fehlschlagen und danach
16 Minuten gesperrt sein, ohne dass je gescannt wurde. Jetzt startet er
entweder wirklich, oder es kommt die Ansage "Scan noch nicht moeglich,
bitte kurz warten" - und die Sperre wird nur gesetzt, wenn wirklich
gescannt wurde. Der Fokus bleibt auf dem Scan-Punkt.
Technisch: AuctionHouseStartQuery gibt true nur zurueck, wenn
QueryAuctionItems tatsaechlich abgesetzt wurde; der getAll-Scan wird
vorher gegen CanSendAuctionQuery geprueft. Der Zeitstempel
(AuctionLastFullScanTime) wird nur bei echtem Start gesetzt.
noStepUpAfterSelect haelt den Fokus.
Auktionshaus: Fokus bleibt beim Filtern/Sortieren
Einfach: Nach dem Waehlen von z. B. "selten" oder "Level absteigend"
springt der Fokus nicht mehr eine Ebene zu weit zurueck, sondern bleibt
auf dem Filter.
Technisch: Die fuenf Filter-/Sortier-Eintraege (Level min/max, Qualitaet,
nur benutzbare, Sortierung) haben jetzt noStepUpAfterSelect = true.
AtlasLoot/Wunschliste: keine Raid-Lags mehr
Einfach: Die Wunschliste hat im Raid-Kampf bei vielen Chat-Nachrichten
gebremst. Das ist behoben - der Wunsch-Item-Ton beim Looten/Wuerfeln/
Verlinken funktioniert weiter.
Technisch: Statt pro Chat-Zeile/Item-Link die ganze Favoritenliste mit
GetItemInfoInstant zu durchlaufen, gibt es jetzt einen itemID-Cache
(O(1)-Lookup), der nur bei Aenderung neu gebaut wird. Bei leerer
Wunschliste brechen die Chat-Handler sofort ab.
AtlasLoot: Strg+Shift+L vereinfacht
Einfach: Strg+Shift+L oeffnet jetzt einfach Atlas Loot. Der automatische
Sprung auf die aktuelle Instanz oder den Boss im Ziel wurde entfernt -
er war unzuverlaessig und konnte Fehler machen.
Technisch: Die Kontext-Erkennung (Instanz/Boss/Schwierigkeit) in
AtlasLootShortcut wurde entfernt; es wird immer der Standard-Pfad
geoeffnet und das Kontext-Flag geleert.
Freundesliste: Battle.net-Freunde einladen
Einfach: Man kann jetzt einen Battle.net-Freund, der gerade WoW spielt,
ueber das Menue in die Gruppe einladen. Vorher passierte nichts.
Technisch: Im Invite-OnAction (friends.lua) gibt es jetzt einen BNet-Zweig:
Charaktername + Realm aus gameAccountInfo, Einladung via
C_PartyInfo.InviteUnit (Fallback InviteUnit/BNInviteFriend). Spielt der
Freund nicht WoW, kommt eine Ansage.
Auren: Anzeigename stuerzt nicht mehr ab
Einfach: Beim Anzeigen oder Durchblaettern von Auren konnte es einen
Lua-Fehler geben, wenn eine Aura einen Wert oder eine Aktion
benutzte, die das Addon gerade nicht aufloesen konnte. Das ist behoben.
Technisch: BuildAuraName (SkuAuras/Options.lua) macht alle dynamischen
Lookups (Types, attributes, Operators, values, actions, outputs) jetzt
nil-sicher; bei unbekanntem Schluessel wird der Rohschluessel angezeigt
statt eines Fehlers.
Nicht in dieser Version (bewusst verschoben)
- Taschen: Fokus/Aktualisierung nach "wird an dich gebunden" - beruehrt den
empfindlichen Taschen-Frame-Bereich und wird separat angegangen.
- Soft-/Hardtarget (Hardtarget soll Softtarget verdraengen; weniger
Target-Spam bei rausgezoomter Kamera) - liegt im geschuetzten
Zielsystem; nur analysiert, noch nicht umgesetzt.
Versionsanzeige
- Sku.toc und SkuDispatcher/Sku.toc auf v41.04 aktualisiert.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v41.03
Barrierefreiheit-Menue: 7.4 Sonstiges
- Neuer Unterpunkt 7.4 "Sonstiges" unter Menuepunkt 7. Schnellzugriff auf:
Spieltooltip nicht ausblenden, Alle Tooltips lesen, NPC-Begruessungen,
Menuenummern ansagen, Untermenues ansagen.
- Verknuepfungen auf die bestehenden Optionen - Aenderungen wirken in
beide Richtungen. Der Cursor bleibt nach dem Umschalten auf dem Eintrag.
AtlasLoot/Wunschliste: Boss-Quelle im Tooltip (Ansicht "Nach Slot")
- In der Wunschliste unter "Nach Slot" wird die Drop-Quelle (Instanz und
Boss) jetzt zuverlaessig im Tooltip angezeigt - auch direkt nach dem
Login, ohne vorher die Ansicht "Nach Dungeon" geoeffnet zu haben.
Auren: Waffenbuff-Bedingungen (neu)
- Vier neue Bedingungen: "Deine Waffenverzauberung Haupthand" und "... Nebenhand"
(enthaelt / enthaelt nicht) sowie deren verbleibende Dauer in Sekunden.
- Damit lassen sich Alarme bauen, z. B. wenn ein Gift/Oel/Schaerfstein auf
der Haupthand laeuft oder die Rest-Dauer unter einen Wert faellt.
- Rein zusaetzlich gebaut; bestehende Auren sind unveraendert.
Versionsanzeige
- Sku.toc und SkuDispatcher/Sku.toc auf v41.03 aktualisiert.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v41.02.08
Menue 7 "Barrierefreiheit" mit Schnellzugriffen
- Menuepunkt 7 heisst jetzt "Barrierefreiheit". Darunter:
7.1 Lautstaerke, 7.2 Sprachausgabe, 7.3 Kamera.
- 7.1 Lautstaerke: Gesamt-, Soundeffekte-, Musik-, Umgebungs- und
Dialoglautstaerke, Beacon-Lautstaerke sowie Hall, positionsbezogener
Tiefpassfilter, DSP-Effekte, Sound im Hintergrund und Zonenmusik ohne
Verzoegerung. Es sind Verknuepfungen auf die bestehenden Optionen -
Aenderungen wirken in beide Richtungen (Barrierefreiheit und Originalmenue).
- 7.2 Sprachausgabe: TTS-Stimme, -Geschwindigkeit und -Lautstaerke.
- 7.3 Kamera: das bisherige Video-Optionen-Menue (Verfolgung, Zoom usw.).
- Die urspruenglichen Menues (Optionen/Optionen, Navigation/Optionen,
Chat/Optionen) bleiben unveraendert erhalten.
- Nach einer Wertaenderung bleibt der Cursor auf dem jeweiligen Regler
(nur im 7er-Menue), sodass man zuegig mehrere Werte einstellen kann.
Briefkasten: Fokus bleibt auf dem Brief
- Nach dem Entnehmen von Gold oder einem Gegenstand bleibt der Cursor
auf dem Brief stehen, statt zur Briefliste hochzuspringen. Per Pfeil-
rechts oeffnet man die (aktualisierten) Anhaenge erneut und entnimmt
weitere. Beim Loeschen wird sauber der Nachbar-Brief fokussiert.
Navigation: Menuepunkt "Daten" ausgeblendet
- Der Punkt "Daten" unter Navigation ist nicht mehr sichtbar.
Versionsanzeige
- Sku.toc und SkuDispatcher/Sku.toc auf v41.02.08 aktualisiert.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v41.02.07
Kamera: Freie Kamera nach Brechen des SkuStandards
- Wird der SkuStandard freigegeben, bleibt die selbst eingestellte
Kamera jetzt erhalten - auch beim Drehen mit T oder zum Wegpunkt.
Der erzwungene Kamera-Sprung (SetView) wirkt nur noch im SkuStandard.
Die Drehung selbst funktioniert weiterhin korrekt.
- Persoenlicher Kamera-Speicher: Aenderungen im freien Modus werden
gespeichert und nach dem Login automatisch wieder geladen. Der sichere
SkuStandard bleibt Standard fuer alle anderen Nutzer.
- Menue 7 "Video-Optionen" als Grundlage fuer die neue Struktur.
Versionsanzeige
- Sku.toc und SkuDispatcher/Sku.toc auf v41.02.07 aktualisiert.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v41.02.06
Kamera-Optionen (Menuepunkt 7)
- Neues Menue "Kamera-Optionen" ersetzt den bisherigen Platzhalter "Reserviert".
- Sku Standard sperren/entsperren: Sperrt alle Kameraeinstellungen auf den Sku-Standard (noetig fuer Wegpunktnavigation). Beim Sperren wird eine Bestaetigung abgefragt und ein vollstaendiger Kamera-Reset durchgefuehrt inkl. SaveView(2). Beim Entsperren werden die gespeicherten User-Einstellungen wiederhergestellt.
- Kamera-Entfernung: 6 Stufen von Nah (Faktor 1) bis Maximum (Faktor 4). Zoom wird physisch ausgefuehrt.
- Kamera-Hoehe: 4 Stufen von flach bis Vogelperspektive. Hinweis: funktioniert nur wenn Verfolgungsstil nicht auf Immer steht.
- Kamera-Neigungsgeschwindigkeit: 4 Stufen von Langsam bis Sehr schnell.
- Kamera-Verfolgungsstil: 4 Optionen wie im WoW-Original (Intelligent, Nur bei Bewegung, Immer, Niemals). "Immer" ist der Sku Standard fuer Wegpunktnavigation.
- Interface ein/ausblenden: Blendet die gesamte WoW-Oberflaeche ein oder aus.
- Weitere Kamerafunktionen: Kamera-Uebergang (sofort/sanft), Ueber-die-Schulter-Ansicht, Plaketten (Gegner/Freundliche/Alle ein/aus).
- Alle Einstellungen zeigen ihren aktuellen Wert im Menuenamen an. Aktive Option mit "(eingestellt)" markiert.
- Bei gesperrtem Sku Standard sind alle Untermenues blockiert mit Ansage.
- Einstellungen bleiben ueber Logout/Login erhalten (persistent in SavedVariables).
Auktionshaus: Absturz auf englischem Client behoben
- Beim Oeffnen des Auktionshauses konnte ein Fehler auftreten (ipairs auf nil), wenn AuctionCategories noch nicht von Blizzard initialisiert war. Fix: nil-Guard vor beiden ipairs-Schleifen und 0.3s Verzoegerung beim Menue-Aufbau.
AtlasLoot: Lokalisierung korrigiert
- Die Gruppen "Instanzen", "Schlachtzuege" und "Weltbosse" unter AtlasLoot Listen waren hardcoded auf Deutsch. Sie verwenden jetzt L[]-Eintraege und erscheinen auf englischen Clients korrekt. Ebenso "Heroisch", "Normal" und der Schwierigkeitsgrad-Fallback.
Charakterfenster: Gegenstand im Slot
- CheckFrames wird nach dem Aufnehmen eines Gegenstands aus einem Equipment-Slot nicht mehr sofort aufgerufen. Dadurch kann der Gegenstand in die Tasche gelegt werden, ohne dass das Menue den Slot-Zustand verfaelscht.
Soulbind-Bestaetigung: Fokus-Verbesserung
- Nach dem Bestaetigen der "Gegenstand wird gebunden"-Abfrage springt der Fokus nicht mehr auf die Taschen-Ebene zurueck. Stattdessen wird CheckFrames verzoegert aufgerufen und der Cursor korrekt positioniert.
Weltkarte: Visuelles Flackern reduziert
- Das Addon oeffnete und schloss die Weltkarte im Hintergrund (alle 0.15s), um Positionsdaten zu lesen. Wenn die Karte bereits offen war, verursachte dies visuelles Flackern. Fix: Show/Hide wird nur noch ausgefuehrt, wenn die Karte nicht sichtbar ist.
Versionsanzeige
- Sku.toc und SkuDispatcher/Sku.toc aktualisiert auf v41.02.06.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v41.02.05
Begleiter-Aktionsleiste: Automodus repariert
- Der Automodus (Autocast) fuer Begleiterfaehigkeiten funktioniert jetzt. Die Umschaltung nutzt macrotext mit /click RightButton im Hardware-Event-Kontext. Menue zeigt "Permanent (aktiviert/deaktiviert)" mit Untereintraegen zum Ein- und Ausschalten.
Rollenabfrage-Fenster zugaenglich gemacht
- Die Rollenabfrage des Gruppenleiters oeffnet jetzt ein Sku-Menue mit den Optionen "Tank", "Heiler" und "Schaden". Enter auf eine Rolle waehlt sie und bestaetigt sofort. Bereits gewaehlte Rollen werden nicht zurueckgesetzt.
Equipment-Slot Doppelklick behoben
- Linksklick auf ausgeruestete Gegenstaende im Charakterfenster nahm den Gegenstand auf und legte ihn sofort wieder ab. Ursache: macrotext und OnAction feuerten beide. Fix: OnAction prueft per GetCursorInfo ob der Gegenstand bereits am Cursor haengt.
Tastenbelegung: Konflikt-Aufloesung repariert
- Beim Umbelegen einer Taste auf eine andere Aktion wurden bisher ALLE Belegungen der alten Aktion geloescht (primaer und sekundaer). Jetzt wird nur die konfliktbehaftete Taste entfernt, die andere Belegung bleibt erhalten.
Sockelfenster: Duplikat-Edelsteine repariert
- Gleichnamige Edelsteine werden jetzt gruppiert und mit Anzahl angezeigt (z.B. "Gediegener Zirkon 2x"). Nach dem Einsetzen in einen Sockel wird der genutzte Taschenplatz als belegt markiert, sodass der naechste Sockelplatz den verbleibenden Stein korrekt anzeigt und einsetzen kann.
Wunschliste: Kategorie "Sonstiges" hinzugefuegt
- Items ohne Equipment-Slot (Tokens, Rezepte, Reittiere) koennen jetzt zur Wunschliste hinzugefuegt werden. Sie erscheinen unter "Nach Slot" in der neuen Kategorie "Sonstiges".
Tastenbelegungsliste beigelegt
- Drei Readme-Dateien im Sku-Ordner: Standard-Tastenbelegung fuer blinde Spieler auf Deutsch, Englisch und Franzoesisch.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v41.02.04
PageDown/PageUp im Sku-Menue korrigiert
- PageDown/Up springt nicht mehr 10 Menuepunkte im Sku-Menue. Die Tasten loesen jetzt nur noch das Blaettern in Berufefenstern (Rezeptlisten) aus und aktualisieren das Menue entsprechend. In allen anderen Menues (Taschen, Auktionshaus etc.) haben die Tasten keine Wirkung mehr.
Lokalisierung: Ausruestungssets
- Der Menuepunkt "Ausruestungssets" im Charakterfenster war bisher ein hardcoded deutscher String. Er verwendet jetzt L["Equipment sets"] und erscheint auf englischen Clients korrekt als "Equipment sets".
Lokalisierung: Sockelfenster
- Der Frame-Name "Sockeln" auf der ersten Menue-Ebene war bisher ein hardcoded String. Er verwendet jetzt L["Sockeln"] und erscheint auf englischen Clients korrekt als "Socket".
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v41.02.03
Briefkasten: Neue kombinierte Eingabe
- Neuer Brief hat jetzt drei Menuepunkte: "Gegenstaende anhaengen", "Gold anhaengen" und "Versendevorgang starten". Die Reihenfolge ist logisch: zuerst optionale Anhaenge, dann Versand.
- "Versendevorgang starten" oeffnet ein Eingabefeld. Bedienung: Name eingeben, Tab druecken, Betreff eingeben, Tab druecken, optional Text eingeben, Enter druecken. Der Brief wird direkt gesendet.
- Nach dem Anhaengen von Gegenstaenden oder Gold kehrt der Fokus automatisch zum jeweiligen Menuepunkt zurueck. Nach dem Senden kehrt der Fokus auf "Neuer Brief" zurueck.
- Technisch: Neue Funktion SkuCore:MailEditorCombined() in mail.lua. Nutzt OnKeyDown-Handler auf der EditBox fuer Tab- und Enter-Erkennung. Tab wechselt das Feld (Name/Betreff/Text), Enter schliesst ab und ruft SendMail() direkt auf. Das Menue bleibt offen (MailFrame muss fuer SendMail() sichtbar sein).
Hexenmeister-Begleiter: Eigenes Zielmenue
- Das Zielmenue fuer Hexenmeister-Begleiter (Daemonen) zeigt jetzt die korrekten Aktionen: Schlachtzugsymbol, Fokus setzen, Interagieren und Freigeben. Bisher wurden faelschlich die Jaeger-Pet-Aktionen angezeigt.
- Technisch: SkuMob/Options.lua, tIsPet-Block: Klassenpruefung via UnitClass("player"). HUNTER zeigt Jaeger-Aktionen, alle anderen Klassen zeigen das generische Pet-Menue.
Fehlende Audiowoerter behoben
- "Tabulatortaste" und "absenden" durch "Tab" und "Senden" ersetzt, da die urspruenglichen Woerter keine Audiodateien im SkuAudioData hatten und einen Beep ausloesten.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v41.02.02 (Arbeitsversion)
Erkenntnisse aus der Briefkasten-Reparatur:
- CloseMenu() schliesst auch das Blizzard MailFrame. SendMail() benoetigt aber ein offenes MailFrame. Daher darf CloseMenu() NICHT vor der Mail-Eingabe aufgerufen werden.
- EditBox OnEnterPressed feuert nicht wenn SetScript("OnKeyDown") gesetzt ist. Enter muss im OnKeyDown-Handler manuell abgefangen werden.
- SkuOptionsEditBoxOkScript ist eine lokale Variable in SkuZOptions/Core.lua und kann nicht aus anderen Dateien (z.B. mail.lua) aufgerufen werden. Callbacks muessen als lokale Funktionen im aufrufenden Scope definiert werden.
- RegisterForClicks("AnyDown") verhindert Double-Enter, blockiert aber EditBox-OnEnterPressed (feuert auf Key-Up). Loesung: OnKeyDown-Handler auf der EditBox faengt Enter direkt ab — unabhaengig vom SecureActionButton-Override-Binding.
- Debounce-Ansatz (100ms Sperre im PostClick) funktioniert fuer Taschen und Wunschliste, bricht aber Briefkasten und andere EditBox-Eingaben.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v41.02.01 (Arbeitsversion)
Doppeltes Ausloesen von Enter behoben
- Der SecureActionButton reagierte auf Taste-runter UND Taste-hoch, wodurch jeder Enter-Druck zwei Aktionen ausloeste. Betroffen waren alle Menues: Taschen (Enter sprang 2 Ebenen statt 1), Auktionshaus, Wunschliste (Items wurden sofort wieder entfernt). Fix: RegisterForClicks auf AnyDown geaendert (1x pro Tastendruck).
- Technisch: SkuZOptions/Core.lua Zeile 2738. "AnyUp, AnyDown" -> "AnyDown". AnyDown liefert Hardware-Event-Kontext (wichtig fuer Linksklick/Gegenstaende). AnyUp allein liefert keinen Hardware-Kontext.
Stallmeister repariert
- Die Stallmeister-Funktionen aus Version 40.x wurden uebernommen, da sie funktionsfaehig sind. Der Stallmeister ist nun wieder bedienbar.
- Technisch: SkuCore/LocalMenu.lua, Build_PetStableFrame 1:1 aus Vorlage 2.x kopiert. Nutzt tFrame:GetScript("OnDragStart")(...) und OnReceiveDrag — funktioniert im Gossip/LocalMenu-System ueber den click=true-Pfad des Gossip-Builders.
Pet-Umbenennung repariert
- Fix: Menue wird vor dem Eingabefeld geschlossen (CloseMenu), EditBoxShow statt EditBoxPasteShow, mit Verzoegerung (C_Timer.After 0.3s).
- Technisch: SkuMob/Options.lua. EditBoxPasteShow war fuer Paste-Eingabe (OnChar, min. 10 Zeichen). EditBoxShow ist fuer Tastatur-Eingabe (OnEnterPressed). CloseMenu() hebt das Enter-Override-Binding auf, sodass die EditBox Enter empfangen kann.
secureMacro-System fuer geschuetzte Funktionen
- Das SecureActionButton-Attribut wurde mit dem ungueltigen Mausbutton-Parameter "ENTER" gesetzt. TBC 2.5.5 findet type/macrotext-Attribute nicht fuer unbekannte Button-Namen (kein Fallback auf Default-Attribute).
- Fix: Neues secureMacro-Flag auf Menu-Eintraegen. Wenn gesetzt, werden zusaetzlich typeENTER/macrotextENTER-Attribute gesetzt, die der SecureActionButton korrekt verarbeitet. Eintraege ohne secureMacro loeschen diese Attribute (verhindert Konflikte mit Linksklick/OnAction).
- Technisch: SkuZOptions/templates.lua OnEnter-Handler (Zeile 274). SkuMob/Options.lua: secureMacro=true auf PetDismiss und PetRename-Bestaetigungseintrag.
- Erkenntnis: macrotext feuert NICHT im Gossip/LocalMenu-System (getestet mit /say, /run, /click — keine Ausgabe). macrotext feuert NUR im SkuMob/SkuGenericMenuItem-System (bewiesen durch PetRename/PetDismiss).
Tier freigeben / Tier zuruecklassen
- Lokalisierung an In-Game-Begriffe angepasst.
- secureMacro-Flag fuer PetDismiss (/petdismiss im Hardware-Event-Kontext).
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v41.02
Versionssprung 40.x auf 41.x
- Performance verbessert, Wiki-Bereich entfernt.
- Lokalisierung der neuen Inhalte: Sockeln, AtlasLoot-Wunschliste, Dropdown-Menue, Dungeonfinder.
Bugfix: Zahlen- und Buchstabentasten auf englischem Client blockiert
- Beim Einloggen auf einem englischen WoW-Client wurden nach einem automatischen Profilwechsel alle Buchstaben-, Zahlen- und Leertasten-Eingaben durch verwaiste Override-Bindings blockiert. Betroffen war z. B. die Taste 7 (und damit / auf QWERTZ-Tastaturen). Ursache: SkuKeyBindsUpdate() rief direkt den OnShow-Handler des Menuefensters auf, der saemtliche Menue-Navigations-Bindings setzte, ohne dass OnHide sie wieder raeumte. Der betroffene Keybinding-Eintrag (SKU_KEY_QUESTABANDON) wurde korrigiert.
- Zusaetzlich werden alle Modul-OnEnable-Aufrufe in den Profil-Handlern (OnProfileChanged, OnProfileCopied, OnProfileReset) nun per pcall geschuetzt, damit SkuKeyBindsUpdate() auch bei einzelnen Modul-Fehlern immer erreicht wird.
- Die Deduplizierung in SkuKeyBindsUpdate wurde repariert: Funktionen wie CreateMainFrame werden jetzt nur noch einmal statt ~30-mal aufgerufen.
Lokalisierung: Sockelfenster
- Alle ~20 hardcoded deutschen Strings in Build_SocketingFrame.lua durch L[]-Aufrufe ersetzt. Auf englischen Clients erscheinen nun korrekte englische Texte (Sockelfarben, Menuepunkte, Statusmeldungen).
- Kritischer Menueabgleich (child.name == "Sockeln") lokalisiert, sodass das Sockelmenue auf englischen Clients korrekt gefunden wird.
Fehlender Locale-Key
- L["Warlock"] in enUS.lua ergaenzt. Der Key war in deDE.lua vorhanden, fehlte aber in der englischen Locale-Datei.
API-Kompatibilitaet
- SetMinResize/SetMaxResize in SkuNav/SkuMM.lua durch Capability Detection ersetzt (SetResizeBounds bevorzugt, Fallback auf SetMinResize). Verhindert moegliche Fehler auf TBC Anniversary (Interface 11508).
Versionsanzeige
- Sku.toc und SkuDispatcher/Sku.toc auf v41.01.04 aktualisiert (ohne beta).
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v41.01.03 beta
Pet-Umbenennung
- ADDON_ACTION_BLOCKED behoben: Der SecureActionButton war durch einen HookScript-Handler getaintet. WoW blockierte deshalb den geschuetzten PetRename()-Aufruf. Der HookScript wurde durch PostClick ersetzt, der die sichere Macro-Ausfuehrung nicht beeintraechtigt.
- Menu-Rebuild nach Namenseingabe wiederhergestellt: Nach dem Eintippen des neuen Namens wird das Menu jetzt automatisch aktualisiert, damit der Bestaetigungseintrag sofort sichtbar ist.
Auktionshaus
- Absturz bei "Neue Auktion" behoben: Wenn ein Gegenstand im Inventar noch nicht vollstaendig im Client-Cache geladen war, fuehrte ein nil-Wert bei der Namensabfrage zum Absturz. Items ohne gecachten Namen werden jetzt uebersprungen.
Navigation
- Absturz bei Spezialaufgaben behoben: Wenn die Aufgaben-Datenbank nicht geladen war, fuehrte der Zugriff auf SkuDB.Tasks zum Absturz. Es wird jetzt vorher geprueft ob die Daten vorhanden sind.
- Gefaehrlichen Menuepunkt entfernt: Der Menuepunkt "Alle Routen und Wegpunkte loeschen" unter Navigation/Daten wurde entfernt. Er haette alle benutzerdefinierten Navigationsdaten unwiderruflich geloescht.
- Export-Funktion freigeschaltet: Unter Navigation/Daten kann die Routendaten-Kartierung jetzt als Text exportiert werden, um sie im SkuMapper-Tool zu importieren.
Wunschliste (Atlasloot)
- Audio-Feedback bei Enter repariert: Die Rueckmeldung beim Hinzufuegen/Entfernen von Wunschlisten-Items wurde von einer internen Bereinigung sofort geloescht. Die Sprachausgabe wird jetzt leicht verzoegert abgespielt, sodass sie zuverlaessig hoerbar ist.
Stabilitaet
- Nil-Guard fuer Menueposition-Name: Verhindert den Folgefehler "bad argument #1 to find (string expected, got nil)" wenn das Menue in einem ungueltigen Zustand ist.
Versionsanzeige
- Sku.toc und SkuDispatcher/Sku.toc aktualisiert auf v41.01.03 beta.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v41.01.02 beta
Fehlerbehebungen (Sound)
- Sound-Verlust behoben: Wenn das gespeicherte Profil eine Gesamt-Lautstaerke von 0 enthielt (z.B. durch beschaedigte SavedVariables), wurden beim Login alle WoW-Sound-Kanaele auf stumm gesetzt. Es gibt jetzt einen Schutz: Wird im Profil eine Gesamt-Lautstaerke von 0 erkannt, liest das Addon die aktuellen Blizzard-Einstellungen neu ein, anstatt die 0 anzuwenden.
- CVar-Reads abgesichert: Alle Lautstaerke-Abfragen beim Profil-Erststart verwenden jetzt tonumber() mit Fallback auf 100 Prozent. Falls WoW einen ungueltigen Wert zurueckgibt, wird die volle Lautstaerke verwendet statt stumm.
- Vorbestehenden CVar-Bug behoben: Drei Sound-Einstellungen (DSP-Effekte, Sound im Hintergrund, Zonenmusik ohne Verzoegerung) wurden bisher nicht korrekt an WoW uebergeben, weil durch einen Copy-Paste-Fehler immer derselbe CVar-Name verwendet wurde. Die drei Einstellungen werden jetzt korrekt angewendet.
Hinweis zur Installation
- Nach dem Kopieren des neuen Addons wird empfohlen, einmalig die Sku-SavedVariables zu loeschen. Die Datei befindet sich unter WTF/Account/ACCOUNTNAME/SavedVariables/Sku.lua im WoW-Ordner. Dadurch wird ein frisches Profil erstellt, das die korrekten Blizzard-Lautstaerken uebernimmt.
Versionsanzeige
- Sku.toc und SkuDispatcher/Sku.toc aktualisiert auf Titel/Version v41.01.02 beta.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v41.01.01 beta
Performance
- Wiki/Tutorial-Modul entfernt: Das Modul "Tutorials und Wiki" (Menuepunkt 7) wurde vollstaendig entfernt. Das spart ca. 30 MB Arbeitsspeicher (28 MB Wiki-Datenbank plus Lookup-Index) und beschleunigt den Login spuerbar, da 39.600 Zeilen weniger geparst werden muessen.
- Kein permanenter OnUpdate-Handler mehr: Der Frame-Handler, der bei jedem Wiki-Menueoeffnen lief (~60x pro Sekunde), existiert nicht mehr.
Menue
- Menuepunkt 7 ist jetzt ein Platzhalter mit dem Namen "Reserviert". Er zeigt den Hinweis "Dieser Bereich wird derzeit ueberarbeitet" an. Der Bereich wird in einer zukuenftigen Version mit neuen Inhalten befuellt.
Tastenbelegung
- Die Standard-Tastenbelegung SHIFT-F4 (Abenteuerfuehrer oeffnen) wurde entfernt, da das zugehoerige Modul nicht mehr existiert. Spieler, die die Taste manuell umbelegt hatten, muessen nichts tun — der Eintrag wird ignoriert und verursacht keinen Fehler.
Sicherheit
- Nil-Guards fuer Wiki-Referenzen: Alle Stellen im TTS-System (SkuTTS), im Optionssystem (SkuZOptions) und in der Sprachausgabe (SkuVoice), die auf Wiki-Daten zugreifen, sind jetzt mit Nil-Pruefungen abgesichert. Damit wird sichergestellt, dass keine Fehlermeldungen auftreten, obwohl die Wiki-Daten nicht mehr geladen werden.
Fehlerbehebungen
- tasks.lua (Navigations-Aufgaben fuer DK-Quests) wurde faelschlicherweise mit dem Wiki-Modul entfernt. Die Datei wurde wiederhergestellt. Behebt den Fehler "bad argument #1 to 'pairs' (table expected, got nil)" in specialNavigationTasks.lua.
Begleit-Addons
- SkuAudioData_fast_de: Interface-Version auf 11508 aktualisiert, Abhaengigkeit zu Sku hinzugefuegt. Behebt "attempt to index global 'Sku' (a nil value)".
- SkuBeaconSoundsets: Interface-Version auf 11508 aktualisiert.
- SkuCustomBeaconsAdditional: Interface-Version auf 11508 aktualisiert, Abhaengigkeiten hinzugefuegt.
- SkuCustomBeaconsEssential: Interface-Version auf 11508 aktualisiert, Abhaengigkeiten hinzugefuegt.
- Die korrigierten TOC-Dateien liegen im Ergebnisordner neben dem Sku-Ordner. Einfach in die bestehenden Addon-Ordner im Spiel kopieren.
Versionsanzeige
- Sku.toc und SkuDispatcher/Sku.toc aktualisiert auf Titel/Version v41.01.01 beta.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v40.06
Wunschliste
- Items hinzufuegen/entfernen repariert: Die Wunschliste reagiert jetzt zuverlaessig beim Hinzufuegen und Entfernen von Items. Vorher konnte die Aktion still fehlschlagen, wenn das Item noch nicht im Cache war oder der Menu-Rebuild einen Fehler ausloeste.
- Audio-Feedback: Beim Hinzufuegen eines Items wird jetzt "Auf Wunschliste gesetzt" angesagt, beim Entfernen "Von Wunschliste entfernt". Bisher gab es keinerlei Rueckmeldung.
- Cache-Fallback: Wenn ein Item beim ersten Versuch noch nicht im Client-Cache liegt, wird es automatisch angefragt und nach kurzer Verzoegerung erneut versucht.
Pet-Umbenennung
- Bestaetigung repariert: Der Zwei-Schritt-Prozess (Name eingeben, dann "Umbenennung bestaetigen" waehlen) funktioniert wieder zuverlaessig. Der fehlerhafte Menu-Rebuild nach der Namenseingabe, der den Absturz "attempt to call method 'BuildChildren' (a nil value)" ausloeste, wurde entfernt.
Stallmeister
- Drag/Drop repariert: Pet-Tausch zwischen aktivem Begleiter und Stallplaetzen nutzt jetzt macrotext im Hardware-Event-Kontext. Vorher lief der Klick im Addon-Kontext und konnte von Blizzard blockiert werden.
- Kaufpreis: Der Button "Weiteren Platz kaufen" zeigt jetzt den Preis in Gold/Silber/Kupfer an.
- Automatischer Refresh: Nach einem Pet-Tausch oder Stallplatz-Kauf wird das Stallmeister-Fenster automatisch aktualisiert (PET_STABLE_UPDATE Event).
- Event-Registrierung: PET_STABLE_SHOW, PET_STABLE_CLOSED und PET_STABLE_UPDATE werden jetzt korrekt im SkuDispatcher registriert. Die Event-Handler existierten vorher, wurden aber nie aufgerufen.
Fehlerbehebungen
- VocalizeCurrentMenuName: Nil-Guard fuer BuildChildren eingefuegt. Verhindert den generischen Absturz "attempt to call method 'BuildChildren' (a nil value)", der in mehreren Menuebereichen (Wunschliste, Pet-Umbenennung, Stallmeister) auftreten konnte.
Versionsanzeige
- Sku.toc und SkuDispatcher/Sku.toc aktualisiert auf Titel/Version v40.06.
-------------------------------------------------------------------------------------------------------
Aenderungen in Sku v40.05
Wunschliste
- Sound bei Chat-Link: Wenn ein Wunschlisten-Gegenstand im Party-, Raid-, Sag- oder Schrei-Chat verlinkt wird, ertoennt jetzt der gleiche Hinweiston wie beim Wuerfelfenster.
- Farbcodes entfernt: Dungeon-Namen und Boss-Namen aus AtlasLoot werden jetzt ohne WoW-Farbcodes (|cff...) angezeigt. Betrifft sowohl die Ansicht "Nach Dungeon" als auch den Tooltip mit Boss-Drop-Quellen.
Fehlerbehebungen
- Fehlende Locale-Eintraege: L["Up"] und L["Down"] fuer die Wunschlisten-Reihenfolge hinzugefuegt. Behebt "AceLocale-3.0: Missing entry for 'Down'" Fehler.
- Kampflog: CombatLog_OnEvent wird jetzt auf Verfuegbarkeit geprueft, bevor es aufgerufen wird. Behebt den Absturz "attempt to call global 'CombatLog_OnEvent' (a nil value)" auf TBC Anniversary.
- Gegenstandsliste: C_Item.GetItemNameByID wird jetzt mit einem Fallback abgesichert. Behebt den Absturz "attempt to concatenate a nil value" wenn ein Item noch nicht im Cache ist.
- Interaktionsdistanz: CheckInteractDistance wird jetzt per pcall aufgerufen. Behebt "ADDON_ACTION_BLOCKED CheckInteractDistance()" im Kampf.
Versionsanzeige
- Sku.toc und SkuDispatcher/Sku.toc aktualisiert auf Titel/Version v40.05.
-------------------------------------------------------------------------------------------------------
Changes in Sku v40.04.01
Atlas Loot
- Atlas Loot ist jetzt ueber Strg+Shift+L erreichbar (wenn installiert). Das Tastenkuerzel kann unter Shift+F1, Core, Skutastenbelegung frei umbelegt werden.
- Wunschliste mit Sound: Wenn ein Wunschlisten-Item im Loot erscheint, ertoennt ein Sound. Beim Erhalten des Items wird es automatisch von der Wunschliste entfernt.
- Wunschliste: Neue Menuestruktur mit zwei Untermenues "Nach Dungeon" und "Nach Slot". "Nach Dungeon" zeigt nur Dungeons, die Items auf der Wunschliste haben (Format: "Anzahl Dungeonname"). "Nach Slot" enthaelt die bisherige Slot-basierte Liste.
Ausruestungsmanager
- Der Ausruestungsmanager ist im Charakterfenster (Taste C) erreichbar. Ausruestungssets koennen gespeichert, angelegt, ueberschrieben, umbenannt und geloescht werden.
- Makro erstellen: Neuer Menueeintrag bei jedem Ausruestungsset. Erstellt ein Charaktermakro, das beim Ausfuehren das Set anlegt. Bereits vorhandene Makros werden aktualisiert.
- Lokalisierung: Alle Menue-Eintraege und Statusmeldungen des Ausruestungsmanagers sind jetzt lokalisiert. Auf englischen Clients erscheinen alle Texte auf Englisch.
Ziel-Aktionsmenue (CTRL+T) / Pet-Aktionen
- Zuruecklassen repariert: "Zuruecklassen" verwendet jetzt macrotext (/petdismiss) statt eines Addon-Kontext-Aufrufs. Dadurch wird ADDON_ACTION_FORBIDDEN vermieden und das Pet wird zuverlaessig temporaer weggeschickt.
- Umbenennen repariert: Die Pet-Umbenennung funktioniert jetzt ueber ein Zwei-Schritt-Verfahren. Schritt 1: Name eingeben. Schritt 2: "Umbenennung bestaetigen" waehlen (macrotext im Hardware-Kontext). Dadurch wird ADDON_ACTION_FORBIDDEN beim Speichern des Namens vermieden.
- Aufloesen mit Sicherheitsabfrage: "Pet aufloesen" heisst jetzt "Pet dauerhaft entlassen" und erfordert eine Bestaetigung ueber einen Sicherheitsdialog. Der bisherige Code rief PetAbandon direkt auf, was das Pet permanent entliess, ohne dass der Benutzer gewarnt wurde.
PopUp-Erkennung
- Verzoegerter Zweitaufruf: StaticPopup_Show ruft CheckFrames jetzt zusaetzlich mit 0,15 Sekunden Verzoegerung auf. Damit werden PopUps (z.B. Verzauberung ueberschreiben, Pet-Umbenennung bestaetigen) zuverlaessig im Sku-Menue angezeigt, auch wenn der PopUp-Inhalt beim ersten Aufruf noch nicht vollstaendig gesetzt ist.
Fehlerprotokoll (ErrorLog)
- Kampf-Throttling: Waehrend des Kampfes werden maximal 5 Fehler pro Sekunde protokolliert. Ueberzaehlige Fehler werden verworfen. Die BugGrabber-Bridge wird im Kampf vollstaendig pausiert. Dadurch wird die Fehlermeldung "insecure scripts exceeded execution limit" in Raids (z.B. Karazhan, AQ40) vermieden.
- Lokalisierung: Alle Slash-Befehl-Hilfe und Statusmeldungen sind jetzt lokalisiert.
Lokalisierung
- Rund 70 neue L[]-Eintraege in beiden Locale-Dateien (AL_*, EQ_*, ERRLOG_*, MOB_*).
- Hardcoded deutsche Strings in alIntegration.lua, equipmentSets.lua und ErrorLog.lua durch L[]-Aufrufe ersetzt.
- equipmentSets.lua: Fehlerhaftes Locale-System (SkuLocale) durch Sku.L ersetzt.
Versionsanzeige
- Sku.toc und SkuDispatcher/Sku.toc auf Title/Version v40.04.01 aktualisiert.
-------------------------------------------------------------------------------------------------------
Changes in Sku v40.04
Dungeon-Browser
- Lokalisierung: Alle Menue-Eintraege des Dungeon-Browsers (Rollen, Status, Dungeon-Liste, Spielerliste, Aktionen) verwenden jetzt das Lokalisierungssystem. Auf englischen Clients erscheinen alle Texte korrekt auf Englisch.
- Heroische Dungeons: Der Dungeon-Browser zeigt jetzt auch heroische Dungeons an. Diese erscheinen in einer eigenen Sektion unterhalb der normalen Dungeons mit dem Praefix "Heroisch: " vor dem Namen. Heroische Dungeons koennen wie normale Dungeons ausgewaehlt und angemeldet werden.
- Tastenkuerzel: Der Dungeon-Browser hat jetzt ein eigenes Tastenkuerzel unter Shift+F1, Core, Skutastenbelegung, Taste zuweisen, "Dungeon Browser oeffnen". Standard ist keine Taste belegt; der User kann frei zuweisen.
- Alle abwaehlen: Neuer Button "Alle abwaehlen" im Dungeon-Browser. Setzt alle Dungeon-Auswahlen auf einmal zurueck.
- Anzeige: Der Hinweis "Ausgewaehlt" wird jetzt vor den Dungeon-Namen gesetzt (statt dahinter), damit blinde Spieler beim Durchblaettern sofort hoeren, ob ein Dungeon bereits markiert ist.
- Technisch: ~39 neue L[]-Eintraege (DB_*) in beiden Locale-Dateien. Hardcoded Strings in dungeonBrowser.lua durch L[]-Aufrufe ersetzt. Zwei "not info.isHeroic"-Filter entfernt (tGetEligibleDungeons und tBuildPhaseB). Heroische Dungeons werden in Phase A als eigene Sektion mit L["DB_HeroicSection"] dargestellt. SKU_KEY_OPENDUNGEONBROWSER in SkuKeyBinds.lua definiert, Handler und Override-Binding in SkuZOptions/Core.lua. DungeonBrowserDeselectAll() setzt db.selection = {} und triggert Menu-Rebuild.
Navigation / Nahe Route
- Bugfix: "Nahe Route" bricht nicht mehr nach dem ersten Wegpunkt ab. Die Navigation ueber "Nahe Route" (im Questbuch und im SkuNav-Menue) wurde nach Erreichen des ersten Wegpunkts faelschlicherweise mit "Route folgen beendet" abgebrochen, anstatt zum Ziel weiterzufuehren. Dieser Fehler trat zonenuebergreifend auf und betraf alle Nahe-Route-Navigationen. Das Problem ist behoben -- Nahe Routen fuehren nun zuverlaessig bis zum Ziel.
- Technisch: Die BuildChildren der "Closest route"-Handler in SkuQuest/Options.lua (Zeilen 1101ff) und SkuNav/Options.lua (Zeilen 447ff) verwendeten eine flache Struktur, die metapathFollowingStart und metapathFollowingMetapaths einmalig fuer den ersten Einstiegspunkt setzte. Der bereits korrigierte "Route"-Handler setzte in seinen Per-Entry-Point-Submenues metapathFollowingTarget = nil, was bei Menue-Navigation zwischen Geschwistern die Nahe-Route-Daten zerstoerte. Fix: Gleiche Umstrukturierung auf Per-Entry-Point-Submenues wie beim "Route"-Handler -- jeder Einstiegspunkt berechnet seine eigenen Metapaths in seiner eigenen BuildChildren-Funktion.
Chat-Einladung
- Bugfix: Die Einladungsfunktion im Chat-Kontextmenue (CTRL+Enter) funktioniert wieder. Bisher konnte ein Fehler auftreten, wenn InviteUnit als globale Funktion nicht verfuegbar war.
- Technisch: SkuChat/Core.lua Zeile 2688: InviteUnit() durch C_PartyInfo.InviteUnit()-Fallback ersetzt (gleicher Pattern wie in SkuMob/Options.lua).
Ziel-Aktionsmenue (CTRL+T)
- Pet-Aktionen erweitert: Zwei neue Eintraege im Pet-Untermenue. "Zuruecklassen" schickt das Pet temporaer weg (es kann jederzeit wieder gerufen werden). "Umbenennen" oeffnet ein Eingabefeld, in dem ein neuer Name eingegeben und mit Eingabetaste bestaetigt werden kann.
- Lokalisierung: Alle Eintraege des Ziel-Aktionsmenues (Untersuchen, Folgen, Handeln, Duell, Fluestern, Einladen, Freund hinzufuegen, Ignorieren, Anfuehrer uebergeben, Entfernen, Pet-Aktionen, Pet-Modus, Raid-Markierungen, Spieler melden, Pluendermethode, Instanzen zuruecksetzen, Gruppe verlassen) sind jetzt lokalisiert. Auf englischen Clients erscheinen alle Texte auf Englisch.
- Technisch: SkuMob/Options.lua: ~78 neue L[]-Eintraege (MOB_*) in beiden Locale-Dateien. Alle hardcoded Strings in tRaidMarkers, tReportReasons, tLootMethods, tBuildPetModeSubmenu und tBuildTargetMenu durch L[]-Aufrufe ersetzt. PetDismiss (nur temporaer) und PetRename (ueber EditBoxPasteShow) als neue tAddAction-Eintraege im tIsPet-Zweig.
Charakterfenster (Equipment-Slots)
- Bugfix: Wizard Oil, Gifte und Schleifsteine koennen jetzt ueber das Sku-Menue auf ausgeruestete Waffen angewendet werden, ohne ADDON_ACTION_FORBIDDEN-Fehler. Bisher wurde der Klick auf Equipment-Slots aus dem Addon-Kontext ausgefuehrt, was von Blizzard blockiert wurde.
- Technisch: SkuZOptions/Core.lua Zeile 3958: Equipment-Slot-Linksklick verwendet jetzt macrotext ("/click SlotName LeftButton") statt reinem OnAction mit PickupInventoryItem. Dadurch laeuft der Klick im Hardware-Event-Kontext und Blizzard erlaubt die Interaktion. Der bisherige OnAction-Code bleibt als Fallback erhalten.
Rollenabfrage
- Bugfix: Die manuelle Rollenabfrage (Tank/Heiler/Schaden) verursacht keinen Absturz mehr. Bisher konnte ein Fehler auftreten, wenn die Rollenbuttons keine .role-Eigenschaft hatten, was zu einem nil-Fehler fuehrte und einen Reload erforderte.
- Technisch: SkuCore/LocalMenu.lua Zeile 2026: Nil-Guard und Fallback-Rollennamen (TANK/HEALER/DAMAGER) eingefuegt. tButtons[x] wird zusaetzlich auf Existenz geprueft.
Aura-Export
- Bugfix: "Alle Auren exportieren" funktioniert wieder und wirft keinen Fehler mehr. Die Funktion GetAddOnMetadata war in neueren WoW-Versionen nicht verfuegbar und verursachte beim Export einen Absturz.
- Technisch: SkuAuras/Options.lua Zeile 812: GetAddOnMetadata durch sicheren Fallback-Pattern ersetzt (GetAddOnMetadata oder C_AddOns.GetAddOnMetadata, mit "unknown" als letztem Fallback). Gleicher Fix auch in SkuZOptions/Core.lua Zeile 5252 (Wegpunkt-Export).
/sku version Befehl
- Bugfix: Der Chat-Befehl "/sku version" gibt jetzt zuverlaessig die Addon-Version aus. Bisher konnte die Ausgabe leer bleiben, wenn GetAddOnInfo nicht verfuegbar war.
- Technisch: SkuZOptions/Core.lua Zeile 128: GetAddOnInfo durch sicheren GetAddOnMetadata-Fallback ergaenzt (gleicher Pattern wie ErrorLog.lua). Ausgabe zeigt jetzt Titel und Versionsnummer.
Minimap-Ressourcen-Scan
- Bugfix: Die passive Minimap-Ueberwachung (Erz, Kraeuter, etc.) faengt keine Mausklicks mehr ab. Bisher konnte beim Klicken an verschiedenen Stellen im Addon ein "Ping"-Geraeusch ertoennen und der Klick wurde nicht ausgefuehrt, weil die unsichtbare 1-Pixel-Minimap unter dem Cursor Klicks abgefangen hat.
- Technisch: SkuCore/minimapScanner.lua: In MinimapScanFast() werden jetzt vor dem Positionieren der Minimap unter den Cursor alle sichtbaren Minimap-Kinder (insbesondere MiniMapTrackingFrame) versteckt. Schutz portiert aus Version 1.x (Zeilen 479-484). RestoreMinimap stellt die Kinder per MMA_VISIBLE wieder her.
- Bugfix: Kraeutersuche, Bergbau und weitere Tracking-Funktionen funktionieren jetzt korrekt mit dem passiven Minimap-Scan. Bisher wurde der Tracking-Zustand bei jedem Scan-Durchlauf deaktiviert und konnte nicht wiederhergestellt werden, weil die C_Minimap.GetTrackingInfo-Rueckgabe (Tabelle statt Einzelwerte) falsch entpackt wurde. Kraeuter und Erze erschienen nicht mehr auf der Minimap, obwohl der Buff-Balken die Suche als aktiv anzeigte.
- Technisch: GetTrackingInfo-Aufrufe in tCaptureMinimapState() und in der Tracking-Disable-Schleife von MinimapScanFast() verwenden jetzt den gleichen type(result)=="table"-Check wie SlashActiveSeekings und SkuZOptions/Core.lua. tCaptureMinimapState/tApplyMinimapState sichern und stellen den Tracking-Zustand korrekt wieder her.
- Bugfix: Der passive Minimap-Scan kuendigt Kraeuter, Erze und andere Ressourcen beim Laufen jetzt wieder per Sprache an. Bisher blieb die Ansage aus, weil die Tooltip-Auswertung im passiven Scan-Pfad die Ressourcennamen nie korrekt erkennen konnte -- die Matching-Logik verwendete exakte Gleichheit statt Teilstring-Suche und konnte bei Sonderzeichen (Apostrophe in "Khadgar's Whisker" etc.) oder fehlenden Abhaengigkeiten den Tooltip-Text nicht zuordnen.
- Technisch: C_Timer.After-Callback in MinimapScanFast() verwendet jetzt denselben string.find-Substring-Match wie der aktive Scan (MinimapScanFindActiveRessource). SkuChat:Unescape wird optional genutzt, blockiert aber nicht mehr die Verarbeitung. gmatch-Fragmentierung und exakte Gleichheitspruefung entfernt.
Versionsanzeige
- Sku.toc und SkuDispatcher/Sku.toc auf Title/Version v40.04 aktualisiert.
-------------------------------------------------------------------------------------------------------
Changes in Sku v40.03y
Briefkasten
- Mehrfach-Anhaenge: nach dem Entnehmen eines einzelnen Anhangs werden die verbleibenden Anhaenge im selben Brief wieder zuverlaessig per Sapi vorgelesen. Auto-Jump-Pfad entfernt -- der Briefkasten nutzt jetzt wieder den Standard-Refresh (MAIL_INBOX_UPDATE, currentMenuPosition:OnUpdate), exakt wie beim physischen Wieder-Oeffnen des Briefkastens.
Atlas Loot
- Tastenkuerzel zum Oeffnen frei umbelegbar: unter Shift+F1, Core, Skutastenbelegung, Taste zuweisen erscheint jetzt der Eintrag "Atlas Loot oeffnen". Die Standardtaste bleibt Strg+Shift+L; der User kann sie aber wie alle anderen Sku-Tastenkuerzel auf eine eigene Kombination umlegen. Die neue Belegung wird sofort wirksam.
- Zielorientierter Sprung in Boss-/Instanz-Submenue deutlich verbessert:
Pfad-Reihenfolge entspricht jetzt exakt der Menue-Hierarchie (Listen, Plugin, Erweiterung, Gruppe, Instanz/Raid, Boss, Schwierigkeit, Items). Die Schwierigkeitsstufe wurde vorher faelschlich vor die Instanz gesetzt -- Pfad konnte nie aufgeloest werden.
Schwierigkeits-Erkennung dreifach abgesichert: primaer GetInstanceInfo, sekundaer die Charakterportrait-Einstellung (GetDungeonDifficulty / GetRaidDifficulty -- wird beim Betreten der Instanz festgenagelt und ist daher zuverlaessig), tertiaer Default "Normal" fuer Welt-Bosse.
Lookup-Tabellen werden jetzt bereits beim Login (mit gestaffelten Retries 5/10/20/35/60 s) und bei Zonenwechsel ins Instanz-Innere vorbefuellt. Damit ist der Sprung beim ersten Tastendruck ohne Latenz nutzbar.
- Wunschlisten-Auto-Remove: sobald der "I feel Good"-Sound spielt (Wunschlisten-Item ist im Inventar gelandet), wird das Item automatisch aus allen Wunschlisten-Slots entfernt. Vergleich primaer per itemID, mit Hyperlink-Pattern als Fallback. Items wie Ringe oder Schmuckstuecke, die in zwei Slots gleichzeitig stehen koennen, werden vollstaendig abgeraeumt.
Charakterfenster (Equipment-Slots)
- Linksklick / Rechtsklick auf ausgeruestete Items funktioniert wieder. Auf TBC-Anniversary 2.5.5 ruft /click LeftButton ohne Modifier-Taste nur UseInventoryItem auf -- wirkungslos fuer Ruestung, Ringe und Schmuckstuecke. Sku nutzt fuer Equipment-Slots jetzt den direkten API-Pfad:
Linksklick: PickupInventoryItem(slotID) -- Item heftet sich an den Cursor (zum Umsetzen, Verkaufen oder Abstecken).
Rechtsklick: ausziehen -- PickupInventoryItem + Iteration ueber die Taschen, erstes freies Fach, PickupContainerItem. Bei vollen Taschen Cursor leeren und Sapi-Hinweis "Keine Tasche frei". Bei leerem Slot Sapi-Hinweis "Leer".
Dungeon-Browser
- Auto-Refresh entfernt: die Spielerliste wird nicht mehr automatisch alle 10 Sekunden aktualisiert. Der bisherige Ticker griff faelschlich auf alle Sku-Menues durch (currentMenuPosition:OnUpdate unabhaengig vom aktuellen Menue-Pfad) und unterbrach Ansagen in komplett unbeteiligten Untermenues.
- Manueller "Liste aktualisieren"-Button: loest /who-Suche aus und rebuildet das Dungeon-Browser-Menue gezielt nach 0,6 s. Cross-Menue-Schutz: wenn der User in der Zwischenzeit wegnavigiert ist, passiert nichts.
- Sapi-Feedback nach erfolgreichem Refresh: "Aktualisiert. N Spieler gefunden" (oder "Keine Spieler gefunden" / "1 Spieler gefunden"). Wird zeitversetzt nach der OnUpdate-Vokalisierung abgesetzt, damit die Status-Ansage nicht unterdrueckt wird.
- Phasenwechsel A nach B (Anmeldung): zwei zeitversetzte Paesse -- erster Pass mit Sapi-Ansage des neuen Status, zweiter Pass stumm im Hintergrund (DungeonBrowserRebuildSilent), um die per /who eingelaufenen Spieler nachzuziehen. Status-Ansage laeuft jetzt vollstaendig durch, und die Spielerliste ist trotzdem sofort gefuellt.
- Phasenwechsel B nach A (Abmeldung): Doppel-Rebuild auf einen reduziert; Sapi-Ansage wird nicht mehr abgeschnitten.
- Verhalten bei Gruppeneinladung: Sku-Menue bleibt waehrend eines offenen Einladungs-Popups offen. Skus Standard-Pfad fokussiert das Popup, der User kann direkt mit Ja/Nein interagieren. Bei Annehmen schliesst Blizzard das Container-Frame automatisch -- Sku-Menue folgt und schliesst sich. Bei Ablehnen bleibt das Container-Frame stehen und das Sku-Menue ebenfalls.
Stabilitaet / Quest-Tooltip
- Crash beim Quest-Tooltip-Aufruf (Shift+Pfeil-Runter) im Schattenmondtal behoben. Ursache: tInternalChannelName konnte in CHAT_MSG_CHANNEL_NOTICE/YOU_LEFT nil werden (zonen-spezifischer Channel ohne Mapping), string.lower(nil) crashte. Der nachfolgende Lua-Error riss den currentMenuPosition-Pointer mit sich, wodurch alle weiteren Pfeil-/Enter-Tastendrucke mit "attempt to index nil" kaskadierten -- Sku-Menue blieb bis zum Reload unbedienbar.
- Drei zusammenwirkende Schutzschichten:
1. Direkter nil-Guard in SkuChat/Core.lua vor dem string.lower-Aufruf.
2. Defensiver nil-Schutz im SkuGenericMenuItem-OnUpdate (templates.lua) fuer currentMenuPosition:OnEnter / VocalizeCurrentMenuName.
3. Recovery-Guard im OnClick-Key-Dispatcher: bei nil-currentMenuPosition wird Menu[1] als Fallback gesetzt, andernfalls der Tastendruck still verworfen -- kein Crash-Spam mehr.
Versionsanzeige
- Sku.toc und SkuDispatcher/Sku.toc auf Title/Version v40.03y aktualisiert.
-------------------------------------------------------------------------------------------------------