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

[ROZWIĄZANE] Poruszanie entem wg. klawiszy naciskanych przez gracza.


  • Zamknięty Temat jest zamknięty
9 odpowiedzi w tym temacie

#1 NoLiFeR

    Wszechobecny

  • Użytkownik

Reputacja: 103
Zaawansowany

  • Postów:483
  • GG:
  • Imię:Adrian
  • Lokalizacja:Sosnowiec
Offline

Napisano 26.02.2016 22:23

Witam, mam dość nietypowy problem, dotyczy on poruszania się entity.

Za pomocą pluginu tworzę enta, ustawiam mu odpowiednie movetype i solid (TOSS i SLIDEBOX), jednak próba zrobienia sterowania nie wychodzi mi najlepiej :/ Ktoś ma jakieś pomysły ? Mój obecny kod



public UpgradePosition(ent)
{
	new id = 0;
	for(new i=0;i<33;i++)
		if(ent == entskrz[i]) {
			id = i
			break;
		}
	if(id == 0)
		return FMRES_IGNORED;
		
	if(!is_user_alive(id)) {
		entity[id] = 0
		remove_entity(ent)
		if(is_user_connected(id)) {
			set_user_rendering(id, kRenderFxNone, 0, 0, 0, kRenderTransAlpha, 255);
			attach_view( id, id );
		}
		przemieniony[id] = false;
		return FMRES_IGNORED;
	}
	new buttons = get_user_button(id)
	if(buttons & IN_USE) {
		if(!nieruszalny[id] && licznik[id] == -1)
			licznik[id] = 10;
		
		else if(!nieruszalny[id] && licznik[id] > 0)
			licznik[id]--
			
		else if(!nieruszalny[id] && licznik[id] == 0)
			nieruszalny[id] = true;
			
		else nieruszalny[id] = false;
	}
	if(nieruszalny[id]) {
		entity_set_float(ent, EV_FL_nextthink, get_gametime());
		return FMRES_IGNORED;
	}
	new Float:Angles[3]
	pev(id, pev_angles, Angles)
	Angles[0] = 0.0
	Angles[2] = 0.0
	set_pev(ent, pev_angles, Angles)
	set_user_health(id, pev(ent, pev_health))
	new Float:velocity[3];
	pev(ent, pev_velocity, velocity)
	new Float:old2vel = velocity[2]
		
	new Float:fector[4][3];
	new bool:old = false;
	if((buttons & IN_FORWARD) || (buttons & IN_BACK) || (buttons & IN_RIGHT) || (buttons & IN_LEFT)) {
		new count = 0; 
		new bool:zm_p[4]
		if(buttons & IN_BACK && !(buttons & IN_FORWARD)) {
			angle_vector (Angles, ANGLEVECTOR_FORWARD, fector[0])
			count++
			zm_p[0] = true;
		}
		if(buttons & IN_FORWARD && !(buttons & IN_BACK)) {
			angle_vector (Angles, ANGLEVECTOR_FORWARD, fector[0])
			xs_vec_neg(fector[0],fector[1])
			count++
			zm_p[1] = true;
		}
		if(buttons & IN_LEFT && !(buttons & IN_RIGHT)) {
			angle_vector (Angles, ANGLEVECTOR_RIGHT,fector[2])
			count++
			zm_p[2] = true;
		}
		if(buttons & IN_RIGHT && !(buttons & IN_LEFT)) {
			angle_vector (Angles, ANGLEVECTOR_RIGHT,fector[2])
			xs_vec_neg(fector[2],fector[3])
			count++
			zm_p[3] = true;
		}
		
		new Float:speed = 250.0 / count
		if(count == 0)
			old = true;
		else if(count == 1){
			new ktoraz = -1
			for(new i=0;i<4;i++) {
				if(zm_p[i]) {
					xs_vec_mul_scalar( fector[i] , speed , fector[i] ); 
					ktoraz = i
					break;
				}
			}
			for(new i=0;i<3;i++)
				velocity[i] = fector[ktoraz][i]
		}
		else if(count == 2){
			new bool:ilosczm = false;
			new bool:ktoraz[2]
			for(new i=0;i<4;i++) {
				if(zm_p[i]) {
					xs_vec_mul_scalar( fector[i] , speed , fector[i] ); 
					ktoraz[i > 1 ? 1 : 0] = i%2 == 1 ? true : false
					if(ilosczm)
						break;
					else
						ilosczm = true;
				}
			}
			for(new i=0;i<3;i++)
				velocity[i] = floatdiv(floatadd(fector[ktoraz[0] ? 1 : 0][i], fector[ktoraz[0] ? 3 : 2][i]), 2.0)
		}
	}
	if(old) {
		entity_set_float(ent, EV_FL_nextthink, get_gametime());
		return FMRES_IGNORED;
	}
	
	velocity[2] = old2vel + 0.05
	
	if(!(get_user_oldbutton(id) & IN_JUMP) && buttons & IN_JUMP && pev(ent, pev_flags) & FL_ONGROUND)
		velocity[2] = random_float(25.0, 26.0)
		
	if(!(buttons & IN_BACK) && !(buttons & IN_FORWARD) && !(buttons & IN_RIGHT) && !(buttons & IN_LEFT)) {
		entity_set_float(ent, EV_FL_nextthink, get_gametime());
		return FMRES_IGNORED;
	}
	
	set_pev(ent,pev_velocity,velocity)
	entity_set_float(ent, EV_FL_nextthink, get_gametime());
	return FMRES_IGNORED;
}

