package game import ( "fmt" "strings" "time" "thehouseoficarus/internal/engine" "thehouseoficarus/internal/item" "thehouseoficarus/internal/net" "thehouseoficarus/internal/player" ) func (g *Game) executeEat(sess *net.Session, args []string, rawInput string) { g.doEat(sess, strings.Join(args, " ")) } func (g *Game) executeDrink(sess *net.Session, args []string, rawInput string) { g.doDrink(sess, args) } func (g *Game) doEat(sess *net.Session, input string) { p := sess.Player if input == "" { sess.WriteLine("Eat what?") return } qty, itemName := parseQty(input) _ = qty matches := g.findInventoryMatches(itemName, p) if len(matches) == 0 { sess.WriteLine(fmt.Sprintf("You don't have any '%s'.", itemName)) return } unique := uniqueItemNames(matches) if len(unique) > 1 { g.showWhichOne(sess, matches) return } itemID := matches[0].ID def, _ := g.ItemStore.Load(itemID) if def == nil || def.EatMessage == "" { sess.WriteLine("You can't eat that.") return } if p.ConsumeCooldown > 0 { sess.WriteLine("You're still digesting your last meal.") return } g.cancelRest(p.Name) if p.Action == nil && len(p.WalkSequence) == 0 { g.doEatNow(sess, p, itemID, def) return } g.cancelAction(p) g.queue.EnqueueConsume(p.Name, QueuedCommand{ Session: sess, Command: "eat", Args: itemID, Timestamp: time.Now(), }) if p.OptionBool("show_queued_cmds") { sess.WriteLine(fmt.Sprintf("You prepare to eat %s.", g.itemColorize(sess, def, def.Name))) } } func (g *Game) doEatNow(sess *net.Session, p *player.Player, itemID string, def *item.ItemDef) { if def == nil { var err error def, err = g.ItemStore.Load(itemID) if err != nil || def.EatMessage == "" { return } } p.RemoveItem(itemID, 1) p.HP += def.HealValue maxHP := p.MaxHP() if p.HP > maxHP { p.HP = maxHP } if p.HP < 0 { p.HP = 0 } if def.HealValue != 0 { p.StartRegen() } p.ConsumeCooldown = 3 g.AccountStore.SaveCharacter(p) sess.WriteLine(g.colorize(sess, "eat_food", def.EatMessage)) if p.HP <= 0 { g.endCombat(sess, p, nil) } } func (g *Game) processConsumeQueue(p *player.Player, sess *net.Session) bool { qc, ok := g.queue.DrainConsume(p.Name) if !ok { return false } itemID := qc.Args def, err := g.ItemStore.Load(itemID) if qc.Command == "drink" { if err != nil || (def.PotionEffect == "" && def.HealValue <= 0) { return false } if p.ConsumeCooldown > 0 { return false } if !p.HasItem(itemID) { sess.WriteLine("You no longer have that to drink.") return false } g.applyPotion(sess, p, itemID, def) return true } if err != nil || def.EatMessage == "" { return false } if p.ConsumeCooldown > 0 { return false } if !p.HasItem(itemID) { sess.WriteLine("You no longer have that to eat.") return false } g.doEatNow(sess, p, itemID, def) return true } func (g *Game) doDrink(sess *net.Session, args []string) { p := sess.Player if len(args) == 0 { sess.WriteLine("Drink what?") return } input := strings.Join(args, " ") matches := g.findInventoryMatches(input, p) if len(matches) == 0 { sess.WriteLine(fmt.Sprintf("You don't have any '%s'.", input)) return } unique := uniqueItemNames(matches) if len(unique) > 1 { g.showWhichOne(sess, matches) return } itemID := matches[0].ID def, _ := g.ItemStore.Load(itemID) if def == nil { sess.WriteLine("Something went wrong.") return } if def.PotionEffect == "" && def.HealValue <= 0 { sess.WriteLine(fmt.Sprintf("You can't drink the %s.", g.itemColorize(sess, def, def.Name))) return } if p.ConsumeCooldown > 0 { sess.WriteLine("You're still recovering from your last drink.") return } g.cancelRest(p.Name) if p.Action == nil && len(p.WalkSequence) == 0 { g.applyPotion(sess, p, itemID, def) return } g.cancelAction(p) g.queue.EnqueueConsume(p.Name, QueuedCommand{ Session: sess, Command: "drink", Args: itemID, Timestamp: time.Now(), }) if p.OptionBool("show_queued_cmds") { sess.WriteLine(fmt.Sprintf("You prepare to drink the %s.", g.itemColorize(sess, def, def.Name))) } } func (g *Game) applyPotion(sess *net.Session, p *player.Player, itemID string, def *item.ItemDef) { if def == nil { var err error def, err = g.ItemStore.Load(itemID) if err != nil || (def.PotionEffect == "" && def.HealValue <= 0) { return } } p.RemoveItem(itemID, 1) effect := strings.ToLower(def.PotionEffect) switch effect { case "battery": batteryRestore := def.PotionBonus p.Battery += float64(batteryRestore) if p.Battery > 100 { p.Battery = 100 } sess.WriteLine(fmt.Sprintf("You drink the %s. Your battery is restored by %d%%.", g.itemColorize(sess, def, def.Name), batteryRestore)) case "heal", "": healAmount := def.PotionBonus if healAmount <= 0 { healAmount = def.HealValue } if healAmount <= 0 { healAmount = 50 } before := p.HP maxHP := p.Level(player.Hitpoints) if p.HP+healAmount > maxHP { p.HP = maxHP } else { p.HP += healAmount } actualHeal := p.HP - before sess.WriteLine(fmt.Sprintf("You drink the %s. You restore %d hitpoints.", g.itemColorize(sess, def, def.Name), actualHeal)) case "all_combat": duration := engine.ToTicks(def.PotionDuration) buffs := []string{"accuracy", "strength", "defense"} for _, stat := range buffs { p.ActiveBuffs = append(p.ActiveBuffs, player.PotionBuff{ Stat: stat, BonusPercent: def.PotionBonus, TicksLeft: duration, }) } sess.WriteLine(fmt.Sprintf("You drink the %s. Your combat stats are boosted by %d%% for %d ticks.", g.itemColorize(sess, def, def.Name), def.PotionBonus, duration)) default: duration := engine.ToTicks(def.PotionDuration) p.ActiveBuffs = append(p.ActiveBuffs, player.PotionBuff{ Stat: effect, BonusPercent: def.PotionBonus, TicksLeft: duration, }) sess.WriteLine(fmt.Sprintf("You drink the %s. Your %s is boosted by %d%% for %d ticks.", g.itemColorize(sess, def, def.Name), effect, def.PotionBonus, duration)) } p.ConsumeCooldown = 3 g.broadcastAction(sess, "%s drinks a %s.", p.Name, def.Name) }