Zwrot wartości przez skrypt (własne funkcje, makra)

Moderator: Inkwizytor

ODPOWIEDZ
Awatar użytkownika
aszek
Posty: 133
Rejestracja: 11 lipca 2008, 06:17
ID Steam:
Numer GG: 8568774
ID gracza: 0

Zwrot wartości przez skrypt (własne funkcje, makra)

Post autor: aszek »

Natknołem się na ciekawy mechanizm w skryptach, jest możliwość zwrotu wartości przez nazwę uruchomianego 'skryptu' (funkcji makra) i nawet wydobycie z niego argumentów (wartości) poprzez nazwy zmiennych. A to działa jak funkcja, ale jest makrem, które sami możemy sobie napisać:

coś prostego:

isAlive (aP)

#define isAlive (X)
(alive X)


coś ciekawszego:

isAlone (aP)

#define isAlone (X)
(count units group X < 1) and isAlive (aP)


jeszcze ciekawsze:

? isAlone (aP, liczebnosc) : aP sidechat format ["Baza, wybili mi oddział ! Zostało nas %1", liczebnosc];

#define isAlone (X, ILE_JEDNOSTEK)
(ILE_JEDNOSTEK = count units group X; ILE_JEDNOSTEK < 1)


coś trudniejszego, ale i bardziej użytecznego:

? isMyGroupInVehicle (aP, aHeli) : aP sidechat "Wszyscy na pokładzie, pilot startuj !";

#define isMyGroupInVehicle (X, VEH)
(
private ['units', 'isInVehicle'];

units = units group (_this select 0);
isInVehicle = true;
{isInVehicle = isInVehicle and (_x in VEH)} forEach units;
isInVehicle == true
)



Argumenty (ich nazwy) wydają się być dowolne i można ich użyć zarówno do przekazywania parametrów, jak i ich obierania od makra. Ciągle to testuje, bo to dla mnie nowość. To jest naprawdę ciekawe:

#define PUSH (ARRAY, VALUE) ARRAY resize ((count ARRAY) + 1); ARRAY set [(count ARRAY) - 1, VALUE]

'array resize' i 'set' ? Wydaje się to być modyfikacją kodu:

ARRAY = ARRAY + [VALUE],
ale jako wstawiająca VALUE w konkretny indeks:
ARRAY[count ARRAY - 1] = VALUE

Engine Army to naprawdę świetna zabawka. Ma ktoś doświadczenie z makrami ?
"True glory consists in doing what deserves to be written, in writing what deserves to be read." - Pliny The Elder
Awatar użytkownika
kondor
Posty: 1522
Rejestracja: 13 marca 2007, 11:50
ID Steam: Przemek_kondor
Kontakt:

Re: Zwrot wartości przez skrypt (własne funkcje, makra)

Post autor: kondor »

Używał makr jedynie w najprostszej z form, ale wygląda ciekawie i przejrzyściej w użyciu.

Nie wiem, czy to przeoczyłeś, czy jedynie nie wspomniałeś, ale mamy w ofp/arma "normalne" funkcje:
(z pamięci) :

Kod: Zaznacz cały

//definicja:
ptr_isAlive = {
private "_res";
_res = alive (_this select 0);
_res
};

//użycie:
hint format["gracz żyje: %1", [player] call ptr_isAlive];
lub przy pomocy oddzielnego skrypu:
(funkcja zwraca tablicę ze zmienionym elementem):

Kod: Zaznacz cały

private ["_idx", "_array", "_newValue", "_i", "_newArray"];

_idx = _this select 0;
_array = _this select 1;
_newValue = _this select 2;
_newArray = [];

for[{_i=0}, {_i<(count _array)}, {_i=_i+1}]do
{
	if( _i == _idx )then
	{
		_newArray = _newArray + [_newValue];
	}
	else
	{
		_newArray = _newArray + [_array select _i];
	};
};
_newArray
użycie:

Kod: Zaznacz cały

ptr_set_array_ceil = call compile "set_array_ceil.sqf";
myArray = [1, 2, 3, 4, 5];
myArray = [0, myArray, 2] call ptr_set_array_ceil;
//będzie [2, 2, 3, 4, 5]
Awatar użytkownika
aszek
Posty: 133
Rejestracja: 11 lipca 2008, 06:17
ID Steam:
Numer GG: 8568774
ID gracza: 0

Re: Zwrot wartości przez skrypt (własne funkcje, makra)

Post autor: aszek »

Dzięki kondor, liczyłem na to że przybliżysz temat :) Nie, nie byłem świadomy istnienia funkcji o własnej definicji, dopiero niedawno oglądając dzieło niejakiego Spoona, autora SPON_Radar (radar na dialogach):

"Sweeping radar which displays detected aircraft as blips (type seen from the 1950s). The detection range for the radar can be set from 1 to 350 km. The mission-maker can also set how fast the radar beam rotates and whether to show an unrealistic wire-frame map with the radar image."

podejrzałem u niego makra. Kiedyś dawo czytałem na biwiki, że SQFy (odpalane execVM) nie mogą zwracać wartości przez nazwę, bo execVM tworzy odseparowany wątek zwracając jedynie uchwyt (handle) do wątku, który pozwala go jakotako kontrolować (ubić). W sumie, po takiej informacji nie interesowały mnie dłużej .sqf'y, bo byłem w przekonaniu, że technicznie normalnej funkcji nie da się zrobić. Korzyści używania bardziej zaawansowanej składni sqf (case, for, if) da się łatwo w .sqm zaaranżować, a prędkość wykonywania była dla mnie kwestią pomijalną. Zresztą, ostatnio nawet zażarcie dłubałem 'funkcję blokowe' w .sqm, działającą na zmiennych (parametrach lokalnych), które co prawada musiałby być określone przed wywołaniem bloku w innym miejscu, ale trick ze skokami w dowolne miejsce stworzył trochę możliwości dla parsera. Ale, co za marnotrastwo czasu...

Ten mechanizm, który pokazałeś z typowaniem procedury na zmienną (ptr_set_array_ceil = call compile ...) i odpalanie zmiennej jako funkcji (call ptr_set_array_ceil) - to świetna rzecz i teraz widzę czemu ten trick służy. Dzięki :) Zwrot wartości przez nazwę, super sprawa. Przyznam, że możliwość definicji własnych funkcji czy makr daje wprost niewyobrażalne możliwości. Praktycznie każdy warunek dla tiggera czy WPta można uhermetyzować i sięgać po wynik pojedynczą instrukcją, po prostu cudo ;]

btw. jak tylko gdzieś rozdam RP dołoże Ci kolejny ;) Kondor RP +1
"True glory consists in doing what deserves to be written, in writing what deserves to be read." - Pliny The Elder
ODPOWIEDZ

Wróć do „Edytor - tworzenie misji, skrypty oraz programowanie”