biome_info.gno
3.85 Kb · 162 lines
1package personal_world
2
3import (
4 "chain"
5 "chain/runtime"
6 "strconv"
7
8 "gno.land/p/nt/avl"
9 "gno.land/p/nt/ufmt"
10)
11
12const (
13 SetBiomeInfoEvent = "SetBiomeInfo"
14 SetDefaultBiomeEvent = "SetDefaultBiome"
15)
16
17var (
18 biomeInfos = avl.NewTree() // biome name -> map[string]string
19 defaultBiome string = "everdawn_plains"
20)
21
22func init() {
23 // Initialize default biome (Everdawn Plains)
24 everdawnPlains := map[string]string{
25 "biome": "everdawn_plains",
26 "name": "Everdawn Plains",
27 "description": "The beginning of all things — a peaceful grassland bathed in eternal morning light.",
28 "cost": "0",
29 "priceMultiplier": "1.000000",
30 "theme": "origin,serenity",
31 }
32 biomeInfos.Set("everdawn_plains", everdawnPlains)
33}
34
35// SetBiomeInfo sets a single biome info (admin only)
36func SetBiomeInfo(cur realm, biomeName string, cost int64, priceMultiplier float64,
37 name, description, theme, option string) {
38 caller := runtime.PreviousRealm().Address()
39 assertIsAdmin(caller)
40
41 // Validate required fields
42 if biomeName == "" {
43 panic("biome name cannot be empty")
44 }
45 if cost < 0 {
46 panic("cost must be non-negative")
47 }
48 if priceMultiplier <= 0 {
49 panic("price multiplier must be positive")
50 }
51
52 // Create biome info
53 biomeInfo := map[string]string{
54 "biome": biomeName,
55 "cost": ufmt.Sprintf("%d", cost),
56 "priceMultiplier": ufmt.Sprintf("%f", priceMultiplier),
57 "name": name,
58 "description": description,
59 "theme": theme,
60 "option": option,
61 }
62
63 biomeInfos.Set(biomeName, biomeInfo)
64
65 chain.Emit(
66 SetBiomeInfoEvent,
67 "admin", caller.String(),
68 "biome", biomeName,
69 "cost", ufmt.Sprintf("%d", cost),
70 "priceMultiplier", ufmt.Sprintf("%f", priceMultiplier),
71 )
72}
73
74func GetBiomeInfo(biomeName string) map[string]string {
75 if biomeName == "" {
76 panic("biome name cannot be empty")
77 }
78
79 biomeInfo, exists := biomeInfos.Get(biomeName)
80 if !exists {
81 panic("biome info not found: " + biomeName)
82 }
83
84 return biomeInfo.(map[string]string)
85}
86
87func ListBiomeInfos() []map[string]string {
88 var result []map[string]string
89
90 biomeInfos.Iterate("", "", func(key string, value interface{}) bool {
91 biomeInfo := value.(map[string]string)
92 result = append(result, biomeInfo)
93 return false
94 })
95
96 return result
97}
98
99// mustGetBiomeInfo gets biome info with panic on not found
100func mustGetBiomeInfo(biomeName string) map[string]string {
101 biomeInfo, found := biomeInfos.Get(biomeName)
102 if !found {
103 panic("biome not found: " + biomeName)
104 }
105 return biomeInfo.(map[string]string)
106}
107
108// GetActualCreationCost returns the actual cost to create a world for a specific owner
109// The first world of default biome is free
110func GetActualCreationCost(owner address, biome string) int64 {
111 validateBiomeName(biome)
112
113 // Get base creation cost
114 biomeInfo := mustGetBiomeInfo(biome)
115 creationCost, _ := strconv.ParseInt(biomeInfo["cost"], 10, 64)
116
117 // Check if this is user's first world
118 isFirstWorld := !ownerIndex.Has(owner.String())
119
120 // First world is free only if it's default biome
121 if isFirstWorld && biome == defaultBiome {
122 return 0
123 }
124
125 return creationCost
126}
127
128// SetDefaultBiome sets the default biome (admin only)
129func SetDefaultBiome(cur realm, biomeName string) {
130 caller := runtime.PreviousRealm().Address()
131 assertIsAdmin(caller)
132
133 if biomeName == "" {
134 panic("biome name cannot be empty")
135 }
136
137 // Validate biome exists
138 validateBiomeName(biomeName)
139
140 oldDefault := defaultBiome
141 defaultBiome = biomeName
142
143 chain.Emit(
144 SetDefaultBiomeEvent,
145 "admin", caller.String(),
146 "oldDefault", oldDefault,
147 "newDefault", defaultBiome,
148 )
149}
150
151// GetDefaultBiome returns the current default biome name
152func GetDefaultBiome() string {
153 return defaultBiome
154}
155
156// validateBiomeName validates biome name exists
157func validateBiomeName(biomeName string) {
158 _, found := biomeInfos.Get(biomeName)
159 if !found {
160 panic("unknown biome")
161 }
162}