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

Operacje na obrażeniachPrzykłady


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

#1 Fili:P

    Godlike

  • Power User

Reputacja: 754
Guru

  • Postów:1 679
  • Imię:Darek
  • Lokalizacja:Warszawa
Offline

Napisano 18.02.2013 19:47

W tym poradniku postaram się opisać kilka operacji związanych z obrażeniami.

Wstęp

  • Opis argumentów funkcji RegisterHam
  • Argument 1 = Ham_TakeDamage: Ten argument oznacza jakie zdarzenie chcemy "złapać". Skoro chcemy przechwycić zadawanie obrażeń, będzie to Ham_TakeDamage.
  • Argument 2 = "player": Drugi argument oznacza klasę u której chcemy "złapać" zdarzenie, w tym wypadku zadanie obrażeń. Ta wartość oznacza gracza.
  • Argument 3 = "fw_TakeDamagePre": Jest to po prostu nazwa funkcji, za pomocą której będziemy "łapać" zdarzenie.
  • Argument 4: W tym wypadku nie podaje jego wartości, ponieważ jego domniemana wartość to 0. 0 oznacza, iż chcemy złapać moment przed zdarzeniem ( daje to możliwość modyfikacji parametrów zdarzenia ). 1 oznacza, że nie mamy już wpływu na przebieg zdarzenia.

2. Opis argumentów zdarzenia Ham_TakeDamage

  • this - identyfikator istoty ( bytu, entu, etc. ), która otrzyma/ła obrażenia
  • idinflictor - identyfikator bytu zadającego obrażenia, zwykle idinflictor == idattacker, jednak kiedy obrażenia zadaje przykładowo granat to w tym argumencie właśnie będzie jego identyfikator.
  • idattacker - identyfikator osoby, istoty, bytu, etc. która atakuje this-a
  • Float:damage - ilość zadawanych obrażeń ( zwróć uwagę iż jest to liczba typu float )
  • damagebits - bit typ/ów zadanych obrażeń ( więcej: http://amxx.pl/topic/28881-damagebits/ )

a) Natychmiastowe zabicie z X broni:
wymagane moduly

hamsandwich
amxmodx

opis
1. Zarejestruj w plugin_init zdarzenie z modułu hamsandwich, Ham_TakeDamage.
RegisterHam( Ham_TakeDamage, "player", "fw_TakeDamagePre" );

2. "Utwórz" funkcję:
public fw_TakeDamagePre( this, idinflictor, idattacker, Float:damage, damagebits )
{
// tu będzie kod
}

3. Wewnątrz funkcji, sprawdź czy this i idattacker żyją:
if( !is_user_alive( idattacker ) || !is_user_alive( this ) )
return HAM_IGNORED;

4. Jeżeli chcesz, aby było natychmiastowe zabicie z granatu dodaj taki warunek:
if( idinflictor == idattacker )
return HAM_IGNORED;
if( !(damagebits & (1<<24) ) )
return HAM_IGNORED;
  • Teraz dodajemy natychmiastowe zabicie z HE:
    SetHamParamFloat( 4, float( get_user_health( this ) + 1) );
    return HAM_HANDLED;
  • Jeżeli chcesz mieć ułamkową szansę na natychmiastowe zabicie przed powyższym kodem dodaj:
    if( !random( X ))
    return HAM_IGNORED;

    Jako x należy podstawić wartość zakresu, np. jeżeli dasz 5, to szansa będzie 1/5.

4. Jeżeli chcesz, aby było natychmiastowe zabicie z innej broni niż granat dodaj warunek:

if( idifnlictor != idattacker )
return HAM_IGNORED;

  • Teraz sprawdźmy z jakiej broni zabito:
    if( get_user_weapon( idattacker ) != Y )
    return HAM_IGNORED;
    Jako Y należy podstawić definicje identyfikatora naszej broni.
  • Teraz dodajemy natychmiastowe zabicie z naszej broni:
    SetHamParamFloat( 4, float( get_user_health( this ) + 1) );
    return HAM_HANDLED;
  • Jeżeli chcesz mieć ułamkową szansę na natychmiastowe zabicie przed powyższym kodem dodaj:
    if( !random( X ))
    return HAM_IGNORED;

    Jako x należy podstawić wartość zakresu, np. jeżeli dasz 5, to szansa będzie 1/5.

