
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.
|
Lacostii
Rejestracja: 03.12.2012Aktualnie: Nieaktywny
Poza forum Ostatnio: 25.09.2018 01:38





Statystyki
- Grupa: Użytkownik
- Całość postów: 172
- Odwiedzin: 4 840
- Tytuł: Profesjonalista
- Wiek: Wiek nie został ustalony
- Urodziny: Data urodzin nie została podana
-
Płeć
Mężczyzna
-
Lokalizacja
Poland
Narzędzia użytkownika
Ostatnio byli
#650038 [ROZWIĄZANE] emit_sound - zasięg dźwieku do ustalenia?
Napisane przez BlackPerfum
w 15.07.2014 08:50

#650036 [ROZWIĄZANE] emit_sound - zasięg dźwieku do ustalenia?
Napisane przez GwynBleidD
w 15.07.2014 08:30
Co do att, oznacza osłabienie, a nie wzmocnienie. 0.00 to maksymalny zasięg. Ogólnie osłabienie polega na tym, jak bardzo ma dźwięk zanikać z odległością, czyli będąc w miejscu emitującym dźwięk słyszymy go zawsze z maksymalną głośnością, bez względu na att. Będąc 5 kroków od niego już att robi różnicę. Wpływa to oczywiście na zasięg dźwięku.
Nie jestem pewny, ale wartość 0.00 oznaczała chyba całkowity brak zanikania, czyli nieograniczony zasięg.
#628700 Informacje o stałych pev
Napisane przez DarkGL
w 28.03.2014 12:53
Dzięki pomocy osób z rangą Power User i Support Team przygotowaliśmy listę stałych pev używanych wraz z pev i set_pev i wyjaśnieniem na co wpływa dana zmienna.
Jest to tłumaczenie angielskiej wersji takiego opisu więc czasami naprawdę ciężko było znaleźć dobre tłumaczenie .
Szczególne podziękowania dla
15427
21503
27559
Bezpośredni link http://amxx.pl/pevresearch
Strona jest też dodana do zakładki Dodatki AMXX w górnym menu.
#597485 [ROZWIĄZANE] 1<<14 - Jak rozumieć taką wartość czasu?
Napisane przez sebul
w 27.12.2013 19:00
W tym przypadku zwykłe potęgowanie liczby 2.
A jeśli chcesz ułatwienia, to korzystaj z tego
#define bitfloatvalue(%1) floatround((%1)*(1<<12))
i po prostu używasz tego z liczbami rzeczywistymi/zmiennoprzecinkowymi.
#585313 Team SemiClip (nieoficjalny) - optymalizacja kodu
Napisane przez ^Grzyboo
w 14.11.2013 16:17
#583878 [ROZWIĄZANE] Pytania o get_maxplayers(), szanse na perk, if(random(x))...
Napisane przez GwynBleidD
w 09.11.2013 14:57
Sprostowanie do 1.1, TAK, MOŻE WYSTĄPIĆ ID WIĘKSZE!!!
Jest to ogólny bug HLDS, gdy ktoś wychodzi z serwera ID jest zwalniane, ale jeśli nastąpi timeout może się zdarzyć tak, że HLDS dalej ID gracza zajmuje, jednak ogólną liczbę graczy na serwerze zmniejsza. Mamy wtedy do czynienia z zamrożonym modelem na respie (jak zabijemy gracza to zamiast upaść tak dziwnie drży) lub nawet niewidzialnym modelem na respie, co jest jeszcze gorsze, bo runda się nie kończy i nie wiadomo gdzie strzelać, żeby ten model zabić...
AMX jednak nie dostaje już żadnych informacji o tym graczu, dostaje nawet informację, że opuścił serwer. Jednak wchodzący nowy gracz dostanie ID następne, gdyż to ID HLDS uważa za zajęte nadal. W ten sposób ID może osiągnąć większą wartość..
Co ciekawe, id gracza może w takim przypadku osiągnąć nawet 33 albo i więcej. Jednak nie należy się tym przejmować, AMX wewnętrznie posiada mechanizm identyfikujący gracza jako gracza po ID. Każde ID większe od 32 dla AMX oznacza entity i gracz z większym numerem nawet nie wywoła forwardu client_putinserver i tym podobnych... po prostu dla AMX będzie niewidoczny
Dlatego najlepszą praktyką co do tablic jest wpisywanie wielkości 33, ni mniej, ni więcej.
#583760 [ROZWIĄZANE] Pytania o get_maxplayers(), szanse na perk, if(random(x))...
Napisane przez sebul
w 08.11.2013 22:54
3. Czyli tak jak myślałem, dlatego zadziwia mnie kod w tym temacie: http://amxx.pl/topic...między-klasami/
if(random(19)) { cod_inflict_damage(idattacker, this, float(get_user_health(this))-damage+1.0, 0.0, idinflictor, damagebits); }Oni to mają za 1/20 (19) , natomiast ja to widzę jako 18/19, a niby im działa, więc ja jestem lekko zdezorientowany co jest teraz właściwe.
if(!random(19))
I będzie 1/19.
#583756 [ROZWIĄZANE] Pytania o get_maxplayers(), szanse na perk, if(random(x))...
Napisane przez
Aemiksowy
w 08.11.2013 22:37
1.2 nie. Nawet jak ustawisz hideslot 1, to pobierana wartość jest z "linii startowej". Może nie do końca dobrze mówię, bo nie wiem czy tak rzeczywiście jest, ale mam nadzieję, że sens będzie zrozumiały. Zwróć uwagę, że wpisując "status" w konsoli wyświetla Ci się poprawna wartość slotów (nie bierze pod uwagę ukryte). Funkcja get_maxplayers też będzie poprawnie zwracać to, bez względu na to czy masz ukryte. Mimo, że nie ma tu dużego związku, to chodzi o sam sens przekazu. Przynajmniej ja zawsze testując to nie zauważyłem, aby hideslot był brany pod uwagę w tej funkcji.
1.3 Sama nazwa wskazuje co to jest zmienna globalna. Nie potrzeba filozofii czy tutków do tego.
To, czy zrobisz:
new tablica[24] lub new tablica[33] (od razu) bądź tak, jak wyżej nie zrobi dużej różnicy, bo to nie o ten sens chodzi. Chodzi o to, że czasem niepotrzebnie jest tworzenie dla zmiennej takiej wielkości tablicy. Polecam poczytać też: http://darkgl.amxx.p...amieci-pluginu/
#583723 [ROZWIĄZANE] Pytania o get_maxplayers(), szanse na perk, if(random(x))...
Napisane przez sebul
w 08.11.2013 21:29
1.2. Nie słyszałem nic o tym, ale na pewno nie, zresztą u mnie przez to problemów nie ma.
1.3. Nie da się w taki sposób utworzyć zmiennej, jak już to poprzez zdefiniowanie stałej.
2. Ponownie losuje, żeby w ogóle nie dawało perku, to trzeba w silniku to ustawić.
3. Prawdą logiczną jest wszystko inne od 0, a nie tylko 1.
4. X razy.
#486600 Byty, istotne zdarzenia i studium pluginu
Napisane przez
Gość
w 03.12.2012 20:04
Byty, istotne zdarzenia i studium pluginu
Scripting AMXX
[kotwica=cel]Cel[/kotwica]
- Nauka o istocie bytów
- Przedstawienie istotnych zdarzeń
- Tworzenie optymalnych pluginów
- Znajomość podstawowych metod komunikacji gracza z serwerem
- Informacje wstępne
Spoiler- Znajomość obsługi AMXX
- Umiejętność programowania
- Podstawowa znajomość Pawna
- Racjonalne tworzenie algorytmów
- Umiejętność korzystania z manuala
- Edytor Pawna wraz z kompilatorem AMXX
- Zrozumienie istoty działania AMXX
- Znajomość podstawowych funkcji
- Umiejętność importowania bibliotek
- Zwracanie odpowiedniej wartości funkcji
- Odczytywanie argumentów wiadomości
Poza poznanymi już funkcjami związanymi z samym pluginem,
istnieją także forwardy, wywoływane na podstawie czynności gracza.
Przykładowe funkcje to:
- client_connect
wywoływana w momencie rozpoczęcia łączenia się gracza z serwerem
- client_authorized
wywoływana w momencie uzyskania przez gracza flag uprawnień
- client_putinserver
wywoływana w momencie pobrania wszelkich wymaganych plików i wejścia do gry
- client_disconnect
wywoływana w momencie wyjścia gracza z serwera
- client_infochanged
wywoływana w momencie zmiany informacji klienta, np. nicku
- client_command
wywoływana w momencie wpisania jakiejkolwiek komendy do konsoli
Uwaga! Podczas, gdy client_connect jest pierwszą czynnością dokonywaną w momencie łączenia się gracza z serwerem,
nie można ustalić kolejności wykonywania funkcji client_authorized oraz client_putinserver, mogą być one wykonane w różnej kolejności.
Dlatego zaleca się dla niektórych instrukcji, sprawdzenie wywołania obydwu tych funkcji poprzez utworzenie prostej funkcji client_ingame
Warto znać parę tych podstawowych forwardów z biblioteki amxmodx, gdyż często się przydają.
[kotwica=client_cmd]client_cmd[/kotwica]
Serwer może wykonać pewne komendy u klienta tak, jakby on sam je wykonał.
Służy ku temu funkcja client_cmd

