Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Orders #28

Merged
merged 4 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .artifactsmmo-engine.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,16 @@ characters:
- name: Milnor
actions:
- gather
- bank
- name: Bilnor
actions:
- gather
- bank
- name: Wilnor
actions:
- gather
- bank
- name: Jilnor
actions:
- gather
- bank
- name: Vilnor
actions:
- gather
- bank
- refine
12 changes: 7 additions & 5 deletions cmd/engine/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/promiseofcake/artifactsmmo-engine/internal/actions"
"github.com/promiseofcake/artifactsmmo-engine/internal/engine"
"github.com/promiseofcake/artifactsmmo-engine/internal/logging"
"github.com/promiseofcake/artifactsmmo-engine/internal/models"
)

func init() {
Expand All @@ -33,9 +34,10 @@ const (
)

type Config struct {
Token string `mapstructure:"token"`
LogLevel int `mapstructure:"log_level"`
Characters []Character `mapstructure:"characters"`
Token string `mapstructure:"token"`
LogLevel int `mapstructure:"log_level"`
Characters []Character `mapstructure:"characters"`
Orders models.SimpleItems `mapstructure:"orders"`
}

type Character struct {
Expand Down Expand Up @@ -74,15 +76,15 @@ func main() {

charCtx := logging.ContextWithLogger(ctx, slog.With("character", c.Name))
l := logging.Get(charCtx)
l.Info("starting BuildInventory engine", "actions", c.Actions)
l.Info("starting execute engine", "actions", c.Actions)

go func(charCtx context.Context) {
defer wg.Done()
err = blockInitialAction(charCtx, r, c.Name)
if err != nil {
log.Fatal(err)
}
err = engine.BuildInventory(charCtx, r, c.Name, c.Actions)
err = engine.Execute(charCtx, r, c.Name, c.Actions, cfg.Orders)
if err != nil {
log.Fatal(err)
}
Expand Down
98 changes: 89 additions & 9 deletions internal/actions/state.go
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
package actions

import (
"cmp"
"context"
"fmt"
"net/http"
"slices"

"github.com/promiseofcake/artifactsmmo-go-client/client"

"github.com/promiseofcake/artifactsmmo-engine/internal/models"
)

// GetBankItems returns all items in the bank
func (r *Runner) GetBankItems(ctx context.Context) (models.BankItems, error) {
func (r *Runner) GetBankItems(ctx context.Context) (models.SimpleItems, error) {
resp, err := r.Client.GetBankItemsMyBankItemsGetWithResponse(ctx, &client.GetBankItemsMyBankItemsGetParams{})
if err != nil {
return models.BankItems{}, fmt.Errorf("failed to get bank items: %w", err)
return models.SimpleItems{}, fmt.Errorf("failed to get bank items: %w", err)
}

if resp.StatusCode() != http.StatusOK {
return models.BankItems{}, fmt.Errorf("failed to get bank items: %s (%d)", resp.Body, resp.StatusCode())
return models.SimpleItems{}, fmt.Errorf("failed to get bank items: %s (%d)", resp.Body, resp.StatusCode())
}

var bank models.BankItems
var bank models.SimpleItems
for _, i := range resp.JSON200.Data {
item := models.BankItem{
item := models.SimpleItem{
Code: i.Code,
Quantity: i.Quantity,
}
Expand Down Expand Up @@ -55,8 +57,44 @@ func (r *Runner) GetMyCharacterInfo(ctx context.Context, character string) (mode
return models.Character{}, fmt.Errorf("failed to find character: %s", character)
}

// GetMaps fetches world state based upon a given content type
func (r *Runner) GetMaps(ctx context.Context, contentType client.GetAllMapsMapsGetParamsContentType) (models.Locations, error) {
// GetMapsByContentCode fetches world state based upon a given content code
func (r *Runner) GetMapsByContentCode(ctx context.Context, contentCode string) (models.Locations, error) {
resp, err := r.Client.GetAllMapsMapsGetWithResponse(ctx, &client.GetAllMapsMapsGetParams{
ContentCode: &contentCode,
})
if err != nil {
return nil, fmt.Errorf("failed to fetch maps for content: %s %w", contentCode, err)
}

if resp.StatusCode() != http.StatusOK {
return nil, fmt.Errorf("failed to fetch maps: %s (%d)", resp.Body, resp.StatusCode())
}

var locs models.Locations
for _, l := range resp.JSON200.Data {
s, dataErr := l.Content.AsMapContentSchema()
if dataErr != nil {
return nil, fmt.Errorf("failed to extra map content schema: %w", err)
}

loc := models.Location{
Name: l.Name,
Skin: l.Skin,
Coords: models.Coords{
X: l.X,
Y: l.Y,
},
Code: s.Code,
Type: s.Type,
}

locs = append(locs, loc)
}
return locs, nil
}

// GetMapsByContentType fetches world state based upon a given content type
func (r *Runner) GetMapsByContentType(ctx context.Context, contentType client.GetAllMapsMapsGetParamsContentType) (models.Locations, error) {
resp, err := r.Client.GetAllMapsMapsGetWithResponse(ctx, &client.GetAllMapsMapsGetParams{
ContentType: &contentType,
})
Expand Down Expand Up @@ -174,7 +212,40 @@ func (r *Runner) GetMonsters(ctx context.Context, min, max int) (models.Monsters
return monsters, nil
}

func (r *Runner) GetResources(ctx context.Context, skill client.ResourceSchemaSkill, min, max int) (models.Resources, error) {
func (r *Runner) GetResourcesByDrop(ctx context.Context, drop string) (models.Resources, error) {
resp, err := r.Client.GetAllResourcesResourcesGetWithResponse(ctx, &client.GetAllResourcesResourcesGetParams{
Drop: &drop,
})
if err != nil {
return nil, fmt.Errorf("failed to fetch resources for drop %s, %w", drop, err)
}
if resp.StatusCode() != http.StatusOK {
return nil, fmt.Errorf("status failure (%d), message: %s", resp.StatusCode(), resp.Body)
}

var resources models.Resources
for _, res := range resp.JSON200.Data {

locations, lErr := r.GetMapsByContentCode(ctx, res.Code)
if lErr != nil || len(locations) == 0 {
return nil, fmt.Errorf("failed to find resource locations: %w", err)
}

resource := models.Resource{
Name: res.Name,
Code: res.Code,
Skill: res.Skill,
Level: res.Level,
Location: locations[0], // todo allow more locations
}
resources = append(resources, resource)
}

return resources, nil
}

// GetResourcesBySkill returns all resources (and location) for resources in a given skill / level range
func (r *Runner) GetResourcesBySkill(ctx context.Context, skill client.ResourceSchemaSkill, min, max int) (models.Resources, error) {
if min < 0 {
min = 0
}
Expand All @@ -199,15 +270,24 @@ func (r *Runner) GetResources(ctx context.Context, skill client.ResourceSchemaSk

var resources models.Resources
for _, res := range resp.JSON200.Data {
locations, lErr := r.GetMapsByContentCode(ctx, res.Code)
if lErr != nil || len(locations) == 0 {
return nil, fmt.Errorf("failed to find resource locations: %w", err)
}

resource := models.Resource{
Name: res.Name,
Code: res.Code,
Skill: res.Skill,
Level: res.Level,
Location: models.Location{},
Location: locations[0], // todo allow more locations
}
resources = append(resources, resource)
}

slices.SortFunc(resources, func(a, b models.Resource) int {
return cmp.Compare(b.Level, a.Level)
})

return resources, nil
}
53 changes: 23 additions & 30 deletions internal/engine/decision.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,18 @@ import (
// ideally this is an event that is run until a stop value is returned
type Operation func(ctx context.Context, r *actions.Runner, character models.Character) bool

// BuildInventory commands a character to focus on building their inventory
// Execute commands a character to focus on building their inventory
// for harvestable items
func BuildInventory(ctx context.Context, r *actions.Runner, character string, actions []string) error {
func Execute(ctx context.Context, r *actions.Runner, character string, actions []string, orders models.SimpleItems) error {
l := logging.Get(ctx)

var operations []Operation
for _, op := range actions {
switch op {
case "bank":
operations = append(operations, bank)
case "gather":
operations = append(operations, gather)
// fallthrough
case "forage":
operations = append(operations, forage)
case "refine":
operations = append(operations, refine)
}
Expand All @@ -52,7 +52,19 @@ func BuildInventory(ctx context.Context, r *actions.Runner, character string, ac
l.Debug("operation loop canceled.")
return nil
default:
// TODO this isnt' right

l.Debug("checking for orders to fulfil", "orders", orders)
for _, o := range orders {
if ShouldFulfilOrder(ctx, r, c, o) {
l.Debug("order required to be fulfilled", "order", o)
oErr := FulfilOrder(ctx, r, character, o)
if oErr != nil {
l.Error("failed to fulfil order", "order", o, "error", oErr)
}
}
}

l.Debug("performing designated tasks", "tasks", operations)
currentIndex = (currentIndex + 1) % len(operations)
for !operations[currentIndex](ctx, r, c) {
select {
Expand All @@ -68,39 +80,20 @@ func BuildInventory(ctx context.Context, r *actions.Runner, character string, ac
}

// Operation loops
func bank(ctx context.Context, r *actions.Runner, character models.Character) bool {
l := logging.Get(ctx)
for {
select {
case <-ctx.Done():
l.Debug("banking context closed")
return true
default:
l.Debug("banking")
err := DepositAll(ctx, r, character.Name)
if err != nil {
panic(err)
}
l.Debug("banking done")
return true
}
}
}

func gather(ctx context.Context, r *actions.Runner, character models.Character) bool {
func forage(ctx context.Context, r *actions.Runner, character models.Character) bool {
l := logging.Get(ctx)
for {
select {
case <-ctx.Done():
l.Debug("gather context closed")
l.Debug("foraging context closed")
return true
default:
l.Debug("gathering")
err := Gather(ctx, r, character.Name)
l.Debug("foraging")
err := Forage(ctx, r, character.Name)
if err != nil {
panic(err)
}
l.Debug("gathering done")
l.Debug("foraging done")
return true
}
}
Expand Down
2 changes: 1 addition & 1 deletion internal/engine/fight.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func Fight(ctx context.Context, r *actions.Runner, character string) error {
return err
}

monsterLocations, err := r.GetMaps(ctx, client.Monster)
monsterLocations, err := r.GetMapsByContentType(ctx, client.Monster)
if err != nil {
l.Error("failed to get monster locations", "error", err)
return err
Expand Down
Loading
Loading