aboutsummaryrefslogtreecommitdiff
path: root/internal/game/production_engine.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-10-06 12:57:23 -0400
committerhistoria <[not public]>2026-10-06 12:57:23 -0400
commit9666676766bf21364f4fc4d0d1d336e72f2a91b4 (patch)
tree0cade34091d7602790dc38cd44053f0b74bbadf2 /internal/game/production_engine.go
parent4bc1daaf259e0c19c5fe4a12ec8bc7f6e5a735c1 (diff)
downloadthehouseoficarus-9666676766bf21364f4fc4d0d1d336e72f2a91b4.tar.gz
refactor: split casino.go, dedup helpers, remove audit docs
Diffstat (limited to 'internal/game/production_engine.go')
-rw-r--r--internal/game/production_engine.go43
1 files changed, 29 insertions, 14 deletions
diff --git a/internal/game/production_engine.go b/internal/game/production_engine.go
index 4717fbf..682cea3 100644
--- a/internal/game/production_engine.go
+++ b/internal/game/production_engine.go
@@ -76,14 +76,12 @@ func (g *Game) startProduction(sess *net.Session, p *player.Player, item *item.I
g.cancelAction(p)
g.cancelBgAction(p)
- skill := craft.EffectiveSkill()
- if skill != "" {
- skillLevel := p.Level(player.SkillName(skill))
- if skillLevel < craft.Level {
- sess.WriteLine(fmt.Sprintf("You need level %d %s to do that.", craft.Level, skill))
- g.reprompt(sess)
- return
- }
+ skill := recipeSkill(craft)
+ skillLevel := p.Level(skill)
+ if skillLevel < craft.Level {
+ sess.WriteLine(fmt.Sprintf("You need level %d %s to do that.", craft.Level, skill))
+ g.reprompt(sess)
+ return
}
if !craftHasAllItemsQty(craft, p.CountItem) {
@@ -92,6 +90,23 @@ func (g *Game) startProduction(sess *net.Session, p *player.Player, item *item.I
return
}
+ // Enforce station and tool requirements here, at the single execution
+ // chokepoint. Recipes can also start via `use X with Y` and trigger
+ // transports that bypass the crafting menus; without this, a recipe can
+ // be executed anywhere with no station or tool.
+ if len(craft.Station) > 0 {
+ if stID, _ := g.findStation(p.RoomID, craft.Station); stID == "" {
+ sess.WriteLine("You are not near the required station.")
+ g.reprompt(sess)
+ return
+ }
+ }
+ if craft.Tool != "" && !g.hasToolType(p, craft.Tool) {
+ sess.WriteLine("You do not have the required tool.")
+ g.reprompt(sess)
+ return
+ }
+
outDef, _ := g.ItemStore.Load(item.ID)
wait := craft.TicksPerCycle
@@ -129,8 +144,8 @@ func (g *Game) startProduction(sess *net.Session, p *player.Player, item *item.I
func (g *Game) usableCraftIndex(p *player.Player, item *item.ItemDef) int {
for i := range item.Craft {
c := &item.Craft[i]
- skill := c.EffectiveSkill()
- if skill != "" && p.Level(player.SkillName(skill)) < c.Level {
+ skill := recipeSkill(c)
+ if p.Level(skill) < c.Level {
continue
}
if !craftHasAllItemsQty(c, p.CountItem) {
@@ -248,8 +263,8 @@ func (g *Game) advanceProduction(sess *net.Session, p *player.Player) {
return
}
- skill := craft.EffectiveSkill()
- skillLevel := p.Level(player.SkillName(skill))
+ skill := recipeSkill(craft)
+ skillLevel := p.Level(skill)
chance := 1.0
if craft.Success != nil {
chance = behavior.SuccessChance(behavior.SuccessFormula(*craft.Success), skillLevel, craft.Level)
@@ -313,7 +328,7 @@ func (g *Game) advanceProduction(sess *net.Session, p *player.Player) {
}
if craft.XP > 0 {
- if newLevel := p.AddSkillXP(player.SkillName(skill), craft.XP); newLevel > 0 {
+ if newLevel := p.AddSkillXP(skill, craft.XP); newLevel > 0 {
sess.WriteLine(g.colorize(sess, "level_up", fmt.Sprintf("*** You are now level %d %s! ***", newLevel, skill)))
}
}
@@ -327,7 +342,7 @@ func (g *Game) advanceProduction(sess *net.Session, p *player.Player) {
}
msg := g.resolveCraftMessage(sess, craft.SuccessMessage, defaultSuccess, craft, item.ID, byproducts, hasItem)
if p.OptionBool("xp_drops") && craft.XP > 0 {
- msg += g.formatXpDropSingle(sess, p, player.SkillName(skill), craft.XP)
+ msg += g.formatXpDropSingle(sess, p, skill, craft.XP)
}
sess.WriteLine(msg)
} else {