1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
package descriptors
import (
"encoding/json"
"fmt"
"strings"
components "github.com/DegustatorPonos/RuinesOfRafdolon/Components"
coreobjects "github.com/DegustatorPonos/RuinesOfRafdolon/CoreObjects"
rl "github.com/gen2brain/raylib-go/raylib"
)
const ObjectsDirName string = "Objects"
type ObjectDescriptor struct {
Name string
YLevelOffset float64
Textures []*ObjectTextureBlock
Colliders []*ObjectColliderBlock
}
// Maps objects by their IDs
func MapObjectDescriptors(loaded []*ObjectDescriptor) map[string]*ObjectDescriptor {
var outp = make(map[string]*ObjectDescriptor, 0)
for _, v := range loaded {
outp[v.Name] = v
}
return outp
}
func (base *ObjectDescriptor) IsValid() error {
if base.Textures == nil {
return fmt.Errorf("The textures are not specified")
}
for i, v := range base.Textures {
// The texture was not specified
if v.TextureId == nil && len(v.Name) == 0 {
return fmt.Errorf("The texture #%d was not specified (neither texture name nor ID)", i)
}
}
return nil
}
func (base *ObjectDescriptor) parseTextures() []*coreobjects.TextureBlock {
var outp = make([]*coreobjects.TextureBlock, 0, len(base.Textures))
for _, v := range base.Textures {
var texture, err = v.GetTexture()
if err != nil {
rl.TraceLog(rl.LogWarning, "Failed to get the required by the object %s texture: %s", base.Name, err.Error())
continue
}
outp = append(outp, &coreobjects.TextureBlock {
Texture: texture,
Window: v.getTargetWindow(texture),
})
}
return outp
}
func (base *ObjectDescriptor) parseColliders() []*coreobjects.ColliderBlock {
var outp = make([]*coreobjects.ColliderBlock, 0, len(base.Colliders))
for _, v := range base.Colliders {
var parsed, err = v.GetCollider()
if err != nil {
rl.TraceLog(rl.LogWarning, "Failed to parse the required by the object %s collidet: %s", base.Name, err.Error())
continue
}
outp = append(outp, &coreobjects.ColliderBlock{
Collider: parsed,
Offset: v.Offset,
})
}
return outp
}
func (base *ObjectDescriptor) Parse() coreobjects.DynamicObject {
return coreobjects.DynamicObject {
YLevelOffset: float32(base.YLevelOffset),
Textures: base.parseTextures(),
Colliders: base.parseColliders(),
}
}
type ObjectTextureBlock struct {
Name string
TextureId *uint64
Offset rl.Vector2
TargetScale *rl.Vector2
}
func (base *ObjectTextureBlock) GetTexture() (*rl.Texture2D, error) {
if base.TextureId != nil {
return components.Resources.Textures.GetTexture(*base.TextureId)
}
return components.Resources.Textures.GetTextureByName(base.Name)
}
// Calculates the target window of the tetxure block. Should be provided with its target texture
func (base *ObjectTextureBlock) getTargetWindow(texture *rl.Texture2D) *rl.Rectangle {
var outp = &rl.Rectangle {
X: base.Offset.X,
Y: base.Offset.Y,
Width: float32(texture.Width),
Height: float32(texture.Height),
}
if base.TargetScale != nil {
outp.Width = base.TargetScale.X
outp.Height = base.TargetScale.Y
}
return outp
}
type ObjectColliderBlock struct {
Type string
Size rl.Vector2
Offset rl.Vector2
}
func (base *ObjectColliderBlock) GetCollider() (coreobjects.Collider, error) {
switch strings.ToLower(base.Type) {
case "box":
return base.parseAsBox(), nil
}
return nil, fmt.Errorf("Failed to parse collider: type %s is unknown", base.Type)
}
func (base *ObjectColliderBlock) parseAsBox() coreobjects.Collider {
var outp = (&coreobjects.BoxCollider{}).Init(
base.Offset.X, base.Offset.Y,
base.Size.X, base.Size.Y )
return outp
}
func (base *ObjectDescriptor) String() string {
var outp, jsonErr = json.Marshal(base)
if jsonErr != nil {
return fmt.Sprintf("Failed to parse object: %s", jsonErr.Error())
}
return string(outp)
}
|