From 8ee8982b8759bcae116647cc993867f4c8b0a6ce Mon Sep 17 00:00:00 2001 From: workhorse Date: Fri, 19 Jun 2026 20:24:52 -0400 Subject: reorganized items, objects, and rooms in directories. oranized module names. added startup checks. --- internal/game/core_course.go | 135 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 internal/game/core_course.go (limited to 'internal/game/core_course.go') diff --git a/internal/game/core_course.go b/internal/game/core_course.go new file mode 100644 index 0000000..908466d --- /dev/null +++ b/internal/game/core_course.go @@ -0,0 +1,135 @@ +package game + +import ( + "path/filepath" + "sync" + + "thehouseoficarus/internal/action" + "gopkg.in/yaml.v3" +) + +type ObstacleDef struct { + RoomID int `yaml:"room_id"` + Verb string `yaml:"verb"` + TicksPerPhase float64 `yaml:"ticks_per_phase"` + XP int `yaml:"xp"` + FailDamage [2]int `yaml:"fail_damage"` + Messages []string `yaml:"messages"` +} + +type CourseConfig struct { + ID string `yaml:"id"` + Name string `yaml:"name"` + RequiredLevel int `yaml:"required_level"` + StartRoom int `yaml:"start_room"` + CompletionXP int `yaml:"completion_xp"` + Obstacles []ObstacleDef `yaml:"obstacles"` +} + +type ObstacleInfo struct { + CourseID string + CourseName string + ObstacleIndex int + TotalObstacles int + Verb string + Messages []string + TicksPerPhase float64 + ObstacleXP int + CompletionXP int + FailDamage [2]int + NextRoom int + StartRoom int + RequiredLevel int +} + +var obstacleVerbs = map[string]bool{} + +var verbGerund = map[string]string{ + "scramble": "scrambling", + "jump": "jumping", + "swing": "swinging", + "balance": "balancing", + "climb": "climbing", + "crawl": "crawling", + "vault": "vaulting", + "leap": "leaping", + "slide": "sliding", +} + +type CourseStore struct { + dataDir string + mu sync.Mutex + courses map[string]*CourseConfig + roomToObstacle map[int]*ObstacleInfo + loaded bool +} + +func NewCourseStore(dataDir string) *CourseStore { + return &CourseStore{ + dataDir: dataDir, + courses: make(map[string]*CourseConfig), + } +} + +func (cs *CourseStore) LoadAll() { + cs.mu.Lock() + defer cs.mu.Unlock() + cs.loadAllLocked() +} + +func (cs *CourseStore) GetObstacle(roomID int) *ObstacleInfo { + cs.mu.Lock() + defer cs.mu.Unlock() + if !cs.loaded { + cs.loadAllLocked() + } + return cs.roomToObstacle[roomID] +} + +func (cs *CourseStore) loadAllLocked() { + cs.loaded = true + cs.roomToObstacle = make(map[int]*ObstacleInfo) + localVerbs := make(map[string]bool) + + action.WalkYAMLDir(filepath.Join(cs.dataDir, "courses"), func(path, id string, data []byte) error { + var cfg CourseConfig + if err := yaml.Unmarshal(data, &cfg); err != nil { + return nil + } + cs.courses[cfg.ID] = &cfg + + totalObstacles := len(cfg.Obstacles) + for i, obs := range cfg.Obstacles { + nextRoom := 0 + if i < totalObstacles-1 { + nextRoom = cfg.Obstacles[i+1].RoomID + } + + completionXP := 0 + if i == totalObstacles-1 { + completionXP = cfg.CompletionXP + } + + info := &ObstacleInfo{ + CourseID: cfg.ID, + CourseName: cfg.Name, + ObstacleIndex: i, + TotalObstacles: totalObstacles, + Verb: obs.Verb, + Messages: obs.Messages, + TicksPerPhase: obs.TicksPerPhase, + ObstacleXP: obs.XP, + CompletionXP: completionXP, + FailDamage: obs.FailDamage, + NextRoom: nextRoom, + StartRoom: cfg.StartRoom, + RequiredLevel: cfg.RequiredLevel, + } + cs.roomToObstacle[obs.RoomID] = info + localVerbs[obs.Verb] = true + } + return nil + }) + + obstacleVerbs = localVerbs +} -- cgit v1.2.3