Łapanie eventu - pocisk trafiający w byt/m...
Sooldierr
19.02.2015
Witam
Chciałbym dodać dźwięki (3 losowo odgrywane gdy pocisk trafi w worek, 1 gdy zniszczony) do pluginu boostbags (stawiający worki zniszczalne w grze do kamp na ZM). Podczas ostrzału worków lub zniszczenia odgrywane byłyby dźwięki.
Jak powinienem złapać event trafienia pocisku w worek?
Ham_Touch czy Ham_Takedamage?
I jak ewentualnie dalej sprawdzać czy byt trafiany to model worka?
Poniżej kod pluginu
Attached Files
grankee
19.02.2015
Ham_TakeDamage
Sprawdzasz czy classname victima to "func_bags" oraz czy attacker jest połączony (is_user_connected) żeby wyeliminować jakiej nieprzewidziane obrażenia i odgrywasz dźwięk.
Sooldierr
19.02.2015
Nie jestem jakoś zaawansowany w scriptingu.
Jak sprawdzić ten classname?
Oraz jak sprawdzić czy byt nadal istnieje? Bo w przeciwnym wypadku ma odegrać nie dźwięk trafienia w baga tylko dźwięk zniszczenia,
NoLiFeR
19.02.2015
Sprawdzasz czy damage jest większy od pev_health (fakemeta) i wywołujesz dzwięk zniszczenia zamiast obrażeń.
Sooldierr
19.02.2015
Jak odegrać właściwie dźwięk? Przy użyciu emit_sound?
Jak powinienem zastosować?
Stworzyłem i zainicjalizowałem w zmiennych moje dźwięki:
new const g_soundhit[][] = {"sound/misc/g_soundhit.wav", "sound/misc/g_soundhit2.wav", "sound/misc/g_soundhit3.wav"} new const g_sounddestroy[] = "sound/misc/g_sounddestroy.wav"
w:
public plugin_precache()
dodałem ich buforowanie:
for (new i=0; i < sizeof(g_soundhit); i++) precache_sound(g_soundhit[i]) precache_sound(g_sounddestroy)
W:
public plugin_init()
Dodałem rejestrowanie wydarzenia zadawania obrażeń:
RegisterHam(Ham_TakeDamage, "player", "Fw_PlayerTakeDamage", 0)
Funkcja wywoływana przez Ham_TakeDamage:
public Fw_PlayerTakeDamage(victim, idinflictor, idattacker, Float:damage, damagebits) { new szTouched[16] pev(victim , pev_classname , szTouched , 15); new szHealth = pev(victim, pev_health); if(!is_user_connected(idattacker) || containi(szTouched, "func_bags") == 1) return HAM_IGNORED if (damage < szHealth) { emit_sound(victim, CHAN_AUTO, g_soundhit[random(sizeof g_soundhit)], VOL_NORM, ATTN_NORM, 0, PITCH_NORM) return HAM_SUPERCEDE } if (damage > szHealth) { emit_sound(victim, CHAN_AUTO, g_sounddestroy, VOL_NORM, ATTN_NORM, 0, PITCH_NORM) return HAM_SUPERCEDE } return HAM_IGNORED }
Tak wygląda mój plugin ostatecznie. Ktoś zerknie i ewentualnie poprawi?
Attached Files
Edited by Sooldierr, 19.02.2015 21:06.
grankee
20.02.2015
containi(szTouched, "func_bags") == 1
raczej
containi(szTouched,"func_bags")!=0
bo jeśli by classname było takie samo to funkcja zwróci 0 jako że od zerowej pozycji jeden wyraz zawiera drugi
a najlepiej
!equal(szTouched,"func_bags")
GwynBleidD
21.02.2015
raczej != -1
Warunek ma na celu sprawdzenie, czy napis ZACZYNA się podanym fragmentem, więc !=0 jest prawidłowe.
Sooldierr
21.02.2015
Odwróciłem warunek w drugą stronę, że gdy spełnione są warunki to wtedy się coś ma dziać, inaczej nic po prostu. Tak jest dobrze?
public Fw_PlayerTakeDamage(victim, idinflictor, idattacker, Float:damage, damagebits) { new szTouched[16] pev(victim , pev_classname , szTouched , 15); if(equali(szTouched,"func_bags") && is_user_connected(idattacker)) { new szHealth = pev(victim, pev_health); if (damage < szHealth) { emit_sound(victim, CHAN_AUTO, g_soundhit[random(sizeof g_soundhit)], VOL_NORM, ATTN_NORM, 0, PITCH_NORM) } if (damage > szHealth) { emit_sound(victim, CHAN_AUTO, g_sounddestroy, VOL_NORM, ATTN_NORM, 0, PITCH_NORM) if (get_user_team(idattacker) != 1) { new niszczyciel[32] get_user_name(idattacker, niszczyciel, 31) ColorChat(0, GREEN, "%s zniszczyl kladke!", niszczyciel) } } } return HAM_IGNORED }
radim
22.02.2015
RegisterHam(Ham_TakeDamage, "player", "Fw_PlayerTakeDamage", 0)->
RegisterHam(Ham_TakeDamage, "func_wall", "Fw_PlayerTakeDamage", 0)
Sooldierr
23.02.2015
Dzięki to pomogło.
Pozostała ostatnia kwestia, chciałem dodać jeszcze info o graczu rozwalającym kładkę. Jednak nie ma takiego info. Domyślam się, że błędnie operuję tablicą dwuwymiarową, przypisywaniem do niej i wyświetlaniem.
Deklarowanie i inicjalizowanie:
new niszczyciele[15][32] = {"","","","","","","","","","","","","","",""} new nr = 0
Rejestrowanie komendy wyświetlającej listę graczy (ludzi), którzy w aktualnej rundzie zniszczyli kładkę.
register_clcmd("amx_niszczyciele", "cmd_niszczyciele", ADMIN_KICK)
Funkcja wyświetlająca ową listę graczy:
public cmd_niszczyciele(id) { client_print(id, print_console, "=== W tej rundzie paczki zniszczyli===") for (new i=0; i< 15; i++) { if (!equali(niszczyciele[i], "")) { client_print(id, print_console, "%s", niszczyciele[i]) } } }
Resetowanie listy co rundę:
public event_newround() { nr = 0 for (new i=0; i<15; i++) niszczyciele[i] = "" }
Funkcja reagująca na obrażenia zadawane workowi:
public Fw_PlayerTakeDamage(victim, idinflictor, idattacker, Float:damage, damagebits) { new szTouched[16] pev(victim , pev_classname , szTouched , 15); if(equali(szTouched,"func_bags") && is_user_connected(idattacker)) { new szHealth = pev(victim, pev_health); if (get_user_team(idattacker) == 2) { if (damage < szHealth) emit_sound(victim, CHAN_AUTO, g_soundhit[random(sizeof g_soundhit)], VOL_NORM, ATTN_NORM, 0, PITCH_NORM) if (damage > szHealth) { get_user_name(idattacker, niszczyciele[nr], 31) emit_sound(victim, CHAN_AUTO, g_sounddestroy, VOL_NORM, ATTN_NORM, 0, PITCH_NORM) ColorChat(0, GREEN, "%s zniszczyl kladke!", niszczyciele[nr]) nr++ } } } return HAM_IGNORED }
Sooldierr
16.03.2015
Ktos wie dlaczego to nie spełnia swojego zadania? Nie wyswietla kto zniszczyl kladke.
Mam wrazenie, ze kladka jest zniszczona wczesniej, niz by wskazywalo na to jej zycie.
Dodalem komunikat wysiwrtlajacy stan zycia za kazdym trafieniem i wyniki oscylowaly okolo 400-500 HP.
A ma ustawione 1000 hp to i powinno do konca zjechac i dopiero zniknac?
Czy moze zle pobieram zycie?
public Fw_PlayerTakeDamage(victim, idinflictor, idattacker, Float:damage, damagebits) { pev(victim , pev_classname , szTouched , 15); if(equali(szTouched,"func_bags") && is_user_connected(idattacker)) { if (get_user_team(idattacker) == 2) { pev(victim, pev_health, szHealth); if (damage < szHealth) { emit_sound(victim, CHAN_AUTO, g_soundhit[random(sizeof g_soundhit)], VOL_NORM, ATTN_NORM, 0, PITCH_NORM) return HAM_IGNORED } if (damage >= szHealth) { get_user_name(idattacker, niszczyciele, 31) emit_sound(victim, CHAN_AUTO, g_sounddestroy, VOL_NORM, ATTN_NORM, 0, PITCH_NORM) ColorChat(0, RED, "[%s] ^x04zniszczyl kladke!", niszczyciele) return HAM_IGNORED } } else return HAM_IGNORED } else return HAM_IGNORED }
Sooldierr
19.03.2015
Ok, znalazłem już przyczynę i poprawiłem ją. Teraz sprawa jest taka, że fragment:
if (damage >= szHealth) { get_user_name(idattacker, niszczyciele, 31) emit_sound(victim, CHAN_AUTO, g_sounddestroy, VOL_NORM, ATTN_NORM, 0, PITCH_NORM) ColorChat(0, RED, "[%s] ^x04zniszczyl kladke!", niszczyciele) return HAM_IGNORED }
Wykonuje się dwa razy dla jednej kładki. Czym to może być spowodowane? W momencie gdy wartość obrażeń przewyższa wartość pozostałego HP kładki, powinno się wykonać raz, potem kładki już nie ma, nie istnieje. Wartość pozostałego życia zostaje pobrana przed zadaniem obrażeń. Dlatego nie można zrobić warunku:
szHealth <= 0
gdyż, nie da się tego sprawdzić, a raczej pobrać takiej wartości, bo nie ma z czego.
Ktoś wie dlaczego tak się dzieje, że dwa razy wykonuje się ten warunek?
Poniżej załączam aktualny kod:
Attached Files
Sooldierr
20.03.2015
Można pobrać w jakiś sposób HP kładki po wykonaniu się wydarzenia Ham_TakeDamage a nie przed?
grankee
22.03.2015
RegisterHam(Ham_TakeDamage, "func_wall", "Fw_PlayerTakeDamagePost", 1)
public Fw_PlayerTakeDamagePost(...
Sooldierr
22.03.2015
Juz to znalazlem, ale dziekuje za wypowiedz, bo ostatnio brak zainteresowania.
Jednak event Ham_TakeDamage wykonuje sie nadal choc nie zawsze dwa razy.
O ile wczesniej wykonywal sie przed ostatnim pociskiem rozwalajacym kladke i po nim;
to teraz jest tak, ze nie zawsze dwukrotnie, ale jak juz sie zdarzy to wlasnie po tym ostatnim pocisku rozwalajacym od razu dwukrotnie.
Czyli tak jakby plugin "nie nadaza usunac bytu"??
Prawdopodobnie wina lezy w tym, ze rejestrowanie obrazen sie nachodzi gdyz:
- oryginalnie w pluginie sprawdzanie czy obrazenia zadawane sa bytowi kladki, wykonywane jest za pomoca fakemeta (Think), aby plugin wiedzial kiedy usunac
- moj dodatek dodajacy dzwieki oraz info potrzebuje hamsandwich (Ham_Take_Damage), aby uzyskac info o atakujacym.
Mam racje?
Czy moge sprobowac przeniesc funkcje z fakemeta do hamsandwich, uzyskujac ten sam efekt, bez jakis szkod albo wad w takim wypadku?
Bo to zapewne bardzo nieoptymalne rozwiazanie, podwojne sprawdzanie
grankee
23.03.2015
Niezbyt czaję ideę, daj kod wszystkiego co masz na chwilę obecną i dokładnie wyjaśnij co się dzieje.