Register for your free account! | Forgot your password?

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

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

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.

Reply
 
Old   #1
 
Starguest's Avatar
 
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.
Starguest is offline  
Old 10/23/2013, 12:30   #2
Administrator
 
Muddy Waters's Avatar
 
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.
Muddy Waters is offline  
Old 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

Grommel is offline  
Old 10/25/2013, 05:17   #4
 
Starguest's Avatar
 
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).
Starguest is offline  
Old 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;
}
Grommel is offline  
Old 10/28/2013, 00:52   #6
 
Starguest's Avatar
 
elite*gold: 0
Join Date: Nov 2010
Posts: 78
Received Thanks: 3
Quote:
Originally Posted by Grommel View Post
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 View Post
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.
Starguest is offline  
Old 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.
Talltree is offline  
Old 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.
Grommel is offline  
Old 10/28/2013, 14:07   #9
Administrator
 
Muddy Waters's Avatar
 
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.
Muddy Waters is offline  
Reply


Similar Threads Similar Threads
[D2BS] Pickit Konverter D2NT -> D2BS nt-bot
10/30/2011 - Diablo 2 - 8 Replies
Gibts nen Konverter für die Pickit D2NT zum D2BS nt-bot?
[Release] WrathHunter script für Muddy Waters D2NT
06/22/2011 - Diablo 2 Programming - 31 Replies
Update auf v1.2.1 changelog v1.2.1 - Akt 2 Tombs hinzu. - looten von Chests wieder standardmäßig aktiviert (siehe Tipps). v1.2 - Weitere Gebiete hinzugefügt - MWC_Initialize(); Aufruf ersetzt durch NTA_Initialize();



All times are GMT +1. The time now is 11:29.


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

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