Skocz do zawartości

Witamy w Nieoficjalnym polskim support'cie AMX Mod X

Witamy w Nieoficjalnym polskim support'cie AMX Mod X, jak w większości społeczności internetowych musisz się zarejestrować aby móc odpowiadać lub zakładać nowe tematy, ale nie bój się to jest prosty proces w którym wymagamy minimalnych informacji.
  • Rozpoczynaj nowe tematy i odpowiedaj na inne
  • Zapisz się do tematów i for, aby otrzymywać automatyczne uaktualnienia
  • Dodawaj wydarzenia do kalendarza społecznościowego
  • Stwórz swój własny profil i zdobywaj nowych znajomych
  • Zdobywaj nowe doświadczenia

Dołączona grafika Dołączona grafika

Guest Message by DevFuse
 

Zdjęcie

Pytanie o poprawność zapisu w kodzie


  • Nie możesz napisać tematu
  • Zaloguj się, aby dodać odpowiedź
5 odpowiedzi w tym temacie

#1 Scorpion Flail

    Wszechobecny

  • Użytkownik

Reputacja: 129
Zaawansowany

  • Postów:489
  • GG:
  • Steam:steam
Offline

Napisano 02.02.2014 02:18

Witam.
Dziś edytując silnik PaintBall z tego tematu natknąłem się na dziwną dla mnie rzecz.

Jak mam rozumieć ten fragment kodu?

public new_round()
	if (get_pcvar_num(onoff) && get_pcvar_num(strip))
	{
		new ent;
		while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "armoury_entity")) != 0)
			engfunc(EngFunc_RemoveEntity, ent);
	}

public ev_resethud(id)
	if (get_pcvar_num(onoff))
		if (!task_exists(id))
			set_task(0.3, "player_spawn", id);

public player_spawn(id)
	if (is_user_alive(id))
	{
		if (get_pcvar_num(protc))
		{
			set_pev(id, pev_takedamage, DAMAGE_NO);
			set_task(float(get_pcvar_num(protc)), "player_godmodeoff", id+100);
		}

		if (get_pcvar_num(strip) && !user_has_mp5(id))
		{
			if (pev(id, pev_weapons) & (1 << CSW_C4))
				engclient_cmd(id, "drop", "weapon_c4")
			fm_strip_user_weapons(id);
		}

		if (get_pcvar_num(money))
		{
			message_begin(MSG_ONE_UNRELIABLE, 94, _, id); //HideWeapon
			write_byte(1 << 5);
			message_end();
		}

		if (get_pcvar_num(cmodel))
		{
			engfunc(EngFunc_SetClientKeyValue, id, engfunc(EngFunc_GetInfoKeyBuffer, id), "model", "paintballer");
			new skin = g_plyr_skin[id];			
			if (get_user_team(id) == 1)
			{
				if (skin < 0 || skin > 3) g_plyr_skin[id] = 0;
			}
			else
			{
				if (skin < 4 || skin > 7) g_plyr_skin[id] = 4;
			}
			set_pev(id, pev_skin, g_plyr_skin[id]);
		}

		remove_task(id);
		set_task(random_float(0.9, 1.3), "player_weapons", id);
		set_task(2.0, "clear_moneyhud", id + 300);
	}

public client_command(id)
	if (get_pcvar_num(cmodel))
	{		
		new command[10], speech[2];
		read_argv(0, command, 9);
		read_argv(1, speech, 1);
		if (containi(command, "join") != -1)
			if (equali(command, "jointeam"))
				g_team_select[id] = str_to_num(speech);
			else if (equali(command, "joinclass"))
				g_plyr_skin[id] = (g_team_select[id] == 1) ? str_to_num(speech) - 1: str_to_num(speech) + 3;
	}

public player_weapons(id)
	if (is_user_alive(id))
	{
		set_pdata_int(id, 386, 120, 5);
		fm_give_item(id, "weapon_knife");
		if (get_user_team(id) == 1 && get_pcvar_num(pbglock))
			fm_give_item(id, "weapon_glock18");
		else if (get_pcvar_num(pbusp))
		{
			set_pdata_int(id, 382, 48, 5);
			fm_give_item(id, "weapon_usp");
		}
		if (get_pcvar_num(pbgun))
			fm_give_item(id, "weapon_mp5navy");
		if (get_pcvar_num(pbnade))
			if (get_pcvar_num(gnade) == 1 || g_has_kill[id])
			{
				fm_give_item(id, "weapon_hegrenade");
				g_has_kill[id] = 0;
			}
		remove_task(id);
	}

public clear_moneyhud(id)
	if (get_pcvar_num(money))
	{
		message_begin(MSG_ONE_UNRELIABLE, 94, _, id - 300); //HideWeapon
		write_byte(1 << 5);
		message_end();
	}
	
