add support of Turbo & fix a MP4 bug
This commit is contained in:
parent
ed331a57c0
commit
de96342be4
@ -6,18 +6,32 @@ int author_time;
|
|||||||
void Main() {}
|
void Main() {}
|
||||||
|
|
||||||
void validate(int author_time) {
|
void validate(int author_time) {
|
||||||
auto app = GetApp();
|
CGameCtnEditorFree@ editor = cast<CGameCtnEditorFree>(GetApp().Editor);
|
||||||
auto editor = cast<CGameCtnEditorFree>(app.Editor);
|
#if TMNEXT || MP4
|
||||||
auto map = app.RootMap;
|
CGameCtnChallenge@ map = cast<CGameCtnChallenge>(GetApp().RootMap);
|
||||||
|
CGameEditorPluginMapMapType@ pluginmaptype = cast<CGameEditorPluginMapMapType>(editor.PluginMapType);
|
||||||
|
#elif TURBO
|
||||||
|
CGameCtnChallenge@ map = cast<CGameCtnChallenge>(GetApp().Challenge);
|
||||||
|
CGameCtnEditorPluginMapType@ pluginmaptype = cast<CGameCtnEditorPluginMapType>(editor.EditorMapType);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (editor is null) {
|
if (editor is null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (editor.PluginMapType !is null) {
|
if (pluginmaptype !is null) {
|
||||||
editor.PluginMapType.ValidationStatus = CGameEditorPluginMapMapType::EValidationStatus::Validated;
|
#if TMNEXT || MP4
|
||||||
|
pluginmaptype.ValidationStatus = CGameEditorPluginMapMapType::EValidationStatus::Validated;
|
||||||
|
#elif TURBO
|
||||||
|
pluginmaptype.ValidationStatus = CGameCtnEditorPluginMapType::EValidationStatus::Validated;
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
if (map !is null) {
|
if (map !is null) {
|
||||||
map.TMObjective_AuthorTime = author_time;
|
map.TMObjective_AuthorTime = author_time;
|
||||||
|
#if MP4 || TURBO
|
||||||
|
map.IdName = "";
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,10 +40,17 @@ void Render() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto app = cast<CGameManiaPlanet>(GetApp());
|
CGameCtnEditorFree@ editor = cast<CGameCtnEditorFree>(GetApp().Editor);
|
||||||
|
#if TMNEXT || MP4
|
||||||
|
CGameCtnChallenge@ map = cast<CGameCtnChallenge>(GetApp().RootMap);
|
||||||
|
CGameEditorPluginMapMapType@ pluginmaptype = cast<CGameEditorPluginMapMapType>(editor.PluginMapType);
|
||||||
|
#elif TURBO
|
||||||
|
CGameCtnChallenge@ map = cast<CGameCtnChallenge>(GetApp().Challenge);
|
||||||
|
CGameCtnEditorPluginMapType@ pluginmaptype = cast<CGameCtnEditorPluginMapType>(editor.EditorMapType);
|
||||||
|
#endif
|
||||||
|
|
||||||
UI::Begin("\\$cf9" + Icons::Flag + "\\$z Map Validator###MapValidator", menu_visibility, UI::WindowFlags::NoResize | UI::WindowFlags::AlwaysAutoResize | UI::WindowFlags::NoCollapse);
|
UI::Begin("\\$cf9" + Icons::Flag + "\\$z Map Validator###MapValidator", menu_visibility, UI::WindowFlags::NoResize | UI::WindowFlags::AlwaysAutoResize | UI::WindowFlags::NoCollapse);
|
||||||
if (app.RootMap !is null) {
|
if (map !is null && editor !is null) {
|
||||||
author_time = UI::InputInt("Author time in ms", author_time ,1);
|
author_time = UI::InputInt("Author time in ms", author_time ,1);
|
||||||
|
|
||||||
if (author_time < 0) author_time = 0;
|
if (author_time < 0) author_time = 0;
|
||||||
@ -47,6 +68,9 @@ void Render() {
|
|||||||
UI::SameLine();
|
UI::SameLine();
|
||||||
UI::Text("with " + display_time + " of author time");
|
UI::Text("with " + display_time + " of author time");
|
||||||
|
|
||||||
|
#if TURBO
|
||||||
|
UI::Text("Note: your map must have a start and a finish\n(or a multilap + 1CP) to be validated with the plugin");
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
UI::Text("Open this plugin in the map editor");
|
UI::Text("Open this plugin in the map editor");
|
||||||
}
|
}
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
ـ<EFBFBD><EFBFBD>ً؛S<16><>خZB<5A><42><EFBFBD>j} ةإَ<EFBFBD>ـ<EFBFBD>ن<EFBFBD><EFBFBD>\<5C><><EFBFBD>vH،<48>ٍs<18>غما<>دmZmr -<2D>
|
|
||||||
ك'uـO<D980>
|
|
Binary file not shown.
@ -1,337 +0,0 @@
|
|||||||
#name "Blocks & Items Counter"
|
|
||||||
#author "Beu"
|
|
||||||
#category "Map Editor"
|
|
||||||
#version "1.0"
|
|
||||||
#siteid 97
|
|
||||||
|
|
||||||
#include "Icons.as"
|
|
||||||
|
|
||||||
class Objects { //Items or Blocks
|
|
||||||
string name;
|
|
||||||
string type;
|
|
||||||
string source;
|
|
||||||
int size;
|
|
||||||
int count;
|
|
||||||
bool icon;
|
|
||||||
array<vec3> positions;
|
|
||||||
|
|
||||||
Objects(string name, bool icon, string type, string source, int size, vec3 pos ) {
|
|
||||||
this.name = name;
|
|
||||||
this.count = 1;
|
|
||||||
this.type = type;
|
|
||||||
this.icon = icon;
|
|
||||||
this.source = source;
|
|
||||||
this.size = size;
|
|
||||||
this.positions = {pos};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ESortColumn {
|
|
||||||
ItemName,
|
|
||||||
Type,
|
|
||||||
Source,
|
|
||||||
Size,
|
|
||||||
Count
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool menu_visibility = false;
|
|
||||||
int camerafocusindex = 0;
|
|
||||||
bool include_default_objects = false;
|
|
||||||
bool refreshobject;
|
|
||||||
|
|
||||||
bool sort_reverse;
|
|
||||||
bool forcesort;
|
|
||||||
string infotext;
|
|
||||||
|
|
||||||
array<Objects@> objects = {};
|
|
||||||
array<Objects@> sortableobjects = {};
|
|
||||||
array<string> objectsindex = {};
|
|
||||||
|
|
||||||
|
|
||||||
ESortColumn sortCol = ESortColumn(-1);
|
|
||||||
|
|
||||||
void Main() {
|
|
||||||
while (true) {
|
|
||||||
if (refreshobject) {
|
|
||||||
objects.Resize(0);
|
|
||||||
objectsindex.Resize(0);
|
|
||||||
sortableobjects.Resize(0);
|
|
||||||
RefreshBlocks();
|
|
||||||
RefreshItems();
|
|
||||||
sortableobjects = objects;
|
|
||||||
refreshobject = false;
|
|
||||||
}
|
|
||||||
yield();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Force to split the refresh functions to bypass the script execution delay on heavy maps
|
|
||||||
void RefreshBlocks() {
|
|
||||||
auto map = GetApp().RootMap;
|
|
||||||
|
|
||||||
if (map !is null) {
|
|
||||||
int defaultheight = 0;
|
|
||||||
if (map.DecorationName.SubStr(0, 5) == "48x48") { // Change the default height depending on the presence of the stadium or not
|
|
||||||
defaultheight = 9;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Blocks
|
|
||||||
auto blocks = map.Blocks;
|
|
||||||
for(int i = 0; i < blocks.Length; i++) {
|
|
||||||
int idifexist = -1;
|
|
||||||
string blockname;
|
|
||||||
blockname = blocks[i].BlockModel.IdName;
|
|
||||||
if (blockname.ToLower().SubStr(blockname.Length - 22, 22) == ".block.gbx_customblock") blockname = blockname.SubStr(0, blockname.Length - 12);
|
|
||||||
if (include_default_objects || blockname.ToLower().SubStr(blockname.Length - 10, 10) == ".block.gbx") {
|
|
||||||
vec3 pos;
|
|
||||||
pos.x = blocks[i].CoordX * 32 + 16;
|
|
||||||
pos.y = (blocks[i].CoordY - defaultheight) * 8 + 4;
|
|
||||||
pos.z = blocks[i].CoordZ * 32 + 16;
|
|
||||||
|
|
||||||
int index = objectsindex.Find(blockname);
|
|
||||||
|
|
||||||
if (index >= 0) {
|
|
||||||
objects[index].count++;
|
|
||||||
objects[index].positions.InsertLast(pos);
|
|
||||||
} else {
|
|
||||||
AddNewObject(blockname, "Block", pos );
|
|
||||||
objectsindex.InsertLast(blockname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i % 100 == 0) yield(); // to avoid timeout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Force to split the refresh functions to bypass the script execution delay on heavy maps
|
|
||||||
void RefreshItems() {
|
|
||||||
auto map = GetApp().RootMap;
|
|
||||||
|
|
||||||
if (map !is null) {
|
|
||||||
// Items
|
|
||||||
auto items = map.AnchoredObjects;
|
|
||||||
for(int i = 0; i < items.Length; i++) {
|
|
||||||
int idifexist = -1;
|
|
||||||
string itemname = items[i].ItemModel.IdName;
|
|
||||||
if (include_default_objects || itemname.ToLower().SubStr(itemname.Length - 9, 9) == ".item.gbx") {
|
|
||||||
int index = objectsindex.Find(itemname);
|
|
||||||
if (index >= 0) {
|
|
||||||
objects[index].count++;
|
|
||||||
objects[index].positions.InsertLast(items[i].AbsolutePositionInMap);
|
|
||||||
} else {
|
|
||||||
AddNewObject(itemname, "Item", items[i].AbsolutePositionInMap);
|
|
||||||
objectsindex.InsertLast(itemname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (i % 100 == 0) yield(); // to avoid timeout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void AddNewObject(string objectname, string type, vec3 pos) {
|
|
||||||
bool icon = false;
|
|
||||||
int size;
|
|
||||||
string source;
|
|
||||||
CSystemFidFile@ file;
|
|
||||||
CGameCtnCollector@ collector;
|
|
||||||
CSystemFidFile@ tempfile;
|
|
||||||
|
|
||||||
if (type == "Item" && objectname.SubStr(0,5) == "club:") {// ItemCollections
|
|
||||||
source = "Club";
|
|
||||||
@file = Fids::GetFake('MemoryTemp\\FavoriteClubItems\\' + objectname.SubStr(5,objectname.Length));
|
|
||||||
@collector = cast<CGameCtnCollector>(cast<CGameItemModel>(file.Nod));
|
|
||||||
if (collector is null || (collector.Icon !is null || file.ByteSize == 0)) {
|
|
||||||
@tempfile = Fids::GetFake('MemoryTemp\\CurrentMap_EmbeddedFiles\\ContentLoaded\\ClubItems\\' + objectname.SubStr(5,objectname.Length));
|
|
||||||
}
|
|
||||||
} else { // Blocks and Items
|
|
||||||
source = "Local";
|
|
||||||
@file = Fids::GetUser(type + 's\\' + objectname);
|
|
||||||
CGameItemModel@ model = cast<CGameItemModel>(file.Nod);
|
|
||||||
@collector = cast<CGameCtnCollector>(model);
|
|
||||||
if (collector is null || (collector.Icon !is null || file.ByteSize == 0)) {
|
|
||||||
@tempfile = Fids::GetFake('MemoryTemp\\CurrentMap_EmbeddedFiles\\ContentLoaded\\' + type + 's\\' + objectname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (tempfile !is null) {
|
|
||||||
if (collector !is null && collector.Icon !is null && tempfile.ByteSize == 0) {
|
|
||||||
icon = true;
|
|
||||||
size = file.ByteSize;
|
|
||||||
} else {
|
|
||||||
size = tempfile.ByteSize;
|
|
||||||
}
|
|
||||||
if (file.ByteSize == 0 && tempfile.ByteSize == 0) {
|
|
||||||
source = "In-Game";
|
|
||||||
} else if (file.ByteSize == 0 && tempfile.ByteSize > 0) {
|
|
||||||
source = "Embedded";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
size = file.ByteSize;
|
|
||||||
}
|
|
||||||
objects.InsertLast(Objects(objectname, icon, type, source, size, pos));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FocusCam(string objectname) {
|
|
||||||
auto editor = cast<CGameCtnEditorFree>(GetApp().Editor);
|
|
||||||
auto camera = editor.OrbitalCameraControl;
|
|
||||||
auto map = GetApp().RootMap;
|
|
||||||
|
|
||||||
// variables to workaround the non-existence of positions for freemapping placed blocks
|
|
||||||
bool canfocus = false;
|
|
||||||
int iterations;
|
|
||||||
|
|
||||||
if (camera !is null) {
|
|
||||||
int index = objectsindex.Find(objectname);
|
|
||||||
iterations = 0;
|
|
||||||
|
|
||||||
while (!canfocus) {
|
|
||||||
iterations++;
|
|
||||||
camerafocusindex++;
|
|
||||||
if (camerafocusindex > objects[index].positions.get_Length() - 1 ) {
|
|
||||||
camerafocusindex = 0;
|
|
||||||
}
|
|
||||||
if (objects[index].positions[camerafocusindex].x != 4294967295 && objects[index].positions[camerafocusindex].z != 4294967295) {
|
|
||||||
canfocus = true;
|
|
||||||
}
|
|
||||||
if (iterations > objects[index].positions.get_Length()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
camera.m_TargetedPosition = objects[index].positions[camerafocusindex];
|
|
||||||
// Workaround to update camera TargetedPosition
|
|
||||||
editor.ButtonZoomInOnClick();
|
|
||||||
editor.ButtonZoomOutOnClick();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GenerateRow(Objects@ object) {
|
|
||||||
UI::TableNextRow();
|
|
||||||
UI::TableNextColumn();
|
|
||||||
if (UI::Button(Icons::Search + "###" + object.name)) {
|
|
||||||
FocusCam(object.name);
|
|
||||||
}
|
|
||||||
if (UI::IsItemHovered() && object.type == "Block") infotext = "ATM, it's not possible to focus on blocks placed in free mapping.";
|
|
||||||
UI::SameLine();
|
|
||||||
UI::Text(object.name);
|
|
||||||
UI::TableNextColumn();
|
|
||||||
UI::Text(object.type);
|
|
||||||
UI::TableNextColumn();
|
|
||||||
UI::Text(object.source);
|
|
||||||
UI::TableNextColumn();
|
|
||||||
if (object.icon) {
|
|
||||||
UI::Text("\\$fc0" + Text::Format("%lld",object.size));
|
|
||||||
if (UI::IsItemHovered()) infotext = "All items with size in orange contains the icon. You must re-open the map to have the real size.";
|
|
||||||
} else {
|
|
||||||
UI::Text(Text::Format("%lld",object.size));
|
|
||||||
}
|
|
||||||
UI::TableNextColumn();
|
|
||||||
UI::Text(Text::Format("%lld",object.count));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Render() {
|
|
||||||
if (!menu_visibility) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
infotext = "";
|
|
||||||
auto editor = cast<CGameCtnEditorFree>(GetApp().Editor);
|
|
||||||
|
|
||||||
UI::SetNextWindowSize(600, 400);
|
|
||||||
UI::SetNextWindowPos(200, 200, UI::Cond::Once);
|
|
||||||
UI::Begin("\\$cf9" + Icons::Table + "\\$z Blocks & Items Counter###Blocks & Items Counter", menu_visibility);
|
|
||||||
if (editor !is null) {
|
|
||||||
if (refreshobject) {
|
|
||||||
if (Time::get_Now() % 3000 > 2000) {
|
|
||||||
UI::Button("Loading...");
|
|
||||||
} else if (Time::get_Now() % 3000 > 1000) {
|
|
||||||
UI::Button("Loading.. ");
|
|
||||||
} else {
|
|
||||||
UI::Button("Loading. ");
|
|
||||||
}
|
|
||||||
if (UI::IsItemHovered()) infotext = "Parsing all blocks and items to generate the table. Please wait...";
|
|
||||||
} else {
|
|
||||||
if (UI::Button(Icons::SyncAlt + " Refresh")) {
|
|
||||||
// Force to split the refresh functions to bypass the script execution delay on heavy maps
|
|
||||||
refreshobject = true;
|
|
||||||
forcesort = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UI::SameLine();
|
|
||||||
include_default_objects = UI::Checkbox("Include In-Game Blocks and Items", include_default_objects);
|
|
||||||
UI::Separator();
|
|
||||||
vec2 winsize = UI::GetWindowSize();
|
|
||||||
winsize.x = winsize.x-10;
|
|
||||||
winsize.y = winsize.y-105;
|
|
||||||
if (UI::BeginTable("ItemsTable", 5, UI::TableFlags(UI::TableFlags::Resizable | UI::TableFlags::Sortable | UI::TableFlags::NoSavedSettings | UI::TableFlags::BordersInnerV | UI::TableFlags::SizingStretchProp | UI::TableFlags::ScrollY),winsize )) {
|
|
||||||
UI::TableSetupScrollFreeze(0, 1);
|
|
||||||
UI::TableSetupColumn("Item Name", UI::TableColumnFlags::None, 55.f, ESortColumn::ItemName);
|
|
||||||
UI::TableSetupColumn("Type", UI::TableColumnFlags::None, 7.f, ESortColumn::Type);
|
|
||||||
UI::TableSetupColumn("Source", UI::TableColumnFlags::None, 13.f, ESortColumn::Source);
|
|
||||||
UI::TableSetupColumn("Size", UI::TableColumnFlags::None, 15.f, ESortColumn::Size);
|
|
||||||
UI::TableSetupColumn("Count", UI::TableColumnFlags::DefaultSort, 10.f, ESortColumn::Count);
|
|
||||||
UI::TableHeadersRow();
|
|
||||||
|
|
||||||
UI::TableSortSpecs@ sortSpecs = UI::TableGetSortSpecs();
|
|
||||||
if(sortSpecs !is null && sortSpecs.Specs.Length == 1 && sortableobjects.Length > 1) {
|
|
||||||
if(sortSpecs.Dirty || (forcesort && !refreshobject)) {
|
|
||||||
if(sortCol != ESortColumn(sortSpecs.Specs[0].ColumnUserID) || (forcesort && !refreshobject)) {
|
|
||||||
sortCol = ESortColumn(sortSpecs.Specs[0].ColumnUserID);
|
|
||||||
switch(sortCol) {
|
|
||||||
case ESortColumn::ItemName:
|
|
||||||
sortableobjects.Sort(function(a,b) { return a.name < b.name; });
|
|
||||||
break;
|
|
||||||
case ESortColumn::Type:
|
|
||||||
sortableobjects.Sort(function(a,b) { return a.type < b.type; });
|
|
||||||
break;
|
|
||||||
case ESortColumn::Source:
|
|
||||||
sortableobjects.Sort(function(a,b) { return a.source < b.source; });
|
|
||||||
break;
|
|
||||||
case ESortColumn::Size:
|
|
||||||
sortableobjects.Sort(function(a,b) { return a.size < b.size; });
|
|
||||||
break;
|
|
||||||
case ESortColumn::Count:
|
|
||||||
sortableobjects.Sort(function(a,b) { return a.count < b.count; });
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (forcesort && sort_reverse) {
|
|
||||||
sortableobjects.Reverse();
|
|
||||||
} else {
|
|
||||||
sort_reverse = false;
|
|
||||||
}
|
|
||||||
} else if (sortCol == ESortColumn(sortSpecs.Specs[0].ColumnUserID)) {
|
|
||||||
sortableobjects.Reverse();
|
|
||||||
sort_reverse = !sort_reverse;
|
|
||||||
}
|
|
||||||
|
|
||||||
sortSpecs.Dirty = false;
|
|
||||||
forcesort = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sortableobjects.Length > 0 ) {
|
|
||||||
for(int i = 0; i < sortableobjects.Length; i++) {
|
|
||||||
GenerateRow(sortableobjects[i]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for(int i = 0; i < objects.Length; i++) {
|
|
||||||
GenerateRow(objects[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
UI::EndTable();
|
|
||||||
UI::Separator();
|
|
||||||
UI::Text(Icons::Info + " " + infotext);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
UI::Text("Open this plugin in the map editor");
|
|
||||||
}
|
|
||||||
UI::End();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderMenu() {
|
|
||||||
if(UI::MenuItem("\\$cf9" + Icons::Table + "\\$z Blocks & Items Counter", "", menu_visibility)) {
|
|
||||||
menu_visibility = !menu_visibility;
|
|
||||||
refreshobject = true;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user