Jump to content
  • 0

pomoc Označení vozidel k závodu


snake3321

Dotaz

Popis problému:

Zdravím, mám jeden problém který bych potřeboval vyřešit. Jedná se o to, že si tvořím závod.. Ovšem je tu takovej problém, že nestojím o to, aby si třeba lidi ze závodu vzali vozidlo, závod by jim třeba nešel a tak se prostě zabili, z čehož by vyplývalo, že samotné auto by se někde válelo a to přesně nechci. Potom když třeba budu závod už rušit tak by se mi hodilo odstranit všechny objekty samotného závodu, tudíž ty auta a o to mi jde.. Jak mám udělat aby nějáký příkaz odstranil vozidla jen z toho závodu? V kódu si můžete všimnout, že jediný co jsem udělal bylo to, že jsem zajistil, že při zníčení vozidla se už nerespawne, pak jsem si tam hrál ještě s OnPlayerStateChange, ale to je jasná blbost, jen tak jsem to zkoušel. Takže ještě pro vysvětlení, co potřebuji. Potřebuji příkaz který mi smaže všechna vozidla která na závodu byla hráči spawnuta. Snad jsem vše smysluplně vysvětlil, předem děkuji.

 

Chyby/varování kompilátoru a při běhu:

--

 

Kód:

 

#include 
#include 

new objekt[5];
new pickup;
new stav;
new znicit[MAX_PLAYERS];

#define SCM SendClientMessage

forward destroy(playerid);

CMD:zavodon(playerid, params[])
{
if(!IsPlayerAdmin(playerid)) return SCM(playerid, 0xFF0000AA, "[ ! ] {FFFFFF}Nejsi admin!");
{
   objekt[0] = CreateObject(8040,-2398.7000000,-2322.2000000,131.0100100,0.0000000,0.0000000,0.0000000); //object(airprtcrprk02_lvs) (1)
objekt[1] = CreateObject(8040,-2398.7002000,-2322.2002000,131.1000100,0.0000000,0.0000000,180.0000000); //object(airprtcrprk02_lvs) (2)
objekt[2] = CreateObject(984,-2397.8000000,-2197.0000000,32.9000000,0.0000000,0.0000000,298.0000000); //object(fenceshit2) (1)
objekt[3] = CreateObject(984,-2388.6001000,-2214.7000000,32.9000000,0.0000000,0.0000000,297.9990000); //object(fenceshit2) (2)
objekt[4] = CreateObject(983,-2376.3000000,-2196.2000000,33.0000000,0.0000000,0.0000000,24.0000000); //object(fenceshit3) (2)
pickup = CreatePickup(1239, 1, -2423.9079589844, -2322.2292480469, 131.34201049805, 0);
stav = 1;
}
return 1;
}

CMD:zavodoff(playerid, params[])
{
if(!IsPlayerAdmin(playerid)) return SCM(playerid, 0xFF0000AA, "[ ! ] {FFFFFF}Nejsi admin!");
{
   DestroyObject(objekt[0]);
DestroyObject(objekt[1]);
DestroyObject(objekt[2]);
DestroyObject(objekt[3]);
DestroyObject(objekt[4]);
DestroyPickup(pickup);
stav = 0;
}
return 1;
}

CMD:zavod(playerid, params[])
{
if(stav == 1)
{
   SetPlayerPos(playerid, -2402.5329589844, -2316.9487304688, 131.33438110352);
}
else SCM(playerid, 0xFF0000AA, "[ ! ] {FFFFFF}Závod není vytvořen!");
return 1;
}

public OnPlayerPickUpPickup(playerid, pickupid)
{
if(pickupid == pickup)
{
   ShowPlayerDialog(playerid, 47, DIALOG_STYLE_MSGBOX, "{FFFFFF}Závod", "Chcete se připojit do závodu?", "Ano", "Ne");
}
return 1;
}

