CraftScript für Muddy_Waters D2NT

07/01/2011 13:46 -Nemesis1337-#1
Nach einem Volltest des Scripts, welches mit/durch Muddy geschrieben wurde, kann ich mit Freude verkünden: Es ist betriebsbereit! :)

Funktionsweise:
Das Script für Muddys D2NT Version macht folgendes:
Es schaut im Umkreis um die Truhe nach Craftbaren Items, sofern welche rumliegen, wird geschaut was wie zusammenpasst.
Der Bot hebt die passenden Gegenstände für die Craftrezepte auf die ihr in den Globalsettings eingestellt habt und baut sie im Cube zusammen.
Danach prüft er die Eigenschaften der Ringe in der CraftNip, wie gehabt.

Crapcrafts kommen auf den Boden, der Rest in die Truhe.

Umfang des Tests:
Der Umfang meines Test sind 88x Jools/Rubys/Sols/Ringe gewesen. (Quasi 88 Bloodcraftpacks)
Keine Fehler oder sonstige Bugs.

Nichts desto trotz bitte ich euch, dieses Script auch mal zu testen und euer Feedback zu posten :)

Ich bin der Meinung das es einiges leichter macht, denn: Craftpacks bekommen is eine Sache, die Zeit fürs Craften zu haben eine Andere :P
Und wunde Finger wünsche ich keinem EPvper :)

Ein riesen Dank an Muddy, denn ohne Ihn wäre das Script für mich net realisierbar gewesen.
Ich bin kein großer JavaTexter, aber massig Ideen hab ich :)

Installation:
Macht euch am Besten einen Ordner "MWCraft" im Scripts Ordner :)
Dort kommt die MWCraftGame.ntj rein.
Die MWCraftEntry.ntj kommt in den Scriptsordner.
Die MWCraft.ntj File kommt in den NTBot/Bots Ordner :)

MWCraftEntry.ntj

MWCraftGame.ntj

MWCraft.ntj


Dann müsst ihr einfach nur im D2NT Manager MWCraftEntry.ntj anstatt NTBot.ntj auswählen und euch manuell in das Game einloggen wo ihr die Craftpacks gedroppt habt.
Voila! :)

Viel Spaß & Erfolg beim Craften(lassen)!
07/01/2011 14:47 Muddy Waters#2
NTTMGR_TownManager() würde ich nur einmal zur Initialisierung der Funktion aufrufen, NTTMGR_VisitStash(cubing) bietet sich tatsächlich eher an, wobei für den Parameter cubing einfach konstant true übergeben wird.

Das Aufheben ist etwas komplizierter, mit SnagIt kommst du da nicht weit, mit MWC_GetItems() schon gar nicht, denn die Funktion macht etwas völlig anderes. ;)
Ob ein Item benötigt wird oder nicht, lässt sich durch Aufruf von NTSI_CheckItem(item, checkQuantity) ermitteln. Wird das Item zum Cuben benötigt, liefert die Funktion den Wert 2 zurück.

Soweit so gut, doch musst du sämtliche Items am Boden vor dem eigentlichen Aufheben erstmal sinnvoll gruppieren, damit du volle Craft Sets priorisiert aufheben kannst. Ich hatte es ja schon vorher angedeutet, es kann sonst passieren, dass dein Char sein komplettes Inventar nur mit Gems oder Runen füllt, sodass du keinen Platz mehr hast, aber eben auch nicht craften kannst.

