Ranking
Popularna zawartość
Treść z najwyższą reputacją w 06/21/24 uwzględniając wszystkie działy
-
Działa. Nie wiem jak mam Panu dziękować. Przede wszystkim jestem zszokowany poziomem Pana wiedzy, na prawdę Dziękuję najmocniej. Co do umierania zombie po wyjściu gracza z serwera - tak jak Pan mówi, Skript zamienia informację o online player na offline player. Normalnie dodaje się wartość do zmiennej gracza nawet po wyjściu z serwera. Dziękuję bardzo jeszcze raz. Pozdrawiam serdecznie1 punkt
-
Z początku myślałem, że Pan może mieć jakiś problem ze Skriptem, ale sprawdziłem przed chwilą działanie wyrażenia 'last attacker of %entity%'. Rzeczywiście jest tak jak Pan mówi - w przypadku śmierci od obrażeń innych niż zadane bezpośrednio przez dowolny byt, wyrażenie te zwraca "<none>". Sprawdziłem kod źródłowy Skripta i dowiedziałem się kilku ciekawych rzeczy. https://github.com/SkriptLang/Skript/blob/7fc699e17299763523942d99524216480d426295/src/main/java/ch/njol/skript/expressions/ExprLastAttacker.java#L59 Warto zwrócić uwagę na użycie metody 'getLastDamageCause()', która (jak nazwa wskazuje) zwraca przyczynę ostatnio zadanych obrażeń, a właściwie to całe zdarzenie, które było powiązane z zadanymi ostatnio obrażeniami. Co więcej, poniższa klasa odpowiedzialna za wyrażenie 'attacker' przewiduje jedynie zdarzenie 'EntityDamageByEntityEvent'. Nawet kod od zdarzenia 'EntityDamageByBlockEvent' (np. gdy dozownik trafi w zombie strzałą) jest objęty komentarzem, a więc w przypadku śmierci od strzały wystrzelonej z dozownika również uświadczylibyśmy na czacie '<none>'. https://github.com/SkriptLang/Skript/blob/7fc699e17299763523942d99524216480d426295/src/main/java/ch/njol/skript/expressions/ExprAttacker.java#L78 Na końcu metody 'get()' w klasie ExprAttacker można zauważyć 'return null'. Ponieważ obrażenia od ognia nie są przewidziane w żadnym z warunków tej metody, otrzymujemy w rezultacie niemiło widziane '<none>'. Skoro już poznaliśmy źródło nieporozumienia, podpowiem Panu jak można rozwiązać ten problem. W mojej ocenie najprostszym wyjściem z tej sytuacji będzie użycie 'metadata'. Jak dokumentacja mówi, są to informacje przechowywane w rozmaitych metadata holderach (byty, bloki, itd.) do momentu restartu serwera, ale na Pana potrzeby wydaje mi się, że to będzie wystarczające. No dobrze, jak więc użyć metadata w Pana przypadku? Jest to bardzo proste. Dla przykładu ustawimy wartość metadata "lastAttacker" jako byt, który był odpowiedzialny za zadanie obrażeń. Następnie, będziemy mogli odczytywać jej wartość gdy będzie to potrzebne. Pokażę na przykładzie poniżej. W listenerze zdarzenia 'on damage' należy sprawdzić czy atakujący jest graczem. Jeśli tak, ustawiamy wartość znacznika (tagu) metadata "lastAttacker" na atakującego (w tym przypadku wiemy, że to jest gracz, ponieważ zweryfikowaliśmy to warunkiem w linijce powyżej). # [...] attacker is a player set metadata tag "lastAttacker" of victim to attacker # [...] Następnie, w listenerze zdarzenia 'on death of a zombie' sprawdzamy czy metadata tag "lastAttacker" posiada wartość (warunek 'is set'). Możemy to zrobić bezpośrednio, albo też możemy zapisać jej wartość do zmiennej i sprawdzić czy zmienna przechowuje jakąkolwiek wartość. Ja pokażę drugi sposób, gdyż jest schludniejszy - unikamy podwójnego użycia tego samego wyrażenia. # [...] set {_player} to metadata tag "lastAttacker" of victim {_player} is set # [...] Jeżeli warunek w powyższym fragmencie kodu zostanie spełniony, możemy być pewni, że ofiara posiada zapisaną w sobie informację o ostatnio atakującym graczu. Wystarczy wtedy użyć 'uuid of {_player}' i wszystko powinno być działać jak należy. Oczywiście może Pan rozszerzyć działanie powyższych kodów na wszystkie byty tak, aby na przykład owca zapisywała informację o tym, że wilk ją zaatakował. Wtedy kod nieco się skomplikuje i niewykluczone, że trzeba będzie użyć więcej metadata tagów. Zastanawiające jest jedynie to co jeśli zombie umrze po wyjściu gracza z serwera. Co prawda Skript w tej sytuacji powinien "przemianować" zapisaną informację o online player na informację o offline player. Warto jednak to przetestować, chociaż tę kwestię myślę, że mogę pozostawić Panu do własnego wglądu. Gdyby jeszcze miał Pan jakieś pytania lub wątpliwości, śmiało. Pozdrawiam.1 punkt
-
No dobrze, już podpowiadam. Problem z użyciem tego wyrażenia jest taki, ze zwracana przez nie wartość jest typu 'Object', a więc może to być tak właściwie wszystko. Wynika to z faktu, iż ostatnio atakującym może być dowolny byt, a nawet blok, na przykład dozownik (ang. dispenser), który wystrzeliwuje strzały. Bezpieczniejszą opcją będzie zamiana wartości wyrażenia 'last attacker of %entity%' na typ tekstowy, aby później nakazać Skriptowi interpretację go jako gracza offline. Dlaczego gracz offline, a nie online? Powody ku temu są dwa: Gracz może wyjść z serwera zanim zombie umrze. Może tak być w przypadku nadania efektu obumierania, podpalenia, itd. Powód mniej oczywisty to to, że wyrażenie '%string% parsed as player' ma pewną mało znaną, a znaczącą wadę. W przypadku parse'owania jako gracza online wystarczy początek nazwy gracza, aby Skript "wygenerował" nam obiekt gracza. Natomiast jeśli używamy '[...] parsed as offline player', musimy podać dokładnie nazwę gracza. Podam przykład wykorzystujący moją nazwę. "Kormic" parsed as player # Zwróci obiekt gracza o nazwie "Kormic", o ile jest on na serwerze "Kor" parsed as player # Zwróci obiekt gracza o nazwie "Kormic", o ile jest on na serwerze "Kormic" parsed as offline player # Zwróci obiekt gracza o nazwie "Kormic" niezależnie od tego czy jest i był kiedykolwiek na serwerze "Kor" parsed as offline player # Zwróci obiekt gracza o nazwie "Kor" niezależnie od tego czy jest i był kiedykolwiek na serwerze W tej sytuacji pojawia się pytanie "Co jeśli poprosimy o obiekt gracza online o nazwie "Kor", podczas gdy na serwerze są gracze "Kor" i "Kormic"? Którego gracza otrzymamy?". Dlatego też w mojej ocenie bezpieczniejszy jest 'parsed as offline player', bo musimy podać dokładną nazwę. Poniżej udostępniam Panu fragment kodu, dzięki któremu w zmiennej {_player} przechowywany jest obiekt gracza offline (offline - może, ale nie musi być online). Wtedy wystarczy użyć 'uuid of {_player}' tam gdzie trzeba. # [...] last attacker of victim is a player set {_player} to "%last attacker of victim%" parsed as offline player # [...] Alternatywnie, można spróbować jak poniżej. Nie mam pewności czy poniższy sposób zadziała poprawnie, ale spróbować nie zaszkodzi. # [...] last attacker of victim is a player set {_uuid} to uuid of last attacker of victim # [...] Pozdrawiam.1 punkt
-
Najprościej będzie to rozwiązać za pomocą wyrażenia 'last attacker of %entity%'. Należy mieć na uwadze to, że te wyrażenie zwróci nazwę gracza, nie jego UUID. Dodam, że powinien Pan sprawdzać na początku listeneru zdarzenia czy ostatnio atakujący byt jest graczem. Dzięki temu unikamy zapisu zmiennych dla bytów innych niż gracze (wszystkie byty (nawet przedmioty) posiadają UUID, chociaż głównie należy martwić się tutaj żywymi bytami), na przykład żelazne golemy czy szkielety. One też jak najbardziej są w stanie zabić zombie. on death of a zombie: last attacker of victim is a player # Dalszy kod... Oczywiście może (i myślę, że byłoby wskazane) sprawdzanie czasu od ostatniego uderzenia, ale samo użycie powyższego wyrażenia do podstawowych zastosowań jest wystarczające. Gdyby jednak Pan potrzebował coś takiego, mogę zaproponować jak można taki kod napisać. Pozdrawiam.1 punkt
Ten Ranking jest ustawiony na Warszawa/GMT+02:00
-
Najwięcej postów w tygodniu
-
Najwięcej tematów w tygodniu
-
Aktywni użytkownicy
Nikt jeszcze nie otrzymał reputacji w tym tygodniu.
