Beiträge von Alf21

    Ich finde es iwie sinnlos eine for Schleife zu machen und diese dann in der letzten Ausgabefolge abzubrechen. Dann kann man gleich die schleife weglassen, da sie eh nur 1x durchläuft.
    Man benutzt break, wenn man sie unter bestimmten Bedingungen abbrechen will, zB if( p = 8 ) break; oder so, doofes Beispiel aber dann würde es abgebrochen, wenn p = 8 ist, also die 8. Partei erreicht ist ^^


    Also kurz: Unnötige Schleife wie du ebend gerade selbst gepostet hast :D


    //edit: Das problem was ich nun sehe ist folgendes: in dem /wahl CMD hast du eine for schleife die in abhängigkeit der Parteianzahl funktioniert. Nun wird aber bei jeder Partei die es gibt ein Dialog angezeigt, also wenn es 16Fraktionen gibt wird am ende nur der 16. Dialog angezeigt.
    Ich weiss nicht ob das auch in PAWN geht, ich benutze Shoebill/Java, aber vielleicht kann man ja einen listdialog erstellen und dann jedes mal Items hinzufügen, halt als eintragungen diese Fraktionen. Andernseits einfach in der for schleife den String immer zusammenfügen und vor dem zusammenfügen mit \n trennen und am ende ausgeben/zum Dialog hinzufügen (das heißt Dialog erst nach der for - Schleife), keine Ahnung ob das auch für nen Dialog klappt ^^

    Ist die ID auch eindeutig?
    Du fragst im MySQL Query ab: ... WHERE id ='%i' -> db_id
    Ich hätte das über WHERE player='%s' -> playername oder so geregelt, ist aber egal wenns eindeutig ist ^^


    @Homez, könnte es sein dass er zu ein altes MySQL Plugin hat oder ein verbuggtes?^^

    Ich kann dir mur Wordpress empfehlen, das beste womit man anfangen kann! Es gibt dafür soweit ich weiß die meisten Extensions, also Plugins, kostenlose Templates (Design) und man kann viel dran rumwerkeln und es ist einfach!


    Hab mal nen Plugin dafür gemacht, wo ein Panel für SAMP installiert wird, arbeite gerade aber an was anderen, falls es dich interessiert einfach sagen ob du für das Plugin ne Erweiterung brauchst und ich veröffentliche die..


    Ich will mich ja nicht an der Grafik fest machen. Klar, für das Alter des Games ist das eine echt gute Grafik, aber das ändert nichts daran, dass es mittlerweile zählreiche Spiele mit besserer Grafik gibt. Und mir persönlich ist die Grafik oder Auflösung recht egal, man sollte schon was erkennen, doch wenn man so andere 'Gamer' anguckt oder fragt, so ist es bei mir, die wollen alle eine Top Grafik, mehr Objekte und dass die Ränder von den Objekten stimmen, und man halt nicht durch manches durchlaufen kann und manches, wo man durchlaufen müsste, nicht kann. Sind halt eigentlich kleine Fehler, aber diese haben die neuen GTA Versionen KAUM noch.


    Ich könnte mir vorstellen, dass es weit aus mehr Möglichkeiten geben wird und appelliere an die Entwickler, die immer wieder einen Multiplayer bauen. Top Arbeit! Ich finde es schade, dass Rockstar so etwas nicht gleich macht oder fördert. Hat viele positive Aspekte. Ich hoffe es klappt und wird in Java möglich sein, falls nicht hoffe ich wieder auf Shoebill, aber erst einmal abwarten und bessere Graka kaufen :D

    Ich komme komischerweise mit dem Handy auf die Seite, jedoch aber nicht mehr über den Computer. Dort habe ich eine Ladezeit von mehr als 3min. Wenn ich dann auf Laden Abbrechen klicke, erscheint die Seite, mit ein paar Fehlern. Hauptsächlich klappt es dann, nur ich brauche über 3min um von einer Breadfish-Seite zur anderen zu kommen und über die Console werden mir Javascript Fehler angezeigt. Vielleicht verlädt sie sich? Haben das Problem noch andere?? Meine Cache ist leer und alle Cockies und sonstiges wurde gelöscht. Andere externe Seiten gehen.

    Ich denke mir alles in allem, dass hier viele Recht haben, dass SA:MP legendär ist. Dennoch befürworte ich es sehr, wenn es so etwas nochmal für GTA V gibt. Es reicht ja wenn man dann wieder die nächsten 2 Generationen GTA's auslassen würde und halt einen MP nur für GTA V und später vielleicht wieder für GTA VII machen würde. Ich gehe davon aus, dass GTA immer weiter entwickelt wird^^ Aber um beim Thema zu bleiben: Ich denke, dass man unbedingt einen Multiplayer für GTA V braucht, welcher wie SA:MP funktioniert. Halt mit Scripts. Eigenen ^^ Denn immer mehr Leute hören auf SA:MP zu spielen, und nach meiner Erfahrung kommen kaum neue hinzu. Denn wozu Geld für GTA San Andreas bezahlen, wenn man eh nur 1. den Multiplayer spielen will und es ne schlechte Grafik hat und von den GTA's mittlerweile auch wieder sehr alt ist? So spielt man lieber andere coole neue Games, ist ja auch kein Unterschied. Es wäre also gut, wenn es für GTA V einen Multiplayer geben würde, denn jeder der einen anständigen PC hat und gerne spielt (und nicht nur auf der PS4 / XBOX) wird sich wahrscheinlich GTA V holen ^^


    Als Programmsprache würde ich selbst Java bevorzugen, es gibt mehr Möglichkeiten finde ich, normalerweise bessere Performance und wenn man Hilfe braucht, kennen sich viele aus. Zudem gibt es auch schöne Editoren, oder wie das noch genannt wird. Z.B. Eclipse.
    Ich nutze auch jetzt schon Java für SA:MP, der Nachteil ist aber, dass man einen teuren Root Server braucht, da man mit der Shoebill API seine Server-/Dateistruktur verändert und das nicht normal gehostet wird von iwelchen Anbietern.


    Also alles in allem, um es nochmal aufzugreifen, finde ich, dass man GTA V:MP braucht, um wieder etwas reißen zu können.

    An alle die Probleme mit den Anfängen haben, so wie ich :D
    Es gibt nen schönes Dealership Plugin für Shoebill / auf Java, daran kann man sich gut orientieren, zB wie man objektorientiert programmiert oder Sachen mit Dialogen und Lifecycles / Referenzen.


    Ich werde ein paar experimentelle Sachen ausprobieren, dennoch erstmal ein RPG Grundsystem aufbauen, mal sehen wie es wird ^^

    Wie Installiert man das denn, damit ich es nutzen kann? Das ist mein einzigstes Problem :D

    @MiX(eP) :
    Dazu hat 123marvin123 extra ein Tutorial gemacht :D
    Ich nutze zB Eclipse. Ich habe alles der Anleitung nach gemacht, Downloads sind ja auch angegeben.
    Dann bin ich einfach in Eclipse unter Hilfe gegangen und unter Marktplatz. Dort kannst du dir kostenlos Maven downloaden, dazu musst du nur "m2e" als Plugin suchen und installieren, glaube das heißt iwie "m2e Support for Keppler S2" oder so ^^ Auf jeden Fall, falls das nicht geht muss du dir erst Keppler S2 oder wie das heißt downloaden, kannst du dort auch einfach suchen. Und fertig, dann musst du nur noch einrichten (Maven, einfach nach Installationsanleitung).


    Hier meine Maven Bsp. Datei:

    Code
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">	<modelVersion>4.0.0</modelVersion>	<groupId>[Dein Pfad, wie dein Package-Name, in dem der Gamemode ist, z.B. com.samp.gamemode]</groupId>	<artifactId>Dein_Projektname</artifactId>	<version>0.0.1-SNAPSHOT</version>		<name>Dein_Projektname</name>	<description>Deine Projekt Beschreibung</description>	<url>Deine_URL_zur_Website</url>		<properties>		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>	</properties>		<repositories>		<repository>			<id>central</id>			<name>Central</name>			<url>http://repo1.maven.org/maven2/</url>		</repository>		<repository>			<id>gtaun-public-repo</id>			<name>GTAUN Public Repository</name>			<url>http://repo.gtaun.net/content/groups/public</url>		</repository>		<repository>			<id>sonatype-oss-snapshots</id>			<name>Sonatype Oss Snapshots</name>			<url>https://oss.sonatype.org/content/repositories/snapshots/</url>			<snapshots>			<enabled>true</enabled>			<updatePolicy>daily</updatePolicy>			</snapshots>		</repository>	</repositories>		<dependencies>		<dependency>			<groupId>junit</groupId>			<artifactId>junit</artifactId>			<version>3.8.1</version>			<scope>test</scope>		</dependency>			<dependency>			<groupId>net.gtaun</groupId>			<artifactId>shoebill-api</artifactId>			<version>1.1-SNAPSHOT</version>			<type>jar</type>			<scope>compile</scope>		</dependency>				<dependency>			<groupId>net.gtaun</groupId>			<artifactId>shoebill-common</artifactId>			<version>1.0-SNAPSHOT</version>			<type>jar</type>			<scope>compile</scope>		</dependency>
    		<dependency>			<groupId>net.gtaun</groupId>			<artifactId>shoebill-utilities</artifactId>			<version>1.0-SNAPSHOT</version>			<type>jar</type>			<scope>compile</scope>		</dependency>
    		<dependency>			<groupId>net.gtaun</groupId>			<artifactId>util-event</artifactId>			<version>1.0-SNAPSHOT</version>			<type>jar</type>			<scope>compile</scope>		</dependency>	</dependencies>		<build>		<defaultGoal>clean install</defaultGoal>
    		<plugins>			<plugin>				<groupId>org.apache.maven.plugins</groupId>				<artifactId>maven-compiler-plugin</artifactId>				<version>3.1</version>				<configuration>					<source>1.8</source>					<target>1.8</target>				</configuration>			</plugin>			<plugin>                <groupId>org.apache.maven.plugins</groupId>                <artifactId>maven-jar-plugin</artifactId>                <version>2.3.1</version>                <configuration>                    <outputDirectory>[Dein Ausgabepfad, z.B. C:\Users\...]</outputDirectory>                </configuration>            </plugin>		</plugins>	</build></project>


    Dann ein Gamemode bauen, unter Debug -> Maven Install oder Maven Build ausführen, dann die jar in den ServerOrdner, unter shoebill->gamemodes, alles anpassen, also maven Pfad usw. in shoebill.yml und resources.yml und dann die Startup.bat ausführen ^^


    //edit


    Ich denke ich verstehe jetzt das Problem... Du meintest bestimmt wie man es auf nem Server wie einen externen Linux Server installiert. Falls ja, das Problem habe ich auch. Ich kann keinen Maven Path angeben und keine Ahnung, wie man das Shoebill Plugin da starten lässt...

    Hey ich bins wieder ^^
    Was wäre die einfachste Methode zu checken, ob ein Spieler connected ist ?
    (PAWN: if(IsPlayerConnected(playerid)){...})
    wie mache ich das hier ? Über das neue Update mit den Referenzen oder das update am 25 Jan mit den Callbacks?
    leider gibt es im Internet keine Dokumentation :/
    Man sollte für Shoebill auch eine Übersicht machen, damit man schnell etwas findet und nicht nach Befehlen oder Abfragen / Klassennamen suchen muss :o


    Bin dabei einfach den Chat zu säubern (Chat-Saubermachen-Funktion^^), aber ist wohl schwerer als ich es dachte für mich 8|

    Nemesus: Danke! Das freut mich, wenn es auch NOCH nicht so viel beinhaltet.


    ChristianW, das ist auch nicht mein System, das ist ein anderes Testsystem :D
    (Es funktioniert nicht, da ich die Ordnerstruktur komplett neu angepasst habe, doch diese Systeme werden auch bald dem Plug-in hinzugefügt)


    Gehe mal auf diesen Link und logge dich mit den darunter gegebenen Daten ein:

    Du brauchst die Database nicht extra neu anpassen, das kannst du alles unter "Einstellungen" in Wordpress unter "GameFuechse Plug-ins" einstellen. Es gibt sogar eine Option, welche die Columns, also die Spalten dazuadded, dennoch ist davon abzuraten, da dann die Database modifiziert wird ^^


    ChristianW: Man braucht wie gesagt kein Testscript, sondern nur das aufgelistete:

    • Eine Webspace, auf der Wordpress installiert ist
    • Eine MySQL Datenbank
    • Ein SA:MP Gamemode, welches die User-Daten auf einer über Wordpress erreichbare MySQL Datenbank speichert.
    • Kenntnisse über den Namen dieser MySQL Tabelle und deren Spalten


    seegras: Einen Waffenladen :D Natürlich werden noch andere folgen, aber es ist halt die erste Erweiterung. Sie sind halt Systeme, die einfach zu konfigurieren sind und ihr es nicht extra schreiben müsst, sozusagen wird dadraus irgendwann ein User Control Panel, sobald noch mehr Erweiterungen vorhanden sind. Und man kann halt einstellen, welche man haben möchte, dennoch sind generell alle immer installiert.


    Testwebsite:

    GameFuechse Plug-ins


    Das GameFuechse Plug-ins ist ein Plugin für Wordpress.
    Es ist im Prinzip das Grundgerüst für die Erweiterungen, welche von uns immer wieder über Updates hinzugefügt werden.
    Die erste Erweiterung ist schon vorinstalliert, also der Waffenladen.


    Also veröffentliche ich nun mein erstes Plugin für Wordpress und so wird es auch meine erste Veröffentlichung von Projekten sein, weshalb dieses Plugin auch noch nicht so sehr "OP" geschrieben ist und noch Bugs beinhaltet sind, welche aber bei Bekanntgabe gefixt werden.



    Was ihr benötigt:

    • Eine Webspace, auf der Wordpress installiert ist
    • Eine MySQL Datenbank
    • Ein SA:MP Gamemode, welches die User-Daten auf einer über Wordpress erreichbare MySQL Datenbank speichert.
    • Kenntnisse über den Namen dieser MySQL Tabelle und deren Spalten


    Was ist eigentlich der Sinn dieses Plug-ins?
    Ich habe mir folgendes gedacht: Warum sollte man kein User/Admin Control Panel mit Wordpress haben?
    Es wäre ein echter Vorteil, da Wordpress sehr viele Möglichkeiten bietet. Zum Beispiel tausende von Plug-ins, von denen man viele kostenfrei nutzen kann - wie auch Wordpress.
    Zudem hat man dann gleich einen Blog in seinem ACP/UCP. Und man kann mit Wordpress bbPress sogar mehrere Foren hinzufügen.
    Ein weiterer Vorteil ist, dass man immer ein neues Template nehmen kann bzw. das alte ändern kann und so sehr dynamisch ist und alles nach seinen Wünschen anpassen kann.
    So soll dieses Plugin im Prinzip euch nur die Arbeit mit Wordpress erleichtern, da es dort auch ein wenig abgewandelte PHP Funktionen gibt für bessere Stabilität und euch auch die Arbeit nehmen und auch nur das Grundgerüst geben. Designen könnt ihr das beispielsweise selbst, dazu gibt es auch so einige Plugins, dafür hat der Waffenladen extra style-IDs bekommen, dazu aber leider erst später.
    Die Wünschen bzw. gewünschten Änderungen bitte einfach hier posten oder per PN.


    Im Prinzip ist der Waffenladen auch nicht DAS, was man für ein UCP/ACP braucht, doch es kommen noch weiter hinzu und es war jetzt ein System, welches ich als erstes anfangen wollte, da es eine Herausforderung für mich war und es denke recht selten ist, vielleicht kann man es ja gebrauchen.


    ---------------


    Dieses Plug-in darf nicht in kopiert werden und dann unter anderem Author und Namen weitergegeben oder verfälscht werden, solange es nicht genehmigt wurde (von uns ^^). Doch ihr könnt dadran rumbasteln und ansonsten machen was ihr wollt. Also bitte nicht die Credits ändern, es sind eh nirgends (außer in der Plug-in-Beschreibung) Credits.


    [TODO]:

    • Sprachdateien um das Deutsch zu verbessern (Ja, es ist auf Englisch geschrieben) -> Nächstes Update
    • Bugfixes
    • Neue Erweiterung: Banksystem (fast fertig!)


    [INFO] >> Da die Updates über Selfhosting geregelt werden und dies vielleicht irgendwann geändert wird, solltet ihr hier nachsehen, ob ich hier neue Updates released habe, falls es längere Zeit keine mehr gab und es zu Inaktivität keine Benachrichtigung gibt.


    Bitte Bugs bekanntgeben, damit diese gefixt werden können. Bei mir lief bei 3Tests alles ohne Fehler, localhost und webhost.


    Installation:

    • Plug-in downloaden
    • Plug-in in Wordpress hochladen & installieren
    • Plug-in aktivieren
    • Unter 'Einstellungen' -> 'GameFuechse Plug-ins' gehen und den Namen der MySQL Database, welche die Daten beinhaltet, angeben
    • Alle Columns-/Spaltennamen korrekt eintragen und UNBEDINGT auf Update/Aktualisieren drücken ! (Dadurch wird die Config Datei erstellt, auf der alles basiert)
    • Dann unter 'Seiten'->'Alle Seiten' gehen und dann die Seite Weaponshop suchen. Z.B. den Titel könnt ihr beliebig anpassen und den Permalink (eigentlich^^) auch.
    • Nun könnt ihr noch, wenn ihr wollt, die Seite einem Menü hinzufügen.



    MfG Alf21 :D


    PS:
    >Datei im Anhang, bald über Link verfügbar bzw. mit Download und Antivirus
    >Wir übernehmen keine Haftung für Verluste von Daten. Es ist halt 1. PHP, 2.MySQL und 3. Wordpress, wenn man etwas nicht korrekt konfiguriert hat (Oder auf unserer Seite der Code nicht sauber ist oder etwas in Wordpress an Funktionen geändert wurde, führt das zu Komplikationen und dann kann so etwas passieren, also generell immer: BACKUP! (meistens reicht MySQL Database in phpMyAdmin einfach exportieren.)

    mir fehlt seit dem neuen Update die net/gtaun/shoebill/event/server/GameModeInitEvent, weshalb der Server denke nicht starten will:


    Fehlermeldung:


    Steht die iwo zum download zur Verfügung oder woran liegt es? :(

    >>edit:
    123marvin123:


    Die Links zu den Downloads sind wohl broken, es wird URL not request glaube angezeigt bei beiden...
    Ehm... Ich habe jetzt einfach von der GitHub gedownloaded, mal gucken ob es klappt


    Und wenn alles klappt und auch so, hammer Arbeit ! :thumbup:


    --------------------------


    Hab mir mal die Arbeit (^^) gemacht, um nen kleinen Fix in die DynamicActionLabel.java reinzuhauen.


    Frage: Habt ihr für dieses Problem eine bessere/saubere/stabilere Lösung? Diese braucht recht viel Performance :/


    >>update: Bugs gefixt


    --------------------------


    Fix der Bugs des ersten 'Beta' Posts ^^
    Man kann nun Farben und andere "~"/Tilde in den Inputs/Reasons nutzen (like ~r~, ~h~)
    Das einzige was noch erledigt werden muss: Max String Länge mit Autoremove, um Fehlermeldungen und hässlichem Aussehen voraus zu sein ;)


    DynamicActionLabel.java

    Java
    //Bug: Die max. Länge des input Strings sollte noch definiert werden, bzw ein Erkennungs- und Kürzungssystem eingebaut werden, um Fehlermeldungen zu vermeiden//Anfällig: Für Spams von Strings -> Fehler//Lsg.: Input einlesen, kürzen, ausgeben ^^ Am besten gleich bei addPoints()/add() + Timeout gegen Spam?package com.samp.lvdm;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.regex.*;import net.gtaun.shoebill.constant.TextDrawAlign;import net.gtaun.shoebill.exception.CreationFailedException;import net.gtaun.shoebill.object.Player;import net.gtaun.shoebill.object.PlayerTextdraw;public class DynamicActionLabel extends Thread {	private ArrayList<DynamicItem> items = new ArrayList<DynamicItem>();	private int mPoints = 0;	private boolean combo = false;	private PlayerTextdraw mComboTextbase = null;	private Player mPlayer;	public DynamicActionLabel() { }	public class DynamicItem {		public static final int TYPE_BIG = 1;		public static final int TYPE_SMALL = 2;		private int mYPosition = 0;		private String mText;		private Player mPlayer;		private PlayerTextdraw mVisibleTextdraw;		private boolean mRemovable = false;		private boolean mPending = true;		private long mTimestamp;		private int mType;		private PlayerTextdraw textdraw = null;		public void setPending(boolean pStatus) {			mPending = pStatus;		}		public boolean isActive() {			return ((mTimestamp + 6) < (System.currentTimeMillis() / 1000l)) ? false : true;		}		public boolean isPending() {			return mPending;		}		public boolean isRemovable() {			return mRemovable;		}		public int getYPosition() {			return mYPosition;		}		public String getText() {			return mText;		}		public void setText(String pText) {			mText = pText;		}		public DynamicItem(Player pPlayer, String pText, int pType) {			this.mText = pText;			this.mPlayer = pPlayer;			this.mVisibleTextdraw = createTextDraw(mText, 0, 0);			this.mTimestamp = (System.currentTimeMillis() / 1000l);			this.mType = pType;		}		public PlayerTextdraw createTextDraw(String pText, int x, int y) {			try {				textdraw = PlayerTextdraw.create(mPlayer, 400+x, 310+y);				textdraw.setText(pText);				textdraw.setAlignment(TextDrawAlign.RIGHT);				if(mType == TYPE_SMALL) {					textdraw.setLetterSize(0.135f*3, 0.135f*6);				}				else if(mType == TYPE_BIG) {					textdraw.setLetterSize(0.135f*4, 0.135f*8);				}			}			catch(CreationFailedException e) {		//	catch(Exception e) {				e.printStackTrace();			}			return textdraw;		}		public void setCurrentTextdraw(PlayerTextdraw pTextdraw) {			mVisibleTextdraw = pTextdraw;		}		public void moveDown() {			mYPosition++;			if(mYPosition > 100) {				mRemovable = true;			}			else {				PlayerTextdraw newTextdraw = createTextDraw(mText, 0, mYPosition);				hide();				setCurrentTextdraw(newTextdraw);				display();			}		}		public void display() {			if(mVisibleTextdraw != null)				mVisibleTextdraw.show();		}		public void hide() {			if(mVisibleTextdraw != null) {				mVisibleTextdraw.hide();					mVisibleTextdraw.destroy();			}		}	}	public void run() {		while(!interrupted()) {			//Server.get().sendMessageToAll(Color.BLUE, "Thread:"+Thread.currentThread().getName());			checkItemDuration();			if((mComboTextbase == null && mPlayer != null) || (mPlayer != null && !mComboTextbase.getText().equals(String.valueOf(mPoints))))				updateComboScore(mPlayer);			try {				List<DynamicItem> newList = new ArrayList<DynamicItem>(items);				Iterator<DynamicItem> it = newList.iterator();				while(it.hasNext()) {					DynamicItem item = it.next();					if(item.isPending()) {						moveItemsDown();						// show pending item						fadeItemIn(item);						// unset pending status						item.setPending(false);					}				}				Thread.sleep(200);			}			catch(Exception e) {				System.out.println(">>\t[Error]>> in run() :");				e.printStackTrace();			}		}	}	private void fadeItemIn(DynamicItem item) {		String text = item.getText();		String text2 = text;	//Addition to display Colors by Alf21	//############################################################### WICHTIG ###########################################################	//#								Anfällig, wenn bei der String/Input/Reason zu groß ist oder gespamt wird!  							#	//#												Lsg.: Reason erkennen und kürzen + Timeout?								  	#		boolean colors = false;		int colCount = 0;        Matcher matcher = Pattern.compile("\u007E+\\w+\u007E").matcher(text);        while(matcher.find()){        	colors = true;	    	colCount++;        }		int length = text.length();		if(colors){	        Matcher lastColor = Pattern.compile("\u007E+\\w\u007E\\z").matcher(text); 		//~r~|			if(!lastColor.find()) {				length = text.length()-(colCount-1)*3;			}			else { //Falls hinten eine Farbe ist, um 3 wegen dem Ausschwenken verkürzen, die Farbe sieht man eh nicht, den Ausschwenker jedoch schon				length = text.length()-colCount*3;			}		}		for(int i=0;i<=length;i++) {			int i2 = i;			text2 = text.substring(0, i2);			if(colors) {		        Matcher matcher1 = Pattern.compile("\u007E\\z").matcher(text2); //~|		        Matcher matcher2 = Pattern.compile("\u007E+\\w\\z").matcher(text2); //~r|		        Matcher matcher3 = Pattern.compile("\u007E+\\w\u007E+\\w\\z").matcher(text2); //~r~A|		        Matcher matcher4 = Pattern.compile("\u007E+\\w\u007E\\z").matcher(text2); //~r~|		    /*		    * wenn: - der String ein "~"(Tilde) + [Buchstaben] enthält,		    * aber nicht, wenn: - der String selbst eine Farbangabe "~r~" ist 		    * 					- keine "Buchstabe eines Wortes auf den Str folgt		    * Ergebnis: -> um 1 erweitern		    */		        if(matcher2.find() && !matcher3.find() && !matcher4.find()){		        	i2 += 1;			        Matcher matcher5 = Pattern.compile("\u007E+\\w\u007E\\z").matcher(text.substring(0, i2));		        	if(!matcher5.find()) {		        		i2 -= 1;		        	}		        }		    /*		    * wenn: - der String ein "~"(Tilde) enthält,		    * aber nicht, wenn: - der String selbst eine Farbangabe "~r~" ist 		    * 					- keine "Buchstabe eines Wortes auf den Str folgt		    * Ergebnis: -> um 2 erweitern		    */		        else if(matcher1.find() && !matcher3.find() && !matcher4.find()){		        	i2 += 2;			        Matcher matcher5 = Pattern.compile("\u007E+\\w\u007E\\z").matcher(text.substring(0, i2));		        	if(!matcher5.find()) {		        		i2 -= 2;		        	}		        }			}			PlayerTextdraw newTextdraw = item.createTextDraw(text.substring(0, i2), -10, 0);			item.hide();			item.setCurrentTextdraw(newTextdraw);			item.display();			try {				Thread.sleep(10);			} catch (InterruptedException e) {				// TODO Auto-generated catch block				System.out.println(">>\t[Error]>> in fadeItemIn() :");				e.printStackTrace();			}		}		if(mPlayer != null)			mPlayer.playSound(1131);		for(int i=0;i<=10;i++) {			PlayerTextdraw newTextdraw = item.createTextDraw(text, i-10, 0);			item.hide();			item.setCurrentTextdraw(newTextdraw);			item.display();			try {				Thread.sleep(20);			} catch (InterruptedException e) {				// TODO Auto-generated catch block				System.out.println(">>\t[Error]>> in fadeItemIn() :");				e.printStackTrace();			}		}	}	private void checkItemDuration() {		try {			Iterator<DynamicItem> it = items.iterator();			while(it.hasNext()) {				DynamicItem item = it.next();				if(!item.isActive()) {					//Server.get().sendMessageToAll(Color.RED, "Removing item based on timestamp!");					// custom hide animation					String text = item.getText();					String text2 = text;				//Addition to display Colors by Alf21				//############################################################### WICHTIG ###########################################################				//#								Anfällig, wenn bei der String/Input/Reason zu groß ist oder gespamt wird!  							#				//#												Lsg.: Reason erkennen und kürzen + Timeout?								  	#					boolean colors = false;					int colCount = 0;			        Matcher matcher = Pattern.compile("\u007E+\\w+\u007E").matcher(text);			        while(matcher.find()){			        	colors = true;				    	colCount++;			        }					int length = text.length();					if(colors){				        Matcher lastColor = Pattern.compile("\u007E+\\w\u007E\\z").matcher(text); 		//~r~|						if(!lastColor.find()) {							length = text.length()-(colCount-1)*3;						}						else { //Falls hinten eine Farbe ist, um 3 wegen dem Ausschwenken verkürzen, die Farbe sieht man eh nicht, den Ausschwenker jedoch schon							length = text.length()-colCount*3;						}					}					for(int i=0;i<=length;i++) {						int i2 = i;						text2 = text.substring(0, length-i2);						if(colors) {					        Matcher matcher1 = Pattern.compile("\u007E\\z").matcher(text2); 				//~|					        Matcher matcher2 = Pattern.compile("\u007E+\\w\\z").matcher(text2); 			//~r|					        Matcher matcher3 = Pattern.compile("\u007E+\\w\u007E+\\w\\z").matcher(text2); 	//~r~A|					        Matcher matcher4 = Pattern.compile("\u007E+\\w\u007E\\z").matcher(text2); 		//~r~|					    /*					    * wenn: - der String ein "~"(Tilde) + [Buchstaben] enthält,					    * aber nicht, wenn: - der String selbst eine Farbangabe "~r~" ist 					    * 					- keine "Buchstabe eines Wortes auf den Str folgt					    * Ergebnis: -> um 1 erweitern					    * 					    * Fix: Test, ob Erweiterung eine Farbe ergibt, falls nicht zurücksetzen					    */					        if(matcher2.find() && !matcher3.find() && !matcher4.find()){					        	i2 += 2;						        Matcher matcher5 = Pattern.compile("\u007E+\\w\u007E\\z").matcher(text.substring(0, (length+3)-i2));					        	if(!matcher5.find()) {					        		i2 -= 2;					        	}					        }					    /*					    * wenn: - der String ein "~"(Tilde) enthält,					    * aber nicht, wenn: - der String selbst eine Farbangabe "~r~" ist 					    * 					- keine "Buchstabe eines Wortes auf den Str folgt					    * Ergebnis: -> um 2 erweitern					    * 					    * Fix: Test, ob Erweiterung eine Farbe ergibt, falls nicht zurücksetzen					    */					        else if(matcher1.find() && !matcher3.find() && !matcher4.find()){					        	i2 += 1;						        Matcher matcher5 = Pattern.compile("\u007E+\\w\u007E\\z").matcher(text.substring(0, (length+3)-i2));					        	if(!matcher5.find()) {					        		i2 -= 1;					        	}					        }						}						PlayerTextdraw newTextdraw = item.createTextDraw(text.substring(0, length-i2), 0, item.getYPosition());						item.hide();						item.setCurrentTextdraw(newTextdraw);						item.display();						try {							Thread.sleep(10);						} catch (InterruptedException e) {							// TODO Auto-generated catch block							System.out.println(">>\t[Error]>> in checkItemDuration() :");							e.printStackTrace();						}					}					item.hide();						it.remove();				}			}		}		catch(Exception e) {			// TODO fix ConcurrentModificationException			System.out.println(">>\t[Error]>> in checkItemDuration() :");			e.printStackTrace();		}		//remove if necessary		if(items.size() == 0) {			combo = false;			//Server.get().sendMessageToAll(Color.BLUE, "COMBO:FALSE ("+items.size()+") ");			mPoints = 0;			if(mComboTextbase != null)				removeComboScore();		}	}	private void moveItemsDown() {		for(int i=0;i<18;i++) {			Iterator<DynamicItem> it = items.iterator();			while(it.hasNext()) {				DynamicItem item = it.next();				if(!item.isPending())					item.moveDown();				if(item.isRemovable()) {					if(items.contains(item)) {						item.hide();						it.remove();						//Server.get().sendMessageToAll(Color.RED, "REMOVE:"+items.size());					}				}			}			try {				Thread.sleep(30);			} catch (InterruptedException e) { 				System.out.println(">>\t[Error]>> in moveItemsDown() :");				e.printStackTrace();			}		} 	}	private void add(Player pPlayer, String text, int type) {		DynamicItem item = new DynamicItem(pPlayer, text, type);		items.add(item);	}	public void addPoints(Player pPlayer, String reason, int amount, int type) {		this.mPlayer = pPlayer;	// TODO INSECURE!!! Solve one queue per player in constructor!!!		//Addition by Alf21		if(!LvdmGamemode.allowNegativePoints)		{			if(this.mPoints + amount < 0) { //Test negative Value				this.mPoints = 0;			} else {				this.mPoints += amount; 			}		} else {			this.mPoints += amount;		}		if(amount != 0) {			add(pPlayer, reason+" "+amount, type);		}		else {			add(pPlayer, reason, type);		}		//check if combo mode		if(items.size() > 1) {			combo = true;			//Server.get().sendMessageToAll(Color.BLUE, "COMBO:TRUE ("+items.size()+")");			if(mComboTextbase != null)				removeComboScore();		}	}	private void updateComboScore(Player pPlayer) {		if(mPoints == 0 || items.size() <= 1)			return;		String score = String.valueOf(mPoints);		mComboTextbase = PlayerTextdraw.create(pPlayer, 425, 310);		for(int i=0;i<=score.length();i++) {			mComboTextbase.setText(score.substring(0, i));			mComboTextbase.show();			try {				Thread.sleep(50);			} catch (InterruptedException e) {				// TODO Auto-generated catch block				System.out.println(">>\t[Error]>> in updateComboScore() :");				e.printStackTrace();			}		}	}	private void removeComboScore() {		mComboTextbase.setText(" ");		mComboTextbase.hide();		mComboTextbase.destroy();	}}


    Zum Testen ein paar Commands, aber da es eine Beta ist, gibts auch hier noch ein paar Bugs: beim Spam-Nutzen des Commands 'testBeta6' wird eine kleine Fehlermeldung auftauchen bzw. beim nutzen von zB 2x 'testBeta6' + 'teamKill 0'

    Code
    @Command	@CommandHelp("/teamKill [playerID]")	public boolean teamKill(Player p, int targetID) {		Player.get(targetID).setHealth(0.0f);		Shoebill.get().runOnSampThread(() -> {			LvdmGamemode.queue.addPoints(p, "~r~TEAMKILL (~w~" + Player.get(targetID).getName() + "~r~)", -100, DynamicActionLabel.DynamicItem.TYPE_BIG);			p.sendMessage(Color.RED, "* Du hast " + Player.get(targetID).getName() + " aus deinem Team getötet!");		});		return true;	}	@Command	@CommandHelp("/testBeta1")	public boolean testBeta1(Player player) {		Shoebill.get().runOnSampThread(() -> {			LvdmGamemode.queue.addPoints(player, "~g~Test1 (~w~start~g~)end", 20, DynamicActionLabel.DynamicItem.TYPE_BIG);		});		return true;	}	@Command	@CommandHelp("/testBeta2")	public boolean testBeta2(Player player) {		Shoebill.get().runOnSampThread(() -> {			LvdmGamemode.queue.addPoints(player, "~g~Test2 (~w~start~g~)end~r~", 20, DynamicActionLabel.DynamicItem.TYPE_BIG);		});		return true;	}	@Command	@CommandHelp("/testBeta3")	public boolean testBeta3(Player player) {		Shoebill.get().runOnSampThread(() -> {			LvdmGamemode.queue.addPoints(player, "~g~Test3 ~y~(~w~start~g~)end~r~", 20, DynamicActionLabel.DynamicItem.TYPE_BIG);		});		return true;	}	@Command	@CommandHelp("/testBeta4")	public boolean testBeta4(Player player) {		Shoebill.get().runOnSampThread(() -> {			LvdmGamemode.queue.addPoints(player, "~g~Test4 ~p~(~w~start~g~)hfu~b~dus~x~dhffhu~r~", 20, DynamicActionLabel.DynamicItem.TYPE_BIG);		});		return true;	}	@Command	@CommandHelp("/testBeta5")	public boolean testBeta5(Player player) {		Shoebill.get().runOnSampThread(() -> {			LvdmGamemode.queue.addPoints(player, "~g~Test5 ~p~(~w~start~g~)hfu~b~dus~x~dhffhu", 20, DynamicActionLabel.DynamicItem.TYPE_BIG);		});		return true;	}	@Command	@CommandHelp("/testBeta6")	public boolean testBeta6(Player player) {		Shoebill.get().runOnSampThread(() -> {			LvdmGamemode.queue.addPoints(player, "~g~Test6 ~p~(~w~start~g~)fu~b~dsh~fs~x~dhffhu~", 20, DynamicActionLabel.DynamicItem.TYPE_BIG);		});		return true;	}	@Command	@CommandHelp("/heal [HP]")	public boolean heal(Player p, String params) //String, um es später auf Float und Double zu parsen...	{		try {	       Float.parseFloat(params);	       Double.parseDouble(params);	    } catch (NumberFormatException e) {	    /*	e.printStackTrace();	    	System.out.println(">>\t[ERROR] in heal ::::: in AdminCommands");*/	    	p.sendMessage(Color.RED, ">>[ERROR]: Dein Parameter muss eine Zahl sein!");	        return false;	    }		LvdmGamemode.queue.addPoints(p, "Geheilt auf " + Double.parseDouble(params) + " Leben", -100, DynamicActionLabel.DynamicItem.TYPE_BIG);		p.setHealth(Float.parseFloat(params));		return true;	}	@Command	@CommandHelp("/explode [playerID]") 	public boolean explode(Player p, int pID) {		float x, y, z;		// Get the player's position		AngledLocation locationTarget = Player.get(pID).getLocation();		x = locationTarget.getX();		y = locationTarget.getY();		z = locationTarget.getZ();	    // Create an explosion at the player's position		Player.get(pID).createExplosion(x, y, z, 12, 10);		return true;	}


    MfG Alf21

    Thx, läuft alles super! :)


    Also gibts - wie immer in Java - mehrere Möglichkeiten, es zu realisieren.
    Ich denke ich nehme das mit den Instanzen bei Werten, welche ich später noch brauche und das mit dem neuen EventHandler bei den Sachen, die einfach nur einmal ihren Zweck erfüllen sollen.

    123marvin123:


    Danke, sehr gut erklärt, ich habe es verstanden, dank der Beispiele und Erläuterungen :)
    In meinem Gamemode funktioniert das jetzt, nur ganz durchblicke ich es doch noch nicht ^^
    Das Problem nun besteht darin, dass ich mich in einem EventManager (playerEventManager) befinde, welcher zB das PlayerDeathEvent,... regelt.
    Wie kann ich dort eine Instanz kreieren? Ist ja sozusagen dann eine Instanz in etwas was eine Instanz erstellen soll :/


    Ziel: Ich will den Killer von PlayerDeathEvent nach PlayerSpawnEvent bringen/vererben:

    Java
    package com.samp.lvdm;import java.util.Random;import net.gtaun.shoebill.Shoebill;import net.gtaun.shoebill.common.command.CommandGroup;import net.gtaun.shoebill.common.command.PlayerCommandManager;import net.gtaun.shoebill.common.player.PlayerLifecycleHolder;import net.gtaun.shoebill.constant.WeaponModel;import net.gtaun.shoebill.data.Color;import net.gtaun.shoebill.data.Vector3D;import net.gtaun.shoebill.event.player.PlayerCommandEvent;import net.gtaun.shoebill.event.player.PlayerConnectEvent;import net.gtaun.shoebill.event.player.PlayerDeathEvent;import net.gtaun.shoebill.event.player.PlayerDisconnectEvent;import net.gtaun.shoebill.event.player.PlayerRequestClassEvent;import net.gtaun.shoebill.event.player.PlayerSpawnEvent;import net.gtaun.shoebill.event.player.PlayerUpdateEvent;import net.gtaun.shoebill.event.player.PlayerWeaponShotEvent;import net.gtaun.shoebill.object.Player;import net.gtaun.util.event.EventManager;import net.gtaun.util.event.EventManagerNode;import net.gtaun.util.event.HandlerPriority;public class PlayerManager{	public static final int MAX_PLAYERS = LvdmGamemode.MAX_PLAYERS;	private boolean suicid = false;	private boolean killed = false;	private Player[] lastKiller = new Player[MAX_PLAYERS];	private static final int INITIAL_MONEY = 50000;	private static final Vector3D[] RANDOM_SPAWNS =	{		new Vector3D(1958.3783f, 1343.1572f, 15.3746f),		new Vector3D(2199.6531f, 1393.3678f, 10.8203f),		new Vector3D(2483.5977f, 1222.0825f, 10.8203f),		new Vector3D(2637.2712f, 1129.2743f, 11.1797f),		new Vector3D(2000.0106f, 1521.1111f, 17.0625f),		new Vector3D(2024.8190f, 1917.9425f, 12.3386f),		new Vector3D(2261.9048f, 2035.9547f, 10.8203f),		new Vector3D(2262.0986f, 2398.6572f, 10.8203f),		new Vector3D(2244.2566f, 2523.7280f, 10.8203f),		new Vector3D(2335.3228f, 2786.4478f, 10.8203f),		new Vector3D(2150.0186f, 2734.2297f, 11.1763f),		new Vector3D(2158.0811f, 2797.5488f, 10.8203f),		new Vector3D(1969.8301f, 2722.8564f, 10.8203f),		new Vector3D(1652.0555f, 2709.4072f, 10.8265f),		new Vector3D(1564.0052f, 2756.9463f, 10.8203f),		new Vector3D(1271.5452f, 2554.0227f, 10.8203f),		new Vector3D(1441.5894f, 2567.9099f, 10.8203f),		new Vector3D(1480.6473f, 2213.5718f, 11.0234f),		new Vector3D(1400.5906f, 2225.6960f, 11.0234f),		new Vector3D(1598.8419f, 2221.5676f, 11.0625f),		new Vector3D(1318.7759f, 1251.3580f, 10.8203f),		new Vector3D(1558.0731f, 1007.8292f, 10.8125f),		new Vector3D(-857.0551f, 1536.6832f, 22.5870f),		new Vector3D(817.3494f, 856.5039f, 12.7891f),		new Vector3D(116.9315f, 1110.1823f, 13.6094f),		new Vector3D(-18.8529f, 1176.0159f, 19.5634f),		new Vector3D(-315.0575f, 1774.0636f, 43.6406f),		new Vector3D(1705.2347f, 1025.6808f, 10.8203f)	};	private EventManagerNode eventManagerNode;	private PlayerCommandManager commandManager;	private Random random;	public PlayerManager(EventManager rootEventManager)	{			random = new Random();		eventManagerNode = rootEventManager.createChildNode();		commandManager = new PlayerCommandManager(eventManagerNode);		commandManager.installCommandHandler(HandlerPriority.NORMAL);		commandManager.registerCommands(new LvdmCommands());		commandManager.registerCommands(new TestCommands());		commandManager.registerCommands(new AdminCommands()); 		// Example: register /test [command] ...		CommandGroup testGroup = new CommandGroup();		testGroup.registerCommands(new TestCommands());		commandManager.registerChildGroup(testGroup, "test");		// Example: register /admin [command] ...		CommandGroup adminCommands = new CommandGroup(); 		adminCommands.registerCommands(new AdminCommands()); 		commandManager.registerChildGroup(adminCommands, "admin");		commandManager.setUsageMessageSupplier((player, command, prefix, params, help) -> {             String message = prefix + command;             for (String param : params) {                 message += " [" + param + "]";             }             return message;         }); 	//--		eventManagerNode.registerHandler(PlayerUpdateEvent.class, (e) ->		{			Player player = e.getPlayer(); 			// getUpdateCount() Example			if (player.getUpdateCount() % 100 == 0)			{				player.setScore(player.getMoney());			}			if(suicid) {				Shoebill.get().runOnSampThread(() -> {					LvdmGamemode.queue.addPoints(player, "SELBSTMORD", -100, DynamicActionLabel.DynamicItem.TYPE_BIG);				});				suicid = false;			}			if(killed) {				Shoebill.get().runOnSampThread(() -> {					LvdmGamemode.functions.showKiller(player, lastKiller[player.getId()]);				});				killed = false;			}		});		eventManagerNode.registerHandler(PlayerWeaponShotEvent.class, (e) ->		{		//	e.getPlayer().sendMessage(Color.LIGHTBLUE, String.format("WeaponShot: hittype: %1$s, weapon: %2$s, pos: %3$s", e.getHitType(), e.getWeapon(), e.getPosition()));		});		eventManagerNode.registerHandler(PlayerConnectEvent.class, (e) ->		{			Player player = e.getPlayer();			player.sendGameText(5000, 5, "~w~SA-MP: ~r~Las Venturas ~g~MoneyGrub");			Player.sendMessageToAll(Color.GREEN,player.getName()+" Connected!");			player.sendMessage(Color.PURPLE, "Welcome to Las Venturas MoneyGrub, For help type /help.");			Player.sendDeathMessageToAll(player, null, WeaponModel.CONNECT);			Color color = new Color();			do color.setValue(random.nextInt()); while (color.getY() < 128);			player.setColor(color);		});		eventManagerNode.registerHandler(PlayerDisconnectEvent.class, (e) ->		{			Player player = e.getPlayer();			Player.sendMessageToAll(Color.RED,player.getName()+" Disconnected!");			Player.sendDeathMessageToAll(player, null, WeaponModel.DISCONNECT);		});		eventManagerNode.registerHandler(PlayerSpawnEvent.class, (e) ->		{				Player player = e.getPlayer();			player.giveMoney(INITIAL_MONEY);			player.toggleClock(true);			setRandomSpawnPos(player);			if(suicid) {				Shoebill.get().runOnSampThread(() -> {					LvdmGamemode.queue.addPoints(player, "SELBSTMORD", -100, DynamicActionLabel.DynamicItem.TYPE_BIG);				});				suicid = false;			}			if(killed) {				Shoebill.get().runOnSampThread(() -> {					LvdmGamemode.functions.showKiller(player, lastKiller[player.getId()]);				});				killed = false;			}		});		eventManagerNode.registerHandler(PlayerDeathEvent.class, (e) ->		{			Player player = e.getPlayer();			Player killer = e.getKiller();			player.setMoney(0);						Player.sendDeathMessageToAll(killer, player, e.getReason());			if (killer != null) {				killer.giveMoney(player.getMoney());			}			if(killer != null && killer.getName() != player.getName()) {				LvdmGamemode.queue.addPoints(killer, "GEGNER ELIMINIERT", 100, DynamicActionLabel.DynamicItem.TYPE_BIG);				if(LvdmGamemode.MessageOnRespawnAfterDead) {					killed = true;					lastKiller[player.getId()] = killer;				} else {					LvdmGamemode.functions.showKiller(player, killer);				}			} 			else if(killer == null && player != null || killer.getName() == player.getName()) {				if(LvdmGamemode.MessageOnRespawnAfterDead) {					suicid = true;				} else {					LvdmGamemode.queue.addPoints(player, "SELBSTMORD", -100, DynamicActionLabel.DynamicItem.TYPE_BIG);				}			}		});		eventManagerNode.registerHandler(PlayerRequestClassEvent.class, (e) ->		{			Player player = e.getPlayer();			setupForClassSelection(player);		});		eventManagerNode.registerHandler(PlayerCommandEvent.class, HandlerPriority.BOTTOM, (e) ->		{			Player player = e.getPlayer();			player.sendMessage(Color.RED, "Unknown command. Type /help to see help.");			e.setProcessed();		});	}	public void uninitialize()	{		commandManager.destroy();		eventManagerNode.destroy();	}	private void setRandomSpawnPos(Player player)	{		int rand = random.nextInt(RANDOM_SPAWNS.length);		player.setLocation(RANDOM_SPAWNS[rand]);		player.setInterior(0);	}	private void setupForClassSelection(Player player)	{		player.setInterior(14);		player.setLocation(258.4893f, -41.4008f, 1002.0234f);		player.setAngle(270.0f);		player.setCameraPosition(256.0815f, -43.0475f, 1004.0234f);		player.setCameraLookAt(258.4893f, -41.4008f, 1002.0234f);	}}


    Thx und danke für die Hilfe :thumbup:
    Musst dir das mit den Instanzen merken, für nen Tutorial oder so, war gut erklärt und würde bst noch anderen helfen, falls sie es nicht wussten wie ich ^^
    (Ich nutze normalerweise sehr viele Variablen :/)


    ------------------------
    >>edit:


    Habe es nun im EventHandler/Manager über folgendes gelöst:

    Code
    PlayerLifecycleHolder playerLifecycleHolder = new PlayerLifecycleHolder(rootEventManager.createChildNode()); 
    		playerLifecycleHolder.registerClass(Lifecycle.class, (lifecycle, p) -> new Lifecycle(lifecycle, p));


    Das doofe ist nur immer ein neuen Lifecycle.getObjects in jedem Event zu erstellen... Kann man nicht statt dessen ein globalen Array erstellen mit MAX_PLAYERS, welcher dann beim PlayerConnectEvent bzw PlayerRequestClassEvent auf die playerid abgestimmt wird und so dann immer wieder aufrufbar ist, ohne neu zu definieren? :D


    Bsp.:


    Kann man das auch anders aber einfacher als meine Methode machen oder ist deine wirklich die beste in dem Fall?
    Immer getObject in jeder Methode ist auch nicht soo toll, aber wäre auch nicht schlimm, hilft ja sehr :D
    Nur ich finde es bei meiner Methode nervig, dass man nach jeder Abfrage dann immer ''playerLifecycle[e.getPlayer().getId()]."... schreiben muss :D


    Und wäre meine nicht sicherer? Könnte ja sein, dass sich die playerLifecycle überschreiben, wenn zB 2 gleichzeitig sterben (Explosion) ?

    Stimmt hast recht :D
    Nur ich kam selbst nicht auf die Lösung da es ne ne public function sein soll und das alles im DeathEvent Handler abläuft, und da man nach dem Tod neu spawnt und ich die Nachricht anzeigen wollte, von wem man getötet wurde, wollte ich den letzten Killer speichern um es auch in anderen Funktionen nutzen zu können. Aber stimmt, man könnte über 'extends' den Killer der Klasse bekommen... hatte wohl die falsche Realisierungsrichtung eingeschlagen ^^


    Thx für die Hilfe, Problem gelöst :D