package personal_world import ( "chain" "chain/runtime" "strconv" "gno.land/p/nt/avl" "gno.land/p/nt/ufmt" ) const ( SetBiomeInfoEvent = "SetBiomeInfo" SetDefaultBiomeEvent = "SetDefaultBiome" ) var ( biomeInfos = avl.NewTree() // biome name -> map[string]string defaultBiome string = "everdawn_plains" ) func init() { // Initialize default biome (Everdawn Plains) everdawnPlains := map[string]string{ "biome": "everdawn_plains", "name": "Everdawn Plains", "description": "The beginning of all things — a peaceful grassland bathed in eternal morning light.", "cost": "0", "priceMultiplier": "1.000000", "theme": "origin,serenity", } biomeInfos.Set("everdawn_plains", everdawnPlains) } // SetBiomeInfo sets a single biome info (admin only) func SetBiomeInfo(cur realm, biomeName string, cost int64, priceMultiplier float64, name, description, theme, option string) { caller := runtime.PreviousRealm().Address() assertIsAdmin(caller) // Validate required fields if biomeName == "" { panic("biome name cannot be empty") } if cost < 0 { panic("cost must be non-negative") } if priceMultiplier <= 0 { panic("price multiplier must be positive") } // Create biome info biomeInfo := map[string]string{ "biome": biomeName, "cost": ufmt.Sprintf("%d", cost), "priceMultiplier": ufmt.Sprintf("%f", priceMultiplier), "name": name, "description": description, "theme": theme, "option": option, } biomeInfos.Set(biomeName, biomeInfo) chain.Emit( SetBiomeInfoEvent, "admin", caller.String(), "biome", biomeName, "cost", ufmt.Sprintf("%d", cost), "priceMultiplier", ufmt.Sprintf("%f", priceMultiplier), ) } func GetBiomeInfo(biomeName string) map[string]string { if biomeName == "" { panic("biome name cannot be empty") } biomeInfo, exists := biomeInfos.Get(biomeName) if !exists { panic("biome info not found: " + biomeName) } return biomeInfo.(map[string]string) } func ListBiomeInfos() []map[string]string { var result []map[string]string biomeInfos.Iterate("", "", func(key string, value interface{}) bool { biomeInfo := value.(map[string]string) result = append(result, biomeInfo) return false }) return result } // mustGetBiomeInfo gets biome info with panic on not found func mustGetBiomeInfo(biomeName string) map[string]string { biomeInfo, found := biomeInfos.Get(biomeName) if !found { panic("biome not found: " + biomeName) } return biomeInfo.(map[string]string) } // GetActualCreationCost returns the actual cost to create a world for a specific owner // The first world of default biome is free func GetActualCreationCost(owner address, biome string) int64 { validateBiomeName(biome) // Get base creation cost biomeInfo := mustGetBiomeInfo(biome) creationCost, _ := strconv.ParseInt(biomeInfo["cost"], 10, 64) // Check if this is user's first world isFirstWorld := !ownerIndex.Has(owner.String()) // First world is free only if it's default biome if isFirstWorld && biome == defaultBiome { return 0 } return creationCost } // SetDefaultBiome sets the default biome (admin only) func SetDefaultBiome(cur realm, biomeName string) { caller := runtime.PreviousRealm().Address() assertIsAdmin(caller) if biomeName == "" { panic("biome name cannot be empty") } // Validate biome exists validateBiomeName(biomeName) oldDefault := defaultBiome defaultBiome = biomeName chain.Emit( SetDefaultBiomeEvent, "admin", caller.String(), "oldDefault", oldDefault, "newDefault", defaultBiome, ) } // GetDefaultBiome returns the current default biome name func GetDefaultBiome() string { return defaultBiome } // validateBiomeName validates biome name exists func validateBiomeName(biomeName string) { _, found := biomeInfos.Get(biomeName) if !found { panic("unknown biome") } }