przyjmuje numer identyfikacyjny gracza, a za drugi komendę do wykonania u klienta.
Pozostałe opcjonalne argumenty uzupełniają zmienne w ciągu polecenia z 2. argumentu.
Przykład zastosowania. Funkcja ustawia graczowi interp na 0.01 w momencie pełnego połączenia z serwerem:
public client_ingame(){
new Float:interp=0.01;
client_cmd(id, "ex_interp %d", interp);
}
[kotwica=HLTV_event]HLTV event[/kotwica]
Pierwszym, użytecznym zdarzeniem, jakie warto zanotować, to event HLTV.
register_event("HLTV", "newRound", "a", "1=0", "2=0");
Jest to zdarzenie, które wysyłane jest do HLTV, jednak można je wykorzystać,
by ustalić moment rozpoczęcia Freezetime, bądź, jak kto woli, początku rundy.
Wziąć należy jednak pod uwagę, że zdarzenie wykonywane jest, poza początkiem
rundy, także tuż po zakończeniu wykonywania się komend startowych serwera.
Uwaga! Podczas, gdy forwardy takie, jak client_authorized


event HLTV ejst eventem globalnym, a więc wywoływany jest jednokrotnie i nie przyjmuje parametru gracza.
Oznacza to, że użycie newRound(id) jest nieprawidłowe, gdyż id nie jest identyfikatorem gracza.
[kotwica=Spawn_graczy]Spawn graczy[/kotwica]
Spawn, czyli pojawienie się gracza na mapie, jest zdarzeniem, które powinniśmy wykorzystać,
jeśli chcemy operować na graczu, zanim ten przystąpi do gry, ale po rozpoczęciu nowej rundy.
to tutaj dodajemy bonusowe bronie, lub ustawiamy dodatkowe życie dla danego gracza.
W celu kompleksowej rejestracji spawnu, skorzystamy z eventu Ham_Spawn funkcji RegisterHam

