Geister auf dem Weg killen

01/01/2011 19:19 Eichenlaub#1
Ich würde gerne einbauen, dass der Bot automatisch alle Geister die er auf dem Weg antrifft killt, wie könnte sowas aussehen?

Der Bot soll so z.b. bestimmte Gebiete abfarmen und dort nur die Geister/Schwärme killen. Z.b. Ferne Oase. Gerne würde ich dazu ein neuen Bot schreiben.

(nutze sternenloopers)
01/01/2011 20:08 Muddy Waters#2
Quote:
Originally Posted by Eichenlaub View Post
Ich würde gerne einbauen, dass der Bot automatisch alle Geister die er auf dem Weg antrifft killt, wie könnte sowas aussehen?

Der Bot soll so z.b. bestimmte Gebiete abfarmen und dort nur die Geister/Schwärme killen. Z.b. Ferne Oase. Gerne würde ich dazu ein neuen Bot schreiben.

(nutze sternenloopers)
So so, einen neuen Bot schreiben, na dann mal los, meinen Segen hast du. :handsdown:

Es sei denn, du möchtest doch nur ein kleines eigenes Script schreiben, in dem Fall könnte man dir vermutlich sogar helfen. ;)
Aber du müsstest dir erstmal konkreter überlegen, was du eigentlich willst.
Tatsächlich grundsätzlich alle Geister "auf dem Weg" killen (das würde das Vorankommen extrem verlangsamen).
Oder doch einfach nur ein Script zum säubern einer Ebene, mit einer leicht modifizieren ClearRoom() Funktion?

Also, erstmal möglichst genau gedanklich festlegen, was das die Problemstellung ist, davon hängt nämlich ab, wie man das ganze umsetzt. ;)

Lg
Muddy
01/01/2011 20:32 Eichenlaub#3
Ja also mit Bot meinte ich eine neue ntj Datei ;)

Ich verstehe das so:
Der Bot nimmt einen Wegpunkt in die Ferne Oase. Danach telt er durch das Gebiet und tötet alle Schwärme. Danach nimmt er neuen Wegpunkt z.b. in die Geheime Zuflucht und tötet dort alle Geister.

Das ganze soll dazu dienen, die Chance auf Runenfunde zu erhöhen.
01/01/2011 22:25 Muddy Waters#4
Quote:
Originally Posted by Eichenlaub View Post
Ja also mit Bot meinte ich eine neue ntj Datei ;)

Ich verstehe das so:
Der Bot nimmt einen Wegpunkt in die Ferne Oase. Danach telt er durch das Gebiet und tötet alle Schwärme. Danach nimmt er neuen Wegpunkt z.b. in die Geheime Zuflucht und tötet dort alle Geister.

Das ganze soll dazu dienen, die Chance auf Runenfunde zu erhöhen.
Wenn du meinst, dass das effektiv ist, warum nicht.

Es würde sich anbieten, ein eigenes Script pro Ebene anzusetzen, sonst wird es zu unübersichtlich.

Prinzipiell kann man das mit Standardfunktionen lösen, nur die NTA_ClearRoom() bzw. NTA_ClearLevel Funktion müsste erweitert werden, ausserdem muss noch eine kleine Funktion geschrieben werden, in der die classids der Ziele definiert werden.
Letzteres ließe sich natürlich auch mit einem Array lösen, aber ich finde eine kleine Funktion mit einer Switch Anweisung eigentlich immer übersichtlicher.

Alles in allem recht überschaubar, das Raussuchen der classids ist aus meiner Sicht die einzige Arbeit dabei, der Rest ist Kleinkram.

Da du ja sagst, du willst es selber machen und suchst nur Vorschläge zur ungefähren Umsetzung, halte ich mich mal bewusst bedeckt.
Ich kann ohnehin schlecht etwas zu Sternis Funktionen sagen, ohne diese konkret vor Augen zu haben, da sie bei mir vermutlich etwas anders aussehen.

Lg
Muddy
01/01/2011 23:02 Eichenlaub#5
Ja gut dann werde ich mich morgen einmal daran setzen. Hatte schon einmal einen Versuch gemacht, aber damit war ich nicht sonderlich erfolgreich (Bot killte ersten Schwarm in Ferne Oase und beendete dann game).

