Tworzenie scenariuszy – cz. 4.
Akcje pośrednie i ich znaczenie:
W tym tutorialu zajmiemy się działaniami, których nie widać za bardzo w grze, ale które mają ogromne dla jej przebiegu znaczenie, mianowicie mowa tu o akcjach pośrednich.
Akcje pośrednie dotyczą głównie 2 rodzajów czynności – tworzenia/modyfikacji zmiennych oraz gromadzenia danych o aktualnym stanie gry na użytek scenariusza. Brzmi trochę strasznie ale tak naprawdę jest to bardzo proste :)
Zanim przejdziemy to omówienia akcji pośrednich, musimy zrozumieć, czym tak naprawdę są zmienne i do czego służą.
Zmienne (ang. variables):
Zmienne to nic innego jak… niewidzialne pudełka, w których można umieścić dane. Możemy sobie takie pudełko stworzyć, umieścić w nim jakieś informacje i w razie kiedy będą nam potrzebne, otworzyć pudełko i pobrać te informacje.
Zmienne dają nam ogromne możliwości tworzenia i kontrolowania scenariuszy. Przy użyciu zmiennych możemy zapamiętywać wybory naszego bohatera w całej kampanii i dostosowywać jej dalszy przebieg w zależności od podjętych decyzji, liczyć tury od określonego momentu, mnożyć, dzielić, odejmować wyniki a nawet możemy tworzyć nowe tryby rozgrywki, w których, np. wygrywa ten, który pierwszy zgromadzi odpowiednią ilość złota, albo zrekrutuje odpowiednią ilość określonych jednostek.
Tworzenie/modyfikacja/usuwanie zmiennych:
Tworzenie:
Aby szybko stworzyć zmienną i przypisać jej jakąś wartość korzystamy z prostego makra:
{VARIABLE nazwa_zmiennej wartość}
a więc jeśli chcemy utworzyć zmienną o nazwie „punkty” i przypisać jej wartość „0” to makro będzie wyglądało tak:
{VARIABLE punkty 0}
Do zmiennych oprócz liczb możemy przypisywać również dane tekstowe, np.:
{VARIABLE aktywny_towarzysz Fineas}
Modyfikacja:
Jeśli już istnieje zmienna o takiej nazwie to jej wartość zostanie zastąpiona. Warto o tym pamiętać.
Jeśli chcemy dodać do zmiennej jakąś wartość, albo odjąć, pomnożyć, podzielić a nawet wydobyć resztę z dzielenia to korzystamy z prostego makra:
{VARIABLE_OP nazwa_zmiennej działanie wartość}
W miejscu działanie piszemy nazwę działania, a więc:
dodawanie – add
odejmowanie – sub
mnożenie – mulitply
dzielenie – divide
reszta z dzielenia - modulo
Załóżmy, że chcemy do zmiennej punkty dodać wartość „5”. Robimy to w ten sposób:
{VARIABLE_OP punkty add 5}
Usuwanie:
Jeśli chcemy pozbyć się jakiejś zmiennej to korzystamy z prostego makra:
{CLEAR_VARIABLE nazwa_zmiennej}
Pobieranie danych ze zmiennych:
Znamy już podstawowe działania na zmiennych. Potrafimy je stworzyć, nadać wartość modyfikować i usuwać, ale jak pobrać informację z takiego „pudełka”?
Posłużmy się przykładem zmiennej „punkty”. Przypisaliśmy do niej wartość „0”. Aby pobrać to zero z naszego „pudełka” używamy znaczka dolara „$” a po nim piszemy nazwę zmiennej. Gra wtedy zastąpi takie wyrażenie wartością zmiennej. A więc pisząc: $punkty, gra zamieni to na aktualną wartość zmiennej punkty.
Załóżmy, że chcemy, aby co turę nasz bohater mówił ile aktualnie ma punktów. Tworzymy więc event name=turn, ustawiamy first_time_only=no (aby wywoływał się co turę) i tworzymy komunikat od naszego bohatera:
|
[message]
speaker=id_bohatera
message = _ „Moja ilosc punktow to $punkty”
[/message]
|
W trakcie gry bohater oczywiście będzie mówił coś w stylu: „Moja ilosc punktow to 0”. Wraz z dodawaniem do zmiennej punkty nowych wartości, bohater automatycznie będzie mówił najnowszą aktualną wartość.
Pobieranie danych najczęściej ma jednak miejsce w przypadku sprawdzania ich wartości wewnątrz warunków, np. sprawdzanie co turę ilości punktów i jeśli któryś z graczy ma określony wynik zakończenie gry lub aktywowanie innych działań, ale o tym później.
Rodzaje zmiennych:
Istnieją 3 rodzaje zmiennych w WML, które istnieją również w innych językach programowania. Oto one:
Skalar:
To najprostszy typ zmiennej, który już poznaliśmy. Jedna zmienna typu skalarnego może przyjmować tylko jedną wartość.
Kontener:
Zmienna ta składa się z wielu skalarów. Najlepiej wyobrazić to sobie jako kontener pełen pudełek. Otwierając taki kontener musimy wskazać, które pudełko nas interesuje i dopiero wtedy da się podejrzeć jego wartość.
Dobrym przykładem jest, np. sprawdzenie ilości punktów życia u jednostki pierwszorzędnej aktywującej event. Wystarczy wtedy napisać $unit.hitpoints i to nam zwróci ile hp ma ta jednostka. Unit to kontener, a hitpoints skalar z określoną wartością.
Tablica (array):
To zmienna, która posiada wiele kontenerów. Przykładami tablic są zmienne, w których przechowujemy jednostki, ale o tym później.
Tablicę tworzymy korzystając z tagu [set_variables], np.:
|
[set_variable]
name=moja_tablica
[value]
x=10
[/value]
[value]
x=12
[/value]
[value]
x=14
[/value]
[/set_variable]
|
W ten sposób utworzyliśmy tablicę z 3 kontenerami, każdy ze skalarem o nazwie x, który ma przypisany jakąś wartość.
Aby dostać się do powiedzmy drugiego kontenera i jego wartości x napiszemy:
$moja_tablica[1].x
Dlaczego 1 a nie 2, skoro chcemy 2 kontener? Ponieważ TABLICE ZACZYNAJĄ SIĘ OD ZERA. Jeśli będziemy chcieli pierwszy kontener to napiszemy $moja_tablica[0].x.
Gromadzenie danych z gry:
To drugi rodzaj akcji pośrednich. Wiemy już jak tworzyć zmienne i się nimi posługiwać. Teraz możemy wykorzystać je do pobrania określonych informacji z gry i wykorzystania do własnych celów.
Gromadzenie takich danych odbywa się poprzez użycie różnych tagów, w których występuje słowo „store”. Oto one:
[store_gold]
Gromadzi informacje o ilości złota określonego gracza.
|
side – numer gracza
variable – nazwa zmiennej do jakiej ma zostać przypisana ilość złota tego gracza
|
Załóżmy, że przypisujemy tą informację do zmiennej gracz1_zloto. Jeśli będziemy chcieli znać wartość to poprzedzimy tą nazwę dolarem: $gracz1_zloto.
[store_locations]
Gromadzi współrzędne heksów spełniających kryteria filtru (x,y), ich typ terenu (terrain) i przynależność, jeśli to wioski (owner_side) – wszystko w postaci tablicy.
|
(filtr terenu) – tu podajemy kryteria
variable - nazwa zmiennej do jakiej mają zostać przypisane zgromadzone dane.
|
[store_map_dimensions]
Pobiera dane o wymiarach mapy i zapisuje do zmiennej typu kontener o nazwie map_size. Szerokość takiej mapy to atrybut width, a wysokość height.
[store_side]
Pobiera informacje o określonym graczu, jego imieniu (name), nazwie drużyny (team_name), ilości złota (gold), obecnym przychodzie z wiosek (income), przychodzie z jednej wioski (village_gold) oraz kto nim steruje (controller – wartości human, ai, none).
|
side – numer gracza
variable – nazwa zmiennej do jakiej mają zostać przypisane informacje.
|
[store_turns]
Pobiera informację o limicie turn. Tworzy zmienną o nazwie turns. Jeśli nie ma limitu tur, wartość będzie wynosić -1.
[store_unit]
Gromadzi szczegółowe dane o określonej jednostce bądź grupie jednostek. W ten sposób możliwa jest modyfikacja dosłownie wszystkich parametrów jednostki, odwołując się do jej atrybutów z jej pliku konfiguracyjnego.
„Storując” jednostkę do zmiennej, możemy zmieniać jej ilość punktów życia, doświadczenia, ruchu, ustawiać statusy, zmieniać drużyny, ale należy pamiętać, że wszystkie zmiany, jakie zrobimy, będą dotyczyły zmiennej, a nie jednostki, dlatego aby efekt tych zmian był widoczny, musimy stworzyć jednostkę na nowo ze zmodyfikowanej zmiennej (podmienić). Wykorzystujemy do tego tag [unstore_unit].
Wygląda to dosyć skomplikowanie, dlatego powstało makro, które omówiłem w poprzednim tutorialu i które nazywa się MODIFY_UNIT. Jest bardzo proste w obsłudze i bazuje na [store_unit], jednak nie mamy możliwości zmiany niektórych parametrów, które bardzo zaawansowanym użytkownikom byłyby potrzebne. Jednak są to parametry rzadko stosowane, więc zostaną przeze mnie pominięte.
Automatycznie gromadzone zmienne:
Poprzez wykorzystywanie omówionych wyżej tagów, możemy gromadzić interesujące nas dane o stanie gry i wykorzystywać na najrozmaitsze sposoby. Warto jednak wiedzieć, że gra czasem automatycznie gromadzi za nas niektóre dane, dzięki czemu nie musimy się trudzić tworzeniem własnych zmiennych. Oto one:
side_numer – numer aktualnego gracza,
turn_number – numer aktualnej tury,
x1,y1 – współrzędne, których dotyczy aktywowany ewent. (są to również koordynaty pierwszorzędnej jednostki),
x2,y2 – współrzędne drugorzędnej jednostki,
unit – jednostka pierwszorzędna (zmienna typu kontener z atrybutami takimi jak parametry jednostki) stojąca na heksie $x1,$y1
second_unit – jednostka drugorzędna stojąca na heksie $x1,$y1
damage_inflicted – wartość obrażeń jakie odniosła ostatnia jednostka
Dla wszystkich, którym zawarte w tym tutorialu informacje są niewystarczające zapraszam na oficjalną stronę BfW do sekcji poświęconej akcjom pośrednim:
http://wiki.wesnoth.org/InternalActionsWMLoraz sekcji dotyczącej zmiennych:
http://wiki.wesnoth.org/VariablesWML#Variables
W następnym tutorialu omówione zostaną różnego rodzaju warunki, które w połączeniu ze zmiennymi i gromadzeniem danych umożliwią tworzenie pełnowymiarowych scenariuszy. Przykłady te zawierać będą całą opisaną tu wiedzę jak i wiedzę z poprzednich tutoriali. Zostaną zaprezentowane różne sposoby wykorzystywania zmiennych w tym tworzenie alternatywnych warunków zwycięstwa.