Prymex 1 Napisano 12 Stycznia 2020 Witam mam 2 problemy po krótce je opiszę. A więc pierwszy polega na tym iż mam funkcje GetRandomInt i wiem jak zrobić tak aby losowało int tych graczy którzy są aktualnie na serwerze. Druga z zagwostek na dziś jak zaczymać na jakiś czas gracza w miejscu aby nie mógł się ruszyć, wpadłem na pomysł aby zrobić timer i na czas timera zmienić szybkość client'owi na 0. Aczkolwiek nie wiem czy jest to dobry pomysł może są jakieś szybsze wygodniejsze sposoby. Z góry dzięki za pomoc. Pozdrawiam i życzę miłego kodowania. Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach
Vasto_Lorde Napisano 12 Stycznia 2020 2. Nie ma szybszego sposobu niż zrobienie timera niestety 1. Co do losowego gracza można to zrobić tak: stock int getRandomPlayer() { int players[65]; int players_counter = 0; for (int i = 1; i <= MaxClients; i++) if(IsClientValid(i)) { players[players_counter] = i; players_counter++; } return players[GetRandomInt(0, players_counter-1)]; } stock bool IsClientValid(int client) { return (client > 0 && client <= MaxClients && IsClientInGame(client) && !IsClientSourceTV(client)); } Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach
MAGNET 1 Napisano 12 Stycznia 2020 Co do zamrażania, to jeśli chcesz aby ofiara nie mogła też ruszać myszką: //Odmrozenie int buttons = GetEntityFlags(client); SetEntityFlags(client, (buttons &= ~FL_FROZEN)) //zamrozenie int buttons = GetEntityFlags(client); SetEntityFlags(client, (buttons |= FL_FROZEN)) Jeśli zaś chodzi o losowanie: nie możesz po prostu pobrać sobie ilości graczy i wylosować przez: GetRandomInt(1,Ilosc_graczy()) Załóżmy, że na serwerze masz 4 graczy. Mają oni przypisane indexy: 1 2 3 4. W momencie, gdy gracz z ID=2 wyjdzie na serwerze masz 3 graczy o indexach 1 3 4. Losowa wartość mogłaby natrafić na 2 - osobę niepołączoną Skoro tak, to może po prostu losować gracza i patrzeć, czy jest połączony - i robić to aż do skutku? bool wylosowano = false; int winner_index = -1; while (wylosowano == false) { winner_index = GetRandomInt(1,MAXPLAYERS); if (IsClientInGame(wylosowany) wylosowano = true; } // w tym miejscu mamy wygrany index Teoretycznie jest to jakieś rozwiązanie, choć baardzo słabe. O ile przy większej ilości graczy (np. 30) ma to jeszcze sens, to w sytuacji, gdyby na serwerze było ich 3, to szansa na trafienie dobrego gracza to 3/65 (4%!). Kto wie, ile razy pętla będzie się musiała obrócić zanim kogoś trafisz...do tego czasu możesz nawet złapać crasha serwera. A jeśli nie będzie nikogo? Wtedy mamy do czynienia z nieskończoną pętlą i w efekcie pewnym crashem. Oczywiście w trakcie pisania mojego wywodu vasto zdążył już podać prawidłowe rozwiązanie problemu - iterujemy pętlą po wszystkich indexach. Jesli znajdziemy gracza - wpychamy go do tablicy, by na samym końcu zwrócić z niej wartość pod losowym indexem w przedziale <0,ilość_znalezionych_graczy> Jedyny problem jaki tutaj widzę w tym kodzie to sytuacja, gdy na serwerze nie ma żadnego gracza - wówczas funkcja zwróci niechybnie 0. Dlatego pamiętaj o tym, żeby zawsze sprawdzać, czy funkcja nie zwróciła 0 - jeśli tak, na serwerze nie ma żadnego gracza. PS: Jeśli chcesz dowiedzieć się o co do cholery chodzi w kodzie na górze posta (dot. zamrażania, co to za |= &= ~flags itd.), to zapraszam tutaj: Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach
Prymex Napisano 12 Stycznia 2020 @Vasto_Lorde doszedłem do takiego czegoś : #include <sourcemod> #include <sdktools> #include <sdkhooks> #pragma semicolon 1; public void OnClientPutInServer(int client) { SDKHook(client, SDKHook_OnTakeDamage, OnTakeDamage); HookEvent("round_start", Event_RoundStart); } public Action OnTakeDamage(int victim, int &attacker, int &inflictor, float &damage, int &damagetype) { if (damagetype & DMG_SLASH) { SetEntityRenderColor(victim, 255, 0, 0, 255); SetEntityRenderColor(attacker, 0); PrintHintTextToAll("Goni : %n", victim); damage = 0.0; return Plugin_Handled; } return Plugin_Continue; } public Action Event_RoundStart(Event event, const char[] name, bool dontBroadcast) { int random = getRandomPlayer(); PrintToChatAll("%i", random); PrintHintTextToAll("Goni : %n", random); SetEntityRenderColor(random, 255, 0, 0, 255); return Plugin_Continue; } stock int getRandomPlayer() { int players[65]; int players_counter = 0; for (int i = 1; i <= MaxClients; i++) if(IsClientValid(i)) { players[players_counter] = i; players_counter++; } return players[GetRandomInt(0, players_counter-1)]; } stock bool IsClientValid(int client) { return (client > 0 && client <= MaxClients && IsClientInGame(client) && !IsClientSourceTV(client)); } Niestety zamist raz wysolować jednego gracza losuje jakieś 20 nie wiem dlaczego. Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach
Vasto_Lorde Napisano 12 Stycznia 2020 Ponieważ HookEvent round_start rejestrujesz w OnClientPutInServer. Więc za każdym razem jak wejdzie ktokolwiek na serwer, będzie się round_start wykonywał o jeden więcej razy. Rejestruj to w OnPluginStart Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach
Prymex Napisano 12 Stycznia 2020 @Vasto_Lorde Bardzo ci dziękuję ale jeszcze jeden problem Na początku rundy nie działa PrintHintTextToAll("Goni : %n", random); i pewnie dlatego że nie mogę się odnieść do random prawda ? Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach
Vasto_Lorde Napisano 12 Stycznia 2020 Nie działa prawdopodobnie dlatego, że używasz %n do wyświetlenia integer'a. %n oznacza formatowanie string'a. String to ciąg znaków, integer to liczba bez przecinka. Do formatowania intger'a użyj %i Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach
Prymex Napisano 12 Stycznia 2020 @Vasto_Lorde Ale ja chciałbym wyświetlić tam nick gracza. Z tego co dobrze pamiętam u Magneta na filmach było że %n z client wyświetli nick. Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach
Vasto_Lorde Napisano 12 Stycznia 2020 %N wyświetla nick gracza %n wyświetla string 😉 Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach
Prymex Napisano 12 Stycznia 2020 Faktycznie dzięki serdeczne. Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach
Prymex Napisano 12 Stycznia 2020 int buttons = GetEntityFlags(victim); SetEntityFlags(victim, (buttons |= FL_FROZEN)); timerer = CreateTimer(10.0, Odmrozenie(victim),_, TIMER_DATA_HNDL_CLOSE); PrintCenterText(victim, "Spowrotem możesz gonić za : %t", timerer); // C:\Users\Prymex\Desktop\scripting\ganiany.sp(24) : error 017: undefined symbol "timerer" // C:\Users\Prymex\Desktop\scripting\ganiany.sp(24) : error 100: function prototypes do not match // C:\Users\Prymex\Desktop\scripting\ganiany.sp(25) : error 017: undefined symbol "timerer" Czy tym razem ktoś zdefiniuje problem ? Przez Vasto_Lorde, 12 Stycznia 2020 Dodawaj proszę kod w tagi "code" Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach
Vasto_Lorde Napisano 12 Stycznia 2020 Hej, dobrym pomysłem jest zaglądanie do tematu ze spisem errorów, gdzie niektóre rzeczy są już wytłumaczone Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach
Prymex Napisano 12 Stycznia 2020 @Vasto_Lorde A jak zrobić aby timer był w PrintCenterText A i jeszcze jedno pytanie ponieważ ja goniącemu daje color czerwony A chciałbym później sprawdzać kto jest goniący A po kolorze sprawdzanie go będzie trochę trwało Jak szybsza metoda typu nadanie flagi Albo coś Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach
Inext 1 Napisano 12 Stycznia 2020 (edytowane) 34 minuty temu, Prymex napisał: @Vasto_Lorde A jak zrobić aby timer był w PrintCenterText A i jeszcze jedno pytanie ponieważ ja goniącemu daje color czerwony A chciałbym później sprawdzać kto jest goniący A po kolorze sprawdzanie go będzie trochę trwało Jak szybsza metoda typu nadanie flagi Albo coś Możesz stworzyć boola czyli wartość logiczną true/false i sprawdzać czy dana osoba posiada tego bool'a ustawionego na true bool NazwaBoola[MAXPLAYERS +1]; // Tworzenie boola // Ustawianie wartości boola NazwaBoola[client] = true; NazwaBoola[client] = false; // // if sprawdzający czy gracz posiada boola ustawionego na true if(NazwaBoola[client] == true) { // Funkcja zostaje wykonana kiedy wartośc jest ustawiona na true } else { // Funkcja zostaje wykonana kiedy wartośc jest ustawiona na false } Edytowane 12 Stycznia 2020 przez Inext Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach
Prymex Napisano 12 Stycznia 2020 (edytowane) Kolejny błąd na mojej drodzę nie wiem dlaczego ma prawo bytu ale po 1 starcie pluginy PrintHintTextToAll działa poprawnie ale powinien działać po każdym rozpoczęciu rundy niestety tak się nie dzieje. public Action Event_RoundStart(Event event, const char[] name, bool dontBroadcast) { int random = getRandomPlayer(); int userid = GetClientUserId(random); int client = GetClientOfUserId(userid); PrintToChatAll("%i", random); NazwaBoola[client] = true; PrintHintTextToAll("Goni : %N", client); SetEntityRenderColor(client, 255, 0, 0, 255); return Plugin_Continue; } I właśnie linijka PrintHintTextToAll("Goni : %N", client); działa tylko raz po starcie pluginy. A powinna działać co nową rundę. Edytowane 12 Stycznia 2020 przez Prymex Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach
Vasto_Lorde Napisano 12 Stycznia 2020 1 minutę temu, Prymex napisał: Kolejny błąd na mojej drodzę nie wiem dlaczego ma prawo bytu ale po 1 starcie pluginy PrintHintTextToAll działa poprawnie ale powinien działać po każdym rozpoczęciu rundy niestety tak się nie dzieje. Najlepiej jakbyś podesłał teraz cały kod pluginu 😋 Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach
Prymex Napisano 12 Stycznia 2020 @Vasto_Lorde Prosze bardzo #include <sourcemod> #include <sdktools> #include <sdkhooks> #pragma semicolon 1; bool NazwaBoola[MAXPLAYERS +1]; public void OnClientPutInServer(int client) { SDKHook(client, SDKHook_OnTakeDamage, OnTakeDamage); } public OnPluginStart( ) { HookEvent("round_start", Event_RoundStart); HookEvent("round_end", Event_RoundEnd); } public Action OnTakeDamage(int victim, int &attacker, int &inflictor, float &damage, int &damagetype) { if (damagetype & DMG_SLASH && NazwaBoola[attacker]==true) { SetEntityRenderColor(victim, 255, 0, 0, 255); SetEntityRenderColor(attacker, 0); PrintHintTextToAll("Goni : %N", victim); NazwaBoola[victim] = true; NazwaBoola[attacker] = false; int buttons = GetEntityFlags(victim); SetEntityFlags(victim, (buttons |= FL_FROZEN)); Handle timer = CreateTimer(10.0, Odmrozenie, victim); PrintCenterText(victim, "Spowrotem możesz gonić za : %t", timer); damage = 0.0; return Plugin_Handled; } return Plugin_Continue; } public Action Event_RoundStart(Event event, const char[] name, bool dontBroadcast) { int random = getRandomPlayer(); int userid = GetClientUserId(random); int client = GetClientOfUserId(userid); PrintToChatAll("%i", random); NazwaBoola[client] = true; PrintHintTextToAll("Goni : %N", client); SetEntityRenderColor(client, 255, 0, 0, 255); return Plugin_Continue; } public Action Event_RoundEnd(Event event, const char[] name, bool dontBroadcast) { int players[65]; int players_counter = 0; for (int i = 1; i <= MaxClients; i++) if(IsClientValid(i)) { players[players_counter] = i; int userid = GetClientUserId(players[players_counter]); int client = GetClientOfUserId(userid); NazwaBoola[client] = false; players_counter++; } return Plugin_Continue; } stock int getRandomPlayer() { int players[65]; int players_counter = 0; for (int i = 1; i <= MaxClients; i++) if(IsClientValid(i)) { players[players_counter] = i; players_counter++; } return players[GetRandomInt(0, players_counter-1)]; } stock bool IsClientValid(int client) { return (client > 0 && client <= MaxClients && IsClientInGame(client) && !IsClientSourceTV(client)); } public Action Odmrozenie(Handle timer, int client){ int buttons = GetEntityFlags(client); SetEntityFlags(client, (buttons &= ~FL_FROZEN)); NazwaBoola[client] = false; KillTimer(timer); } Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach
Inext Napisano 12 Stycznia 2020 4 godziny temu, Prymex napisał: Kolejny błąd na mojej drodzę nie wiem dlaczego ma prawo bytu ale po 1 starcie pluginy PrintHintTextToAll działa poprawnie ale powinien działać po każdym rozpoczęciu rundy niestety tak się nie dzieje. U mnie na serwerze ten błąd nie występuj. Obstawiam że sprawdzałeś to na zwykłym serwerze , w drużynie terrotystów i wyskakiwała ci informacja, że posiadasz bombe w EQ. Udostępnij tę odpowiedź Odnośnik do odpowiedzi Udostępnij na innych stronach