public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
if(dialogid == 47)
{
   if(response)
   {
       PutPlayerInVehicle(playerid, CreateVehicle(495, -2379.5444, -2197.6877, 34.0459, 0, 211, 211, 60), 0);
       znicit[playerid] = 1;
   }
   return 1;
}
return 0;
}

public OnVehicleDeath(vehicleid, killerid)
{
if(GetVehicleModel(vehicleid) == 495)
{
   for(new i=0; i < MAX_PLAYERS; i++)
   {
       if(IsPlayerConnected(i))
       {
           if(znicit[i] == 1)
           {
           DestroyVehicle(vehicleid);
           znicit[i] = 0;
           }
       }
   }
}
return 1;
}

public OnPlayerStateChange(playerid, newstate, oldstate)
{
if(oldstate == PLAYER_STATE_DRIVER && newstate == PLAYER_STATE_ONFOOT)
{
   new veh = GetPlayerVehicleID(playerid);
   if(GetVehicleModel(veh) == 495 && znicit[playerid] == 1)
   {
       SetTimerEx("destroy", 20000, false, "i", playerid);
   }
}
return 1;
}

public destroy(playerid)
{
new vehic = GetPlayerVehicleID(playerid);
DestroyVehicle(vehic);
return 1;
}

 

 

 

Dodatečné poznámky:

--

Link to comment
Share on other sites

11 odpovědí na tuto otázku

Recommended Posts

  • 0
  • Hlavní moderátor

Je tu pár možností:

 

1. Vytvoříš si pole pro všechny hráče (třeba raceCar[MAX_PLAYERS]) a když se hráč připojí do závodu, vytvoříš mu auto, posadíš ho do něj a ID toho vytvořeného auta uložíš do toho pole (raceCar[playerid] = id_hracova_vytvoreneho_auta). Po ukončení závodu smažeš auto daného hráče (ID je v raceCar[playerid], popř. cyklem projedeš a zničíš auta všech závodníků) a proměnnou vynuluješ (raceCar[playerid] = 0, popř. cyklem pro všechny závodníky).

 

2. Pokud v módu nemáš nic, co by přidávalo auta za běhu serveru (nemyslím staticky přidaná vozidla spawnutá při spuštění módu), třeba admin příkaz /adminveh nebo tak něco, tak si můžeš zjistit, od jakého ID se spawnují vozidla pro závod a ty pak mazat.

 

Momentálně mě nic lepšího nenapadá.

  • Líbí se mi to! (+1) 2
Link to comment
Share on other sites

  • 0

Omlouvám se, ale jsem s pawnem prakticky na začátku jelikož jsem jednou na cca rok přestal.. Jak by měl vypadat příkladově nějáký ten cyklus prosím? Děkuji

 

//edit

V pořádku.. Přišel jsem na tento cyklus, snad nebude dělat potíže, ještě jsem nic netestoval s druhým hráčem..

 

 

for(new i; i < racecar[playerid]; i++)
{
   new vehicl = GetPlayerVehicleID(playerid);
   DestroyVehicle(vehicl);
   racecar[playerid] = 0;
}

 

 

Edited by snake3321
Link to comment
Share on other sites

  • 0

Omlouvám se, ale jsem s pawnem prakticky na začátku jelikož jsem jednou na cca rok přestal.. Jak by měl vypadat příkladově nějáký ten cyklus prosím? Děkuji

 

//edit

V pořádku.. Přišel jsem na tento cyklus, snad nebude dělat potíže, ještě jsem nic netestoval s druhým hráčem..

 

 

for(new i; i < racecar[playerid]; i++)
{
   new vehicl = GetPlayerVehicleID(playerid);
   DestroyVehicle(vehicl);
   racecar[playerid] = 0;
}

 

 

Ten cyklus máš zle...

