Jump to content
Prosíme všetkých užívateľov, ktorý sa chcú opätovne pripojiť na discord aby znovu spárovali svoje účty kliknutím na "Discord" v navigácií a pripojili sa na server Read more... ×
Sign in to follow this  
Scydo

návod Práce 2019 - Systémy #4

Recommended Posts

Práce 2019 Systémy #4

*****

Pojďme si udělat návod na všechny "systémy" individuálně.:weSmart:
Vítejte u dalšího dílu PAWN kouzla zbaven.

Práce jsou snad ty nejjednodušší ze všech těch systémů :d

Obsah

1. Vkládání informací o pracích,
2. Funkce pro práci s prací,
3. Zakomponování.

Vkládání informací o pracích

Jsou nejjednodušší už jen z důvodu, že jakmile si to člověk všechno předpřipraví, tak už jediné co, jen přidává nové práce. Prvním, co bych doporučoval začít je přidáním pozic prací. Bude lepší si je oddělit od zbytku dalších informací o práci:

new 
	Float: Prace_Mista[][3] = {

	{741.0, 644.1, 203},
	{572.2, 344.3, 638},
	{379.4, 68.5, 181},
	{760.6, 221.7, 629},
	{532.8, 713.9, 262},
	{483.10, 433.11, 642},
	{598.12, 139.13, 377},
	{182.14, 678.15, 708},
	{32.16, 991.17, 649},
	{659.18, 567.19, 989}
};

Nebudeme si definovat nějaké MAX_JOBS, jelikož můžeme zjistit maximum přidaných prací díky sizeof. Ale o tom později.
Dál bych pokračoval deklarováním si zbytku informací a to klidně rovnou do 1 proměnné a upravit dle sebe, aby to bylo přehledné.
Místo únavného hledání ID zbraní stačí zapsat jejich makro:

enum ENUM_PRACE {

	Prace_Jmeno[11],
	Prace_Vyplata,
	Prace_Zbran1, Prace_Zbran2, Prace_Zbran3,
	Prace_Skin1, Prace_Skin2, Prace_Skin3
}

new 
	Prace_Info[][ENUM_PRACE] = {

	//Jmeno 	Vypla  Zbran1 		Zbran2 		Zbran3 		Skin1 2    3
	{"Grove", 	10000, WEAPON_TEC9, 	WEAPON_KNIFE, 	WEAPON_COLT45, 	105,  106, 107},
	{"Ballas", 	10000, WEAPON_UZI, 	WEAPON_BAT, 	WEAPON_COLT45, 	102,  103, 104},
	{"Vagos", 	10000, WEAPON_UZI, 	WEAPON_KATANA, 	WEAPON_COLT45, 	108,  109, 110},
	{"Aztecas", 	10000, WEAPON_TEC9, 	WEAPON_SHOVEL, 	WEAPON_COLT45, 	114,  115, 116},
	...
};

Funkce pro práci s prací
Než půjde plně pracovat dál, je třeba určité informace nejdříve zjistit. Například, jestliže je hráč u dané práce. Jedna z možností je přidáním pickupu, a jakmile by byl na něm, zobrazit dialog. Což sice přináší problém s neustálým otevíráním dialogu, které jde vyřešit pomocí proměnné, ale to je moc práce. Já bych raději doporučil, aby menu ohledně prací si hráč zobrazil sám. To znamená, že nejdříve musí provést sám nějakou akci (příkaz, stisknutí kláves) a až pak se zobrazí menu práce. Já rozhodně doporučuji přes příkaz. Ano, psát 10x /prace není zrovna záživné ale velmi jednoduše se ošetřuje. Stačí jen fci na případ, že je okolo nějaké práce.
K tomu nám poslouží cyklus, který projede všechny naše pozice prací a zjistí, zda není hráč kolem nějaké z nich:

bool: IsPlayerAroundJob(playerid) {

	for (new i, j = sizeof(Prace_Mista); i < j; i++) {

		if (IsPlayerInRangeOfPoint(playerid, 1.0, Prace_Mista[0], Prace_Mista[1], Prace_Mista[2])) return true;
	}
	return false;
}

