Anmerkung: Ich werde hier keine Aktualisierungen mehr einfügen, da mir der Aufwand einzelne Scripts zu isolieren zu hoch ist. Die hier hochgeladene Version ist nicht mehr aktuell, eine aktuelle Version findet sich in meinem .
Hallo zusammen,
nach meinem Patzer beim Itemlog bin ich euch was schuldig glaube ich.
Darum gibts hier nun meine Find Item Implementierung.
Ist in meinen Augen definitiv noch nicht perfekt, auch wenn sie sogesehen ziemlich rund läuft und keine Abstürze produziert. Trotzdem ist dieses Release mehr eine Testversion, die sich an Leute richtet die ein bisschen Erfahrung mitbringen, mit dem Ziel, das ganze noch weiter auszubauen und zu verbessern.
Bevor ich irgendwas genaueres erzähle möchte ich zunächst kurz die Char Anforderungen ansprechen:
Ich selbst benutze einen WW Barb mit Eni und 37fcr. 37fcr empfehle ich stark, wenn ihr auch Area runs macht, ansonsten wird das looten einer Horde Monster zu einer extrem langwierigen Sache, etwas fcr sorgt hingegen direkt für einen deutliche besseren und flotteren Ablauf. Insgesamt sicherlich auch eine effektibe Sache, schließlich hat man bei nem guten Find Item Level schnell mal 50% Chance auf einen Zweitdrop, in Alvl85 Ebenen macht sich das sicherlich gut.
Stichwort Eni: Ist in jedem Fall Vorraussetzung!
Es wäre zwar denkbar Travi und andere Runs mit kurzen und vor allem konstanten Wegen ohne teleport umzusetzen, aber darum habe ich mich bisher nicht gekümmert. Ich denke ich brauche nicht extra erwähnen, dass der Barb ansonsten auch ein halbwegs hellfähiges Equipment haben sollte.
Soweit so gut, nun zu den eigentlichen Funktionen:
Ich habe Find Item fest in die häufig verwendeten Funktionen NTA_ClearPosition() sowie NTA_ClearRoom() eingebunden. Ihr könnte euch das ein bisschen so vorstellen wie beim Pala mit Redemption, an der Stelle wo das eingesetzt würde, kommt nun als Barb Find Item ins Spiel. Es werden alle gültigen Monster in einem gewissen Radius gelootet, welcher per Variable festgelegt werden kann.
"gültige Monster" soll heissen, dass die Monster auch tatsächlich lootbar sind. Dazu habe ich eine Funktion geschrieben, die an sich alle nicht lootbaren Monster ausschließen sollte, ob das wirklich absolut sicher funktioniert kann ich nicht sagen, da ich das ganze noch nicht in allen Situationen getestet habe. Ohne diese Funktion würde beispielsweise versucht, Find Item bei eurem Merc anzuwenden, sofern dieser gerade gestorben ist und im überprüften Radius liegt. Das ist natürlich etwas nervig, darum gibt es diese Funktion.
Es passiert allerdings öfter mal, dass auch eigentlich gültige Monster nicht gelootet werden können, weil der Barb beispielsweise Probleme hat diese zu erreichen. Für diesen Fall sieht meine Funktion eine Neupositionierung nach 1 Sekunde vor, nach 3 Sekunden wird das Monster dann übersprungen. Insgesamt wird also immer 3 Sekunden versucht ein Monster zu looten, meist gehts natürlich deutlich schneller.
Die Waffen, die für Find Item benutzt werden sollen, müssen sich übrigens im zweiten Slot befinden, auf diesen wird immer gewechselt vor dem Einsatz des Skills.
Achja, da das ganze ja noch im Teststadium ist werden Monster, die nicht gelootet werden konnten, in einer Textdatei geloggt. So kann man Auswerten, ob eventuell versucht wurde, ein ungültiges Monster zu looten und so die entsprechende Funktion verbessern, die dies eigentlich ausschließen soll.
Die meisten Ausgaben habe ich aber schonmal entfernt, sonst wird der Bildschirm teilweise sehr vollgespammt.
Das Looten funktioniert so natürlich nur, nachdem die ganz oben erwähnten Funktionen halbwegs erfolgreich durchgelaufen sind. Ihr könnt natürlich auch weitere Aufrufe in eure Bot Scripte einfügen, meine Funktion NTA_FindItem(range) erwartet dabei einen Integer Wert als range als Übergabeparameter. Dieser kann auch weggelassen werden, dann wird range auf den Defaultwert von 25 gesetzt.
Habe ich nun alles?
Nicht ganz. Meine NTAttack.ntl enthält ausserdem andere kleinere Modfikationen, so z.B. wird Statik nurnoch bei Aktbossen eingesetzt.
Ansonsten stecken auch noch Funktionen zum Öffnen sämtlicher Truhen darin, diese Funktionen sind aber an dieser Stelle auskommentiert, da Ich damit noch nicht absolut zufrieden bin und es hier ausserdem erstmal um die Find Item Funktion gehen soll. Ich wollte es nur anmerken, falls sich der ein oder andere wundert.
Hier nun mal meine modifizierte NTAttack.ntl:
Code:
const NTA_DAMAGE_NONE = 0;
const NTA_DAMAGE_PHYSICAL = 1;
const NTA_DAMAGE_MAGIC = 2;
const NTA_DAMAGE_FIRE = 3;
const NTA_DAMAGE_LIGHTNING = 4;
const NTA_DAMAGE_COLD = 5;
const NTA_DAMAGE_POISON = 6;
var _NTA_SkillHand = new Array(8);
var _NTA_SkillDamage = new Array(8);
var _NTA_SkillRange = new Array(8);
function NTA_Initialize()
{
if(NTConfig_AttackSkill[1] == 0 || NTConfig_AttackSkill[3] == 0)
NTA_DetectAttackPattern();
for(var i = 0 ; i < 8 ; i++)
{
if(NTConfig_AttackSkill[i] > 0)
{
_NTA_SkillHand[i] = GetBaseStat("skills.txt", NTConfig_AttackSkill[i], 166) ? 2 : NTC_HAND_RIGHT;
_NTA_SkillDamage[i] = NTA_GetDamageType(NTConfig_AttackSkill[i]);
switch(NTConfig_AttackSkill[i])
{
case 44: //Frost Nova
case 48: // Nova
_NTA_SkillRange[i] = 10;
break;
case 64: // Frozen Orb
_NTA_SkillRange[i] = 15;
break;
case 97: //Smite
case 106: //Zeal
case 112: //Blessed Hammer
_NTA_SkillRange[i] = 3;
break;
case 151: //Whirlwind
_NTA_SkillRange[i] = 8;
break;
case 152: //Berserk
_NTA_SkillRange[i] = 3;
break;
default:
_NTA_SkillRange[i] = 25;
break;
}
}
}
}
function NTA_KillMonster(classid)
{
var _target;
if(NTConfig_AttackSkill[1] < 1)
return false;
_target = NTC_FindUnit(NTC_UNIT_MONSTER, classid, 5);
if(!_target)
return false;
if(_target.IsAttackable())
{
var _attackcount = 0;
while(_attackcount < 300 && NTA_IsValidMonster(_target))
{
if(NTA_Attack(_target, (_attackcount%30) == 0) < 2)
break;
_attackcount++;
}
}
return (_target.hp <= 0 || _target.mode == 0 || _target.mode == 12);
}
function NTA_ClearPosition(range, pickitem, safelevel, recursion)
{
var _orgx, _orgy;
var _spectype = [0x0A, 0x01, 0x01];
var _skiplist;
var _attackcount = 0;
var _target;
var _distance, _mingid, _mindistance;
var _result;
if(NTConfig_AttackSkill[1] < 1 || NTConfig_AttackSkill[3] < 1)
return false;
switch(arguments.length)
{
case 0:
range = 20;
case 1:
pickitem = false;
case 2:
safelevel = 0;
case 3:
recursion = true;
default:
if(NTConfig_CheckSelfSafe < 0x01 && NTConfig_CheckMercSafe < 0x01)
safelevel = 0;
break;
}
_orgx = me.x;
_orgy = me.y;
for(var i = 0 ; i < _spectype.length ; i++)
{
_skiplist = new Array();
while(_attackcount < (i+1)*100)
{
_mindistance = 100000;
_target = NTC_FindUnit(NTC_UNIT_MONSTER);
if(_target)
{
do
{
if(_skiplist.indexOf(_target.gid) < 0)
{
if(_target.IsAttackable() && (_target.spectype&_spectype[i]))
{
if(GetDistance(_orgx, _orgy, _target.x, _target.y) <= range && NTA_IsValidMonster(_target))
{
_distance = GetDistance(me, _target);
if(_distance < _mindistance)
{
_mingid = _target.gid;
_mindistance = _distance;
}
}
}
else
_skiplist.push(_target.gid);
}
} while(_target.GetNext());
}
if(_mindistance < 100000)
{
_target = NTC_FindUnit(NTC_UNIT_MONSTER, _mingid);
if(_target)
{
_result = NTA_Attack(_target, (_attackcount%30) == 0);
switch(_result)
{
case 1:
_skiplist.push(_mingid);
break;
case 2:
case 3:
_attackcount++;
break;
default:
return false;
}
}
}
else
break;
}
}
if(me.classid == NTC_CHAR_CLASS_PALADIN)
{
if(_attackcount > 2 && (parseInt(me.hp*100/me.hpmax) < NTConfig_UseRedemptionHP || parseInt(me.mp*100/me.mpmax) < NTConfig_UseRedemptionMP))
{
if(NTC_PutSkill(124, NTC_HAND_RIGHT))
NTC_PingDelay(1000);
}
}
if(NTConfig_UseFindItem && me.classid == NTC_CHAR_CLASS_BARBARIAN && _attackcount > 2)
{
if(!NTA_CheckForCloseMonsters(10))
{
//Print("ÿc<No Monsters close - looting");
NTA_FindItem(NTConfig_FindItemRange);
}
else
{
//Print("ÿc1Close Monster detected - clearing area");
if(recursion)
{
NTA_ClearPosition(15, false, 0, false);
NTA_FindItem(NTConfig_FindItemRange);
}
}
}
if(NTConfig_OpenChest)
{
_target = NTC_GetSpecialChest();
if(_target && GetDistance(_orgx, _orgy, _target.x, _target.y) <= range && NTC_OpenChest(_target))
_attackcount++;
}
if(pickitem && _attackcount > 0)
NTSI_PickItems();
/*
if(!NTA_CheckForCloseMonsters(15))
NTA_OpenChests();
*/
switch(safelevel)
{
case 1:
return NTTMGR_CheckSafe(0x00, NTConfig_CheckMercSafe&0x01);
case 2:
return NTTMGR_CheckSafe(NTConfig_CheckSelfSafe, NTConfig_CheckMercSafe);
}
return true;
}
function NTA_ClearLevel(pickitem, safelevel)
{
var i;
var _room, _rooms;
var _distance, _minindex, _mindistance;
_room = GetRoom();
if(!_room)
return false;
switch(arguments.length)
{
case 0:
pickitem = true;
case 1:
safelevel = 2;
default:
if(NTConfig_CheckSelfSafe < 0x01 && NTConfig_CheckMercSafe < 0x01)
safelevel = 0;
break;
}
_rooms = new Array();
do
{
_rooms.push([parseInt(_room.x*5 + _room.xsize*5/2), parseInt(_room.y*5 + _room.ysize*5/2)]);
} while(_room.GetNext());
while(_rooms.length > 0)
{
_mindistance = 100000;
for(i = 0 ; i < _rooms.length ; i++)
{
_distance = GetDistance(me.x, me.y, _rooms[i][0], _rooms[i][1]);
if(_distance < _mindistance)
{
_minindex = i;
_mindistance = _distance;
}
}
if(NTM_MoveTo(me.areaid, _rooms[_minindex][0], _rooms[_minindex][1], 1))
{
if(!NTA_ClearRoom(pickitem, safelevel))
return false;
NTP_DoPrecast(false);
}
_rooms.splice(_minindex, 1);
}
return true;
}
function NTA_ClearRoom(pickitem, safelevel)
{
var _room;
var _spectype = [0x0A, 0x01, 0x01];
var _skiplist;
var _attackcount = 0;
var _target;
var _distance, _mingid, _mindistance;
var _result;
if(NTConfig_AttackSkill[1] < 1 || NTConfig_AttackSkill[3] < 1)
return false;
_room = me.GetRoom();
if(!_room)
return false;
switch(arguments.length)
{
case 0:
pickitem = false;
case 1:
safelevel = 0;
default:
if(NTConfig_CheckSelfSafe < 0x01 && NTConfig_CheckMercSafe < 0x01)
safelevel = 0;
break;
}
for(var i = 0 ; i < _spectype.length ; i++)
{
_skiplist = new Array();
while(_attackcount < (i+1)*100)
{
_mindistance = 100000;
_target = NTC_FindUnit(NTC_UNIT_MONSTER);
if(_target)
{
do
{
if(_skiplist.indexOf(_target.gid) < 0)
{
if(_target.IsAttackable() && (_target.spectype&_spectype[i]))
{
if(_room.UnitInRoom(_target) && NTA_IsValidMonster(_target))
{
_distance = GetDistance(me, _target);
if(_distance < _mindistance)
{
_mingid = _target.gid;
_mindistance = _distance;
}
}
}
else
_skiplist.push(_target.gid);
}
} while(_target.GetNext());
}
if(_mindistance < 100000)
{
_target = NTC_FindUnit(NTC_UNIT_MONSTER, _mingid);
if(_target)
{
_result = NTA_Attack(_target, (_attackcount%30) == 0);
switch(_result)
{
case 1:
_skiplist.push(_mingid);
break;
case 2:
case 3:
_attackcount++;
break;
default:
return false;
}
}
}
else
break;
}
}
if(me.classid == NTC_CHAR_CLASS_PALADIN)
{
if(_attackcount > 2 && (parseInt(me.hp*100/me.hpmax) < NTConfig_UseRedemptionHP || parseInt(me.mp*100/me.mpmax) < NTConfig_UseRedemptionMP))
{
if(NTC_PutSkill(124, NTC_HAND_RIGHT))
NTC_PingDelay(1000);
}
}
if(NTConfig_UseFindItem && me.classid == NTC_CHAR_CLASS_BARBARIAN && _attackcount > 2)
{
if(!NTA_CheckForCloseMonsters(5))
{
//Print("ÿc<No Monsters close - looting");
NTA_FindItem(NTConfig_FindItemRange);
}
}
if(NTConfig_OpenChest)
{
_target = NTC_GetSpecialChest();
if(_target && _room.UnitInRoom(_target) && NTC_OpenChest(_target))
_attackcount++;
}
if(pickitem && _attackcount > 0)
NTSI_PickItems();
/*
if(!NTA_CheckForCloseMonsters(15))
NTA_OpenChests();
*/
switch(safelevel)
{
case 1:
return NTTMGR_CheckSafe(0x00, NTConfig_CheckMercSafe&0x01);
case 2:
return NTTMGR_CheckSafe(NTConfig_CheckSelfSafe, NTConfig_CheckMercSafe);
}
return true;
}
function NTA_IsValidMonster(monster)
{
var _classid;
if(monster.hp <= 0 || monster.mode == 0 || monster.mode == 12)
return false;
_classid = monster.classid;
if(((_classid >= 110 && _classid <= 113) || _classid == 608) && monster.mode == 8) // ignore flying scavengers
return false;
if(_classid == 68 && monster.mode == 14) // ignore burrowing maggots
return false;
if(_classid >= 258 && _classid <= 263 && monster.mode == 14) // ignore submerged WaterWatchers
return false;
if(monster.GetState(53) || monster.GetState(96)) // Conversion, Revive
return false;
return true;
}
function NTA_GetDamageType(skillid)
{
if(skillid == 74) // Corpse Explosion
return NTA_DAMAGE_PHYSICAL;
if(skillid == 112) // Blessed Hammer
return NTA_DAMAGE_NONE;
switch(GetBaseStat("skills.txt", skillid, 233))
{
case "cold":
return NTA_DAMAGE_COLD;
case "fire":
return NTA_DAMAGE_FIRE;
case "ltng":
return NTA_DAMAGE_LIGHTNING;
case "mag":
return NTA_DAMAGE_MAGIC;
case "pois":
return NTA_DAMAGE_POISON;
case "stun":
return NTA_DAMAGE_NONE;
default:
if(GetBaseStat("skills.txt", skillid, 178) || GetBaseStat("skills.txt", skillid, 182)) // aura or passive
return NTA_DAMAGE_NONE;
}
return NTA_DAMAGE_PHYSICAL;
}
function NTA_GetResistance(enemy, type)
{
switch(type)
{
case NTA_DAMAGE_PHYSICAL:
return enemy.GetStat(36);
case NTA_DAMAGE_MAGIC:
return enemy.GetStat(37);
case NTA_DAMAGE_FIRE:
return enemy.GetStat(39);
case NTA_DAMAGE_LIGHTNING:
return enemy.GetStat(41);
case NTA_DAMAGE_COLD:
return enemy.GetStat(43);
case NTA_DAMAGE_POISON:
return enemy.GetStat(45);
}
return 0;
}
function NTA_DetectAttackPattern()
{
switch(me.classid)
{
case NTC_CHAR_CLASS_AMAZON:
return NTA_AmazonAttackPatternInt();
case NTC_CHAR_CLASS_SORCERESS:
return NTA_SorceressAttackPatternInt();
case NTC_CHAR_CLASS_NECROMANCER:
return NTA_NecromancerAttackPatternInt();
case NTC_CHAR_CLASS_PALADIN:
return NTA_PaladinAttackPatternInt();
case NTC_CHAR_CLASS_BARBARIAN:
return NTA_BarbarianAttackPatternInt();
case NTC_CHAR_CLASS_DRUID:
return NTA_DruidAttackPatternInt();
case NTC_CHAR_CLASS_ASSASSIN:
return NTA_AssassinAttackPatternInt();
}
return false;
}
// Return value : 0 = Unrecoverable process, 1 = Unavailable attack, 2 = Onetime fail, 3 = Success
function NTA_Attack(target, firstorder)
{
switch(me.classid)
{
case NTC_CHAR_CLASS_AMAZON:
return NTA_AmazonAttackInt(target, firstorder);
case NTC_CHAR_CLASS_SORCERESS:
return NTA_SorceressAttackInt(target, firstorder);
case NTC_CHAR_CLASS_NECROMANCER:
return NTA_NecromancerAttackInt(target, firstorder);
case NTC_CHAR_CLASS_PALADIN:
return NTA_PaladinAttackInt(target, firstorder);
case NTC_CHAR_CLASS_BARBARIAN:
return NTA_BarbarianAttackInt(target, firstorder);
case NTC_CHAR_CLASS_DRUID:
return NTA_DruidAttackInt(target, firstorder);
case NTC_CHAR_CLASS_ASSASSIN:
return NTA_AssassinAttackInt(target, firstorder);
}
return 0;
}
// Internal function
function NTA_AmazonAttackPatternInt()
{
return false;
}
function NTA_AmazonAttackInt(target, firstorder)
{
return 1;
}
function NTA_AmazonCastSkillInt(index, target)
{
return false;
}
function NTA_SorceressAttackPatternInt()
{
var _maxindex, _maxskill;
var _avgskilllevel = new Array();
_avgskilllevel[0] = parseInt((me.GetSkill(59, false)+me.GetSkill(39, false)+me.GetSkill(45, false)+me.GetSkill(55, false))/4);
_avgskilllevel[1] = parseInt((me.GetSkill(53, false)+me.GetSkill(38, false)+me.GetSkill(48, false)+me.GetSkill(49, false))/4);
_avgskilllevel[2] = parseInt((me.GetSkill(47, false)+me.GetSkill(36, false)+me.GetSkill(56, false)+me.GetSkill(64, false))/4);
_avgskilllevel[3] = parseInt((me.GetSkill(47, false)+me.GetSkill(36, false)+me.GetSkill(56, false))/3);
_maxindex = -1;
_maxskill = 0;
for(var i = 0 ; i < _avgskilllevel.length ; i++)
{
if(_avgskilllevel[i] > _maxskill)
{
_maxindex = i;
_maxskill = _avgskilllevel[i];
}
}
switch(_maxindex)
{
case 0: // Blizzard + Glacial Spike
NTConfig_AttackSkill[1] = 59;
NTConfig_AttackSkill[2] = 55;
NTConfig_AttackSkill[3] = 59;
NTConfig_AttackSkill[4] = 55;
break;
case 1: // Chain Lightning + Lightning
NTConfig_AttackSkill[1] = 49;
NTConfig_AttackSkill[3] = 53;
break;
case 2: // Fire Ball + Frozen Orb
NTConfig_AttackSkill[0] = 64;
NTConfig_AttackSkill[1] = 47;
NTConfig_AttackSkill[3] = 47;
NTConfig_AttackSkill[5] = 64;
NTConfig_AttackSkill[6] = 55;
break;
case 3: // Fire Ball + Meteor
NTConfig_AttackSkill[1] = 56;
NTConfig_AttackSkill[2] = 47;
NTConfig_AttackSkill[3] = 56;
NTConfig_AttackSkill[4] = 47;
break;
}
return (NTConfig_AttackSkill[1] && NTConfig_AttackSkill[3]);
}
function NTA_SorceressAttackInt(target, firstorder)
{
var _primaryindex;
if(NTTMGR_CheckCurse(NTConfig_CheckSelfSafe&0x10, NTConfig_CheckMercSafe&0x10))
{
if(!NTTMGR_VisitTown())
return 0;
}
if(firstorder && NTConfig_AttackSkill[0] > 0 && NTA_GetResistance(target, _NTA_SkillDamage[0]) < 100 && me.GetSkillStatus(NTConfig_AttackSkill[0]) != 8)
{
if(GetDistance(me, target) > _NTA_SkillRange[0] || !CheckCollision(me, target, 4))
{
var _pos = me.GetOptimalAttackPos(target.areaid, target.x, target.y, _NTA_SkillRange[0], 4);
if(_pos)
NTM_MoveTo(target.areaid, _pos[0], _pos[1], 0);
}
if(!NTC_CastSkill(NTConfig_AttackSkill[0], _NTA_SkillHand[0], target))
return 2;
return 3;
}
if(NTA_IsActBoss(target.classid) && NTConfig_CastStatic < 100 && parseInt(target.hp*100/target.hpmax) > NTConfig_CastStatic && NTA_GetResistance(target, NTA_DAMAGE_LIGHTNING) <= 80)
{
var _staticlevel = NTC_GetSkillLevel(42);
if(_staticlevel > 0)
{
var _staticrange;
var _castx, _casty;
_staticrange = Math.floor((5+_staticlevel-1)*2/3);
if(GetDistance(me, target) > _staticrange || !CheckCollision(me, target, 6))
{
var _pos = me.GetOptimalAttackPos(target.areaid, target.x, target.y, _staticrange, 6);
if(_pos)
NTM_MoveTo(target.areaid, _pos[0], _pos[1], 0);
}
if(target.x < me.x)
_castx = me.x - 1;
else if(target.x > me.x)
_castx = me.x + 1;
else
_castx = me.x;
if(target.y < me.y)
_casty = me.y - 1;
else if(target.y > me.y)
_casty = me.y + 1;
else
_casty = me.y;
if(!CheckCollision(target.areaid, _castx, _casty, 1))
{
_castx = me.x;
_casty = me.y;
}
if(!NTC_CastSkill(42, NTC_HAND_RIGHT, _castx, _casty))
return 2;
return 3;
}
}
_primaryindex = (target.spectype&0x0A) ? 1 : 3;
if(NTA_GetResistance(target, _NTA_SkillDamage[_primaryindex]) <= 90)
{
if(!NTA_SorceressCastSkillInt(_primaryindex, target))
return 2;
return 3;
}
if(NTConfig_AttackSkill[5] > 0 && NTA_GetResistance(target, _NTA_SkillDamage[5]) <= 80)
{
if(!NTA_SorceressCastSkillInt(5, target))
return 2;
return 3;
}
if(NTA_GetResistance(target, _NTA_SkillDamage[_primaryindex]) < 100 || (_primaryindex == 1 && NTC_GetMerc()))
{
if(!NTA_SorceressCastSkillInt(_primaryindex, target))
return 2;
return 3;
}
return 1;
}
function NTA_SorceressCastSkillInt(index, target)
{
if(me.GetSkillStatus(NTConfig_AttackSkill[index]) != 8)
{
if(GetDistance(me, target) > _NTA_SkillRange[index] || !CheckCollision(me, target, 4))
{
var _pos = me.GetOptimalAttackPos(target.areaid, target.x, target.y, _NTA_SkillRange[index], 4);
if(_pos)
NTM_MoveTo(target.areaid, _pos[0], _pos[1], 0);
}
return NTC_CastSkill(NTConfig_AttackSkill[index], _NTA_SkillHand[index], target);
}
if(NTConfig_AttackSkill[index+1] > 0)
{
if(NTConfig_AttackSkill[7] > 0 && (NTA_GetResistance(target, _NTA_SkillDamage[index+1]) <= 90 || NTA_GetResistance(target, _NTA_SkillDamage[7]) <= 90))
{
if(NTA_GetResistance(target, _NTA_SkillDamage[index+1]) <= 90)
{
if(GetDistance(me, target) > _NTA_SkillRange[index+1] || !CheckCollision(me, target, 4))
{
var _pos = me.GetOptimalAttackPos(target.areaid, target.x, target.y, _NTA_SkillRange[index+1], 4);
if(_pos)
NTM_MoveTo(target.areaid, _pos[0], _pos[1], 0);
}
return NTC_CastSkill(NTConfig_AttackSkill[index+1], _NTA_SkillHand[index+1], target);
}
else
{
if(GetDistance(me, target) > _NTA_SkillRange[7] || !CheckCollision(me, target, 4))
{
var _pos = me.GetOptimalAttackPos(target.areaid, target.x, target.y, _NTA_SkillRange[7], 4);
if(_pos)
NTM_MoveTo(target.areaid, _pos[0], _pos[1], 0);
}
return NTC_CastSkill(NTConfig_AttackSkill[7], _NTA_SkillHand[7], target);
}
}
else
{
if(GetDistance(me, target) > _NTA_SkillRange[index+1] || !CheckCollision(me, target, 4))
{
var _pos = me.GetOptimalAttackPos(target.areaid, target.x, target.y, _NTA_SkillRange[index+1], 4);
if(_pos)
NTM_MoveTo(target.areaid, _pos[0], _pos[1], 0);
}
return NTC_CastSkill(NTConfig_AttackSkill[index+1], _NTA_SkillHand[index+1], target);
}
}
for(var i = 0 ; i < 25 ; i++)
{
NTC_Delay(NTC_DELAY_FRAME);
if(me.GetSkillStatus(NTConfig_AttackSkill[index]) != 8)
break;
}
return false;
}
function NTA_NecromancerAttackPatternInt()
{
return false;
}
function NTA_NecromancerAttackInt(target, firstorder)
{
return 1;
}
function NTA_NecromancerCastSkillInt(index, target)
{
return false;
}
function NTA_PaladinAttackPatternInt()
{
var _maxindex, _maxskill;
var _avgskilllevel = new Array();
_avgskilllevel[0] = parseInt((me.GetSkill(112, false)+me.GetSkill(108, false)+me.GetSkill(115, false))/3);
_avgskilllevel[1] = parseInt((me.GetSkill(106, false)+me.GetSkill(96, false))/2);
_avgskilllevel[2] = parseInt((me.GetSkill(121, false)+me.GetSkill(101, false)+me.GetSkill(118, false))/3);
_maxindex = -1;
_maxskill = 0;
for(var i = 0 ; i < _avgskilllevel.length ; i++)
{
if(_avgskilllevel[i] > _maxskill)
{
_maxindex = i;
_maxskill = _avgskilllevel[i];
}
}
switch(_maxindex)
{
case 0: // Blessed Hammer
NTConfig_AttackSkill[1] = 112;
NTConfig_AttackSkill[2] = 113;
NTConfig_AttackSkill[3] = 112;
NTConfig_AttackSkill[4] = 113;
break;
case 1: // Zeal
NTConfig_AttackSkill[1] = 106;
NTConfig_AttackSkill[2] = 122;
NTConfig_AttackSkill[3] = 106;
NTConfig_AttackSkill[4] = 122;
break;
case 2: // Fist of the Heavens
NTConfig_AttackSkill[1] = 121;
NTConfig_AttackSkill[2] = 123;
NTConfig_AttackSkill[3] = 121;
NTConfig_AttackSkill[4] = 123;
break;
}
return (NTConfig_AttackSkill[1] && NTConfig_AttackSkill[3]);
}
function NTA_PaladinAttackInt(target, firstorder)
{
var _primaryindex;
if(NTTMGR_CheckCurse(NTConfig_CheckSelfSafe&0x10, NTConfig_CheckMercSafe&0x10))
{
if(!NTTMGR_VisitTown())
return 0;
}
if(firstorder && NTConfig_AttackSkill[0] > 0 && NTA_GetResistance(target, _NTA_SkillDamage[0]) < 100)
{
if(GetDistance(me, target) > _NTA_SkillRange[0] || !CheckCollision(me, target, 4))
{
var _pos = me.GetOptimalAttackPos(target.areaid, target.x, target.y, _NTA_SkillRange[0], 4);
if(_pos)
NTM_MoveTo(target.areaid, _pos[0], _pos[1], 0);
}
if(!NTC_CastSkill(NTConfig_AttackSkill[0], _NTA_SkillHand[0], target))
return 2;
return 3;
}
_primaryindex = (target.spectype&0x0A) ? 1 : 3;
if(NTA_GetResistance(target, _NTA_SkillDamage[_primaryindex]) < 100)
{
if(_NTA_SkillRange[_primaryindex] < 4 && !CheckCollision(target.areaid, target.x, target.y, 1))
return 1;
if(!NTA_PaladinCastSkillInt(_primaryindex, target))
return 2;
return 3;
}
if(NTConfig_AttackSkill[5] > 0 && NTA_GetResistance(target, _NTA_SkillDamage[5]) < 100)
{
if(_NTA_SkillRange[5] < 4 && !CheckCollision(target.areaid, target.x, target.y, 1))
return 1;
if(!NTA_PaladinCastSkillInt(5, target))
return 2;
return 3;
}
return 1;
}
function NTA_PaladinCastSkillInt(index, target)
{
if(NTConfig_AttackSkill[index] == 112)
{
if(me.x-target.x < 1 || me.x-target.x > 2 || me.y-target.y < 1 || me.y-target.y > 2)
{
if(CheckCollision(target.areaid, target.x+2, target.y+2, 1))
NTM_MoveTo(target.areaid, target.x+2, target.y+2, 0);
else if(me.x-target.x < -4 || me.x-target.x > 2 || me.y-target.y < 0 || me.y-target.y > 2)
NTM_MoveTo(target.areaid, target.x-4, target.y, 0);
}
}
else
{
if(GetDistance(me, target) > _NTA_SkillRange[index] || !CheckCollision(me, target, 4))
{
var _pos = me.GetOptimalAttackPos(target.areaid, target.x, target.y, _NTA_SkillRange[index], 4);
if(_pos)
NTM_MoveTo(target.areaid, _pos[0], _pos[1], 0);
}
}
if(NTConfig_AttackSkill[index+1] > 0)
NTC_PutSkill(NTConfig_AttackSkill[index+1], NTC_HAND_RIGHT);
return NTC_CastSkill(NTConfig_AttackSkill[index], _NTA_SkillHand[index], target);
}
function NTA_BarbarianAttackPatternInt()
{
var _maxindex, _maxskill;
var _avgskilllevel = new Array();
_avgskilllevel[0] = me.GetSkill(151, false);
_maxindex = -1;
_maxskill = 0;
for(var i = 0 ; i < _avgskilllevel.length ; i++)
{
if(_avgskilllevel[i] > _maxskill)
{
_maxindex = i;
_maxskill = _avgskilllevel[i];
}
}
switch(_maxindex)
{
case 0: // Whirlwind
NTConfig_AttackSkill[1] = 151;
NTConfig_AttackSkill[3] = 151;
NTConfig_AttackSkill[5] = 152;
break;
}
return (NTConfig_AttackSkill[1] && NTConfig_AttackSkill[3]);
}
function NTA_BarbarianAttackInt(target, firstorder)
{
var _primaryindex;
if(NTTMGR_CheckCurse(NTConfig_CheckSelfSafe&0x10, NTConfig_CheckMercSafe&0x10))
{
if(!NTTMGR_VisitTown())
return 0;
}
if(firstorder && NTConfig_AttackSkill[0] > 0 && NTA_GetResistance(target, _NTA_SkillDamage[0]) < 100)
{
if(GetDistance(me, target) > _NTA_SkillRange[0] || !CheckCollision(me, target, 4))
{
var _pos = me.GetOptimalAttackPos(target.areaid, target.x, target.y, _NTA_SkillRange[0], 4);
if(_pos)
NTM_MoveTo(target.areaid, _pos[0], _pos[1], 0);
}
if(!NTC_CastSkill(NTConfig_AttackSkill[0], _NTA_SkillHand[0], target))
return 2;
return 3;
}
_primaryindex = (target.spectype&0x0A) ? 1 : 3;
if(NTA_GetResistance(target, _NTA_SkillDamage[_primaryindex]) < 100)
{
if((_NTA_SkillRange[_primaryindex] < 4 || NTConfig_AttackSkill[_primaryindex] == 151) && !CheckCollision(target.areaid, target.x, target.y, 1))
return 1;
if(!NTA_BarbarianCastSkillInt(_primaryindex, target))
return 2;
return 3;
}
if(NTConfig_AttackSkill[5] > 0 && NTA_GetResistance(target, _NTA_SkillDamage[5]) < 100)
{
if((_NTA_SkillRange[5] < 4 || NTConfig_AttackSkill[5] == 151) && !CheckCollision(target.areaid, target.x, target.y, 1))
return 1;
if(!NTA_BarbarianCastSkillInt(5, target))
return 2;
return 3;
}
return 1;
}
function NTA_BarbarianCastSkillInt(index, target)
{
if(NTConfig_AttackSkill[index] == 151)
{
var _castx, _casty;
if(GetDistance(me, target) > _NTA_SkillRange[index] || !CheckCollision(me, target, 5))
{
var _pos = me.GetOptimalAttackPos(target.areaid, target.x, target.y, _NTA_SkillRange[index], 5);
if(_pos)
NTM_MoveTo(target.areaid, _pos[0], _pos[1], 0);
}
_castx = target.x > me.x ? target.x+3 : target.x-3;
_casty = target.y > me.y ? target.y+3 : target.y-3;
return NTC_CastSkill(NTConfig_AttackSkill[index], _NTA_SkillHand[index], _castx, _casty);
}
if(GetDistance(me, target) > _NTA_SkillRange[index] || !CheckCollision(me, target, 4))
{
var _pos = me.GetOptimalAttackPos(target.areaid, target.x, target.y, _NTA_SkillRange[index], 4);
if(_pos)
NTM_MoveTo(target.areaid, _pos[0], _pos[1], 0);
}
return NTC_CastSkill(NTConfig_AttackSkill[index], _NTA_SkillHand[index], target);
}
function NTA_DruidAttackPatternInt()
{
return false;
}
function NTA_DruidAttackInt(target, firstorder)
{
return 1;
}
function NTA_DruidCastSkillInt(index, target)
{
return false;
}
function NTA_AssassinAttackPatternInt()
{
return false;
}
function NTA_AssassinAttackInt(target, firstorder)
{
return 1;
}
function NTA_AssassinCastSkillInt(index, target)
{
return false;
}
function NTA_IsActBoss(classid)
{
switch(classid)
{
case 156: //Andariel
case 211: //Duriel
case 242: //Mephisto
case 243: //Diablo
case 544: //Baal
return true;
}
return false;
}
function NTA_FindItem(range)
{
var _corpse;
var _orgx;
var _orgy;
var _startTick;
var _reposition = false;
if(NTC_GetSkillLevel(142) < 1)
return false;
if(arguments.length < 1 || !range)
range = 25;
_corpse = NTC_FindUnit(NTC_UNIT_MONSTER);
_orgx = me.x;
_orgy = me.y;
NTC_PingDelay(100);
NTC_SwapWeapons(2);
if(_corpse)
{
do
{
if(GetDistance(_orgx, _orgy, _corpse.x, _corpse.y) <= range && (_corpse.hp <= 0 || _corpse.mode == 0 || _corpse.mode == 12) && _corpse.GetState(118) == 0 && NTA_IsLootable(_corpse.classid))
{
if(GetDistance(me.x, me.y, _corpse.x, _corpse.y) >= 8)
{
if(!NTM_MoveTo(me.areaid, _corpse.x, _corpse.y))
continue;
}
_startTick = GetTickCount();
while(_corpse.GetState(118) != 0x400000 && (_corpse.hp <= 0 || _corpse.mode == 0 || _corpse.mode == 12) && !_corpse.IsAttackable())
{
NTC_CastSkill(142, NTC_HAND_RIGHT, _corpse);
NTC_PingDelay(50);
if(GetTickCount() >= _startTick + 1000 && !_reposition) // repositioning after 1sec
{
_reposition = true;
if(!NTM_MoveTo(me.areaid, _corpse.x+1, _corpse.y+1))
break;
}
if(GetTickCount() >= _startTick + 2500) // skipping monster after 2.5sec
{
var filehandle = FileOpen("FailedtoLoot.txt", 2);
var dateString = new Date().toLocaleFormat("%a %m/%d/%y %H:%M:%S");
if(filehandle)
{
filehandle.WriteLine("[" + dateString + "] Could not loot: " + _corpse.name +" [" + _corpse.classid + "](Location: " + me.areaid + ")");
filehandle.Close();
}
Print("ÿc;Could not loot: " + _corpse.name +" [" + _corpse.classid + "](Location: " + me.areaid + ")");
break;
}
}
}
} while(_corpse.GetNext());
NTC_PingDelay(100);
NTC_SwapWeapons(0);
NTC_PingDelay(100);
NTSI_PickItems();
return true;
}
return false;
}
function NTA_IsLootable(classid)
{
switch(classid)
{
case 151: // An evil force
case 156: // Andariel
case 180: // Sand Maggot Young
case 181: // Rock Worm Young
case 182: // Devourer Young
case 183: // Giant Lamprey Young
case 184: // World Killer Young
case 190: // Sand Maggot Egg
case 191: // Rock Worm Egg
case 192: // Devourer Egg
case 193: // Giant Lamprey Egg
case 194: // World Killer Egg
case 206: // Fould Crow Nest
case 207: // Blood Hawk Nest
case 208: // Black Vulture Nest
case 209: // Cloud Stalker Nest
case 221: // Duriel
case 227: // Maggot
case 228: // Mummy Generator
case 234: // Flying Scimitar
case 242: // Mephisto
case 243: // Diablo
case 250: // Summoner
case 258: // Water Watcher Limb
case 259: // River Stalker Limb
case 260: // Sygain Watcher Limb
case 261: // Water Watcher Head
case 262: // River Stalker Head
case 263: // Sygain Watcher Head
case 267: // Blood Raven
case 269: // An evil force
case 270: // Rogue Scout (== Merc)
case 273: // Gargoyle Trap
case 289: // Clay Golem
case 290: // Blood Golem
case 291: // Iron Golem
case 292: // Fire Golem
case 301: // Flesh Beast
case 302: // Stygian Dog
case 303: // Grotesque Wyrm
case 326: // A Trap
case 327: // A Trap
case 328: // A Trap
case 329: // A Trap
case 330: // A Trap
case 334: // Sucker Nest
case 335: // Fleeder Nest
case 336: // Blood Hook Nest
case 337: // Blood Wing Nest
case 338: // Act 2 guard (== Merc)
case 348: // Turret
case 349: // Turret
case 350: // Turret
case 351: // Hydra
case 352: // Hydra
case 353: // Hydra
case 354: // A Trap
case 356: // Dopplezon
case 357: // Valkyrie
case 359: // Iron Wolf (== Merc)
case 366: // Compelling Orb
case 369: // A Trap
case 371: // Lightning Spire
case 372: // Fire Tower
case 403: // Traped Soul
case 404: // Traped Soul
case 406: // Izual
// ----------------
case 410: // Wake Of Destruction
case 411: // Charged Bolt Sentry
case 412: // Lightning Sentry
case 413: // Blade Creeper
case 414: // Invisible Pet
case 415: // Inferno Sentry
case 416: // Death Sentry
case 417: // Shadow Warrior
case 418: // Shadow Master
case 419: // Druid Hawk
case 420: // Druid Spirit Wolf
case 421: // Druid Fenris
case 422: // Spirit of Barbs
case 423: // Heart Of Wolverine
case 424: // Oak Sage
case 425: // Druid Plague Poppy
case 426: // Druid Cycle of Life
case 427: // Vine Creature
case 428: // Druid Bear
case 429: // Eagle
case 430: // Wolf
case 431: // Bear
case 432: // Barricaded Door
case 433: // Barricaded Door
case 434: // Prison Door
case 435: // Barricaded Door
case 461: // Fanatic Minion
case 462: // Beserk Slayer
case 463: // Consumed Fire Boar
case 464: // Consumed Ice Boar
case 465: // Frenzied Hell Spawn
case 466: // Frenzied Hell Spawn
case 467: // Insane Hell Spawn
case 468: // Insane Ice Spawn
case 497: // Catapult
case 498: // Catapult
case 499: // Catapult
case 500: // Catapult
case 501: // Frozen Horror 1
case 502: // Frozen Horror 2
case 503: // Frozen Horror 3
case 504: // Frozen Horror 4
case 505: // Frozen Horror 5
case 516: // Catapult
case 517: // Catapult
case 518: // Catapult
case 519: // Catapult
case 522: // Barbarian Fighter
case 523: // Barbarian Fighter
case 524: // Barricade Wall Right
case 525: // Barricade Wall Left
case 526: // Nihlatak
case 528: // Evil Hut
case 535: // Barbarian Fighter
case 536: // Barbarian Fighter
case 537: // Ancient Statue 1
case 538: // Ancient Statue 2
case 539: // Ancient Statue 3
case 540: // Ancient Barbarian 1
case 541: // Ancient Barbarian 2
case 542: // Ancient Barbarian 3
case 543: // Baal Throne
case 544: // Baal Crab
case 545: // Baal Taunt
case 551: // Pain Worm
case 552: // Pain Worm
case 553: // Pain Worm
case 554: // Pain Worm
case 555: // Pain Worm
case 556: // Bunny
case 559: // Baal Crab to Stairs
case 560: // Hireling
case 561: // Hireling
case 562: // Baal Tentacle
case 563: // Baal Tentacle
case 564: // Baal Tentacle
case 565: // Baal Tentacle
case 566: // Baal Tentacle
case 567: // Injured Barbarian
case 568: // Injured Barbarian
case 569: // Injured Barbarian
case 570: // Baal Crab Clone
case 571: // Baals Minions
case 572: // Baals Minionse
case 573: // Baals Minions
case 574: // Worldstone Effect
return false;
break;
default:
return true;
break;
}
}
/*
function NTA_OpenChests()
{
var _orgx;
var _orgy;
var _chest;
if(!NTA_AreaCheckChests(me.areaid))
return false;
_orgx = me.x;
_orgy = me.y;
_chest = NTC_FindUnit(NTC_UNIT_OBJECT);
if(_chest)
{
do
{
if(_chest.mode == 0 && GetDistance(_orgx, _orgy, _chest.x, _chest.y) < 20 && NTA_IsLootableChest(_chest.classid) && !(_chest.classid == 371 && _chest.areaid == 25) && _chest.name.toLowerCase() != "an evil force")
{
NTC_PingDelay(100);
//Print("ÿc2Opening: " + _chest.name + " [" + _chest.classid + "]");
if(!NTC_OpenChest(_chest))
{
Print("ÿc1Could not open: Object (" + _chest.x + "|" + _chest.y + "): " + _chest.name + " [ClassID: " + _chest.classid + ", Mode: " + _chest.mode + "]");
var filehandle = FileOpen("FailedToOpenChest.txt", 2);
var dateString = new Date().toLocaleFormat("%a %m/%d/%y %H:%M:%S");
if(filehandle)
{
filehandle.WriteLine("[" + dateString + "] Failed to open " + _chest.name +" [" + _chest.classid + "] ... Mode|Area: " + _chest.mode + "|" + me.areaid);
filehandle.Close();
}
}
}
} while(_chest.GetNext());
NTSI_PickItems();
return true;
}
return false;
}
function NTA_IsLootableChest(classid)
{
switch(classid)
{
case 1: // Casket
case 3: // Casket
case 4: // Large Urn
case 5: // Chest
case 6: // Chest
case 7: // Barrel
case 8:
case 9: // Urn
case 28: // Undefiled Grave
case 46:
case 50:
case 51: // Casket
case 52: // Urn
case 53: // Casket
case 54: // Dead Rogue
case 55: // Dead Rogue
case 56: // Dead Rogue
case 57: // Dead Rogue
case 58: // Dead Rogue
case 79: // Casket
case 84:
case 85:
case 87: // Chest
case 88: // Chest
case 89:
case 94: // Large Urn
case 95: // Large Urn
case 96:
case 104:
case 105: // Armor Stand
case 106: // Weapon Rack
case 107: // Weapon Rack
case 109:
case 111:
case 113:
case 115:
case 118:
case 120:
case 139: // Chest
case 140: // Chest
case 141: // Chest
case 141:
case 142: // Jug
case 143: // Jug
case 144: // Chest
case 146: // Chest
case 147: // Chest
case 148: // Chest
case 154: // Corpse
case 155: // Hidden Stash
case 158:
case 164:
case 166:
case 167:
case 168:
case 170:
case 171: // Skeleton
case 173:
case 174: // Loose Rock
case 175: // Loose Boulder
case 176:
case 177:
case 178: // Guard Corpse
case 181: // Chest
case 182:
case 183: // Chest
case 185: // Stash
case 186: // Stash
case 198:
case 203: // Stash
case 204: // Stash
case 205: // Stash
case 208: // Basket
case 209: // Basket
case 223:
case 224:
case 225: // Skullpile
case 239: // Body
case 240: // Chest
case 241: // Chest
case 242: // Chest
case 243:
case 244: // Rat's Nest
case 247: // Bed
case 266: // Goo Pile
case 270: // Corpse
case 271: // Corpse
case 329: // Chest
case 330: // Chest
case 331:
case 332: // Chest
case 333:
case 334:
case 335:
case 336:
case 360:
case 362:
case 363:
case 365:
case 371:
case 372:
case 389:
case 390:
case 391:
case 397: // (Super) Chest
case 405: // (Super) Chest
case 413:
case 416:
case 418: // Barrel
case 419: // Barrel
case 420: // Wooden Chest
case 424: // Burial Chest
case 425:
case 430: // Chest
case 431:
case 432:
case 433:
case 443: // Jar
case 444: // Jar
case 445: // Jar
case 455:
case 463:
//case 466: // Evil Urn
case 467:
case 468:
case 469:
case 470:
case 471:
case 477: // Dead Barbarian
case 501:
case 502:
case 504:
case 505:
case 548:
case 549:
case 550:
case 551:
return true;
break;
default:
return false;
break;
}
}
*/
function NTA_CheckForCloseMonsters(range)
{
if(range < 1 || arguments.length < 1)
return false;
var _monstersClose = false;
var _checkMonster = NTC_FindUnit(NTC_UNIT_MONSTER);
if(_checkMonster)
{
do
{
if(_checkMonster.IsAttackable() && GetDistance(me.x, me.y, _checkMonster.x, _checkMonster.y) < range && NTA_IsValidMonster(_checkMonster))
{
//Print("ÿc1Close Monster detected: " + _checkMonster.name);
_monstersClose = true;
break;
}
} while(_checkMonster.GetNext());
}
return _monstersClose;
}
/*
function NTA_AreaCheckChests(areaid)
{
var exeptionsArray = new Array();
exeptionsArray.push(25); // Tower Cellar Level 5
for(var i = 0; i < exeptionsArray.length; i++)
{
if(areaid == exeptionsArray[i])
return false;
}
return true;
}
*/
Ausserdem müssen folgende Variablen global in der NTConfig.ntl deklariert und in der jeweiligen Charconfig initialisiert werden.
Beispielsweise so:
Was ich dafür haben möchte?
In erster Linie Rückmeldungen, um das Ganze auf anständiges release Niveau zu bekommen und es weiter zu verbessern. Interessant wären dazu beispielsweise classids von ungültigen bzw. nicht lootbaren Monstern welche bisher noch nicht in ignoriert werden.
Aber auch andere eventuell auftretenden Fehler oder Probleme würden mich interessieren. Natürlich auch ganz einfach Meinungen dazu.
Also, wer schon immer mal einen Gold- oder Mf-barb Bot haben wollte und ein bisschen Ahnung mitbringt und das ohne weitere Hinweise implementieren kann ist hiermit aufgefordert es zu testen und mir hinterher eine Rückmeldung zu geben.
Ich freue mich auf Rückmeldungen und wünsche viel Spaß beim Testen!
Dann mal schnell nen barb hochziehn und testen (: danke schonmal! das ist genau das was ich immer wollte
Mir gefällt das Konzept auch extrem gut, da es gerade für solo games perfekt geeignet ist. Hab gestern erstmal einen zweiten Barb nachgelegt, zwei machen sich schließlich besser als einer.
Bin am basteln und ka was ich machen soll um auf die 37 fcr zu kommen ?
arach + krönchen( statt ner lemed krone der diebe ) / arach + 2 ringe (statt 2 von den zwegensternen 9 oder arach + to ( statt 40er cg )
Ich tendiere zum ersteren. Bzw wie hast du deinen barb equipt dafür ?
Meine Barbs sehen derzeit beide etwa so aus:
LEMed Arreats
17+fcr Amu
2xDwarf
Eni Mp
CHAMed Storm
BotD Ba
Arach
Chance Guards
Rare Boots mit eg
2xLEMed Cs für den 2. Slot
Man muss hier definitiv Kompromisse finden, aber ich bin so ganz zufrieden.
Vom Killspeed her eher langsam, aber das ist mir ehrlich gesagt ziemlich egal, solange sie robust sind und nicht sterben.
Achja, die Mercs nutzen übrigens Insights, um den Mana Verbrauch zu decken.
Man könnte vielleicht auch zum Reaper's greifen, aber ich befürchte dann gäbe es starke Mana Probleme.
Mit diesem Equipment mache ich derzeit Pit, Travi und Nihla, was relativ gut funktioniert.
Die 37fcr sind natürlich kein Muss, damit der Char überhaupt läuft, ich lege es nur nahe, da Find Item mit weniger fcr wirklich extrem langsam ist.
Habs jetzt endlich geschaft mir nen barb auf 80 zu spielen und den einzischalten.
Was mir aufgefallen ist.
Sobald ne leiche zerplatzt kommt die fehlermeldung mit dem looten.
+ ne wizzi auf 2. slot oder gar 2 wizzis dürften das looten nochmal erheblich beschleunigen (: und manaprobs sind dann auch nemmer.
werd mir nu noch nen gescheiten goldbarb hochspielen und weitertesten (:
Habs jetzt endlich geschaft mir nen barb auf 80 zu spielen und den einzischalten.
Was mir aufgefallen ist.
Sobald ne leiche zerplatzt kommt die fehlermeldung mit dem looten.
+ ne wizzi auf 2. slot oder gar 2 wizzis dürften das looten nochmal erheblich beschleunigen (: und manaprobs sind dann auch nemmer.
werd mir nu noch nen gescheiten goldbarb hochspielen und weitertesten (:
Klingt gut.
Das mit den Leichen ist bei meiner aktuellen Version schon nicht mehr drin, muss ich bei Zeiten mal updaten, aber nicht jetzt, habe im Moment keinen Nerv irgendwas rauszusuchen, kommt aber die Tage denke ich.
wenn ja könntest du mal das was neu is (was ich brauch) und wo hin das muss erklären damit ich das in meine modefizirten datein packen kann!?
Sollte an sich auch in 3.1 laufen, ja.
Ich würde noch etwas warten, da ich heute noch ein bisschen was ändern wollte. Ich werde das dann auch in ein anderes Script verpacken, denn an sich haben die Funktionen selbst nichts in der NTAttack.ntj verloren, lässt sich aber "vor Ort" leichter schreiben.
Das ist leider wieder eine elende Testerei, da die Referenz fehlt.
Ich schaue mal wie ich voran komme, ich hoffe das klappt bis heute Abend.
So, also so ganz hat das nicht geklappt, dafür habe ich mein Script aber noch weiter verbessert und konnte sogar einen kleineren Fehler rausnehmen. Das generelle Problem was ich habe, ist, dass bei mir alles immer mehr und mehr ineinander greift, was es extrem schwer macht, einzelne Teile zu isolieren.
Bei mir sieht das dann beispielsweise so aus:
Für diesen Tooltip werden natürlich auch Daten in der Find Item Funktion gesammelt. Eine umfassende Version mag ich aber noch nicht veröffentlichen, dazu läuft es mir noch nicht Rund genug.
Ich versuche trotzdem mal, nur die Find Item Funktion und die ausserdem dafür notwendigen Funktionen zu posten.
Code:
function NTA_FindItem(range)
{
var _corpse;
var _orgx;
var _orgy;
var _startTick;
var _reposition = false;
if(me.classid != NTC_CHAR_CLASS_BARBARIAN || NTC_GetSkillLevel(142) < 1)
return false;
if(arguments.length < 1 || !range)
range = 25;
_corpse = NTC_FindUnit(NTC_UNIT_MONSTER);
_orgx = me.x;
_orgy = me.y;
NTC_PingDelay(100);
NTC_SwapWeapons(2);
if(_corpse)
{
do
{
if(GetDistance(_orgx, _orgy, _corpse.x, _corpse.y) <= range && NTA_CheckLootStatus(_corpse) && NTA_IsLootable(_corpse.classid))
{
if(GetDistance(me.x, me.y, _corpse.x, _corpse.y) >= 8)
{
if(!NTM_MoveTo(me.areaid, _corpse.x, _corpse.y))
continue;
}
_startTick = GetTickCount();
_reposition = false;
while(NTA_CheckLootStatus(_corpse) && !_corpse.IsAttackable())
{
NTC_CastSkill(142, NTC_HAND_RIGHT, _corpse);
NTC_PingDelay(50);
if(GetTickCount() >= _startTick + 1000 && !_reposition) // repositioning after 1sec
{
_reposition = true;
if(!NTM_MoveTo(me.areaid, _corpse.x, _corpse.y))
break;
}
if(GetTickCount() >= _startTick + 2500) // skipping monster after 2.5sec
{
if(me.mp < 10)
{
Print("Lack of ÿc3Manaÿc0!");
if(NTConfig_BuyPotsIfLackOfMana)
{
if(NTTMGR_VisitTown())
NTC_SwapWeapons(2);
}
break;
}
var _filehandle = FileOpen("FailedtoLoot.txt", 2);
var _dateString = new Date().toLocaleFormat("%a %m/%d/%y %H:%M:%S");
if(_filehandle)
{
var _states = "States:: ";
for(var i = 0; i < 144; i++)
{
if(_corpse.GetState(i))
_states += "State(" + i + "): " + _corpse.GetState(i) + "<--> ";
}
_filehandle.WriteLine("[" + _dateString + "] Could not loot: " + _corpse.name +" [" + _corpse.classid + "] (Location: " + me.areaid + ") " + _states);
_filehandle.Close();
}
Print("ÿc;Could not loot: " + _corpse.name +" [" + _corpse.classid + "] <Mode: " + _corpse.mode + "> (Location: " + me.areaid + ")");
break;
}
}
/*if(GetTickCount() < _startTick + 2000)
NTC_SendMsgToScript("NTBotGame.ntj", "SET_LOOTED_NULL");*/
}
} while(_corpse.GetNext());
NTC_SwapWeapons(0);
NTC_PingDelay(100);
NTSI_PickItems();
return true;
}
return false;
}
function NTA_CheckForCloseMonsters(range)
{
if(range < 1 || arguments.length < 1)
return false;
var _monstersClose = false;
var _checkMonster = NTC_FindUnit(NTC_UNIT_MONSTER);
if(_checkMonster)
{
do
{
if(_checkMonster.IsAttackable() && GetDistance(me.x, me.y, _checkMonster.x, _checkMonster.y) < range && NTA_IsValidMonster(_checkMonster))
{
_monstersClose = true;
break;
}
} while(_checkMonster.GetNext());
}
return _monstersClose;
}
function NTA_CheckLootStatus(monsterunit)
{
if(!monsterunit.GetState(107) // Shattered
&& !monsterunit.GetState(104) // Corpse Explosion
&& !monsterunit.GetState(118) // Already Looted/Unlootable
&& (monsterunit.hp <= 0 || monsterunit.mode == 0 || monsterunit.mode == 12)) // Dead
return true;
else
return false;
}
function NTA_IsLootable(classid)
{
switch(classid)
{
case 151: // An evil force
case 156: // Andariel
case 180: // Sand Maggot Young
case 181: // Rock Worm Young
case 182: // Devourer Young
case 183: // Giant Lamprey Young
case 184: // World Killer Young
case 190: // Sand Maggot Egg
case 191: // Rock Worm Egg
case 192: // Devourer Egg
case 193: // Giant Lamprey Egg
case 194: // World Killer Egg
case 206: // Fould Crow Nest
case 207: // Blood Hawk Nest
case 208: // Black Vulture Nest
case 209: // Cloud Stalker Nest
case 221: // Duriel
case 227: // Maggot
case 228: // Mummy Generator
case 234: // Flying Scimitar
case 242: // Mephisto
case 243: // Diablo
case 250: // Summoner
case 258: // Water Watcher Limb
case 259: // River Stalker Limb
case 260: // Sygain Watcher Limb
case 261: // Water Watcher Head
case 262: // River Stalker Head
case 263: // Sygain Watcher Head
case 267: // Blood Raven
case 269: // An evil force
case 270: // Rogue Scout (== Merc)
case 273: // Gargoyle Trap
case 289: // Clay Golem
case 290: // Blood Golem
case 291: // Iron Golem
case 292: // Fire Golem
case 301: // Flesh Beast
case 302: // Stygian Dog
case 303: // Grotesque Wyrm
case 318: // An Evil Force
case 326: // A Trap
case 327: // A Trap
case 328: // A Trap
case 329: // A Trap
case 330: // A Trap
case 334: // Sucker Nest
case 335: // Fleeder Nest
case 336: // Blood Hook Nest
case 337: // Blood Wing Nest
case 338: // Act 2 guard (== Merc)
case 348: // Turret
case 349: // Turret
case 350: // Turret
case 351: // Hydra
case 352: // Hydra
case 353: // Hydra
case 354: // A Trap
case 356: // Dopplezon
case 357: // Valkyrie
case 359: // Iron Wolf (== Merc)
case 366: // Compelling Orb
case 369: // A Trap
case 371: // Lightning Spire
case 372: // Fire Tower
case 403: // Traped Soul
case 404: // Traped Soul
case 406: // Izual
case 410: // Wake Of Destruction
case 411: // Charged Bolt Sentry
case 412: // Lightning Sentry
case 413: // Blade Creeper
case 414: // Invisible Pet
case 415: // Inferno Sentry
case 416: // Death Sentry
case 417: // Shadow Warrior
case 418: // Shadow Master
case 419: // Druid Hawk
case 420: // Druid Spirit Wolf
case 421: // Druid Fenris
case 422: // Spirit of Barbs
case 423: // Heart Of Wolverine
case 424: // Oak Sage
case 425: // Druid Plague Poppy
case 426: // Druid Cycle of Life
case 427: // Vine Creature
case 428: // Druid Bear
case 429: // Eagle
case 430: // Wolf
case 431: // Bear
case 432: // Barricaded Door
case 433: // Barricaded Door
case 434: // Prison Door
case 435: // Barricaded Door
case 461: // Fanatic Minion
case 462: // Beserk Slayer
case 463: // Consumed Fire Boar
case 464: // Consumed Ice Boar
case 465: // Frenzied Hell Spawn
case 466: // Frenzied Hell Spawn
case 467: // Insane Hell Spawn
case 468: // Insane Ice Spawn
case 497: // Catapult
case 498: // Catapult
case 499: // Catapult
case 500: // Catapult
case 501: // Frozen Horror 1
case 502: // Frozen Horror 2
case 503: // Frozen Horror 3
case 504: // Frozen Horror 4
case 505: // Frozen Horror 5
case 516: // Catapult
case 517: // Catapult
case 518: // Catapult
case 519: // Catapult
case 522: // Barbarian Fighter
case 523: // Barbarian Fighter
case 524: // Barricade Wall Right
case 525: // Barricade Wall Left
case 526: // Nihlatak
case 528: // Evil Hut
case 535: // Barbarian Fighter
case 536: // Barbarian Fighter
case 537: // Ancient Statue 1
case 538: // Ancient Statue 2
case 539: // Ancient Statue 3
case 540: // Ancient Barbarian 1
case 541: // Ancient Barbarian 2
case 542: // Ancient Barbarian 3
case 543: // Baal Throne
case 544: // Baal Crab
case 545: // Baal Taunt
case 551: // Pain Worm
case 552: // Pain Worm
case 553: // Pain Worm
case 554: // Pain Worm
case 555: // Pain Worm
case 556: // Bunny
case 559: // Baal Crab to Stairs
case 560: // Hireling
case 561: // Hireling
case 562: // Baal Tentacle
case 563: // Baal Tentacle
case 564: // Baal Tentacle
case 565: // Baal Tentacle
case 566: // Baal Tentacle
case 567: // Injured Barbarian
case 568: // Injured Barbarian
case 569: // Injured Barbarian
case 570: // Baal Crab Clone
case 571: // Baals Minions
case 572: // Baals Minionse
case 573: // Baals Minions
case 574: // Worldstone Effect
case 662: // Flayer Shaman
return false;
break;
default:
return true;
break;
}
}
Die Einbindung in die Üblichen Funktionen NTA_ClearPosition() und NTA_ClearLevel() kannst du dem Startpost entnehmen, da müsste sich nicht viel geändert haben. Ist wenig elegant, werde ich ändern, wenn ich wieder Zeit habe, was heute nicht mehr der Fall ist.
Auf jeden Fall auch noch ein
Code:
NTC_SwapWeapons(0);
am Anfang der NTTMGR_TownManager() einfügen, um sicherzustellen, dass vor jedem Script, der Waffenslot ausgewählt wird.
Du kannst natürlich auch noch entsprechende Aufrufe der NTA_FindItem() Funktion in deine Bot Script einfügen, als Parameter wird dabei ein Integer Wert als "Radius" erwartet, lässt du diesen weg, wird defaultmäßig 25 angesetzt.
Dies ist die Initialsierung der nötigen Config Variablen:
Code:
NTConfig_UseFindItem = true; // Loot corpses of slain Monsters when clearing positions or areas
NTConfig_BuyPotsIfLackOfMana = true; // Visit Town if your char lacks mana while trying to loot a corpse
NTConfig_FindItemRange = 40; // Default range to check for corpses to loot when clearing positions or areas
Diese müssen natürlich vorher noch in der NTConfig.ntl deklariert werden.
Das müsste es an sich sein, damit sollte es gehen. Ich muss mal schauen wann ich dazu komme eine geordnete und rund laufende Gesamtversion zu posten, denn einzelne Teile zu isolieren ist für mich aufwändiger und ausserdem auch fehleranfälliger, weil beim Zurechtschieben wieder Fehler passieren können. Ich hoffe die Erklärung reicht dir, das ganze richtet sich weiterhin erstmal nur an Leute, die halbwegs wissen was sie tun.
Habs bei mir ja schon ne Weile laufen und bin insgesamt zufrieden damit - er lootet zwar schon mal während noch Horden rumschlappen, aber zum einen hat er massig Life und zum andern haut die der Sölli um - von daher alles Paletti. Steht nun auch kurz vor lvl 92, da kann ich auch net meckern
Habs bei mir ja schon ne Weile laufen und bin insgesamt zufrieden damit - er lootet zwar schon mal während noch Horden rumschlappen, aber zum einen hat er massig Life und zum andern haut die der Sölli um - von daher alles Paletti. Steht nun auch kurz vor lvl 92, da kann ich auch net meckern
Die Einbindung ist in der Tat etwas stümperhaft, stammt noch aus der Zeit, wo ich das Grundscript geschrieben habe. Das ganze sollte ich mal überarbeiten...
Ansonsten ist die Find Item Funktion jetzt aber auf einem Niveau, das mir schon durchaus gefällt. Die meisten Monster die nicht lootbar sind werden korrekt ausgelassen, ich habe an sich nurnoch Ausfälle, wenn die leichen ungünstig liegen, was aber auch völlig ok ist, denn das sind villeicht 2-3 Leichen pro Spiel, wobei das schon übertrieben ist, bei einer Summe von ~150 Leichen pro Spiel.
Durch die Überprüfung auf zu wenig Mana kann man jetzt sogar einen Reapers Merc Spielen, bei Engpässen gehts dann eben in die Stadt um ein paar Tränke nachzulegen.
Ich denke ich werde mal die Einbindung verbessern und dann gibst demnächst mal eine finale Version.
Quote:
Originally Posted by toya_ger
also ies funktioniert nur wenn ich NTA_FindItem() einbaue bei NTA_ClearPosition()
ich gehe doch richtig in der an name das der befehl (range) das in ClearPosition einbindet
halt das er wenn case1 range kommt sollte er das machen ?
Ohne dir zu nahe treten zu wollen, ich bin relativ phantasielos und kann mir schlecht Sachverhalte zusammenreimen, weil deren Beschreibung schlecht überschaubar oder ungenügend ist. Darum bitte etwaige Fragen so formulieren, dass diese auch sprachlich halbwegs verständlich sind.
Also es funtionir ohne probleme wenn ich in das script z.B travi NTA_FindItem() einbaue
bei NTA_ClearPosition() geht es nicht.
meine frage ist es richt das function function NTA_FindItem(range) das (range) in der klammer
es and die stelle (rot) einfügen soll?
Code:
function NTA_ClearPosition(range, pickitem, safelevel)
{
var _orgx, _orgy;
var _spectype = [0x0A, 0x01, 0x01];
var _skiplist;
var _attackcount = 0;
var _target;
var _distance, _mingid, _mindistance;
var _result;
if(NTConfig_AttackSkill[1] < 1 || NTConfig_AttackSkill[3] < 1)
return false;
switch(arguments.length)
{
case 0:
[COLOR="Red"]range = 20;[/COLOR]
case 1:
pickitem = false;
case 2:
safelevel = 0;
default:
wenn ja funkt das irgenwie bei mir nicht!
sry für den ersten post der is ja wirklich schlimm xD da wuste ich nicht mal genau mehr was jetzt der fehler war.
Also es funtionir ohne probleme wenn ich in das script z.B travi NTA_FindItem() einbaue
bei NTA_ClearPosition() geht es nicht.
meine frage ist es richt das function function NTA_FindItem(range) das (range) in der klammer
es and die stelle (rot) einfügen soll?
Code:
function NTA_ClearPosition(range, pickitem, safelevel)
{
var _orgx, _orgy;
var _spectype = [0x0A, 0x01, 0x01];
var _skiplist;
var _attackcount = 0;
var _target;
var _distance, _mingid, _mindistance;
var _result;
if(NTConfig_AttackSkill[1] < 1 || NTConfig_AttackSkill[3] < 1)
return false;
switch(arguments.length)
{
case 0:
[COLOR=Red]range = 20;[/COLOR]
case 1:
pickitem = false;
case 2:
safelevel = 0;
default:
wenn ja funkt das irgenwie bei mir nicht!
sry für den ersten post der is ja wirklich schlimm xD da wuste ich nicht mal genau mehr was jetzt der fehler war.
Also sooo viel besser ist das jetzt auch nicht, vielleicht mal ne runde Korrekturlesen vorm Abschicken.
Anyway, ich glaube jedenfalls, diesmal das grundsätzliche Problem verstanden zu haben (...und damit sind jetzt nicht deine Tippfähigkeiten gemeint ) .
Allerdings hat die range Variable die du dort nennst, rein gar nichts mit meiner FindItem() Funktion zu tun, ist ja auch relativ leicht ersichtlich, dass diese Variable Formalparameter der NTA_ClearPosition() Funktion ist.
Siehe hier:
Code:
NTA_ClearPosition([COLOR=Red]range, pickitem, safelevel[/COLOR]) // Einmal die Formalparameter in rot ;)
Für meine Funktion ist an sich nur dieser Teil hier interessant, welcher die FindItem() Funktion aufruft, sofern die Config passt, dein Char ein Barb ist, eine gewisse Anzahl von Monster getötet wurde (man beachte hierbei die Analogie zu dem Redemption Part direkt darüber) und keine Monster in direkter Nähe sind.
Die beiden Configvariablen NTConfig_UseFindItem und NTConfig_FindItemRange sollten natürlich vorher korrekt Deklariert und Initialisiert worden sein, auf jeden Fall die erstere, ansonsten wird die der logische Ausdruck in der if-Bedingung nämlich direkt false und das Ganze kann gar nicht gehen.
Wenn das alles korrekt gemacht wurde, sollte das grundsätzlich problemlos funktionieren, von den Kinderkrankheiten meiner Funktion mal abgesehen.
d2nt Item log 06/15/2010 - Diablo 2 - 3 Replies Wenn mein Bot grüne ringe aufhebt dann zeigt er es im Item Log an genauso auch wo er es gefunden hat....
Hab das damals so geändert aber weiss jetzt nicht mehr wie ich das rückgängig machen kann! Kann mir da jemand bitte helfen?
@ Kal_El ich hab wirklich schon lange hier gesucht und hab es nicht gefunden =)
goldbarb mit d2nt 3.1? 04/25/2010 - Diablo 2 - 7 Replies hi
hab da glaub ich die tage auchma nen post zu gesehn, konnt ihn aber mit der sufu nicht finden...
brauch man da unbedingt nen eni, oder könnte der travi auch mit ww oder sowas killn?
und geht das mim lootskill und dafür slot wechseln?
wär cool wenn da kurz wer ne antwort weiß, oder ne ahnung hat wie das Thema hieß, wo darüber disskutiert wurde
I need Bot Find item can?? 06/26/2009 - Ragnarok Online - 1 Replies someone can help me??
give me bOt can hunt item...
i wan make quest so hard...
Send me at [email protected]
i hope u is kind man :rolleyes:
how to find ID of a item 05/30/2008 - Conquer Online 2 - 4 Replies I know how to find ID of an item but how do i find an ID of an item in inventory? is there something that can tell me the ID of the moonbox in my inventory? beacuse i looked there are about 30 different IDs just for moonbox maybe it has to do with each different ID have a certian type of item inside. Let me know I will figure out which ID have sockets and let you guys know.
I have 40 moonboxes in my inventory i want to find out the differnet ID for each one and open them slowly and i will...
Where to find Item IDs? 02/16/2006 - Conquer Online 2 - 1 Replies Hi All,
maybe anyone of you could help me a bit,
i've tried to get item ids out of the itemtype.dat
but i cant figure out...