RegisterHam(Ham_Spawn, "player", "spawned", 1);
Pierwszy parametr oznacza typ rejestrowanego zdarzenia, w tym przypadku spawn, drugi parametr to klasa bytu.
[kotwica=Byty]Byty[/kotwica]
I tutaj warto wspomnieć o bytach. Otóż niemal każdy obiekt na mapie to byt, czyli istota wirtualna.
Ponadto, każdy byt ma swój unikalny numer identyfikacyjny, klasę i pewne właściwości, jak np. model.
Specjanymi bytami są gracze o numerach identyfikacyjnych od 1 do maksymalnej liczby graczy,
których maksymalną liczbą może być 32. Każdy byt posiada pewną klasę, klasą gracza jest "player".
Ponadto, każdy byt posiada pewne dane prywatne, jak np. model, życie, czy czas następnego procesu myślenia.
Proces myślenia to zdarzenie cykliczne wykonywane co pewien czas, który może być modyfikowany.
Przykładowo, granat wybuchowy posiada proces myślenia, który dokonuje jego eksplozji.
Modyfikacja czasu procesu myślenia tego bytu, czyli wpływanie na dane prywatne bytu,
pozwoli na szybszy, bądź wolniejszy wybuch granatu, lub całkowitą blokadę wybuchu.
Pobieranie danych prywatnych z bytu możliwe jest dzięki następującym funkcjom.
Na forum znajdziemy listę niektórych danych prywatnych bytów w temacie R3Xa, Offsety pdata.
Większość funkcji tak naprawdę operuje na bytach, jak np. funkcja cs_get_user_money

