Okay, in dem Fall erkläre ich es mal etwas genauer, denn was man hier sieht lässt sich auch auf beliebige andere Funktionen übertragen.
Dass dort eine Schleife verwendet wird ist ja soweit richtig, allerdings ist die Anzahl der Durchläufe gegeben durch den Wert der Variable
retry + 1.
Schauen wir uns aber zunächst mal die Funktion
NTC_FindUnit() genauer an:
Code:
function NTC_FindUnit(unittype, search, retry)
{
var _unit;
switch(arguments.length)
{
case 0:
return null;
case 1:
search = null;
case 2:
retry = 0;
break;
}
for(var i = 0 ; i <= retry ; i++)
{
_unit = GetUnit(unittype, search);
if(_unit)
return _unit;
if(i < retry)
NTC_Delay(200);
}
return null;
}
Die Funktion erwartet offenbar bis zu drei Parameter, nämlich gerade
unittype,
search und
retry.
Typische für JavaScript/D2NT findet nun eine Abfrage statt, mit wievielen Parametern die Funktion denn nun tatsächlich aufgerufen wurde. Denn nur weil es bis zu drei sein können (genaugenommen können es grundsätzlich immer beliebig viele sein), heisst das nicht, dass wir automatisch auch immer alle 3 Parameter übergeben müssen.
Je nachdem wieviele Parameter übergeben, hat
arguments.length einen anderen Wert, nämlich gerade die Anzahl der übergebenen Parameter.
Das Objekt
arguments ist übrigens in
jeder JavaScript Funktion definiert.
Zurück zur Funktion:
In der switch-Anweisung wird nun
arguments.length überprüft.
Um das voll zu verstehen, muss man eigentlich auch switch-Anweisungen verstehen - man merkt schon, es hängt irgendwie alles zusammen, was die Sache für Einsteiger nicht immer ganz einfach macht.
Zu beachten ist hierbei, dass bei den einzelnen cases der switch-Anweisung die breaks fehlen. Dies hat zur Folge, dass sämtliche cases nach dem ersten Aufgerufenen case
immer mit ausgeführt werden und nicht etwa nur der case, zu dem der Sprung erfolgt.
Wurden nun keine Parameter übergeben, ist der Aufruf zu unspezifisch, darum wird die Funktion in dem Fall direkt mit dem Rückgabewert
null beendet.
Wurde nur nur ein Parameter übergeben, ist die Angabe spezifisch genug, um damit in der Nähe (~ 70 yards) befindliche Units zu finden.
In diesem Fall wird case 1 erreicht und
search mit dem Wert
null Initialisiert.
Wie oben erwäht, wird danach auch case 2 ausgeführt und retry mit 0 initialisiert. Nun sind alle Parameter initialisiert und es kann die globale Funktion
GetUnit() aufgerufen werden.
Wurden nur zwei Parameter übergeben, wird nur case 2 erreicht, um den noch undefinierten Parameter
retry zu initialisieren.
Dies ist ein recht schickes Beispiel für die Verwendung von Default Parametern in D2NT/JavaScript.
Achja, es gibt natürlich noch den Fall, dass alle 3 Parameter übergeben werden, in dem Fall sind aber alle Parameter definiert und es ist keine Initialisierung mit Defaultwerten von Nöten. :)
Nun schauen wir uns mal die Schleife an:
Nachdem wir nun wie in meinem Code Schnipsel zu sehen, nur zwei Parameter übergeben haben, wird retry mit dem Defaultwert 0 initialisiert.
Für die Schleife bedeutet dies, das genau ein Durchlauf stattfindet, denn die Bedingung
i <= retry ist nur für den ersten Durchlauf
true, nämlich dann wenn
i und
retry beide den Wert 0 haben.
Es ist zwar eine Schleife, aber bei entsprechenden Parametern verhält sie sich so, als wäre sie gar nicht vorhanden.
Demzufolge ist deine Aussage von oben, dass
NTC_FindUnit() eine Schleife enthält und somit per se mehr als einmal sucht, ganz einfach falsch. Ich könnte mir höchstens vorstellen, dass du
NTC_FindUnit() mit falschen Parametern aufgerufen hast, sprich du hast für
retry einen Wert übergeben, der ungleich 0 ist. In dem Fall ist das genannte Verhalten nicht weiter verwunderlich.
Ich würde es daher einfach mal so versuchen:
Code:
if(!NTM_MoveTo(me.areaid, 7795, 5282))
{
NTC_SendMsgToScript("MWBotGame.ntj", NTM_MoveTo, 145, me.areaid, 7795, 5282);
return;
}
NTP_DoPrecast(true);
if(me.classid == NTC_CHAR_CLASS_PALADIN)
{
NTC_PutSkill(113, NTC_HAND_RIGHT);
for(var i = 0; i < 150; i++)
{
if(!NTC_CastSkill(112, 2))
NTC_Delay(200); // 200ms Delay, falls das Casten aus irgendeinem Grund nicht funktioniert.
if(NTC_FindUnit(NTC_UNIT_MONSTER, 243)) // Wird true, sobald Diablo auftaucht.
break;
}
}
else
NTC_FindUnit(NTC_UNIT_MONSTER, 243, 150); // Hier wird NTC_FindUnit als Variables Delay genutzt, welches dann endet, wenn Diablo auftaucht.
if(!NTA_KillMonster(243))
{
NTC_SendMsgToScript("MWBotGame.ntj", NTA_KillMonster, 158, 243);
return;
}
NTSI_PickItems();
if(NTConfig_PublicMode)
Say(_msgNG);
NTC_SendMsgToScript("MWBotGame.ntj", "SCRIPT_END");
Achja, was auch gegen deine vorherige Lösung spricht, ist die Lesbarkeit.
Denn wenn man sich ein bisschen damit beschäftigt, kennt man die Funktionen der common library und hat deren Verhalten im Hinterkopf.
Wenn ich nun meine Variante lese, weiss ich sofort, was dort passiert.
Bei deiner Variante sehe ich erstmal eine mir unbekannte Funktion und muss mir zunächst die Implementierung dieser Funktion anschauen, um zu verstehen, was dort passiert.
Mal abgesehen dass das Kopieren und minimale ändern von common library Funktionen einfach nicht elegant ist. :)
Sollten nach dieser kleinen Abhandlung noch Rückfragen bestehen, einfach nachfragen. ;)
LG
Muddy