Gamestudio Links
Zorro Links
Newest Posts
Blobsculptor tools and objects download here
by NeoDumont. 03/28/24 03:01
Issue with Multi-Core WFO Training
by aliswee. 03/24/24 20:20
Why Zorro supports up to 72 cores?
by Edgar_Herrera. 03/23/24 21:41
Zorro Trader GPT
by TipmyPip. 03/06/24 09:27
VSCode instead of SED
by 3run. 03/01/24 19:06
AUM Magazine
Latest Screens
The Bible Game
A psychological thriller game
SHADOW (2014)
DEAD TASTE
Who's Online Now
2 registered members (AndrewAMD, VoroneTZ), 831 guests, and 5 spiders.
Key: Admin, Global Mod, Mod
Newest Members
sakolin, rajesh7827, juergen_wue, NITRO_FOREVER, jack0roses
19043 Registered Users
Previous Thread
Next Thread
Print Thread
Rate Thread
Page 1 of 2 1 2
[ANET] A6 Pointer in entity.skill speichern #333254
07/15/10 08:23
07/15/10 08:23
Joined: Dec 2003
Posts: 988
Germany, Magdeburg
JoGa Offline OP
User
JoGa  Offline OP
User

Joined: Dec 2003
Posts: 988
Germany, Magdeburg
Hallo
Im Singleplayer bin ich oft so vorgegangen, dass ich von Entities den pointer in einem Skill abgespeichert habe, wenn ich den Pointer noch brauchte (handle(pointer)+ptr_for_handle(skill);).
Nun funktioniert im Multiplayer bei mir der pointer player nicht als lokaler Pointer:
Beispiel:
Spieler 1 ist player, klinkt sich ein und bekommt eine Entity an sich angehängt - alles funktioniert
Spieler 2 joint, bekommt auch eine neue Entity an sich angehängt, aber es hängen beide Entitys an ihm, der erste Spieler hat keins mehr an sich.
Daher denk ich, dass player nicht lokal sondern global ist.

Nun hab ich versucht, dem Problem aus dem Weg zu gehn, indem ich wie oben angesprochen mit handle und ptr_for_handle arbeite, um die jeweiligen Spieler-Pointer-IDs bei den angehängten Entities abzuspeichern und dann wieder aufzurufen, damit sie sich an die you = ptr_for_handle(my.skillx) dranhängen.
Da bekomme ich aber folgende Fehlermeldung:
"Empty pointer in enet_ent_globpointer: vec_sub(temp.x,you.x)" (bei einer mit enet_ent_create erstellten Entity)
D.h. ich kann die handle - und ptr_for_hanlde-befehle mit ANET nicht verwenden? Wurde ja auch im Manual gewarnt, dass man befehle nicht vermischen darf. - Weis jemand die Lösung meines Problems, warum ich meine Pointer nicht richtig verwenden kann?
2 globale Entities, die die Spieler sind, brauchen einfach noch jeder ein globales Entitie als "Anhängsel" (zB. bei Panzersimulationen der Turm, bei Hack&Slay die Waffen usw...)
Aber irgendwie steh ich sowohl mit den Pointern grad auf dem Kriegsfuß als auch momentan grad auf dem Schlauch, glaub ich ^^ -.-

Re: [ANET] A6 Pointer in entity.skill speichern [Re: JoGa] #333260
07/15/10 09:35
07/15/10 09:35
Joined: Jul 2005
Posts: 1,930
Austria
Dark_samurai Offline
Serious User
Dark_samurai  Offline
Serious User

Joined: Jul 2005
Posts: 1,930
Austria
Gilt nur für globale Entities (erstellt mit enet_ent_create()):
Wenn du einen Pointer brauchst, der auf allen PCs gleich ist musst du ihn per enet_get_globpointer(entityxyz); ermitteln. Auf jedem einzelnen PC kannst du dann diesen globalen Pointer per enet_get_locpointer(globalerpointervonvorher); umwandeln und so die Entity wie im Singleplayer ansprechen.
Zur Erklärung: Der Server führt eine Liste 0-unendlich in der nach der Reihe die globalen Entities eingetragen sind. Der globale Pointer ist nichts anderes als die Nummer des Eintrags. Jeder Client hat ein Duplikat der Liste in dem der lokale Pointer (also der Pointer am jeweiligen Client) gespeichert ist. Mit enet_get_locpointer() wird einfach dieser Pointer aus der Liste ausgelesen.

