summaryrefslogtreecommitdiff
path: root/engine/Dynamic/Descriptors/Objects.go
blob: eb3fb7898ddeedd20a4361821f8c5345c63c9bd3 (plain)
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 settings: %s", jsonErr.Error())
	}
	return string(outp)
}