[Guide] Questprofil erstellen, aber wie? - MMOCrawlerbots | WoW Bot Forum
Important: Please register to use the 20 minutes trial version or buy the bot!
Bot ready for World of Warcraft 5.4.2 Build 17688
If you have troubles with updating: Download the new UpdateLauncher.exe and replace the old one.

UpdateLauncher DOWNLOAD

Wow Bot: CrawlerBot Last version: click here State: EU:workingUS:working

Author Topic: [Guide] Questprofil erstellen, aber wie?  (Read 258 times)

December 19, 2013, 14:02:18 PM

kolbenhans Offline

  • *
  • *
  • Join Date: Dec 2012
  • Posts: 768
  • Reputation: 233
    • View Profile
Was brauche ich um QuestProfile zu erstellen?

Grundsätzliches Wissen über scripting (bestenfalls Lua) sollten vorhanden sein.

Wie baue ich eine Quest und welche Informationen brauche ich bzw. wie bekomme ich sie?

Der Erste Schritt zum erstellen eines Questprofils ist das finden der entsprechenden QuestID. Hierfür gibt es mehrere Wege, 3 möchte ich kurz erläutern.
  • (mein aktueller Weg) Durch die Wow Addons: Grail, Wholly
    Ich navigiere zu dem NPC der eine Quest bereit hält und interagiere mit ihm. Bei einer Quest, ist diese nun direkt offen, bei mehreren wähle ich entsprechende Quest aus.
    Bevor ich die Quest annehme bekomme ich nun oben rechts die QuestID angezeitgt (als Beispiel nehmen wir mal: 12345). Diese ID merke ich mir und nehme die Quest dann an.
  • Ich navigiere zu dem NPC der eine Quest bereit hält und interagiere mit ihm. Bei einer Quest, ist diese nun direkt offen, bei mehreren wähle ich entsprechende Quest aus.
    Bevor ich die Quest annehme, öffne ich den Chat in wow und gebe dort ein (ohne Anführungszeichen): "/run print(GetQuestID())" im Chatfenster sehe ich nun die QuestID. Diese ID merke ich mir und nehme die Quest dann an.
  • Ich navigiere zu dem NPC der eine Quest bereit hält und interagiere mit ihm. Bei einer Quest, ist diese nun direkt offen, bei mehreren wähle ich entsprechende Quest aus und nehme die Quest an
    Ich gebe den Namen der Quest auf der Seite www.wowhead.com ein (ggf. auf eigene Sprache umstellen), klicke den link an und lese in der Adresszeile die QuestID aus. Diese ID merke ich mir.


Ich starte den Bot (sofern nicht bereits geschehen) und wähle den Modus Debug und wechsle auf den Reiter QuestGen. In das obere Eingabefeld trage ich nun die QuestID ein, also: 12345 und klicke auf Generate.
Der Bot liest nun die QuestInformationen aus und zeigt mir unten ein automatisch generiertes Questprofil an (Die Vorlage hierfür liegt um Botverzeichnis/Data/QuestPattern.txt und kann natürlich auch nach eigenen Wünschen angepasst werden)
Den Generierten Code füge ich nun in meine neue oder vorhandene Datei ein die ich zum QuestProfil machen möchte.

Der Bot füllt die notwendigen Informationen sofern möglich bereits auf, ggf. müssen hier aber auch mal Anpassungen durchgeführt werden

Wie ist die standard Vorlage aufgebaut?

