diff options
| author | historia <[not public]> | 2026-06-25 15:40:48 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-06-25 15:40:48 -0400 |
| commit | abd612c15799f604e671e83dc7c410ed2b44185f (patch) | |
| tree | 0597ca92350de73aac2a7cf26b2f2d6595dac0cc /internal/game/action_farm.go | |
| parent | 2725e2927a1595c7b100d942d1f14146252adeb7 (diff) | |
| download | thehouseoficarus-abd612c15799f604e671e83dc7c410ed2b44185f.tar.gz | |
slop refactor
Diffstat (limited to 'internal/game/action_farm.go')
| -rw-r--r-- | internal/game/action_farm.go | 645 |
1 files changed, 0 insertions, 645 deletions
diff --git a/internal/game/action_farm.go b/internal/game/action_farm.go deleted file mode 100644 index 61a66cc..0000000 --- a/internal/game/action_farm.go +++ /dev/null @@ -1,645 +0,0 @@ -package game - -import ( - "fmt" - "math/rand" - "sort" - "strings" - - "thehouseoficarus/internal/action" - "thehouseoficarus/internal/net" - "thehouseoficarus/internal/object" - "thehouseoficarus/internal/player" - "thehouseoficarus/internal/world" -) - -const FarmTickInterval = 500 - -var farmPatchDefIDs = map[string]bool{ - "herb_patch": true, - "allotment_patch": true, - "flower_patch": true, - "bush_patch": true, - "tree_patch": true, -} - -func farmFlagPrefix(defID string, index int) string { - switch defID { - case "herb_patch": - return fmt.Sprintf("farm_herb_%d", index+1) - case "allotment_patch": - return fmt.Sprintf("farm_allot_%d", index+1) - case "flower_patch": - return fmt.Sprintf("farm_flower_%d", index+1) - case "bush_patch": - return fmt.Sprintf("farm_bush_%d", index+1) - case "tree_patch": - return fmt.Sprintf("farm_tree_%d", index+1) - } - return "" -} - -func (g *Game) ensureFarmState(p *player.Player, prefix string) { - p.EnsureFlags() - if _, exists := p.Flags[prefix+"_seed"]; !exists { - p.Flags[prefix+"_weeds"] = true - p.Flags[prefix+"_seed"] = "" - p.Flags[prefix+"_stage"] = 0 - p.Flags[prefix+"_watered"] = false - p.Flags[prefix+"_diseased"] = false - p.Flags[prefix+"_dead"] = false - p.Flags[prefix+"_ready"] = false - } -} - -func (g *Game) findFarmPrefixes(p *player.Player) []string { - seen := make(map[string]bool) - var prefixes []string - for key := range p.Flags { - if !strings.HasPrefix(key, "farm_") { - continue - } - if !strings.HasSuffix(key, "_seed") { - continue - } - prefix := strings.TrimSuffix(key, "_seed") - if !seen[prefix] { - seen[prefix] = true - if seedID, ok := p.Flags[key].(string); ok && seedID != "" { - prefixes = append(prefixes, prefix) - } - } - } - sort.Strings(prefixes) - return prefixes -} - -func (g *Game) FarmTick() { - g.farmTickCounter++ - if g.farmTickCounter < FarmTickInterval { - return - } - g.farmTickCounter = 0 - - if g.Hub == nil { - return - } - - for _, sess := range g.Hub.AllSessions() { - p := sess.Player - if p == nil || p.Flags == nil { - continue - } - g.advanceFarmGrowth(sess, p) - } -} - -func (g *Game) advanceFarmGrowth(sess *net.Session, p *player.Player) { - prefixes := g.findFarmPrefixes(p) - for _, prefix := range prefixes { - seedID, _ := p.Flags[prefix+"_seed"].(string) - if seedID == "" { - continue - } - dead, _ := p.Flags[prefix+"_dead"].(bool) - if dead { - continue - } - diseased, _ := p.Flags[prefix+"_diseased"].(bool) - ready, _ := p.Flags[prefix+"_ready"].(bool) - if ready { - continue - } - - if diseased { - p.Flags[prefix+"_dead"] = true - p.Flags[prefix+"_diseased"] = false - sess.WriteLine(g.colorize(sess, "farm_disease", - fmt.Sprintf("\nYour %s has died from disease!", g.seedDisplayName(sess, seedID)))) - g.AccountStore.SaveCharacter(p) - continue - } - - stage := intFromFlag(p.Flags, prefix+"_stage") - watered, _ := p.Flags[prefix+"_watered"].(bool) - - seedDef, err := g.ItemStore.Load(seedID) - if err != nil { - continue - } - - maxStages := seedDef.FarmStages - if maxStages <= 0 { - maxStages = 4 - } - - stage++ - - if stage >= maxStages { - p.Flags[prefix+"_stage"] = stage - p.Flags[prefix+"_ready"] = true - p.Flags[prefix+"_watered"] = false - sess.WriteLine(g.colorize(sess, "farm_grow", - fmt.Sprintf("\nYour %s is fully grown and ready to harvest!", - g.seedDisplayName(sess, seedID)))) - } else { - if !watered && rand.Float64() < 0.10 { - p.Flags[prefix+"_stage"] = stage - p.Flags[prefix+"_diseased"] = true - p.Flags[prefix+"_watered"] = false - sess.WriteLine(g.colorize(sess, "farm_disease", - fmt.Sprintf("\nYour %s has become diseased!", - g.seedDisplayName(sess, seedID)))) - } else { - p.Flags[prefix+"_stage"] = stage - p.Flags[prefix+"_watered"] = false - sess.WriteLine(g.colorize(sess, "farm_grow", - fmt.Sprintf("\nYour %s has grown to stage %d/%d.", - g.seedDisplayName(sess, seedID), stage, maxStages))) - } - } - g.AccountStore.SaveCharacter(p) - } -} - -func (g *Game) seedDisplayName(sess *net.Session, seedID string) string { - if def, err := g.ItemStore.Load(seedID); err == nil { - return g.itemColorize(sess, def, def.Name) - } - return seedID -} - -func (g *Game) advancePlant(sess *net.Session, p *player.Player) { - if p.Action == nil || p.Action.Data == nil { - return - } - data, ok := p.Action.Data.(*action.FarmData) - if !ok { - return - } - prefix := data.Prefix - seedID := data.SeedID - xp := data.XP - - g.ensureFarmState(p, prefix) - - p.Flags[prefix+"_weeds"] = false - p.Flags[prefix+"_seed"] = seedID - p.Flags[prefix+"_stage"] = 0 - p.Flags[prefix+"_watered"] = false - p.Flags[prefix+"_diseased"] = false - p.Flags[prefix+"_dead"] = false - p.Flags[prefix+"_ready"] = false - - if intXP := int(xp); intXP > 0 { - g.awardSkillXP(sess, p, player.Farming, intXP) - } - - g.AccountStore.SaveCharacter(p) - - seedName := seedID - if def, err := g.ItemStore.Load(seedID); err == nil { - seedName = g.itemColorize(sess, def, def.Name) - } - patchName := patchDisplayName(prefix) - msg := fmt.Sprintf("You plant a %s in the %s.", seedName, patchName) - if int(xp) > 0 && p.OptionBool("xp_drops") { - msg += g.formatXpDropSingle(sess, p, player.Farming, int(xp)) - } - sess.WriteLine(msg) - - p.Action = nil -} - -func (g *Game) advanceHarvest(sess *net.Session, p *player.Player) { - if p.Action == nil || p.Action.Data == nil { - return - } - data, ok := p.Action.Data.(*action.FarmData) - if !ok { - return - } - prefix := data.Prefix - product := data.Product - minYield := data.MinYield - maxYield := data.MaxYield - xp := data.XP - - ready, _ := p.Flags[prefix+"_ready"].(bool) - if !ready { - sess.WriteLine("There's nothing ready to harvest here.") - p.Action = nil - return - } - - yield := int(minYield) + rand.Intn(int(maxYield)-int(minYield)+1) - bonus := p.Level(player.Farming) / 20 - yield += bonus - - freeSlots := p.FreeSlots() - if yield > freeSlots { - productDef, _ := g.ItemStore.Load(product) - if productDef == nil || !productDef.Stackable { - yield = freeSlots - } - } - if yield <= 0 { - sess.WriteLine("Your inventory is too full!") - p.Action = nil - return - } - - productDef, _ := g.ItemStore.Load(product) - if productDef != nil && productDef.Stackable { - added := 0 - for i := 0; i < 28 && added < yield; i++ { - slot := p.InvSlot(i) - if slot != nil && slot.ItemID == product { - slot.Quantity += yield - added = yield - break - } - } - if added == 0 { - freeSlot := p.FirstFreeSlot() - if freeSlot >= 0 { - p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: product, Quantity: yield}) - } - } - } else { - for i := 0; i < yield; i++ { - freeSlot := p.FirstFreeSlot() - if freeSlot < 0 { - break - } - p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: product, Quantity: 1}) - } - } - - if intXP := int(xp); intXP > 0 { - g.awardSkillXP(sess, p, player.Farming, intXP) - } - - g.ensureFarmState(p, prefix) - p.Flags[prefix+"_seed"] = "" - p.Flags[prefix+"_stage"] = 0 - p.Flags[prefix+"_ready"] = false - p.Flags[prefix+"_watered"] = false - p.Flags[prefix+"_weeds"] = true - p.Flags[prefix+"_diseased"] = false - p.Flags[prefix+"_dead"] = false - - g.AccountStore.SaveCharacter(p) - - productName := product - if productDef != nil { - productName = g.itemColorize(sess, productDef, productDef.Name) - } - patchName := patchDisplayName(prefix) - msg := fmt.Sprintf("You harvest %d %s from the %s.", yield, productName, patchName) - if int(xp) > 0 && p.OptionBool("xp_drops") { - msg += g.formatXpDropSingle(sess, p, player.Farming, int(xp)) - } - sess.WriteLine(msg) - - p.Action = nil -} - -func (g *Game) advanceRake(sess *net.Session, p *player.Player) { - if p.Action == nil || p.Action.Data == nil { - return - } - data, ok := p.Action.Data.(*action.FarmData) - if !ok { - return - } - prefix := data.Prefix - - p.Flags[prefix+"_weeds"] = false - p.Flags[prefix+"_dead"] = false - p.Flags[prefix+"_seed"] = "" - p.Flags[prefix+"_stage"] = 0 - p.Flags[prefix+"_ready"] = false - p.Flags[prefix+"_diseased"] = false - p.Flags[prefix+"_watered"] = false - - g.AccountStore.SaveCharacter(p) - - patchName := patchDisplayName(prefix) - sess.WriteLine(fmt.Sprintf("You rake the %s clean.", patchName)) - - p.Action = nil -} - -func (g *Game) advanceWater(sess *net.Session, p *player.Player) { - if p.Action == nil || p.Action.Data == nil { - return - } - data, ok := p.Action.Data.(*action.FarmData) - if !ok { - return - } - prefix := data.Prefix - - p.Flags[prefix+"_watered"] = true - - g.AccountStore.SaveCharacter(p) - - patchName := patchDisplayName(prefix) - sess.WriteLine(fmt.Sprintf("You water the %s.", patchName)) - - p.Action = nil -} - -func (g *Game) advanceCure(sess *net.Session, p *player.Player) { - if p.Action == nil || p.Action.Data == nil { - return - } - data, ok := p.Action.Data.(*action.FarmData) - if !ok { - return - } - prefix := data.Prefix - - p.RemoveItem("plant_cure", 1) - p.Flags[prefix+"_diseased"] = false - - g.AccountStore.SaveCharacter(p) - - sess.WriteLine("You apply the plant cure. The patch looks healthy again.") - - p.Action = nil -} - -func patchDisplayName(prefix string) string { - switch { - case strings.Contains(prefix, "herb"): - return "herb patch" - case strings.Contains(prefix, "allot"): - return "allotment patch" - case strings.Contains(prefix, "flower"): - return "flower patch" - case strings.Contains(prefix, "bush"): - return "bush patch" - case strings.Contains(prefix, "tree"): - return "tree patch" - } - return "patch" -} - -func (g *Game) farmPatchLookSuffix(p *player.Player, defID string, index int) string { - prefix := farmFlagPrefix(defID, index) - if prefix == "" { - return "" - } - g.ensureFarmState(p, prefix) - - weeds, _ := p.Flags[prefix+"_weeds"].(bool) - if weeds { - return "\nIt is overgrown with weeds." - } - - seedID, _ := p.Flags[prefix+"_seed"].(string) - if seedID == "" { - return "\nThe patch is empty and ready for planting." - } - - dead, _ := p.Flags[prefix+"_dead"].(bool) - if dead { - return "\nThe plant has died. You need to rake it clean." - } - - diseased, _ := p.Flags[prefix+"_diseased"].(bool) - if diseased { - return "\nThe plant looks diseased! Use plant cure to save it." - } - - ready, _ := p.Flags[prefix+"_ready"].(bool) - if ready { - name := seedID - if def, err := g.ItemStore.Load(seedID); err == nil { - name = def.Name - } - return fmt.Sprintf("\nA fully grown %s is ready to harvest!", name) - } - - stage := intFromFlag(p.Flags, prefix+"_stage") - maxStages := 4 - if def, err := g.ItemStore.Load(seedID); err == nil && def.FarmStages > 0 { - maxStages = def.FarmStages - } - name := seedID - if def, err := g.ItemStore.Load(seedID); err == nil { - name = def.Name - } - watered, _ := p.Flags[prefix+"_watered"].(bool) - suffix := fmt.Sprintf("\nA %s is growing (stage %d/%d).", name, stage, maxStages) - if watered { - suffix += " It has been watered." - } - return suffix -} - -func (g *Game) toolShedLookSuffix(p *player.Player) string { - var stored []string - if v, _ := p.Flags["tool_shed_rake"].(bool); v { - stored = append(stored, "a rake") - } - if v, _ := p.Flags["tool_shed_spade"].(bool); v { - stored = append(stored, "a spade") - } - if v, _ := p.Flags["tool_shed_watering_can"].(bool); v { - stored = append(stored, "a watering can") - } - if len(stored) == 0 { - return "\nThe shed is empty." - } - return fmt.Sprintf("\nInside: %s.", strings.Join(stored, ", ")) -} - -func (g *Game) farmMatchPrefix(p *player.Player, input string) (prefix string, defID string, index int) { - objInstances := g.World.AllObjInstances(p.RoomID) - if len(objInstances) == 0 { - return "", "", -1 - } - - type indexedFarm struct { - prefix string - defID string - index int - name string - } - var farms []indexedFarm - - for _, obj := range objInstances { - if !farmPatchDefIDs[obj.DefID] { - continue - } - pref := farmFlagPrefix(obj.DefID, obj.Index) - if pref == "" { - continue - } - var name string - if def, err := g.ObjectStore.Load(obj.DefID); err == nil { - name = def.Name - } else { - name = obj.DefID - } - farms = append(farms, indexedFarm{prefix: pref, defID: obj.DefID, index: obj.Index, name: name}) - } - - if len(farms) == 0 { - return "", "", -1 - } - - if input == "" { - return farms[0].prefix, farms[0].defID, farms[0].index - } - - lower := strings.ToLower(input) - for _, f := range farms { - if strings.Contains(lower, strings.ToLower(f.name)) || object.WordPrefixMatch(lower, f.name) { - return f.prefix, f.defID, f.index - } - } - - return "", "", -1 -} - -func (g *Game) farmObjSuffix(p *player.Player, defID string, index int) string { - if defID == "tool_shed" { - return g.toolShedLookSuffix(p) - } - if farmPatchDefIDs[defID] { - return g.farmPatchLookSuffix(p, defID, index) - } - return "" -} - -func (g *Game) showFarmPatches(sess *net.Session, p *player.Player) []string { - objInstances := g.World.AllObjInstances(p.RoomID) - hasFarmPatches := false - for _, obj := range objInstances { - if farmPatchDefIDs[obj.DefID] { - hasFarmPatches = true - break - } - } - if !hasFarmPatches { - return nil - } - - type farmDisplay struct { - name string - line string - } - var displays []farmDisplay - - for _, obj := range objInstances { - if !farmPatchDefIDs[obj.DefID] { - continue - } - def, _ := g.ObjectStore.Load(obj.DefID) - patchName := obj.DefID - if def != nil { - patchName = def.Name - } - - prefix := farmFlagPrefix(obj.DefID, obj.Index) - if prefix == "" { - continue - } - g.ensureFarmState(p, prefix) - - idxStr := "" - if obj.Index > 0 || g.countPatchesByType(objInstances, obj.DefID) > 1 { - idxStr = fmt.Sprintf(" %d", obj.Index+1) - } - - weeds, _ := p.Flags[prefix+"_weeds"].(bool) - if weeds { - displays = append(displays, farmDisplay{ - name: fmt.Sprintf("%s%s", patchName, idxStr), - line: fmt.Sprintf("overgrown with weeds"), - }) - continue - } - - seedID, _ := p.Flags[prefix+"_seed"].(string) - if seedID == "" { - displays = append(displays, farmDisplay{ - name: fmt.Sprintf("%s%s", patchName, idxStr), - line: fmt.Sprintf("empty and ready for planting"), - }) - continue - } - - seedName := seedID - if sd, err := g.ItemStore.Load(seedID); err == nil { - seedName = g.itemColorize(sess, sd, sd.Name) - } - - dead, _ := p.Flags[prefix+"_dead"].(bool) - if dead { - displays = append(displays, farmDisplay{ - name: fmt.Sprintf("%s%s", patchName, idxStr), - line: fmt.Sprintf("contains a dead plant"), - }) - continue - } - - diseased, _ := p.Flags[prefix+"_diseased"].(bool) - if diseased { - displays = append(displays, farmDisplay{ - name: fmt.Sprintf("%s%s", patchName, idxStr), - line: fmt.Sprintf("has a sickly-looking %s plant", seedName), - }) - continue - } - - ready, _ := p.Flags[prefix+"_ready"].(bool) - if ready { - displays = append(displays, farmDisplay{ - name: fmt.Sprintf("%s%s", patchName, idxStr), - line: fmt.Sprintf("has a fully grown %s {ready to harvest}", seedName), - }) - continue - } - - stage := intFromFlag(p.Flags, prefix+"_stage") - maxStages := 4 - if sd, err := g.ItemStore.Load(seedID); err == nil && sd.FarmStages > 0 { - maxStages = sd.FarmStages - } - watered, _ := p.Flags[prefix+"_watered"].(bool) - waterStr := "" - if watered { - waterStr = ", watered" - } - displays = append(displays, farmDisplay{ - name: fmt.Sprintf("%s%s", patchName, idxStr), - line: fmt.Sprintf("has a growing %s (stage %d/%d%s)", seedName, stage, maxStages, waterStr), - }) - } - - if len(displays) == 0 { - return nil - } - - var lines []string - lines = append(lines, "") - for _, d := range displays { - lines = append(lines, fmt.Sprintf("A %s: %s.", d.name, d.line)) - } - return lines -} - -func (g *Game) countPatchesByType(instances []world.ObjState, defID string) int { - count := 0 - for _, obj := range instances { - if obj.DefID == defID && farmPatchDefIDs[obj.DefID] { - count++ - } - } - return count -} |
