# WRobot Quest Profile Tutorial
**Source:** https://wrobot.eu/forums/topic/374-how-to-create-quest-profile/
**Author:** Droidz (Creator of WRobot)

---

## QUEST PROFILE STRUCTURE

Quest profile = 2 files:
1. **Quests.cs** - C# code (what bot does for quest objectives, one class per quest)
2. **Profile.xml** - XML code (quest order, NPC list, vendors)

---

## QUEST TOOLS (Profile Creator Helper)

1. Get target Entry & Position → C# syntax for current target
2. Get player position → Your coordinates
3. Get GameObject info → Objects by name
4. Get Unit info → Units by name  
5. Create base quest class → Auto-gen from WowHead ID
6. Create NPC quest giver → Auto-gen XML from WowHead
7. Get current quest info → Quest status/objectives
8. Convert Zygor guide → Zygor to WRobot
9. Quest Profile Editor → GUI for Profile.xml

---

## PROFILE.XML

**QuestFile:** Path to Quests.cs

**Actions:**
- PickUp → Accept quest from NPC
- Pulse → Execute quest objectives
- TurnIn → Complete quest at NPC
- PulseAllInOne → All 3 in sequence

**NpcQuest:** Quest givers (NPCs/GameObjects)
**Npc:** Vendors, repair, mailbox

---

## QUESTS.CS - SETUP

**Required using statements:**
```csharp
using wManager.Wow.Class;
using robotManager.Helpful;
```

**Use Visual Studio:**
- Create Class Library project
- Add references: wManager.dll, robotManager.dll
- NO namespace in Quests.cs

---

## QUEST TYPES

### 1. Simple (PickUp/TurnIn only)
```csharp
public class QuestName : QuestClass {
    public QuestName() {
        QuestId.Add(54);
    }
}
```

### 2. Kill & Loot
```csharp
public sealed class QuestName : QuestGrinderClass {
    public QuestName() {
        QuestId.Add(28757);
        Step.AddRange(new[] { 6, 0, 0, 0 }); // [obj1, obj2, obj3, obj4]
        HotSpots.Add(new Vector3(-8885.293f, -62.18237f, 85.49203f));
        EntryTarget.Add(49871); // Mob Entry ID
    }
}
```

### 3. Gatherer (Pick objects)
```csharp
public sealed class QuestName : QuestGathererClass {
    public QuestName() {
        QuestId.Add(5545);
        Step.AddRange(new[] { 8, 0, 0, 0 });
        EntryIdObjects.Add(176793); // GameObject ID
        HotSpots.Add(new Vector3(-9364, -1274, 60));
    }
}
```

### 4. Use Item On
```csharp
public sealed class QuestName : QuestUseItemOnClass {
    public QuestName() {
        QuestId.Add(26391);
        Step.AddRange(new[] { 8, 0, 0, 0 });
        ItemId = 58362;
        Range = 5;
        EntryIdTarget.Add(42940); // Target ID
        HotSpots.Add(new Vector3(-8921, -354, 73));
    }
}
```

**Use Spell:** Replace `QuestUseItemOnClass` → `QuestUseSpellOnClass`, `ItemId` → `SpellId`

### 5. Interact With NPC
```csharp
public sealed class QuestName : QuestInteractWithClass {
    public QuestName() {
        QuestId.Add(28813);
        Step.AddRange(new[] { 4, 0, 0, 0 });
        EntryIdTarget.Add(50047);
        GossipOptionNpcInteractWith = 0; // Gossip menu option
        HotSpots.Add(new Vector3(-8781, -105, 83));
    }
}
```

---

## OVERRIDE METHODS

### Can Conditions (Requirements)
```csharp
public override bool CanConditions() {
    if (ObjectManager.Me.WowClass == WoWClass.Monk) return false;
    if (ObjectManager.Me.Level > 5) return false;
    if (ObjectManager.Me.WowRace != WoWRace.Human) return false;
    return true;
}
```

### PickUp from Item
```csharp
public override bool PickUp() {
    ItemsManager.UseItem(ItemsManager.GetNameById(1307));
    Quest.AcceptQuest();
    return true;
}
```

### Custom Pulse (Special logic)
```csharp
private bool _step1;

public override bool Pulse() {
    if (!_step1 && GoToTask.ToPosition(new Vector3(-9097, -565, 61))) {
        Thread.Sleep(3000);
        _step1 = true;
    }
    return true;
}

public override bool IsComplete() {
    if (IsCompleted()) return true;
    if (!HasQuest()) return false;
    return _step1;
}
```

### Multi Quest (same objective, different IDs)
```csharp
public QuestName() {
    // WoW has 9 versions (one per class)
    QuestId.AddRange(new[] { 28757, 28762, 28763, 28764, 28765, 28766, 28767, 31139 });
    Step.AddRange(new[] { 6, 0, 0, 0 });
    // ... rest same as single quest
}
```

---

## COMMON API

```csharp
// Quest checks
Quest.GetQuestCompleted(questId)     // Is completed?
Quest.HasQuest(questId)              // Player has quest?
Quest.AcceptQuest()                  // Accept quest
Quest.IsObjectiveComplete(1, questId) // Objective 1 done?

// Items
ItemsManager.UseItem(itemId)
ItemsManager.GetItemCountById(itemId)

// Player info
ObjectManager.Me.Level
ObjectManager.Me.WowClass
ObjectManager.Me.WowRace

// Cast spell
RunMacroText("/cast SpellName")
CastSpell(1, "spell")  // Cast 1st spell in spellbook
```

---

## PROFILE.XML EXAMPLE

```xml
<?xml version="1.0" encoding="utf-8"?>
<QuesterProfile>
  <QuestFile>Quests.cs</QuestFile>
  
  <QuestsSorted>
    <QuestsSorted Action="PickUp" NameClass="MyQuest" />
    <QuestsSorted Action="Pulse" NameClass="MyQuest" />
    <QuestsSorted Action="TurnIn" NameClass="MyQuest" />
  </QuestsSorted>
  
  <NpcQuest>
    <NPCQuest Id="1234" Name="Quest Giver" GameObject="false">
      <PickUpQuests><int>54</int></PickUpQuests>
      <TurnInQuests><int>54</int></TurnInQuests>
      <Position X="-8854.09" Y="-205.618" Z="81.7792" Type="None" />
    </NPCQuest>
  </NpcQuest>
</QuesterProfile>
```

---

## TROUBLESHOOTING

**Error: "Cannot find type QuestGrinderClass"**
→ Add `using wManager.Wow.Class;` at top

**Quest won't start**
→ Check NameClass matches class name exactly (case-sensitive)

**Compilation errors**
→ Add both using statements, check C# syntax

**Can't find WowHead IDs**
→ URL: wowhead.com/quest=QUESTID or wowhead.com/npc=NPCID

---

## TIPS

1. Use Quest Tools for auto-generation
2. Check WRobot/Profiles/Quester/Cache/ for converted examples
3. Test simple quests first
4. Use WowHead for quest/NPC IDs
5. Download creature positions: wrobot.eu → Data_creature.csv.zip