która pobiera jedynie wartość prywatną od określonego gracza.
[kotwica=Spawn_graczy_cd]Spawn graczy, c.d.[/kotwica]
Trzecim argumentem użytej funkcji RegisterHam jest nazwa funkcji, która zostanie wywołana po spawnie,
a ostatni argument ustawiony na 1, odpowiada za wykonanie funkcji po skończonym procesie ożywiania gracza.
W przeciwieństwie do zdarzenia HLTV, funkcja spawned przyjmie za argument id gracza ożywianego.
Jednakże, funkcja spawnu wykonywana jest także podczas wchodzenia gracza na serwer, będącego
jeszcze martwym, dlatego chcąc operować na właśnie ożywionym graczu, należy sprawdzić, czy żyje.
Funkcja Ham_Spawned dla każdego gracza wykonywana jest zawsze po evencie HLTV, ale przed startem rundy.
[kotwica=Start_rundy]Start rundy[/kotwica]
Po ożywieniu wszystkich graczy i zakończeniu czasu zamrożenia (freezetime), następuje event globalny Round_Start.
register_logevent("roundStart", 2, "1=Round_Start");
Jest to zdarzenie notowane, więc użyjemy funkcji register_logevent

[kotwica=Koniec_rundy]Koniec rundy[/kotwica]
Alternatywnie do początku rundy, koniec rundy rejestrujemy dzięki informacji logowanej.
register_logevent("roundEnd", 2, "1=Round_End");
Koniec rundy może nastąpić na wskutek wielu innych czynników, co należy mieć na uwadze.
Ponadto, koniec rundy nie musi nastąpić nigdy, lub nastąpić rzadziej, niż początek rundy.
[kotwica=Reset_rundy]Reset rundy[/kotwica]
register_logevent("GameCommencing", 2, "1=Game_Commencing");
Każdorazowo, w momencie dołączenia do gry pierwszego gracza do drużyny, której przeciwna posiada już wrogów,
dokonywany jest reset gry poprzez wywołanie eventu GameCommencing. Należy to wziąć pod uwagę przy liczeniu rund.
[kotwica=Liczenie_rund]Liczenie rund[/kotwica]
W celu policzenia rundy, potrzebować będziemy zmiennej globalnej, którą zainicjujemy tuż po imporcie bibliotek.
#include <amxmodx>Zmienna globalna zostanie początkowo zainicjowana wartością zero, co nam odpowiada, gdyż runda się jeszcze nie rozpoczęła.
new runda;
public plugin_init(){
register_plugin("Liczenie rund", "0.1", "benio101");
}
Co rundę będziemy inkrementować zmienną runda, a zrobimy to w funkcji newRound eventu HLTV.
#include <amxmodx>Jednakże, ponieważ funkcja HLTV wykonywana jest tuż po starcie serwera,
new runda;
public plugin_init(){
register_plugin("Liczenie rund", "0.1", "benio101");
register_event("HLTV", "newRound", "a", "1=0", "2=0");
}
public newRound(){
++runda;
}
a po dołączeniu zazwyczaj drugiego gracza, wykonywany jest reset, przez co ponownie
wywoływany będzie event HLTV, rozpoczęlibyśmy grę właściwą ze zmienną runda równą 2 zamiast 0.
Dlatego też zarejestrujemy event Game_Commencing i w momencie jego wystąpienia, zresetujemy licznik rund.
I tym samym sposobem, uzyskamy zmienną runda, która przechowuje numer aktualnej rundy:
#include <amxmodx>
new runda;
public plugin_init(){
register_plugin("Liczenie rund", "0.1", "benio101");
register_event("HLTV", "newRound", "a", "1=0", "2=0");
register_logevent("GameCommencing", 2, "1=Game_Commencing");
}
public newRound(){
++runda;
}
public GameCommencing(){
runda=0;
}
[kotwica=studium]Studium pluginu: Bonus pieniężny[/kotwica]
Teraz, w ramach praktyki, napiszemy prosty plugin, który w 2., 5. i 10. rundzie,
jednemu, losowemu graczowi przyzna 5000 dolarów na zachętę lepszej gry.
Ponadto, postaramy się, by jeden gracz nie uzyskał nagrody kilkukrotnie.
Zaczniemy od powyższej bazy, liczącej rundy, będzie to nam potrzebne.
Dodamy event nowej rundy i kod będzie wyglądał następująco:
#include <amxmodx>Zacznijmy od warunku. Najprostsza metoda:
new runda;
public plugin_init(){
register_plugin("Bonus pieniezny", "0.1", "benio101");
register_event("HLTV", "newRound", "a", "1=0", "2=0");
register_logevent("roundStart", 2, "1=Round_Start");
register_logevent("GameCommencing", 2, "1=Game_Commencing");
}
public newRound(){
++runda;
}
public GameCommencing(){
runda=0;
}
public roundStart(){
// dodanie w 2., 5. i 10. rundzie losowemu graczowi 5000$
}
public roundStart(){Jednak niepotrzebnie się powtarzamy, stąd pomysł na
if(runda==2){
// dodanie losowemu graczowi 5000$
}
if(runda==5){
// dodanie losowemu graczowi 5000$
}
if(runda==10){
// dodanie losowemu graczowi 5000$
}
}
public roundStart(){to rozwiązanie jest dobre, ale nie najlepsze. Dlaczego?
if(runda==2 || runda==5 || runda==10){
// dodanie losowemu graczowi 5000$
}
}
Dokonujemy tak naprawdę trzech porównań, choć zawsze porównujemy zmienną runda.
[kotwica=switch]Switch[/kotwica]
Do porównywania jednej zmiennych do kolejno wielu różnych, nadaje się idealnie funkcja switch.
Dzięki zastosowaniu funkcji switch, zaoszczędzimy zasoby sprzętowe i skrócimy czas wykonywania skryptu. Poprawne rozwiązanie:
public roundStart(){
switch(runda){
case 2,5,10:{
// dodanie losowemu graczowi 5000$
}
}
}
Teraz przejdziemy do losowania gracza. w tym celu będziemy musieli poszukać wśród żywych graczy na serwerze poprzez funkcję for.
W tym celu utworzymy sobie tablicę gracze i w niej będziemy przechowywać numery identyfikacyjne osób, kwalifikujących się do losowania.
Dodatkowo, utworzymy zmienną liczbaGraczy, która będzie przechowywać liczbę kandydatów do nagrody, czyli, de facto, żywych graczy.
każdy gracz, który jest żywy, zostanie dodany to tablicy gracze, a następnie liczbaGraczy ulegnie inkrementacji.
#include <amxmodx>Jednakże, maksymalna liczba graczy nie musi wynosić 32.
new runda;
public plugin_init(){
register_plugin("Bonus pieniezny", "0.1", "benio101");
register_event("HLTV", "newRound", "a", "1=0", "2=0");
register_logevent("roundStart", 2, "1=Round_Start");
register_logevent("GameCommencing", 2, "1=Game_Commencing");
}
public newRound(){
++runda;
}
public GameCommencing(){
runda=0;
}
public roundStart(){
switch(runda){
case 2,5,10:{
new gracze[32];
new liczbaGraczy;
for(new id=1; id<=32; ++id){
if(is_user_alive(id)){
gracze[liczbaGraczy]=id;
++liczbaGraczy;
}
}
}
}
}
Maksymalna liczba graczy (czy też liczba slotów), może być inna.
[kotwica=get_maxplayers]get_maxplayers[/kotwica]
Aby pobrać liczbę slotów, użyjemy funkcji get_maxplayers