CMD:zavodon(playerid, params[])
{
if(!IsPlayerAdmin(playerid)) return SCM(playerid, 0xFF0000AA, "[ ! ] {FFFFFF}Nejsi admin!");
{
   objekt[0] = CreateObject(8040,-2398.7000000,-2322.2000000,131.0100100,0.0000000,0.0000000,0.0000000); //object(airprtcrprk02_lvs) (1)
objekt[1] = CreateObject(8040,-2398.7002000,-2322.2002000,131.1000100,0.0000000,0.0000000,180.0000000); //object(airprtcrprk02_lvs) (2)
objekt[2] = CreateObject(984,-2397.8000000,-2197.0000000,32.9000000,0.0000000,0.0000000,298.0000000); //object(fenceshit2) (1)
objekt[3] = CreateObject(984,-2388.6001000,-2214.7000000,32.9000000,0.0000000,0.0000000,297.9990000); //object(fenceshit2) (2)
objekt[4] = CreateObject(983,-2376.3000000,-2196.2000000,33.0000000,0.0000000,0.0000000,24.0000000); //object(fenceshit3) (2)
pickup = CreatePickup(1239, 1, -2423.9079589844, -2322.2292480469, 131.34201049805, 0);
stav = 1;
}
return 1;
}

CMD:zavodoff(playerid, params[])
{
if(!IsPlayerAdmin(playerid)) return SCM(playerid, 0xFF0000AA, "[ ! ] {FFFFFF}Nejsi admin!");
{
   DestroyObject(objekt[0]);
DestroyObject(objekt[1]);
DestroyObject(objekt[2]);
DestroyObject(objekt[3]);
DestroyObject(objekt[4]);
DestroyPickup(pickup);
stav = 0;
}

Toto si použil hore, v podstate na rovnakom princípe postavíš to mazanie vozidiel (to ti už vEnd písal).

for(new playerid; playerid <= GetPlayerPoolSize(); playerid++) // spustíme cyklus pre všetkých hráčov
{
   if(racecar[playerid] == 0) continue; // ak sa racecar pre daného hráča rovná 0, preskočíme na ďalšie ID
   DestroyVehicle(racecar[playerid]); // zničíme vozidlo s ID, ktoré je uložené v racecar[playerid]
   racecar[playerid] = 0; // racecar nastavíme na 0
}

// POZOR!!! Ak v móde nemáš iné vozidlá (napr. pri štarte GM nevytváraš), bude to robiť hlúposti s prvým vozidlom!
  • Líbí se mi to! (+1) 1
Link to comment
Share on other sites

  • 0

Dobře, děkuji moc všem. Něják jsem si s tím hrál a celkově se vracel zpět k pawnu.. No jde to pomalu, ale chce to čas.. Každopádně měl bych ještě jeden dotaz ohledně cyklu který tu psal Quiter

 

for(new playerid; playerid <= GetPlayerPoolSize(); playerid++) // spustíme cyklus pre všetkých hráčov
{
if(racecar[playerid] == 0) continue; // ak sa racecar pre daného hráča rovná 0, preskočíme na ďalšie ID
DestroyVehicle(racecar[playerid]); // zničíme vozidlo s ID, ktoré je uložené v racecar[playerid]
racecar[playerid] = 0; // racecar nastavíme na 0
}

 

zajistí mi tento cyklus i to, že se například vozidla odstraní i přes to, že se hráč například odpojí? Vím, že funguje tak, že aniž by hráč seděl ve vozidle, funguje to.. Ale jak je to když se odpojí?

 

Měl bych ještě ke všemu jednu malou otázečku a to tu, že potřebuji něják zajistit, aby se hráčovi například zrušil Checkpoint když si zníčí to svoje vozidlo, ovšem aby to pracovalo logicky jen pro toho hráče.. Vzhledem k tomu, že v Callbacku OnVehicleDeath není playerid.. Nemám tušení jak zajistit vykonání příkazu pro konkrétního hráče.. Jak toho tedy docílím? Předem děkuji.

Link to comment
Share on other sites

  • 0

Ten cyklus(který mimochodem započítá i nepřítomné hráče) zničí vozidla všem hráčům(a nastaví hodnotu), kteří mají hodnotu racecar jinou, než 0.

 

Pokud chceš zničit vozidla někomu konkrétnímu, nepoužívej cyklus, ale pouze přidej do podmínky tu proměnnou racecar hráčovi při odpojování ze serveru.

Edited by Ernst Remer
Link to comment
Share on other sites

  • 0

Dobře, děkuji moc všem. Něják jsem si s tím hrál a celkově se vracel zpět k pawnu.. No jde to pomalu, ale chce to čas.. Každopádně měl bych ještě jeden dotaz ohledně cyklu který tu psal Quiter

 

 

zajistí mi tento cyklus i to, že se například vozidla odstraní i přes to, že se hráč například odpojí? Vím, že funguje tak, že aniž by hráč seděl ve vozidle, funguje to.. Ale jak je to když se odpojí?

 

Měl bych ještě ke všemu jednu malou otázečku a to tu, že potřebuji něják zajistit, aby se hráčovi například zrušil Checkpoint když si zníčí to svoje vozidlo, ovšem aby to pracovalo logicky jen pro toho hráče.. Vzhledem k tomu, že v Callbacku OnVehicleDeath není playerid.. Nemám tušení jak zajistit vykonání příkazu pro konkrétního hráče.. Jak toho tedy docílím? Předem děkuji.

Máš pravdu, s tým som nepočítal. Zničí to vozidlá aj odpojených hráčov, ale nie ak sa odpojí hráč s najvišším ID (playerid)...

 

Môžeš to opraviť tým, že do disconnectu pridáš kontrolu a mazanie (rovnaký kód ako v cykle s výnimkou FOR), alebo zmeníš GetPlayerPoolSize() na MAX_PLAYERS

 

________________________________________

 

Ten cyklus(který mimochodem započítá i nepřítomné hráče) zničí vozidla všem hráčům(a nastaví hodnotu), kteří mají hodnotu racecar jinou, než 0.

 

Pokud chceš zničit vozidla někomu konkrétnímu, nepoužívej cyklus, ale pouze přidej do podmínky tu proměnnou racecar hráčovi při odpojování ze serveru.

 

Je niečo zlé, že to kontroluje aj "neprítomného" hráča? S hráčom tam predsa nič nerobím, akurát s premennou ktorá využíva jeho ID

Link to comment
Share on other sites

  • 0

Dobře, děkuji moc.. Ještě jedna malinká otázečka.. Když mám tedy například callback OnVehicleDeath, který mi neumožní najít konkrétního hráče (playerid), jak mám tedy pracovat s proměnnými u kterých je playerid potřeba? Konkrétně by se mi to hodilo k tomu, že když si hráč zníčí vozidlo, které měl k tomu závodu, zníčí se mu i například Checkpointy, nebo se vynulují některé hodnoty proměnných..

Link to comment
Share on other sites

  • 0

ale nie ak sa odpojí hráč s najvišším ID (playerid)...

Cože? icon_e_biggrin.gif To ti zajišťuje podmínka v cyklu, zda je v inte. menší nebo rovno. To znamená, že započítá i poslední(nejvyšší) id. A pokud se začne cyklit po tom, co hráč odejde, tak vezme jiného hráče s nejvyšším id.

 

alebo zmeníš GetPlayerPoolSize() na MAX_PLAYERS

To je blbost. Akorát z jednotek uděláš stovky.

 

Jak jsem říkal, na "vyřazení" ze závodu při odchodě nepotřebuješ nic, kromě jedné podmínky v callbacku:

public OnPlayerDisconnect(...) {

	if (je_v_závodě == 1 /* == true */) {

		DestroyVehicle(...)
		je_v_zavode[playerid] = 0; /* /false */
	}
}
(pokud chceš u jednoho hráče. Pokud pro celý závod, to pak ano použi cyklus, ale s jiným jménem proměnné než playerid, protože callback ho už má)

 

Je niečo zlé, že to kontroluje aj "neprítomného" hráča? S hráčom tam predsa nič nerobím, akurát s premennou ktorá využíva jeho ID

 

Napsal jsem snad, že je to špatně? Šlo jenom o mojí skromnou poznámku. Když už využíváš keywords(což tady používá fakt málokdo), mohl jsi dodat obsáhlejší ukázku, například fci jestliže je hráč přítomen, pokud ne, přeskočit. Chápeme se?

 

Dobře, děkuji moc.. Ještě jedna malinká otázečka.. Když mám tedy například callback OnVehicleDeath, který mi neumožní najít konkrétního hráče (playerid), jak mám tedy pracovat s proměnnými u kterých je playerid potřeba? Konkrétně by se mi to hodilo k tomu, že když si hráč zníčí vozidlo, které měl k tomu závodu, zníčí se mu i například Checkpointy, nebo se vynulují některé hodnoty proměnných..

Ale ten callback má na to arg. jenom se jmenuje killerid ne playerid.

 

a pro vypnutí checkpointu použi DisablePlayerCheckpoint()

Edited by Ernst Remer
Link to comment
Share on other sites

  • 0

Cože? icon_e_biggrin.gif To ti zajišťuje podmínka v cyklu, zda je v inte. menší nebo rovno. To znamená, že započítá i poslední(nejvyšší) id. A pokud se začne cyklit po tom, co hráč odejde, tak vezme jiného hráče s nejvyšším id.

 

To je blbost. Akorát z jednotek uděláš stovky.

 

Jak jsem říkal, na "vyřazení" ze závodu při odchodě nepotřebuješ nic, kromě jedné podmínky v callbacku:

public OnPlayerDisconnect(...) {

	if (je_v_závodě == 1 /* == true */) {

		DestroyVehicle(...)
		je_v_zavode[playerid] = 0; /* /false */
	}
}
(pokud chceš u jednoho hráče. Pokud pro celý závod, to pak ano použi cyklus, ale s jiným jménem proměnné než playerid, protože callback ho už má), preto som mu povedal aby využil tvoju radu, ALEBO dal do cyklu MAX_PLAYERS

 

 

Napsal jsem snad, že je to špatně? Šlo jenom o mojí skromnou poznámku. Když už využíváš keywords(což tady používá fakt málokdo), mohl jsi dodat obsáhlejší ukázku, například fci jestliže je hráč přítomen, pokud ne, přeskočit. Chápeme se?

 

Ale ten callback má na to arg. jenom se jmenuje killerid ne playerid.

 

a pro vypnutí checkpointu použi DisablePlayerCheckpoint()

 

 

1) Áno, lenže ak má premenná racecar[48] (48 je momentálne najvyšie ID na servery) uložené id vozidla, a hráč 48 sa odpojí, tak cyklus toto vozidlo nezmaže

