Skip to content

Commit f7fd71c

Browse files
Merge pull request #496 from FFXIV-CombatReborn/ElliLib-Integration
Fishing Generator Improvements
2 parents ff3e092 + 8838439 commit f7fd71c

File tree

14 files changed

+817
-173
lines changed

14 files changed

+817
-173
lines changed

GatherBuddy.GameData/Data/Fish/Data3.0.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ private static void ApplyHeavensward(this GameData data)
243243
.Bait (data, 12707)
244244
.Bite (data, HookSet.Precise, BiteType.Weak);
245245
data.Apply (12780, Patch.Heavensward) // Sweetfish
246-
.Bait (data, 12706)
246+
.Bait (data, 12707)
247247
.Bite (data, HookSet.Powerful, BiteType.Strong)
248248
.Snag (data, Snagging.None);
249249
data.Apply (12781, Patch.Heavensward) // Orn Butterfly

GatherBuddy/AutoGather/AutoGather.Actions.cs

Lines changed: 11 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,14 @@ private unsafe void DoActionTasks(IEnumerable<GatherTarget> target)
138138

139139
private unsafe void DoFishingTasks(IEnumerable<GatherTarget> targets)
140140
{
141+
if (TryUseFoodAndMedicine())
142+
return;
143+
141144
if (SpiritbondMax > 0)
142145
{
146+
if (GatherBuddy.Config.AutoGatherConfig.DeferMateriaExtractionDuringFishingBuffs && (IsFishing || HasActiveFishingBuff()))
147+
return;
148+
143149
if (IsGathering || IsFishing)
144150
{
145151
if (GatherBuddy.Config.AutoGatherConfig.UseAutoHook && AutoHook.Enabled)
@@ -171,7 +177,10 @@ private unsafe void DoFishingTasks(IEnumerable<GatherTarget> targets)
171177

172178
if (FreeInventorySlots < 20 && HasReducibleItems())
173179
{
174-
if (IsFishing)
180+
if (GatherBuddy.Config.AutoGatherConfig.DeferReductionDuringFishingBuffs && (IsFishing || HasActiveFishingBuff()))
181+
return;
182+
183+
if (IsFishing || IsGathering)
175184
{
176185
QueueQuitFishingTasks();
177186
return;
@@ -186,7 +195,7 @@ private unsafe void DoFishingTasks(IEnumerable<GatherTarget> targets)
186195
});
187196
}
188197

189-
ReduceItems(false, () =>
198+
ReduceItems(true, () =>
190199
{
191200
if (GatherBuddy.Config.AutoGatherConfig.UseAutoHook && AutoHook.Enabled)
192201
{
@@ -230,40 +239,6 @@ private void HandleReady(GatherTarget target, ConfigPreset config)
230239

231240
SetupAutoHookForFishing(target);
232241

233-
var bait = GetCorrectBaitId(target);
234-
if (bait == 0)
235-
{
236-
Communicator.Print($"No bait found in inventory. Auto-fishing cannot continue.");
237-
AbortAutoGather();
238-
}
239-
240-
if (bait != GatherBuddy.CurrentBait.Current)
241-
{
242-
var switchResult = GatherBuddy.CurrentBait.ChangeBait(bait);
243-
switch (switchResult)
244-
{
245-
case CurrentBait.ChangeBaitReturn.InvalidBait:
246-
GatherBuddy.Log.Error("Invalid bait selected: " + bait);
247-
AbortAutoGather();
248-
break;
249-
case CurrentBait.ChangeBaitReturn.NotInInventory:
250-
Communicator.Print(
251-
$"Bait '{target.Fish!.InitialBait.Name}' for fish '{target.Fish!.Name[GatherBuddy.Language]}' not in inventory. Auto-fishing cannot continue.");
252-
AbortAutoGather();
253-
break;
254-
case CurrentBait.ChangeBaitReturn.Success:
255-
case CurrentBait.ChangeBaitReturn.AlreadyEquipped:
256-
break;
257-
case CurrentBait.ChangeBaitReturn.UnknownError:
258-
GatherBuddy.Log.Error("Unknown error when switching bait. Auto-gather cannot continue.");
259-
AbortAutoGather();
260-
break;
261-
}
262-
263-
TaskManager.DelayNext(1000);
264-
return;
265-
}
266-
267242
if (GatherBuddy.Config.AutoGatherConfig.UseAutoHook && AutoHook.Enabled)
268243
{
269244
var hasSnagStatus = Player.Status.Any(s => s.StatusId == 761);
@@ -331,22 +306,6 @@ private bool NeedsSurfaceSlap(GatherTarget target)
331306
return false;
332307
}
333308

334-
private uint GetCorrectBaitId(GatherTarget target)
335-
{
336-
var bait = target.Fish!.InitialBait;
337-
if (GetInventoryItemCount(bait.Id) > 0)
338-
return bait.Id;
339-
340-
var versatileLure = GatherBuddy.GameData.Bait[29717];
341-
if (GetInventoryItemCount(versatileLure.Id) > 0)
342-
return versatileLure.Id;
343-
344-
var firstBait = GatherBuddy.GameData.Bait.FirstOrDefault();
345-
if (GetInventoryItemCount(firstBait.Value.Id) > 0)
346-
return firstBait.Value.Id;
347-
348-
return 0;
349-
}
350309

351310
private bool HasPatienceStatus()
352311
{

GatherBuddy/AutoGather/AutoGather.Config.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,22 @@ public class AutoGatherConfig
101101
public bool UseHookTimers { get; set; } = false;
102102
public bool AutoCollectablesFishing { get; set; } = true;
103103
public bool DiademAutoAetherCannon { get; set; } = false;
104+
public bool DeferRepairDuringFishingBuffs { get; set; } = true;
105+
public bool DeferReductionDuringFishingBuffs { get; set; } = true;
106+
public bool DeferMateriaExtractionDuringFishingBuffs { get; set; } = true;
107+
public bool UseFood { get; set; } = false;
108+
public uint FoodItemId { get; set; } = 0;
109+
public bool UseMedicine { get; set; } = false;
110+
public uint MedicineItemId { get; set; } = 0;
111+
public bool UseCordialForFishing { get; set; } = false;
112+
public int CordialForFishingGPThreshold { get; set; } = 0;
113+
public bool UsePatience { get; set; } = true;
114+
public bool UsePrizeCatch { get; set; } = false;
115+
public int PrizeCatchGPThreshold { get; set; } = 200;
116+
public bool PrizeCatchGPAbove { get; set; } = true;
117+
public bool UseChum { get; set; } = false;
118+
public int ChumGPThreshold { get; set; } = 100;
119+
public bool ChumGPAbove { get; set; } = true;
104120

105121
public enum SortingType
106122
{
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
using System.Linq;
2+
using GatherBuddy.Helpers;
3+
4+
namespace GatherBuddy.AutoGather;
5+
6+
public partial class AutoGather
7+
{
8+
private static readonly uint[] FishingBuffIds =
9+
[
10+
850, // Angler's Fortune (Patience)
11+
1803, // Surface Slap
12+
1804, // Identical Cast
13+
2779, // Makeshift Bait
14+
2780, // Prize Catch
15+
568, // Fisher's Intuition
16+
763, // Chum
17+
762, // Fish Eyes
18+
3907, // Big Game Fishing
19+
3972, // Ambitious Lure
20+
3973 // Modest Lure
21+
];
22+
23+
private bool HasActiveFishingBuff()
24+
{
25+
var player = Dalamud.Objects.LocalPlayer;
26+
if (player == null)
27+
return false;
28+
29+
return player.StatusList.Any(status => FishingBuffIds.Contains(status.StatusId));
30+
}
31+
32+
private bool HasFoodBuff()
33+
{
34+
var player = Dalamud.Objects.LocalPlayer;
35+
if (player == null)
36+
return false;
37+
38+
return player.StatusList.Any(status => status.StatusId == 48);
39+
}
40+
41+
private bool HasMedicineBuff()
42+
{
43+
var player = Dalamud.Objects.LocalPlayer;
44+
if (player == null)
45+
return false;
46+
47+
return player.StatusList.Any(status => status.StatusId == 49);
48+
}
49+
50+
private bool TryUseFoodAndMedicine()
51+
{
52+
if (Player.Job != 18)
53+
return false;
54+
55+
var config = GatherBuddy.Config.AutoGatherConfig;
56+
var needFood = config.UseFood && config.FoodItemId > 0 && !HasFoodBuff() && GetInventoryItemCount(config.FoodItemId) > 0;
57+
var needMed = config.UseMedicine && config.MedicineItemId > 0 && !HasMedicineBuff() && GetInventoryItemCount(config.MedicineItemId) > 0;
58+
59+
if (!needFood && !needMed)
60+
return false;
61+
62+
if (HasActiveFishingBuff())
63+
return false;
64+
65+
if (IsFishing || IsGathering)
66+
{
67+
GatherBuddy.Log.Debug("[Consumables] Quitting fishing to use food/medicine");
68+
QueueQuitFishingTasks();
69+
return true;
70+
}
71+
72+
if (needFood)
73+
{
74+
var itemCount = GetInventoryItemCount(config.FoodItemId);
75+
if (itemCount > 0)
76+
{
77+
GatherBuddy.Log.Information($"[Consumables] Using food item {config.FoodItemId}");
78+
EnqueueActionWithDelay(() => UseItem(config.FoodItemId));
79+
return true;
80+
}
81+
else
82+
{
83+
GatherBuddy.Log.Warning($"[Consumables] Configured food item {config.FoodItemId} not found in inventory");
84+
}
85+
}
86+
87+
if (needMed)
88+
{
89+
GatherBuddy.Log.Information($"[Consumables] Using medicine item {config.MedicineItemId}");
90+
EnqueueActionWithDelay(() => UseItem(config.MedicineItemId));
91+
return true;
92+
}
93+
94+
return false;
95+
}
96+
}

GatherBuddy/AutoGather/AutoGather.FishingCollectable.cs

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,39 @@ private unsafe bool HandleFishingCollectable()
5353

5454
GatherBuddy.Log.Debug($"[AutoCollectable] Detected collectable dialog with text: {text}");
5555

56-
var name = Enum.GetValues<SeIconChar>()
57-
.Cast<SeIconChar>()
58-
.Aggregate(addon->AtkValues[15].String.AsDalamudSeString().TextValue,
59-
(current, enumValue) => current.Replace(enumValue.ToIconString(), ""))
60-
.Trim();
56+
if (addon->AtkValuesCount < 15)
57+
{
58+
GatherBuddy.Log.Debug($"[AutoCollectable] Not enough AtkValues ({addon->AtkValuesCount}), cannot read item ID");
59+
return false;
60+
}
61+
62+
var itemIdEncoded = addon->AtkValues[14].UInt;
63+
if (itemIdEncoded < 500000)
64+
{
65+
GatherBuddy.Log.Debug($"[AutoCollectable] Invalid encoded item ID: {itemIdEncoded}");
66+
return false;
67+
}
68+
69+
var itemId = itemIdEncoded - 500000;
70+
GatherBuddy.Log.Debug($"[AutoCollectable] Extracted item ID: {itemId} (from encoded value {itemIdEncoded})");
6171

6272
var itemSheet = Dalamud.GameData.GetExcelSheet<Item>();
63-
var item = itemSheet.FirstOrDefault(x => x.IsCollectable && !x.Singular.IsEmpty &&
64-
name.Contains(x.Singular.ToString(), StringComparison.InvariantCultureIgnoreCase));
65-
if (item.RowId == 0)
73+
var item = itemSheet.GetRowOrDefault(itemId);
74+
75+
if (item == null || item.Value.RowId == 0)
76+
{
77+
GatherBuddy.Log.Debug($"[AutoCollectable] Failed to find item with ID {itemId}");
78+
return false;
79+
}
80+
81+
var itemValue = item.Value;
82+
if (!itemValue.IsCollectable)
6683
{
67-
GatherBuddy.Log.Debug($"[AutoCollectable] Failed to match any collectable to {name} [original={addon->AtkValues[15].String}]");
84+
GatherBuddy.Log.Debug($"[AutoCollectable] Item [{itemValue.RowId}] {itemValue.Name} is not a collectable");
6885
return false;
6986
}
7087

71-
GatherBuddy.Log.Debug($"[AutoCollectable] Detected item [{item.RowId}] {item.Name}");
88+
GatherBuddy.Log.Debug($"[AutoCollectable] Detected item [{itemValue.RowId}] {itemValue.Name}");
7289

7390
if (!int.TryParse(Regex.Match(text, @"\d+").Value, out var value))
7491
{
@@ -77,35 +94,35 @@ private unsafe bool HandleFishingCollectable()
7794
}
7895

7996
GatherBuddy.Log.Debug($"[AutoCollectable] Detected collectability value: {value}");
80-
GatherBuddy.Log.Debug($"[AutoCollectable] Item data - AetherialReduce: {item.AetherialReduce}, AdditionalData.RowId: {item.AdditionalData.RowId}");
97+
GatherBuddy.Log.Debug($"[AutoCollectable] Item data - AetherialReduce: {itemValue.AetherialReduce}, AdditionalData.RowId: {itemValue.AdditionalData.RowId}");
8198
{
82-
if (item.AetherialReduce > 0)
99+
if (itemValue.AetherialReduce > 0)
83100
{
84-
GatherBuddy.Log.Debug($"[AutoCollectable] Accepting [{item.RowId}] {item.Name} - aethersand fish");
101+
GatherBuddy.Log.Debug($"[AutoCollectable] Accepting [{itemValue.RowId}] {itemValue.Name} - aethersand fish");
85102
Callback.Fire(&addon->AtkUnitBase, true, 0);
86103
return true;
87104
}
88-
else if (item.AdditionalData.RowId != 0)
105+
else if (itemValue.AdditionalData.RowId != 0)
89106
{
90-
var wksItem = Dalamud.GameData.GetExcelSheet<WKSItemInfo>().GetRow(item.AdditionalData.RowId);
107+
var wksItem = Dalamud.GameData.GetExcelSheet<WKSItemInfo>().GetRow(itemValue.AdditionalData.RowId);
91108
if (wksItem.RowId != 0)
92109
{
93-
GatherBuddy.Log.Debug($"[AutoCollectable] Accepting [{item.RowId}] {item.Name} - stellar fish for {wksItem.WKSItemSubCategory.ValueNullable?.Name ?? "null"}");
110+
GatherBuddy.Log.Debug($"[AutoCollectable] Accepting [{itemValue.RowId}] {itemValue.Name} - stellar fish for {wksItem.WKSItemSubCategory.ValueNullable?.Name ?? "null"}");
94111
Callback.Fire(&addon->AtkUnitBase, true, 0);
95112
return true;
96113
}
97114
else
98115
{
99-
GatherBuddy.Log.Debug($"[AutoCollectable] No CollectablesShopItem found for [{item.RowId}] {item.Name}");
116+
GatherBuddy.Log.Debug($"[AutoCollectable] No CollectablesShopItem found for [{itemValue.RowId}] {itemValue.Name}");
100117
}
101118
}
102119
else
103120
{
104-
GatherBuddy.Log.Debug($"[AutoCollectable] No CollectablesShopItem found for [{item.RowId}] {item.Name}");
121+
GatherBuddy.Log.Debug($"[AutoCollectable] No CollectablesShopItem found for [{itemValue.RowId}] {itemValue.Name}");
105122
}
106123
}
107124

108-
GatherBuddy.Log.Debug($"[AutoCollectable] Accepting [{item.RowId}] {item.Name} - generic collectable fish with value {value}");
125+
GatherBuddy.Log.Debug($"[AutoCollectable] Accepting [{itemValue.RowId}] {itemValue.Name} - generic collectable fish with value {value}");
109126
Callback.Fire(&addon->AtkUnitBase, true, 0);
110127
return true;
111128
}

GatherBuddy/AutoGather/AutoGather.Repair.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,9 @@ private bool RepairIfNeededForFishing()
135135
return false;
136136
}
137137

138+
if (GatherBuddy.Config.AutoGatherConfig.DeferRepairDuringFishingBuffs && (IsFishing || HasActiveFishingBuff()))
139+
return false;
140+
138141
if ((DateTime.Now - _lastRepairTime).TotalSeconds < 5)
139142
return false;
140143

0 commit comments

Comments
 (0)