diff options
| author | historia <[not public]> | 2026-06-11 04:46:27 -0400 |
|---|---|---|
| committer | historia <[not public]> | 2026-06-11 08:58:37 +0000 |
| commit | 1b9e2da3b3c438d8dc53d3489725dd5ba0022777 (patch) | |
| tree | 62264f24420bf4cfaa734942c65cc8dd45ba3d3b /internal/game/action_use.go | |
| parent | 06c02a697e5daf8832a462de5970dd4c0e13a02c (diff) | |
| download | thehouseoficarus-1b9e2da3b3c438d8dc53d3489725dd5ba0022777.tar.gz | |
feat: web client, get/drop updates and fixes
Diffstat (limited to 'internal/game/action_use.go')
| -rw-r--r-- | internal/game/action_use.go | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/internal/game/action_use.go b/internal/game/action_use.go new file mode 100644 index 0000000..c1a07ed --- /dev/null +++ b/internal/game/action_use.go @@ -0,0 +1,120 @@ +package game + +import ( + "fmt" + "math/rand" + + "thirdcollapse/internal/action" + "thirdcollapse/internal/net" + "thirdcollapse/internal/object" + "thirdcollapse/internal/player" +) + +func (g *Game) startUse(sess *net.Session, p *player.Player, obj *object.ObjectDef) { + cfg, err := g.BehaviorStore.LoadUse(obj.BehaviorID) + if err != nil { + sess.WriteLine("You can't use this.") + return + } + + for itemID, qty := range cfg.Consume { + if !p.HasItem(itemID) { + defName := itemID + if def, err := g.ItemStore.Load(itemID); err == nil { + defName = def.Name + } + sess.WriteLine(fmt.Sprintf("You need %s to use this.", defName)) + return + } + _ = qty + } + + if cfg.Success == nil && p.FirstFreeSlot() == -1 { + sess.WriteLine("Your inventory is full.") + return + } + + p.Action = &action.Action{ + Type: "use", + TargetID: obj.ID, + TargetName: obj.Name, + WaitLeft: 1, + Data: map[string]any{"step": 0, "behavior_id": obj.BehaviorID}, + } + + sess.WriteLine(fmt.Sprintf("\n%s", cfg.Message)) +} + +func (g *Game) advanceUse(sess *net.Session, p *player.Player) { + behaviorID := p.Action.Data["behavior_id"].(string) + cfg, err := g.BehaviorStore.LoadUse(behaviorID) + if err != nil { + g.CancelAction(p) + return + } + + for itemID, qty := range cfg.Consume { + if !p.HasItem(itemID) { + defName := itemID + if def, err := g.ItemStore.Load(itemID); err == nil { + defName = 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 := action.SuccessChance(*cfg.Success, skillLevel, cfg.Level) + if rand.Float64() >= chance { + if cfg.FailMsg != "" { + sess.WriteLine(cfg.FailMsg) + } + p.Action.WaitLeft = 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 { + p.AddXP(player.SkillName(cfg.Skill), cfg.XP) + } + g.AccountStore.SaveCharacter(p) + + itemName := cfg.Reward.ItemID + if def, err := g.ItemStore.Load(cfg.Reward.ItemID); err == nil { + itemName = def.Name + } + line := fmt.Sprintf("You make a %s.", itemName) + if cfg.XP > 0 && p.Toggles["xpdrops"] { + line += fmt.Sprintf(" (+%dxp %s)", cfg.XP, player.SkillAbbr[player.SkillName(cfg.Skill)]) + } + sess.WriteLine(line) + + if p.FirstFreeSlot() == -1 { + sess.WriteLine("Your inventory is full.") + g.CancelAction(p) + return + } + + p.Action.WaitLeft = cfg.Wait +} |