2) Alternatíva k tomu disconnectu

3) Prepáč, myslel som že si mi niečo vyčítal :d

Link to comment
Share on other sites

  • 0
  • Hlavní moderátor
například fci jestliže je hráč přítomen, pokud ne, přeskočit

Proč by to dělal? Bavíme se o odstraňování závodních vozidel. Hráč s ID 5 se připojí do závodu, do racecar pro jeho ID se uloží ID vytvořeného vozidla. Ale ejhle, co čert nechtěl, hráč se uprostřed závodu odpojí. V poli pro jeho ID ovšem ID vozidla stále zůstává. Proto správný cyklus pro smazání všech závodních vozidel je ten, co sem dal Quiter:

    for(new i; i < sizeof(racecar); i++) // spustíme cyklus pro vsechny vozidla
    {
    if(racecar[i] == 0) continue; // ak sa racecar pre daného hráča rovná 0, preskočíme na ďalšie ID
    DestroyVehicle(racecar[i]); // zničíme vozidlo s ID, ktoré je uložené v racecar[i]
    racecar[i] = 0; // racecar nastavíme na 0
    }

Takhle nemusíte ani řešit OnPlayerDeath pro zničení vozidel, po konci závodu to smaže i vozidla již odpojených hráčů.

Link to comment
Share on other sites

  • 0
  • Globální moderátor