public ev_death()
{
	g_has_kill[read_data(1)] = 1;
	if (get_pcvar_num(death))
	{
		new id = read_data(2) + 200;
		set_task(3.0, "player_spawner", id);
		set_task(3.2, "player_spawner", id);
	}
}

public ev_money(id)
	if (get_pcvar_num(money))
		if (get_pdata_int(id, 115, 5) > 0)
			set_pdata_int(id, 115, 0, 5);

public say_respawn(id)
	if (get_pcvar_num(death))
		if (!is_user_alive(id))
			if (get_user_team(id) == 1 || get_user_team(id) == 2)
			{
				set_task(1.5, "player_spawner", id + 200);
				set_task(1.7, "player_spawner", id + 200);
			}

public player_godmodeoff(id)
	set_pev(id-100, pev_takedamage, DAMAGE_AIM);

public player_spawner(id)
	if (is_user_connected(id - 200))
		if (get_user_team(id - 200) == 1 || get_user_team(id - 200) == 2)
			dllfunc(DLLFunc_Spawn, id - 200);

Chodzi mi przede wszystkim o klamerki otwierające i zamykające public'i.

Plugin w praktyce niby działa, ale czy taki zapis jest poprawny (bez klamerek)?


  • +
  • -
  • 0

#2 Adiloveskan

    Pomocny

  • Użytkownik

Reputacja: 1
Nowy

  • Postów:52
  • Imię:Adrian
  • Lokalizacja:Jamajka
Offline

Napisano 02.02.2014 04:37

po każdym publicku, musisz w tej samej lub następnej (więcej bugów) postawić {, a po zakończeniu danego publicka, musisz dać }

 

Pokaze to na przykładzie

 

public say_respawn(id)
    if (get_pcvar_num(death))
        if (!is_user_alive(id))
            if (get_user_team(id) == 1 || get_user_team(id) == 2)
            {
                set_task(1.5, "player_spawner", id + 200);
                set_task(1.7, "player_spawner", id + 200);
            }

 

Ten zapis jest niepoprawny, gdyż plugin (Gdyby nie było nowych publicków) ciagnął by się dalej, niby powinno działać, ale zaleca się używanie { i }

 

 

public say_respawn(id){
    if (get_pcvar_num(death))
        if (!is_user_alive(id))
            if (get_user_team(id) == 1 || get_user_team(id) == 2)
            {
                set_task(1.5, "player_spawner", id + 200);
                set_task(1.7, "player_spawner", id + 200);
            }

}

 

W tym zapisie, klamra } Ostatecznie zamyka publicka, a więc nie może wystąpić błąd związany z jej brakiem.

 

Dodatkowo, klamr { musi być w jednym publicku tyle co klamr }, inaczej

 

 

public say_respawn(id){1 czerwona

    if (get_pcvar_num(death))
        if (!is_user_alive(id))
            if (get_user_team(id) == 1 || get_user_team(id) == 2)
            {2 czerwona
                set_task(1.5, "player_spawner", id + 200);
                set_task(1.7, "player_spawner", id + 200);
            }1 niebieska

}Brak 2 niebieskiej

 

Ten kod jest niepoprawny, dlatego że są 2 klamry czerwone ( { ), a tylko 1 niebieska ( } ), i plugin nie zostaje zamknięty, bo druga klamra czerwona jest zamykana przez pierwsza niebieską, dlatego że niema pomiędzy nimi żadnych innych klamr. a pierwsza czerwona pozostaje niezamknięta, co wywala Error

 

 

Teraz zamykanie

 

public say_respawn(id){druga para, pomiędzy nimi jest para 1
    if (get_pcvar_num(death))
        if (!is_user_alive(id))
            if (get_user_team(id) == 1 || get_user_team(id) == 2)
            {1-sza para, pomiedzy nimi nie ma zadnej innej pary
                set_task(1.5, "player_spawner", id + 200);
                set_task(1.7, "player_spawner", id + 200);
            }1-sza para, pomiedzy nimi nie ma zadnej innej pary

}druga para, pomiędzy nimi jest para 1

 

Jeżeli jest para 1, i klamry { i } są "kolo siebie" (Nie ma w ich zamknieciu zadnych innych klamr { czy }) to się lączą w pare,

Jeżeli jest para 2, i klamry { i } nie są "kolo siebie" (W ich zamknieciu wystepuja pary)  to pary sa eliminowane przy "rozumowaniu"

Jest jeszcze 1 przypadek, lecz ja ci go nie wytłumacze bo nie wiem jak :D


  • +
  • -
  • 1

b_350_20_000000_560100_BD0000_F11715.png


#3 Gość_21977_*

  • Gość

