Plany były większe, ale weekend zszedł mi na dość się prostej rzeczy. Przynajmniej tak do tego poszedłem na początku i srogo się zdziwiłem komplikacją.
Mianowicie jak prawidłowo obsłużyć dwie listy rozwijalne tak, aby wybrane elementy z listy A nie były dostępne do wyboru w liście B i vice versa. Jak łatwo się domyślić (i o ile czytelniku znasz zasady kryształów czasu) chodziło o wybór profesji dla postaci dwuprofesyjnej. Nikt przecież nie chce grać Wojownikiem-Wojownikiem 😊
Cel
- jak chcemy mieć tylko postać jednoprofesyjną to wszystkie opcje powinny być dostępne
- jak wybieramy opcję postaci dwuprofesyjnej to w ramach listy dla drugiej profesji do wyboru nie może być dostępna aktualna wybrana profesja z listy pierwszej
- jak zmieniamy selekcję w liście z pierwszej (lub odpowiednio drugiej) listy to opcje muszą się na przemian blokować czyli opcja A z listy pierwszej profesji nie może być dostępna w liście drugiej profesji i oczywiście odwrotnie
- zmiana selekcji powoduje odpowiednie odblokowania / blokady w obu listach
- jak zamykamy listę drugiej profesji musza być możliwe do wyboru wszystkie opcje dla listy pierwszej profesji
- powinny odpowiednio zmieniać się etykiety na ekranie
- podobnie etykiety poziomów, które teraz sprzęgnięte są z wyborem profesji
Doprowadzenie kodu do działania zajęło nadzwyczaj dużo czasu, a powodem tego była nieznajomość … powiedzmy, że API stojącym za listami rozwijalnymi godot czyli obiektami OptionButton. Cała trudność polegała na prawidłowym obsługiwaniu kolekcji, która trzyma w sobie definicje poszczególnych elementów listy rozwijalnej czyli tzw. popup. Zanim to zrozumiałem wsparłem się copilotem (wypluł trochę bzdur) oraz zwykłym – mozolnym – testowaniem co się stanie gdy ustawię opcję tak albo śmak. I powoli, powoli udało się.
Efekt pracy
Stan startowy - jedna profesja |
A tutaj już widać wybór profesji. Jak widać pogrupowane są per typ. Jak uzyskać jakieś ikonki niżej. |
Wybieramy drugą profesję i ładuje się druga lista. |
Profesja Hunter nie jest dostępna w drugiej liście do wyboru ponieważ wybrano ją w liście pierwszej. |
I odpowiednio profesja Knight wybrana w drugiej liście blokuję wybór w liście pierwszej. |
Po zamknięciu listy drugiej profesji i zdjęciu checkboxa że tworzymy postać dwuprofesyjną ponownie wszystkie opcje dostępne. |
Jak widać na zrzucie jest jeszcze jakiś błąd z tym, że czasem odblokowuje się nagłówek grupy, ale ... to poprawie przy okazji.
Co do kodu
Cała magia z podstawowym blokowaniem list opierała się na poprawnym przekazaniu selekcji między listami i ich ciągłe odświeżanie.
Kłopotem okazało się przekazanie, które elementy są nagłówkiem listy grupującym elementy oraz co zawierają poszczególne wiersze tak żeby nie opierać się na zawartości textowej wybranej opcji. Na potrzeby przekazania do generatora chciałbym wiedzieć czy coś jest Grupą Rycerz - Profesja Paladyn czy czymkolwiek innym. Stąd powstał obiekt opakowujący każdą opcję i do niej przypisany. Żeby był możliwy do użycia w kontolce silnika musi rozszerzać typ dla Variant, a najłatwiej po prostu Node
Tenże obiek wpinany był w każdą opcję z użyciem dostępnej dla wierszy listy rozwijalnej metody .SetItemMetadata
Poniżej ustawienie dla nagłówka grupy:
Dla wiersza z profesją dane wstawiane były identycznie (tylko zmieniał się zakres) ponieważ najpierw wczytaną z json kolekcję profesji grupowałem, tworzyłem obiekty ProfessionMetadata per profesja i przypisywałem do wierszy listy rozwijalnej.
A teraz cała funkcja budująca opcje dla podanej grupy profesji (i tak wiem ifologia dla ikon powinna zniknąć a ikonka powinna pochodzić z konfiguracji jsona. Się to kiedyś zrefaktoruje)
I są jeszcze dwie metody wspierające przywracanie dostępności poszczególnych opcji per zmiana czy tworzymy jedno czy dwu-profesyjną postać, ale jako, że jest w nich jeszcze błąd czyli to nieszczęsne odblokowywanie nagłówków, to nie pokazuję. :)
Z rzeczy, które trzeba będzie dodać to brakuje wykluczenia profesji, aby nie wybrać np. paladyna-złodzieja, jednakże ten filtr będzie już taką wisienką na torcie jak cała funkcja będzie mi działać bez błędów.
p.s
Dorzuciłem w międzyczasie sporo konfiguracji do jsonów jak np. listy broni czy zbroi.