Das Botscript könnte dann in etwa so aussehen:
Code:
function NTMain()
{
	Include("libs/common/NTCommon.ntl");
	NTC_IncludeLibs();
	NTC_IncludeConfig("NTBot/char_configs");

	NT_LoadConfig();
	NTSI_LoadNIPFiles("NTBot/item_configs");

	MWC_Initialize();

	if(!NTTM_CheckAct(1, true))
	{
		NTC_SendMsgToScript("MWBotGame.ntj", NTTM_CheckAct, 18, me.act, true);
		return;
	}

	NTTMGR_TownManager();
	
	while(true)
	{
		NTCU_InitCubing();
		
		MWCR_PickIngredients();
		
		if(NTCU_CheckCubing())
			NTTMGR_VisitStash(true);
			
		NTC_Delay(1000);
	}
	
	NTC_SendMsgToScript("MWBotGame.ntj", "SCRIPT_END");
}
Wie oben schon erwähnt liegt die Schwierigkeit hier in der Implementierung der Funktion MWCR_PickIngredients(), ich werde mir dazu mal Gedanken machen und eventuell nachher mal einen Entwurf posten, du kannst dir ja selber auch mal eine Umsetzung ausdenken.
Wie man unschwer erkennt, hat die Endlosschleife derzeit keine Abbruchbedingung, hierzu sollte man eventuell den Game Thread erweitern und Key Events abfangen und das Script dann über den Pointer auf das dazugehörige Script Objekt stoppen. ;)

LG
Muddy
07/01/2011 15:19 -Nemesis1337-#3
Alles klar, ich mach mal nen Brainstorming und schreib mal was zusammen :)
07/01/2011 16:41 Muddy Waters#4
Hier mal ein Entwurf:
Code:
const _MWCR_PICKUP_RANGE = 15;

function NTMain()
{
	Include("libs/common/NTCommon.ntl");
	NTC_IncludeLibs();
	NTC_IncludeConfig("NTBot/char_configs");

	NT_LoadConfig();
	NTSI_LoadNIPFiles("NTBot/item_configs");

	MWC_Initialize();

	if(!NTTM_CheckAct(1, true))
	{
		NTC_SendMsgToScript("MWBotGame.ntj", NTTM_CheckAct, 18, me.act, true);
		return;
	}

	NTTMGR_TownManager();
	
	while(true)
	{
		NTCU_InitCubing();
		
		MWCR_PickIngredients();
		
		if(NTCU_CheckCubing())
			NTTMGR_VisitStash(true);
			
		NTC_Delay(1000);
	}
	
	NTC_SendMsgToScript("MWBotGame.ntj", "SCRIPT_END");
}

function MWCR_PickIngredients()
{
	var _item, _craftSets, _index;
	var i, j;
	
	_craftSets = new Array();
	
	_item = NTC_FindUnit(NTC_UNIT_ITEM);
	
	if(!_item)
		return;
		
	// _craftSets structure: [requiredIngredients[], runegid, gemgid, jewelgid, basegid]
	// requiredIngredients[] structure: [ilvl, runeclassid, gemclassid, jewelclassid, baseclassid]
	for(i = 0; i < NTConfig_CubingItem.length; i++)
	{
		_craftSets.push([_NTCU_CraftRecipe[NTConfig_CubingItem[i][0] - NTCU_CRAFT_HITPOWER_HELM], null, null, null]);
		_craftSets[_craftSets.length - 1][0].push(MWCU_JEWEL, NTConfig_CubingItem[i][1]);
	}
	
	do
	{
		if(GetDistance(me, _item) < _MWCR_PICKUP_RANGE && NTSI_CheckItem(_item) == 2)
		{
			for(i = 0; i < _craftSets.length; i++)
			{
				_index = _craftSets[i][0].indexOf(_item.classid); // Returns a valid array index if the item is required for the current recipe (1: rune; 2: perfect gem; 3: base item)
				
				if(_index > 0)
				{
					if(_craftSets[i][_index] == null)
					{
						_craftSets[i][_index] = _item.gid;
						break;
					}
				}
			}
		}
	} while(_item.GetNext());

	for(i = 0; i < _craftSets.length; i++)
	{
		for(j = 0; j < _craftSets[i].length; j++)
		{
			if(_craftSets[i][j] == null)
				break;
		}
		
		if(j >= _craftSets[i].length)
		{
			for(j = 1; j < _craftSets[i].length; j++)
				MWSI_PickupItem(_craftSets[i][j]);
		}
	}
}
Das ist nur ein relativ simpler und wenig intelligenter Ansatz, wobei nur soviele Sets aufgehoben werden, wie entsprechende Rezepte aktiviert sind. Ausserdem werden nur vollständige Sets aufgehoben.
Kannst es ja mal ausprobieren, ich habe es nicht getestet, sollte aber funktionieren, sofern ich mich nicht vertippt habe. :)

