Skocz do zawartości
bocian941

Przydatne funkcje

Rekomendowane odpowiedzi

NextInterpolateCamera

 

Funkcja, która ułatwia stworzenie kamer przy użyciu: InterpolateCameraPos oraz InterpolateCameraLookAt, dokładniej to umożliwia ona stworzenie kamery, która zadziała za kilka sekund (timer), można więc tworzyć kamerę, która przechodzi z punktu A do punktu B, a następnie z punktu B do C.

stock NextInterpolateCamera(playerid, timer, Float:FromX, Float:FromY, Float:FromZ, Float:ToX, Float:ToY, Float:ToZ, time, cut, Float:lFromX, Float:lFromY, Float:lFromZ, Float:lToX, Float:lToY, Float:lToZ)
	return SetTimerEx("nextCam",timer,false,"dffffffddffffff",playerid, FromX, FromY, FromZ, ToX, ToY, ToZ, time, cut,lFromX, lFromY, lFromZ, lToX, lToY, lToZ);

forward nextCam(playerid, Float:FromX, Float:FromY, Float:FromZ, Float:ToX, Float:ToY, Float:ToZ, time, cut, Float:lFromX, Float:lFromY, Float:lFromZ, Float:lToX, Float:lToY, Float:lToZ);
public nextCam(playerid, Float:FromX, Float:FromY, Float:FromZ, Float:ToX, Float:ToY, Float:ToZ, time, cut, Float:lFromX, Float:lFromY, Float:lFromZ, Float:lToX, Float:lToY, Float:lToZ)
{
	TogglePlayerSpectating(playerid, 1);
	InterpolateCameraPos(playerid, FromX, FromY, FromZ, ToX, ToY, ToZ, time, cut);
	InterpolateCameraLookAt(playerid, lFromX, lFromY, lFromZ, lToX, lToY, lToZ, time, cut);
	return 1;
}

Przykład użycia:

public OnPlayerSpawn(playerid)
{
	NextInterpolateCamera(playerid,15000,1114.1283,-1376.2242,113.8628,1341.1298,-1400.3218,25.8619,15000,CAMERA_MOVE,1341.1298,-1400.3218,25.8619,1297.8378,-1669.0496,71.4115); // kamera uruchomi się za 15000 ms.
	return 1;
}

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Absolute value

Funkcja zwraca wartość bezwzględną liczby podanej jako argument.

abs(int)
   return (int < 0) ? (-int) : (int);

Przykład użycia:

printf("Wartość bezwzględna dla liczby -69: %i", abs(-69));
printf("Wartość bezwzględna dla liczby 123: %i", abs(123));
printf("Wartość bezwzględna dla liczby 0: %i", abs(0));

Uwaga! Nie da się przedstawić liczbowo wartości cellmin (minimalnej wartości w PAWN), przy próbie jej przedstawienia zostaną pokazane dwa minusy (--):

printf("Wartość bezwzględna dla liczby cellmax: %i", abs(cellmax));
printf("Wartośc bezwzględna dla liczby cellmin: %i", abs(cellmin));

Funkcja działa na takiej samej zasadzie jak floatabs, tylko ona zwraca wartość bezwzględną dla liczb zmiennoprzecinkowych (float).

 

<--- Dodano --->

 

Można to zrobić za pomocą makrodefinicji:

#define abs(%0) ((%0) < 0) ? (-(%0)) : (%0)

Tylko należy pamiętać, że dając jako argument samą liczbę (nie zmienną!):

printf("Wartość bezwzględna dla liczby 666: %i", abs(-666));

Wyskoczy ostrzeżenie:

warning 206: redundant test: constant expression is non-zero
Edytowane przez Andrew

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Wiem że to niby proste makro definicję ale mogę się przydać.

 

Time_Convert

oraz

Time_ConvertEx

Makro zmieniają czas z sekund na:

  • Time_Convert - minuty sekundy.
  • Time_ConvertEx - godziny, minuty, sekundy. 