B) Odporność ( % ) na obrażenia
opis
1. Zarejestruj w plugin_init zdarzenie z modułu hamsandwich, Ham_TakeDamage.

RegisterHam( Ham_TakeDamage, "player", "fw_TakeDamagePre" );

2. "Utwórz" funkcję:
public fw_TakeDamagePre( this, idinflictor, idattacker, Float:damage, damagebits )
{
// tu będzie kod
}

3. Wewnątrz funkcji, sprawdź czy this i idattacker żyją:
if( !is_user_alive( idattacker ) || !is_user_alive( this ) )
return HAM_IGNORED;

4. Teraz dodajemy już ostatnie 2 linie:
SetHamParamFloat( 4, damage * ( 1.00 - ( O_ILE_PROCENT_ZMNIEJSZAMY_OBRAZENIA / 100 ) ) );
return HAM_HANDLED;

Chyba nie muszę tłumaczyć co podstawiamy za O_ILE_PROCENT_ZMNIEJSZAMY_OBRAZENIA.

c) Obrażenia większe o %
opis
1. Zarejestruj w plugin_init zdarzenie z modułu hamsandwich, Ham_TakeDamage.
RegisterHam( Ham_TakeDamage, "player", "fw_TakeDamagePre" );

2. "Utwórz" funkcję:
public fw_TakeDamagePre( this, idinflictor, idattacker, Float:damage, damagebits )
{
// tu będzie kod
}

3. Wewnątrz funkcji, sprawdź czy this i idattacker żyją:
if( !is_user_alive( idattacker ) || !is_user_alive( this ) )
return HAM_IGNORED;

4. Teraz dodajemy już ostatnie 2 linie:
SetHamParamFloat( 4, damage * ( 1.00 + ( O_ILE_PROCENT_ZWIĘKSZAMY_OBRAZENIA / 100 ) ) );
return HAM_HANDLED;

Chyba nie muszę tłumaczyć co podstawiamy za O_ILE_PROCENT_ZWIĘKSZAMY_OBRAZENIA.

d) Szansa na pełną absorpcję obrażeń
opis
1. Zarejestruj w plugin_init zdarzenie z modułu hamsandwich, Ham_TakeDamage.
RegisterHam( Ham_TakeDamage, "player", "fw_TakeDamagePre" );

2. "Utwórz" funkcję:
public fw_TakeDamagePre( this, idinflictor, idattacker, Float:damage, damagebits )
{
// tu będzie kod
}

3. Wewnątrz funkcji, sprawdź czy this i idattacker żyją:
if( !is_user_alive( this ) )
return HAM_IGNORED;

4. W poniższym kodzie jako X wstaw szansę na absorpcję ( 1/X ):
if( !random( X ))
return HAM_IGNORED;

5. Teraz dodajemy już ostatnie 2 linie:
return HAM_SUPERCEDE;


Jeżeli macie jeszcze jakieś pomysły na nowe podpunkty dotyczące operacji na obrażeniach, proszę pisać śmiało w komentarzach :)


  • +
  • -
  • 3

#2 sebul

    Godlike

  • Przyjaciel

Reputacja: 2 035
Godlike

  • Postów:5 411
  • Steam:steam
  • Imię:Sebastian
  • Lokalizacja:Ostrołęka
Offline

Napisano 19.02.2013 19:08

SetHamParamFloat( 4, float( get_user_health( this ) + 1) );

To nie zabija natychmiast, a przynajmniej nie w każdym przypadku.
  • +
  • -
  • 0

Posiadam TBM (inaczej PTB), które działa dużo lepiej niż zwykłe PTB, nawet na modach z lvlami. Zainteresowany? Proszę bardzo


#3 Fili:P

    Godlike

  • Autor tematu
  • Power User