Quiter mel pravdu, GetPlayerPoolSize vraci nejvyssi ID a v pripade ze se odpoji nejvyssi hrac (pripadne vic hracu s nejvyssimi ID) algoritmus nemusi a ani nebude spravne fungovat. Nejvhodnejsi variantou je to co uvedl vEnd s upravenym limitem – sizeof(racecar), ten nam zabezpeci ze projede cele pole

 

Ovsem ted je potreba jeste zajistit pripad prepisovani vozidel – tedy pripad, kdy se pripoji do zavodu hrac s ID 5, vytvori se pro neho vozidlo racecar[5] = id_vozidla1 a odpoji se.

Pripoji se novy hrac, ktery bude mit ID 5, prihlasi se do zavodu a prepise se jiz existujici promenna racecar[5] = id_vozidla2. 

Takze jeste osetrit v Disconnectu pokud je v zavodu. V tomhle mel zas pravdu Ernest.

 

V podstate tady mel kazdej kus pravdy, ale dost zalezi na tom jak ten zavod mas implementovany. Shrnu ti pripady at to mas jednotnejsi a jak si to udelas (jak se ti to bude hodit) je na tobe.

 

Predpokladam, ze vytvareni vozidel uz mas spravne:

 

Pripad 1) Zavod skonci, je potreba smazat vozidla

