mirror of
https://github.com/HarbourMasters/SpaghettiKart
synced 2026-07-10 07:07:17 -04:00
SceneManager nearly working
This commit is contained in:
@@ -150,6 +150,8 @@ namespace Editor {
|
||||
eObjectPicker.eGizmo.dimensions.MinZ = minZ + -1000;
|
||||
eObjectPicker.eGizmo.dimensions.MaxZ = maxZ + 1000;
|
||||
}
|
||||
|
||||
// This is more of a reset
|
||||
void Editor::NewTrack() {
|
||||
auto course = gWorldInstance.CurrentCourse = new Course();
|
||||
course->Props.New();
|
||||
|
||||
@@ -1,85 +0,0 @@
|
||||
#include "SaveLevel.h"
|
||||
#include "port/Game.h"
|
||||
#include "CoreMath.h"
|
||||
#include "World.h"
|
||||
#include "GameObject.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
namespace Editor {
|
||||
|
||||
// SaveLevel::SaveLevel() {}
|
||||
|
||||
void SaveLevel() {
|
||||
auto props = gWorldInstance.CurrentCourse->Props;
|
||||
|
||||
nlohmann::json data;
|
||||
|
||||
data["Props"] = props.to_json();
|
||||
|
||||
nlohmann::json actors;
|
||||
|
||||
/* for (const auto& actor : gWorldInstance.StaticMeshActors) {
|
||||
actors.push_back(actor->to_json());
|
||||
}
|
||||
|
||||
data["Actors"] = actors;*/
|
||||
|
||||
std::ofstream file("track.json");
|
||||
file << data.dump(4); // Pretty print with indent
|
||||
}
|
||||
|
||||
void LoadLevel() {
|
||||
// Open the JSON file
|
||||
std::ifstream file("track.json");
|
||||
if (!file.is_open()) {
|
||||
std::cerr << "Failed to open track.json for reading!" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if level data file is empty
|
||||
if (file.peek() == std::ifstream::traits_type::eof()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse the JSON file into a nlohmann::json object
|
||||
nlohmann::json data;
|
||||
file >> data;
|
||||
|
||||
|
||||
// Load the Props (deserialize it)
|
||||
if (data.contains("Props")) {
|
||||
auto& propsJson = data["Props"];
|
||||
gWorldInstance.CurrentCourse->Props.from_json(propsJson); // Assuming you have a `from_json` function
|
||||
} else {
|
||||
std::cerr << "Props data not found in the JSON file!" << std::endl;
|
||||
}
|
||||
|
||||
// Load the Actors (deserialize them)
|
||||
if (data.contains("Actors")) {
|
||||
auto& actorsJson = data["Actors"];
|
||||
gWorldInstance.StaticMeshActors.clear(); // Clear existing actors, if any
|
||||
|
||||
for (const auto& actorJson : actorsJson) {
|
||||
Load_AddStaticMeshActor(actorJson);
|
||||
}
|
||||
} else {
|
||||
std::cerr << "Actors data not found in the JSON file!" << std::endl;
|
||||
}
|
||||
// Close the file after loading
|
||||
file.close();
|
||||
}
|
||||
|
||||
void Load_AddStaticMeshActor(const nlohmann::json& actorJson) {
|
||||
gWorldInstance.StaticMeshActors.push_back(new StaticMeshActor("", FVector(0, 0, 0), IRotator(0, 0, 0), FVector(1, 1, 1), "", nullptr));
|
||||
auto actor = gWorldInstance.StaticMeshActors.back();
|
||||
actor->from_json(actorJson);
|
||||
|
||||
printf("After from_json: Pos(%f, %f, %f), Name: %s, Model: %s\n",
|
||||
actor->Pos.x, actor->Pos.y, actor->Pos.z, actor->Name.c_str(), actor->Model.c_str());
|
||||
gEditor.AddObject(actor->Name.c_str(), &actor->Pos, (Vec3s*)&actor->Rot, &actor->Scale, (Gfx*) nullptr, 1.0f,
|
||||
GameObject::CollisionType::BOUNDING_BOX, 20.0f, (int32_t*) &actor->bPendingDestroy, (int32_t) 1);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
#include <libultraship.h>
|
||||
#include "Course.h"
|
||||
|
||||
namespace Editor {
|
||||
void SaveLevel();
|
||||
void LoadLevel();
|
||||
void Load_AddStaticMeshActor(const nlohmann::json& actorJson);
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
#include "SceneManager.h"
|
||||
#include "port/Game.h"
|
||||
#include "CoreMath.h"
|
||||
#include "World.h"
|
||||
#include "GameObject.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "port/Engine.h"
|
||||
#include <libultraship/src/resource/type/json.h>
|
||||
#include <libultraship/src/resource/File.h>
|
||||
|
||||
namespace Editor {
|
||||
|
||||
std::shared_ptr<Ship::Archive> CurrentArchive;
|
||||
std::string SceneFile = "";
|
||||
|
||||
void SaveLevel() {
|
||||
auto props = gWorldInstance.CurrentCourse->Props;
|
||||
|
||||
if ((CurrentArchive) && (!SceneFile.empty())) {
|
||||
nlohmann::json data;
|
||||
|
||||
data["Props"] = props.to_json();
|
||||
|
||||
nlohmann::json actors;
|
||||
|
||||
// for (const auto& actor : gWorldInstance.StaticMeshActors) {
|
||||
// actors.push_back(actor->to_json());
|
||||
// }
|
||||
// data["Actors"] = actors;
|
||||
|
||||
auto dat = data.dump();
|
||||
std::vector<uint8_t> stringify;
|
||||
stringify.assign(dat.begin(), dat.end());
|
||||
|
||||
bool wrote = GameEngine::Instance->context->GetResourceManager()->GetArchiveManager()->WriteFile(CurrentArchive, SceneFile, stringify);
|
||||
if (wrote) {
|
||||
printf("Successfully wrote scene file!\n");
|
||||
} else {
|
||||
printf("Failed to write scene file!\n");
|
||||
}
|
||||
} else {
|
||||
printf("Could not save scene file, SceneFile or CurrentArchive not set\n");
|
||||
}
|
||||
}
|
||||
|
||||
void LoadLevel(std::string sceneFile) {
|
||||
printf("LOAD TRACK PROPS %s\n", sceneFile.c_str());
|
||||
|
||||
nlohmann::json data;
|
||||
|
||||
CurrentArchive = GameEngine::Instance->context->GetResourceManager()->GetArchiveManager()->GetArchiveFromFile(sceneFile);
|
||||
SceneFile = sceneFile;
|
||||
|
||||
if (CurrentArchive) {
|
||||
auto initData = std::make_shared<Ship::ResourceInitData>();
|
||||
initData->Parent = CurrentArchive;
|
||||
initData->Format = RESOURCE_FORMAT_BINARY;
|
||||
initData->ByteOrder = Ship::Endianness::Little;
|
||||
initData->Type = static_cast<uint32_t>(Ship::ResourceType::Json);
|
||||
initData->ResourceVersion = 0;
|
||||
|
||||
nlohmann::json data = std::static_pointer_cast<Ship::Json>(
|
||||
GameEngine::Instance->context->GetResourceManager()->LoadResource(sceneFile, true, initData))->Data;
|
||||
|
||||
if (data == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Load the Props (deserialize it)
|
||||
if (data.contains("Props")) {
|
||||
auto& propsJson = data["Props"];
|
||||
gWorldInstance.CurrentCourse->Props.from_json(propsJson); // Assuming you have a `from_json` function
|
||||
} else {
|
||||
std::cerr << "Props data not found in the JSON file!" << std::endl;
|
||||
}
|
||||
|
||||
// Load the Actors (deserialize them)
|
||||
if (data.contains("Actors")) {
|
||||
auto& actorsJson = data["Actors"];
|
||||
gWorldInstance.StaticMeshActors.clear(); // Clear existing actors, if any
|
||||
|
||||
for (const auto& actorJson : actorsJson) {
|
||||
Load_AddStaticMeshActor(actorJson);
|
||||
}
|
||||
} else {
|
||||
std::cerr << "Actors data not found in the JSON file!" << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Load_AddStaticMeshActor(const nlohmann::json& actorJson) {
|
||||
gWorldInstance.StaticMeshActors.push_back(new StaticMeshActor("", FVector(0, 0, 0), IRotator(0, 0, 0), FVector(1, 1, 1), "", nullptr));
|
||||
auto actor = gWorldInstance.StaticMeshActors.back();
|
||||
actor->from_json(actorJson);
|
||||
|
||||
printf("After from_json: Pos(%f, %f, %f), Name: %s, Model: %s\n",
|
||||
actor->Pos.x, actor->Pos.y, actor->Pos.z, actor->Name.c_str(), actor->Model.c_str());
|
||||
gEditor.AddObject(actor->Name.c_str(), &actor->Pos, (Vec3s*)&actor->Rot, &actor->Scale, (Gfx*) nullptr, 1.0f,
|
||||
GameObject::CollisionType::BOUNDING_BOX, 20.0f, (int32_t*) &actor->bPendingDestroy, (int32_t) 1);
|
||||
}
|
||||
|
||||
void SetSceneFile(std::string sceneFile) {
|
||||
SceneFile = sceneFile;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#include <libultraship.h>
|
||||
#include "Course.h"
|
||||
|
||||
namespace Editor {
|
||||
void SaveLevel();
|
||||
void LoadLevel(std::string sceneFile);
|
||||
void Load_AddStaticMeshActor(const nlohmann::json& actorJson);
|
||||
void SetSceneFile(std::string sceneFile);
|
||||
|
||||
extern std::shared_ptr<Ship::Archive> CurrentArchive; // This is used to retrieve and write the scene data file
|
||||
extern std::string SceneFile;
|
||||
}
|
||||
+1
-1
@@ -77,7 +77,7 @@ GameEngine::GameEngine() {
|
||||
if (std::filesystem::is_directory(patches_path)) {
|
||||
for (const auto& p : std::filesystem::recursive_directory_iterator(patches_path)) {
|
||||
auto ext = p.path().extension().string();
|
||||
if (StringHelper::IEquals(ext, ".otr") || StringHelper::IEquals(ext, ".o2r")) {
|
||||
if (StringHelper::IEquals(ext, ".zip") || StringHelper::IEquals(ext, ".o2r")) {
|
||||
archiveFiles.push_back(p.path().generic_string());
|
||||
}
|
||||
}
|
||||
|
||||
+7
-3
@@ -47,7 +47,7 @@
|
||||
|
||||
#include "engine/editor/Editor.h"
|
||||
#include "engine/editor/EditorMath.h"
|
||||
#include "engine/editor/SaveLevel.h"
|
||||
#include "engine/editor/SceneManager.h"
|
||||
|
||||
extern "C" {
|
||||
#include "main.h"
|
||||
@@ -212,8 +212,12 @@ void HM_DrawIntro() {
|
||||
gMenuIntro.HM_DrawIntro();
|
||||
}
|
||||
|
||||
void CM_LoadLevelProps() {
|
||||
Editor::LoadLevel();
|
||||
void CM_SpawnFromLevelProps() {
|
||||
// Spawning actors needs to be delayed to the correct time.
|
||||
// And loadlevel needs to happen asap
|
||||
|
||||
//Editor::LoadLevel(nullptr);
|
||||
// Editor::SpawnFromLevelProps();
|
||||
}
|
||||
|
||||
World* GetWorld(void) {
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ void HM_InitIntro(void);
|
||||
void HM_TickIntro(void);
|
||||
void HM_DrawIntro(void);
|
||||
|
||||
void CM_LoadLevelProps();
|
||||
void CM_SpawnFromLevelProps();
|
||||
|
||||
void CM_DisplayBattleBombKart(s32 playerId, s32 primAlpha);
|
||||
void CM_DrawBattleBombKarts(s32 cameraId);
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#include "CoreMath.h"
|
||||
#include "World.h"
|
||||
#include "AllActors.h"
|
||||
#include "port/Game.h"
|
||||
#include "src/engine/editor/SceneManager.h"
|
||||
|
||||
namespace Editor {
|
||||
|
||||
@@ -24,51 +26,36 @@ namespace Editor {
|
||||
}
|
||||
|
||||
void ContentBrowserWindow::DrawElement() {
|
||||
static bool refresh = true;
|
||||
static bool actorContent = false;
|
||||
static bool objectContent = false;
|
||||
static bool customContent = false;
|
||||
static bool trackContent = false;
|
||||
|
||||
|
||||
// List the available mods/o2r files
|
||||
// for (size_t i = 0; i < GameEngine::Instance->archiveFiles.size(); i++) {
|
||||
// auto str = GameEngine::Instance->archiveFiles[i];
|
||||
// if (str.starts_with("./mods/")) {
|
||||
// ImGui::Text(GameEngine::Instance->archiveFiles[i].c_str());
|
||||
// }
|
||||
// }
|
||||
|
||||
if (ImGui::Button(ICON_FA_REFRESH)) {
|
||||
refresh = true;
|
||||
Refresh = true;
|
||||
}
|
||||
|
||||
// Query content in o2r and add them to Content
|
||||
if (refresh) {
|
||||
refresh = false;
|
||||
if (Refresh) {
|
||||
Refresh = false;
|
||||
Tracks.clear();
|
||||
Content.clear();
|
||||
TrackAssetMap.clear();
|
||||
TrackPath.clear();
|
||||
FindTracks();
|
||||
FindContent();
|
||||
return;
|
||||
}
|
||||
|
||||
ContentBrowserWindow::FolderButton("Tracks", trackContent);
|
||||
ContentBrowserWindow::FolderButton("Actors", actorContent);
|
||||
ContentBrowserWindow::FolderButton("Objects", objectContent);
|
||||
ContentBrowserWindow::FolderButton("Custom", customContent);
|
||||
|
||||
std::string actorText = fmt::format("{0} {1}", actorContent ? ICON_FA_FOLDER_OPEN_O : ICON_FA_FOLDER_O, "Actors");
|
||||
if (ImGui::Button(actorText.c_str(), ImVec2(80, 32))) {
|
||||
actorContent = !actorContent;
|
||||
objectContent = false;
|
||||
customContent = false;
|
||||
}
|
||||
|
||||
std::string objectText = fmt::format("{0} {1}", objectContent ? ICON_FA_FOLDER_OPEN_O : ICON_FA_FOLDER_O, "Objects");
|
||||
if (ImGui::Button(objectText.c_str(), ImVec2(80, 32))) {
|
||||
objectContent = !objectContent;
|
||||
actorContent = false;
|
||||
customContent = false;
|
||||
}
|
||||
|
||||
std::string customText = fmt::format("{0} {1}", customContent ? ICON_FA_FOLDER_OPEN_O : ICON_FA_FOLDER_O, "Custom");
|
||||
if (ImGui::Button(customText.c_str(), ImVec2(80, 32))) {
|
||||
customContent = !customContent;
|
||||
actorContent = false;
|
||||
objectContent = false;
|
||||
if (trackContent) {
|
||||
AddTrackContent();
|
||||
}
|
||||
|
||||
if (actorContent) {
|
||||
@@ -84,6 +71,13 @@ namespace Editor {
|
||||
}
|
||||
}
|
||||
|
||||
void ContentBrowserWindow::FolderButton(const char* label, bool& contentFlag, const ImVec2& size) {
|
||||
std::string buttonText = fmt::format("{0} {1}", contentFlag ? ICON_FA_FOLDER_OPEN_O : ICON_FA_FOLDER_O, label);
|
||||
if (ImGui::Button(buttonText.c_str(), size)) {
|
||||
contentFlag = !contentFlag;
|
||||
}
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, std::function<AActor*(const FVector&)>> ActorList = {
|
||||
{ "Mario Sign", [](const FVector& pos) { return new AMarioSign(pos); } },
|
||||
{ "Wario Sign", [](const FVector& pos) { return new AWarioSign(pos); } },
|
||||
@@ -125,6 +119,39 @@ namespace Editor {
|
||||
{ "Podium", [](const FVector& pos) { return new OPodium(pos); } },
|
||||
};
|
||||
|
||||
void ContentBrowserWindow::AddTrackContent() {
|
||||
size_t i_track = 0;
|
||||
for (const auto& track : Tracks) {
|
||||
std::string label = fmt::format("{}##{}", track, i_track);
|
||||
bool foundTrackFile = false;
|
||||
|
||||
for (auto& asset : TrackAssetMap[track]) {
|
||||
if (asset.ends_with("track.json")) {
|
||||
foundTrackFile = true;
|
||||
if (ImGui::Button(label.c_str())) {
|
||||
|
||||
SetCourseByClass(new Course());
|
||||
LoadLevel(asset);
|
||||
|
||||
gGamestateNext = RACING;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundTrackFile) {
|
||||
std::string label = fmt::format("{} {}", "ADD PATH AND MESH TO TRACK PROPS AND CLICK HERE TO INIT TRACK:", track);
|
||||
if (ImGui::Button(label.c_str())) {
|
||||
SetSceneFile(TrackPath[track]);
|
||||
SaveLevel();
|
||||
Refresh = true;
|
||||
}
|
||||
}
|
||||
|
||||
i_track += 1;
|
||||
}
|
||||
}
|
||||
|
||||
void ContentBrowserWindow::AddActorContent() {
|
||||
FVector pos = GetPositionAheadOfCamera(300.0f);
|
||||
|
||||
@@ -183,12 +210,47 @@ namespace Editor {
|
||||
}
|
||||
}
|
||||
|
||||
// Finds modded archives only. For discovering tracks
|
||||
void ContentBrowserWindow::FindTracks() {
|
||||
|
||||
// ListFiles(whitelist, blacklist);
|
||||
auto ptr2 = GameEngine::Instance->context->GetResourceManager()->GetArchiveManager()->ListFiles({"*/tracks/*"}, {""});
|
||||
if (ptr2) {
|
||||
auto files = *ptr2;
|
||||
std::set<std::string> uniqueTracks;
|
||||
|
||||
for (const auto& file : files) {
|
||||
//printf("TRACK FILES: %s\n", file.c_str());
|
||||
|
||||
// Find "tracks/"
|
||||
size_t pos = file.find("tracks/");
|
||||
if (pos == std::string::npos) continue; // Skip if not found
|
||||
|
||||
// Extract track name
|
||||
size_t start = pos + 7; // Move past "tracks/"
|
||||
size_t end = file.find('/', start); // Find next '/'
|
||||
std::string trackName = file.substr(start, end - start);
|
||||
|
||||
TrackAssetMap[trackName].push_back(file);
|
||||
|
||||
// Insert into set (ensuring uniqueness)
|
||||
uniqueTracks.insert(trackName);
|
||||
|
||||
// Extract directory path (remove filename)
|
||||
size_t lastSlash = file.find_last_of('/');
|
||||
std::string directoryPath = (lastSlash != std::string::npos) ? file.substr(0, lastSlash) : file;
|
||||
|
||||
// Store in TrackPath
|
||||
TrackPath[trackName] = directoryPath;
|
||||
}
|
||||
|
||||
// Move unique tracks into the vector
|
||||
Tracks.assign(uniqueTracks.begin(), uniqueTracks.end());
|
||||
}
|
||||
}
|
||||
|
||||
void ContentBrowserWindow::FindContent() {
|
||||
std::list<std::string> myList = {"tracks/*", "actors/*", "objects/*"};
|
||||
std::list<std::string> myList2 = {""};
|
||||
|
||||
|
||||
auto ptr = GameEngine::Instance->context->GetResourceManager()->GetArchiveManager()->ListFiles(myList, myList2);
|
||||
auto ptr = GameEngine::Instance->context->GetResourceManager()->GetArchiveManager()->ListFiles({"*tracks/*","actors/*", "objects/*"}, {""});
|
||||
if (ptr) {
|
||||
auto files = *ptr;
|
||||
for (const auto& file : files) {
|
||||
|
||||
@@ -9,13 +9,21 @@ public:
|
||||
~ContentBrowserWindow();
|
||||
|
||||
std::vector<std::string> Content;
|
||||
std::vector<std::string> Tracks; // Contains modded archives in mods/
|
||||
std::unordered_map<std::string, std::vector<std::string>> TrackAssetMap;
|
||||
std::unordered_map<std::string, std::string> TrackPath;
|
||||
|
||||
bool Refresh = true;
|
||||
protected:
|
||||
void InitElement() override {};
|
||||
void DrawElement() override;
|
||||
void UpdateElement() override {};
|
||||
void AddTrackContent();
|
||||
void AddActorContent();
|
||||
void AddObjectContent();
|
||||
void AddCustomContent();
|
||||
void FindTracks();
|
||||
void FindContent();
|
||||
void FolderButton(const char* label, bool& contentFlag, const ImVec2& size = ImVec2(80, 32));
|
||||
};
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include <common_structs.h>
|
||||
#include <defines.h>
|
||||
#include "port/Game.h"
|
||||
#include "engine/editor/SaveLevel.h"
|
||||
#include "engine/editor/SceneManager.h"
|
||||
|
||||
extern "C" {
|
||||
#include "code_800029B0.h"
|
||||
|
||||
+1
-1
@@ -1227,8 +1227,8 @@ void init_actors_and_load_textures(void) {
|
||||
init_red_shell_texture();
|
||||
destroy_all_actors();
|
||||
CM_CleanWorld();
|
||||
CM_LoadLevelProps();
|
||||
|
||||
CM_SpawnFromLevelProps();
|
||||
CM_BeginPlay();
|
||||
spawn_course_actors();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user