←  Pytania

AMXX.pl: Support AMX Mod X i SourceMod

»

[ROZWIĄZANE] Respawn bytu?


Najlepsza odpowiedź grankee 17.12.2014 12:57


#include <amxmodx>
#include <engine>
#include <fakemeta>
new bool:gBreakable[500]//w razie wiekszej ilosci bytow na mapie-zwiekszyc(nie sadze zeby bylo to konieczne)
public plugin_init() {
	register_plugin("Napraw kratke", "0.1", "grankee")

	register_forward(FM_EmitSound,"emitsound",1)
	register_event("HLTV", "Nowa_Runda", "a", "1=0", "2=0")
	register_clcmd("say /byt","RespawnujByt")
	
}
public RespawnujByt(id){
	//Kod który przywróci na swoje miejsce zniszczony
	//byt func_breakable znajdujący się najbliżej gracza id
	if(!is_user_alive(id)) return PLUGIN_CONTINUE
	new Float:or[3]
	pev(id,pev_origin,or)
	new Float:absmin[3],Float:absmax[3],ent,najblizszy_ent,Float:najkrotszy_dystans
	while((ent=find_ent_by_class(ent,"func_breakable"))!=0)
	{
		if(!gBreakable[ent])	continue//jesli ent nie jest rozwalony to go pomijamy
		pev(ent,pev_absmin,absmin)
		pev(ent,pev_absmax,absmax)
		wartosc_srodkowa(absmin,absmax,absmin)//ustala origin na podstawie absmin i absmax a nazstepnie zapisuje go do absmin, zeby nie tworzyc kolejnej zmiennej
		
		new Float:dystans
		dystans=get_distance_f(or,absmin)
		//odkomentuj sobie linijkę pod spodem jesli chcesz, zeby nie znajdowało dalej niż 300 unitów
		//zeby ktos np z drugiego konca mapy nie mogl wstawic kratki, oczywiscie 300.0 zmien sobie na inna jak chcesz
		//if(dystans>300.0) continue
		if(dystans<najkrotszy_dystans || najkrotszy_dystans==0.0)
		{
			najkrotszy_dystans=dystans
			najblizszy_ent=ent
		}
	}
	if(!najblizszy_ent)
	{
		client_print(id,print_chat,"Brak celu do naprawienia")
		return PLUGIN_CONTINUE
	}
	set_pev(najblizszy_ent,pev_solid,4)
	set_pev(najblizszy_ent,pev_takedamage,1.0)
	set_pev(najblizszy_ent,pev_health,20.0)
	set_pev(najblizszy_ent,pev_deadflag,0)
	set_pev(najblizszy_ent,pev_effects,0)
	client_print(id,print_chat,"Naprawiono")
	gBreakable[najblizszy_ent]=false
	return PLUGIN_CONTINUE
	
}
public Nowa_Runda()
{
	for(new a=33;a<sizeof gBreakable;a++)
		gBreakable[a]=false
}
public emitsound(ent)
{
	new classname[32]
	pev(ent,pev_classname,classname,31)
	if(equali(classname,"func_breakable"))
	{
		set_task(0.1,"breakable_killed",ent)
		
	}
	return FMRES_IGNORED
}
public breakable_killed(ent)
{
	if(pev(ent,pev_solid)==0)
	{
		gBreakable[ent]=true
		client_print(0,print_chat,"%d killed",ent)
	}
	return 0
}

	
wartosc_srodkowa(const Float:liczba1[3],const Float:liczba2[3],Float:wynik[3])
{
	new Float:roznica
	for(new a=0;a<3;a++)
	{
		roznica=liczba1[a]-liczba2[a]
		if(roznica==0)
		{
			wynik[a]=0.0
			continue
		}
		wynik[a]=(roznica>0)?(liczba1[a]-(roznica/2)):(liczba2[a]-(floatabs(roznica)/2))
	}
}
		

Przejdź do postu
Zablokowany

  • +
  • -
Ossal - zdjęcie Ossal 15.12.2014

Czy "respawnowanie" bytu jest możliwe?
Chodzi oczywiście o func_breakable (kratki, szyby, skrzynki), domyślnie wracają na mapę przy starcie nowej rundy, ale czy da się je przywrócić na własne miejsce przed nową rundą? Nie wszystkich na raz, tylko żeby były jakoś poindeksowane i żeby można było wybrać 1 dowolny (np na podstawie orginów)? Dzięki za odp, pozdrawiam :)
Odpowiedz

  • +
  • -
grankee - zdjęcie grankee 15.12.2014

