D2NT GoldBarb

11/18/2011 18:58 Someone3#1
Haben hier alle zu viele Enigma und Botd? Jedenfalls konnte ich nirgends ein Script für einen laufenden, passiven (d.h. Merc killt) Goldbarb in Travincal gefunden hab, hab ich meinen Nachmittag geopfert um eines zu schreiben... ich empfehle max fire res + battle cry + war cry. Meiner packt Nightmare mit max-EG-equipment ohne Probleme. Da er auch gleich gamblen kann, ist hohes Level + Runenwort Edge dringend zu empfehlen. Abschließend geht er in Akt 4 um Laufweg zu sparen.
PS: Wenn er ab und zu ein TP aufmacht und gleich wieder zurückgeht dann dient das dem Warpen des Mercs (der soll ja nicht irgendwo killen, sondern da wo wir sind).
PPS: IdInField ist je nach freiem Inventar zu empfehlen ;).

Wer gamblen will, muss leider eine Kleinigkeit im libs\common\NTTownManager.ntl anpassen (Zeile 14-19, ein Parameter dazu der verhindert dass immer zum Slot 0 geswitched wird):
Code:
function NTTMGR_TownManager(simple[B][COLOR="Red"], noswap[/COLOR][/B])
{
	while(me.areaid == 0){
		NTC_Delay(200);
	}
	[COLOR="Red"][B]if(!noswap) [/B][/COLOR]NTC_SwapWeapons(0);
Ansonsten einfach den folgenden Code in den bots Ordner haun und entsprechend in der Char Config pushen.
Code:
function NTMain(){

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

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

	NTA_Initialize();

	if(!NTTM_CheckAct())	{
		NTC_SendMsgToScript("NTBotGame.ntj", "NTTM_CheckAct()");
		return;
	}
	
	var switched = false;
	if(NTConfig_Gamble && Trav_HasEdge() > 0) {
		if(NTC_MyGold() > NTConfig_GambleStartGold) {
			Trav_SwitchEdge();
			switched = true;
		}
		else {
			NTC_SwapWeapons(0);
		}
	}
	NTTMGR_TownManager(false, true);
	if(switched) {
		NTC_SwapWeapons();
	}
	
	if(!NTTM_TownMove("waypoint")){
		NTC_SendMsgToScript("NTBotGame.ntj", "NTTM_TownMove()");
		return;
	}
	if(!NTM_TakeWaypoint(83)){
		NTC_SendMsgToScript("NTBotGame.ntj", "NTM_TakeWaypoint()");
		return;
	}
	var _wp = NTC_FindUnit(NTC_UNIT_OBJECT, 237);
	if(!_wp){
		NTC_SendMsgToScript("NTBotGame.ntj", "NTC_FindUnit()");
		return;
	}

	NTP_DoPrecast(true);

	NTM_MoveTo(me.areaid, _wp.x + 19, _wp.y + 5);
	NTM_MoveTo(me.areaid, _wp.x + 23, _wp.y - 23);
	NTM_MoveTo(me.areaid, _wp.x + 100, _wp.y - 31);
	NTM_MoveTo(me.areaid, _wp.x + 99, _wp.y - 61);
	NTM_MoveTo(me.areaid, _wp.x + 99, _wp.y - 75);
	
	var firstTimeWarp = true;
	while(true) {
		var _monster = Trav_GetNearestCouncil(_wp);
		if(_monster) {
			if(Trav_isUnitInside(_monster, _wp)) {
				Trav_GetInsideTemple(_wp);
			}
			else {
				Trav_GetOutsideTemple(_wp);
			}
			if(firstTimeWarp && Trav_GetDistanceToMerc() > 20) {
				Trav_TPWarpMerc();
				firstTimeWarp = false;
				continue;
			}
			firstTimeWarp = false;
			if(GetDistance(me.x, me.y, _monster[0], _monster[1]) >= 5) {
				NTM_MoveTo(me.areaid, _monster[0], _monster[1], 0);
			}
			Trav_StunNearByMonsters();
			
			Trav_CheckMercAndMeInOrOutTemple(_wp, _monster);
		}
		else  {
			break;
		}
		
		NTC_Delay(750);
	}
	
	looting = true;
	NTSI_PickItems();
	Trav_LootCorpses(_wp);
	
	NTTM_CheckAct(4);
	
	NTC_SendMsgToScript("NTBotGame.ntj", "SCRIPT_END");
}

var lastRelocate = 0;
function Trav_CheckMercAndMeInOrOutTemple(_wp, _monster) {
	var _merc = NTC_GetMerc();
	if(!_merc) return false;
	if(Trav_amInsideTemple(_wp) == Trav_isUnitInside(_monster, _wp) && Trav_amInsideTemple(_wp) != Trav_isUnitInside([_merc.x, _merc.y], _wp) && GetTickCount() - lastRelocate > 5000) {
		Trav_TPWarpMerc();
		lastRelocate = GetTickCount();
	}
}

function Trav_GetDistanceToMerc() {
	var _merc = NTC_GetMerc();
	if(_merc) return GetDistance(me, _merc);
	return null;
}

function Trav_LootCorpses(_wp) {
	var _corpse = NTC_FindUnit(NTC_UNIT_MONSTER);
	if(_corpse){
		var corpses = [];
		do{
			if(_corpse.mode == 12 && _corpse.name != "Hydra" && GetDistance(me, _corpse) < NTConfig_SnagRange && _corpse.GetState(118) == 0 && !(_corpse.GetState(96)) && !(_corpse.GetState(104)) && !(_corpse.GetState(107)) && !(_corpse.GetState(118))) {
				corpses.push([_corpse.x, _corpse.y]);
			}
		} while(_corpse.GetNext());
		
		while(corpses.length > 0) {
			corpses.sort(Trav_SortRoomInt);
			_corpse = corpses.shift();
			if(Trav_isUnitInside(_corpse, _wp)) {
				Trav_GetInsideTemple(_wp);
			}
			else {
				Trav_GetOutsideTemple(_wp);
			}
			if(GetDistance(me, _corpse) > 15) {
				NTM_MoveTo(me.areaid, _corpse[0], _corpse[1], 0);
			}
			NTC_CastSkill(142, NTC_HAND_RIGHT);
			NTSI_PickItems();
		}
	}
	return false;
}

function Trav_TPWarpMerc() {
	NTTM_CheckAct();
	var retry = 0;
	while(me.areaid != 83) {
		NTM_UsePortal("BluePortal", 83);
		NTC_Delay(500);
		if(me.areaid != 83 && ++retry > 10) {
			NTC_SendMsgToScript("NTBotGame.ntj", "SCRIPT_ERROR UsePortal");
			return;
		}
	}
}

function Trav_amInsideTemple(_wp) {
	return Trav_isUnitInside([me.x, me.y], _wp);
}

function Trav_isDoorBlocked(_wp) {
	var _monster = NTC_FindUnit(NTC_UNIT_MONSTER);
	if(_monster){
		do{
			if(NTA_IsValidMonster(_monster) && _monster.IsAttackable() && GetDistance(_wp.x+98, _wp.y-84, _monster.x, _monster.y) < 5) {
				return true;
			}
		} while(_monster.GetNext());
	}
	return false;
}

function Trav_GetOutsideTemple(_wp) {
	if(!Trav_amInsideTemple(_wp)) return;
	NTM_MoveTo(me.areaid, _wp.x+100, _wp.y-92);
	if(!looting && Trav_isDoorBlocked(_wp)) {
		return;
	}
	NTM_MoveTo(me.areaid, _wp.x+99, _wp.y-75);
}

function Trav_GetInsideTemple(_wp) {
	if(Trav_amInsideTemple(_wp)) return;
	NTM_MoveTo(me.areaid, _wp.x+99, _wp.y-75);
	if(!looting && Trav_isDoorBlocked(_wp)) {
		return;
	}
	NTM_MoveTo(me.areaid, _wp.x+98, _wp.y-92);
	NTM_MoveTo(me.areaid, _wp.x+87, _wp.y-92);
}

function Trav_StunNearByMonsters() {
	var _monster = NTC_FindUnit(NTC_UNIT_MONSTER);
	if(_monster){
		var casted1 = false, casted2 = false;
		do{
			if(NTA_IsValidMonster(_monster) && _monster.IsAttackable() && GetDistance(me, _monster) < 5 && _monster.name != "Hydra") {
				if(!(_monster.spectype&0x0A) && !_monster.GetState(21)) { //bosses cant get stunned
					NTC_CastSkill(154, NTC_HAND_RIGHT);
					casted1 = true;
				}
				if(!_monster.GetState(89)) {
					NTC_CastSkill(146, NTC_HAND_RIGHT);
					casted2 = true;
				}
				if(casted1 && casted2) break;
			}
		} while(_monster.GetNext());
	}
}

function Trav_isUnitInside(_unit, _wp) {
	if(((_unit[0] >= _wp.x + 68 && _unit[0] <= _wp.x + 89) || (_unit[0] >= _wp.x + 108 && _unit[0] <= _wp.x + 129)) && _unit[1] <= _wp.y - 80) {
		return true;
	}
	if(_unit[0] >= _wp.x + 90 && _unit[0] <= _wp.x + 107 && _unit[1] <= _wp.y - 85) {
		return true;
	}
	return false;
}

function Trav_GetNearestCouncil() {
	var _monster = NTC_FindUnit(NTC_UNIT_MONSTER);
	var name1 = GetLocaleString(3139);//	Council Member
	var name2 = GetLocaleString(2860);//	Toorc Icefist
	var name3 = GetLocaleString(2862);//	Geleb Flamefinger
	var name4 = GetLocaleString(2863);//	Ismail Vilehand
	if(_monster){
		var sortme = [];
		do{
			if(NTA_IsValidMonster(_monster) && (_monster.name == name1 || _monster.name == name2 || _monster.name == name3 || _monster.name == name4) ) {
				sortme.push([_monster.x, _monster.y]);
			}
		} while(_monster.GetNext());
		sortme.sort(Trav_SortRoomInt);
		if(sortme.length == 0) return null;
		return sortme.shift();
	}
}

var _NTP_HaveEdge = -1;
function Trav_HasEdge()
{
	if(_NTP_HaveEdge < 0) {
		var _weapon;

		_NTP_HaveEdge = 0;

		_weapon = me.GetItems();

		if(_weapon)
		{
			for(var i = 0 ; i < _weapon.length ; i++)
			{
				if(_weapon[i].mode == 1 && (_weapon[i].itemflag&0x4000000) && _weapon[i].itemprefix == 20537)
				{
					if(_weapon[i].itemloc == 4 || _weapon[i].itemloc == 5) {
						_NTP_HaveEdge = 1;
					}
					else {
						_NTP_HaveEdge = 2;
					}

					break;
				}
			}
		}
	}
	return _NTP_HaveEdge;
}

function Trav_SwitchEdge() {
	if(Trav_HasEdge() > 0)
		return NTC_SwapWeapons(_NTP_HaveEdge-1);
}

function Trav_SortRoomInt(a, b) {
   if(GetDistance(me.x, me.y, a[0], a[1]) < GetDistance(me.x, me.y, b[0], b[1]))
      return -1;

   return 1;
}
Wer sich wundert warum ich nicht die Stairs benutze um den Merc zu warpen: leider funktioniert hier NTM_TakeStair nicht :(.
Die Reichweite von WC und BC hab ich jetzt mal auf 5 geschätzt, scheint soweit zu funktionieren.

Ursprünglich hatte ich vor aufm Switch BO Waffen zu haben, aber jedesmal zur Truhe zu rennen und mühsam Edge zu equippen war mir dann doch zu blöd... und in NM kommts auf das bissl Leben Unterschied net an.
Probleme gibts wenn PickItems() versucht in oder aus dem Tempel zu kommen, aber die Erfolgsquote ist trotzdem gut ;).

/ps: werde hier dann noch den durchschnittlichen Goldertrag pro Run reinschreiben...
11/18/2011 22:08 D2_sid#2
Danke! Habe schon sehr lange nach so einem Script gesucht :)
Ein paar fragen dazu.

