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_use.go | |
| parent | 2725e2927a1595c7b100d942d1f14146252adeb7 (diff) | |
| download | thehouseoficarus-abd612c15799f604e671e83dc7c410ed2b44185f.tar.gz | |
slop refactor
Diffstat (limited to 'internal/game/act_use.go')
| -rw-r--r-- | internal/game/act_use.go | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/internal/game/act_use.go b/internal/game/act_use.go new file mode 100644 index 0000000..34f28c3 --- /dev/null +++ b/internal/game/act_use.go @@ -0,0 +1,123 @@ +package game + +import ( + "fmt" + "math/rand" + + "thehouseoficarus/internal/behavior" + "thehouseoficarus/internal/engine" + "thehouseoficarus/internal/net" + "thehouseoficarus/internal/object" + "thehouseoficarus/internal/player" +) + +func (g *Game) startUse(sess *net.Session, p *player.Player, obj *object.ObjectDef) { + cfg := obj.Use + if cfg == nil { + sess.WriteLine("You can't use this.") + return + } + + for itemID := range cfg.Consume { + if !p.HasItem(itemID) { + defName := itemID + if def, err := g.ItemStore.Load(itemID); err == nil { + defName = g.itemColorize(sess, def, def.Name) + } + sess.WriteLine(fmt.Sprintf("You need %s to use this.", defName)) + return + } + } + + if cfg.Success == nil && p.FirstFreeSlot() == -1 { + sess.WriteLine("Your inventory is full.") + return + } + + g.broadcastAction(sess, "\n%s uses the %s.", p.Name, obj.Name) + + p.Action = &behavior.Action{ + Type: "use", + TargetID: obj.ID, + TargetName: obj.Name, + WaitLeft: engine.ToTicks(1), + Data: &behavior.UseData{Cfg: cfg, Step: 0}, + } + + sess.WriteLine(fmt.Sprintf("%s", cfg.Message)) +} + +func (g *Game) advanceUse(sess *net.Session, p *player.Player) { + d, ok := p.Action.Data.(*behavior.UseData) + if !ok || d == nil || d.Cfg == nil { + g.cancelAction(p) + return + } + cfg := d.Cfg + + for itemID, qty := range cfg.Consume { + if !p.HasItem(itemID) { + defName := itemID + if def, err := g.ItemStore.Load(itemID); err == nil { + defName = g.itemColorize(sess, def, def.Name) + } + sess.WriteLine(fmt.Sprintf("You've run out of %s.", defName)) + g.cancelAction(p) + return + } + if !p.RemoveItem(itemID, qty) { + sess.WriteLine(fmt.Sprintf("You need %d of %s.", qty, itemID)) + g.cancelAction(p) + return + } + } + + if cfg.Success != nil { + skillLevel := p.Level(player.SkillName(cfg.Skill)) + chance := behavior.SuccessChance(*cfg.Success, skillLevel, cfg.Level) + if rand.Float64() >= chance { + if cfg.FailMsg != "" { + sess.WriteLine(cfg.FailMsg) + } + p.Action.WaitLeft = engine.ToTicks(cfg.Wait) + return + } + } + + freeSlot := p.FirstFreeSlot() + if freeSlot == -1 { + sess.WriteLine("Your inventory is full.") + g.cancelAction(p) + return + } + + qty := cfg.Reward.Quantity + if qty <= 0 { + qty = 1 + } + + p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: cfg.Reward.ItemID, Quantity: qty}) + if cfg.XP > 0 { + g.awardSkillXP(sess, p, player.SkillName(cfg.Skill), cfg.XP) + } + g.AccountStore.SaveCharacter(p) + + itemName := cfg.Reward.ItemID + rewardDef, _ := g.ItemStore.Load(cfg.Reward.ItemID) + if rewardDef != nil { + itemName = rewardDef.Name + } + line := fmt.Sprintf("You make a %s.", g.itemColorize(sess, rewardDef, itemName)) + if cfg.XP > 0 && p.OptionBool("xp_drops") { + line += g.formatXpDropSingle(sess, p, player.SkillName(cfg.Skill), cfg.XP) + } + sess.WriteLine(line) + + if p.FirstFreeSlot() == -1 { + sess.WriteLine("Your inventory is full.") + g.cancelAction(p) + return + } + + p.Action.WaitLeft = engine.ToTicks(cfg.Wait) +} |