Reputacja: 754
Guru

  • Postów:1 679
  • Imię:Darek
  • Lokalizacja:Warszawa
Offline

Napisano 20.02.2013 09:48

SetHamParamFloat( 4, float( get_user_health( this ) + 1) );

To nie zabija natychmiast, a przynajmniej nie w każdym przypadku.

Masz na myśli brak wliczonego współczynniku pancerza ?
  • +
  • -
  • 0

#4 Jak się nazwać

    Wszechmogący

  • Power User

Reputacja: 169
Profesjonalista

  • Postów:617
  • Imię:a
  • Lokalizacja:a
Offline

Napisano 20.02.2013 11:41

Wszędzie:
random_num( 1, x ) != 1
-->
!random(x)

SetHamParamFloat( 4, 0.0 );
return HAM_HANDLED;
-->
return HAM_SUPERCODE

  • +
  • -
  • 2
Pisze na zamówienie statystyki pod nvault. GG: 15600964

#5 Fili:P

    Godlike

  • Autor tematu
  • Power User

Reputacja: 754
Guru

  • Postów:1 679
  • Imię:Darek
  • Lokalizacja:Warszawa
Offline

Napisano 20.02.2013 14:00

Po operacjach zwracamy HAM_HANDLED, aby zatwierdzić zmiany.


  • +
  • -
  • 0

#6 sebul

    Godlike

  • Przyjaciel

Reputacja: 2 035
Godlike

  • Postów:5 411
  • Steam:steam
  • Imię:Sebastian
  • Lokalizacja:Ostrołęka
Offline

Napisano 20.02.2013 14:15

Ktoś się chyba pomylił i źle podpowiedział

if( !random( X ))
return HAM_IGNORED;

na
if(random( X ))
return HAM_IGNORED;

dopiero teraz będzie 1/x szansy na brak obrażeń.

Po operacjach zwracamy HAM_HANDLED, aby zatwierdzić zmiany.

Jeśli zmieniasz obrażenia, czy coś tam jeszcze, to wtedy piszesz HAM_HANDLED, ale skoro ma blokować całe obrażenia, to należy zwrócić HAM_SUPERCODE, bez żadnego zmieniania obrażeń na 0.

SetHamParamFloat( 4, float( get_user_health( this ) + 1) );

To nie zabija natychmiast, a przynajmniej nie w każdym przypadku.

Masz na myśli brak wliczonego współczynniku pancerza ?

Tak.
  • +
  • -
  • 0

Posiadam TBM (inaczej PTB), które działa dużo lepiej niż zwykłe PTB, nawet na modach z lvlami. Zainteresowany? Proszę bardzo


#7 Jak się nazwać

    Wszechmogący

  • Power User

Reputacja: 169
Profesjonalista

  • Postów:617
  • Imię:a
  • Lokalizacja:a
Offline

Napisano 20.02.2013 14:43

Po operacjach zwracamy HAM_HANDLED, aby zatwierdzić zmiany.

Niby tak napisał, ale z moich testów wynika że ham_ignored też modyfikuje obrażenia, co do supercode to właśnie o to mi chodziło, żeby nie zmieniać obrażeń na 0.0 tylko po prostu zablokować
  • +
  • -
  • 0
Pisze na zamówienie statystyki pod nvault. GG: 15600964

#8 dasiek

    Nie wiem, nie znam się, nie orientuję się, zarobiony jestem.

  • Junior Admin

Reputacja: 2 077
Godlike

  • Postów:5 706
  • Imię:Adaś
  • Lokalizacja:No teraz trochę dalej od WWy
Offline

Napisano 20.02.2013 20:44

Automatyczna wiadomość


Ten temat został przeniesiony z forum

Scripting AMXXTutoriale

do

Scripting AMXXGotowe funkcje
  • +
  • -
  • 0

#9 Gość_21977_*

  • Gość

Reputacja: 0

Offline

Napisano 20.02.2013 21:15