1) Was macht der Barb genau? Bei den passiven Builds ist es ja oft so,
dass der Barb den Rat mit Sprung angreift, um sie zu stunnen.

2)
Quote:
PPS: IdInField ist je nach freiem Inventar zu empfehlen.
Was genau bewirkt diese Funktion?

3) Benutzt der Barb den Skill "find Item" nachdem der Merc seine Arbeit
gemacht hat?
11/19/2011 02:12 Someone3#3
Quote:
Originally Posted by D2_sid View Post
Danke! Habe schon sehr lange nach so einem Script gesucht :)
Ein paar fragen dazu.

1) Was macht der Barb genau? Bei den passiven Builds ist es ja oft so,
dass der Barb den Rat mit Sprung angreift, um sie zu stunnen.

2)
Was genau bewirkt diese Funktion?

3) Benutzt der Barb den Skill "find Item" nachdem der Merc seine Arbeit
gemacht hat?
1) Momentan läuft er immer nur in die Nähe des nächsten Rats, castet wenn nötig BC/WC und wartet dann 750ms. Ggf. wird auch TP benutzt um dedn Merc herzuholen. Sprung? Funktioniert das so gut? Ich hab den so langsam in Erinnerung...

2) IdInField lässt den Bot bei mangelndem Platz zum Aufheben die Id Tome benutzen um alles was sonst verscherbelt würde einfach fallen zu lassen. Soviel Zeug wie der Rat immer fallen lässt spart das viel Zeit/TPs, aber wer natürlich seine Pickit drauf ausrichtet 35k Items aufzusammeln und zu verkaufen sollte das aus lassen.

