Register for your free account! | Forgot your password?

Go Back   elitepvpers > Other Online Games > Diablo 2 > Diablo 2 Programming
You last visited: Today at 08:24

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



[D2NT] Verbesserung fuer den .nip-Parser (einschl. Code}

Discussion on [D2NT] Verbesserung fuer den .nip-Parser (einschl. Code} within the Diablo 2 Programming forum part of the Diablo 2 category.

Reply
 
Old   #1
 
elite*gold: 0
Join Date: Jan 2012
Posts: 18
Received Thanks: 10
[D2NT] Verbesserung fuer den .nip-Parser (einschl. Code}

Die Zeilenlaenge der Itemdefinitionen bei komplexeren Itembeschreibungen in den .nip-Dateien ist leider zu lang, um sie vernuenftig handhaben zu koennen.

Eine Definition kann dann leicht so unuebersichtlich aussehen:
Code:
[Type] == jewel && [Quality] == magic # ([IAS] >= 15 || [ItemReqPercent] <= -15 || [FHR] >= 7 || [Strength] >= 9 || [Dexterity] >= 9) && ([EnhancedDamage] >= 40 || [MaxDamage] >= 15 || [ToHit] >= 80 || [FireResist] >= 12 && [LightResist] >= 12 || [FireResist] >= 20 || [LightResist] >= 30 || [ColdResist] >= 30 || [PoisonResist] >= 30)
Wieviel schoener waere es, wenn man wie in C/C++ einfach ein '\' als letztes Zeichen der Zeile setzen kann, um das uebersichtlicher zu gestalten, indem so mehrere Zeilen zu einer einzelnen zusammengefasst werden koennen.

Dieselbe Definition wie oben, auf diese Weise lesbarer gestaltet:
Code:
[Type] == jewel && [Quality] == magic # \
           ([IAS] >= 15 || [ItemReqPercent] <= -15 || \
           [FHR] >= 7 || [Strength] >= 9 || [Dexterity] >= 9) && \
           ([EnhancedDamage] >= 40 || [MaxDamage] >= 15 || [ToHit] >= 80 || \
           [FireResist] >= 12 && [LightResist] >= 12 || \
           [FireResist] >= 20 || [LightResist] >= 30 || \
           [ColdResist] >= 30 || [PoisonResist] >= 30)
