[Release] Client-Interface {"illumina"}

03/18/2016 07:55 ProfessorEnte#151
Einfach ein uebermenschliches Design, Danke!
03/18/2016 10:31 Mr. 'Avenue™#152
Hab vorhin im Source noch was gefunden, um die Questscrolls im CharacterWindow bei der QuestPage zu ändern:

UserInterface/PythonQuest.cpp
Code:
PyObject * questGetQuestData(PyObject * poSelf, PyObject * poArgs)
{
	int iIndex;
	if (!PyTuple_GetInteger(poArgs, 0, &iIndex))
		return Py_BadArgument();

	CPythonQuest::SQuestInstance * pQuestInstance;
	if (!CPythonQuest::Instance().GetQuestInstancePtr(iIndex, &pQuestInstance))
		return Py_BuildException("Failed to find quest by index %d", iIndex);

	CGraphicImage * pImage = NULL;
	if (!pQuestInstance->strIconFileName.empty())
	{
		std::string strIconFileName;
		strIconFileName = "d:/ymir work/ui/game/quest/questicon/";
		strIconFileName += pQuestInstance->strIconFileName.c_str();
		pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(strIconFileName.c_str());
	}
	else
	{
		{
			// Illumina Questicon
			std::string strIconFileName = "illumina/images/icons/special/quest_open.tga";
			pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(strIconFileName.c_str());
		}
	}

	return Py_BuildValue("sisi",	pQuestInstance->strTitle.c_str(),
									pImage,
									pQuestInstance->strCounterName.c_str(),
									pQuestInstance->iCounterValue);
}
03/18/2016 16:57 xCPx#153
Quote:
Originally Posted by Mr. 'Avenue™ View Post
Hab vorhin im Source noch was gefunden, um die Questscrolls im CharacterWindow bei der QuestPage zu ändern:

UserInterface/PythonQuest.cpp
Code:
PyObject * questGetQuestData(PyObject * poSelf, PyObject * poArgs)
{
	int iIndex;
	if (!PyTuple_GetInteger(poArgs, 0, &iIndex))
		return Py_BadArgument();

	CPythonQuest::SQuestInstance * pQuestInstance;
	if (!CPythonQuest::Instance().GetQuestInstancePtr(iIndex, &pQuestInstance))
		return Py_BuildException("Failed to find quest by index %d", iIndex);

	CGraphicImage * pImage = NULL;
	if (!pQuestInstance->strIconFileName.empty())
	{
		std::string strIconFileName;
		strIconFileName = "d:/ymir work/ui/game/quest/questicon/";
		strIconFileName += pQuestInstance->strIconFileName.c_str();
		pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(strIconFileName.c_str());
	}
	else
	{
		{
			// Illumina Questicon
			std::string strIconFileName = "illumina/images/icons/special/quest_open.tga";
			pImage = (CGraphicImage *)CResourceManager::Instance().GetResourcePointer(strIconFileName.c_str());
		}
	}

	return Py_BuildValue("sisi",	pQuestInstance->strTitle.c_str(),
									pImage,
									pQuestInstance->strCounterName.c_str(),
									pQuestInstance->iCounterValue);
}
Bist du dir sicher, dass der Part überhaupt mal irgendwo genutzt wird?

ich hab keine Datei gefunden wo der Befehl überhaupt verwendet wird :o
03/18/2016 17:24 King Sora#154
Quote:
Originally Posted by Lord Metho View Post
@[Only registered and activated users can see links. Click Here To Register...], leider gibts keine solche leichte Rotate etc. Möglichkeit, er müsste gebenenfalls ein Image mit (.rotate, .paste, .crop) Zuschneiden / Drehen / Zuschneiden / Zurückdrehen bearbeiten.

Verstehe aber ohnehin zuwenig C# um deine Methode genau nachvollziehen zu können
Ich weiß zu 100% dass es eine rotate Möglichkeit in Metin2 gibt.

Quote:
Originally Posted by xCPx View Post
In C# / C++ ist das kein Problem, das weis ich selbst zu gut.
Jedoch ist es in der bestehenden Metin2 Funktionalität bisher leider nicht bzw kaum ohne grössere Performance Verluste möglich (Es sei denn der Code soll auch n C++ Part fürn Source beinhalten, dann ist das wiederum recht einfach)


Glaub mir freiwillig mach ichs auch nicht mit Bildern ^^
Der Code lässt sich von der Logik her auch problemlos in Python umsetzen. Als Poccix sich noch am Code versucht hat, war es ja auch möglich.