public roundStart(){Jednakże, przy każdej iteracji pętli for, dokonujemy zapytania, poprzez MetaModa:P
switch(runda){
case 2,5,10:{
new gracze[32];
new liczbaGraczy;
for(new id=1; id<=get_maxplayers(); ++id){
if(is_user_alive(id)){
gracze[liczbaGraczy]=id;
++liczbaGraczy;
}
}
}
}
}
aż do silnika gry, co jest istotnym błędem i powinniśmy to zoptymalizować.
W tym celu, zainicjujemy zmienną globalną maxPlayers i uzupełnimy ją
w funkcji plugin_cfg i nie będziemy musieli więcej zmiennej pobierać.
Jest to rozwiązanie na tyle dobre, że funkcja plugin_cfg wykonywana jest tylko jednokrotnie
i dzięki pobraniu liczby slotów do zmiennej globalnej, oszczędzimy kolejnych, identycznych
zapytań, do silnika gry. Oczywiście, w naszej pętli, zastąpimy funkcję get_maxplayers

#include <amxmodx>
new runda, maxPlayers;
public plugin_init(){
register_plugin("Bonus pieniezny", "0.1", "benio101");
register_event("HLTV", "newRound", "a", "1=0", "2=0");
register_logevent("roundStart", 2, "1=Round_Start");
register_logevent("GameCommencing", 2, "1=Game_Commencing");
}
public plugin_cfg(){
maxPlayers=get_maxplayers();
}
public newRound(){
++runda;
}
public GameCommencing(){
runda=0;
}
public roundStart(){
switch(runda){
case 2,5,10:{
new gracze[32];
new liczbaGraczy;
for(new id=1; id<=maxPlayers; ++id){
if(is_user_alive(id)){
gracze[liczbaGraczy]=id;
++liczbaGraczy;
}
}
}
}
}
[kotwica-losowanie]Losowanie[/kotwica]
Teraz przejdziemy do losowania zwycięzcy.
W tym celu, użyjemy funkcji random