A ještě jednu funkce a ta nám vrátí ID té dané práce. Ano, šlo by to oboje zakomponovat do jedné fce (fce by vrátila číslo větší než 0 takže by bylo vždy true), ale ať máme víc fcí :d.
Obsah se nějak nezmění, stačí jen, aby vracela ID té práce kolem které je:

GetJobIDFromPlayer(playerid) {

	for (new i, j = sizeof(Prace_Mista); i < j; i++) {

		if (IsPlayerInRangeOfPoint(playerid, 1.0, Prace_Mista[0], Prace_Mista[1], Prace_Mista[2])) return i;
	}
	return 0;
}

A nakonec deklaraci proměnné (a i několik maker z ní), která nám řekne, že hráč je zaměstnaný. Vypustíme datový typ bool a rovnou použijeme int z důvodu, že nám kromě informace že je zaměstnaný, nám taky poví kde podle ID:

new 
	Hrac_Maka[MAX_PLAYERS];

#define IsPlayerInAnyJob(%0) (Hrac_Maka[%0]>0)
#define GetPlayerJob(%0) Hrac_Maka[%0]

A nakonec samotné přidání hráče do práce. Doho docílíme snadno tím, že mu nastavíme všechno známé:

SetPlayerJob(playerid, jobid) {

	Hrac_Maka[playerid] = jobid;
	GivePlayerWeapon(playerid, Prace_Info[jobid][Prace_Zbran1], 9999);
	GivePlayerWeapon(playerid, Prace_Info[jobid][Prace_Zbran2], 9999);
	GivePlayerWeapon(playerid, Prace_Info[jobid][Prace_Zbran3], 9999);
	SetPlayerSkin(playerid, Prace_Info[jobid][Prace_Skin1]);
}

Stále je v tom zmatek? Tak si jde z toho udělat i makra:

#define GetJobSalary(%0) Prace_Info[%0][Prace_Vyplata]
#define GetJobFirstWeapon(%0) Prace_Info[%0][Prace_Zbran1]
#define GetJobSecondWeapon(%0) Prace_Info[%0][Prace_Zbran2]
#define GetJobThirdWeapon(%0) Prace_Info[%0][Prace_Zbran3]
#define GetJobFirstSkin(%0) Prace_Info[%0][Prace_Skin1]
#define GetJobSecondSkin(%0) Prace_Info[%0][Prace_Skin2]
#define GetJobThirdSkin(%0) Prace_Info[%0][Prace_Skin3]

Zakomponování 
No a pak už jen všechno aplikovat, například na příkaze:

public OnPlayerCommandText(...) {

	if (!strcmp("/prace", cmdtext, true)) {

		if (IsPlayerAroundJob(playerid) == true) {

          	/* Nejdříve jestli je vůbec zaměstnaný */
			if (IsPlayerInAnyJob(playerid)) {

              	/* Teď v případě, že se id práce na které stojí se shoduje s id ve které je zaměstnaný: */
				if (GetPlayerJob(playerid) == GetJobIDFromPlayer(playerid)) ShowPlayerDialog(...);
              	/* Jinak v případě, že je to jiná práce, než ta ve které je: */
				else ShowPlayerDialog(...);
			 /* A nebo ještě v případě, že není zaměstnaný vůbec: */
			} else ShowPlayerDialog(...);
		}
		return true;
	}
}

V případě výplaty to je snadné. Stačí si spustit opakující se timer například každé 3 minuty.
Poté projít cyklem všechny přítomné hráče, zjistit zda jsou v nějaké práci. a z jejich id prací jim dát danou výplatu:

forward Prace_Vyplata();
public Prace_Vyplata() {

	for (new i; i < MAX_PLAYERS; i++) {

		if (!IsPlayerConnected(i)) continue;
		if (IsPlayerInAnyJob(i) == true) GivePlayerMoney(i, Prace_Info[GetPlayerJob(i)][Prace_Vyplata]);
	}
	return 1;
}

Seznam všech fcí (a maker) jen pro ukázku :d:

IsPlayerInAnyJob(playerid);
GetPlayerJob(playerid);
SetPlayerJob(playerid, jobid);
GetJobSalary(jobid);
GetJobFirstWeapon(jobid);
GetJobSecondWeapon(jobid);
GetJobThirdWeapon(jobid);
GetJobFirstSkin(jobid);
GetJobSecondSkin(jobid);
GetJobThirdSkin(jobid);
InPlayerAroundJob(playerid);
GetJobIDFromPlayer(playerid);

Odkazy
Anketa2019  Systémy #1 - [Topic] [Pastebin]
Carmenu2019 Systémy #2 - [Topic] [Pastebin]
Oprávnění (Admin/Vip)2019 Systémy #3 - [Topic] [Pastebin]
Práce2019 Systémy #4 - [Pastebin]

WhiteFlashyGoshawk-size_restricted.gif&key=9ae98bc298c254f5893c36f9819ca4e4209e7018d545ee665b211d581277691e

Edited Úterý o 15:43 by Scydo 

Edited by Scydo
in->is
  • Líbí se mi to! (+1) 1

Sdílet tento příspěvek


Link to post
Share on other sites
před 36 minutami, Scydo said:

Nebudeme si definovat nějaké MAX_JOBS, jelikož můžeme zjistit maximum přidaných prací díky sizeof.

Takže při každé iteraci budeš raději opakovaně zjišťovat velikost pole pomocí sizeof, než abys použil makro, které se nahradí při kompilaci? Je mi jasné, že chceš, aby si velikost pole překladač odvodil sám, ale aspoň ty cykly předělej následovně:

for (new i, j = sizeof Prace_Mista; i < j; i++)
před 38 minutami, Scydo said:

bool: InPlayerAroundJob(playerid)

Záměrně je tam In, nebo je to překlep a má tam být Is?

Sdílet tento příspěvek


Link to post
Share on other sites
před 48 minutami, vEnd said:

Takže při každé iteraci budeš raději opakovaně zjišťovat velikost pole pomocí sizeof, než abys použil makro, které se nahradí při kompilaci? Je mi jasné, že chceš, aby si velikost pole překladač odvodil sám...(více)

Opraveno, díky.

(Jsem chtěl použít sizeof ze 2 důvodu: 1. zkusit něco nového a za 2. jelikož já furt všude cpu makro snad na každou kravinu co mě napadne, tak i zároveň hledám způsob jak některé vytěsnit a napadlo mě se právě vykašlat na to nejhlavnější a to MAX_JOBS. Ano, je to kktina. Ano, je to lepší způsob ale tak hej, kdyžtak si to pak každý může předělat dle sebe :d

před 48 minutami, vEnd said:

Záměrně je tam In, nebo je to překlep a má tam být Is?

Ne, je to překlep, má to být Is. Opraveno.

Sdílet tento příspěvek


Link to post
Share on other sites
On 9. 5. 2019 at 15:07, vEnd said:

Takže při každé iteraci budeš raději opakovaně zjišťovat velikost pole pomocí sizeof, než abys použil makro, které se nahradí při kompilaci?

sizeof je direktiva kompilatoru, nahradzuje sa pri kompilacii rovnako ako makro. Inak to byt ani nemoze, kedze pawn neuklada velkosti pola pri runtime. Pouzivat dalsiu premennu je preto pomalsie nez pouzit priamo sizeof...

Edited by xhunterx
  • Paráda! (+1) 1
  • Líbí se mi to! (+1) 2

Sdílet tento příspěvek


Link to post
Share on other sites
před 1 hodinou, xhunterx said:

sizeof je direktiva kompilatoru, nahradzuje sa pri kompilacii rovnako ako makro. Inak to byt ani nemoze, kedze pawn neuklada velkosti pola pri runtime. Pouzivat dalsiu premennu je preto pomalsie nez pouzit priamo sizeof...

U got me. I já se něčemu mohu přiučit. 😀 Scydo, slyšel jsi. Hunterovi věřím. 

  • Paráda! (+1) 1

Sdílet tento příspěvek


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×