handle und ptr_for_handle() benötigst du gar nicht. Dafür sind die obigen Funktionen vorgesehen.


ANet - A stable and secure network plugin with multi-zone, unlimited players, voip, server-list features,... (for A7/A8)!
get free version
Re: [ANET] A6 Pointer in entity.skill speichern [Re: Dark_samurai] #333274
07/15/10 12:29
07/15/10 12:29
Joined: Dec 2003
Posts: 988
Germany, Magdeburg
JoGa Offline OP
User
JoGa  Offline OP
User

Joined: Dec 2003
Posts: 988
Germany, Magdeburg
wow, super, genau das hab ich gesucht, danke!

Jetzt hab ich "nur noch" ein Problem gerade bemerkt, als ich die Entityanzahl überprüft habe:
Sobald sich ein neuer Client einloggt, werden die anderen Spieler-figuren alle im Grund doppelt erstellt und werden dann vom ersten Spieler(serverclient) gesteuert - hast du da ne spontane Idee, was das sein könnte? Irgendein bekannter ANET-Anfänger-Fehler?

Re: [ANET] A6 Pointer in entity.skill speichern [Re: JoGa] #333276
07/15/10 13:07
07/15/10 13:07
Joined: May 2009
Posts: 445
Peine, Germany
Razoron Offline
Senior Member
Razoron  Offline
Senior Member

Joined: May 2009
Posts: 445
Peine, Germany
Also dafür bräuchte man etwas code. laugh
Wer erstellt den die Entity? der Serverclient oder der Client selber?
Und nur mal so, hast du dir schon das "Simple 3D Chat" Tutorial durchgelesen?
Sehr hilfreich!

Re: [ANET] A6 Pointer in entity.skill speichern [Re: Razoron] #333278
07/15/10 13:32
07/15/10 13:32
Joined: Dec 2003
Posts: 988
Germany, Magdeburg
JoGa Offline OP
User
JoGa  Offline OP
User

Joined: Dec 2003
Posts: 988
Germany, Magdeburg
Jop, hab ich durchgelesen, ich hab daraus sogar Code für den Anfang kopiert -.- *schähm* ^^
über die while-Schleifen oder das mit dem Pan-Winkel bei der Bewegung bitte darüber weg sehn, ich schreib das meist etwas kompliziert hin und wenn es vom Prinzip funktioniert, optimiere ich das dann noch ^^
Okay, dann hier etwas Code:
Die mainfunktion steht im ersten Code-Block zu unterst. Syntaxfehler(sowas wie Semikolon vergessen oder so), die eigentlich Fehlermeldungen produzieren würden, sind mir dann beim hier hereinkopieren passiert, die Engine läuft das bei mir problemlos durch.
Code:
function create_player()
{
	enet_ent_create("spieler01_unten.mdl",vector(random(100), 0, 0),"move_player");
	wait(1);
}

string playername_str = "#50"; 
//client event beim einklinken
function connected_with_server(sender, msg)
{
	inkey(playername_str); //Lässt den Spieler einen Spielernamen eingeben 
	enet_set_playername(playername_str); //Speichert den Spielernamen 
	if(enet_get_connection() == CLIENT_MODE) //if started as client
	{
		error("neuer client");
		//level_load(msg); //loads the level which is loaded on the server
		level_load("level_001__test.wmb"); //loads the level which is loaded on the server
		wait(3); //wait until the level is loaded
		enet_ent_synchronize(); //sends a synchronizing request
	}
	else //started as server or server/client
	{
		error("neuer server");
		create_player(); //creates the correct character
	}
}

function synchronizing_complete(sender, msg)
{
	create_player(); //creates the correct character
}

