mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-15 08:32:41 +00:00
Sim: cross region boundaries; word mid-zone clears as region clears
Mirror runAutopilotWalk's multi-region auto-advance in the headless sim:
on a mid-zone stopComplete (active multi-region exp with a next region),
advanceToNextRegion and keep simulating instead of scoring a premature
"cleared". A transit error there is now recorded as halted, not cleared.
Also fix misleading run-complete wording: a non-boss region clear of a
multi-region zone now reads "Cleared {region}. The way to {next} opens
ahead." instead of "Cleared {zone}. Run complete." New midZoneRegionClear
helper shares finalizeExpeditionOnZoneClear's gating; the path is shared
with manual !region travel, so both autopilot and manual play get it.
(cherry picked from commit 5d2bba70849a0a3fdeac285cc55ea9b8fadea29c)
This commit is contained in:
@@ -170,6 +170,29 @@ func (p *AdventurePlugin) finalizeExpeditionOnZoneClear(userID id.UserID, runID
|
|||||||
return p.AwardCompletionMilestones(exp, false)
|
return p.AwardCompletionMilestones(exp, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// midZoneRegionClear reports whether the just-completed run (runID) is the
|
||||||
|
// active expedition's current run AND finishes a non-boss region of a
|
||||||
|
// multi-region zone — i.e. a region clear that leaves the expedition active
|
||||||
|
// with a next region to cross into. Returns the cleared region, the next
|
||||||
|
// region, and true in that case; zero-values + false for a full zone clear,
|
||||||
|
// a standalone run, or any read error. Used to word the run-complete message
|
||||||
|
// (region-cleared vs zone-cleared) without re-deriving region state inline.
|
||||||
|
func midZoneRegionClear(userID id.UserID, runID string) (cur, next ExpeditionRegion, ok bool) {
|
||||||
|
exp, err := getActiveExpedition(userID)
|
||||||
|
if err != nil || exp == nil || exp.RunID != runID || !IsMultiRegionZone(exp.ZoneID) {
|
||||||
|
return ExpeditionRegion{}, ExpeditionRegion{}, false
|
||||||
|
}
|
||||||
|
region, found := CurrentRegion(exp)
|
||||||
|
if !found || region.IsZoneBoss {
|
||||||
|
return ExpeditionRegion{}, ExpeditionRegion{}, false
|
||||||
|
}
|
||||||
|
nxt, found := nextRegion(exp.ZoneID, region.ID)
|
||||||
|
if !found {
|
||||||
|
return ExpeditionRegion{}, ExpeditionRegion{}, false
|
||||||
|
}
|
||||||
|
return region, nxt, true
|
||||||
|
}
|
||||||
|
|
||||||
// getResumableExpedition returns the most recent 'extracting' row for the
|
// getResumableExpedition returns the most recent 'extracting' row for the
|
||||||
// user, regardless of age (caller checks the 7-day window).
|
// user, regardless of age (caller checks the 7-day window).
|
||||||
func getResumableExpedition(userID id.UserID) (*Expedition, error) {
|
func getResumableExpedition(userID id.UserID) (*Expedition, error) {
|
||||||
|
|||||||
@@ -593,7 +593,16 @@ func (p *AdventurePlugin) advanceOnceWithOpts(ctx MessageContext, compact bool)
|
|||||||
b.WriteString(outcome)
|
b.WriteString(outcome)
|
||||||
b.WriteString("\n\n")
|
b.WriteString("\n\n")
|
||||||
}
|
}
|
||||||
b.WriteString(fmt.Sprintf("🏆 **Cleared %s.** Run complete.\n\n", zone.Display))
|
// A "complete" run is only a full zone clear when it isn't a mid-zone
|
||||||
|
// region clear of a multi-region zone. For the latter, name the region
|
||||||
|
// and point at the next one — "Cleared {zone}. Run complete." reads
|
||||||
|
// wrong right before the auto-advance transit block (and is shared with
|
||||||
|
// manual `!region travel`, which advances next).
|
||||||
|
if region, next, midZone := midZoneRegionClear(ctx.Sender, run.RunID); midZone {
|
||||||
|
b.WriteString(fmt.Sprintf("🏁 **Cleared %s.** The way to %s opens ahead.\n\n", region.Name, next.Name))
|
||||||
|
} else {
|
||||||
|
b.WriteString(fmt.Sprintf("🏆 **Cleared %s.** Run complete.\n\n", zone.Display))
|
||||||
|
}
|
||||||
if line := twinBeeLine(zone.ID, DMZoneComplete, run.RunID, prevIdx); line != "" {
|
if line := twinBeeLine(zone.ID, DMZoneComplete, run.RunID, prevIdx); line != "" {
|
||||||
b.WriteString(line)
|
b.WriteString(line)
|
||||||
b.WriteString("\n\n")
|
b.WriteString("\n\n")
|
||||||
|
|||||||
@@ -363,6 +363,29 @@ func (s *SimRunner) RunExpedition(uid id.UserID, zoneID ZoneID, walkCap int) (*S
|
|||||||
res.Outcome = "tpk"
|
res.Outcome = "tpk"
|
||||||
i = walkCap // exit
|
i = walkCap // exit
|
||||||
case stopComplete:
|
case stopComplete:
|
||||||
|
// A stopComplete that reaches the sim is normally a full zone
|
||||||
|
// clear (the walk auto-advances mid-zone region boundaries
|
||||||
|
// internally). But a mid-zone region clear can still surface
|
||||||
|
// here — e.g. the walk's auto-advance hit a transit error and
|
||||||
|
// returned stopComplete. Mirror runAutopilotWalk: if the
|
||||||
|
// expedition is still active in a multi-region zone with a
|
||||||
|
// next region, cross into it and keep simulating instead of
|
||||||
|
// scoring a premature "cleared".
|
||||||
|
if fresh, ferr := getActiveExpedition(uid); ferr == nil && fresh != nil &&
|
||||||
|
IsMultiRegionZone(fresh.ZoneID) {
|
||||||
|
if cur, ok := CurrentRegion(fresh); ok {
|
||||||
|
if next, ok := nextRegion(fresh.ZoneID, cur.ID); ok {
|
||||||
|
if _, terr := s.P.advanceToNextRegion(uid, fresh, cur, next); terr != nil {
|
||||||
|
res.Outcome = "halted"
|
||||||
|
res.StopCode = "region_transit:" + terr.Error()
|
||||||
|
i = walkCap
|
||||||
|
break
|
||||||
|
}
|
||||||
|
exp = fresh
|
||||||
|
break // continue the outer walk loop in the next region
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
res.Outcome = "cleared"
|
res.Outcome = "cleared"
|
||||||
i = walkCap
|
i = walkCap
|
||||||
case stopBoss, stopElite:
|
case stopBoss, stopElite:
|
||||||
|
|||||||
Reference in New Issue
Block a user