#define Time_Convert(%0,%1,%2) new %1 =floatround(((%0) / 60)); new %2 = floatround((%0) - (60 * (%1)))
#define Time_ConvertEx(%0,%1,%2,%3) new %1 = floatround(((%0) / 3600)); new %2 = floatround(((%0) / 60) % 60); new %3 = floatround(((%0) - (60 * (%2))) - (3600 * %1) )

Przykład użycia:

#include a_samp

#define Time_Convert(%0,%1,%2) new %1 = floatround(((%0) / 60)); new %2 = floatround((%0) - (60 * (%1)))
#define Time_ConvertEx(%0,%1,%2,%3) new %1 = floatround(((%0) / 3600)); new %2 = floatround(((%0) / 60) % 60); new %3 = floatround(((%0) - (60 * (%2))) - (3600 * %1) )

	
public OnFilterScriptInit()
{

	new czas = 99;
	
	Time_Convert(czas, tc_min, tc_sek);
	
	printf("%d sek  to %dmin %ds", czas, tc_min, tc_sek);
	
	Time_ConvertEx(czas, tcex_h, tcex_min, tcex_sek);
	
	printf("%d sek  to %dh %dmin %ds",czas, tcex_h, tcex_min, tcex_sek);
	
 	return 1;
}
Edytowane przez mrdrifter

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

 

Wiem że to niby proste makro definicję ale mogę się przydać.

 

Time_Convert

oraz

Time_ConvertEx

Makro zmieniają czas z sekund na:

  • Time_Convert - minuty sekundy.
  • Time_ConvertEx - godziny, minuty, sekundy. 
#define Time_Convert(%0,%1,%2) new %1 =floatround(((%0) / 60)); new %2 = floatround((%0) - (60 * (%1)))
#define Time_ConvertEx(%0,%1,%2,%3) new %1 = floatround(((%0) / 3600)); new %2 = floatround(((%0) / 60) % 60); new %3 = floatround(((%0) - (60 * (%2))) - (3600 * %1) )

Przykład użycia:

#include a_samp

#define Time_Convert(%0,%1,%2) new %1 = floatround(((%0) / 60)); new %2 = floatround((%0) - (60 * (%1)))
#define Time_ConvertEx(%0,%1,%2,%3) new %1 = floatround(((%0) / 3600)); new %2 = floatround(((%0) / 60) % 60); new %3 = floatround(((%0) - (60 * (%2))) - (3600 * %1) )

	
public OnFilterScriptInit()
{

	new czas = 99;
	
	Time_Convert(czas, tc_min, tc_sek);
	
	printf("%d sek  to %dmin %ds", czas, tc_min, tc_sek);
	
	Time_ConvertEx(czas, tcex_h, tcex_min, tcex_sek);
	
	printf("%d sek  to %dh %dmin %ds",czas, tcex_h, tcex_min, tcex_sek);
	
 	return 1;
}

Da się tego użyć w czasie gry online ?

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Da się tego użyć w czasie gry online ?

#include a_samp
#include zcmd

#define Time_ConvertEx(%0,%1,%2,%3) new %1 = floatround(((%0) / 3600)); new %2 = floatround(((%0) / 60) % 60); new %3 = floatround(((%0) - (60 * (%2))) - (3600 * %1) )

new pOnline[MAX_PLAYERS];

public OnPlayerConnect(playerid)
{
	pOnline[playerid] = gettime();
	
	return 1;
}



CMD:ilegram(playerid, cmdtext[])
{
	new str[128];
	
	Time_ConvertEx(gettime()-pOnline[playerid], h, m, s);
	
	format(str, sizeof(str), "Grasz %dh %dm %ds", h, m, s);
	
	SendClientMessage(playerid, -1, str);
	return 1;
}

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

fcreateEx

Funkcja tworzy plik z możliwością zapisania tekstu do niego. Jeżeli plik istnieje wcześniej - nie zostaną wykonane na nim żadne czynności.

fcreateEx(fname[], const text[] = EOS) {
   if (!fexist(fname)) {
      new
         File:fileHandle = fopen(fileName, io_write);
 
      if (fileHandle && text[0] != EOS) {
         fwrite(fileHandle, text);
         fclose(fileHandle);
      }
   }
}

Przykładowy kod:

fcreateEx("mojplik.txt", "Imie=Kazimierz\r\nNazwisko=Kowalski"); // Tworzymy plik o nazwie 'mojplik.txt' oraz zapisujemy do niego dane (tekst)

#2

fcreateEx("mojplik.txt"); // Tworzymy sam plik o nazwie 'mojplik.txt'
Edytowane przez Andrew

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

strcopy

 

Funkcja kopiująca jedną tablicę znaków do drugiej najszybszą metodą.

stock strcopy(dest[], const source[], length = sizeof source)
{
	strins((dest[0] = EOS, dest), source, 0, length);
}

Dowód:

[15:43:50] Time of Strcat: 583 ms
[15:43:50] Time of Strins: 573 ms

Kod testu: http://pastebin.com/d2fBdNeY

 

W zasadzie to strcat i strins mają bardzo podobne czasy wykonania.

 

Dla porównania czas zwykłego format:

[15:40:48] Time of Format1: 1064 ms

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

fcreateEx

Funkcja tworzy plik z możliwością zapisania tekstu do niego. Jeżeli plik istnieje wcześniej - nie zostaną wykonane na nim żadne czynności.

fcreateEx(fname[], const text[] = EOS) {
   if (!fexist(fname)) {
      new
         File:fileHandle = fopen(fileName, io_write);
 
      if (fileHandle && text[0] != EOS)
         fwrite(fileHandle, text);
 
      fclose(fileHandle);
   }
}
Przykładowy kod:

 

fcreateEx("mojplik.txt", "Imie=Kazimierz\r\nNazwisko=Kowalski"); // Tworzymy plik o nazwie 'mojplik.txt' oraz zapisujemy do niego dane (tekst)
 

#2

 

fcreateEx("mojplik.txt"); // Tworzymy sam plik o nazwie 'mojplik.txt'

Skoro już dajesz if'a z fileHandle to zrób to tak by fclose też wykonywało się tylko gdy fileHandle jest różne 0

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

GetNearestPlayerID

Funkcja zwraca ID najbliższego gracza





stock GetNearestPlayerID(p)
{ 
    new id = INVALID_PLAYER_ID;
    new Float:pos[3];
    new Float:odleglosc = 20000;
    GetPlayerPos(p, pos[0], pos[1], pos[2]);
    for(new a = GetMaxPlayers(); a; a--)
    {
        if(IsPlayerConnected(a)) 
            if(GetPlayerDistanceFromPoint(a, pos[0], pos[1], pos[2]) < odleglosc)
                {
                    id = a; odleglosc = GetPlayerDistanceFromPoint(a, pos[0], pos[1], pos[2]);
                }
    }
    return id;
}

Przykładowy kod:





CMD:nearestplayer(playerid, params[])
{
    new string[160];
    format(string, 160, "ID najbliższego gracza od Ciebie to: %d!", GetNearestPlayerID(playerid));
    SendClientMessage(playerid, -1 string);
    return 1;
}
Edytowane przez Drakon

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

IsAnyPlayerNearPlayer

Funkcja zwraca wartość "1" jeżeli w podanej odległości od gracza jest jakiś inny gracz.

stock IsAnyPlayerNearPlayer(p, Float:o)
{
    new Float:pos[3];
    GetPlayerPos(p, pos[0], pos[1], pos[2]);
    for(new a; a < GetMaxPlayers(); a++){
        if(IsPlayerConnected(a)){
            if(GetPlayerDistanceFromPoint(a, pos[0], pos[1], pos[2]) <= o){
                return 1;
            }
        }
    }
    return 0;
}
Przykładowy kod:
CMD:100hp(playerid, params[])
{
    if(IsAnyPlayerNearPlayer(playerid, 10.0)) return SendClientMessage(playerid, -1, "Nie możesz użyć tej komendy, ponieważ w odległości 10m od Ciebie stoi jakiś graacz!");
    SetPlayerHealth(playerid, 100.0);
    SendClientMessage(playerid, -1, "Uzdrowiłeś się!");
    return 1;
}
Edytowane przez Drakon

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