Code: Lua
  1. function Quest_12345()  --Name der Funktion die anschließend ausgeführt wird. Funktionen werden beim starten des Profils in den Speicher gelesen aber NICHT direkt ausgeführt.
  2.     <Block1> --Prüfung ob die Quest bereits erledigt wurde. Wenn true wird gibt die funktion ein return 0 zurück, was sozusagen einen Abbruch verursacht. Ansonsten geht es zu Block2
  3.  
  4.     <Block2> --Prüfung ob die Quest bereits im Log ist, wenn ja gehts zum Block3, ansonsten wird eine Navigation zum Questgeber durchgeführt und die Quest angenommen.
  5.  
  6.     <Block3> --Wenn es keine reine Quest ist in der man nur zu einem anderen NPC gehen muss um die Quest abzugeben folgt hier die eigentliche Tätigkeit zum erfüllen der Quest, ansonsten fehlt dieser Teil bzw. kann weg gelassen werden. Ist die Questaufgabe erfüllt geht es zu Block4.
  7.  
  8.     <Block4> --Wenn die Questaufgabe durchgeführt ist, geht es nun zum NPC an dem die Quest abgegeben werden muss (NavigatTo) und das eigentliche abgeben der Quest erfolgt.
  9. end
  10. -----------------------------
  11. Quest_12345() --Dieses ist der eigentliche Aufruf der Funktion der sie überhaupt erst starten lässt. Der Aufruf muss immer am Ende der Datei durchgeführt werden, da ansonsten die Funktionen noch nicht eingelesen sind.


Details zu Block3:
Da der Block1, Block2, Block4 sind bei fast jeder Quest gleich und bedürfen oftmals keiner oder nur geringer Anpassungen, Block4 hingegen muss für jede Quest entsprechend angepasst werden.
Wenn es keine zu erfüllende Aufgabe gibt (z.B. töte 10 Mobs etc.) sondern man nur zu einem andern Questgeber muss, kann man das Template oft schon direkt übernehmen und es sind keine Anpassungen notwendig.
Ansonsten füllen wir den Block je nach Quest mit entsprechenden Informationen. An einem Beispiel z.B. "töte 10 Mobs" sieht es folgendermaßen aus:

Hier ein Beispiel einer generierten Quest:
Code: Lua
  1. function Quest_26503()
  2.  
  3.     if WasQuestDone(26503) == true then
  4.         return 0
  5.     end
  6.    
  7.     while IsQuestInLog(26503) == false do
  8.         _Log("Accept Quest: Still Assessing the Threat (26503)")        
  9.         NavigateTo(-9620.8,-1872.82,99.2486, 2)
  10.         Sleep(1000)
  11.         AcceptQuest(2150,26503) -- Use AcceptQuestRunningNPC for moving NPCS
  12.     end
  13.  
  14.     _Log("Doing Quest: Still Assessing the Threat (26503)")
  15.  
  16.     if IsQuestStepDone(26503,1) == false then --
  17.         --Your code here type: 513
  18.     end
  19.  
  20.     if IsQuestStepDone(26503,2) == false then --
  21.         --Your code here type: 513
  22.     end
  23.  
  24.     if IsQuestStepDone(26503,3) == false then --
  25.         --Your code here type: 513
  26.     end
  27.    
  28.     while WasQuestDone(26503) == false do
  29.         NavigateTo(-9620.8,-1872.82,99.2486, 2)
  30.         Sleep(1000)
  31.         TurnInQuest(2150,26503) -- Use TurnInQuestRunningNPC for moving NPCS
  32.     end
  33. end
  34.  
  35. -----------------------------------------
  36. Quest_26503()                                   --[A] Still Assessing the Threat

Code: Lua
  1. if IsQuestStepDone(12345,1) == false then --Wenn Questschritt 1 (können auch mehrere Ziele pro Quest sein!!!) nicht erfüllt ist, dann....
  2.     AddGrindingHotspot(x,y,z) --Dieses sind die Wegpunkte die durch den Bot abgelaufen werden sollen. Sinnvollerweise dort wo auch die zu tötenden Mobs sind :)
  3.     AddGrindingHotspot(x,y,z) --Punkt 2
  4.     AddGrindingHotspot(x,y,z) --Punkt 3
  5.     AddGrindingHotspot(x,y,z) --usw. usw. je nachdem wie lang der Pfad werden soll. (Diese Wegpunkte können ganz einfach über den Crawli Editor hinzugefügt werden!!!)
  6.     AddGrindingMobID(54321)  --Die MobID die getötet werden soll. bekommt man entwender über den Crawli Editor (show Objects) oder über den Bot im Debug Modus (Ziel ins Target nehmen und im Reiter "Game Info" auf Refresh klicken)
  7.     AddGrindingMobID(54322)  --Es können natürlich auch mehrere MobIDs zum erfüllen der Quest angegeben werden
  8.     DoGrind("QuestCond", 12345,1,1)  --dieser Teil startet das eigentliche Grinden und bedeutet DoGrind=Grinde, "QuestCond"=bis der QuestStep (in diesem Fall 1) erfüllt ist, 12345=QuestID, 1=true, sollte immer drin sein, 1=Step (bei mehreren Zielen muss entsprechend 2,3,4 oder sonstiges eingestellt werden)
  9.     ClearGrindingSettings() --löscht alle WegPunkte und MobIDs aus dem Speicher, damit diese in der nächsten Quest nicht wieder verwendet werden
  10. end