function start_client(ip)
{l
	enet_init_client(ip,used_port,""); //initializes a client
}

function start_server()
{
	while(key_F1){wait(1);} // zum schnell testen mit F1 server
	level_load("level_001__test.wmb"); //Loads the first Level
	wait(3); //wait until the level is loaded
	while((enet_init_server(used_port,max_players,""))==ANET_ERROR)	{wait(1);}
	enet_set_level("level_001__test.wmb"); //sets the level
	wait(4);
	//start_client("localhost"); // server spielt auch mit
	start_client("255.255.255.255");
}

function test_start_client() //zum testen den Client dazu
{
	while(1)
	{
		if(KEY_F2)
		{
			//start_client("localhost");
			start_client("255.255.255.255");
			break;
		}
		wait(1);
	}
}

function main()
{
	fps_max = 60;
	wait(1); //wait for the plugin to get loaded
	if((enet_init())==ANET_ERROR){exit;}
	anet_set_compatibility(1);
//enet_svset_event(EVENT_DISCONNECTED,"client_disconnected");
	enet_clset_event(EVENT_CONNECTED,"connected_with_server");
	//enet_clset_event(EVENT_DISCONNECTED,"disconnected_from_server");
	enet_clset_event(EVENT_SYNCHRONIZED,"synchronizing_complete");
	//enet_clset_event(EVENT_LEVEL,"change_level_event");
	//sets userevents:
	//enet_svset_event(16,"kick_client");
	//enet_svset_event(17,"receive_chatmsg");
	//enet_clset_event(17,"receive_chatmsg");
	level_load(""); //loads an empty level
	wait(3); //wait until the level is loaded
	//shows the mouse
	mouse_mode = 1;
	mouse_map = arrow_bmap;
	test_start_client(); //temp
	while(1)
	{
		//gets some info vars:
		enet_connection = enet_get_connection();
		enet_clientid = enet_get_clientid();
		enet_clients = enet_connected_clients();
		ping = enet_get_ping();
		//controls the mouse:
		MOUSE_POS.X = POINTER.X;
		MOUSE_POS.Y = POINTER.Y;
		wait(1);
	}
}
ON_F1 = start_server(); //test


das ist die Mainfunktion und was den Server+Client initialisiert.
Die Spielerfunktion ist hier:
Code:
function oberes_teil()
{
	while(enet_ent_globpointer(my) == ANET_ERROR) {wait(1);}
	my.passable = on;
	while(1)
	{
		you = enet_ent_locpointer(my.entity_handle);
		vec_set(my.x,you.x);
		vec_set(temp.x,vector(mouse_pos.x,mouse_pos.y,camera_dist));
		vec_for_screen(temp,camera);
		temp.z = 0;
		vec_sub (temp.x, you.x);
		vec_to_angle (my.pan, temp); // rotate it towards the target
		wait(1);
	}
}
function move_player() 
{
	my.leben = 100;
	my.max_leben = 100;
	my.mana = 100;
	my.max_mana = 100;
	var dist_move[3];
	var moved_dist; //die Distanz, die zurückgelegt wurde (damit wird überprüft, ob Spieler bewegt wurde, wenn ja -> broadcast)
	var moved_pan; //die Drehung, die zurückgelegt wurde (damit wird überprüft, ob Spieler bewegt wurde, wenn ja -> broadcast)
	while(enet_ent_globpointer(my) == ANET_ERROR) {wait(1);}
	you = enet_ent_create("spieler01_oben.mdl",vector(my.x,my.y,my.z),"oberes_teil");
	while(enet_ent_globpointer(you) == ANET_ERROR) {wait(1);}
	you.entity_handle = enet_ent_globpointer(my);
//	updates();	//updates für Charakter-Wert-Balken u.ä.
	while(1)
	{
		if(enet_ent_creator(enet_ent_globpointer(my)) == enet_get_clientid()) 
		{
			while(my.leben>0) 
			{
				if(key_A+key_W+key_D+key_S>0)	{dist_move.x = 25*time;} else {dist_move.x = 0;}


				moved_dist = c_move(my,dist_move,nullvector,IGNORE_PASSABLE|GLIDE|IGNORE_PUSH); 
				if(abs(moved_dist) > 0) //Wenn sich die Entity bewegt hat 
				{ 
					enet_set_unreliable(1); //damit die Position unreliable gesendet wird 
					//sendet die neue Position an alle: 
					enet_send_pos(enet_ent_globpointer(my),BROADCAST,0); 
					enet_set_unreliable(0); //schaltet unreliable wieder aus 
					//damit andere Sendfunktionen nicht beeinflusst werden 
				}
				if(key_W)	{moved_pan =  90;}
				if(key_A)	{moved_pan = 180;}
				if(key_S)	{moved_pan = 270;}
				if(key_D)	{moved_pan =   0;}
				if(key_W && key_D)	{moved_pan =  45;}
				if(key_S && key_D)	{moved_pan = 315;}
				if(key_S && key_A)	{moved_pan = 225;}
				if(key_W && key_A)	{moved_pan = 135;}
				if(moved_pan != my.pan) //wenn der Player gedreht wurde 
				{
					my.pan = moved_pan;
					enet_set_unreliable(1); 
					//sendet die neuen Winkel an alle: 
					enet_send_angle(enet_ent_globpointer(my),BROADCAST,ONLYSEND_PAN);
					enet_set_unreliable(0); 
				}
				kamera_bewegung();  //if(key_F){erster_slot+=1;} enet_send_skill(enet_ent_globpointer(my),1,1,BROADCAST);
				wait(1);
			}
		}
		wait(1);
	}
}