LG
Muddy
07/02/2011 12:02 -Nemesis1337-#5
Quote:
Originally Posted by Muddy_Waters View Post
Hier mal ein Entwurf:
Code:
const _MWCR_PICKUP_RANGE = 15;

function NTMain()
{
	Include("libs/common/NTCommon.ntl");
	NTC_IncludeLibs();
	NTC_IncludeConfig("NTBot/char_configs");

	NT_LoadConfig();
	NTSI_LoadNIPFiles("NTBot/item_configs");

	MWC_Initialize();

	if(!NTTM_CheckAct(1, true))
	{
		NTC_SendMsgToScript("MWBotGame.ntj", NTTM_CheckAct, 18, me.act, true);
		return;
	}

	NTTMGR_TownManager();
	
	while(true)
	{
		NTCU_InitCubing();
		
		MWCR_PickIngredients();
		
		if(NTCU_CheckCubing())
			NTTMGR_VisitStash(true);
			
		NTC_Delay(1000);
	}
	
	NTC_SendMsgToScript("MWBotGame.ntj", "SCRIPT_END");
}

function MWCR_PickIngredients()
{
	var _item, _craftSets, _index;
	var i, j;
	
	_craftSets = new Array();
	
	_item = NTC_FindUnit(NTC_UNIT_ITEM);
	
	if(!_item)
		return;
		
	// _craftSets structure: [requiredIngredients[], runegid, gemgid, jewelgid, basegid]
	// requiredIngredients[] structure: [ilvl, runeclassid, gemclassid, jewelclassid, baseclassid]
	for(i = 0; i < NTConfig_CubingItem.length; i++)
	{
		_craftSets.push([_NTCU_CraftRecipe[NTConfig_CubingItem[i][0] - NTCU_CRAFT_HITPOWER_HELM], null, null, null]);
		_craftSets[_craftSets.length - 1][0].push(MWCU_JEWEL, NTConfig_CubingItem[i][1]);
	}
	
	do
	{
		if(GetDistance(me, _item) < _MWCR_PICKUP_RANGE && NTSI_CheckItem(_item) == 2)
		{
			for(i = 0; i < _craftSets.length; i++)
			{
				_index = _craftSets[i][0].indexOf(_item.classid); // Returns a valid array index if the item is required for the current recipe (1: rune; 2: perfect gem; 3: base item)
				
				if(_index > 0)
				{
					if(_craftSets[i][_index] == null)
					{
						_craftSets[i][_index] = _item.gid;
						break;
					}
				}
			}
		}
	} while(_item.GetNext());

	for(i = 0; i < _craftSets.length; i++)
	{
		for(j = 0; j < _craftSets[i].length; j++)
		{
			if(_craftSets[i][j] == null)
				break;
		}
		
		if(j >= _craftSets[i].length)
		{
			for(j = 1; j < _craftSets[i].length; j++)
				MWSI_PickupItem(_craftSets[i][j]);
		}
	}
}
Das ist nur ein relativ simpler und wenig intelligenter Ansatz, wobei nur soviele Sets aufgehoben werden, wie entsprechende Rezepte aktiviert sind. Ausserdem werden nur vollständige Sets aufgehoben.
Kannst es ja mal ausprobieren, ich habe es nicht getestet, sollte aber funktionieren, sofern ich mich nicht vertippt habe. :)

LG
Muddy
Ah okay, ich hatte mir überlegt das ma vllt. direkt aus der Cubing.ntj die Rezepte verwenden kann, weil dort steht ja eig. schon drin welches Set ist und was dazu gehört, aber dann würde der Cubing Algorithmus glaub nicht mehr stimmen :/

Bevor ichs ausprobieren kann, fehlt mir noch ne sinnvolle Schleife in der MwCraftGame.

Code:
/**
*	This file was modified by [Only registered and activated users can see links. Click Here To Register...]
*	Check the programming section for updates and further scripts
*	Last Update: 02/19/2011
*/