Vielleicht kennst du nur die rotate Methode nicht, wie schon erwähnt wird diese standardmäßig sowieso irgendwo verwendet und ist auch ohne source Änderungen zugänglich.

#Edit:
Die Methode sollte "SetRotation(value)" heißen, und zmindest (evt. auch weitere Objekte) "ExpandedImage" Objekte sollten diese Methode haben. Leider weiß ich nicht mehr was diese Methode für einen Wert erwartet, also ob es ein Radian, Degree oder Prozentwert ist etc. müsstenst du ausprobieren.

Lg.
03/18/2016 17:39 Mr. 'Avenue™#155
Quote:
Originally Posted by King Sora View Post
Ich weiß zu 100% dass es eine rotate Möglichkeit in Metin2 gibt.



Der Code lässt sich von der Logik her auch problemlos in Python umsetzen. Als Poccix sich noch am Code versucht hat, war es ja auch möglich.

Vielleicht kennst du nur die rotate Methode nicht, wie schon erwähnt wird diese standardmäßig sowieso irgendwo verwendet und ist auch ohne source Änderungen zugänglich.

#Edit:
Die Methode sollte "SetRotation(value)" heißen, und zmindest (evt. auch weitere Objekte) "ExpandedImage" Objekte sollten diese Methode haben. Leider weiß ich nicht mehr was diese Methode für einen Wert erwartet, also ob es ein Radian, Degree oder Prozentwert ist etc. müsstenst du ausprobieren.

Lg.
Erwartet soweit ich weiß float als Wert.

Code:
PyObject * wndImageSetRotation(PyObject * poSelf, PyObject * poArgs)
{
	UI::CWindow * pWindow;
	if (!PyTuple_GetWindow(poArgs, 0, &pWindow))
		return Py_BuildException();
	float fRotation;
	if (!PyTuple_GetFloat(poArgs, 1, &fRotation))
		return Py_BuildException();

	((UI::CExpandedImageBox*)pWindow)->SetRotation(fRotation);

	return Py_BuildNone();
}




Quote:
Originally Posted by xCPx View Post
Bist du dir sicher, dass der Part überhaupt mal irgendwo genutzt wird?

ich hab keine Datei gefunden wo der Befehl überhaupt verwendet wird :o
Ja. uiCharacter.py
Code:
def RefreshQuest(self):
	[...]
	for i in questRange[:questCount]:
		(questName, questIcon, questCounterName, questCounterValue) = quest.GetQuestData(self.questShowingStartIndex+i)
03/18/2016 17:47 #Metho#156
@[Only registered and activated users can see links. Click Here To Register...],

ich habe es unverständlich formuliert, was du sagst ist mir ebenfalls bewusst, jedoch reicht es nicht das Bild zu rotieren. (Ich gehe dabei immer von einem kompletten Bild aus und keinen 6 Einzelteilen.) Ich konnte deine Überlegung mit 6/5 Einzelteilen nicht nachvollziehen, da mir dazu die nötigen C# Kenntnisse fehlen. Meine Überlegung war es, dass man das Bild so ausschneiden müsste, dass das ganze einem Kuchen ähnelt (radial). Man nehme also den Prozentsatz des aktuellen Lebens/maximalen Lebens und schneidet ein Kuchenstück vom Bild ab. Nun könnte man auch sagen, es reicht, wenn man das Bild rotiert, somit würde sich der obere Teil der Anzeige immer mit Drehen. Dies ist aber ganz allein deine Entscheidung, wie du dir das vorgestellt hast, ich hoffe ich konnte die Sachlage etwas erklären.

Anscheinend hat xCPx, im Gegensatz zu mir, deine C# Überlegungsweise nachvollziehen können und ist immernoch der festen Meinung es ginge nicht perfomance effizient, da fehlen mir leider die Kenntnisse von C#.

Würde sich Poccix mit der Lösung präsentieren, wäre dies sicherlich von Vorteil, hoffen wir darauf er den Ausschnitt aus seinem Py noch findet :P
03/18/2016 18:03 xCPx#157
Nicht machbar habe ich so nie gesagt, sondern lediglich sehr Performancelastig.

Habe dafür sogar ne Klasse, nur wie gesagt sehr performancelastig....
Schaut aber nicht schlecht aus.