Ich möchte dann einfach mal ca. 100 runs laufen lassen und die Runen die droppen hier dann auflisten.
01/02/2011 14:16 Eichenlaub#6
Ich bräuchte doch ein wenig Hilfe, ich bekomme es einfach nicht gebacken ;(

Habe vom Kurast Script abgeschaut, wo einzelne Truhen gesucht werden und dann geöffnet:

Hier mein Ansatz:
Code:
      _unit = NTC_FindUnit(NTC_UNIT_MONSTER, GetLocaleString(3003));
			if(NTC_FindUnit(NTC_UNIT_MONSTER, GetLocaleString(3003)))
			{
				Say("Black Raptors found");
			}



   if(_unit)
   {
      Print(GetLocaleString(3003));
      for(n = 0 ; n < _unit.length ; n++)
      {

         if(_unit[n].id == 17 || _unit[n].id == 3003|| _unit[n].id == 106 || _unit[n].id == 107)
         {
            NTM_MoveTo(me.areaid, _unit[n].roomx*5+_unit[n].x, _unit[n].roomy*5+_unit[n].y);
            
            _monster = NTC_FindUnit(NTC_UNIT_MONSTER, GetLocaleString(3003));
            if(_monster)
               {
                  do
                  {
					NTA_ClearPosition(10, true);
                  }while(_monster.GetNext());
               }   
               
            _monster = NTC_FindUnit(NTC_UNIT_MONSTER, GetLocaleString(3053));
            if(_monster)
               {
                  do
                  {
         NTA_ClearPosition(10, true);
                  }while(_monster.GetNext());
               }         
         }
         
      }
   }
Hier versuche ich die Black Raptors zu suchen und zu töten, aber der Bot macht nichts. Weiß auch nicht was es mit den _unit.[id] Werten auf sich hat.


3003 ist die ID zu Black Raptors
01/02/2011 14:59 Muddy Waters#7
Quote:
Originally Posted by Eichenlaub View Post
Ich bräuchte doch ein wenig Hilfe, ich bekomme es einfach nicht gebacken ;(

Habe vom Kurast Script abgeschaut, wo einzelne Truhen gesucht werden und dann geöffnet:

Hier mein Ansatz:
Code:
      _unit = NTC_FindUnit(NTC_UNIT_MONSTER, GetLocaleString(3003));
            if(NTC_FindUnit(NTC_UNIT_MONSTER, GetLocaleString(3003)))
            {
                Say("Black Raptors found");
            }



   if(_unit)
   {
      Print(GetLocaleString(3003));
      for(n = 0 ; n < _unit.length ; n++)
      {

         if(_unit[n].id == 17 || _unit[n].id == 3003|| _unit[n].id == 106 || _unit[n].id == 107)
         {
            NTM_MoveTo(me.areaid, _unit[n].roomx*5+_unit[n].x, _unit[n].roomy*5+_unit[n].y);
            
            _monster = NTC_FindUnit(NTC_UNIT_MONSTER, GetLocaleString(3003));
            if(_monster)
               {
                  do
                  {
                    NTA_ClearPosition(10, true);
                  }while(_monster.GetNext());
               }   
               
            _monster = NTC_FindUnit(NTC_UNIT_MONSTER, GetLocaleString(3053));
            if(_monster)
               {
                  do
                  {
         NTA_ClearPosition(10, true);
                  }while(_monster.GetNext());
               }         
         }
         
      }
   }
Hier versuche ich die Black Raptors zu suchen und zu töten, aber der Bot macht nichts. Weiß auch nicht was es mit den _unit.[id] Werten auf sich hat.


3003 ist die ID zu Black Raptors
Puh... :rolleyes:

Als erstes solltest du dir mal einen etwas anständigeren Editor besorgen und dann ordentlich Einrücken, so kann das kein Mensch lesen. ;)

Desweiteren behandelst du deine Ziele als Preset Units (was sie nicht sind),
instantiierst sie aber nichtmal als solche, sondern als npc Objekte.

Die Eigenschaften id und roomx sind für Preset Units definiert, nicht aber für npc Objekte.

Mit IDs meinte ich übrigens die classid, nicht die ID der LocaleStrings.
Wenn du nicht unbedingt LocaleStrings verwenden musst, tue dies auch nicht. Das ist eigentlich nur ein Ausweg, wenn man ein Ziel nicht ausreichend über classid, spectype oder sonstige Eigenschaften beschreiben kann.

Dein Script sollte am Ende nicht viel anders aussehen, als die anderen Scripte zum säubern von Ebenen.

So sieht zum Beispiel ein Script aus, welches den Char den gesamten River of Flame säubern lässt:
Code:
/**
*    This file was written by [Only registered and activated users can see links. Click Here To Register...]
*    Check the programming section for updates and further scripts
*    Last Update: 12/30/2010
*/

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

    NT_LoadConfig();
    NTSI_LoadNIPFiles("NTBot/item_configs");
    
    NTA_Initialize();
    
    if(!NTTM_CheckAct())
    {
        MWC_GetErrorArgumentString(NTTM_CheckAct, 18);
        NTC_SendMsgToScript("MWBotGame.ntj", "NTTM_CheckAct()");
        return;
    }

    NTTMGR_TownManager();

    if(!NTTM_TownMove("waypoint"))
    {
        MWC_GetErrorArgumentString(NTTM_TownMove, 27, "waypoint");
        NTC_SendMsgToScript("MWBotGame.ntj", "NTTM_TownMove()");
        return;
    }
    
    if(!NTM_TakeWaypoint(106))
    {
        if(!NTM_TakeWaypoint(107))
        {
            MWC_GetErrorArgumentString(NTM_TakeWaypoint, 36, 107);
            NTC_SendMsgToScript("MWBotGame.ntj", "NTM_TakeWaypoint()");
            return;
        }
    }
    else
    {
        if(!NTM_MoveToStair(me.areaid, 107))
        {
            MWC_GetErrorArgumentString(NTM_MoveToStair, 45, me.areaid, 107);
            NTC_SendMsgToScript("MWBotGame.ntj", "NTM_MoveToStair()");
            return;
        }
        
        if(!NTM_TakeStair(107))
        {
            MWC_GetErrorArgumentString(NTM_TakeStair, 52, 107);
            NTC_SendMsgToScript("MWBotGame.ntj", "NTM_TakeStair()");
            return;
        }
    }
    
    NTP_DoPrecast(true);

    [COLOR=Red]NTA_ClearLevel();[/COLOR]

    NTC_SendMsgToScript("MWBotGame.ntj", "SCRIPT_END");
}
Das eigentliche Säubern der Ebene habe ich dir mal rot hervorgehoben.
NTA_ClearLevel() ordnet alle Räume der Ebene dem Abstand nach.