Firma grankee&grankee e femili kompany specjalizuje się już 60 lat w montażu wybitych przez terro i CT kratek oraz szyb, nasze motto to pev'y, spójrz jak działamy:

 

Kiedy łobuzy albo policja wybije kratkę:

pev_deadflag zmienia sie z 0 na 2

pev_solid zmienia sie z 4 na 0

pev_takedamage zmienia sie z 1 na 0

pev_health zmienia sie z 20 na 0 lub wartość ujemną

pev_effects zmienia sie z 0 na 128

 

 

Tak więc

        set_pev(134,pev_solid,4)
	set_pev(134,pev_takedamage,1.0)
	set_pev(134,pev_health,20.0)
	set_pev(134,pev_deadflag,0)
        set_pev(134,pev_effects,0)

I masz kratkę jak nowo zamontowaną :)

 

Numer bytu jest 134, bo testowałem na kratce na nuku, prawa na górnym bsie ma ten numer zwykle (może zależeć od ilości graczy, testowane na jednym)  :D


Użytkownik grankee edytował ten post 15.12.2014 17:24
Odpowiedz

  • +
  • -
Ossal - zdjęcie Ossal 15.12.2014

Dla mnie takie rzeczy to troszke czarna magia na razie, troszke mi to przybliżyłeś, ale dalej nie wiem jak pobrać id bytu, czy też jego pozycje :(
Ktoś ma jakieś pomysły? :)
Odpowiedz

  • +
  • -
grankee - zdjęcie grankee 15.12.2014

Na podstawie originu to trochę ciężko, bo niestety mają zwykle 0 we wszystkich trzech osiach, ale nadal jest to możliwe, trzeba złapać punkt pomiędzy absmin i absmax w trzech osiach i to będzie origin.

Do znajdowania entity możesz użyć fm_find_ent_by_class.

Napisz dokładnie jak chcesz żeby to działało to będę mógł coś więcej.

Odpowiedz

  • +
  • -
Ossal - zdjęcie Ossal 16.12.2014

Numer bytu jest 134, bo testowałem na kratce na nuku, prawa na górnym bsie ma ten numer zwykle (może zależeć od ilości graczy, testowane na jednym)

Raczej wątpię, bo raczej amx rezerwuję zawsze wszystkie pierwsze 32 id dla graczy :P
Co do tego, o co mi chodzi, to tak:
Najlepiej jakby był jakiś event wykonywany w momencie zniszczenia naszej kratki i wtedy można byłoby zapisać jego id do jakiejś tablicy i ewentualne orginsy, bo przecież nie chcemy przywracać na mapę bytów które już na niej są, więc było by spoko :) Chodzi mi o to że na podstawie lokalizacji mógł zrespawnować byt po prostu albo że w okolicy gracza, to już sobie edytuję. Ooo mam pomysł, może proszę o zbyt wiele, ale będzie konkretna prośba przynajmniej :P
#include <amxmodx>

public plugin_init(){
	register_plugin("Spawnowanie bytu", "1.0", "(PRO)gramista jakis")
	register_clcmd("say /byt","RespawnujByt")
}
public RespawnujByt(id){
	//Kod który przywróci na swoje miejsce zniszczony
	//byt func_breakable znajdujący się najbliżej gracza id
}
Jest ktoś w stanie napisać taki specyfik? Teraz już chyba jasno jest napisane, mam nadzieję że to możliwe. Z góry dzięki za same chęci nawet, pozdrawiam
Odpowiedz

  • +
  • -
Najlepsza odpowiedź grankee - zdjęcie grankee 17.12.2014