Code:
class LoadingCircle(Window):
	def __init__(self, clockwise = True):
		Window.__init__(self)
		self.FullImage = None
		self.EmptyImage = ExpandedImageBox()
		self.EmptyImage.AddFlag("not_pick")
		self.EmptyImage.SetParent(self)
		self.StartRotation = 0
		self.MaxAngle = 360
		self.clockwise = clockwise
		self.Show()
	def __del__(self):
		self.Hide()
		Window.__del__(self)
	def AddFullImage(self, img,width):
		self.FullImage	= []
		for i in xrange(0,360):
			part = ExpandedImageBox()
			part.AddFlag("not_pick")
			part.LoadImage(img)
			part.SetSize(width, 1)
			part.SetParent(self)
			part.SetPosition(0, width/2)
			part.Show()
			part.SetRotation(self.StartRotation + i)
			self.FullImage.append(part)	
			pass
	def AddEmptyImage(self, img, width, height):		
		self.EmptyImage.LoadImage(img)
		self.EmptyImage.SetSize(width, height)		
		self.EmptyImage.Show()
	def SetStartRotation(self, rotation):
		self.StartRotation = rotation
	def SetMaxAngle(self, angle):
		self.MaxAngle = angle
	def SetValue(self, actual, _max):
		perc =  minmax(0.0,float(actual) / float(_max), 1.0) * 100.0
		intPerc = FloatRountToInt(0.0, perc * float(self.MaxAngle)/100.0, float(self.MaxAngle)	)
		for i in xrange(0, 360):
			i2 = i
			if(self.clockwise == False):
				i2 = self.MaxAngle-1-i
			if(i <= intPerc):
				self.FullImage[i2].Show()
			else:
				self.FullImage[i2].Hide()

hab meine basic functions vergessen...
Code:
def minmax(_min,act,_max):
	return max(_min, min(act, _max))
def FloatRountToInt(_min, r, _max):
	r2 = int(r)
	if( int(r*2.0) >= (r2*2)+1):
		r2 = r2+1
	_min = int(_min)
	_max = int(_max)
	return int(minmax(_min, r2, _max))
03/18/2016 18:44 King Sora#158
Quote:
Originally Posted by Lord Metho View Post
@[Only registered and activated users can see links. Click Here To Register...],

ich habe es unverständlich formuliert, was du sagst ist mir ebenfalls bewusst, jedoch reicht es nicht das Bild zu rotieren. (Ich gehe dabei immer von einem kompletten Bild aus und keinen 6 Einzelteilen.) Ich konnte deine Überlegung mit 6/5 Einzelteilen nicht nachvollziehen, da mir dazu die nötigen C# Kenntnisse fehlen. Meine Überlegung war es, dass man das Bild so ausschneiden müsste, dass das ganze einem Kuchen ähnelt (radial). Man nehme also den Prozentsatz des aktuellen Lebens/maximalen Lebens und schneidet ein Kuchenstück vom Bild ab. Nun könnte man auch sagen, es reicht, wenn man das Bild rotiert, somit würde sich der obere Teil der Anzeige immer mit Drehen. Dies ist aber ganz allein deine Entscheidung, wie du dir das vorgestellt hast, ich hoffe ich konnte die Sachlage etwas erklären.

Anscheinend hat xCPx, im Gegensatz zu mir, deine C# Überlegungsweise nachvollziehen können und ist immernoch der festen Meinung es ginge nicht perfomance effizient, da fehlen mir leider die Kenntnisse von C#.

Würde sich Poccix mit der Lösung präsentieren, wäre dies sicherlich von Vorteil, hoffen wir darauf er den Ausschnitt aus seinem Py noch findet :P
Naja, man sollte sich zumindest die slices ansehen, damit meine Überlegung nachvollziehen kann.
Da muss man nicht unbedingt C# dazu können, weil man das Programm ja auch ausführen kann.


Quote:
Originally Posted by xCPx View Post
Nicht machbar habe ich so nie gesagt, sondern lediglich sehr Performancelastig.

Habe dafür sogar ne Klasse, nur wie gesagt sehr performancelastig....
Schaut aber nicht schlecht aus.
Hast du denn auch eine Begründung warum es sehr performance lastig sein soll? - Meiner Meinung nach ist das ein relativ effizienter Weg das mit wenig Code und wenig Bildern hin zu bekommen. DirectX ist nicht gerade schlecht, was die Verwaltung und Manipulation von Texturen (Bildern) angeht.