Ich hab das aus dem 3D-Chat-workshop(der echt toll ist!).
Der Server wird erstellt.
Er clinkt sich dabei selbst als Client ein und erstellt ne Spielfigur.
Clients joinen und per enet_clset_event->EVENT_CONNECTED wird synchronisiert.
Durch das ausgelöste enet_clset_event->EVENT_SYNCHRONIZED wird eine Spielfigur für den Clienten erstellt.
Doch wenn ich das ausführe, passiert das, was ich vorhin beschrieben habe -
1. Servervlient: 2 entities (ober- und unterkörper)
weiterer client: 6 entities
dritter client: 12 entities
jeder kann sich bewegen, es ist alles "normal" - mir ist das erst garnicht aufgefallen, nur durch die Anzahl der Entities später.
Die, die zusätzlich "nicht da sein dürften" "kleben" an der Serverclient-Entity.

Re: [ANET] A6 Pointer in entity.skill speichern [Re: JoGa] #333298
07/15/10 16:32
07/15/10 16:32
Joined: Jul 2005
Posts: 1,930
Austria
Dark_samurai Offline
Serious User
Dark_samurai  Offline
Serious User

Joined: Jul 2005
Posts: 1,930
Austria
Das Problem liegt in deiner Playerfunktion. Diese wird von JEDEM Rechner ausgeführt => es wird von jedem enet_ent_create("spieler01_oben.mdl"...); ausgeführt. enet_ent_create() erzeugt automatisch auf jedem Rechner eine Entity. Deswegen die vielen Entities.

Ich würde enet_ent_create("spieler01_oben.mdl"...); in dem Teil der Funktion ausführen, der nur vom Ersteller der Spielerentity ausgeführt wird. Also nach if(enet_ent_creator(enet_ent_globpointer(my)) == enet_get_clientid()). Dann wird die Funktion nur einmal ausgeführt und es wird dadurch auch nur eine Entity auf jedem Rechner erstellt.


ANet - A stable and secure network plugin with multi-zone, unlimited players, voip, server-list features,... (for A7/A8)!
get free version
Re: [ANET] A6 Pointer in entity.skill speichern [SOLVED] [Re: Dark_samurai] #333309
07/15/10 17:35
07/15/10 17:35
Joined: Dec 2003
Posts: 988
Germany, Magdeburg
JoGa Offline OP
User
JoGa  Offline OP
User