Danach wird jeder Raum angesteuert und dann die Funktion NTA_ClearRoom() aufgerufen, um alle Monster innerhalb des Raumes zu töten.

Prinzipiell ist das auch schon genau das, was du brauchst, die beiden Funktionen müssen nurnoch so erweitert werden, dass nur bestimmte Monstertypen beachtet werden. In deinem Fall: Geister.

Die Erweiterung dieser Funktionen hat den Vorteil, dass du nicht das Rad neu erfinden musst und ausserdem einen Script Aufbau erhältst, der sich mit minimalen Änderungen auf jede beliebige Ebene übertragen lässt.
Darum habe ich dir auch nahe gelegt, dort anzusetzen. ;)

NTA_ClearRoom()
ist die eigentliche Funktion, in der Monster Attackiert werden, darum muss die Überprüfung des Ziels hier erfolgen.
Letztlich wird aber nur NTA_ClearLevel() aufgerufen. Darum muss auch in NTA_ClearLevel() ein Parameter eingeführt werden, der dann an NTA_ClearRoom() weitergegeben wird.

Wichtig: Die neuen Parameter brauchen Defaultwerte, damit die Funktion auch noch das tut was sie soll, wenn sie mit den üblichen Parametern aufgerufen wird.
Letzteres ist grundsätzlich zu beachten, wenn man Funktionen der common library erweitert.

Dann fehlt noch eine kleine Funktion, die die Zielparameter festlegt, also in diesem Fall die classid des Ziels.

Sowas könnte so aussehen:
Code:
function MWA_IsSwarm(target)
{
    if(arguments.length < 1 || !target)
        return false;
        
    switch(target.classid)
    {
        case 40: // Specter (Arcane Sanctuary)
        case 87: // Itchies (Far Oasis)
        case 88: // Black Locusts (Maggot's Lair)
            return true;
    }

    return false;
}
Ich habe dir auch mal ein paar classids ausgelesen, die anderen darfst du dann selbst in Erfahrung bringen. ;)

Wenn du es nicht selbst versuchen willst, kann ich dir auch schnell sagen, wie die genannten Funktionen angepasst bzw. erweitert werden müssen.
Allerdings müsstest du diese dann erstmal posten, da ich nicht wiess, wie die Implementierung bei dir aussieht und sie bei mir Erweiterungen enthalten, die Sterni's Version nicht unterstützt.

Lg
Muddy
01/02/2011 15:24 Eichenlaub#8
Erstmal vielen Dank hierfür!

Hatte auch schon mal diese zwei Funktionen in mein Script eingebaut, aber dachte dann dass das Kurast Travel Script auch funktionieren würde.

Werde es dann noch einmal versuchen.