Dokładnie, w momencie, gdy chcemy absorbować całkowicie obrażenia, to blokujemy wywołanie funkcji poprzez zwrócenie HAM_SUPERCEDE.
Zmiana obrażeń na 0, a następnie zwrócenie HAM_HANDLED, nie zada, co prawda, obrażeń, ale nie zablokuje eventu obrażeń.
Innymi słowy, gracz dalej będzie odpychany (pomimo pozornej absorpcji obrażeń), a event TakeDamage Post zostanie wykonany.
Jeśli będę dodawał np. amunicję za każde trafienie wroga, zostanie ona dodana pomimo właśnie pozornej absorpcji obrażeń.
Dlatego też, w przypadku chęci absorpcji obrażeń, należy zwrócić HAM_SUPERCEDE, by całkowicie zablokować event.

!random(x) ma faktycznie 1/x procent szans na wywołanie, jednak w użytej przez autora tematu formie, ma to być
szansa na zablokowanie wydarzenia, z powodu stojącej za funkcją pseudo-losową, instrukcji return HAM_IGNORED.

Jeśli chodzi zaś o natychmiastowe zabicie gracza, to zdejmijmy mu kamizelkę przed wywołaniem operacji, by mieć pewność, że nie uratuje ona mu życia:
cs_set_user_armor(id, 0, CS_ARMOR_NONE);

Użytkownik Benio101 edytował ten post 20.02.2013 21:18
lit., drobne stylistyczne


#10 sebul

    Godlike

  • Przyjaciel

Reputacja: 2 035
Godlike

  • Postów:5 411
  • Steam:steam
  • Imię:Sebastian
  • Lokalizacja:Ostrołęka
Offline

Napisano 20.02.2013 21:24

Jeśli chodzi zaś o natychmiastowe zabicie gracza, to zdejmijmy mu armor przed wywołaniem operacji, by mieć pewność, że nie uratuje ona mu życia:

cs_set_user_armor(id, 0, CS_ARMOR_NONE);

To też nie zawsze może pomóc, najlepiej jest gdzieś po zadaniu obrażeń sprawdzać, czy dany gracz miał być od razu zabity i jeśli tak, to wtedy gdy jest dalej żywy, zadać jeszcze raz takie same obrażenia jak wcześniej (lub jakiekolwiek obrażenia) i tak oczywiście aż dany gracz nie zostanie zabity.

Jeszcze co do zmieniania obrażeń przed ich zadaniem, to niestety, ale takie coś może powodować tzw. bug z 0hp, bo gdy gracz będzie miał hp pomiędzy 0, a 1 (czyli wartość zmiennoprzecinkową 0 < hp < 1), to wtedy ekran przekręca się na bok i wyświetla 0hp. Chyba najlepszym sposobem jest po prostu sprawdzanie po zadaniu obrażeń ile hp ma gracz oraz czy żyje, jeśli hp ma mniej od 1 i żyje, to zadać mu jakieś tam obrażenia lub po prostu zabić go za pomocą "kanapki".
  • +
  • -
  • 0

Posiadam TBM (inaczej PTB), które działa dużo lepiej niż zwykłe PTB, nawet na modach z lvlami. Zainteresowany? Proszę bardzo


#11 Gość_21977_*

  • Gość

Reputacja: 0

Offline

Napisano 20.02.2013 22:40

W przypadku stosowania systemu żyć bądź natychmiastowego autoodradzania (typu DM) dla rozgrywki na rundy, gracz natychmiast straci wszystkie swoje życia, zamiast tylko jednego.
btw. Teraz mnie jeszcze zaciekawiłeś, w jakim wypadku zdjęcie kamizelki będzie niewystarczające (uzględniając to +1 dodawane do liczby odejmowanych punktów życia gracza)?

#12 sebul

    Godlike

  • Przyjaciel

Reputacja: 2 035
Godlike

  • Postów:5 411
  • Steam:steam
  • Imię:Sebastian
  • Lokalizacja:Ostrołęka
Offline

Napisano 20.02.2013 22:49

W przypadku stosowania systemu żyć bądź natychmiastowego autoodradzania (typu DM) dla rozgrywki na rundy, gracz natychmiast straci wszystkie swoje życia, zamiast tylko jednego.