Das ist eigentlich schon alles, der Bot läuft nun die Wegstrecke ab und killt die entsprechenden Mobs bis die QuestAufgabe erfüllt wurde.

Gäbe es noch eine 2. zu erfüllenden QuestAufgabe, z.B. sammle 10 items, dann müsste folgendes ebenfalls mit eingebaut werden.
Code: Lua
  1. if IsQuestStepDone(12345,2) == false then --Wenn Questschritt 2 nicht erfüllt ist, dann....
  2.     AddGrindingHotspot(x,y,z)
  3.     AddGrindingHotspot(x,y,z)
  4.     AddGrindingHotspot(x,y,z)
  5.     AddGrindingCollectObject(22222) --Hier wurde nun das CollectObject angegegeben, also die ID des zu sammelnden items, die ID erhält man wieder über show Objects des Crawli Editors oder über den Bot.
  6.     DoGrind("QuestCond", 12345,1,2)  --Hier wurde nun die QuestAufgabe 2 eingestellt da die Items gesammelt werden sollen bis Schritt 2 der Quest erfüllt wurde
  7.     ClearGrindingSettings()
  8. end

Wenn nun alle Schritte der Quest erfüllt wurden geht die Funktion in den Block4 der wiederrum die Quest abgibt (siehe oben).

Alle Quest bei denen andere Aufgaben als Kill xxx oder Sammle yyy durchgeführt werden müssen, brauchen entsprechenden eigenen Code im Block3, hierzu wird in kürze aber auch noch ein QuestFramework veröffentlicht das viele weitere Questmethoden auf ähnliche Weise durchführt.

Beispiel Aufruf mehrerer Quests hintereinander:
Code: Lua
  1. function Quest_1()
  2.     ---hier die Questprüfung, Annahme, Durchführung, abgeben
  3. end
  4.  
  5. function Quest_2()
  6.     ---hier die Questprüfung, Annahme, Durchführung, abgeben
  7. end
  8. --> Hier startet die eigentliche Ausführung des Codes!!!
  9. Quest_1() --Hier erfolgt der Aufruf für Quest1 und die Durchführung, erst dann geht es eine zeile tiefer...
  10. Quest_2() --Aufruf der 2. Quest.

Weitere Korrekturen und Ergänzungen folgen noch.

Kolbenhans
« Last Edit: December 20, 2013, 08:42:48 AM by kolbenhans »

December 19, 2013, 14:10:33 PM
Reply #1

HaseHarry Offline

  • *
  • Join Date: Feb 2013
  • Posts: 54
  • Reputation: 8
  • Sklaventreiber
    • View Profile
Schönes ding!
Wer Rechtschreibfehler findet darf sie behalten ;)

January 17, 2014, 21:14:47 PM
Reply #2

hijina Offline

  • *
  • Join Date: Jan 2014
  • Posts: 1
  • Reputation: 0
    • View Profile
Danke erst mal dafür,
habe es mir aufmerksam durchgelesen =)

Allerdings habe ich noch eine Frage, wie gestalte ich es denn, dass er quasi erst zwei Quest annimmt und dann erst los läuft?

Weil zur zeit ist es so:
Quest 1 annehmen, ausführen, abgeben.
Quest 2 annehmen, ausführen, abgeben.

Theoretisch könnte er aber auch Q1 und Q2 annehmen und dann nach einander abarbeiten.

Stehe da gerade irgendwie auf den Schlauch.
Die Lösung ist bestimmt total einfach xD

Danke sehr für die hilfe schon mal im vorraus.