// EDIT po to żeby przestawić new buttons = get_user_button(id) z warunkiem czy gracz jest żywy

 

 

sprawia że entity po wciśnięciu w, a, s lub d po prostu staje w miejscu, nic nie da się z nią zrobić (z samym thinkiem wszystko w porządku, bo obraca bytem co mogę zaobserwować)

Czy możliwe jest że funkcja jest zbudowana źle i po prostu entity "klinuje się" w ziemi ?

Dziękuje.


Użytkownik NoLiFeR edytował ten post 26.02.2016 22:37

  • +
  • -
  • 0

#2 DarkGL

    Nie oddam ciasteczka !

  • Administrator

Reputacja: 6 555
Godlike

  • Postów:11 980
  • GG:
  • Steam:steam
  • Imię:Rafał
  • Lokalizacja:Warszawa
Offline

Napisano 27.02.2016 15:54

Najpierw to zrób prościej bo obecnie wygląda to strasznie dopiero wtedy przystąpimy do poprawy


  • +
  • -
  • 1

#3 NoLiFeR

    Wszechobecny

  • Autor tematu
  • Użytkownik

Reputacja: 103
Zaawansowany

  • Postów:483
  • GG:
  • Imię:Adrian
  • Lokalizacja:Sosnowiec
Offline

Napisano 27.02.2016 19:57

Nie mam pojęcia jak można to zrobić prościej.. :/ Pewnie nie widze najprostszego rozwiązania...


  • +
  • -
  • 0

#4 grankee

    Godlike

  • Support Team

Reputacja: 517
Wszechwiedzący

  • Postów:1 500
  • Lokalizacja:Radom
Offline

Napisano 28.02.2016 16:39

Prawdę mówiąc jest tu nasrane dużo kodu i ciężko z niego jasno wywnioskować co ma on dokładnie robić i w jakich okolicznościach.

Kilka wskazówek jak ułatwić innym a także sobie w przyszłości odszyfrowanie kodu (dziś ogarniasz, bo dopiero co go pisałeś, ale za kilka tygodni/miesięcy jak zapragniesz coś zmienić to się pogubisz):

-nazywaj zmienne zgodnie z ich przeznaczeniem-używaj pełnych nazw a nie skrótów, które tylko Ty rozumiesz, nawet jeśli nazwa będzie przez to dłuższa.

-używaj przedrostków sugerujących typ zmiennej w jej nazwie (dużo lepiej czyta się vecSpeed, iCount,szClass niż speed, count,class)

-! używaj komentarzy jak najwięcej, na prawdę dużo można po nich wywnioskować

-podajesz tylko jedną funkcję, która nie wiadomo kiedy się wykonuje i używasz w niej zmiennych, które nie wiadomo co przechowują, można jedynie wywnioskować, że skoro ich deklaracji nie ma wewnątrz to są globalne, ale gdzie i kiedy są jeszcze modyfikowane to nie wiadomo.

 

 

Konicznie opisz jaki player i jak ma sterować no i czym oczywiście. Podaj szczegóły dotyczące bytu sterowanego, jak ma wyglądać i jak się poruszać, jakiej jest klasy, po prostu co możesz. No i popraw ten kod bo faktycznie nie jest dobrze...


Użytkownik grankee edytował ten post 28.02.2016 16:42

  • +
  • -
  • 1

#5 NoLiFeR

    Wszechobecny

  • Autor tematu
  • Użytkownik

Reputacja: 103
Zaawansowany

  • Postów:483
  • GG:
  • Imię:Adrian
  • Lokalizacja:Sosnowiec
Offline

Napisano 28.02.2016 21:12

A więc tak. Zastosowałem się do Waszych porad, i napisałem osobną funkcje na ten cel, na razie bez skakania, aby nie zaciemniać kodu.
Myśle jednak że to nie wina funkcji, a samego enta.
 


