-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTilemapObjectSpawner.cpp
More file actions
105 lines (93 loc) · 3.43 KB
/
Copy pathTilemapObjectSpawner.cpp
File metadata and controls
105 lines (93 loc) · 3.43 KB
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
#include "TilemapObjectSpawner.h"
#include <cstring>
#include "DekiLogSystem.h"
#include "DekiMath.h"
#include "DekiObject.h"
#include "Prefab.h"
#include "assets/AssetManager.h"
namespace
{
// Walk the property pool entries that belong to a single object and look for
// the well-known "prefab_guid" string property.
const DekiTilemap::DTilemapProperty* FindPrefabGuidProperty(
const DekiTilemap::Tilemap& tm,
const DekiTilemap::DTilemapObject& obj)
{
if (obj.propertyCount == 0) return nullptr;
const auto& props = tm.Properties();
if (props.empty()) return nullptr;
// propertyOffset is treated as a property-array index baked by the editor.
if (obj.propertyOffset + obj.propertyCount > props.size())
return nullptr;
for (uint32_t i = 0; i < obj.propertyCount; ++i)
{
const auto& p = props[obj.propertyOffset + i];
if (p.type != static_cast<uint32_t>(DekiTilemap::DPropertyType::String))
continue;
std::string name = tm.GetString(p.nameOffset);
if (name == "prefab_guid")
return &p;
}
return nullptr;
}
} // namespace
void TilemapObjectSpawner::Awake()
{
DekiTilemap::Tilemap* tm = tilemap.Get();
if (!tm)
{
DEKI_LOG_WARNING("TilemapObjectSpawner: no tilemap assigned");
return;
}
DekiObject* owner = GetOwner();
if (!owner) return;
Prefab* targetPrefab = owner->GetOwnerPrefab();
if (!targetPrefab)
{
DEKI_LOG_ERROR("TilemapObjectSpawner: spawner's owner has no prefab");
return;
}
const float ppm = (pixels_per_meter > 0.0f) ? pixels_per_meter : 1.0f;
const auto& objs = tm->Objects();
auto* mgr = Deki::AssetManager::Get();
for (const auto& obj : objs)
{
const float wx = static_cast<float>(obj.x) / ppm;
const float wy = static_cast<float>(obj.y) / ppm;
const DekiTilemap::DTilemapProperty* guidProp = FindPrefabGuidProperty(*tm, obj);
if (guidProp)
{
std::string guid = tm->GetString(guidProp->valueOffset);
if (guid.empty())
{
DEKI_LOG_ERROR("TilemapObjectSpawner: object %u has empty prefab_guid", obj.id);
continue;
}
Prefab* prefab = mgr ? static_cast<Prefab*>(
mgr->LoadByGuidAndType(guid, Prefab::AssetTypeName)) : nullptr;
if (!prefab)
{
DEKI_LOG_ERROR("TilemapObjectSpawner: prefab '%s' not found for object %u",
guid.c_str(), obj.id);
continue;
}
DekiObject* spawned = prefab->Instantiate(targetPrefab, wx, wy);
if (!spawned) continue;
// Tiled stores rotation in degrees; engine convention is radians.
spawned->SetRotation(obj.rotation * DekiMath::kDegToRad);
owner->AddChild(spawned);
m_spawned.push_back(spawned);
continue;
}
// No prefab_guid — bare DekiObject with transform only. SpriteComponent
// synthesis for tile objects is a follow-up.
DekiObject* spawned = new DekiObject();
spawned->SetX(wx);
spawned->SetY(wy);
// Tiled stores rotation in degrees; engine convention is radians.
spawned->SetRotation(obj.rotation * DekiMath::kDegToRad);
if (obj.name[0]) spawned->SetName(obj.name);
owner->AddChild(spawned);
m_spawned.push_back(spawned);
}
}