function NTMain()
{
	SetStatusText("ÿc8Initializing...");
	
	Include("libs/common/NTCommon.ntl");
		
	NTC_IncludeLibs();
	NTC_IncludeConfig("NTBot/char_configs");
	
	NT_LoadConfig();
	NTSI_LoadNIPFiles("NTBot/item_configs");
		
	if(NTConfig_StartDelay > 0);
		NTC_Delay(NTConfig_StartDelay);
	
	NTT_GetCorpses();

	if(Load("NTBot/bots/MWCraft.ntj"))
		Print("ÿc8Running MWCraft.ntj");
		
	ExitGame();
}
Er lädt das Script und geht dann direkt ausm Game, was ja logisch is.
wie genau kann ich jetz hier ne sinnvolle Schleife einbaun?

Bei der Rush.ntj ist das dazwischen.

Code:
	if(Load("NTBot/bots/MWCraft.ntj"))
		Print("ÿc8Running MWCraft.ntj");
		
[COLOR="DarkRed"]	var _count = 0;

	while(!LeaveGame)
	{
		NTC_Delay(1000);
		
		if(_count > 5)
		{
			_count = 0;
			
			MWC_ManageParty();
		}
		
		_count++;
	}[/COLOR]
	
	ExitGame();
Aber wär ja sinnfrei :D
07/02/2011 12:17 Muddy Waters#6
Du brauchst nur eine Endlosschleife, was du darin genau machst ist eigentlich egal, da diese ja ohnehin im Hintergrund Thread ausgeführt wird.

Versuch es mal so, dann kannst du mit Druck auf Entf das Spiel verlassen:
Code:
/**
*	This file was modified by [Only registered and activated users can see links. Click Here To Register...]
*	Check the programming section for updates and further scripts
*	Last Update: 12:13 02.07.2011
*/

var _MW_LeaveGame = false;

function NTMain()
{
	SetStatusText("ÿc8Initializing...");
	
	Include("libs/common/NTCommon.ntl");
		
	NTC_IncludeLibs();
	NTC_IncludeConfig("NTBot/char_configs");
	
	NT_LoadConfig();
	NTSI_LoadNIPFiles("NTBot/item_configs");
		
	RegisterEvent(EVENT_KEYDOWN, MW_KeyEventHandler);
	
	if(NTConfig_StartDelay > 0);
		NTC_Delay(NTConfig_StartDelay);
	
	NTT_GetCorpses();

	if(Load("NTBot/bots/MWCraft.ntj"))
		Print("ÿc8Running MWCraft.ntj");
		
	while(!_MW_LeaveGame)
		NTC_Delay(1000);
		
	ExitGame();
}

function MW_KeyEventHandler(keycode)
{
	if(keycode == 46) // Exit (DEL)
		_MW_LeaveGame = true;
}
LG
Muddy
07/04/2011 11:34 -Nemesis1337-#7
Habs ausprobiert und er gibt direkt:
[Only registered and activated users can see links. Click Here To Register...]

Als Fehler aus, obwohls doch definiert is o.O

Code:
	var _item, _craftSets, _index;
	var i, j;
	
	_craftSets = new Array();
	
	_item = NTC_FindUnit(NTC_UNIT_ITEM);
	
	if(!_item)
		return;
		
	// _craftSets structure: [requiredIngredients[], runegid, gemgid, jewelgid, basegid]
	// requiredIngredients[] structure: [ilvl, runeclassid, gemclassid, jewelclassid, baseclassid]
	for(i = 0; i < NTConfig_CubingItem.length; i++)
	{
		_craftSets.push([_NTCU_CraftRecipe[NTConfig_CubingItem[i][0] - NTCU_CRAFT_HITPOWER_HELM], null, null, null]);
[COLOR="Red"]Line 54->[/COLOR]		_craftSets[_craftSets.length - 1][0].push(MWCU_JEWEL, NTConfig_CubingItem[i][1]);
	}
07/04/2011 18:55 Muddy Waters#8
Da fehlt eine if-Anweisung, ohne die gibt es eine Bereichsüberschreitung, die die Fehlermeldung verursacht.
So sollte es klappen:
Code:
const _MWCR_PICKUP_RANGE = 15;