Reputacja: 0

Offline

Napisano 02.02.2014 12:25

po każdym publicku, musisz w tej samej lub następnej (więcej bugów) postawić {, a po zakończeniu danego publicka, musisz dać }
(…)

:facepalm: Nie.
 
Klamry grupują komendy zawarte wewnątrz nich.
W przypadku, kiedy nie użyjemy klamer, komendy nie zostaną po prostu pogrupowane.
 

public say_respawn(id)
	if (get_pcvar_num(death))
		if (!is_user_alive(id))
			if (get_user_team(id) == 1 || get_user_team(id) == 2)
			{
				set_task(1.5, "player_spawner", id + 200);
				set_task(1.7, "player_spawner", id + 200);
			}

 
Kod ten jest poprawny.

Funkcja publiczna say_respawn składa się z jednego ifa, który w przypadku, gdy wartość logiczna get_pcvar_num(death) jest prawdziwa, to wykonuje kolejnego ifa.
Jeśli jego wartość logiczna !is_user_alive(id) jest prawdziwa, to wywołuje kolejnego ifa i jeśli jego wartość logiczna get_user_team(id) == 1 || get_user_team(id) == 2 jest prawdziwa,
to wywołuje on wszystkie zgrupowane instrukcje zawarte wewnątrz klamry, tj. dwa wywołania natywu set_task.
 
Klamry mamy konieczność stosować jedynie, gdy chcemy zgrupować wiele komend.
W przypadku, gdy wywołujemy jedynie jedną komendę, użycie klamry jest opcjonalne.
 
Kod zacytowany wyżej w tym poście można napisać również, używając klamer w miejscu, gdzie nie są one potrzebne, tj.:

public say_respawn(id){
	if (get_pcvar_num(death)){
		if (!is_user_alive(id)){
			if (get_user_team(id) == 1 || get_user_team(id) == 2)
			{
				set_task(1.5, "player_spawner", id + 200);
				set_task(1.7, "player_spawner", id + 200);
			}
		}
	}
}

 

Podejrzewam, że z tak właśnie formą zazwyczaj obcowałeś, stąd to pytanie odnośnie klamer.

Podsumowując,forma bezklamrowa jest poprawna dla pojedynczych komend, choć rzadko używana ze względu na czytelność oraz kompatybilność z wieloma, głównie starszymi, środowiskami programistycznymi.

 

To, czy dany programista używa klamer dla pojedynczych instrukcji, czy nie, jest kwestią osobistą.

Dla jednych czytelniejsza jest forma z klamrami, dla innych bez. Jedni używają klamer w tej samej linii, co przekazywane argumenty funkcji, inni w linii niżej.

Jedni stawiają spacje, tabulacje (6262 robi niezłego mixa  :crazy:), inni nie. Jest to kwestia estetyki i każdy postrzega ją inaczej.


GwynBleidD (08.02.2014 12:22):
Dlatego wolę Pythona :)


#4 Scorpion Flail

    Wszechobecny

  • Autor tematu
  • Użytkownik

Reputacja: 129
Zaawansowany

  • Postów:489
  • GG:
  • Steam:steam
Offline

Napisano 02.02.2014 13:23

Ok.

Czyli jeśli dobrze rozumiem, gdybym tutaj:

public new_round()
    if (get_pcvar_num(onoff) && get_pcvar_num(strip))
    {
        new ent;
        while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "armoury_entity")) != 0)
            engfunc(EngFunc_RemoveEntity, ent);
    }

Dodał jeszcze innego if'a, np:

public new_round()
    if (get_pcvar_num(onoff) && get_pcvar_num(strip))
    {
        new ent;
        while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "armoury_entity")) != 0)
            engfunc(EngFunc_RemoveEntity, ent);
    }
   if (!is_user_alive(id))
    //kod

To wtedy zastosowanie klamer byłoby konieczne, ponieważ mam więcej komend, które chcę przypisac do danej funkcji, tak?


(02.02.2014 13:43):
Tak

  • +
  • -
  • 0

#5 Scorpion Flail

    Wszechobecny

  • Autor tematu
  • Użytkownik

Reputacja: 129
Zaawansowany

  • Postów:489
  • GG:
  • Steam:steam
Offline

Napisano 02.02.2014 14:47

Ok.

Od jakiegoś czasu analizuję przyczynę crashy, które zdarzają się z 1-2x dziennie.. Dzieją się one zawsze w nowej rundzie przy spawnie/chwile po spawnie lub pod sam koniec rundy (przed spawnem) i są związane z silnikiem PB (resztę pluginów wykluczyłem).

 

Patrząc w ten kod:

public new_round()
    if (get_pcvar_num(onoff) && get_pcvar_num(strip))
    {
        new ent;
        while ((ent = engfunc(EngFunc_FindEntityByString, ent, "classname", "armoury_entity")) != 0)
            engfunc(EngFunc_RemoveEntity, ent);
    }
public ev_resethud(id)

    if (get_pcvar_num(onoff))
        if (!task_exists(id))
            set_task(0.3, "player_spawn", id);

Zastanawiam się nie optymalniej i poprawniej byłoby przerzucić wszystko z ev_resethud do new_round (a może odwrotnie?)

W końcu obydwie funkcje wykonują się przy nowej rundzie (oczywiście wiem, że z eventem ResetHUD jest trochę inaczej niż z Round_Start)


Użytkownik Scorpion Flail edytował ten post 02.02.2014 14:48

  • +
  • -
  • 0

#6 Adiloveskan

    Pomocny

  • Użytkownik

Reputacja: 1
Nowy

  • Postów:52
  • Imię:Adrian
  • Lokalizacja:Jamajka
Offline

Napisano 02.02.2014 21:19

 

po każdym publicku, musisz w tej samej lub następnej (więcej bugów) postawić {, a po zakończeniu danego publicka, musisz dać }
(…)

:facepalm: Nie.
 
Klamry grupują komendy zawarte wewnątrz nich.
W przypadku, kiedy nie użyjemy klamer, komendy nie zostaną po prostu pogrupowane.
 

public say_respawn(id)
	if (get_pcvar_num(death))
		if (!is_user_alive(id))
			if (get_user_team(id) == 1 || get_user_team(id) == 2)
			{
				set_task(1.5, "player_spawner", id + 200);
				set_task(1.7, "player_spawner", id + 200);
			}

 
Kod ten jest poprawny.

Funkcja publiczna say_respawn składa się z jednego ifa, który w przypadku, gdy wartość logiczna get_pcvar_num(death) jest prawdziwa, to wykonuje kolejnego ifa.
Jeśli jego wartość logiczna !is_user_alive(id) jest prawdziwa, to wywołuje kolejnego ifa i jeśli jego wartość logiczna get_user_team(id) == 1 || get_user_team(id) == 2 jest prawdziwa,
to wywołuje on wszystkie zgrupowane instrukcje zawarte wewnątrz klamry, tj. dwa wywołania natywu set_task.
 
Klamry mamy konieczność stosować jedynie, gdy chcemy zgrupować wiele komend.
W przypadku, gdy wywołujemy jedynie jedną komendę, użycie klamry jest opcjonalne.
 
Kod zacytowany wyżej w tym poście można napisać również, używając klamer w miejscu, gdzie nie są one potrzebne, tj.:

public say_respawn(id){
	if (get_pcvar_num(death)){
		if (!is_user_alive(id)){
			if (get_user_team(id) == 1 || get_user_team(id) == 2)
			{
				set_task(1.5, "player_spawner", id + 200);
				set_task(1.7, "player_spawner", id + 200);
			}
		}
	}
}

 

Podejrzewam, że z tak właśnie formą zazwyczaj obcowałeś, stąd to pytanie odnośnie klamer.

Podsumowując,forma bezklamrowa jest poprawna dla pojedynczych komend, choć rzadko używana ze względu na czytelność oraz kompatybilność z wieloma, głównie starszymi, środowiskami programistycznymi.

 

To, czy dany programista używa klamer dla pojedynczych instrukcji, czy nie, jest kwestią osobistą.

Dla jednych czytelniejsza jest forma z klamrami, dla innych bez. Jedni używają klamer w tej samej linii, co przekazywane argumenty funkcji, inni w linii niżej.

Jedni stawiają spacje, tabulacje (6262 robi niezłego mixa  :crazy:), inni nie. Jest to kwestia estetyki i każdy postrzega ją inaczej.

 

Dzięki ze naprostowałeś moje twierdzenie, Lecz i tak uważam, że lepiej i łatwiej do odczytania potem jest, jak się użyje klamr.

 

 

@TOPIC tak, lepiej by było gdybyś użył Start_Round, ale jak wspomniałeś, trzeba będzie przepisać :)


GwynBleidD (08.02.2014 12:24):
Łatwe czytanie kodu daje tabulacja odpowiednia, klamry zapewniają poprawność działania kodu. Usuń sobie wcięcia z kodu w którym jest tabulacja, a usuń niepotrzebne klamry i pomyśl co Ci zrobi różnicę, a co praktycznie wcale :)

Użytkownik Adiloveskan edytował ten post 02.02.2014 21:21

  • +
  • -
  • 0

b_350_20_000000_560100_BD0000_F11715.png





Użytkownicy przeglądający ten temat: 0

0 użytkowników, 0 gości, 0 anonimowych