3) Klar.
11/19/2011 05:04 Diablofarmer#4
feine sache, ich such heute nachmittag mal, wenn ich zeit hab, die Funktion raus um runter ins DOH zu stiefeln

e: grade mal kurz angestest, wegen der Funktion, dabei kam raus, dass in Zeile 229 "SortRoomInt" nicht definiert ist :)
11/19/2011 10:33 Someone3#5
Quote:
Originally Posted by Diablofarmer View Post
feine sache, ich such heute nachmittag mal, wenn ich zeit hab, die Funktion raus um runter ins DOH zu stiefeln

e: grade mal kurz angestest, wegen der Funktion, dabei kam raus, dass in Zeile 229 "SortRoomInt" nicht definiert ist :)
Hm, ich benutz d2etal, kann sein dass der mehr mitliefert... hab die Funktion mal oben umbenannt reinkopiert.
11/19/2011 13:04 Metal God#6
Sprung würd ich total empfehlen, falls das in den bot einbaubar ist!
Ich hab passiv goldbarb bisher nur selbst gespielt und find dendauerleaper wesentlich angenehmer als den schreihals (aka wc). einfach in den rat reinlaufen, notfalls merc mitporten und shift+leap gedrückt halten bis das ganze vorbei ist.

Vorteil : Bei genügend hohem leap level bewegt sich niemand mehr vom rat --> keine attacken, keine blitze, kaum hydras.

Nachteil : Durch leap werden alle ratsmitglieder bis zur nächsten wand zurückgestoßen und bleiben da kleben bis der merc sie gefunden hat, was beim bot evtl dauern kann(?)
11/27/2011 22:38 Someone3#7
Hm... habs bissl mit Sprung ausprobiert (selber spielen). Ist nicht ganz trivial wies die da weghaut :/. Auf Hölle überlebts mein Lvl 81 Merc leider nicht mit Wealth und upped Hone Sundan ^^'. Also selbst wenn die dauernd gestunnt sind, tippe auf die Blitzverzauberung ;). Bin jetzt gerade an was anderem dran, dann schau ichs mir vlt noch an.
12/04/2011 17:53 ravetheone#8
ich bekomme immer den fehler:

looting not defined

kann mir jemand helfen? :)
12/06/2011 14:44 ravetheone#9
niemand ne idee?
12/06/2011 16:28 Someone3#10
oh sry, das hab ich wohl abgeschnitten, gleich vor NTMain:
var looting = false;
12/06/2011 19:32 ravetheone#11
ah sehr gut! danke!

habs jetzt vors function geschrieben.

funktioniert gut :)