aboutsummaryrefslogtreecommitdiff
path: root/internal/game/action_gather.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-06-19 18:20:26 -0400
committerhistoria <[not public]>2026-06-19 18:20:26 -0400
commit0ea4eec5dd2122c6704216971eb1249276297867 (patch)
tree430fbbef04e837820f1d031c190f52ecd6112e25 /internal/game/action_gather.go
parent3a58125d14bb307f861b38c6c5b0a63babde7e08 (diff)
downloadthehouseoficarus-0ea4eec5dd2122c6704216971eb1249276297867.tar.gz
shop fixes, 'toggle' completely removed, movement speed increased
Diffstat (limited to 'internal/game/action_gather.go')
-rw-r--r--internal/game/action_gather.go114
1 files changed, 61 insertions, 53 deletions
diff --git a/internal/game/action_gather.go b/internal/game/action_gather.go
index edc8545..e169beb 100644
--- a/internal/game/action_gather.go
+++ b/internal/game/action_gather.go
@@ -14,9 +14,19 @@ import (
"thehouseoficarus/internal/world"
)
-func (g *Game) startGather(sess *net.Session, p *player.Player, obj *object.ObjectDef, st *world.ObjState) {
- cfg, err := g.BehaviorStore.LoadGather(obj.BehaviorID)
+const birdsNestItemID = "birds_nest"
+
+func loadGatherConfig(g *Game, objDefID string) *action.GatherConfig {
+ def, err := g.ObjectStore.Load(objDefID)
if err != nil {
+ return nil
+ }
+ return def.Gather
+}
+
+func (g *Game) startGather(sess *net.Session, p *player.Player, obj *object.ObjectDef, st *world.ObjState) {
+ cfg := obj.Gather
+ if cfg == nil {
sess.WriteLine("Something is wrong with this object.")
return
}
@@ -34,7 +44,7 @@ func (g *Game) startGather(sess *net.Session, p *player.Player, obj *object.Obje
msg += fmt.Sprintf(" (%d ticks to respawn)", int(st.DepleteTimer))
}
sess.WriteLine(msg)
- } else if cfg.DepleteTimer > 0 {
+ } else if cfg.DepleteTimer > 0 {
sess.WriteLine(fmt.Sprintf("The %s has been cut down for %d more ticks.", obj.Name, int(st.DepleteTimer)))
} else {
sess.WriteLine(fmt.Sprintf("The %s is depleted for %d more ticks.", obj.Name, int(st.DepleteTimer)))
@@ -156,13 +166,13 @@ func (g *Game) startGather(sess *net.Session, p *player.Player, obj *object.Obje
}
data := map[string]any{
- "behavior_id": obj.BehaviorID,
+ "obj_def_id": obj.ID,
"instance_key": g.World.ObjStateKey(st.RoomID, st.DefID, st.Index),
"instance_idx": st.Index + 1,
"effective_wait": wait,
"step": 0,
}
- if cfg.DepleteTimer > 0 {
+ if cfg.DepleteTimer > 0 {
data["deplete_timer"] = true
}
p.Action = &action.Action{
@@ -175,10 +185,10 @@ func (g *Game) startGather(sess *net.Session, p *player.Player, obj *object.Obje
}
func (g *Game) advanceGather(sess *net.Session, p *player.Player) {
- behaviorID := p.Action.Data["behavior_id"].(string)
- cfg, err := g.BehaviorStore.LoadGather(behaviorID)
- if err != nil {
- g.CancelAction(p)
+ objDefID := p.Action.Data["obj_def_id"].(string)
+ cfg := loadGatherConfig(g, objDefID)
+ if cfg == nil {
+ g.cancelAction(p)
return
}
@@ -190,7 +200,7 @@ func (g *Game) advanceGather(sess *net.Session, p *player.Player) {
if step == 0 {
if p.FirstFreeSlot() == -1 {
sess.WriteLine(g.colorize(sess, "error", "Your inventory is too full!"))
- g.CancelAction(p)
+ g.cancelAction(p)
return
}
if cfg.Bait != "" {
@@ -200,7 +210,7 @@ func (g *Game) advanceGather(sess *net.Session, p *player.Player) {
baitName = def.Name
}
sess.WriteLine(g.colorize(sess, "error", fmt.Sprintf("You've run out of %s.", baitName)))
- g.CancelAction(p)
+ g.cancelAction(p)
return
}
}
@@ -228,7 +238,7 @@ func (g *Game) advanceGather(sess *net.Session, p *player.Player) {
baitName = def.Name
}
sess.WriteLine(g.colorize(sess, "error", fmt.Sprintf("You've run out of %s.", baitName)))
- g.CancelAction(p)
+ g.cancelAction(p)
return
}
p.RemoveItem(cfg.Bait, 1)
@@ -239,12 +249,12 @@ func (g *Game) advanceGather(sess *net.Session, p *player.Player) {
if rand.Float64() < chance {
eligible := filterDropsByLevel(cfg.Drops, skillLevel)
- drop := g.BehaviorStore.ResolveDrop(eligible)
+ drop := action.ResolveDrop(g.DataDir, eligible)
if drop != nil {
freeSlot := p.FirstFreeSlot()
if freeSlot == -1 {
sess.WriteLine(g.colorize(sess, "error", "Your inventory is too full!"))
- g.CancelAction(p)
+ g.cancelAction(p)
return
}
@@ -265,9 +275,7 @@ func (g *Game) advanceGather(sess *net.Session, p *player.Player) {
xp = cfg.XP
}
if xp > 0 {
- if newLevel := p.AddSkillXP(player.SkillName(cfg.Skill), xp); newLevel > 0 {
- sess.WriteLine(g.colorize(sess, "level_up", fmt.Sprintf("*** You are now level %d %s! ***", newLevel, cfg.Skill)))
- }
+ g.awardSkillXP(sess, p, player.SkillName(cfg.Skill), xp)
}
g.AccountStore.SaveCharacter(p)
@@ -284,20 +292,20 @@ func (g *Game) advanceGather(sess *net.Session, p *player.Player) {
g.checkBirdNest(sess, p, cfg, freeSlot)
- if shared {
- st := g.World.GetObjStateByKey(instanceKey)
- if st != nil && st.SharedTimer <= 0 {
- g.pendingDepletions = append(g.pendingDepletions, pendingDepletion{
- instanceKey: instanceKey,
- behaviorID: behaviorID,
- targetName: p.Action.TargetName,
- playerNames: []string{p.Name},
- })
- p.Action.Data["step"] = 2
- p.Action.WaitLeft = engine.ToTicks(1)
- return
+ if shared {
+ st := g.World.GetObjStateByKey(instanceKey)
+ if st != nil && st.SharedTimer <= 0 {
+ g.pendingDepletions = append(g.pendingDepletions, pendingDepletion{
+ instanceKey: instanceKey,
+ objDefID: objDefID,
+ targetName: p.Action.TargetName,
+ playerNames: []string{p.Name},
+ })
+ p.Action.Data["step"] = 2
+ p.Action.WaitLeft = engine.ToTicks(1)
+ return
+ }
}
- }
if !shared && drop.Depletes {
delay := engine.ToTicks(cfg.RespawnTimer)
@@ -310,20 +318,20 @@ func (g *Game) advanceGather(sess *net.Session, p *player.Player) {
st.DepleteTimer = float64(delay)
}
- for _, other := range g.Hub.PlayersInRoom(p.RoomID) {
- if other == sess {
- continue
- }
- op, ok := other.Player.(*player.Player)
- if !ok || op.Action == nil || op.Action.Type != "gather" {
- continue
- }
- if op.Action.Data["instance_key"] == instanceKey {
- other.WriteLine(fmt.Sprintf("\nThe %s was depleted by %s!", g.colorize(sess, "item", p.Action.TargetName), g.colorize(sess, "player_name", p.Name)))
- g.CancelAction(op)
- g.writePrompt(other)
+ for _, other := range g.Hub.PlayersInRoom(p.RoomID) {
+ if other == sess {
+ continue
+ }
+ op := other.Player
+ if op == nil || op.Action == nil || op.Action.Type != "gather" {
+ continue
+ }
+ if op.Action.Data["instance_key"] == instanceKey {
+ other.WriteLine(fmt.Sprintf("\nThe %s was depleted by %s!", g.colorize(sess, "item", p.Action.TargetName), g.colorize(sess, "player_name", p.Name)))
+ g.cancelAction(op)
+ g.writePrompt(other)
+ }
}
- }
p.Action.Data["step"] = 2
p.Action.WaitLeft = engine.ToTicks(1)
@@ -332,7 +340,7 @@ func (g *Game) advanceGather(sess *net.Session, p *player.Player) {
if p.FirstFreeSlot() == -1 {
sess.WriteLine(g.colorize(sess, "error", "Your inventory is too full!"))
- g.CancelAction(p)
+ g.cancelAction(p)
return
}
p.Action.Data["step"] = 0
@@ -344,7 +352,7 @@ func (g *Game) advanceGather(sess *net.Session, p *player.Player) {
sess.WriteLine(cfg.FailMsg)
if p.FirstFreeSlot() == -1 {
sess.WriteLine(g.colorize(sess, "error", "Your inventory is too full!"))
- g.CancelAction(p)
+ g.cancelAction(p)
return
}
p.Action.Data["step"] = 0
@@ -375,8 +383,8 @@ func (g *Game) depleteSharedTree(st *world.ObjState, cfg *action.GatherConfig, t
}
for _, sess := range g.Hub.PlayersInRoom(st.RoomID) {
- op, ok := sess.Player.(*player.Player)
- if !ok || op.Action == nil || op.Action.Type != "gather" {
+ op := sess.Player
+ if op == nil || op.Action == nil || op.Action.Type != "gather" {
continue
}
if op.Action.Data["instance_key"] != g.World.ObjStateKey(st.RoomID, st.DefID, st.Index) {
@@ -394,7 +402,7 @@ func (g *Game) depleteSharedTree(st *world.ObjState, cfg *action.GatherConfig, t
continue
}
sess.WriteLine(fmt.Sprintf("\n%s", msg))
- g.CancelAction(op)
+ g.cancelAction(op)
g.writePrompt(sess)
}
}
@@ -419,8 +427,8 @@ func (g *Game) flushPendingDepletions() {
if st == nil || st.Depleted {
continue
}
- cfg, err := g.BehaviorStore.LoadGather(pd.behaviorID)
- if err != nil {
+ cfg := loadGatherConfig(g, pd.objDefID)
+ if cfg == nil {
continue
}
g.depleteSharedTree(st, cfg, pd.targetName, pd.playerNames)
@@ -438,7 +446,7 @@ func (g *Game) checkBirdNest(sess *net.Session, p *player.Player, cfg *action.Ga
}
nestName := "bird's nest"
- if def, err := g.ItemStore.Load("birds_nest"); err == nil {
+ if def, err := g.ItemStore.Load(birdsNestItemID); err == nil {
nestName = def.Name
}
@@ -453,12 +461,12 @@ func (g *Game) checkBirdNest(sess *net.Session, p *player.Player, cfg *action.Ga
}
}
if freeSlot == -1 {
- g.World.AddGroundItem(p.RoomID, "birds_nest", 1)
+ g.World.AddGroundItem(p.RoomID, birdsNestItemID, 1)
sess.WriteLine(fmt.Sprintf("A %s falls to the ground.", nestName))
return
}
- p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: "birds_nest", Quantity: 1})
+ p.SetInvSlot(freeSlot, &player.InventorySlot{ItemID: birdsNestItemID, Quantity: 1})
g.AccountStore.SaveCharacter(p)
sess.WriteLine(fmt.Sprintf("A %s falls out of the tree!", nestName))
}