Lg.
03/18/2016 18:52 xCPx#159
Quote:
Originally Posted by King Sora View Post
Naja, man sollte sich zumindest die slices ansehen, damit meine Überlegung nachvollziehen kann.
Da muss man nicht unbedingt C# dazu können, weil man das Programm ja auch ausführen kann.




Hast du denn auch eine Begründung warum es sehr performance lastig sein soll? - Meiner Meinung nach ist das ein relativ effizienter Weg das mit wenig Code und wenig Bildern hin zu bekommen. DirectX ist nicht gerade schlecht, was die Verwaltung und Manipulation von Texturen (Bildern) angeht.

Lg.
Es gibt nen Unterschied zwischen Direct X und Direct X via py.
Wenn was unter C++ über direct x ohne Probleme läuft ( < 1s) heist es noch lange nicht dass das im Clienten so ist, dort genehmigt sich dieselbe Aktion teils > 10s

Aber ja, solange man nicht 1000 davon verwendet sollte es keine Probleme geben, so wie ich es oben gemacht hab.
Nur denk ich immer ein wenig an die performance ^^
03/18/2016 19:06 King Sora#160
Quote:
Originally Posted by xCPx View Post
Es gibt nen Unterschied zwischen Direct X und Direct X via py.
Wenn was unter C++ über direct x ohne Probleme läuft ( < 1s) heist es noch lange nicht dass das im Clienten so ist, dort genehmigt sich dieselbe Aktion teils > 10s

Aber ja, solange man nicht 1000 davon verwendet sollte es keine Probleme geben, so wie ich es oben gemacht hab.
Nur denk ich immer ein wenig an die performance ^^
Nach dieser Logik müsste ja das Gleiche für alle anderen Funktionen gelten, egal ob Rotationen oder das Zeichnen anderer Bilder. xD

Ist ja auch egal, wenn es dir möglich ist, bitte versuchs so zu machen wie es ursprünglich geplant war. Das Schohnt auf jeden Fall die Größe des Clients / des Designs.

Lg.
03/18/2016 19:30 xCPx#161
Quote:
Originally Posted by King Sora View Post
Nach dieser Logik müsste ja das Gleiche für alle anderen Funktionen gelten, egal ob Rotationen oder das Zeichnen anderer Bilder. xD

Ist ja auch egal, wenn es dir möglich ist, bitte versuchs so zu machen wie es ursprünglich geplant war. Das Schohnt auf jeden Fall die Größe des Clients / des Designs.

Lg.
Aktuell hab ich ne Version, wofür ich leider deine Gauges zerschneiden musste :/

ich nehm die Gauges auf 1px höhe und bastel mir daraus den ganzen kreis. schaut nichtmal schlecht aus :o
Und spart zudem 60kb :D

[Only registered and activated users can see links. Click Here To Register...]

Verwendete Bilder für die Hp/Mp Anzeige im Anhang, kannst sie ja anpassen wenn du willst.

Code Dazu:


Functions:
Code:
def minmax(_min,act,_max):
	return max(_min, min(act, _max))
def FloatRountToInt(_min, r, _max):
	r2 = int(r)
	if( int(r*2.0) >= (r2*2)+1):
		r2 = r2+1
	_min = int(_min)
	_max = int(_max)
	return int(minmax(_min, r2, _max))
LoadingCircle:
Code:
class LoadingCircle(Window):
	def __init__(self, clockwise = True):
		Window.__init__(self)
		self.FullImage = None
		self.EmptyImage = ExpandedImageBox()
		self.EmptyImage.AddFlag("not_pick")
		self.EmptyImage.SetParent(self)
		self.StartRotation = 0
		self.MaxAngle = 360
		self.clockwise = clockwise
		self.curPct = 0
		self.Show()
	def __del__(self):
		self.Hide()
		Window.__del__(self)
	def AddFullImage(self, img,width):
		self.FullImage	= []
		for i in xrange(0,360):
			part = ExpandedImageBox()
			part.AddFlag("not_pick")
			part.LoadImage(img)
			part.SetSize(width, 1)
			part.SetParent(self)
			part.SetPosition(0, width/2)
			part.Show()
			part.SetRotation(self.StartRotation + i)
			self.FullImage.append(part)	
			pass
	def AddEmptyImage(self, img, width, height):		
		self.EmptyImage.LoadImage(img)
		self.EmptyImage.SetSize(width, height)		
		self.EmptyImage.Show()
	def SetStartRotation(self, rotation):
		self.StartRotation = rotation
	def SetMaxAngle(self, angle):
		self.MaxAngle = angle
	def SetValue(self, actual, _max):
		perc =  minmax(0.0,float(actual) / float(_max), 1.0) * 100.0
		intPerc = FloatRountToInt(0.0, perc * float(self.MaxAngle)/100.0, float(self.MaxAngle)	)
		if(intPerc == self.curPct):
			return
		self.curPct = intPerc
		for i in xrange(0, 360):
			i2 = i
			if(self.clockwise == False):
				i2 = self.MaxAngle-1-i
			if(i <= intPerc):
				self.FullImage[i2].Show()
			else:
				self.FullImage[i2].Hide()