public poruszanie(ent, id, Float:Angles[3], buttons) {
	new Float:vecVelocity[3];
	//pev(ent, pev_velocity, vecVelocity)
//	new Float:f_OldFallVelocity = vecVelocity[2]
		
	new iCount = 0; 
	new Float:Temp[3]
	// W && !S
	if(buttons & IN_FORWARD && !(buttons & IN_BACK)) {
		angle_vector (Angles, ANGLEVECTOR_FORWARD, Temp)
		xs_vec_mul_scalar(Temp, 250.0, Temp);
		for(new i=0;i<3;i++)
			vecVelocity[i] += Temp[i]
		iCount++
	}
	// S && !W
	else if(buttons & IN_BACK && !(buttons & IN_FORWARD)) {
		angle_vector (Angles, ANGLEVECTOR_FORWARD, Temp)
		xs_vec_neg(Temp,Temp)
		xs_vec_mul_scalar(Temp, 250.0, Temp);
		for(new i=0;i<3;i++)
			vecVelocity[i] += Temp[i]
		iCount++
	}
	// D && !A
	if(buttons & IN_LEFT && !(buttons & IN_RIGHT)) {
		angle_vector (Angles, ANGLEVECTOR_RIGHT,Temp)
		xs_vec_neg(Temp,Temp)
		xs_vec_mul_scalar(Temp, 250.0, Temp);
		for(new i=0;i<3;i++)
			vecVelocity[i] += Temp[i]
		iCount++
	}
	// A && !D
	else if(buttons & IN_RIGHT && !(buttons & IN_LEFT)) {
		angle_vector (Angles, ANGLEVECTOR_RIGHT,Temp)
		xs_vec_mul_scalar(Temp, 250.0, Temp);
		for(new i=0;i<3;i++)
			vecVelocity[i] += Temp[i]
		iCount++
	}
	
	if(iCount == 0)
		return;
		
	for(new i=0;i<3;i++)
		vecVelocity[i] /= iCount
		
	//vecVelocity[2] = f_OldFallVelocity
	
	set_pev(ent,pev_velocity,vecVelocity)
}

którą odpalam gdy gracz naciska w, a, s lub d.
Byt musi mieć wymiary maksymalne, bo chcę, abu kolidował ze światem.
Ustawiam je w ten sposób

set_pev(entity[id],pev_mins, Min);
set_pev(entity[id],pev_maxs ,Max);

entity[id] to globalny identyfikator bytu, który został stworzony przez gracza.
Gdy gracz jest martwy, byt jest usuwany.
Kamera jest trzeciosobowa (próbowałem ustawić attachview'em w sam byt, ale nie wyglądało to najlepiej), jednak myśle że nie ma to większego znaczenia.
Byt to "bomba" (model c4), która sterowana przez gracza ma dojść w określone miejsce.

Kolejnym powodem dla którego byt musi mieć wymiary jest wymagana ustrzelalność..


Użytkownik NoLiFeR edytował ten post 28.02.2016 21:15

  • +
  • -
  • 0

#6 grankee

    Godlike

  • Support Team

Reputacja: 517
Wszechwiedzący

  • Postów:1 500
  • Lokalizacja:Radom
Offline

Napisano 28.02.2016 23:56

Co dokładnie się dzieje? Nie mam jak przetestować moich przypuszczeń, ale tak:

 

-Zakładam, że funkcja ta jest odpalana w prethinku

-Zmienna iCount to wielka zagadka :) jeżeli funkcja odpalana jest w prethinku tak jak zakladam to wartosc iCount może wynosić 0,1,2,3 lub 4 zależnie ile przycisków trzymasz w danej klatce.

Jaki sens ma zatem dzielenie vectora przez 1,2,3 lub 4? (przy zerze funkcja zostanie wcześniej przerwana i słusznie, bo przez 0 się nie dzieli)

for(new i=0;i<3;i++)
		vecVelocity[i] /= iCount

Zakładam, że chciałeś jej użyć do spokojnego przyspieszania, ale jest ona deklarowana na nowo za każdym wywołaniem funkcji więc nigdy nie pójdzie wyżej.

 

 

Zobacz jak to zadziała:

public poruszanie(ent, id, Float:Angles[3], buttons) {
	new Float:vecVelocity[3];
	//pev(ent, pev_velocity, vecVelocity)
//	new Float:f_OldFallVelocity = vecVelocity[2]
		
	static  iCount[32] ; 
	new iTrzymaRuch=0;
	new Float:Temp[3];
	// W && !S
	if(buttons & IN_FORWARD && !(buttons & IN_BACK)) {
		angle_vector (Angles, ANGLEVECTOR_FORWARD, Temp)
		if(iCount[id]<250)	iCount[id]++
		iTrzymaRuch=1;
	}
	// S && !W
	else if(buttons & IN_BACK && !(buttons & IN_FORWARD)) {
		angle_vector (Angles, ANGLEVECTOR_FORWARD, Temp)
		xs_vec_neg(Temp,Temp)
		if(iCount[id]<250)	iCount[id]++
		iTrzymaRuch=1;
	}
	
	// D && !A
	if(buttons & IN_LEFT && !(buttons & IN_RIGHT)) {
		angle_vector (Angles, ANGLEVECTOR_RIGHT,Temp)
		xs_vec_neg(Temp,Temp)
		if(iCount[id]<250)	iCount[id]++
		iTrzymaRuch=1;
	}
	// A && !D
	else if(buttons & IN_RIGHT && !(buttons & IN_LEFT)) {
		angle_vector (Angles, ANGLEVECTOR_RIGHT,Temp)
		if(iCount[id]<250)	iCount[id]++
		iTrzymaRuch=1;
	}
	
	if(iTrzymaRuch==0)
	{
		iCount[id]=0;
		return;
	}
		
	xs_vec_mul_scalar(Temp, float(iCount[id]), Temp);
	for(new i=0;i<3;i++)
		vecVelocity[i] += Temp[i]
	
		
	//vecVelocity[2] = f_OldFallVelocity
	
	set_pev(ent,pev_velocity,vecVelocity)
}

Użytkownik grankee edytował ten post 29.02.2016 00:13

  • +
  • -
  • 1

#7 NoLiFeR

    Wszechobecny

  • Autor tematu
  • Użytkownik

Reputacja: 103
Zaawansowany

  • Postów:483
  • GG:
  • Imię:Adrian
  • Lokalizacja:Sosnowiec
Offline

Napisano 29.02.2016 00:17   Najlepsza odpowiedź

Jak wciskam jednocześnie W i D to prędkość będzie sumą dwóch wektorów. Dziele przez iCount tylko po to aby nie dało się poruszać klawiszami w i d szybciej niż samym w.

Problem rozwiązany, ostatni movetype okazał się zbawienny :) ( MOVETYPE_PUSHSTEP )



// Funkcja działa idealnie, a zastosowany wyżej movetype sprawia że sam byt porusza się jak na lodzie (płynne przyspieszanie)

Użytkownik sebul edytował ten post 01.03.2016 19:50

  • +
  • -
  • 0

#8 grankee

    Godlike

  • Support Team

Reputacja: 517
Wszechwiedzący

  • Postów:1 500
  • Lokalizacja:Radom
Offline

Napisano 29.02.2016 14:48

for(new i=0;i<3;i++)
		vecVelocity[i] /= iCount

nie dziel vecVelocity[2] bo ono odpowiada za prędkość w pionie, a tej niepotrzeba zmniejszać jeśli trzymasz dwa przyciski :P


  • +
  • -
  • 1

#9 NoLiFeR

    Wszechobecny

  • Autor tematu
  • Użytkownik

Reputacja: 103
Zaawansowany

  • Postów:483
  • GG:
  • Imię:Adrian
  • Lokalizacja:Sosnowiec
Offline

Napisano 29.02.2016 15:49

Trafna uwaga, dostrzegłem to dodając skakanie :) Dla osób które chciały by podpatrzeć kod, zmieniłem jeszcze IN_RIGHT IN_LEFT na IN_MOVERIGHT i IN_MOVELEFT, co dało efekt końcowy (no prawie, bo zmieniłem iCount na fCount oraz dodawałem 0,5 zamiast 1, przez to dzieli teraz max przez 1.5 (wartość początkowa to 0.5). Zrobiłem tak bo byt był zbyt zatrzymywany przez to dzielenie) Zmieniłem sprawdzanie iCount == 0 na fCount == 0.5, bo taka jest wartość początkowa (skoro nic się nie zmieniło, po co co kolwiek dodawać?). Skok jest wykonywany przed tą czynnością, także gdy gracz użyje skoku a nie użyje W, A ,S czy D wartość fCount zostanie powiększona o 0.5, aby nie przerwało funkcji (i żeby nie trzeba było robić obejść).

Dziękuje wszystkim za pomoc, temat się wyczerpał więc proszę o jego zamknięcie.


  • +
  • -
  • 0

#10 sebul

    Godlike

  • Przyjaciel

Reputacja: 2 035
Godlike

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

Napisano 01.03.2016 19:51

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
  • +
  • -
  • 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