przyjmuje pseudo-losową liczbę naturalną z zakresu [0;x)
Funkcja jest świetnie przystosowana do naszej tablicy gracze,
przyjęwszy za argument zmienną liczbaGraczy, od razu wyłoni nam zwycięzcę.
public roundStart(){Podobną funkcją do random
switch(runda){
case 2,5,10:{
new gracze[32];
new liczbaGraczy;
for(new id=1; id<=maxPlayers; ++id){
if(is_user_alive(id)){
gracze[liczbaGraczy]=id;
++liczbaGraczy;
}
}
new zwyciezca=gracze[random(liczbaGraczy)];
}
}
}


która losuje liczbę z zakresu od pierwszego argumentu, do drugiego włącznie.
Funkcja random


random(x) ⇔ random_num(0, x-1)
Pomimo jednoznaczności, zawsze używanie funkcji random_num

jego prostszej wersji random

[kotwica=nagroda]Nagroda[/kotwica]
Mając wyłonionego zwycięzcę, dodamy mu 5000$ i poinformujemy o tym jedynie zwycięzcę, by innym nie było smutno.
W tym celu, będziemy tak naprawdę modyfikować jedną z informacji prywatnych pdata zwycięskiego gracza, co można
byłoby zrobić funkcją set_pdata_int i get_pdata_int, jednak skorzystamy z prostszych natywów biblioteki cstrike.
#include <amxmodx>
#include <cstrike>
new runda, maxPlayers;
public plugin_init(){
register_plugin("Bonus pieniezny", "0.1", "benio101");
register_event("HLTV", "newRound", "a", "1=0", "2=0");
register_logevent("roundStart", 2, "1=Round_Start");
register_logevent("GameCommencing", 2, "1=Game_Commencing");
}
public plugin_cfg(){
maxPlayers=get_maxplayers();
}
public newRound(){
++runda;
}
public GameCommencing(){
runda=0;
}
public roundStart(){
switch(runda){
case 2,5,10:{
new gracze[32];
new liczbaGraczy;
for(new id=1; id<=maxPlayers; ++id){
if(is_user_alive(id)){
gracze[liczbaGraczy]=id;
++liczbaGraczy;
}
}
new zwyciezca=gracze[random(liczbaGraczy)];
cs_set_user_money(zwyciezca, cs_get_user_money(zwyciezca)+5000);
client_print(zwyciezca, print_chat, "Na zachete lepszej gry, wygrales 5000 dolarow!");
}
}
}
[kotwica=define]#define[/kotwica]
Zamiast pisać długą linijkę
cs_set_user_money(zwyciezca, cs_get_user_money(zwyciezca)+5000);zwłaszcza, jeśli wykorzystywalibyśmy ją wielokrotnie,
warto stworzyć sobie definicję preprocesora, udającą funkcję dodawania pieniędzy.
Zaimplementujemy zatem funkcję add_user_money(id, ammount). W tym celu,
stworzymy pod importowanymi bibliotekami, definicję preprocesora:
#define add_user_money(%1,%2) cs_set_user_money(%1,cs_get_user_money(%1)+%2)
I w miejsce starej, długiej linijki, wstawimy nowo utworzoną funkcję preprocesora add_user_money
#include <amxmodx>
#include <cstrike>
#define add_user_money(%1,%2) cs_set_user_money(%1,cs_get_user_money(%1)+%2)
new runda, maxPlayers;
public plugin_init(){
register_plugin("Bonus pieniezny", "0.1", "benio101");
register_event("HLTV", "newRound", "a", "1=0", "2=0");
register_logevent("roundStart", 2, "1=Round_Start");
register_logevent("GameCommencing", 2, "1=Game_Commencing");
}
public plugin_cfg(){
maxPlayers=get_maxplayers();
}
public newRound(){
++runda;
}
public GameCommencing(){
runda=0;
}
public roundStart(){
switch(runda){
case 2,5,10:{
new gracze[32];
new liczbaGraczy;
for(new id=1; id<=maxPlayers; ++id){
if(is_user_alive(id)){
gracze[liczbaGraczy]=id;
++liczbaGraczy;
}
}
new zwyciezca=gracze[random(liczbaGraczy)];
add_user_money(zwyciezca, 5000);
client_print(zwyciezca, print_chat, "Na zachete lepszej gry, wygrales 5000 dolarow!");
}
}
}
[kotwica=limitacja_nagrod]Limitacja nagród[/kotwica]
Teraz dodamy ostatnią rzecz, czyli ograniczymy możliwość wygrania kilkukrotnie przez tę samą osobę.
W tym celu utworzymy sobie tablicę globalną typu logicznego i będziemy przechowywać informację o tym,
który gracz wygrał już swoją nagrodę. Łącznie, nasz plugin ma teraz dwie zmienne i jedną tablicę logiczną:
new runda, maxPlayers, bool:nagrodzeni[33];
W momencie sprawdzania danego gracza w pętli, dodamy warunek na brak bycia nagrodzonym:
public roundStart(){Dlaczego jednak warunek w koniunkcji umieściłem po lewej stronie?
switch(runda){
case 2,5,10:{
new gracze[32];
new liczbaGraczy;
for(new id=1; id<=maxPlayers; ++id){
if(!nagrodzeni[id] && is_user_alive(id)){
gracze[liczbaGraczy]=id;
++liczbaGraczy;
}
}
new zwyciezca=gracze[random(liczbaGraczy)];
add_user_money(zwyciezca, 5000);
client_print(zwyciezca, print_chat, "Na zachete lepszej gry, wygrales 5000 dolarow!");
}
}
}
[kotwica=dzialanie_koniunkcji_i_alternatywy]Działanie koniunkcji i alternatywy[/kotwica]
Koniunkcja działa w taki sposób, że spełniona jest, gdy wszystkie warunki są spełnione.
Gdy choć jeden z nich nie jest spełniony, to cała koniunkcja nie jest spełniona i
nie ma potrzeby sprawdzać kolejnych warunków. Podobnie jest z alternatywą, jeśli
choć jeden z warunków zostanie spełniony, nie ma potrzeby sprawdzać kolejnych.
[kotwica=optymalizacja_warunkow_logicznych]Optymalizacja warunków logicznych[/kotwica]
Tak samo działa nasz AMXX, jeśli jeden z warunków koniunkcji nie zostanie spełniony,
to kolejne nie są sprawdzane. Istotne uwagi jest, że warunki sprawdzane są kolejno od lewej strony.
Wiedząc to, powinniśmy najbardziej prawdopodobne warunki koniunkcji ustalać możliwie najbardziej po prawej stronie,
a te mniej prawdopodobne po lewej, a dla alternatywy zaś odwrotnie, warunki najbardziej prawdopodobne winny być po lewej stronie.
[kotwica=unikanie_zapytan_do_HLDS]Unikanie zapytań do HLDS[/kotwica]
Dlaczego więc umieściłem nasz warunek !nagrodzeni[id] po lewej stronie, gdy wydaje się, że jest on bardziej prawdopodobny,
niż to, że gracz jest martwy? Ponieważ staram się możliwie unikać mocno obciążających maszynę i długich zapytań do
silnika HLDS poprzez Metamoda:P, a funkcja is_user_alive

