|
You last visited: Today at 11:27
Advertisement
D2NT Muddy Waters to D2BS
Discussion on D2NT Muddy Waters to D2BS within the Diablo 2 Programming forum part of the Diablo 2 category.
10/18/2013, 03:56
|
#1
|
elite*gold: 0
Join Date: Nov 2010
Posts: 78
Received Thanks: 3
|
D2NT Muddy Waters to D2BS
Hallo liebe Community, mit diesem Thema möchte ich nochmal zum Ausdruck bringen das der D2NT von Muddy Waters einer der besten Bots auf dem Schwarzmarkt war und ich einige Funktionen in die D2BS Umgebung portieren möchte, dazu brauche ich eure Hilfe.
D2NT to D2BS- Projekt #1: AttackTime, Repositioning: Bot soll sich repositionieren und teleportiert / rennt nach X Angriffen auf eine neue Position
Code:
// ehemals
MWConfig_AttacksBeforeRepositioning = X;
- Projekt #2: Wind Druid AttackPosition: Bot soll sich teleportieren und direkt vor den Gegner stellen (ähnlich wie beim Hammerdin) um Tornado zu casten, damit er das Ziel nicht mehr verfehlt.
Code:
getHammerPosition: function (unit) {
var i, x, y, positions,
baseId = getBaseStat("monstats", unit.classid, "baseid"),
size = getBaseStat("monstats2", baseId, "sizex");
// in case base stat returns something outrageous
if (typeof size !== "number" || size < 1 || size > 3) {
size = 3;
}
switch (unit.type) {
case 0: // Player
x = unit.x;
y = unit.y;
positions = [[x + 1, y], [x + 1, y + 1]];
break;
case 1: // Monster
x = unit.x;
y = unit.y;
positions = [[x + size - 1, y + size - 1], [x + 1, y - 1], [x, y + 1], [x - 1, y - 1]];
break;
}
for (i = 0; i < positions.length; i += 1) {
if (getDistance(me, positions[i][0], positions[i][1]) < 1) {
return true;
}
}
for (i = 0; i < positions.length; i += 1) {
if (Attack.validSpot(positions[i][0], positions[i][1])) {
this.reposition(positions[i][0], positions[i][1]);
if (!checkCollision(me, unit, 0x1)) {
return true;
}
}
}
return false;
},
reposition: function (x, y) {
while (!me.idle) {
delay(40);
}
if (getDistance(me, x, y) > 0) {
if (Pather.teleport && !me.inTown && me.getStat(97, 54)) {
//Pather.teleportTo(x, y);
Skill.cast(54, 0, x, y);
} else {
me.move(x, y);
}
}
while (!me.idle) {
delay(40);
}
return true;
}
- Habe dazu aus der Attack Sequence vom Paladin die entsprechenden Part kopiert, bin mir nur nicht sicher ob es so richtig geschrieben ist und überhaupt funktioniert, Bot teleport allerdings schon.
Weitere Änderungen können mir per PM mitgeteilt werden, ich halte dieses Thema aktuell.
|
|
|
10/23/2013, 12:30
|
#2
|
Administrator
elite*gold: 41624
Join Date: Jan 2010
Posts: 22,728
Received Thanks: 12,654
|
Könntest du mal mehr Kontext posten? Am besten die ganze Bibliothek.
Was diese Hammer Position angeht, so kann ich nicht alles nachvollziehen, weil mir zu dem Attack-Objekt die Klasse fehlt. Prinzipiell müsste das aber funktionieren, wenn es darum geht, dich direkt "auf" einem Gegner zu positionieren, ich bin allerdings nicht sicher, was Attack.validSpot() macht.
|
|
|
10/23/2013, 22:20
|
#3
|
elite*gold: 0
Join Date: Oct 2008
Posts: 216
Received Thanks: 47
|
Attack.validSpot() kontrolliert eine einzelne Position auf Kollision
|
|
|
10/25/2013, 05:17
|
#4
|
elite*gold: 0
Join Date: Nov 2010
Posts: 78
Received Thanks: 3
|
Ich habe folgendes in der d2bs\kolbot\libs\common\Attacks\Druid.js geändert:
Code:
/**
* @filename Druid.js
* @author kolton
* @desc Druid attack sequence
*/
var ClassAttack = {
skillRange: [],
skillHand: [],
skillElement: [],
init: function () {
var i;
for (i = 0; i < Config.LowManaSkill.length; i += 1) {
Config.AttackSkill.push(Config.LowManaSkill[i]);
}
for (i = 0; i < Config.AttackSkill.length; i += 1) {
this.skillHand[i] = getBaseStat("skills", Config.AttackSkill[i], "leftskill");
this.skillElement[i] = Attack.getSkillElement(Config.AttackSkill[i]);
switch (Config.AttackSkill[i]) {
case 0: // Normal Attack
this.skillRange[i] = Attack.usingBow() ? 20 : 2;
this.skillHand[i] = 2; // shift bypass
break;
case 225: // Firestorm
case 229: // Molten Boulder
case 230: // Arctic Blast
this.skillRange[i] = 10;
break;
case 234: // Fissure
case 244: // Volcano
this.skillRange[i] = 15;
break;
case 240: // Twister
case 245: // Tornado
this.skillRange[i] = 1;
break;
case 232: // Feral Rage
case 233: // Maul
case 238: // Rabies
case 239: // Fire Claws
case 242: // Hunger
case 248: // Fury
this.skillRange[i] = 2;
break;
case 243: // Shock Wave
this.skillRange[i] = 8;
break;
default: // Every other skill
this.skillRange[i] = 20;
break;
}
}
},
doAttack: function (unit, preattack) {
if (Config.MercWatch && Town.needMerc()) {
Town.visitTown();
}
if (me.getSkill(250, 1) && !me.getState(144)) { // Rebuff Hurricane
Skill.cast(250, 0);
}
if (me.getSkill(235, 1) && !me.getState(151)) { // Rebuff Cyclone Armor
Skill.cast(235, 0);
}
if (preattack && Config.AttackSkill[0] > 0 && Attack.checkResist(unit, this.skillElement[0]) && (!me.getState(121) || !Skill.isTimed(Config.AttackSkill[0]))) {
if (Math.round(getDistance(me, unit)) > this.skillRange[0] || checkCollision(me, unit, 0x4)) {
if (!Attack.getIntoPosition(unit, this.skillRange[0], 0x4)) {
return 1;
}
}
if (!Skill.cast(Config.AttackSkill[0], this.skillHand[0], unit)) {
return 2;
}
return 3;
}
var index;
index = ((unit.spectype & 0x7) || unit.type === 0) ? 1 : 3;
if (Attack.checkResist(unit, this.skillElement[index])) {
if (this.skillRange[index] < 2 && checkCollision(me, unit, 0x1) && (getCollision(unit.area, unit.x, unit.y) & 0x1)) { //EDIT
return 1; //EDIT
} //EDIT
switch (this.doCast(unit, index)) {
case 0: // total fail
return 1;
case false: // fail to cast
return 2;
}
return 3;
}
if (Config.AttackSkill[5] > -1 && Attack.checkResist(unit, this.skillElement[5])) {
if (this.skillRange[5] < 2 && checkCollision(me, unit, 0x1) && (getCollision(unit.area, unit.x, unit.y) & 0x1)) { //EDIT
return 1; //EDIT
} //EDIT
switch (this.doCast(unit, 5)) {
case 0: // total fail
return 1;
case false: // fail to cast
return 2;
}
return 3;
}
if ((me.getState(144) && Attack.checkResist(unit, "cold")) || (Config.TeleStomp && me.getMerc() && Attack.checkResist(unit, "physical"))) {
if (getDistance(me, unit) > 4) {
Pather.moveToUnit(unit);
}
delay(300);
return 3;
}
return 1;
},
afterAttack: function () {
Precast.doPrecast(false);
},
doCast: function (unit, index) {
var i,
timed = index,
untimed = index + 1;
// Low mana timed skill
if (Config.AttackSkill[timed] > -1 && Config.AttackSkill[Config.AttackSkill.length - 2] > -1 && Skill.getManaCost(Config.AttackSkill[timed]) > me.mp) {
timed = Config.AttackSkill.length - 2;
}
if (!me.getState(121) || !Skill.isTimed(Config.AttackSkill[timed])) {
if (Math.round(getDistance(me, unit)) > this.skillRange[timed] || checkCollision(me, unit, 0x4)) {
if (!Attack.getIntoPosition(unit, this.skillRange[timed], 0x4)) {
return 0;
}
}
if (Config.AttackSkill[timed] === 245) {
return Skill.cast(Config.AttackSkill[timed], this.skillHand[timed], unit.x + rand(-2, 2), unit.y);
}
return Skill.cast(Config.AttackSkill[timed], this.skillHand[timed], unit);
}
// Low mana untimed skill
if (Config.AttackSkill[untimed] > -1 && Config.AttackSkill[Config.AttackSkill.length - 1] > -1 && Skill.getManaCost(Config.AttackSkill[untimed]) > me.mp) {
untimed = Config.AttackSkill.length - 1;
}
if (Config.AttackSkill[untimed] > -1) {
if (Math.round(getDistance(me, unit)) > this.skillRange[untimed] || checkCollision(me, unit, 0x4)) {
if (!Attack.getIntoPosition(unit, this.skillRange[untimed], 0x4)) {
return 0;
}
}
return Skill.cast(Config.AttackSkill[untimed], this.skillHand[untimed], unit);
}
for (i = 0; i < 25; i += 1) {
delay(40);
if (!me.getState(121)) {
break;
}
}
return false;
},
getHammerPosition: function (unit) {
var i, x, y, positions,
baseId = getBaseStat("monstats", unit.classid, "baseid"),
size = getBaseStat("monstats2", baseId, "sizex");
// in case base stat returns something outrageous
if (typeof size !== "number" || size < 1 || size > 3) {
size = 3;
}
switch (unit.type) {
case 0: // Player
x = unit.x;
y = unit.y;
positions = [[x + 1, y], [x + 1, y + 1]];
break;
case 1: // Monster
x = unit.x;
y = unit.y;
positions = [[x + size - 1, y + size - 1], [x + 1, y - 1], [x, y + 1], [x - 1, y - 1]];
break;
}
for (i = 0; i < positions.length; i += 1) {
if (getDistance(me, positions[i][0], positions[i][1]) < 1) {
return true;
}
}
for (i = 0; i < positions.length; i += 1) {
if (Attack.validSpot(positions[i][0], positions[i][1])) {
this.reposition(positions[i][0], positions[i][1]);
if (!checkCollision(me, unit, 0x1)) {
return true;
}
}
}
return false;
},
reposition: function (x, y) {
while (!me.idle) {
delay(40);
}
if (getDistance(me, x, y) > 0) {
if (Pather.teleport && !me.inTown && me.getStat(97, 54)) {
//Pather.teleportTo(x, y);
Skill.cast(54, 0, x, y);
} else {
me.move(x, y);
}
}
while (!me.idle) {
delay(40);
}
return true;
}
};
So stellte ich mir vor, mit dem Zusatz an Code, das Verhalten meines Druidens der den Wind-Skill drinhat so sehr dem Hammerdin Attack-Routinen anzupassen, dass der Druide keinerlei Probleme mehr hat Tornados zu zaubern, da mancher Zauber des Tornados neben den Gegner vorbeisaust. Außerdem erleichtert die automatische Zielsuche des Söldners dem Druiden Primärziel anzugreifen.
Meine Frage stellt sich nun soweit, ob dieses Script so wie es aufgegliedert ist funktionieren kann. Ich persönliche Merke eine Leistungssteigerung allerdings kann ich jetzt nicht sagen ob der Charakter durch die Attackrange heranteleportiert oder ob der Charakter nach meiner wackligen Konstruktion agiert.
Projekt #1: Nach X Angriffen die position um das Ziel wechseln, wie schon im D2NT umgesetzt wurde.
Hierzu habe ich keine Ahnung, ich hatte versucht Scriptabschnitte zu kopieren und sie dann in den D2BS einzuordnern, da meine Programmierkentnisse nicht ausreichen um mir selbst dazu einen Kopf zu zerbrechen. Natürlich hat das ganze nicht funktioniert, ich wusste nicht wie ich
Code:
var _MWA_Attack_Time = new Array();
dem D2BS beibringe (dazu wären ein paar hilfreiche Seiten / Links nützlich).
|
|
|
10/25/2013, 13:24
|
#5
|
elite*gold: 0
Join Date: Oct 2008
Posts: 216
Received Thanks: 47
|
wozu soll Projekt#1 den gut sein ? der Kolbot kann doch ausweichen und abstand halten.
Code:
Config.Dodge = true; // Move away from monsters that get too close.
Config.DodgeRange = 15; // Distance to keep from monsters.
Config.DodgeHP = 85; // Dodge only if HP percent is less than or equal to Config.DodgeHP. 100 = always dodge.
Config.DodgeHP. 100 = always dodge
Ansonsten hatte das ständige Ausweichen bei Muddy nur noch Sinn, weil manchmal zwischen dir und dem Monster ein Schrein, ne Wand oder sowas war. Auf die Muddy´s dann wild draufgeballert hat, sowas passiert beim Kolbot aber nicht da er die Strecke vorher auf Kollisionen prüfen kann.
Und zu Projekt#2: Nur reinkopieren bringt dir da nicht viel du müsstest
die Funktion wohl auch anpassen und irgendwann mal aufrufen.
Setz eventuell mal hier an:
Code:
if (!Attack.getIntoPosition(unit, this.skillRange[0], 0x4)) {
return 1;
}
|
|
|
10/28/2013, 00:52
|
#6
|
elite*gold: 0
Join Date: Nov 2010
Posts: 78
Received Thanks: 3
|
Quote:
Originally Posted by Grommel
wozu soll Projekt#1 den gut sein ?
|
Wenn der Hammerding oder der Druide vor einem Boss stehen, diesen aber durch irgendeine ungünstige Position verfehlen, ist es effektiv die Position nach X attacks/casts zu wechseln. Außerdem greift der Söldner direkt das Ziel vor ihm an (Bsp. Akt 5, Thron der Zerstörung, Welle 2, dort kommt es beim Hammerdin auf Merc-Damage & Holy Bolt an)
Quote:
Originally Posted by Grommel
Code:
Config.Dodge = true; // Move away from monsters that get too close.
Config.DodgeRange = 15; // Distance to keep from monsters.
Config.DodgeHP = 85; // Dodge only if HP percent is less than or equal to Config.DodgeHP. 100 = always dodge.
|
Ich hätte gerne gewusst wo ich diese Funktion finde? In meiner master & temp branch ist es nicht zu finden.
|
|
|
10/28/2013, 10:07
|
#7
|
elite*gold: 0
Join Date: Oct 2009
Posts: 798
Received Thanks: 165
|
Die Funktion ist nur bei Necro, Ama, Sorc, Assa enthalten soweit ich weiß. Druids, Barbs und Palas müssen höchstens dodgen wenn man sie verskillt hat/sie nackt sind.
|
|
|
10/28/2013, 13:17
|
#8
|
elite*gold: 0
Join Date: Oct 2008
Posts: 216
Received Thanks: 47
|
Quote:
|
Wenn der Hammerding oder der Druide vor einem Boss stehen, diesen aber durch irgendeine ungünstige Position verfehlen, ist es effektiv die Position nach X attacks/casts zu wechseln.
|
Der Hammerdin würde bei einer Repositionierung wieder die selbe Angriffsposition für die richtige halten bzw. stehen bleiben wenn Sie schon auf einer der Angriffspositionen stehen.
Da könntest du höchsten getHammerPosition so anpassen, dass sie ständig versuchen die best mögliche Position zu kriegen, was wohl nicht gut laufen wird. (wäre die erste for)
Oder du beist in den sauren Apfel und versucht die Angriffsposition zu erweitern bzw. zu optimieren.
|
|
|
10/28/2013, 14:07
|
#9
|
Administrator
elite*gold: 41624
Join Date: Jan 2010
Posts: 22,728
Received Thanks: 12,654
|
Es reicht vielleicht schon, wenn du nicht direkt Attacken zählst und dann repositionierst, sondern stattdessen lieber prüfst, ob deine vorherige Attacke Schaden verursacht hat. Nach x Attacken ohne Schaden wäre es dann sinnvoll, die Position zu wechseln, wobei nur Positionen gültig sind, die nicht deiner jetzigen Position entsprechen.
Das könnte dann z.B. so aussehen:
Code:
/**
* @filename Druid.js
* @author kolton
* @desc Druid attack sequence
*/
var ClassAttack = {
skillRange: [],
skillHand: [],
skillElement: [],
lastTarget: null,
_MAX_FUTILE_ATTACKS: 5,
init: function () {
var i;
for (i = 0; i < Config.LowManaSkill.length; i += 1) {
Config.AttackSkill.push(Config.LowManaSkill[i]);
}
for (i = 0; i < Config.AttackSkill.length; i += 1) {
this.skillHand[i] = getBaseStat("skills", Config.AttackSkill[i], "leftskill");
this.skillElement[i] = Attack.getSkillElement(Config.AttackSkill[i]);
switch (Config.AttackSkill[i]) {
case 0: // Normal Attack
this.skillRange[i] = Attack.usingBow() ? 20 : 2;
this.skillHand[i] = 2; // shift bypass
break;
case 225: // Firestorm
case 229: // Molten Boulder
case 230: // Arctic Blast
this.skillRange[i] = 10;
break;
case 234: // Fissure
case 244: // Volcano
this.skillRange[i] = 15;
break;
case 240: // Twister
case 245: // Tornado
this.skillRange[i] = 1;
break;
case 232: // Feral Rage
case 233: // Maul
case 238: // Rabies
case 239: // Fire Claws
case 242: // Hunger
case 248: // Fury
this.skillRange[i] = 2;
break;
case 243: // Shock Wave
this.skillRange[i] = 8;
break;
default: // Every other skill
this.skillRange[i] = 20;
break;
}
}
},
getTornadoPosition: function (unit, forceReposition) {
var i, x, y, positions,
baseId = getBaseStat("monstats", unit.classid, "baseid"),
size = getBaseStat("monstats2", baseId, "sizex");
// in case base stat returns something outrageous
if (typeof size !== "number" || size < 1 || size > 3) {
size = 3;
}
switch (unit.type) {
case 0: // Player
x = unit.x;
y = unit.y;
positions = [[x + 1, y], [x + 1, y + 1]];
break;
case 1: // Monster
x = unit.x;
y = unit.y;
positions = [[x + size - 1, y + size - 1], [x + 1, y - 1], [x, y + 1], [x - 1, y - 1]];
break;
}
if(!forceReposition)
{
for (i = 0; i < positions.length; i += 1) {
if (getDistance(me, positions[i][0], positions[i][1]) < 1) {
return true;
}
}
}
for (i = 0; i < positions.length; i += 1) {
if ((!forceReposition || me.x != positions[i][0] || me.y != positions[i][0])
&& Attack.validSpot(positions[i][0], positions[i][1])) {
this.reposition(positions[i][0], positions[i][1]);
if (!checkCollision(me, unit, 0x1)) {
return true;
}
}
}
return false;
},
doAttack: function (unit, preattack) {
if (Config.MercWatch && Town.needMerc()) {
Town.visitTown();
}
if (me.getSkill(250, 1) && !me.getState(144)) { // Rebuff Hurricane
Skill.cast(250, 0);
}
if (me.getSkill(235, 1) && !me.getState(151)) { // Rebuff Cyclone Armor
Skill.cast(235, 0);
}
if(!this.lastTarget || this.lastTarget.gid != unit.gid)
{
// Cache last target info
this.lastTarget = {
hprel: unit.hp / unit.hpmax,
futileAttacks: 0,
gid: unit.gid
};
}
else
{
var currHpRel = unit.hp / unit.hpmax;
if(this.lastTarget.hprel >= currHpRel)
{
// We didn't do any damage, so count this one as a failure
this.lastTarget.futileAttacks++;
}
else
{
// We did do damage, update relative hp and reset counter
this.lastTarget.hprel = currHpRel;
this.lastTarget.futileAttacks = 0;
}
if(this.lastTarget.futileAttacks > this._MAX_FUTILE_ATTACKS)
{
// We need to get to a position other than our current one since we aren't doing any damage
if(!this.getTornadoPosition(unit, true))
return 1;
}
}
if (preattack && Config.AttackSkill[0] > 0 && Attack.checkResist(unit, this.skillElement[0]) && (!me.getState(121) || !Skill.isTimed(Config.AttackSkill[0]))) {
if (Math.round(getDistance(me, unit)) > this.skillRange[0] || checkCollision(me, unit, 0x4)) {
if (!Attack.getIntoPosition(unit, this.skillRange[0], 0x4)) {
return 1;
}
}
if (!Skill.cast(Config.AttackSkill[0], this.skillHand[0], unit)) {
return 2;
}
return 3;
}
var index;
index = ((unit.spectype & 0x7) || unit.type === 0) ? 1 : 3;
if (Attack.checkResist(unit, this.skillElement[index])) {
if (this.skillRange[index] < 2 && checkCollision(me, unit, 0x1) && (getCollision(unit.area, unit.x, unit.y) & 0x1)) { //EDIT
return 1; //EDIT
} //EDIT
switch (this.doCast(unit, index)) {
case 0: // total fail
return 1;
case false: // fail to cast
return 2;
}
return 3;
}
if (Config.AttackSkill[5] > -1 && Attack.checkResist(unit, this.skillElement[5])) {
if (this.skillRange[5] < 2 && checkCollision(me, unit, 0x1) && (getCollision(unit.area, unit.x, unit.y) & 0x1)) { //EDIT
return 1; //EDIT
} //EDIT
switch (this.doCast(unit, 5)) {
case 0: // total fail
return 1;
case false: // fail to cast
return 2;
}
return 3;
}
if ((me.getState(144) && Attack.checkResist(unit, "cold")) || (Config.TeleStomp && me.getMerc() && Attack.checkResist(unit, "physical"))) {
if (getDistance(me, unit) > 4) {
Pather.moveToUnit(unit);
}
delay(300);
return 3;
}
return 1;
},
afterAttack: function () {
Precast.doPrecast(false);
},
doCast: function (unit, index) {
var i,
timed = index,
untimed = index + 1;
// Low mana timed skill
if (Config.AttackSkill[timed] > -1 && Config.AttackSkill[Config.AttackSkill.length - 2] > -1 && Skill.getManaCost(Config.AttackSkill[timed]) > me.mp) {
timed = Config.AttackSkill.length - 2;
}
if (!me.getState(121) || !Skill.isTimed(Config.AttackSkill[timed])) {
if (Math.round(getDistance(me, unit)) > this.skillRange[timed] || checkCollision(me, unit, 0x4)) {
if (!Attack.getIntoPosition(unit, this.skillRange[timed], 0x4)) {
return 0;
}
}
if (Config.AttackSkill[timed] === 245) {
return Skill.cast(Config.AttackSkill[timed], this.skillHand[timed], unit.x + rand(-2, 2), unit.y);
}
return Skill.cast(Config.AttackSkill[timed], this.skillHand[timed], unit);
}
// Low mana untimed skill
if (Config.AttackSkill[untimed] > -1 && Config.AttackSkill[Config.AttackSkill.length - 1] > -1 && Skill.getManaCost(Config.AttackSkill[untimed]) > me.mp) {
untimed = Config.AttackSkill.length - 1;
}
if (Config.AttackSkill[untimed] > -1) {
if (Math.round(getDistance(me, unit)) > this.skillRange[untimed] || checkCollision(me, unit, 0x4)) {
if (!Attack.getIntoPosition(unit, this.skillRange[untimed], 0x4)) {
return 0;
}
}
return Skill.cast(Config.AttackSkill[untimed], this.skillHand[untimed], unit);
}
for (i = 0; i < 25; i += 1) {
delay(40);
if (!me.getState(121)) {
break;
}
}
return false;
},
getHammerPosition: function (unit) {
var i, x, y, positions,
baseId = getBaseStat("monstats", unit.classid, "baseid"),
size = getBaseStat("monstats2", baseId, "sizex");
// in case base stat returns something outrageous
if (typeof size !== "number" || size < 1 || size > 3) {
size = 3;
}
switch (unit.type) {
case 0: // Player
x = unit.x;
y = unit.y;
positions = [[x + 1, y], [x + 1, y + 1]];
break;
case 1: // Monster
x = unit.x;
y = unit.y;
positions = [[x + size - 1, y + size - 1], [x + 1, y - 1], [x, y + 1], [x - 1, y - 1]];
break;
}
for (i = 0; i < positions.length; i += 1) {
if (getDistance(me, positions[i][0], positions[i][1]) < 1) {
return true;
}
}
for (i = 0; i < positions.length; i += 1) {
if (Attack.validSpot(positions[i][0], positions[i][1])) {
this.reposition(positions[i][0], positions[i][1]);
if (!checkCollision(me, unit, 0x1)) {
return true;
}
}
}
return false;
},
reposition: function (x, y) {
while (!me.idle) {
delay(40);
}
if (getDistance(me, x, y) > 0) {
if (Pather.teleport && !me.inTown && me.getStat(97, 54)) {
//Pather.teleportTo(x, y);
Skill.cast(54, 0, x, y);
} else {
me.move(x, y);
}
}
while (!me.idle) {
delay(40);
}
return true;
}
};
Ich habe zur Neupositionierung nun einfach die Hammerdin Funktion missbraucht und diese nur minimal abgeändert - das ist alles rein theoretisch, ob das so funktioniert weiß ich nicht.
|
|
|
All times are GMT +1. The time now is 11:29.
|
|