Joined: Dec 2003
Posts: 988
Germany, Magdeburg
Wow, Leute, danke, wenn wir im Pub säßen, würd ich euch zwei ne Runde spendieren wink
Das Problem war, wie Dark_samurai erkannt hat, dass das Entity von jedem Client erstellt wurde, anstatt nur von dem zugehörigen Client.
Danach tauchte noch ein weiteres Problem meines Codes auf und zwar, dass das obere angefügte Teil trotzdem nicht an seiner Position, sondern an der Position vom serverclient-Entity war.
Das habe ich dann mit dem roten Einschub, weiter unten zu sehen, behoben. Zwar wird das jetzt jeden Tick gesendet, aber es klappt wenigstens mal und jetzt kann ich ja das senden noch einschränken, das ist ja dann machbar für mich.
Code:
function oberes_teil()
{
	while(enet_ent_globpointer(my) == ANET_ERROR) {wait(1);}
	//my.entity_handle = handle(you);
	//player_attacs();
	my.passable = on;
	my.transparent = on;
	while(1)
	{
		you = enet_ent_locpointer(my.entity_handle);
		vec_set(my.x,you.x);
		vec_set(temp.x,vector(mouse_pos.x,mouse_pos.y,camera_dist));
		vec_for_screen(temp,camera);
		temp.z = 0;
		//you = 
		vec_sub (temp.x, you.x);
		vec_to_angle (my.pan, temp); // rotate it towards the target
		/*EINSCHUB*/if(enet_ent_creator(enet_ent_globpointer(my)) == enet_get_clientid())/*EINSCHUB*/
		{
			enet_send_pos(enet_ent_globpointer(my),BROADCAST,0);
			enet_send_angle(enet_ent_globpointer(my),BROADCAST,ONLYSEND_PAN);
		}
		wait(1);
	}
}


Ich denk, dass das rote, zweite Problem, das nach dem, das dark_samurai gelöst hat, auftrat; mit dem ersten zusammenhing.
Jeder Spieler hat die ganzen angehängten Entitiy-Funktionen der anderen auch ausgeführt und dann "sich" alle angehängt, der Server läuft da dann wohl als letztes durch und hat dann die angehängten Entities an sich - aber das ist nur ein Erklärungsversuch von mir, genau hab ichs noch nicht geblickt, zum Glück xD (oh gott, mit so ner Einstellung werd ich nie Programmierer xD) funktionierts ^^ und ich gies erstmal ne Runde Garten und dann noch mal schaun.

DANKE!!
allein dem Support ist es Wert, sich ANET zuzulegen ;-)
(was ich dann hoffentlich auch mach, wenn das jetzt einigermaßen läuft und ich mein erstes kleines Multiplayerspiel dann fertig bekomm)

EDIT: rot markierne hat nicht geklappt, habs Einschub genannt. (kommentar vor und nach der Codezeile)

Last edited by JoGa; 07/15/10 17:36.
Re: [ANET] A6 Pointer in entity.skill speichern [SOLVED] [Re: JoGa] #333412
07/16/10 09:59
07/16/10 09:59
Joined: Jul 2005
Posts: 1,930
Austria
Dark_samurai Offline
Serious User
Dark_samurai  Offline
Serious User

Joined: Jul 2005
Posts: 1,930
Austria
Dadurch, dass ja bereits die Position des Spielers aktualisiert wird ist es nicht nodwendig auch die Position von "oberes_teil" zu senden, da dies ja die selbe Position hat wie der Player. Aber das hast du ja schon richtig erkannt.

Das Problem ist glaube ich, dass du my.entity_handle nur lokal speicherst (also auf dem PC der den Player und "oberes_teil" erstellt hat). Sende per enet_send_skills() den Skill zuerst an alle. Dann hat die Entity "oberes_teil" auf allen Rechnern im Skill my.entity_handle den globalen Pointer der zugehörigen Playerentity gespeichert. Dann sollte eigentlich alles funktionieren auch ohne dem Einschub.