HpMPBar:
Code:
	class HpMPBar(Window):
		def __init__(self, parent):
			Window.__init__(self)
			self.SetParent(parent)
			self.SetPosition(137, 42)
			mp = LoadingCircle(False)
			mp.SetParent(self)
			mp.SetStartRotation(0)
			mp.SetMaxAngle(90)
			mp.AddEmptyImage("illumina/controls/special/taskbar/gauge_mp/gauge_mp_empty.tga",104, 104)
			mp.AddFullImage("illumina/controls/special/taskbar/gauge_mp/gauge_mp_fill_0.tga", 104)
			self.mp = mp
			hp = LoadingCircle()
			hp.SetParent(self)
			hp.SetStartRotation(91)
			hp.SetMaxAngle(270)
			hp.AddEmptyImage("illumina/controls/special/taskbar/gauge_hp/gauge_hp_empty.tga",104, 104)
			hp.AddFullImage("illumina/controls/special/taskbar/gauge_hp/gauge_hp_fill_00.tga", 104)
			self.hp = hp

			self.Show()
		def OnUpdate(self):
			import player
			curHP = player.GetStatus(player.HP)
			maxHP = player.GetStatus(player.MAX_HP)
			curSP = player.GetStatus(player.SP)
			maxSP = player.GetStatus(player.MAX_SP)
			self.hp.SetValue(curHP, maxHP)
			self.mp.SetValue(curSP	, maxSP	)
		def __del__(self):
			self.Hide()
			Window.__del__(self)
03/18/2016 19:40 King Sora#162
Quote:
Originally Posted by xCPx View Post
Aktuell hab ich ne Version, wofür ich leider deine Gauges zerschneiden musste :/

ich nehm die Gauges auf 1px höhe und bastel mir daraus den ganzen kreis. schaut nichtmal schlecht aus :o
Und spart zudem 60kb :D

[Only registered and activated users can see links. Click Here To Register...]

Verwendete Bilder für die Hp/Mp Anzeige im Anhang, kannst sie ja anpassen wenn du willst
Das ist zwar keine schlechte Idee, sieht aber meiner Meinung nach nicht gut aus. Es ist bleibt zwar deine Entscheidung wie du es machst, aber ich bin da aus dem Grund dass es so einfach viel schlechter aussieht, dagegen.

Da man auch nur so einen kleinen Spielraum hat, hat man auch kaum Möglichkeiten da etwas zu verbessern.
03/18/2016 20:57 Mr. 'Avenue™#163
paar Controls für die ui.py
Sind größtenteils aus Yivs Controls zusammengebastelt.







03/19/2016 00:18 Yiv#164
@[Only registered and activated users can see links. Click Here To Register...]:
Ich hoffe, Poccix hat nichts dagegen, habe gerade den alten DEV-Client gefunden, dort hat er folgendes gemacht, was einwandfrei funktionierte: [Only registered and activated users can see links. Click Here To Register...]

Kann man zwar besser machen, aber das war bisher sowieso noch kein optimierter Code, also sollte man ihm Unschönheiten nicht übel nehmen :D

MfG
03/19/2016 13:03 UltraShock#165
Hi Sora,
viel zusagen gibt es hier nicht, einfach Staunen und Danke sagen
die Krittiker können auch selber hier Staunen, so nochmal Danke dir
sehr und auch die anderen die dir dabei helfen dieses Interface zu
Realisieren.

Ich weiß man kann von dir nicht genug bekommen und man das nehmen soll
was du uns Zurverfügung stellst, aber dennoch habe ich eine Bitte vlt auch
jemand anders der gleich denkt und zwar, die Buttons 1x Leer speichern ohne
icons oder sonstiges drauf oder halt eine kleine PSD davon das man selber
ohne dich zu fragen nach wunsch buttons erstellt.