wszelkie warunki nie wykonujące zapytań do silnika, umieszczać możliwie po lewej stronie koniunkcji czy alternatyw.
[kotwica=kolejne_warunki_studium]Kolejne warunki studium[/kotwica]
W przypadku braku odpowiednich kandydatów, nie dodajemy losujemy zwycięzcy, nie dajemy pieniędzy ani nie informujemy gracza o zwycięstwie.
W tym celu, musimy te 3 instrukcje wykonać warunkowo, o ile zmienna liczbaGraczy jest niezerowa.
if(liczbaGraczy){Tworzenie zapytania if(x!=0) gdzie x to warunek jest niepotrzebne i wystarczy samo if(x)
new zwyciezca=gracze[random(liczbaGraczy)];
add_user_money(zwyciezca, 5000);
client_print(zwyciezca, print_chat, "Na zachete lepszej gry, wygrales 5000 dolarow!");
}
Ostatecznie, funkcja if i tak zwraca prawdę lub fałsz, jedynkę lub zero.
Zwycięzcę trzeba oznaczyć jako wygranego, więc wewnątrz warunku, dopisujemy
nagrodzeni[zwyciezca]=true;
Od teraz, do końca mapy, gracz nie będzie miał szansy wygrać 5000 dolarów.
Jednakże, zwycięski gracz mógł w międzyczasie wyjść z serwera, a w miejsce jego numeru identyfikacyjnego mógł wejść inny gracz.
Dlatego, w momencie wchodzenia gracza na serwer, ustawimy mu wartość zwycięstwa na false, by miał szansę brać udział w losowaniu.
Możliwość reconnecta zwycięzcy nie przeraża nas pomimo otrzymania kolejnej szansy na zwycięstwo, gdyż całą gotówkę w
momencie opuszczenia serwera straci, a jeśli serwer korzysta z pluginu, zapisującego stan gracza, jak np. pieniędzy,
można dodać prosty natyw do tego pluginu, który zapisywałby także i tę, zerojedynkową informację o graczu.
W tym celu, skorzystamy z forwardu client_putinserver