Wenn du den Skill nicht sendest ist er auf den anderen PCs immer 0. D.h. die Entity wird an die Entity angehängt die den globalen Pointer 0 hat also die, die als erstes erstellt wurde wink


ANet - A stable and secure network plugin with multi-zone, unlimited players, voip, server-list features,... (for A7/A8)!
get free version
Re: [ANET] A6 nochmal kleines Problem mit glob_pointer [Re: Dark_samurai] #333643
07/17/10 20:54
07/17/10 20:54
Joined: Dec 2003
Posts: 988
Germany, Magdeburg
JoGa Offline OP
User
JoGa  Offline OP
User

Joined: Dec 2003
Posts: 988
Germany, Magdeburg
Okay, super - funktioniert einwandfrei.
Jetzt hab ich noch eine Frage, dann hab ich warscheinlich das Multiplayerplugin einigermaßen als Anwender kapiert ^^

Folgendes Problem:
Entity wird in WED gesetzt. (als "Medipack" - spieler läuft drüber und bekommt Hp gutgeschrieben)

Wenn ich es in WED setze, wird es dank synchronize-Befehl am Anfang ja ein globales Entity.
Trotzdem bekomme ich eine Empty-Pointermeldung, wenn ich das Entity mit
enet_ent_remove(enet_ent_globpointer(my));
entfernen möchte.
Per ent_remove geht, aber dann ists ja nur auf dem jeweiligen Clienten gelöscht und nicht global.


Code:
function item_hp_event()
{
	my.passable = on;
	if(you.gesinnung != spieler)	{my.leben = 0; return;}
	you.leben += my.leben;
	my.leben = 0;
}

action item_hp
{
	while(enet_get_connection() == NO_CONNECTION) 	{wait(1);} //wartet bis ein Service initialisiert wird 
	if(enet_get_connection() == SERVER_MODE || enet_get_connection() == CLIENT_SERVER_MODE)  {enet_ent_register(my);} // Server registriert 
	while(enet_ent_globpointer(my) == ANET_ERROR) 	{wait(1);} //wartet bis der Entity ein globaler Pointer zugewiesen wird 
	my.push = -1;
	my.leben = 25;
	my.event = item_hp_event;
	my.enable_push = on;
	while(my.leben>0)
	{
		wait(1);
	}
	/*if(enet_get_connection() == CLIENT_SERVER_MODE) {*/enet_ent_remove(enet_ent_globpointer(my));//}
}


Meinem Code anzusehn habe ich schon etwas probiert:
- anfangs das Entity nochmal als globales Entity registrieren
- und am Ende die Entity nur vom Clientserver zu löschen, damit das nicht x-mal ausgeführt wird.

Irgendwie wieder ein Denkfehler meinerseits - ich hoff, ich muss euch diesbezüglich nicht mit noch mehr dupfbackenfragen plagen >.<

Re: [ANET] A6 nochmal kleines Problem mit glob_pointer [Re: JoGa] #333727
07/18/10 17:11
07/18/10 17:11
Joined: Jul 2005
Posts: 1,930
Austria
Dark_samurai Offline
Serious User
Dark_samurai  Offline
Serious User

Joined: Jul 2005
Posts: 1,930
Austria
Quote:
Wenn ich es in WED setze, wird es dank synchronize-Befehl am Anfang ja ein globales Entity.


Nein, dafür gibt es diese Funktion: enet_ent_register().
Einfach am Server alle solche Entities mit dieser Funktion in eine globale umwandeln. Danach wird beim Synchronisieren auch bei den Clients jede Entity zu globalen.


ANet - A stable and secure network plugin with multi-zone, unlimited players, voip, server-list features,... (for A7/A8)!
get free version
Page 1 of 2 1 2

Moderated by  HeelX, Spirit 

Gamestudio download | chip programmers | Zorro platform | shop | Data Protection Policy

oP group Germany GmbH | Birkenstr. 25-27 | 63549 Ronneburg / Germany | info (at) opgroup.de

Powered by UBB.threads™ PHP Forum Software 7.7.1