January 17, 2014, 22:17:12 PM
Reply #3

kolbenhans Offline

  • *
  • *
  • Join Date: Dec 2012
  • Posts: 768
  • Reputation: 233
    • View Profile
gibt verschiedene Wege:

Beispiel1: vorteil: kürzer zu schreiben, nachteil: wenn eine von hand erledigt wurde gäbe es probleme deshalb muss immer zusätzlich geprüft werden ob die Quest im Log ist
Code: Lua
  1. Quest_1_and_2()
  2.         AcceptQuest1
  3.     AcceptQuest2
  4.  
  5.     DoQuest1
  6.     DoQuest2
  7.  
  8.     TurninQuest1
  9.     TurninQuest2    
  10. end

Beispiel2: vorteil: läuft auch wenn eine Quest von hand gemacht wurde, nachteil: dauert länger beim erstellen
Code: Lua
  1. Quest_1()      
  2.         AcceptQuest1
  3.  
  4.     Quest_2() --nach dem annehmen der ersten Quest wird die 2. Quest aufgerufen
  5.  
  6.     DoQuest1
  7.    
  8.     --hier Quest2 abgeben wenn in log (prüfung)
  9.     TurninQuest2
  10.     --
  11.     TurninQuest1    
  12. end  
  13.  
  14. Quest_2()
  15.         AcceptQuest2
  16.  
  17.     DoQuest2
  18.  
  19.     --hier nur abgeben wenn Quest1 schon erledigt wurde (prüfung)
  20.     TurninQuest2
  21.     --    
  22. end

...weitere

Yesterday at 07:37:58
Reply #4

Axas Offline

  • *
  • Join Date: Oct 2012
  • Posts: 35
  • Reputation: 7
    • View Profile
Kolbenhans ich hab mal ne frage bezueglich der WasQuestDone() function.

Als damals diese funktion hinzugefuegt wurde wurde sie in der function documentation nur so beschrieben:

Wenn der bot eine quest abschliesst wird eine varible gespeichert.

Was aber wenn ein spieler von hand diese quest abgeschlossen hat?

Die variante mit der variable war mir damals zu unsicher also hatte ich mir eine eigene funktion geschrieben mit der man den quest speicher eines character auslesen kann ueber lua aus dem charcter speicher unabhaengig vom bot.

Macht WasQuestDone() nun das gleiche oder ist das echt nur eine abfrage fuer von dem bot gespeicherten variablen?

Hier ist als beispiel meine funktion. Diese checkt ob irgendwann in der historie des characters die quest schon abgegeben wurde.
Code: Lua
  1. function IsQuestCompleted(qid)
  2.     WowLuaDoString("qc = 0; if GetQuestsCompleted()["..qid.."] then qc= 1; end")
  3.     QuestCheck = tonumber(WowGetLuaValue("qc"))
  4.     if QuestCheck > 0 then
  5.         _Log(qid..": is completed")
  6.         return true
  7.     else
  8.         _Log(qid..": is not completed")
  9.         return false
  10.     end
  11. end


Meine finale frage ist: macht die WasQuestDone() funktion das gleiche? Ich war mir nie sicher :-)

Yesterday at 16:49:47
Reply #5

kolbenhans Offline

  • *
  • *
  • Join Date: Dec 2012
  • Posts: 768
  • Reputation: 233
    • View Profile
Moin Axas,

die Funktion im Bot ist die gleiche, allerdings gibt es manchmal den Fehler das die QuestDaten nicht vom Server abgerufen werden könnne und desalb schreibt oder schrieb die Funktion TurninQuest... auch noch die QuestID in eine INI Datei die ebenfalls mit abgefragt wird/wurde.

Die schwierigkeiten bei dem Abruf der Quests aus WoW heraus treten meistens dann auf wenn man einen 24h disconnect oder absturz von wow hatte, da hilft dann nur ausloggen, realm wechseln, dann wieder zurück.

ich habe mittlerweile eine function in meinem scripten die am Anfang prüft ob die OnlineQuests abgefragt werden könnne, ansonsten gebe ich einen hinweis aus und stoppe das script.

VG Kolbenhans

 

* Recent Topics

* Useful Stuff