Do czego to się odnosi?

btw. Teraz mnie jeszcze zaciekawiłeś, w jakim wypadku zdjęcie kamizelki będzie niewystarczające (uzględniając to +1 dodawane do liczby odejmowanych punktów życia gracza)?

Z moich testów wynika (czyli na podstawie logów), że nie zawsze pomaga zabranie kamizelki, czemu tak jest, nie wiem, ale po prostu w logach miałem coś takiego, że graczowi zostawało trochę hp (liczę sytuację, gdy gracz miał hp >= 1) i był żywy. Testy robiłem właśnie dlatego, bo szukałem przyczyny bugu z 0hp.
sebul (20.02.2013 23:18):
Choć co do kamizelki, to pewny nie jestem, nie używałem "cs_set_user_armor", do tego nie jestem pewien, kiedy dokładnie wywaliłem z kodu usuwanie kamizelki, na pewno już po tym jak zacząłem zapisywać do logów natychmiastowe zabicie.

  • +
  • -
  • 0

Posiadam TBM (inaczej PTB), które działa dużo lepiej niż zwykłe PTB, nawet na modach z lvlami. Zainteresowany? Proszę bardzo


#13 Gość_21977_*

  • Gość

Reputacja: 0

Offline

Napisano 20.02.2013 23:21

Do czego to się odnosi?

Do tego:

najlepiej jest gdzieś po zadaniu obrażeń sprawdzać, czy dany gracz miał być od razu zabity i jeśli tak, to wtedy gdy jest dalej żywy, zadać jeszcze raz takie same obrażenia jak wcześniej (lub jakiekolwiek obrażenia) i tak oczywiście aż dany gracz nie zostanie zabity.

Za to dobicie na to kilka HP, będzie dobrym pomysłem (nie sądziłem, że właśnie może gracz takie "zabicie" przeżyć), szczerze powiedziawszy, nigdy z tej opcji jeszcze nie korzystałem.

#14 sebul

    Godlike

  • Przyjaciel

Reputacja: 2 035
Godlike

  • Postów:5 411
  • Steam:steam
  • Imię:Sebastian
  • Lokalizacja:Ostrołęka
Offline

Napisano 20.02.2013 23:31

Do czego to się odnosi?

Do tego:

najlepiej jest gdzieś po zadaniu obrażeń sprawdzać, czy dany gracz miał być od razu zabity i jeśli tak, to wtedy gdy jest dalej żywy, zadać jeszcze raz takie same obrażenia jak wcześniej (lub jakiekolwiek obrażenia) i tak oczywiście aż dany gracz nie zostanie zabity.

Za to dobicie na to kilka HP, będzie dobrym pomysłem (nie sądziłem, że właśnie może gracz takie "zabicie" przeżyć), szczerze powiedziawszy, nigdy z tej opcji jeszcze nie korzystałem.

Skoro gracz jest żywy (nawet mając mniej niż 1 hp, ale więcej niż 0), to raczej nie jest to liczone jako zabójstwo i nic nie będzie zabierane kilka razy, nawet zadając jeszcze raz 100 (lub więcej) dmg. W każdym razie, natychmiastowe zabijanie można też robić bez usuwania kamizelki, wystarczy dobrze to napisać.
  • +
  • -
  • 0

Posiadam TBM (inaczej PTB), które działa dużo lepiej niż zwykłe PTB, nawet na modach z lvlami. Zainteresowany? Proszę bardzo


#15 MarWit

    The Chosen One

  • Przyjaciel

Reputacja: 843
Czempion

  • Postów:1 485
  • GG:
  • Steam:steam
  • Imię:Marcin
  • Lokalizacja:Bystrzyca
Offline

Napisano 21.02.2013 14:55

Jeśli chodzi zaś o natychmiastowe zabicie gracza, to zdejmijmy mu kamizelkę przed wywołaniem operacji, by mieć pewność, że nie uratuje ona mu życia:
cs_set_user_armor(id, 0, CS_ARMOR_NONE);