Diese Verbesserung erfordert nur eine geringfuegige Codeaenderung.
In der Datei ntitemparser.ntl muss dieser Abschnitt
Code:
function NTIP_OpenFile(filepath)
{
	var _nipfile;
	var _line;
	var _filename, _lineCount, _buffer;
	
	_lineCount = 0;
	_nipfile = FileOpen(filepath, 0);
	_filename = filepath.split("/")[filepath.split("/").length - 1];

	if(!_nipfile)
		return false;

	while(!_nipfile.eof)
	{
		_lineCount++;
		_buffer = _nipfile.ReadLine();
		
		try
ersetzt werden durch
Code:
function NTIP_OpenFile(filepath)
{
	var _nipfile;
	var _line;
	var _filename, _lineCount, _buffer, _tmpbuf;
	
	_lineCount = 0;
	_nipfile = FileOpen(filepath, 0);
	_filename = filepath.split("/")[filepath.split("/").length - 1];

	if(!_nipfile)
		return false;

	while(!_nipfile.eof)
	{
		for ( _tmpbuf = _buffer = "";; _lineCount++) {
			_tmpbuf = _nipfile.ReadLine();
			if (_nipfile.eof) break;
			if ( _tmpbuf.charAt( _tmpbuf.length - 1) == '\\') {
				_tmpbuf += _buffer.concat( _tmpbuf.slice( 0,-1));
			} else {
				_tmpbuf += _buffer.concat( _tmpbuf);
				break;
			}
            }
		
		try
[ Hinweis: Der obige Code funktioniert nicht so, wie er sollte. Warum, habe ich noch nicht richtig verstanden. Die C-Kommentare /* */ werden irgendwie auseinandergezogen zu / * * /, Whitespace wird eingefuegt, und damit kommen nur Syntaxfehler en masse. Siehe mein Nachtrag weiter unten im Posting fuer eine ueberarbeitete, funktionierende Fassung! ]

Meiner Meinung nach eine einfache, aber sinnvolle Verbesserung.
Wuerde mich freuen, wenn das in das naechste Update mit aufgenommen werden koennte.

Quote:
Originally Posted by TheCrazy11 View Post
Ansonsten sehe ich keinen Sinn hinter deinem Wunsch des Line-Wrappings, mir kommt vor, dass dadurch die Nips eher unübersichtlicher werden.
Ich glaube, ich sollte mal an einem praxisnaeheren Beispiel als dem oben genannten Eintrag in den voreingestellten .nip-Dateien zeigen, wozu ich diese Funktionalitaet brauche.

Mein Hauptinteresse gilt den Imba-Rares.

Leider sind diese erheblich schwieriger zu definieren als die anderen Itemklassen.
Die entsprechenden Beschreibungen sind also zwangslaeufig weitaus laenger.
Denn es muessen z.B. Levelbereiche und die interessierenden Prefixe/Suffixe beruecksichtigt werden.

Als Beispiel eine einzige (noch unfertige) Definition aus meiner sich gerade in Arbeit befindlichen magic_rare.nip:
Code:
[Type] == amulet && [Quality] == rare # [ItemLevelReq] <= 31 && \
	( \
		( \
			/* prefix */ \
			[FireResist] + [LightResist] + [ColdResist] + [PoisonResist] >= 40 \
		) || \
		( \
			( \
				/* prefix */ \
				[FireResist] + [LightResist] + [ColdResist] + [PoisonResist] >= 30 \
			) && \
			( \
				( \
					/* fuer caster chars */ \
					( \
						/* prefix */ \
						[MaxMana] >= 5 || \
						[ItemDamageToMana] >= 1 || \
						/* suffix */ \
						[FCR] >= 10 || \
						[Strength] >= 5 || [Dexterity] >= 5 || \
						[MaxHP] >= 10 || [Energy] >= 5 || \
						[normaldamagereduction] >= 2 || [magicdamagereduction] >= 2 || \
						[ItemPoisonLengthResist] >= 75 || \
						/* prefix + suffix */ \
						[ItemMagicBonus] >= 20 \
					) && \
					( \
						/* prefix */ \
						[fireskilltab] + [coldskilltab] + [lightningskilltab] + \
						[poisonandboneskilltab] + [necromancersummoningskilltab] + \
						[palicombatskilltab] + [trapsskilltab] >= 2 || \
						[sorceressskills] + [necromancerskills] + \
						[paladinskills] + [druidskills] + [assassinskills] >= 1 \
					) \
				) || \
				( \
					/* fuer physical damage chars */ \
					( \
						/* prefix */ \
						[ItemDamageToMana] >= 1 || \
						/* suffix */ \
						[ManaLeech] >= 3 || [LifeLeech] >= 3 || \
						[Strength] >= 5 || [Dexterity] >= 5 || \
						[MaxHP] >= 10 ||  \
						[normaldamagereduction] >= 2 || [magicdamagereduction] >= 2 || \
						[ItemPoisonLengthResist] >= 75 || \
						/* prefix + suffix */ \
						[ItemMagicBonus] >= 20 \
					) && \
					( \
						/* prefix */ \
						[palicombatskilltab] + [barbcombatskilltab] + \
						[bowandcrossbowskilltab] + [javelinandspearskilltab] + \
						[shapeshiftingskilltab] + [martialartsskilltab] >= 2 || \
						[barbarianskills] + [amazonskills] + \
						[paladinskills] + [druidskills] + [assassinskills] >= 1 \
					) \
				) \
			) \
		) \
	)
Ein solch komplexer Ausdruck in einer einzigen Textzeile zusammengefasst waere definitiv unverstaendlich und unmanagbar.

Vielleicht erschliesst sich aus diesem Beispiel der Sinn und Nutzen meines Verbesserungsvorschlags etwas besser.



Nachtrag:

Habe nun die ganze Funktion NTIP_OpenFile() ueberarbeitet.

Habe toten Code entfernt, wie das try/catch ohne entsprechendes throw.

Weiterhin das Einlesen soweit anders implementiert, dass die ganze Datei zeilenweise zunaechst in einen Buffer eingelesen wird, wobei mit End-Backslash verbundene Zeilen gleich konkatenniert werden.

Nach dem Einlesen werden dann alle Kommentare sowie der Whitespace gestrippt, damit die Fehlersuche so weit wie moeglich erleichtert ist.
Denn bei Zeilenlaengen von teils ueber tausend Zeichen (ohne Kommentare und Whitespaces!) ist sonst die Fehlersuche sehr erschwert, wenn man in NipErrors.txt nachsehen muss.

Desweiteren ist da jetzt noch ein DEBUG_PRINT flag drin, das man nutzen kann, wenn man den Verdacht hat, dass beim Einlesen irgendwas bugt.

Hier die grundueberarbeitete Funktion NTIP_OpenFile(), die bei mir anstandslos funktioniert:

Code:
function NTIP_OpenFile(filepath)
{
	var _nipfile, _line, _filename, fileinf, s_file, s_line, s_rawline, 
			no_lines, no_rawlines, code_lines, successful, nl_offset, line_oldoffset;
	var DEBUG_PRINT = 0;			// auf nonzero setzen wenn man Extra-Info will

	_nipfile = FileOpen(filepath, 0);
	_filename = filepath.split("/")[filepath.split("/").length - 1];
	if (!_nipfile) return false;
		
	
	// Erster Abschnitt: File in einen String einlesen.
	// Jede Zeile mit \n abgetrennt.
	// Dabei die Zeilen mit \ als letztem Zeichen zu einzelnen Zeilen zusammenfassen.
	s_file = s_rawline = "";
	successful = no_lines = no_rawlines = 0;
	
	while(!_nipfile.eof) {
		s_rawline = "";
		for (;;) {
			s_rawline = _nipfile.ReadLine();
			if (_nipfile.eof && !s_rawline) break;
			++no_rawlines;
			// leere Zeilen auslassen
			if (s_rawline.length == 0) break;		
			if ( s_rawline.charAt( s_rawline.length - 1) == '\\') {   // statt length - 1 reicht -1 ?
				// diese Zeile mit der naechsten zusammenfassen
				s_file = s_file.concat( s_rawline.slice( 0, s_rawline.length - 1));  // negative werte gehen nicht??
			} else {
				s_file = s_file.concat( s_rawline + '\n');
				++no_lines;
				break;
			}
        }
	}
	
	// Jetzt die Kommentare entfernen.
	s_file = s_file.replace(/\/\*.+?\*\/|\/\/.*(?=[\n\r])/g, '');
	// Nachdem die Kommentare raus sind, nun auch noch den Whitespace entfernen.
	s_file = s_file.replace(/ /g,'');	// away with whitespaces
	s_file = s_file.replace(/\t/g,'');	// away with tabs
	s_file = s_file.replace(/\r/g,'');	// away with crs
	
	// Jetzt haben wir im String s_file alles, was interessiert, drin.
	// Nun arbeiten wir dies zeilenweise durch.

	fileinf = "/" + filepath.split("/")[filepath.split("/").length - 2] + "/" + _filename;

	// zweiter Parameter = file mode	1 = create, 2 = append
	if (DEBUG_PRINT != 0) {
		MWC_WriteToTextfile( "File: " + fileinf, "Logs/NipDebug.txt", 2);
	}

	code_lines = nl_offset = line_oldoffset = 0
	for ( lin = 1; lin <= no_lines; ++lin ) {
		// das naechste newline suchen
		nl_offset = s_file.indexOf( '\n', line_oldoffset = nl_offset);
		s_line = s_file.substring( line_oldoffset, nl_offset++);
		// pruefen, ob die Zeile (nach der Kommentarentfernung) leer ist
		if (s_line.length == 0) continue;
		if (s_line.match(/^\s[ \t]*$/)) continue;
		++code_lines;
		// nun das dem eigentlichen Parser uebergeben
		_line = NTIP_ParseLineInt( s_line );
			if (DEBUG_PRINT != 0) {
				MWC_WriteToTextfile( code_lines + " (" + s_line.length + ") : " + s_line, "Logs/NipDebug.txt", 2);
			}
		if (_line == -1) {
			Print( "In " + _filename + " ist etwas Boeses nahe Zeile: " + s_line );
		} else {
			_line.push( fileinf);
			_line.push( lin);
			_line.push( s_line);
			_NTIP_CheckList.push(_line);
			++successful;
		}
	}

	// Fertig!
	_nipfile.Close();
	
	if (DEBUG_PRINT != 0)
		Print("ÿc8NTIP_OpenFile( " + _filename + " ) ÿc0processed " + no_rawlines + " text lines, " +
				code_lines + " code lines, " + successful + " with success."); 
	return true;
}
Ich persoenlich bin sehr froh, dass es so leicht war, diese Modifikation einzubauen.
Denn ein grosser Teil meiner Pickup-Definitionszeilen ist bereits ohne Leerzeichen und Kommentare mehrere hundert Zeichen lang.

Ohne diese Modifikation waere es fuer mich viel aufwendiger und muehseliger gewesen, meine NIP-Konfig zusammenzustellen.
worthless1337 is offline  
Thanks
5 Users
Reply


Similar Threads Similar Threads
[B]Assassin´s Creed Brotherhood Bonus-Code fuer Xbox[S] 65 e*gold
12/23/2011 - elite*gold Trading - 0 Replies
Hallo ich verkaufe heute den Assasin's Creed Brotherhood Bonus-Code Er enthaelt: 2 neue Einzelspielermissionen Die Aquaedukte und Tranjansforum 2 neue Mehrspielcharakter Der Harlekin und der Offesier
[C++] Code verbesserung gesucht.
06/16/2011 - C/C++ - 9 Replies
Hey, habe mit C++ eine Windowsforms Anwendung gemacht. Und wollte mal mit "then" einen Test machen. So mein Code: if checkBox1->Checked->true then MessageBox::Show("Test")
[Verbesserung nötig] D2nt Bluebird Leech/baal
07/26/2010 - Diablo 2 - 1 Replies
Mir ist aufgefallen das man am BaalLeechFight wa ändern könnte und auch alllgemein am baalscript. zum baalleechfightscript man könnte er ändern... das der (follow)bot in das tp des leaders geht und nicht selber zum throne telt. (aber wie habe ka) baalscript man könnte es so einrichten dass der bot erst tp mach dann anfängt zu safen und wenn des abgeschlossen ist könnte man doch des dämliche drumrumgetele vor der ersten wave auch weglassen?
D2NT verbesserung vom PindleskinWP
05/01/2010 - Diablo 2 - 5 Replies
hallo, falls es jemanden interessiert - pindleskin direkt via wp killen ist super aber mich hat gestört, das der char direkt nachdem er die treppe hoch geht stehen bleibt und sich tot kloppen lässt :mofo: bzw. viele chicken verursacht oder massenhaft reg. pots braucht. so wie ich ihn leicht modifiziert habe teleportiert er sich vor die pindlebande, als würde er durch das rote portal gehen. einfach den code in die NTPindleskin.ntj kopieren.
GM-Befehle: Code fuer Status?
04/16/2010 - Metin2 Private Server - 79 Replies
guten morgen :> hätte mal eine frage, nämlich: wie lautet der gm befehl um den status (vit, int, str, dex) zu verändern? hab in folgenden vid gesehen, das der seinen status verändert hat (sieht man sehr gut bei 0:40) YouTube - Clubmt2, Longju2 Private Server der hat 10005 vit, 9999 int, 10011 str und 9999 dex. der macht an einem 90er metin ohne gaul 20k dmg :handsdown:. wenn ich mal wieder auf einem gm server spielen darf, (schickt mir keine pn deswegen, ich spiele nicht auf einem...



All times are GMT +1. The time now is 08:27.


Powered by vBulletin®
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2026 elitepvpers All Rights Reserved.