-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.cpp
More file actions
executable file
·155 lines (142 loc) · 6.42 KB
/
main.cpp
File metadata and controls
executable file
·155 lines (142 loc) · 6.42 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
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#pragma once
#include "../bml_includes.hpp"
#include "../utils.hpp"
#include <numeric>
#include <unordered_map>
extern "C" {
__declspec(dllexport) IMod* BMLEntry(IBML* bml);
}
class Sectorless : public IMod {
IProperty* prop_enabled{}, * prop_remove_checkpoints{}, * prop_dupe_modules{};
bool enabled{}, remove_checkpoints{}, dupe_modules{};
utils utils;
void load_config() {
enabled = prop_enabled->GetBoolean();
remove_checkpoints = prop_remove_checkpoints->GetBoolean();
dupe_modules = false; // prop_dupe_modules->GetBoolean();
// disabled temporarily - pending fix
}
void output_abort_message(const char* msg) {
char text[96];
std::snprintf(text, sizeof(text), "[%s] %s, aborting", GetID(), msg);
m_bml->SendIngameMessage(msg);
}
bool remove_all_other_sectors() {
auto group_01 = m_bml->GetGroupByName("Sector_01");
if (!group_01)
return output_abort_message("Group `Sector_01` not found"), false;
for (int sector = 2; sector < 1000; sector++) {
auto* group = utils.get_sector_group(sector);
if (!group)
break;
auto length = group->GetObjectCount();
for (int i = 0; i < length; i++) {
group_01->AddObject(group->GetObject(i));
}
m_bml->GetCKContext()->DestroyObject(group);
}
return true;
}
// mostly the same code at remove_all_other_sectors()
// this is to try to make the code less convoluted
void dupe_to_other_sectors() {
//std::vector<CKGroup*> groups;
std::unordered_map<CKGroup*, std::vector<CKBeObject*>> group_items;
for (int sector = 1; sector < 1000; sector++) {
auto* group = utils.get_sector_group(sector);
if (!group)
break;
decltype(group_items)::mapped_type items;
auto length = group->GetObjectCount();
items.resize(length);
for (int i = 0; i < length; i++)
items[i] = group->GetObject(i);
group_items.try_emplace(group, items);
}
CKDependencies dep;
dep.Resize(40); dep.Fill(0);
dep.m_Flags = CK_DEPENDENCIES_CUSTOM;
dep[CKCID_OBJECT] = CK_DEPENDENCIES_COPY_OBJECT_NAME | CK_DEPENDENCIES_COPY_OBJECT_UNIQUENAME;
dep[CKCID_BEOBJECT] = CK_DEPENDENCIES_COPY_BEOBJECT_ATTRIBUTES | CK_DEPENDENCIES_COPY_BEOBJECT_GROUPS | CK_DEPENDENCIES_COPY_BEOBJECT_SCRIPTS;
dep[CKCID_3DOBJECT] = CK_DEPENDENCIES_COPY_3DENTITY_MESH;
auto* ctx = m_bml->GetCKContext();
for (auto& [group, items] : group_items) {
GetLogger()->Info("%s", group->GetName());
for (auto& [other_group, _] : group_items) {
if (other_group == group)
continue;
for (auto* obj : items) {
auto new_obj = static_cast<CKBeObject*>(ctx->CopyObject(obj, &dep, ".Sectorless", CK_OBJECTCREATION_RENAME));
GetLogger()->Info("%s", obj->GetName());
other_group->AddObject(new_obj);
group->RemoveObject(new_obj);
}
}
}
m_bml->RestoreIC(m_bml->GetArrayByName("PH_Groups"));
for (auto& [group, _] : group_items) {
GetLogger()->Info("----------------- %s", group->GetName());
for (int i = 0; i < group->GetObjectCount(); i++) {
GetLogger()->Info("%s", group->GetObject(i)->GetName());
}
}
}
public:
Sectorless(IBML* bml) : IMod(bml), utils(bml) {}
virtual iCKSTRING GetID() override { return "Sectorless"; }
virtual iCKSTRING GetVersion() override { return "0.0.1"; }
virtual iCKSTRING GetName() override { return GetID(); }
virtual iCKSTRING GetAuthor() override { return "BallanceBug"; }
virtual iCKSTRING GetDescription() override {
return
"A mod for making every module in the map show up at the same time"
" regardless of their sectors. Useful for previewing your maps.";
}
DECLARE_BML_VERSION;
void OnLoad() override {
auto config = GetConfig();
prop_enabled = config->GetProperty("Main", "Enabled");
prop_enabled->SetDefaultBoolean(true);
prop_remove_checkpoints = config->GetProperty("Main", "RemoveCheckpoints");
prop_remove_checkpoints->SetDefaultBoolean(false);
prop_remove_checkpoints->SetComment("Remove all checkpoints so the map actually only contains 1 single sector.");
prop_dupe_modules = config->GetProperty("Main", "Experimental_DuplicateModules");
prop_dupe_modules->SetDefaultBoolean(false);
prop_dupe_modules->SetComment("Duplicate modules so they show up even after switching the sector. Experimental. May make your game unstable.");
load_config();
}
void OnModifyConfig(iCKSTRING category, iCKSTRING key, IProperty* prop) {
load_config();
}
virtual void OnLoadObject(iCKSTRING filename, CKBOOL isMap, iCKSTRING masterName,
CK_CLASSID filterClass, CKBOOL addtoscene, CKBOOL reuseMeshes, CKBOOL reuseMaterials,
CKBOOL dynamic, XObjectArray* objArray, CKObject* masterObj) override {
if (!enabled || !isMap)
return;
if (!dupe_modules) {
if (!remove_all_other_sectors())
return;
}
else if (!remove_checkpoints) {
dupe_to_other_sectors();
}
if (remove_checkpoints) {
auto* group_pc = m_bml->GetGroupByName("PC_Checkpoints");
if (!group_pc)
return output_abort_message("Group `PC_Checkpoints` not found");
// constexpr const char* first_pc_name = "PC_TwoFlames_01";
const VxVector pos{0, std::numeric_limits<float>::infinity(), 0};
for (int i = 0; i < group_pc->GetObjectCount(); i++) {
auto* obj = static_cast<CK3dEntity*>(group_pc->GetObject(i));
obj->SetPosition(VT21_REF(pos));
/* if (stricmp(obj->GetName(), first_pc_name)) {
// m_bml->GetCKContext()->DestroyObject(obj);
}; */
// would mess up indices
}
}
}
};
IMod* BMLEntry(IBML* bml) {
return new Sectorless(bml);
}