aboutsummaryrefslogtreecommitdiff
path: root/internal/game/act_agility.go
diff options
context:
space:
mode:
authorhistoria <[not public]>2026-07-05 22:35:21 -0400
committerhistoria <[not public]>2026-07-05 22:35:21 -0400
commit94823b52168b44894fb5e9c960358ed02ebb122b (patch)
tree3060799b89bb7edfa708c72bdd981107d40f4d09 /internal/game/act_agility.go
parent843fa6db681e494bf46e191655323a40577542b5 (diff)
downloadthehouseoficarus-94823b52168b44894fb5e9c960358ed02ebb122b.tar.gz
feat: courses gui overhaul, add course tab to map, add hidden exits to give courses structure
Diffstat (limited to 'internal/game/act_agility.go')
-rw-r--r--internal/game/act_agility.go66
1 files changed, 45 insertions, 21 deletions
diff --git a/internal/game/act_agility.go b/internal/game/act_agility.go
index d66b9c5..18dbf4a 100644
--- a/internal/game/act_agility.go
+++ b/internal/game/act_agility.go
@@ -12,15 +12,24 @@ import (
func (g *Game) startObstacle(sess *net.Session, p *player.Player, info *ObstacleInfo) {
failChance := g.calcFailChance(p, info)
-
- msgs := make([]any, len(info.Messages))
- for i, m := range info.Messages {
- msgs[i] = m
+ var failPtr *float64
+ if failChance != nil {
+ v := *failChance
+ failPtr = &v
}
gerund := info.Verb + "ing"
- if g, ok := verbGerund[info.Verb]; ok {
- gerund = g
+ if gr, ok := verbGerund[info.Verb]; ok {
+ gerund = gr
+ }
+
+ phases := make([]behavior.PhaseData, len(info.Phases))
+ for i, ph := range info.Phases {
+ phases[i] = behavior.PhaseData{
+ Message: ph.Message,
+ Delay: ph.Delay,
+ FailCheck: ph.FailCheck,
+ }
}
p.Action = &behavior.Action{
@@ -37,11 +46,10 @@ func (g *Game) startObstacle(sess *net.Session, p *player.Player, info *Obstacle
StartRoom: info.StartRoom,
ObstacleXP: info.ObstacleXP,
CompletionXP: info.CompletionXP,
- FailChance: failChance,
+ FailChance: failPtr,
FailDamageMin: info.FailDamage[0],
FailDamageMax: info.FailDamage[1],
- Messages: msgs,
- TicksPerPhase: info.TicksPerPhase,
+ Phases: phases,
RequiredLevel: info.RequiredLevel,
},
}
@@ -52,19 +60,21 @@ func (g *Game) startObstacle(sess *net.Session, p *player.Player, info *Obstacle
func (g *Game) advanceObstacle(sess *net.Session, p *player.Player) {
d := p.Action.Data.(*behavior.ObstacleData)
phase := d.Phase
- messages := d.Messages
- ticksPerPhase := d.TicksPerPhase
+ phases := d.Phases
- if phase >= len(messages) {
+ if phase >= len(phases) {
g.cancelAction(p)
return
}
- msg := messages[phase].(string)
- sess.WriteLine(g.colorize(sess, "broadcast", msg))
+ ph := phases[phase]
+ sess.WriteLine(g.colorize(sess, "broadcast", ph.Message))
- if phase == 1 {
- failChance := d.FailChance
+ if ph.FailCheck {
+ failChance := 0.30
+ if d.FailChance != nil {
+ failChance = *d.FailChance
+ }
if rand.Float64() < failChance {
g.obstacleFail(sess, p, d)
return
@@ -73,7 +83,7 @@ func (g *Game) advanceObstacle(sess *net.Session, p *player.Player) {
nextPhase := phase + 1
- if nextPhase >= len(messages) {
+ if nextPhase >= len(phases) {
obstacleXP := d.ObstacleXP
completionXP := d.CompletionXP
nextRoom := d.NextRoom
@@ -121,7 +131,7 @@ func (g *Game) advanceObstacle(sess *net.Session, p *player.Player) {
}
d.Phase = nextPhase
- p.Action.WaitLeft = engine.ToTicks(ticksPerPhase)
+ p.Action.WaitLeft = engine.ToTicks(phases[nextPhase].Delay)
}
func (g *Game) obstacleFail(sess *net.Session, p *player.Player, d *behavior.ObstacleData) {
@@ -148,7 +158,21 @@ func (g *Game) obstacleFail(sess *net.Session, p *player.Player, d *behavior.Obs
g.teleportPlayer(sess, p, startRoom)
}
-func (g *Game) calcFailChance(p *player.Player, info *ObstacleInfo) float64 {
+// calcFailChance returns the failure probability for an obstacle attempt.
+// If the obstacle defines an explicit fail_chance it is used; otherwise the
+// chance is derived from the player's Agility level relative to the course's
+// required level (70% success at required, scaling to 95% above, capped).
+func (g *Game) calcFailChance(p *player.Player, info *ObstacleInfo) *float64 {
+ if info.FailChance != nil {
+ v := *info.FailChance
+ if v < 0 {
+ v = 0
+ }
+ if v > 1 {
+ v = 1
+ }
+ return &v
+ }
level := p.Level(player.Agility)
required := info.RequiredLevel
chance := 0.30 - float64(level-required)*0.01
@@ -158,5 +182,5 @@ func (g *Game) calcFailChance(p *player.Player, info *ObstacleInfo) float64 {
if chance > 0.60 {
chance = 0.60
}
- return chance
-}
+ return &chance
+} \ No newline at end of file