W pierwszej funkcji gdy nie znajdzie żadnego gracza w pobliżu to zwróci wartość zerową, czyli gracza o id 0 (który niekoniecznie musi być podłączony do serwera lub być koło gracza), warto nadać zmiennej 'id' wartość początkową INVALID_PLAYER_ID:

new id = INVALID_PLAYER_ID;

Oraz odpowiednio sprawdzać, czy funkcja zwróciła inną wartość niż INVALID_PLAYER_ID.

Edytowane przez Andrew

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

W pierwszej funkcji gdy nie znajdzie żadnego gracza w pobliżu to zwróci wartość zerową, czyli gracza o id 0 (który niekoniecznie musi być podłączony do serwera lub być koło gracza), warto nadać zmiennej 'id' wartość początkową INVALID_PLAYER_ID:



new id = INVALID_PLAYER_ID;

Oraz odpowiednio sprawdzać, czy funkcja zwróciła inną wartość niż INVALID_PLAYER_ID.

 

Poprawione (chyba prawidłowo, bo nic innego nie mogłem wykminić) :D

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Po co tak kombinować, wystarczyło tylko nadać zmiennej 'id' wartość INVALID_PLAYER_ID przy deklaracji, tyle.

 

Czyli ten warunek na końcu jest całkowicie niepotrzebny?

Wysrczy tylko:

new id = INVALID_PLAYER_ID;

?

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

crashPlayer

 

Funkcja, która wywołuje crash klienta SA:MP. Przydatne podczas, gdy gracz staje się nieznośny. 

Warto nadmienić, że gracz nie otrzyma tej informacji, a treść można zmienić.

#define CrashPlayer(%0) GameTextForPlayer(%0, "~w~~CRASH~", 100, 4)

Przykładowy kod:

CMD:crash(playerid, params[])
{
	if(isnull(params))
		return SendClientMessage(playerid, -1, "Użyj: /crash [id gracza]");
	new player = strval(params);
	if(!IsPlayerConnected(player))
		return SendClientMessage(playerid, -1, "Podany gracz nie jest online.");
	CrashPlayer(playerid);
	return 1;
} 
Edytowane przez KaZ

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

 

crashPlayer

 

Funkcja, która wywołuje crash klienta SA:MP. Przydatne podczas, gdy gracz staje się nieznośny. 

Warto nadmienić, że gracz nie otrzyma tej informacji, a treść można zmienić.



#define CrashPlayer(%0) GameTextForPlayer(%0, "~w~~CRASH~", 100, 4)

Przykładowy kod:



CMD:crash(playerid, params[])
{
	if(isnull(params))
		return SendClientMessage(playerid, -1, "Użyj: /crash [id gracza]");
	new player = strval(params);
	if(!IsPlayerConnected(player))
		return SendClientMessage(playerid, -1, "Podany gracz nie jest online.");
	CrashPlayer(playerid);
	return 1;
} 

 

O ile wiem to chyba te makro nie zadziała, ponieważ nie można robić w nim spacji (może się mylę)

A tak BTW - dlaczego to wywołuje crasha?

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Ponieważ SA-MP znajduje kolory zawarte w tyldach (~). Muszą być one parzyste, jeżeli nie będą - dostaniemy crasha. Takie tam luki SA-MPa. ;-)

Bo sa:mp to gufno ;P

A prawda jest taka że niekoniecznie musi to wywować crash, sprawdzałem nieraz na swoim serwerze i niektórych graczy nie wyrzucało (nie wiem czemu), są też inne sposoby na wywołanie crasha, np. stworzenie obiektu gracza (niedaleko gracza) o id modelu pojazdu albo postaci

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
/*  -- GetPointInAngleOfPlayer --
/   distance - odleglosc od gracza
/   angle - +30.0 gdy chcemy przesunac wzglednie w lewo oraz -30.0 gdy wzglednie prawo
/
*/
stock GetPointInAngleOfPlayer(playerid, &Float:x, &Float:y, &Float:z, Float:distance, Float:angle)
{
	new Float:current_angle;
	GetPlayerPos(playerid, x, y, z);
	
	GetPlayerFacingAngle(playerid, current_angle);

	if( IsPlayerInAnyVehicle(playerid) ) 
	{
            GetVehicleZAngle(GetPlayerVehicleID(playerid), current_angle);
        }
	
	new Float:a = current_angle + angle;
	
	x += (distance * floatsin(-a, degrees));
	y += (distance * floatcos(-a, degrees));
}

