aboutsummaryrefslogtreecommitdiff
path: root/internal/game/cmd_construct.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-06-19 13:28:06 -0400
committerhistoria <[not public]>2026-06-19 13:28:06 -0400
commit3a58125d14bb307f861b38c6c5b0a63babde7e08 (patch)
treebd89e866447d55e6dffd447d8ef5fabf9b8fbe9d /internal/game/cmd_construct.go
parent575a71dcfed3b9fa44af244836f638a23df05a9a (diff)
downloadthehouseoficarus-3a58125d14bb307f861b38c6c5b0a63babde7e08.tar.gz
feat: all skills kind of implemented, random prototype content added
Diffstat (limited to 'internal/game/cmd_construct.go')
-rw-r--r--internal/game/cmd_construct.go157
1 files changed, 157 insertions, 0 deletions
diff --git a/internal/game/cmd_construct.go b/internal/game/cmd_construct.go
new file mode 100644
index 0000000..4ab6409
--- /dev/null
+++ b/internal/game/cmd_construct.go
@@ -0,0 +1,157 @@
+package game
+
+import (
+ "strings"
+
+ "thehouseoficarus/internal/action"
+ "thehouseoficarus/internal/net"
+ "thehouseoficarus/internal/player"
+ "thehouseoficarus/internal/world"
+)
+
+func (g *Game) doConstruct(sess *net.Session, input string) {
+ p := sess.Player.(*player.Player)
+ g.CancelAction(p)
+
+ allRecipes, err := g.RecipeStore.LoadAll()
+ if err != nil {
+ sess.WriteLine("Error loading recipes.")
+ return
+ }
+
+ var constructRecipes []action.RecipeDef
+ for _, r := range allRecipes {
+ if r.Type != "construction" {
+ continue
+ }
+ if !g.constructRecipeVisible(p, &r) {
+ continue
+ }
+ constructRecipes = append(constructRecipes, r)
+ }
+
+ if input != "" {
+ g.doConstructWithInput(sess, p, constructRecipes, input)
+ return
+ }
+
+ lastRecipeID, _ := p.Flags["last_construct"].(string)
+ if lastRecipeID != "" {
+ for i := range constructRecipes {
+ if constructRecipes[i].ID == lastRecipeID {
+ r := &constructRecipes[i]
+ if g.canDoConstructRecipe(p, r) {
+ g.startConstructRecipe(sess, p, r, 0)
+ return
+ }
+ break
+ }
+ }
+ }
+
+ available := g.availableConstructRecipes(p, constructRecipes)
+ if len(available) == 0 {
+ sess.WriteLine("You don't have any materials to construct.")
+ return
+ }
+
+ if p.OptionBool("construct_all") && len(available) == 1 {
+ g.startConstructRecipe(sess, p, &available[0], 0)
+ return
+ }
+
+ g.showProductionTable(sess, p, available, "Construction", "construction", "last_construct", "Construct", false)
+}
+
+func (g *Game) doConstructWithInput(sess *net.Session, p *player.Player, constructRecipes []action.RecipeDef, input string) {
+ qty, productName := parseQty(input)
+ productName = strings.TrimSpace(productName)
+
+ var matched []action.RecipeDef
+ for _, r := range constructRecipes {
+ outDef, _ := g.ItemStore.Load(r.Output)
+ name := r.Output
+ if outDef != nil {
+ name = outDef.Name
+ }
+ if world.WordPrefixMatch(productName, name) {
+ matched = append(matched, r)
+ }
+ }
+
+ if len(matched) == 0 {
+ sess.WriteLine("You can't construct that.")
+ return
+ }
+
+ var available []action.RecipeDef
+ for _, r := range matched {
+ if g.canDoConstructRecipe(p, &r) {
+ available = append(available, r)
+ }
+ }
+
+ if len(available) == 0 {
+ sess.WriteLine("You don't have the materials or level for that.")
+ return
+ }
+
+ if len(available) == 1 {
+ g.startConstructRecipe(sess, p, &available[0], qty)
+ return
+ }
+
+ g.showProductionTable(sess, p, available, "Construction", "construction", "last_construct", "Construct", false)
+}
+
+func (g *Game) constructRecipeVisible(p *player.Player, r *action.RecipeDef) bool {
+ if len(r.Station) > 0 {
+ stID, _ := g.findStation(p.RoomID, r.Station)
+ if stID == "" {
+ return false
+ }
+ }
+ if r.Tool != "" && !g.hasToolType(p, r.Tool) {
+ return false
+ }
+ return true
+}
+
+func (g *Game) canDoConstructRecipe(p *player.Player, r *action.RecipeDef) bool {
+ if p.Level(player.Construction) < r.Level {
+ return false
+ }
+ if !r.HasAllItemsQty(p.CountItem) {
+ return false
+ }
+ if len(r.Station) > 0 {
+ stID, _ := g.findStation(p.RoomID, r.Station)
+ if stID == "" {
+ return false
+ }
+ }
+ if r.Tool != "" && !g.hasToolType(p, r.Tool) {
+ return false
+ }
+ return true
+}
+
+func (g *Game) availableConstructRecipes(p *player.Player, allConstruct []action.RecipeDef) []action.RecipeDef {
+ var result []action.RecipeDef
+ for _, r := range allConstruct {
+ if r.HasAllItemsQty(p.CountItem) {
+ result = append(result, r)
+ }
+ }
+ return result
+}
+
+func (g *Game) startConstructRecipe(sess *net.Session, p *player.Player, recipe *action.RecipeDef, count int) {
+ if p.Flags == nil {
+ p.Flags = make(map[string]any)
+ }
+ p.Flags["last_construct"] = recipe.ID
+ g.AccountStore.SaveCharacter(p)
+
+ g.startProductionFromRecipe(sess, p, recipe, count)
+}