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/act_fletch.go | |
| parent | 2725e2927a1595c7b100d942d1f14146252adeb7 (diff) | |
| download | thehouseoficarus-abd612c15799f604e671e83dc7c410ed2b44185f.tar.gz | |
slop refactor
Diffstat (limited to 'internal/game/act_fletch.go')
| -rw-r--r-- | internal/game/act_fletch.go | 214 |
1 files changed, 214 insertions, 0 deletions
diff --git a/internal/game/act_fletch.go b/internal/game/act_fletch.go new file mode 100644 index 0000000..78a19ad --- /dev/null +++ b/internal/game/act_fletch.go @@ -0,0 +1,214 @@ +package game + +import ( + "fmt" + + "thehouseoficarus/internal/behavior" + "thehouseoficarus/internal/engine" + "thehouseoficarus/internal/item" + "thehouseoficarus/internal/net" + "thehouseoficarus/internal/player" +) + +func (g *Game) startFletchAction(sess *net.Session, p *player.Player, def *item.ItemDef, count int) { + p.EnsureFlags() + p.Flags["last_fletch"] = def.ID + g.AccountStore.SaveCharacter(p) + + if def.FirstCraft().Wait <= 0 { + g.doInstantFletch(sess, p, def, count) + return + } + + g.startTimedFletch(sess, p, def, count) +} + +func (g *Game) doInstantFletch(sess *net.Session, p *player.Player, def *item.ItemDef, count int) { + c := def.FirstCraft() + outputQty := c.OutputQty + if outputQty <= 0 { + outputQty = 1 + } + + batches := 0 + totalOutput := 0 + skill := player.SkillName(c.EffectiveSkill()) + tmpItem := &item.ItemDef{Craft: item.CraftList{*c}} + for { + if !g.canDoFletchItem(p, tmpItem) { + break + } + + placed := false + if def.Stackable { + for i := 0; i < 28; i++ { + slot := p.InvSlot(i) + if slot != nil && slot.ItemID == def.ID { + craftConsumeAll(c, p.HasItem, p.RemoveItem) + slot.Quantity += outputQty + placed = true + break + } + } + } + if !placed { + craftConsumeAll(c, p.HasItem, p.RemoveItem) + freeSlot := p.FirstFreeSlot() + if freeSlot == -1 { + break + } + p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: def.ID, Quantity: outputQty}) + } + + if c.XP > 0 { + g.awardSkillXP(sess, p, skill, c.XP) + } + + batches++ + totalOutput += outputQty + + if count > 0 { + count-- + if count <= 0 { + break + } + } + } + + if batches == 0 { + sess.WriteLine("You don't have the materials for that.") + return + } + + g.AccountStore.SaveCharacter(p) + + outDef, _ := g.ItemStore.Load(def.ID) + outputName := def.Name + if outDef != nil { + outputName = g.itemColorize(sess, outDef, outDef.Name) + } + msg := fmt.Sprintf("You fletch %d %s.", totalOutput, outputName) + if p.OptionBool("xp_drops") && c.XP > 0 { + msg += g.formatXpDropSingle(sess, p, skill, c.XP*batches) + } + sess.WriteLine(msg) +} + +func (g *Game) startTimedFletch(sess *net.Session, p *player.Player, def *item.ItemDef, count int) { + craft := def.FirstCraft() + + startMsg := g.resolveCraftMessage(sess, craft.StartMessage, "You begin fletching %i1.", craft, def.ID, nil, p.HasItem) + + sess.WriteLine(startMsg) + + broadcastName := def.Name + if dd, _ := g.ItemStore.Load(def.ID); dd != nil { + broadcastName = dd.Name + } + g.broadcastAction(sess, "%s starts fletching.", p.Name) + _ = broadcastName + + p.BackgroundAction = &behavior.Action{ + Type: "fletch", + TargetID: def.ID, + TargetName: def.Name, + Data: &behavior.FletchData{ + ItemID: def.ID, + Phase: 0, + Wait: craft.Wait, + Remaining: count, + }, + WaitLeft: engine.ToTicks(1), + } +} + +func (g *Game) advanceFletch(sess *net.Session, p *player.Player) { + data, ok := p.BackgroundAction.Data.(*behavior.FletchData) + if !ok { + g.cancelBgAction(p) + return + } + itemID := data.ItemID + phase := data.Phase + wait := data.Wait + remaining := data.Remaining + + def := g.loadCraftItem(itemID) + if def == nil { + g.cancelBgAction(p) + return + } + c := def.FirstCraft() + + if phase == 0 { + data.Phase = 1 + p.BackgroundAction.WaitLeft = engine.ToTicks(wait) + return + } + + tmpItem := &item.ItemDef{Craft: item.CraftList{*c}} + if !g.canDoFletchItem(p, tmpItem) { + sess.WriteLine("You've run out of fletching materials.") + g.cancelBgAction(p) + return + } + + outputQty := c.OutputQty + if outputQty <= 0 { + outputQty = 1 + } + + skill := player.SkillName(c.EffectiveSkill()) + + placed := false + if def.Stackable { + for i := 0; i < 28; i++ { + slot := p.InvSlot(i) + if slot != nil && slot.ItemID == def.ID { + craftConsumeAll(c, p.HasItem, p.RemoveItem) + slot.Quantity += outputQty + placed = true + break + } + } + } + if !placed { + craftConsumeAll(c, p.HasItem, p.RemoveItem) + freeSlot := p.FirstFreeSlot() + if freeSlot == -1 { + sess.WriteLine("Your inventory is too full!") + g.cancelBgAction(p) + return + } + p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: def.ID, Quantity: outputQty}) + } + + if c.XP > 0 { + g.awardSkillXP(sess, p, skill, c.XP) + } + g.AccountStore.SaveCharacter(p) + + msg := g.resolveCraftMessage(sess, c.Message, "You fletch a %n.", c, def.ID, nil, p.HasItem) + if p.OptionBool("xp_drops") && c.XP > 0 { + msg += g.formatXpDropSingle(sess, p, skill, c.XP) + } + sess.WriteLine(msg) + + if remaining > 0 { + remaining-- + data.Remaining = remaining + if remaining <= 0 { + sess.WriteLine("You've finished fletching.") + g.cancelBgAction(p) + return + } + } + + if !g.canContinueProduction(p, def) { + sess.WriteLine("You've run out of fletching materials.") + g.cancelBgAction(p) + return + } + + p.BackgroundAction.WaitLeft = engine.ToTicks(wait) +} |
