add crafting action

This commit is contained in:
Rokas Puzonas 2024-08-09 00:30:44 +03:00
parent 166ff8e892
commit 6eb89eae24
2 changed files with 112 additions and 51 deletions

View File

@ -44,9 +44,9 @@ pub const FightError = APIError || error {
MonsterNotFound,
};
pub const GatheringError = APIError || error {
pub const GatherError = APIError || error {
CharacterIsBusy,
CharacterMissingSkill,
NotEnoughSkill,
CharacterIsFull,
CharacterNotFound,
CharacterInCooldown,
@ -92,6 +92,17 @@ pub const BankWithdrawItemError = APIError || error {
BankNotFound
};
pub const CraftError = APIError || error {
RecipeNotFound,
NotEnoughItems,
CharacterIsBusy,
NotEnoughSkill,
CharacterIsFull,
CharacterNotFound,
CharacterInCooldown,
WorkshopNotFound
};
const ServerStatus = struct {
allocator: Allocator,
status: []const u8,
@ -297,9 +308,8 @@ pub const FightResult = struct {
}
};
pub const GatheringResult = struct {
const Details = struct {
const Item = struct {
pub const SkillDetails = struct {
pub const Item = struct {
id: ItemId,
quantity: i64
};
@ -307,7 +317,7 @@ pub const GatheringResult = struct {
xp: i64,
items: std.BoundedArray(Item, 8),
fn parse(api: *ArtifactsAPI, obj: json.ObjectMap) !Details {
fn parse(api: *ArtifactsAPI, obj: json.ObjectMap) !SkillDetails {
var items = std.BoundedArray(Item, 8).init(0) catch unreachable;
const items_obj = json_utils.getArray(obj, "items") orelse return error.MissingProperty;
for (items_obj.items) |item_value| {
@ -320,34 +330,35 @@ pub const GatheringResult = struct {
});
}
return Details{
return SkillDetails{
.xp = try json_utils.getIntegerRequired(obj, "xp"),
.items = items,
};
}
};
pub const GatherResult = struct {
cooldown: Cooldown,
details: Details,
details: SkillDetails,
pub fn parse(api: *ArtifactsAPI, obj: json.ObjectMap) !GatheringResult {
pub fn parse(api: *ArtifactsAPI, obj: json.ObjectMap) !GatherResult {
const cooldown = json_utils.getObject(obj, "cooldown") orelse return error.MissingProperty;
const details = json_utils.getObject(obj, "details") orelse return error.MissingProperty;
return GatheringResult{
return GatherResult{
.cooldown = try Cooldown.parse(cooldown),
.details = try Details.parse(api, details)
.details = try SkillDetails.parse(api, details)
};
}
pub fn parseError(status: std.http.Status) ?GatheringError {
pub fn parseError(status: std.http.Status) ?GatherError {
return switch (@intFromEnum(status)) {
486 => return GatheringError.CharacterIsBusy,
493 => return GatheringError.CharacterMissingSkill,
497 => return GatheringError.CharacterIsFull,
498 => return GatheringError.CharacterNotFound,
499 => return GatheringError.CharacterInCooldown,
598 => return GatheringError.ResourceNotFound,
486 => return GatherError.CharacterIsBusy,
493 => return GatherError.NotEnoughSkill,
497 => return GatherError.CharacterIsFull,
498 => return GatherError.CharacterNotFound,
499 => return GatherError.CharacterInCooldown,
598 => return GatherError.ResourceNotFound,
else => null
};
}
@ -468,6 +479,35 @@ pub const ItemTransactionResult = struct {
}
};
pub const CraftResult = struct {
cooldown: Cooldown,
details: SkillDetails,
pub fn parse(api: *ArtifactsAPI, obj: json.ObjectMap) !CraftResult {
const cooldown = json_utils.getObject(obj, "cooldown") orelse return error.MissingProperty;
const details = json_utils.getObject(obj, "details") orelse return error.MissingProperty;
return CraftResult{
.cooldown = try Cooldown.parse(cooldown),
.details = try SkillDetails.parse(api, details)
};
}
pub fn parseError(status: std.http.Status) ?CraftError {
return switch (@intFromEnum(status)) {
404 => return CraftError.RecipeNotFound,
478 => return CraftError.NotEnoughItems,
486 => return CraftError.CharacterIsBusy,
493 => return CraftError.NotEnoughSkill,
497 => return CraftError.CharacterIsFull,
498 => return CraftError.CharacterNotFound,
499 => return CraftError.CharacterInCooldown,
598 => return CraftError.WorkshopNotFound,
else => null
};
}
};
pub const ArtifactsFetchResult = struct {
arena: std.heap.ArenaAllocator,
status: std.http.Status,
@ -741,15 +781,15 @@ pub fn actionFight(self: *ArtifactsAPI, name: []const u8) FightError!FightResult
);
}
pub fn actionGathering(self: *ArtifactsAPI, name: []const u8) GatheringError!GatheringResult {
pub fn actionGather(self: *ArtifactsAPI, name: []const u8) GatherError!GatherResult {
const path = try std.fmt.allocPrint(self.allocator, "/my/{s}/action/gathering", .{name});
defer self.allocator.free(path);
return try self.fetchObject(
GatheringError,
GatheringResult.parseError,
GatheringResult,
GatheringResult.parse, .{ },
GatherError,
GatherResult.parseError,
GatherResult,
GatherResult.parse, .{ },
.{ .method = .POST, .path = path }
);
}
@ -852,6 +892,27 @@ pub fn actionBankWithdrawItem(
);
}
pub fn actionCraft(
self: *ArtifactsAPI,
name: []const u8,
code: []const u8,
quantity: u64
) !CraftResult {
const path = try std.fmt.allocPrint(self.allocator, "/my/{s}/action/crafting", .{name});
defer self.allocator.free(path);
const payload = try std.fmt.allocPrint(self.allocator, "{{ \"code\":\"{s}\",\"quantity\":{} }}", .{code, quantity});
defer self.allocator.free(payload);
return try self.fetchObject(
CraftError,
CraftResult.parseError,
CraftResult,
CraftResult.parse, .{ },
.{ .method = .POST, .path = path, .payload = payload }
);
}
test "parse date time" {
try std.testing.expectEqual(1723069394.105, parseDateTime("2024-08-07T22:23:14.105Z").?);
}

View File

@ -24,7 +24,7 @@ const Position = struct {
const QueuedAction = union(enum) {
move: Position,
attack,
gathering,
gather,
depositGold: u64,
depositItem: struct { id: ArtifactsAPI.ItemId, quantity: u64 },
};
@ -172,7 +172,7 @@ fn gatherResourceRoutine(managed_char: *ManagedCharacter, resource_pos: Position
return;
}
try action_queue.append(.{ .gathering = {} });
try action_queue.append(.{ .gather = {} });
}
pub fn main() !void {
@ -259,9 +259,9 @@ pub fn main() !void {
cooldown = result.cooldown;
char.character.inventory.removeItem(item.id, item.quantity);
},
.gathering => {
.gather => {
std.log.debug("{s} gathers", .{char.character.name});
var result = try api.actionGathering(char.character.name);
var result = try api.actionGather(char.character.name);
cooldown = result.cooldown;
for (result.details.items.slice()) |item| {