for(new i; i < sizeof(racecar); i++) // spustíme cyklus pro vsechny vozidla
    {
    if(racecar[i] == 0) continue; // ak sa racecar pre daného hráča rovná 0, preskočíme na ďalšie ID
    DestroyVehicle(racecar[i]); // zničíme vozidlo s ID, ktoré je uložené v racecar[i]
    racecar[i] = 0; // racecar nastavíme na 0
    }

Pripad 2) Hrac poskodil vozidlo do takoveho stavu, ze se znici

public OnVehicleDeath(vehicleid, killerid)
{
    // vehicleid - vozidlo, ktere bylo zniceno
    // killerid - id hrace, ktery ho "znicil", resp oznamil zniceni vozidla. Vetsinou se jedna o nejblizsiho hrace tedy ridic nebo pasazer.

    /* Hezky popis je na wiki http://wiki.sa-mp.com/wiki/OnVehicleDeath, kde je vypis pri zavolani tohoto callbacku. 
       Muzes si vyzkouset koho hlasi jako killerid pri niceni
    */
    
    if(racecar[killerid]){ // pokud racecar neni nulove, ekvivalentni s racecar[killerid] != 0
        DestroyVehicle(racecar[killerid]);
        racecar[killerid] = 0;
    }
    return 1;
}

Pripad 3) Hrac vystoupi ze zavodniho vozidla (pripad, ktery mas osetreny ty a neni az tak uplne zly, rozhodne to neni blbost. Akorat ti ho upravim)

public OnPlayerStateChange(playerid, newstate, oldstate)
{
    if(oldstate == PLAYER_STATE_DRIVER && newstate == PLAYER_STATE_ONFOOT) {
        if(racecar[playerid]) {
            DestroyVehicle(racecar[playerid]);
            racecar[playerid] = 0;
        }
    }
}
return 1;
}

Ovsem jedna se jen o kostru niceni vozidel. Do nich si ovsem jeste vloz svoje veci okolo zavodu jako jestli zavod zacal / skoncil. Vyhodit hrace z vozidla aby ho to nebuglo pri zniceni, zpravy o diskvalifikaci apod. icon_e_smile.gif

  • Líbí se mi to! (+1) 1
Link to comment
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
×
×
  • Create New...