public client_putinserver(id){
nagrodzeni[id]=false;
}
Gotowy kod z naszego studium, plugin na bonus 5000$ dla losowego gracza z limitem 1 wygranej na mapę w 2., 5. i 10. rundzie:
#include <amxmodx>
#include <cstrike>
#define add_user_money(%1,%2) cs_set_user_money(%1,cs_get_user_money(%1)+%2)
new runda, maxPlayers, bool:nagrodzeni[33];
public plugin_init(){
register_plugin("Bonus pieniezny", "0.1", "benio101");
register_event("HLTV", "newRound", "a", "1=0", "2=0");
register_logevent("roundStart", 2, "1=Round_Start");
register_logevent("GameCommencing", 2, "1=Game_Commencing");
}
public plugin_cfg(){
maxPlayers=get_maxplayers();
}
public newRound(){
++runda;
}
public GameCommencing(){
runda=0;
}
public roundStart(){
switch(runda){
case 2,5,10:{
new gracze[32];
new liczbaGraczy;
for(new id=1; id<=maxPlayers; ++id){
if(!nagrodzeni[id] && is_user_alive(id)){
gracze[liczbaGraczy]=id;
++liczbaGraczy;
}
}
if(liczbaGraczy){
new zwyciezca=gracze[random(liczbaGraczy)];
add_user_money(zwyciezca, 5000);
client_print(zwyciezca, print_chat, "Na zachete lepszej gry, wygrales 5000 dolarow!");
nagrodzeni[zwyciezca]=true;
}
}
}
}
public client_putinserver(id){
nagrodzeni[id]=false;
}
#581668 [ROZWIĄZANE] is_user_connected(id) - Koniecznie pierwszym warunkiem?
Napisane przez GwynBleidD
w 31.10.2013 11:51
#578460 Jak przerobić model na przezroczysty?
Napisane przez mastah7991
w 18.10.2013 07:40
#564319 [ROZWIĄZANE] Jak zrobić losowy pev_rendercolor?
Napisane przez BlackPerfum
w 17.08.2013 06:41
#559723 Automat do reklam
Napisane przez
Flk
w 30.07.2013 17:06
Witam dziś wam przedstawiam bota do reklam.
Bota robiłem z nudów oraz z chęci nauki php Niestety jakiś dzieciak sprzedaje go w sieci oraz podszywa się pod autora.
1. Tworzysz nowa baze danych.
2. Importujesz Plik sql.sql do bazy danych.
3. Wypełniasz dane do bazy danych w configs/head_config.php
Bot jest słabo napisany ale działa.
W pliku rar macie baze danych sql.sql.
Zakaz zmiany stopki oraz kopiowania na inne fora.
#560088 Automat do reklam
Napisane przez
Flk
w 31.07.2013 21:41
1. Działa na 100% zobacz http://adv.ct8.pl/
No stronka z wyglądu działa, to oczywiste, ale reklam nie idzie robić. Dodałem tam na próbę jedno forum, ale oczywiście ta baza nadal tam jest pusta, więc nie idzie zamówić, a jak u siebie uzupełniłem, to tak jak pisałem, zacina się i ładuje bez końca i z innej karty wejść już się na automat nie da, trzeba restartować stronę.
Z lenistwa
korzystałem z tego bota sam i wiem że działa na 1000%
Nic nam po zapewnieniach, że działa jak nam nie działa, bo albo nie potrafimy używać poprawnie (Prosimy o wyjaśnienie) lub coś w bazie/plikach nie tak.
Źle dodane forum na końcu linka ma być ukośnik "\"
1. Tworzysz nowa baze danych.
2. Importujesz Plik sql.sql do bazy danych.
3. Wypełniasz dane do bazy danych w configs/head_config.php
4. Dodajesz w bazie danych w tabeli cena. Cenne oraz ile reklam ma zrobić .
- AMXX.pl: Support AMX Mod X i SourceMod
- → Przeglądanie profilu: Reputacja: Lacostii
- Regulamin