#include <amxmodx>
#include <engine>
#include <fakemeta>
new bool:gBreakable[500]//w razie wiekszej ilosci bytow na mapie-zwiekszyc(nie sadze zeby bylo to konieczne)
public plugin_init() {
	register_plugin("Napraw kratke", "0.1", "grankee")

	register_forward(FM_EmitSound,"emitsound",1)
	register_event("HLTV", "Nowa_Runda", "a", "1=0", "2=0")
	register_clcmd("say /byt","RespawnujByt")
	
}
public RespawnujByt(id){
	//Kod który przywróci na swoje miejsce zniszczony
	//byt func_breakable znajdujący się najbliżej gracza id
	if(!is_user_alive(id)) return PLUGIN_CONTINUE
	new Float:or[3]
	pev(id,pev_origin,or)
	new Float:absmin[3],Float:absmax[3],ent,najblizszy_ent,Float:najkrotszy_dystans
	while((ent=find_ent_by_class(ent,"func_breakable"))!=0)
	{
		if(!gBreakable[ent])	continue//jesli ent nie jest rozwalony to go pomijamy
		pev(ent,pev_absmin,absmin)
		pev(ent,pev_absmax,absmax)
		wartosc_srodkowa(absmin,absmax,absmin)//ustala origin na podstawie absmin i absmax a nazstepnie zapisuje go do absmin, zeby nie tworzyc kolejnej zmiennej
		
		new Float:dystans
		dystans=get_distance_f(or,absmin)
		//odkomentuj sobie linijkę pod spodem jesli chcesz, zeby nie znajdowało dalej niż 300 unitów
		//zeby ktos np z drugiego konca mapy nie mogl wstawic kratki, oczywiscie 300.0 zmien sobie na inna jak chcesz
		//if(dystans>300.0) continue
		if(dystans<najkrotszy_dystans || najkrotszy_dystans==0.0)
		{
			najkrotszy_dystans=dystans
			najblizszy_ent=ent
		}
	}
	if(!najblizszy_ent)
	{
		client_print(id,print_chat,"Brak celu do naprawienia")
		return PLUGIN_CONTINUE
	}
	set_pev(najblizszy_ent,pev_solid,4)
	set_pev(najblizszy_ent,pev_takedamage,1.0)
	set_pev(najblizszy_ent,pev_health,20.0)
	set_pev(najblizszy_ent,pev_deadflag,0)
	set_pev(najblizszy_ent,pev_effects,0)
	client_print(id,print_chat,"Naprawiono")
	gBreakable[najblizszy_ent]=false
	return PLUGIN_CONTINUE
	
}
public Nowa_Runda()
{
	for(new a=33;a<sizeof gBreakable;a++)
		gBreakable[a]=false
}
public emitsound(ent)
{
	new classname[32]
	pev(ent,pev_classname,classname,31)
	if(equali(classname,"func_breakable"))
	{
		set_task(0.1,"breakable_killed",ent)
		
	}
	return FMRES_IGNORED
}
public breakable_killed(ent)
{
	if(pev(ent,pev_solid)==0)
	{
		gBreakable[ent]=true
		client_print(0,print_chat,"%d killed",ent)
	}
	return 0
}

	
wartosc_srodkowa(const Float:liczba1[3],const Float:liczba2[3],Float:wynik[3])
{
	new Float:roznica
	for(new a=0;a<3;a++)
	{
		roznica=liczba1[a]-liczba2[a]
		if(roznica==0)
		{
			wynik[a]=0.0
			continue
		}
		wynik[a]=(roznica>0)?(liczba1[a]-(roznica/2)):(liczba2[a]-(floatabs(roznica)/2))
	}
}
		


Użytkownik grankee edytował ten post 17.12.2014 14:27
Odpowiedz

  • +
  • -
Ossal - zdjęcie Ossal 17.12.2014

Człowieku jesteś genialny :o
Dziękuję Ci bardzo, ludzie obsypcie tego gościa repką :P
Wielkie dzięki, pozdrawiam :)
PS jeżeli coś z tym wykombinuję to na pewno znajdziesz się na liście zasłużonych! :)
Edit - minimalny błąd w linijce którą zostawiłeś do odkodowania jest "distance" zamiast "dystans" ja możesz to edytuj :)
Użytkownik Ossal edytował ten post 17.12.2014 14:02
Odpowiedz

  • +
  • -
grankee - zdjęcie grankee 17.12.2014


Edit - minimalny błąd w linijce którą zostawiłeś do odkodowania jest "distance" zamiast "dystans" ja możesz to edytuj

Poprawione. Nie wiem jak ja to zrobiłem Oo

 

 

Byłbym dobry, gdybym napisał to raz z głowy i by to nie wymagało sprawdzenia i poprawek, a niestety po przetestowaniu parę drobiazgów poprawiałem :D Nie mogę się nauczyć myśleć jak maszyna, w sensie pisać kod i od razu w głowie analizować co zrobi, a co może zrobić źle :> A chciałbym.

 

 

Chociaż wydaje mi się, że taki już urok programowania, że zawsze się coś poprawia.

Odpowiedz

  • +
  • -
radim - zdjęcie radim 17.12.2014

Wiadomość wygenerowana automatycznie


Ten temat został zamknięty przez moderatora.

Powód: Pomoc udzielona

Jeśli się z tym nie zgadzasz, report.png raportuj ten post, a moderator lub administrator rozpatrzy go ponownie.


Z pozdrowieniami,
Zespół AMXX.PL
Odpowiedz
Zablokowany