Nie szybciej użyć po prostu ( z zablokowaniem obrażeń przez HAM_SUPERCEDE ) ?:
ExecuteHam( Ham_Killed, ... );

  • +
  • -
  • 0

marwit-0.png


#16 sebul

    Godlike

  • Przyjaciel

Reputacja: 2 035
Godlike

  • Postów:5 411
  • Steam:steam
  • Imię:Sebastian
  • Lokalizacja:Ostrołęka
Offline

Napisano 21.02.2013 18:26

Jeśli chodzi zaś o natychmiastowe zabicie gracza, to zdejmijmy mu kamizelkę przed wywołaniem operacji, by mieć pewność, że nie uratuje ona mu życia:
cs_set_user_armor(id, 0, CS_ARMOR_NONE);


Nie szybciej użyć po prostu ( z zablokowaniem obrażeń przez HAM_SUPERCEDE ) ?:
ExecuteHam( Ham_Killed, ... );

Też można (ale lepiej używać "ExecuteHamB" w tym przypadku, przynajmniej tak mi się wydaję), zresztą sam zastanawiałem się nad tym, żeby z tego korzystać, ale tutaj nie da się ustawić inflictora (tak jak to w przypadku Ham_TakeDamage), czyli bytu co zabija (zadaje obrażenia), chyba że ja o czymś nie wiem.
  • +
  • -
  • 0

Posiadam TBM (inaczej PTB), które działa dużo lepiej niż zwykłe PTB, nawet na modach z lvlami. Zainteresowany? Proszę bardzo


#17 Gość_21977_*

  • Gość

Reputacja: 0

Offline

Napisano 21.02.2013 18:29

ExecuteHam nie będzie wykryte przez silnik, dlatego wersja z B będzie lepsza, do tego trzeba sprawdzić, czy gracz nie ma godmoda.

#18 Jak się nazwać

    Wszechmogący

  • Power User

Reputacja: 169
Profesjonalista

  • Postów:617
  • Imię:a
  • Lokalizacja:a
Offline

Napisano 21.02.2013 18:52

do tego trzeba sprawdzić, czy gracz nie ma godmoda.

Z tego co wiem, to przy godmode TakeDamagePre nie zostanie wykonane (tak mi się wydaje) więc to trzeba byłoby sprawdzić (chyba że już sprawdzałeś, jak tak to zwracam honor)
  • +
  • -
  • 0
Pisze na zamówienie statystyki pod nvault. GG: 15600964

#19 MarWit

    The Chosen One

  • Przyjaciel

Reputacja: 843
Czempion

  • Postów:1 485
  • GG:
  • Steam:steam
  • Imię:Marcin
  • Lokalizacja:Bystrzyca
Offline

Napisano 21.02.2013 19:21

ale tutaj nie da się ustawić inflictora

"inflictorem" jest broń aktualnie trzymana przez gracza, lub jeżeli byt nie jest graczem to "inflictorem" jest właśnie byt atakujący.
  • +
  • -
  • 0

marwit-0.png


#20 sebul

    Godlike

  • Przyjaciel

Reputacja: 2 035
Godlike

  • Postów:5 411
  • Steam:steam
  • Imię:Sebastian
  • Lokalizacja:Ostrołęka
Offline

Napisano 21.02.2013 20:18

ale tutaj nie da się ustawić inflictora

"inflictorem" jest broń aktualnie trzymana przez gracza, lub jeżeli byt nie jest graczem to "inflictorem" jest właśnie byt atakujący.

O tym to ja wiem, chodzi mi po prostu o ustawienie "inflictora" bez względu na to, kto jest atakującym, co zresztą pisałem, że chodzi mi o coś takiego jak można ustawić przy "Ham_TakeDamage", czyli jeszcze dokładniej, w "Ham_Killed" nie da się ustawić gracza jako atakującego, a jakiś byt jako to coś, co zadaje obrażenia.
  • +
  • -
  • 0

Posiadam TBM (inaczej PTB), które działa dużo lepiej niż zwykłe PTB, nawet na modach z lvlami. Zainteresowany? Proszę bardzo





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

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