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.OptionBool("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 }