function NTMain()
{
	Include("libs/common/NTCommon.ntl");
	NTC_IncludeLibs();
	NTC_IncludeConfig("NTBot/char_configs");

	NT_LoadConfig();
	NTSI_LoadNIPFiles("NTBot/item_configs");

	MWC_Initialize();

	if(!NTTM_CheckAct(1, true))
	{
		NTC_SendMsgToScript("MWBotGame.ntj", NTTM_CheckAct, 18, me.act, true);
		return;
	}

	NTTMGR_TownManager();
	
	while(true)
	{
		NTCU_InitCubing();
		
		MWCR_PickIngredients();
		
		if(NTCU_CheckCubing())
			NTTMGR_VisitStash(true);
			
		NTC_Delay(1000);
	}
	
	NTC_SendMsgToScript("MWBotGame.ntj", "SCRIPT_END");
}

function MWCR_PickIngredients()
{
	var _item, _craftSets, _index;
	var i, j;
	
	_craftSets = new Array();
	
	_item = NTC_FindUnit(NTC_UNIT_ITEM);
	
	if(!_item)
		return;
		
	// _craftSets structure: [requiredIngredients[], runegid, gemgid, jewelgid, basegid]
	// requiredIngredients[] structure: [ilvl, runeclassid, gemclassid, jewelclassid, baseclassid]
	for(i = 0; i < NTConfig_CubingItem.length; i++)
	{
		if(NTConfig_CubingItem[i][0] >= NTCU_CRAFT_HITPOWER_HELM && NTConfig_CubingItem[i][0] <= NTCU_CRAFT_SAFETY_WEAPON)
		{
			_craftSets.push([_NTCU_CraftRecipe[NTConfig_CubingItem[i][0] - NTCU_CRAFT_HITPOWER_HELM], null, null, null]);
			_craftSets[_craftSets.length - 1][0].push(MWCU_JEWEL, NTConfig_CubingItem[i][1]);
		}
	}
	
	do
	{
		if(GetDistance(me, _item) < _MWCR_PICKUP_RANGE && NTSI_CheckItem(_item) == 2)
		{
			for(i = 0; i < _craftSets.length; i++)
			{
				_index = _craftSets[i][0].indexOf(_item.classid); // Returns a valid array index if the item is required for the current recipe (1: rune; 2: perfect gem; 3: base item)
				
				if(_index > 0)
				{
					if(_craftSets[i][_index] == null)
					{
						_craftSets[i][_index] = _item.gid;
						break;
					}
				}
			}
		}
	} while(_item.GetNext());

	for(i = 0; i < _craftSets.length; i++)
	{
		for(j = 0; j < _craftSets[i].length; j++)
		{
			if(_craftSets[i][j] == null)
				break;
		}
		
		if(j >= _craftSets[i].length)
		{
			for(j = 1; j < _craftSets[i].length; j++)
				MWSI_PickupItem(_craftSets[i][j]);
		}
	}
}
LG
Muddy
07/12/2011 23:31 -Nemesis1337-#9
Sow ich meld mich mal wieder zu Wort :D

Da ich meinen Pc neu aufgesetzt habe und entsprechende Probleme eingetreten sind, die eine typische Windowsneuinstallation so mit sich bringt - Ein Dankeschön an Mr. Gates nebenbei - hat es dementsprechend länger gedauert.


EDIT:

Also :) Habs ausprobiert, klappt wunderbar.
Hab 88x Craftpacks gedroppt. Bin mit dem Entry ins Game und er hat auch direkt angefangen zu craften. Unwichtige hat er einfach bei der Truhe gedroppt und Wichtige gestashed.

Ich habe, als er dann fertig war, alle 2Sek. heftige Lags bemerkt die wohl vom Scannen kommen.
Da man das Script aber eh einsetzt wenn die Craftpacks aufm Boden rumliegen und rausgeht wenn er fertig is, geht das :)

Sehr feine Sache!! :O
Vielen Vielen Dank!
07/18/2011 00:08 -Nemesis1337-#10
MajorUpdate.