Czasami potrzebujemy w ten sposób wyliczyć konkretny punkt, np. w przypadku spawnowania pojazdu, dodawania obiektu czy /holuj(aby sprawdzić czy za pojazdem znajduje się inny - który chcemy holować).

Edytowane przez promsters

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach
/*  -- GetPointInAngleOfPlayer --
/   distance - odleglosc od gracza
/   angle - +30.0 gdy chcemy przesunac wzglednie w lewo oraz -30.0 gdy wzglednie prawo
/
*/
stock GetPointInAngleOfPlayer(playerid, &Float:x, &Float:y, &Float:z, Float:distance, Float:angle)
{
	new Float:current_angle;
	GetPlayerPos(playerid, x, y, z);
	
	GetPlayerFacingAngle(playerid, current_angle);

	if( IsPlayerInAnyVehicle(playerid) ) 
	{
            GetVehicleZAngle(GetPlayerVehicleID(playerid), current_angle);
        }
	
	new Float:a = current_angle + angle;
	
	x += (distance * floatsin(-a, degrees));
	y += (distance * floatcos(-a, degrees));
}

Czasami potrzebujemy w ten sposób wyliczyć konkretny punkt, np. w przypadku spawnowania pojazdu, dodawania obiektu czy /holuj(aby sprawdzić czy za pojazdem znajduje się inny - który chcemy holować).

 

Fajna funkcja, testowałem i działa bez zarzutu. Zobaczę jeszcze czy można ją jakoś przerobić, żeby zwiększyć funkcjonalność ;)

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Jedynie co to można wyrzucić chyba tylko funkcję IsPlayerInAnyVehicle:

if (!GetVehicleZAngle(GetPlayerVehicleID(playerid), current_angle))
   GetPlayerFacingAngle(playerid, current_angle);

Ale ważne, że funkcja działa poprawnie (a czas wykonania jest zapewne przybliżony, więc nie widzę sensu poprawiać kodu żeby uzyskać te milisekundy).

Edytowane przez Andrew

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

Według wiki SA-MP'a funkcja nie zwraca specyficznej (konkretnej) wartości, a nie żadnej. Tak naprawdę funkcje zwracają wartość true bądź false (no, w sumie zależy od funkcji - jak w przykładowym kodzie, AddStaticVehicle zwraca ID stworzonego auta, albo inny przykład - GetPlayerState zwraca ID stanu). Prostym dowodem może być taki kod:

new
  Float:angle,
  vehicle = AddStaticVehicle(522, 0.0, 0.0, 0.0, 0.0, 1, 1); // Tworzymy auto za pomocą funkcji AddStaticVehicle
 
printf("vehicle == %i", vehicle); // Dowiadujemy się, że stworzone auto ma ID 1
printf("GetVehicleZAngle: %i", GetVehicleZAngle(vehicle, angle)); // W konsoli powinniśmy otrzymać tekst: "GetVehicleZAngle: 1", gdyż jako pierwszy argument funkcji GetVehicleZAngle podaliśmy vehicleid pojazdu, który istnieje(!)
printf("GetVehicleZAngle: %i", GetVehicleZAngle(2, angle)); // Tutaj zaś w konsoli otrzymamy tekst: "GetVehicleZAngle: 0", ponieważ argument przyjął wartość 2, a na serwerze nie ma pojazdu o takim ID.

Dzięki takiej operacji możemy pisać nie tylko zwięzły i krótki kod, ale też nie musimy używać innych funkcji (typu IsPlayerInAnyVehicle).

Edytowane przez Andrew

Udostępnij tę odpowiedź


Odnośnik do odpowiedzi
Udostępnij na innych stronach

  • Przeglądający   0 użytkowników

    Brak zarejestrowanych użytkowników przeglądających tę stronę.

×