package dynamic import ( "encoding/json" "fmt" "os" descriptors "github.com/DegustatorPonos/RuinesOfRafdolon/Dynamic/Descriptors" settings "github.com/DegustatorPonos/RuinesOfRafdolon/Settings" rl "github.com/gen2brain/raylib-go/raylib" ) // The defenition of the package type PackageDescription struct { Name string `json:"name"` Version uint64 `json:"version"` Type string `json:"type"` MinimumVersion *settings.AppVersion MaximumVersion *settings.AppVersion } func (base *PackageDescription) IsValid() error { if base.Name == "" { return fmt.Errorf("Invalid package descriptor: the name cannot be empty") } if base.Version == 0 { return fmt.Errorf("Invalid package descriptor: the version cannot be 0") } if base.MinimumVersion == nil { return fmt.Errorf("Invalid package descriptor: The package must specify the minimal version") } if !base.MinimumVersion.IsCompatible() || (base.MaximumVersion != nil && !base.MaximumVersion.IsLessThan(&settings.Current.Version)){ return fmt.Errorf("Invalid package descriptor: The package is made for the newer or older version") } return nil } // The dynamic collection of the things type Package struct { Description PackageDescription Textures *descriptors.TexturesDescriptor Worlds map[string]*descriptors.WorldDescriptor location string } func (base *Package) String() string { var outp, jsonErr = json.Marshal(base) if jsonErr != nil { return fmt.Sprintf("Failed to parse settings: %s", jsonErr.Error()) } return string(outp) } func ReadPackage(dir os.DirEntry) (*Package, error) { var dirPath = ConcantinateFileLocation(settings.Current.PackagesLocation, dir.Name()) var desc = PackageDescription{} if descErr := ReadValidJSONfromFile(ConcantinateFileLocation(dirPath, "Description.json"), &desc); descErr != nil { return nil, descErr } return &Package{ Description: desc, }, nil } func loadAssetsFromDir[T Validatable](dirLocation string, InitializeFunc func()T) ([]T, error) { var files, err = os.ReadDir(dirLocation) if err != nil { return nil, err } var outp = make([]T, 0) for _, v := range files { var new = InitializeFunc() var loadErr = ReadValidJSONfromFile(ConcantinateFileLocation(dirLocation, v.Name()), new) if loadErr != nil { rl.TraceLog(rl.LogWarning, "Failed to load the asset %s: %s", v.Name(), loadErr) continue } outp = append(outp, new) } return outp, nil } func (base *Package) LoadWorlds() { if base.Description.Type != "story" { return } var worlds, loadErr = loadWorldsFromDir(ConcantinateFileLocation(base.location, "Worlds")) if loadErr != nil { rl.TraceLog(rl.LogWarning, "Failed to load world from the module %s: %s", base.location, loadErr) } else { base.Worlds = worlds } } func (base *Package) LoadTextures() { var textures = &descriptors.TexturesDescriptor{} var texturesLocation = ConcantinateFileLocation(base.location, descriptors.TexturesDescriptorDirectoryName) var loadErr = ReadJSONfromFile(ConcantinateFileLocation(texturesLocation, descriptors.TexturesDescriptorFileName), textures) if loadErr != nil { rl.TraceLog(rl.LogWarning, "Failed to load texture description from the module %s: %s", base.location, loadErr) } else { base.Textures = textures } } func loadWorldsFromDir(dirLocation string) (map[string]*descriptors.WorldDescriptor, error) { var loaded, err = loadAssetsFromDir(dirLocation, func() *descriptors.WorldDescriptor{ return &descriptors.WorldDescriptor{} }) if err != nil { return nil, err } return descriptors.MapWorldDescriptors(loaded), nil } func loadTilesFromDir(dirLocation string) (map[uint64]*descriptors.TileDescriptor, error) { var loaded, err = loadAssetsFromDir(dirLocation, func() *descriptors.TileDescriptor{ return &descriptors.TileDescriptor{} }) if err != nil { return nil, err } return descriptors.MapTileDescriptors(loaded), nil }