aboutsummaryrefslogtreecommitdiff
path: root/internal/game/action_burn.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/game/action_burn.go')
-rw-r--r--internal/game/action_burn.go532
1 files changed, 0 insertions, 532 deletions
diff --git a/internal/game/action_burn.go b/internal/game/action_burn.go
deleted file mode 100644
index e1872ed..0000000
--- a/internal/game/action_burn.go
+++ /dev/null
@@ -1,532 +0,0 @@
-package game
-
-import (
- "fmt"
- "math/rand"
- "strings"
-
- "thehouseoficarus/internal/action"
- "thehouseoficarus/internal/engine"
- "thehouseoficarus/internal/net"
- "thehouseoficarus/internal/object"
- "thehouseoficarus/internal/player"
-)
-
-func (g *Game) executeBurn(sess *net.Session, args []string, rawInput string) {
- p := sess.Player
- g.cancelAction(p)
- g.doBurn(sess, p, strings.Join(args, " "))
-}
-
-func (g *Game) executeStoke(sess *net.Session, args []string, rawInput string) {
- p := sess.Player
- g.cancelAction(p)
- g.doStoke(sess, p, strings.Join(args, " "))
-}
-
-func (g *Game) doBurn(sess *net.Session, p *player.Player, input string) {
- if p.Action != nil {
- g.cancelAction(p)
- }
- g.cancelBgAction(p)
-
- itemID, fromGround, ambiguous := g.resolveBurnTarget(p, input)
- if ambiguous {
- sess.WriteLine("Burn what?")
- return
- }
- if itemID == "" {
- sess.WriteLine("Burn what?")
- return
- }
-
- g.startBurn(sess, p, itemID, fromGround)
-}
-
-func (g *Game) doStoke(sess *net.Session, p *player.Player, input string) {
- if p.Action != nil {
- g.cancelAction(p)
- }
- g.cancelBgAction(p)
-
- if !g.hasFireObject(p.RoomID) {
- sess.WriteLine("There's no fire here to stoke.")
- return
- }
-
- itemID, ambiguous := g.resolveStokeTarget(p, input)
- if ambiguous {
- sess.WriteLine("Stoke what?")
- return
- }
- if itemID == "" {
- sess.WriteLine("You have no logs to stoke with!")
- return
- }
-
- g.startStoke(sess, p, itemID)
-}
-
-func (g *Game) startBurn(sess *net.Session, p *player.Player, itemID string, fromGround bool) {
- if p.FirstFreeSlot() == -1 && !fromGround {
- sess.WriteLine("Your inventory is too full!")
- return
- }
-
- if g.hasFireObject(p.RoomID) {
- sess.WriteLine("There is already a fire burning here.")
- return
- }
-
- logDef, err := g.ItemStore.Load(itemID)
- if err != nil {
- sess.WriteLine("Something is wrong with that item.")
- return
- }
-
- if logDef.BurnTicks <= 0 {
- sess.WriteLine(fmt.Sprintf("You can't burn the %s.", g.itemColorize(sess, logDef, logDef.Name)))
- return
- }
-
- skillLevel := p.Level(player.Firemaking)
- if logDef.FireLevel > 0 && skillLevel < logDef.FireLevel {
- sess.WriteLine(fmt.Sprintf("You need level %d firemaking to burn %s.", logDef.FireLevel, g.itemColorize(sess, logDef, logDef.Name)))
- return
- }
-
- toolSpeed, ok := g.findFireTool(sess, p)
- if !ok {
- return
- }
-
- if !fromGround {
- if !p.HasItem(itemID) {
- sess.WriteLine(fmt.Sprintf("You don't have any %s.", g.itemColorize(sess, logDef, logDef.Name)))
- return
- }
- } else {
- ground := g.World.GroundItems(p.RoomID)
- if ground[itemID] <= 0 {
- sess.WriteLine(fmt.Sprintf("There are no %s on the ground here.", g.itemColorize(sess, logDef, logDef.Name)))
- return
- }
- }
-
- phase := 1
- if !fromGround {
- phase = 0
- }
-
- g.broadcastAction(sess, "\n%s starts building a fire.", p.Name)
-
- p.Action = &action.Action{
- Type: action.TypeBurn,
- TargetID: itemID,
- TargetName: logDef.Name,
- WaitLeft: 0,
- Data: &action.BurnData{
- ItemID: itemID,
- ToolSpeed: toolSpeed,
- Level: logDef.FireLevel,
- XP: logDef.FireXP,
- BurnTicks: logDef.BurnTicks,
- Phase: phase,
- },
- }
-}
-
-func (g *Game) startStoke(sess *net.Session, p *player.Player, itemID string) {
- fireKey := g.findFireObjectKey(p.RoomID)
- if fireKey == "" {
- sess.WriteLine("There's no fire here to stoke.")
- return
- }
-
- logDef, err := g.ItemStore.Load(itemID)
- if err != nil || logDef.BurnTicks <= 0 {
- sess.WriteLine(fmt.Sprintf("You can't stoke the fire with that."))
- return
- }
-
- if !p.HasItem(itemID) {
- sess.WriteLine(fmt.Sprintf("You don't have any %s.", g.itemColorize(sess, logDef, logDef.Name)))
- return
- }
-
- sess.WriteLine("You begin to tend to the fire.")
-
- g.broadcastAction(sess, "\n%s tends to the fire.", p.Name)
-
- p.Action = &action.Action{
- Type: action.TypeStoke,
- TargetID: itemID,
- TargetName: logDef.Name,
- WaitLeft: engine.ToTicks(10),
- Data: &action.BurnData{
- ItemID: itemID,
- BurnTicks: logDef.BurnTicks,
- XP: logDef.FireXP,
- },
- }
-}
-
-func (g *Game) advanceBurn(sess *net.Session, p *player.Player) {
- d := p.Action.Data.(*action.BurnData)
- itemID := d.ItemID
- toolSpeed := d.ToolSpeed
- phase := d.Phase
-
- logDef, err := g.ItemStore.Load(itemID)
- if err != nil {
- g.cancelAction(p)
- return
- }
-
- if phase == 0 {
- if !p.HasItem(itemID) {
- sess.WriteLine(fmt.Sprintf("You're out of %s.", g.itemColorize(sess, logDef, logDef.Name)))
- g.cancelAction(p)
- return
- }
- p.RemoveItem(itemID, 1)
- g.World.AddGroundItem(p.RoomID, itemID, 1)
- g.AccountStore.SaveCharacter(p)
-
- sess.WriteLine(g.colorize(sess, "fire", fmt.Sprintf("You drop the %s and begin to make a fire...", g.itemColorize(sess, logDef, logDef.Name))))
- g.broadcastDrop(p, itemID, logDef.Name)
-
- d.Phase = 1
- p.Action.WaitLeft = engine.ToTicks(toolSpeed)
- return
- }
-
- ground := g.World.GroundItems(p.RoomID)
- if ground[itemID] <= 0 {
- sess.WriteLine("The thing you were trying to burn is gone.")
- g.cancelAction(p)
- return
- }
-
- if phase == 1 {
- sess.WriteLine(g.colorize(sess, "fire", fmt.Sprintf("You try burning the %s on the ground...", g.itemColorize(sess, logDef, logDef.Name))))
- d.Phase = 2
- p.Action.WaitLeft = engine.ToTicks(toolSpeed)
- return
- }
-
- if phase == 2 {
- skillLevel := p.Level(player.Firemaking)
- chance := 0.5 + float64(skillLevel-logDef.FireLevel)*0.02
- if chance > 0.95 {
- chance = 0.95
- }
- if chance < 0.05 {
- chance = 0.05
- }
-
- if rand.Float64() < chance {
- g.World.RemoveGroundItem(p.RoomID, itemID, 1)
- g.World.AddObjInstance(p.RoomID, "fire", logDef.BurnTicks)
-
- xp := logDef.FireXP
- if xp > 0 {
- g.awardSkillXP(sess, p, player.Firemaking, xp)
- }
-
- g.AccountStore.SaveCharacter(p)
- g.cancelAction(p)
-
- msg := g.colorize(sess, "fire", "You manage to get a fire going!")
- if xp > 0 && p.OptionBool("xp_drops") {
- msg += g.formatXpDropSingle(sess, p, player.Firemaking, xp)
- }
- sess.WriteLine(msg)
-
- g.broadcastAction(sess, "\n%s started a fire!", p.Name)
- return
- }
-
- sess.WriteLine("You can't seem to get a fire going.")
- d.Phase = 1
- p.Action.WaitLeft = engine.ToTicks(toolSpeed)
- }
-}
-
-func (g *Game) advanceStoke(sess *net.Session, p *player.Player) {
- d := p.Action.Data.(*action.BurnData)
- itemID := d.ItemID
- fireKey := g.findFireObjectKey(p.RoomID)
- burnTicks := d.BurnTicks
- xp := d.XP
-
- st := g.World.GetObjStateByKey(fireKey)
- if st == nil || st.Quality <= 0 {
- sess.WriteLine("The fire went out!")
- g.cancelAction(p)
- return
- }
-
- logDef, _ := g.ItemStore.Load(itemID)
- name := itemID
- if logDef != nil {
- name = logDef.Name
- }
-
- if !p.HasItem(itemID) {
- sess.WriteLine(g.colorize(sess, "fire", fmt.Sprintf("You're out of %s and the fire is roaring.", g.itemColorize(sess, logDef, name))))
- g.cancelAction(p)
- return
- }
-
- p.RemoveItem(itemID, 1)
- st.Quality += burnTicks / 2
-
- if xp > 0 {
- g.awardSkillXP(sess, p, player.Firemaking, xp)
- }
-
- g.AccountStore.SaveCharacter(p)
-
- msg := g.colorize(sess, "fire", fmt.Sprintf("You throw %s onto the fire.", g.itemColorize(sess, logDef, name)))
- if xp > 0 && p.OptionBool("xp_drops") {
- msg += g.formatXpDropSingle(sess, p, player.Firemaking, xp)
- }
- sess.WriteLine(msg)
-
- if !p.HasItem(itemID) {
- sess.WriteLine(g.colorize(sess, "fire", fmt.Sprintf("You're out of %s and the fire is roaring.", g.itemColorize(sess, logDef, name))))
- g.cancelAction(p)
- return
- }
-
- p.Action.WaitLeft = engine.ToTicks(10.0)
-}
-
-func (g *Game) findFireTool(sess *net.Session, p *player.Player) (toolSpeed float64, ok bool) {
- toolSpeed = -1
- var toolItemID string
-
- if itemID, equipped := p.Equipment[object.SlotMainHand]; equipped {
- def, err := g.ItemStore.Load(itemID)
- if err == nil && def.ToolType == "fire" {
- toolSpeed = def.ToolSpeed
- toolItemID = itemID
- }
- }
-
- if toolSpeed < 0 {
- for _, slot := range p.Inventory {
- if slot == nil || slot.Quantity <= 0 {
- continue
- }
- def, err := g.ItemStore.Load(slot.ItemID)
- if err != nil || def.ToolType != "fire" {
- continue
- }
- toolSpeed = def.ToolSpeed
- toolItemID = slot.ItemID
- break
- }
- }
-
- if toolSpeed < 0 {
- sess.WriteLine("You need a fire starter to do that.")
- return 0, false
- }
-
- if !g.consumeFireTool(sess, p, toolItemID) {
- return 0, false
- }
-
- return toolSpeed, true
-}
-
-func (g *Game) consumeFireTool(sess *net.Session, p *player.Player, toolItemID string) bool {
- def, _ := g.ItemStore.Load(toolItemID)
-
- if def != nil && def.MaxQuality > 0 {
- for _, slot := range p.Inventory {
- if slot != nil && slot.ItemID == toolItemID && slot.MaxQuality > 0 {
- if slot.Quality <= 0 {
- sess.WriteLine("The lighter is out of butane!")
- return false
- }
- slot.Quality--
- g.AccountStore.SaveCharacter(p)
- return true
- }
- }
- if q, ok := p.EquipQuality[toolItemID]; ok {
- if q <= 0 {
- sess.WriteLine("The lighter is out of butane!")
- return false
- }
- p.EquipQuality[toolItemID] = q - 1
- g.AccountStore.SaveCharacter(p)
- return true
- }
- }
-
- if def != nil && def.Stackable {
- if p.HasItem(toolItemID) {
- p.RemoveItem(toolItemID, 1)
- g.AccountStore.SaveCharacter(p)
- return true
- }
- for slot, itemID := range p.Equipment {
- if itemID == toolItemID {
- delete(p.Equipment, slot)
- g.AccountStore.SaveCharacter(p)
- return true
- }
- }
- sess.WriteLine("You need a fire starter to do that.")
- return false
- }
-
- return true
-}
-
-func (g *Game) findFireObjectKey(roomID int) string {
- objs := g.World.AllObjInstances(roomID)
- for _, st := range objs {
- if st.DefID == "fire" && st.Quality > 0 {
- return g.World.ObjStateKey(st.RoomID, st.DefID, st.Index)
- }
- }
- return ""
-}
-
-func (g *Game) hasFireObject(roomID int) bool {
- return g.findFireObjectKey(roomID) != ""
-}
-
-func (g *Game) broadcastDrop(p *player.Player, itemID, itemName string) {
- itemDef, _ := g.ItemStore.Load(itemID)
- for _, other := range g.Hub.PlayersInRoom(p.RoomID) {
- op := other.Player
- if op != nil && op.Name != p.Name {
- colored := itemName
- if itemDef != nil {
- colored = g.itemColorize(other, itemDef, itemName)
- }
- other.WriteLine(fmt.Sprintf("%s drops a %s.", p.Name, colored))
- }
- }
-}
-
-func (g *Game) FireTick() {
- for _, st := range g.World.AllFireStates() {
- st.Quality--
- if st.Quality <= 0 {
- g.World.RemoveObjInstance(st.RoomID, st.DefID)
- g.cancelStokers(st.RoomID)
- if def, err := g.ObjectStore.Load(st.DefID); err == nil && def.RemovalItem != "" {
- g.World.AddGroundItem(st.RoomID, def.RemovalItem, 1)
- }
- }
- }
-}
-
-func (g *Game) cancelStokers(roomID int) {
- for _, other := range g.Hub.PlayersInRoom(roomID) {
- op := other.Player
- if op != nil && op.Action != nil && op.Action.Type == action.TypeStoke {
- other.WriteLine("The fire went out!")
- g.cancelAction(op)
- g.writePrompt(other)
- }
- }
-}
-
-func (g *Game) resolveBurnTarget(p *player.Player, input string) (itemID string, fromGround bool, ambiguous bool) {
- if input != "" {
- return g.namedBurnTarget(p, input)
- }
- return g.defaultBurnTarget(p)
-}
-
-func (g *Game) burnableGround(roomID int, name string) []string {
- var out []string
- for itemID := range g.World.GroundItems(roomID) {
- def, err := g.ItemStore.Load(itemID)
- if err != nil || def.BurnTicks <= 0 {
- continue
- }
- if name == "" || def.MatchesName(name) {
- out = append(out, itemID)
- }
- }
- return out
-}
-
-func (g *Game) burnableInv(p *player.Player, name string) []string {
- var out []string
- seen := make(map[string]bool)
- for _, slot := range p.Inventory {
- if slot == nil || slot.Quantity <= 0 {
- continue
- }
- def, err := g.ItemStore.Load(slot.ItemID)
- if err != nil || def.BurnTicks <= 0 || seen[slot.ItemID] {
- continue
- }
- if name == "" || def.MatchesName(name) {
- seen[slot.ItemID] = true
- out = append(out, slot.ItemID)
- }
- }
- return out
-}
-
-func (g *Game) namedBurnTarget(p *player.Player, input string) (itemID string, fromGround bool, ambiguous bool) {
- groundMatches := g.burnableGround(p.RoomID, input)
- if len(groundMatches) > 1 {
- return "", false, true
- }
- if len(groundMatches) == 1 {
- return groundMatches[0], true, false
- }
-
- invMatches := g.burnableInv(p, input)
- if len(invMatches) > 1 {
- return "", false, true
- }
- if len(invMatches) == 1 {
- return invMatches[0], false, false
- }
-
- return "", false, false
-}
-
-func (g *Game) defaultBurnTarget(p *player.Player) (itemID string, fromGround bool, ambiguous bool) {
- groundBurnable := g.burnableGround(p.RoomID, "")
- if len(groundBurnable) == 1 {
- return groundBurnable[0], true, false
- }
- if len(groundBurnable) > 1 {
- return "", false, true
- }
-
- invBurnable := g.burnableInv(p, "")
- if len(invBurnable) == 1 {
- return invBurnable[0], false, false
- }
- if len(invBurnable) > 1 {
- return "", false, true
- }
-
- return "", false, false
-}
-
-func (g *Game) resolveStokeTarget(p *player.Player, input string) (string, bool) {
- invBurnable := g.burnableInv(p, input)
- if len(invBurnable) == 1 {
- return invBurnable[0], false
- }
- if len(invBurnable) > 1 {
- return "", true
- }
- return "", false
-}