diff --git a/GameGuru Core/Dark Basic Public Shared/Dark Basic Pro SDK/DarkSDKMore/DarkLUA/DarkLUA.cpp b/GameGuru Core/Dark Basic Public Shared/Dark Basic Pro SDK/DarkSDKMore/DarkLUA/DarkLUA.cpp index a86a0b2f..cc34c58f 100644 --- a/GameGuru Core/Dark Basic Public Shared/Dark Basic Pro SDK/DarkSDKMore/DarkLUA/DarkLUA.cpp +++ b/GameGuru Core/Dark Basic Public Shared/Dark Basic Pro SDK/DarkSDKMore/DarkLUA/DarkLUA.cpp @@ -3,6 +3,14 @@ //#define FASTBULLETPHYSICS +#ifdef WINVER +#undef WINVER +#endif +//PE: We need the latest dpi functions. +#define WINVER 0x0605 +#include "Windows.h" +#include "WinUser.h" + #define _USING_V110_SDK71_ #include "stdafx.h" #include "DarkLUA.h" @@ -45,6 +53,13 @@ extern StoryboardStruct Storyboard; #include "optick.h" #endif +#include "..\..\..\..\Guru-WickedMAX\wickedcalls.h" +#include "WickedEngine.h" +using namespace std; +using namespace wiGraphics; +using namespace wiScene; +using namespace wiECS; + // Prototypes extern void DrawSpritesFirst(void); extern void DrawSpritesLast(void); @@ -5834,6 +5849,59 @@ int QuatLERP(lua_State *L) lua_pushnumber(L, qa.w * at + qb.w * bt ); return 4; } + +int ScreenCoordsToPercent(lua_State* L) +{ + int n = lua_gettop(L); + if (n < 2) return 0; + float fX = lua_tonumber(L, 1); + float fY = lua_tonumber(L, 2); + float fPercentX = ( fX / (float) g_dwScreenWidth) * 100.0f; + float fPercentY = (fY / (float)g_dwScreenHeight) * 100.0f; + lua_pushnumber(L, fPercentX); + lua_pushnumber(L, fPercentY); + return 2; + +} + +int LuaConvert2DTo3D(lua_State* L) +{ + int n = lua_gettop(L); + if (n < 2) return 0; + float fX = lua_tonumber(L, 1); + float fY = lua_tonumber(L, 2); + + float x = (fX * g_dwScreenWidth) / 100.0f; + float y = (fY * g_dwScreenHeight) / 100.0f; + + float fOutX = 0, fOutY = 0, fOutZ = 0; + float fDirX = 0, fDirY = 0, fDirZ = 0; + Convert2Dto3D(x, y, &fOutX, &fOutY, &fOutZ, &fDirX, &fDirY, &fDirZ); + + lua_pushnumber(L, fOutX); + lua_pushnumber(L, fOutY); + lua_pushnumber(L, fOutZ); + lua_pushnumber(L, fDirX); + lua_pushnumber(L, fDirY); + lua_pushnumber(L, fDirZ); + return 6; +} + + +int LuaConvert3DTo2D(lua_State* L) +{ + int n = lua_gettop(L); + if (n < 3) return 0; + float fX = lua_tonumber(L, 1); + float fY = lua_tonumber(L, 2); + float fZ = lua_tonumber(L, 3); + ImVec2 Convert3DTo2D(float x, float y, float z); + ImVec2 v2DPos = Convert3DTo2D(fX, fY, fZ); + lua_pushnumber(L, v2DPos.x); + lua_pushnumber(L, v2DPos.y); + return 2; +} + // end of Fast Quaternion functions int RotateObject ( lua_State *L ) { @@ -7022,8 +7090,20 @@ int DisplayCurrentScreen(lua_State* L) lua_pushnumber(L, iSpecialLuaReturn); return 1; } +bool bDisableKeyToggles = false; +int DisableBoundHudKeys(lua_State* L) +{ + bDisableKeyToggles = true; + return 0; +} +int EnableBoundHudKeys(lua_State* L) +{ + bDisableKeyToggles = false; + return 0; +} int CheckScreenToggles(lua_State* L) { + if (bDisableKeyToggles) return 0; extern void TriggerScreenFromKeyPress(); TriggerScreenFromKeyPress(); return 1; @@ -9682,6 +9762,191 @@ int EffectSetLifespan(lua_State* L) return 0; } +#ifdef WICKEDPARTICLESYSTEM +std::vector vWickedEmitterEffects; +void CleanUpEmitterEffects(void) +{ + Scene& scene = wiScene::GetScene(); + + std::vector vEntityDelete; + for (int i = 0; i < vWickedEmitterEffects.size(); i++) + { + uint32_t root = vWickedEmitterEffects[i]; + for (int a = 0; a < scene.emitters.GetCount(); a++) + { + Entity emitter = scene.emitters.GetEntity(a); + HierarchyComponent* hier = scene.hierarchy.GetComponent(emitter); + if (hier) + { + if (hier->parentID == root) + { + vEntityDelete.push_back(emitter); + } + } + } + vEntityDelete.push_back(root); + } + + for (int i = 0; i < vEntityDelete.size(); i++) + { + scene.Entity_Remove(vEntityDelete[i]); + } + vEntityDelete.clear(); + vWickedEmitterEffects.clear(); +} + +//PE: WParticleEffectPosition("FileName") - Return EffectID +int WParticleEffectLoad(lua_State* L) +{ + lua = L; + int n = lua_gettop(L); + if (n < 1) return 0; + + Scene& scene = wiScene::GetScene(); + + char pFileName[MAX_PATH]; + strcpy(pFileName, lua_tostring(L, 1)); + + uint32_t root = 0; + uint32_t count_before = scene.emitters.GetCount(); + + cstr pOldDir = GetDir(); + + char path[MAX_PATH]; + strcpy(path, pFileName); + GG_GetRealPath(path, 0); + + WickedCall_LoadWiScene(path, false, NULL, NULL); + uint32_t count_after = scene.emitters.GetCount(); + if (count_before != count_after) + { + Entity emitter = scene.emitters.GetEntity(scene.emitters.GetCount() - 1); + if (scene.emitters.GetCount() > 0) + { + Entity emitter = scene.emitters.GetEntity(0); + HierarchyComponent* hier = scene.hierarchy.GetComponent(emitter); + if (hier) + { + root = hier->parentID; + } + } + wiEmittedParticle* ec = scene.emitters.GetComponent(emitter); + if (ec) + { + ec->Restart(); + ec->SetVisible(true); + } + } + if (root != 0) + vWickedEmitterEffects.push_back(root); + lua_pushnumber(L, root); + return 1; + +} +//PE: WParticleEffectPosition(EffectID,x,y,z) +int WParticleEffectPosition(lua_State* L) +{ + lua = L; + int n = lua_gettop(L); + if (n < 4) return 0; + + Entity root = lua_tonumber(L, 1); + float fX = lua_tonumber(L, 2); + float fY = lua_tonumber(L, 3); + float fZ = lua_tonumber(L, 4); + + Scene& scene = wiScene::GetScene(); + TransformComponent* root_tranform = scene.transforms.GetComponent(root); + if (root_tranform) + { + root_tranform->ClearTransform(); + root_tranform->Translate(XMFLOAT3(fX, fY, fZ)); + root_tranform->UpdateTransform(); + } + + //for (int i = 0; i < scene.emitters.GetCount(); i++) + //{ + // Entity emitter = scene.emitters.GetEntity(i); + // HierarchyComponent* hier = scene.hierarchy.GetComponent(emitter); + // if (hier) + // { + // if (hier->parentID == root) + // { + // } + // } + //} + + return 0; +} +int WParticleEffectVisible(lua_State* L) +{ + lua = L; + int n = lua_gettop(L); + if (n < 2) return 0; + + Entity root = lua_tonumber(L, 1); + bool bVisible = lua_tonumber(L, 2); + + Scene& scene = wiScene::GetScene(); + + for (int i = 0; i < scene.emitters.GetCount(); i++) + { + Entity emitter = scene.emitters.GetEntity(i); + HierarchyComponent* hier = scene.hierarchy.GetComponent(emitter); + if (hier) + { + if (hier->parentID == root) + { + wiEmittedParticle* ec = scene.emitters.GetComponent(emitter); + if (ec) + { + ec->SetVisible(bVisible); + } + } + } + } + + return 0; +} + +//WParticleEffectAction(EffectID,Action) - Action = 1 Burst all. 2 = Pause. - 3 = Resume. - 4 = Restart +int WParticleEffectAction(lua_State* L) +{ + lua = L; + int n = lua_gettop(L); + if (n < 2) return 0; + Entity root = lua_tonumber(L, 1); + int iAction = lua_tonumber(L, 2); + WickedCall_PerformEmitterAction(iAction, root); + return 0; +} +//PE: Missing command for position sound if different then entity position. +int entity_lua_positionsound(lua_State* L) +{ + int n = lua_gettop(L); + if (n < 5) return 0; + int e = lua_tonumber(L, 1); + int v = lua_tonumber(L, 2); + float fX = lua_tonumber(L, 3); + float fY = lua_tonumber(L, 4); + float fZ = lua_tonumber(L, 5); + int entity_lua_sound_convertVtoTSND(int te, int tv); + int snd = entity_lua_sound_convertVtoTSND(e, v); + if (snd > 0) + { + PositionSound(snd, fX, fY, fZ); + } + return 0; +} + +//disableindoor +// rotate +// Stop +// copy lua code from app. +// add emitter with all settings. +#endif + + // Misc Commands int GetBulletHit(lua_State* L) @@ -12190,6 +12455,11 @@ void addFunctions() lua_register(lua, "QuatSLERP", QuatSLERP ); lua_register(lua, "QuatLERP", QuatLERP ); + lua_register(lua, "Convert3DTo2D", LuaConvert3DTo2D); // x,y = Convert3DTo2D(x,y,z) + lua_register(lua, "Convert2DTo3D", LuaConvert2DTo3D); // px,py,pz,dx,dy,dz = Convert2DTo3D(x percent,y percent) -- percent + lua_register(lua, "ScreenCoordsToPercent", ScreenCoordsToPercent); // percentx,percentx = ScreenCordsToPercent(x,y) -- return percent positions. + + // Lua control of dynamic light lua_register(lua, "GetEntityLightNumber", GetEntityLightNumber ); lua_register(lua, "GetLightPosition", GetLightPosition ); @@ -12742,6 +13012,18 @@ void addFunctions() lua_register(lua, "EffectSetColor", EffectSetColor); lua_register(lua, "EffectSetLifespan", EffectSetLifespan); +#ifdef WICKEDPARTICLESYSTEM + //PE: Wicked particle system. + lua_register(lua, "WParticleEffectLoad", WParticleEffectLoad); + lua_register(lua, "WParticleEffectPosition", WParticleEffectPosition); + lua_register(lua, "WParticleEffectVisible", WParticleEffectVisible); + lua_register(lua, "WParticleEffectAction", WParticleEffectAction); + + //PE: Other missing commands. + lua_register(lua, "PositionSound", entity_lua_positionsound); + +#endif + lua_register(lua, "GetBulletHit", GetBulletHit); lua_register(lua, "SetFlashLight" , SetFlashLight ); lua_register(lua, "SetAttachmentVisible" , SetAttachmentVisible ); @@ -12811,6 +13093,8 @@ void addFunctions() lua_register(lua, "GetCurrentScreen", GetCurrentScreen); lua_register(lua, "GetCurrentScreenName", GetCurrentScreenName); lua_register(lua, "CheckScreenToggles", CheckScreenToggles); + lua_register(lua, "DisableBoundHudKeys", DisableBoundHudKeys); + lua_register(lua, "EnableBoundHudKeys", EnableBoundHudKeys); lua_register(lua, "ScreenToggle", ScreenToggle); lua_register(lua, "ScreenToggleByKey", ScreenToggleByKey); lua_register(lua, "GetIfUsingTABScreen", GetIfUsingTABScreen); diff --git a/GameGuru Core/Dark Basic Public Shared/Dark Basic Pro SDK/DarkSDKMore/DarkLUA/DarkLUA.vcxproj b/GameGuru Core/Dark Basic Public Shared/Dark Basic Pro SDK/DarkSDKMore/DarkLUA/DarkLUA.vcxproj index 4cfa7f7d..b8c16a47 100644 --- a/GameGuru Core/Dark Basic Public Shared/Dark Basic Pro SDK/DarkSDKMore/DarkLUA/DarkLUA.vcxproj +++ b/GameGuru Core/Dark Basic Public Shared/Dark Basic Pro SDK/DarkSDKMore/DarkLUA/DarkLUA.vcxproj @@ -79,14 +79,14 @@ MaxSpeed false - WIN32;NDEBUG;_WINDOWS;_USRDLL;DARKLUA_EXPORTS;%(PreprocessorDefinitions) + GGREDUCED;WIN32;NDEBUG;_WINDOWS;_USRDLL;DARKLUA_EXPORTS;%(PreprocessorDefinitions) MultiThreaded true Level1 ProgramDatabase - lua;%(AdditionalIncludeDirectories);$(ProjectDir)..\..\..\Include\;$(ProjectDir)..\..\..\..\Dark Wicked Shared\Include\;$(ProjectDir)..\..\..\..\GameGuru\Include\;$(ProjectDir)..\..\..\..\SDK\RecastContrib;$(ProjectDir)..\..\..\..\SDK\RecastContrib\fastlz;$(ProjectDir)..\..\..\..\Guru-WickedMAX\GGRecastDetour\DebugUtils/Include;$(ProjectDir)..\..\..\..\Guru-WickedMAX\GGRecastDetour\Detour/Include;$(ProjectDir)..\..\..\..\Guru-WickedMAX\GGRecastDetour\DetourCrowd/Include;$(ProjectDir)..\..\..\..\Guru-WickedMAX\GGRecastDetour\DetourTileCache/Include;$(ProjectDir)..\..\..\..\Guru-WickedMAX\GGRecastDetour\Recast/Include;$(ProjectDir)..\..\..\..\Guru-WickedMAX\GGRecastDetour\;$(ProjectDir)..\..\..\..\SDK\RecastContrib\SDL\include + ../../../../../../WICKEDREPO/WickedEngine;lua;%(AdditionalIncludeDirectories);$(ProjectDir)..\..\..\Include\;$(ProjectDir)..\..\..\..\Dark Wicked Shared\Include\;$(ProjectDir)..\..\..\..\GameGuru\Include\;$(ProjectDir)..\..\..\..\SDK\RecastContrib;$(ProjectDir)..\..\..\..\SDK\RecastContrib\fastlz;$(ProjectDir)..\..\..\..\Guru-WickedMAX\GGRecastDetour\DebugUtils/Include;$(ProjectDir)..\..\..\..\Guru-WickedMAX\GGRecastDetour\Detour/Include;$(ProjectDir)..\..\..\..\Guru-WickedMAX\GGRecastDetour\DetourCrowd/Include;$(ProjectDir)..\..\..\..\Guru-WickedMAX\GGRecastDetour\DetourTileCache/Include;$(ProjectDir)..\..\..\..\Guru-WickedMAX\GGRecastDetour\Recast/Include;$(ProjectDir)..\..\..\..\Guru-WickedMAX\GGRecastDetour\;$(ProjectDir)..\..\..\..\SDK\RecastContrib\SDL\include false 4005;4995;4723 Disabled @@ -133,14 +133,14 @@ Disabled false - WIN32;NDEBUG;_WINDOWS;_USRDLL;DARKLUA_EXPORTS;%(PreprocessorDefinitions) + GGREDUCED;WIN32;NDEBUG;_WINDOWS;_USRDLL;DARKLUA_EXPORTS;%(PreprocessorDefinitions) MultiThreadedDebug true Level1 ProgramDatabase - lua;%(AdditionalIncludeDirectories);$(ProjectDir)..\..\..\Include\;$(ProjectDir)..\..\..\..\Dark Wicked Shared\Include\;$(ProjectDir)..\..\..\..\GameGuru\Include\;$(ProjectDir)..\..\..\..\SDK\RecastContrib;$(ProjectDir)..\..\..\..\SDK\RecastContrib\fastlz;$(ProjectDir)..\..\..\..\Guru-WickedMAX\GGRecastDetour\DebugUtils/Include;$(ProjectDir)..\..\..\..\Guru-WickedMAX\GGRecastDetour\Detour/Include;$(ProjectDir)..\..\..\..\Guru-WickedMAX\GGRecastDetour\DetourCrowd/Include;$(ProjectDir)..\..\..\..\Guru-WickedMAX\GGRecastDetour\DetourTileCache/Include;$(ProjectDir)..\..\..\..\Guru-WickedMAX\GGRecastDetour\Recast/Include;$(ProjectDir)..\..\..\..\Guru-WickedMAX\GGRecastDetour\;$(ProjectDir)..\..\..\..\SDK\RecastContrib\SDL\include + ../../../../../../WICKEDREPO/WickedEngine;lua;%(AdditionalIncludeDirectories);$(ProjectDir)..\..\..\Include\;$(ProjectDir)..\..\..\..\Dark Wicked Shared\Include\;$(ProjectDir)..\..\..\..\GameGuru\Include\;$(ProjectDir)..\..\..\..\SDK\RecastContrib;$(ProjectDir)..\..\..\..\SDK\RecastContrib\fastlz;$(ProjectDir)..\..\..\..\Guru-WickedMAX\GGRecastDetour\DebugUtils/Include;$(ProjectDir)..\..\..\..\Guru-WickedMAX\GGRecastDetour\Detour/Include;$(ProjectDir)..\..\..\..\Guru-WickedMAX\GGRecastDetour\DetourCrowd/Include;$(ProjectDir)..\..\..\..\Guru-WickedMAX\GGRecastDetour\DetourTileCache/Include;$(ProjectDir)..\..\..\..\Guru-WickedMAX\GGRecastDetour\Recast/Include;$(ProjectDir)..\..\..\..\Guru-WickedMAX\GGRecastDetour\;$(ProjectDir)..\..\..\..\SDK\RecastContrib\SDL\include false 4005;4995;4723 Default diff --git a/GameGuru Core/Dark Basic Public Shared/Dark Basic Pro SDK/Shared/DBOFormat/DBOFormat.cpp b/GameGuru Core/Dark Basic Public Shared/Dark Basic Pro SDK/Shared/DBOFormat/DBOFormat.cpp index 9d57b99d..0cf41058 100644 --- a/GameGuru Core/Dark Basic Public Shared/Dark Basic Pro SDK/Shared/DBOFormat/DBOFormat.cpp +++ b/GameGuru Core/Dark Basic Public Shared/Dark Basic Pro SDK/Shared/DBOFormat/DBOFormat.cpp @@ -7585,6 +7585,9 @@ DARKSDK_DLL bool LoadDBO ( LPSTR pPassedInFilename, sObject** ppObject ) // construct the object if (!DBOConvertBlockToObject((void*)pDBOBlock, dwBlockSize, ppObject)) { + char str[1024]; + sprintf_s(str, "Failed to load object: %s", pFilename); + Message(0, str, "Error"); RunTimeError(RUNTIMEERROR_B3DOBJECTLOADFAILED); return false; } diff --git a/GameGuru Core/Dark Basic Public Shared/Dark Basic Pro SDK/Shared/Objects/CommonC.cpp b/GameGuru Core/Dark Basic Public Shared/Dark Basic Pro SDK/Shared/Objects/CommonC.cpp index 8fc2adbd..0b983151 100644 --- a/GameGuru Core/Dark Basic Public Shared/Dark Basic Pro SDK/Shared/Objects/CommonC.cpp +++ b/GameGuru Core/Dark Basic Public Shared/Dark Basic Pro SDK/Shared/Objects/CommonC.cpp @@ -950,6 +950,9 @@ DARKSDK_DLL bool SetNewObjectFinalProperties ( int iID, float fRadius ) if ( pObject->ppFrameList==NULL ) { // free object if insufficient data + char str[1024]; + sprintf_s(str, "ObjectID: %d. Do not have a framelist.", iID); + Message(0, str, "Error"); RunTimeError ( RUNTIMEERROR_B3DOBJECTLOADFAILED ); SAFE_DELETE ( g_ObjectList [ iID ] ); return false; diff --git a/GameGuru Core/GameGuru/Imgui/imgui_gg_dx11.cpp b/GameGuru Core/GameGuru/Imgui/imgui_gg_dx11.cpp index 72871810..0dece0ef 100644 --- a/GameGuru Core/GameGuru/Imgui/imgui_gg_dx11.cpp +++ b/GameGuru Core/GameGuru/Imgui/imgui_gg_dx11.cpp @@ -5323,7 +5323,10 @@ int iTotalFiles = 0; #ifdef WICKEDENGINE -std::vector< std::pair > files_time_stamp; +//std::vector< std::pair > files_time_stamp; +std::unordered_map files_time_stamp; + + std::vector files_favorite; std::vector files_availableinfreetrial; std::vector files_pinned_categories; @@ -5652,8 +5655,9 @@ bool fpe_thread_in_progress(void) #endif -std::vector duplicate_files_check; - +//std::vector duplicate_files_check; +//PE: Converted to unordered_set using hash for faster lookups. +std::unordered_set duplicate_files_check; void CustomSortFiles(int iSortBy, cFolderItem::sFolderFiles * m_pFileSortStart) { @@ -6120,7 +6124,8 @@ void GetMainEntityList(char* folder_s, char* rel_s, void *pFolder, char* folder_ time_t ts = GetFileDateLong(); cstr file = pNewFolder->m_pNext->m_sFolderFullPath; file = file + "\\" + file_s; - files_time_stamp.push_back( std::make_pair(file.Get(), ts ) ); + //files_time_stamp.push_back( std::make_pair(file.Get(), ts ) ); + files_time_stamp[file.Get()] = ts; #endif } } @@ -6206,11 +6211,16 @@ void GetMainEntityList(char* folder_s, char* rel_s, void *pFolder, char* folder_ //sCheck = sCheck + cstr("\\") + sName; } sCheck = sCheck.Lower(); - auto itr = std::find(duplicate_files_check.begin(), duplicate_files_check.end(), sCheck.Get()); - if (itr != duplicate_files_check.end() && duplicate_files_check.size() > 0 ) + //auto itr = std::find(duplicate_files_check.begin(), duplicate_files_check.end(), sCheck.Get()); + //if (itr != duplicate_files_check.end() && duplicate_files_check.size() > 0 ) + // bAddToList = false; + //else + // duplicate_files_check.push_back(sCheck.Get()); + + if (duplicate_files_check.count(sCheck.Get()) > 0) bAddToList = false; else - duplicate_files_check.push_back(sCheck.Get()); + duplicate_files_check.insert(sCheck.Get()); } #endif if (it->size() > 0 && bAddToList) @@ -6258,17 +6268,22 @@ void GetMainEntityList(char* folder_s, char* rel_s, void *pFolder, char* folder_ struct stat sb; cstr file = pNewFolder->m_pNext->m_sFolderFullPath; file = file + "\\" + pNewItem->m_sName; - std::vector< std::pair >::iterator its = files_time_stamp.begin(); - for (; its != files_time_stamp.end(); ++its) - { - if (its->first.size() > 0) - { - if( strcmp(its->first.c_str(),file.Get()) == 0 ) - { - pNewItem->m_tFileModify = its->second; - break; - } - } + //std::vector< std::pair >::iterator its = files_time_stamp.begin(); + //for (; its != files_time_stamp.end(); ++its) + //{ + // if (its->first.size() > 0) + // { + // if( strcmp(its->first.c_str(),file.Get()) == 0 ) + // { + // pNewItem->m_tFileModify = its->second; + // break; + // } + // } + //} + + auto it = files_time_stamp.find(file.Get()); + if (it != files_time_stamp.end()) { + pNewItem->m_tFileModify = it->second; } std::vector::iterator itf = files_favorite.begin(); for (; itf != files_favorite.end(); ++itf) @@ -6443,19 +6458,25 @@ void RefreshEntityFolder(char* folder_s, void *pFolder) cstr file = pNewFolder->m_sFolderFullPath; file = file + "\\" + file_s; - std::vector< std::pair >::iterator its = files_time_stamp.begin(); - for (; its != files_time_stamp.end(); ++its) - { - if (its->first.size() > 0) { - if (strcmp(its->first.c_str(), file.Get()) == 0) - { - files_time_stamp.erase(its); - break; - } - } + //std::vector< std::pair >::iterator its = files_time_stamp.begin(); + //for (; its != files_time_stamp.end(); ++its) + //{ + // if (its->first.size() > 0) { + // if (strcmp(its->first.c_str(), file.Get()) == 0) + // { + // files_time_stamp.erase(its); + // break; + // } + // } + //} + + auto it = files_time_stamp.find(file.Get()); + if (it != files_time_stamp.end()) { + files_time_stamp.erase(it); } - files_time_stamp.push_back(std::make_pair(file.Get(), ts)); + //files_time_stamp.push_back(std::make_pair(file.Get(), ts)); + files_time_stamp[file.Get()] = ts; #endif } @@ -6544,9 +6565,13 @@ void RefreshEntityFolder(char* folder_s, void *pFolder) //sCheck = sCheck + cstr("\\") + sName; } sCheck = sCheck.Lower(); - auto itr = std::find(duplicate_files_check.begin(), duplicate_files_check.end(), sCheck.Get()); - if(!(itr != duplicate_files_check.end() && duplicate_files_check.size() > 0)) - duplicate_files_check.push_back(sCheck.Get()); + //auto itr = std::find(duplicate_files_check.begin(), duplicate_files_check.end(), sCheck.Get()); + //if(!(itr != duplicate_files_check.end() && duplicate_files_check.size() > 0)) + // duplicate_files_check.push_back(sCheck.Get()); + + if (duplicate_files_check.count(sCheck.Get()) <= 0) + duplicate_files_check.insert(sCheck.Get()); + } #endif if (it->size() > 0) @@ -6593,18 +6618,25 @@ void RefreshEntityFolder(char* folder_s, void *pFolder) struct stat sb; cstr file = pNewFolder->m_sFolderFullPath; file = file + "\\" + pNewItem->m_sName; - std::vector< std::pair >::iterator its = files_time_stamp.begin(); - for (; its != files_time_stamp.end(); ++its) - { - if (its->first.size() > 0) - { - if (strcmp(its->first.c_str(), file.Get()) == 0) - { - pNewItem->m_tFileModify = its->second; - break; - } - } + + //std::vector< std::pair >::iterator its = files_time_stamp.begin(); + //for (; its != files_time_stamp.end(); ++its) + //{ + // if (its->first.size() > 0) + // { + // if (strcmp(its->first.c_str(), file.Get()) == 0) + // { + // pNewItem->m_tFileModify = its->second; + // break; + // } + // } + //} + + auto it = files_time_stamp.find(file.Get()); + if (it != files_time_stamp.end()) { + pNewItem->m_tFileModify = it->second; } + std::vector::iterator itf = files_favorite.begin(); for (; itf != files_favorite.end(); ++itf) { @@ -6787,8 +6819,10 @@ void InitParseLuaScript(entityeleproftype *tmpeleprof) strcpy(tmpeleprof->PropertiesVariable.VariableValue[i], ""); tmpeleprof->PropertiesVariable.VariableValueFrom[i] = 0.0f; tmpeleprof->PropertiesVariable.VariableValueTo[i] = 0.0f; - strcpy(tmpeleprof->PropertiesVariable.VariableSectionDescription[i], ""); - strcpy(tmpeleprof->PropertiesVariable.VariableSectionEndDescription[i], ""); + //strcpy(tmpeleprof->PropertiesVariable.VariableSectionDescription[i], ""); + tmpeleprof->PropertiesVariable.VariableSectionDescription[i] = ""; + //strcpy(tmpeleprof->PropertiesVariable.VariableSectionEndDescription[i], ""); + tmpeleprof->PropertiesVariable.VariableSectionEndDescription[i] = ""; } #ifdef WICKEDENGINE @@ -6821,15 +6855,18 @@ void ParseLuaScriptWithElementID(entityeleproftype *tmpeleprof, char * script, i tmpeleprof->PropertiesVariable.iVariables = 0; tmpeleprof->PropertiesVariable.VariableDescription = ""; //scriptbank\markers\storyinzone.lua fails. + FILE* fScript = GG_fopen(script, "r"); if (fScript) { - char ctmp[4096]; + char ctmp[8192]; + int include_returns = 0; + int description_lines = 0; bool bFirstLine = true; while (!feof(fScript)) { - fgets(ctmp, 4095 , fScript); - ctmp[4095] = 0; + fgets(ctmp, 8190 , fScript); + ctmp[8190] = 0; if (strlen(ctmp) > 0 && ctmp[strlen(ctmp) - 1] == '\n') ctmp[strlen(ctmp) - 1] = 0; int cadd = 0; @@ -6853,13 +6890,33 @@ void ParseLuaScriptWithElementID(entityeleproftype *tmpeleprof, char * script, i tmpeleprof->PropertiesVariable.VariableDescription += " "; tmpeleprof->PropertiesVariable.VariableDescription += ctmp; } + description_lines++; //Activate Propertie Variables. bFirstLine = false; } - } fclose(fScript); + //PE: Make error for scripts with missing newline. + if (description_lines <= 1) + { + //PE: Check if lua files is missing \n newlines this can really give strange results. + strcpy(ctmp, tmpeleprof->PropertiesVariable.VariableDescription.Get()); + //PE: Scan for non newline text file. + for (int i = 0; i < strlen(ctmp); i++) + { + if (ctmp[i] == '\r') + { + include_returns++; + break; + } + } + if (include_returns > 0) + { + tmpeleprof->PropertiesVariable.VariableDescription = "Lua script is missing 'newlines' and description can't be parsed!"; + } + } + //Activate Propertie Variables. bFirstLine = false; //while [ , collect all variables. @@ -6882,46 +6939,60 @@ void ParseLuaScriptWithElementID(entityeleproftype *tmpeleprof, char * script, i if (tmpeleprof->PropertiesVariable.iVariables >= 1) { //Add space - strcpy(tmpeleprof->PropertiesVariable.VariableSectionDescription[tmpeleprof->PropertiesVariable.iVariables], " "); - strcat(tmpeleprof->PropertiesVariable.VariableSectionDescription[tmpeleprof->PropertiesVariable.iVariables], SectionDescription); + //strcpy(tmpeleprof->PropertiesVariable.VariableSectionDescription[tmpeleprof->PropertiesVariable.iVariables], " "); + //strcat(tmpeleprof->PropertiesVariable.VariableSectionDescription[tmpeleprof->PropertiesVariable.iVariables], SectionDescription); + tmpeleprof->PropertiesVariable.VariableSectionDescription[tmpeleprof->PropertiesVariable.iVariables] = cStr(" ") + cStr(SectionDescription); } else { - strcpy(tmpeleprof->PropertiesVariable.VariableSectionDescription[tmpeleprof->PropertiesVariable.iVariables], SectionDescription); + //strcpy(tmpeleprof->PropertiesVariable.VariableSectionDescription[tmpeleprof->PropertiesVariable.iVariables], SectionDescription); + tmpeleprof->PropertiesVariable.VariableSectionDescription[tmpeleprof->PropertiesVariable.iVariables] = SectionDescription; } - strcpy(tmpeleprof->PropertiesVariable.VariableSectionEndDescription[tmpeleprof->PropertiesVariable.iVariables], ""); + //strcpy(tmpeleprof->PropertiesVariable.VariableSectionEndDescription[tmpeleprof->PropertiesVariable.iVariables], ""); + tmpeleprof->PropertiesVariable.VariableSectionEndDescription[tmpeleprof->PropertiesVariable.iVariables] = ""; SectionDescription = find2 + 1; if (!pestrcasestr(SectionDescription, "[")) { if (SectionDescription[0] != 0) { - strcpy(tmpeleprof->PropertiesVariable.VariableSectionEndDescription[tmpeleprof->PropertiesVariable.iVariables], SectionDescription); + //strcpy(tmpeleprof->PropertiesVariable.VariableSectionEndDescription[tmpeleprof->PropertiesVariable.iVariables], SectionDescription); + tmpeleprof->PropertiesVariable.VariableSectionEndDescription[tmpeleprof->PropertiesVariable.iVariables] = SectionDescription; } } tmpeleprof->PropertiesVariable.VariableType[tmpeleprof->PropertiesVariable.iVariables] = 0; - strcpy(tmpeleprof->PropertiesVariable.Variable[tmpeleprof->PropertiesVariable.iVariables], find + 1); - if (pestrcasestr(tmpeleprof->PropertiesVariable.Variable[tmpeleprof->PropertiesVariable.iVariables], "#")) + + //PE: tmpeleprof->PropertiesVariable.Variable can be larger then 100 before '=' is found. + char tmpVariable[1024]; + strcpy(tmpVariable, find + 1); + + //PE: Scan all lua script for largest [] // [@MULTI_TRIGGER=2(1=Yes, 2=No)] + //if (strlen(tmpeleprof->PropertiesVariable.Variable[tmpeleprof->PropertiesVariable.iVariables]) > maxvariable) + // maxvariable = strlen(tmpeleprof->PropertiesVariable.Variable[tmpeleprof->PropertiesVariable.iVariables]); + + if (pestrcasestr(tmpVariable, "#")) tmpeleprof->PropertiesVariable.VariableType[tmpeleprof->PropertiesVariable.iVariables] = 1; //float - if (pestrcasestr(tmpeleprof->PropertiesVariable.Variable[tmpeleprof->PropertiesVariable.iVariables], "$")) + if (pestrcasestr(tmpVariable, "$")) tmpeleprof->PropertiesVariable.VariableType[tmpeleprof->PropertiesVariable.iVariables] = 2; //string - if (pestrcasestr(tmpeleprof->PropertiesVariable.Variable[tmpeleprof->PropertiesVariable.iVariables], "!")) + if (pestrcasestr(tmpVariable, "!")) tmpeleprof->PropertiesVariable.VariableType[tmpeleprof->PropertiesVariable.iVariables] = 3; //bool #ifdef WICKEDENGINE - if (pestrcasestr(tmpeleprof->PropertiesVariable.Variable[tmpeleprof->PropertiesVariable.iVariables], "@")) + if (pestrcasestr(tmpVariable, "@")) tmpeleprof->PropertiesVariable.VariableType[tmpeleprof->PropertiesVariable.iVariables] = 4; // labelled int[] - if (pestrcasestr(tmpeleprof->PropertiesVariable.Variable[tmpeleprof->PropertiesVariable.iVariables], "*")) + if (pestrcasestr(tmpVariable, "*")) tmpeleprof->PropertiesVariable.VariableType[tmpeleprof->PropertiesVariable.iVariables] = 5; // user specified in seconds - if (pestrcasestr(tmpeleprof->PropertiesVariable.Variable[tmpeleprof->PropertiesVariable.iVariables], "&")) + if (pestrcasestr(tmpVariable, "&")) tmpeleprof->PropertiesVariable.VariableType[tmpeleprof->PropertiesVariable.iVariables] = 6; // should alter eleprof variable #endif //Set default values search for = - char *find3 = (char *)pestrcasestr(tmpeleprof->PropertiesVariable.Variable[tmpeleprof->PropertiesVariable.iVariables], "="); + char *find3 = (char *)pestrcasestr(tmpVariable, "="); if (find3) { strcpy(tmpeleprof->PropertiesVariable.VariableValue[tmpeleprof->PropertiesVariable.iVariables], find3 + 1); find3[0] = 0; // remove = from Variable. + strcpy(tmpeleprof->PropertiesVariable.Variable[tmpeleprof->PropertiesVariable.iVariables], tmpVariable); + //check if we got a range. char *find4 = (char *)pestrcasestr(tmpeleprof->PropertiesVariable.VariableValue[tmpeleprof->PropertiesVariable.iVariables], "("); if (find4) @@ -7042,13 +7113,35 @@ void ParseLuaScriptWithElementID(entityeleproftype *tmpeleprof, char * script, i } if (labels.size() == 2) { + //InterActionWeaponList + if (stricmp(labels[1].c_str(), "interactionweaponlist") == NULL) + { + labels.clear(); + labels.push_back(cVariable); + int iWeaponListIndex = 1; + //PE: Add filter. + int FillWeaponList(std::vector& labels, char* filter); + iWeaponListIndex += FillWeaponList(labels, "Interaction"); + + if (iWeaponListIndex > 0) + { + tmpeleprof->PropertiesVariable.VariableValueFrom[tmpeleprof->PropertiesVariable.iVariables] = 1; + tmpeleprof->PropertiesVariable.VariableValueTo[tmpeleprof->PropertiesVariable.iVariables] = iWeaponListIndex; + } + else + { + tmpeleprof->PropertiesVariable.VariableValueFrom[tmpeleprof->PropertiesVariable.iVariables] = 0; + tmpeleprof->PropertiesVariable.VariableValueTo[tmpeleprof->PropertiesVariable.iVariables] = 0; + } + + } if (stricmp(labels[1].c_str(), "anyweaponlist") == NULL) { labels.clear(); labels.push_back(cVariable); int iWeaponListIndex = 1; - int FillWeaponList(std::vector &labels); - iWeaponListIndex += FillWeaponList( labels); + int FillWeaponList(std::vector &labels, char* filter); + iWeaponListIndex += FillWeaponList( labels , nullptr); if (iWeaponListIndex > 0) { @@ -7126,7 +7219,11 @@ void ParseLuaScriptWithElementID(entityeleproftype *tmpeleprof, char * script, i } } else + { strcpy(tmpeleprof->PropertiesVariable.VariableValue[tmpeleprof->PropertiesVariable.iVariables], ""); + tmpVariable[MAXVARIABLESIZE - 1] = 0; + strcpy(tmpeleprof->PropertiesVariable.Variable[tmpeleprof->PropertiesVariable.iVariables], tmpVariable); + } //Clean variable name. std::string clean_string = tmpeleprof->PropertiesVariable.Variable[tmpeleprof->PropertiesVariable.iVariables]; @@ -7739,7 +7836,12 @@ int DisplayLuaDescription(entityeleproftype *tmpeleprof) } } } - if (bIsAQuestList == true && iQuestIndex > 0) + bool bBelowQuestCombo = false; + if (strstr(tmpeleprof->PropertiesVariable.Variable[i], "QuestChoice") != NULL) + { + bBelowQuestCombo = true; + } + if (bBelowQuestCombo && bIsAQuestList == true && iQuestIndex > 0) { bool bDoARefresh = false; float but_gadget_size = ImGui::GetFontSize() * 12.0; @@ -7762,6 +7864,11 @@ int DisplayLuaDescription(entityeleproftype *tmpeleprof) collectionQuestType item; fill_rpg_quest_defaults(&item, tmpeleprof->name_s.Get()); + //PE: Just to stop crash if not using storyboard. + if (g_collectionQuestLabels.size() == 0) + { + bFoundMatch = false; + } // only add unique quest titles if (bFoundMatch == false) { @@ -8159,11 +8266,16 @@ void fDisplayDescriptionBox(entityeleproftype *tmpeleprof, bool textonly = false { for (int i = 0; i < tmpeleprof->PropertiesVariable.iVariables; i++) { - segs[curseg++] = Segment(tmpeleprof->PropertiesVariable.VariableSectionDescription[i]); + //segs[curseg++] = Segment(tmpeleprof->PropertiesVariable.VariableSectionDescription[i]); + segs[curseg++] = Segment(tmpeleprof->PropertiesVariable.VariableSectionDescription[i].Get()); segs[curseg++] = Segment(tmpeleprof->PropertiesVariable.Variable[i], IM_COL32(col.x, col.y, col.z, col.w), true); - if (strlen(tmpeleprof->PropertiesVariable.VariableSectionEndDescription[i]) > 0) + //if (strlen(tmpeleprof->PropertiesVariable.VariableSectionEndDescription[i]) > 0) + //{ + // segs[curseg++] = Segment(tmpeleprof->PropertiesVariable.VariableSectionEndDescription[i]); + //} + if (tmpeleprof->PropertiesVariable.VariableSectionEndDescription[i].Len() > 0) { - segs[curseg++] = Segment(tmpeleprof->PropertiesVariable.VariableSectionEndDescription[i]); + segs[curseg++] = Segment(tmpeleprof->PropertiesVariable.VariableSectionEndDescription[i].Get()); } if (curseg >= (MAXPROPERTIESVARIABLES * 3) - 1) break; diff --git a/GameGuru Core/GameGuru/Imgui/imgui_gg_dx11.h b/GameGuru Core/GameGuru/Imgui/imgui_gg_dx11.h index c4882344..e14eeee8 100644 --- a/GameGuru Core/GameGuru/Imgui/imgui_gg_dx11.h +++ b/GameGuru Core/GameGuru/Imgui/imgui_gg_dx11.h @@ -400,7 +400,7 @@ IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects(); #define FILTER_THUMBS UIV3IMAGES + 5900 #define TERRAINGENERATOR_OBJECT 17998 -#define TERRAINGENERATOR_IMAGE 63340 +//#define TERRAINGENERATOR_IMAGE 63340 //PE: Not used and goes into storyboard uniqueids. //PE: STORYBOARD_THUMBS must be the last in the list here. if you need room here, increase STORYBOARD_THUMBS so its last. #define STORYBOARD_THUMBS UIV3IMAGES + 6000 @@ -698,14 +698,16 @@ enum eKeyboardShortcutType void UniversalKeyboardShortcut(eKeyboardShortcutType KST); #ifdef STORYBOARD -#define STORYBOARD_MAXOUTPUTS 20 -#define STORYBOARD_MAXNODES 50 +#define STORYBOARD_MAXOUTPUTS 30 +#define STORYBOARD_MAXWIDGETS 100 +//PE: 150 = stack overflow. +#define STORYBOARD_MAXNODES 150 + #define SMALL_STORYBOARD_MAXNODES 15 -#define STORYBOARDVERSION 202 +#define STORYBOARDVERSION 203 #define NODE_WIDTH_PADDING -15.0 #define NODE_HEIGHT_PADDING 23.0 -#define STORYBOARD_MAXWIDGETS 50 void storyboard_menubar(float area_width, float node_width, float node_height); @@ -888,6 +890,7 @@ struct StoryboardNodesStruct int iFillerMaxOutputs20[20][STORYBOARD_MAXOUTPUTS]; char FillerCharMaxOutput20[20][STORYBOARD_MAXOUTPUTS][256]; }; + struct StoryboardStruct { char sig[12] = "Storyboard\0"; @@ -918,6 +921,108 @@ struct StoryboardStruct //PE: To add new variables add them here, always add to botton of list. }; + +#define STORYBOARD_MAXNODES202 50 +#define STORYBOARD_MAXOUTPUTS202 20 +#define STORYBOARD_MAXWIDGETS202 50 + +struct StoryboardNodesStruct202 +{ + int type; + int id; + ImVec2 restore_position; + int iEditEnable; + int used; + int thumb_id; + char title[256]; + char levelnumber[256]; + char thumb[256]; + char level_name[256]; //PE: For custom lua scripts. + char lua_name[256]; //PE: For custom lua scripts. + char scene_name[256]; //PE: Scene temp files can have anykind of info, so just make each scene it own file. + int input_id[STORYBOARD_MAXOUTPUTS202]; + int output_id[STORYBOARD_MAXOUTPUTS202]; + char output_action[STORYBOARD_MAXOUTPUTS202][256]; + char output_title[STORYBOARD_MAXOUTPUTS202][256]; + int output_linkto[STORYBOARD_MAXOUTPUTS202]; + int output_can_link_to_type[STORYBOARD_MAXOUTPUTS202]; + char input_title[STORYBOARD_MAXOUTPUTS202][256]; + char input_action[STORYBOARD_MAXOUTPUTS202][256]; + + //Screen + char screen_title[256]; + char screen_music[256]; + char screen_backdrop[256]; + int screen_backdrop_id; + ImVec4 screen_back_color; + int screen_backdrop_placement; // center,stretch,zoom. + char screen_thumb[256]; + int screen_backdrop_ratio_placement[10]; // 0=1920x1080 center,stretch,zoom. 1=1366x768 center,stretch,zoom ... + int screen_grid_size = 0; + + //Editor. + int widget_used[STORYBOARD_MAXWIDGETS202]; + char widget_label[STORYBOARD_MAXWIDGETS202][256]; + ImVec2 widget_size[STORYBOARD_MAXWIDGETS202]; + ImVec2 widget_pos[STORYBOARD_MAXWIDGETS202]; + char widget_normal_thumb[STORYBOARD_MAXWIDGETS202][256]; + int widget_normal_thumb_id[STORYBOARD_MAXWIDGETS202]; + char widget_highlight_thumb[STORYBOARD_MAXWIDGETS202][256]; + int widget_highlight_thumb_id[STORYBOARD_MAXWIDGETS202]; + char widget_selected_thumb[STORYBOARD_MAXWIDGETS202][256]; //only for state change button, checkbox ... + int widget_selected_thumb_id[STORYBOARD_MAXWIDGETS202]; + char widget_click_sound[STORYBOARD_MAXWIDGETS202][256]; + int widget_action[STORYBOARD_MAXWIDGETS202]; + char widget_font[STORYBOARD_MAXWIDGETS202][256]; + ImVec4 widget_font_color[STORYBOARD_MAXWIDGETS202]; + float widget_font_size[STORYBOARD_MAXWIDGETS202]; + int widget_type[STORYBOARD_MAXWIDGETS202]; // but,text,image,video... + int widget_read_only[STORYBOARD_MAXWIDGETS202]; + int widget_layer[STORYBOARD_MAXWIDGETS202]; + //int widget_output_pin[STORYBOARD_MAXWIDGETS202]; //off,level,screen. 2023 - does not seem to be used + int widget_initial_value[STORYBOARD_MAXWIDGETS202]; //off,level,screen. + char widget_name[STORYBOARD_MAXWIDGETS202][256]; //for generating final images in titlebank/default/... + //PE: Lets do some fillers, so when starting to save project we can just expend it later. + //PE: You just add a new one, a line before the filler and cound the filler down. + int screen_backdrop_transparent; + int readouts_available = 0; + int widgets_available = ALLOW_TEXT | ALLOW_IMAGE | ALLOW_VIDEO; + int toggleKey = 0; + int showAtStart = 0; + int iFiller20[15]; + float fFiller20[20]; + int iFillerMaxOutputs20[20][STORYBOARD_MAXOUTPUTS202]; + char FillerCharMaxOutput20[20][STORYBOARD_MAXOUTPUTS202][256]; +}; + +struct StoryboardStruct202 +{ + char sig[12] = "Storyboard\0"; + char gamename[256]; + int iStoryboardVersion = STORYBOARDVERSION; //PE: Just in case in the future if we need to convert this structure into a new struct. + int iChanged; + ImVec2 vEditorPanning = ImVec2(0.0f, 0.0f); + StoryboardNodesStruct202 Nodes[STORYBOARD_MAXNODES202]; + int NodeRadioButtonSelected[STORYBOARD_MAXNODES202]; + float NodeSliderValues[STORYBOARD_MAXNODES202][STORYBOARD_MAXWIDGETS202]; + char game_icon[256]; + char game_thumb[256]; + char game_description[4096]; + char game_world_edge_text[1024]; //PE: ? should be a node ? so display screen directly ? + int project_readonly; + int game_thumb_id; + int game_icon_id; + char game_developer_desc[1024]; + // Have to add here instead of inside StoryboardNodesStruct, otherwise loaded storyboards would become corrupted + ImVec4 widget_colors[STORYBOARD_MAXNODES202][STORYBOARD_MAXWIDGETS202]; + char widget_readout[STORYBOARD_MAXNODES202][STORYBOARD_MAXWIDGETS202][128]; + ImVec2 widget_textoffset[STORYBOARD_MAXNODES202][STORYBOARD_MAXWIDGETS202]; + int widget_ingamehidden[STORYBOARD_MAXNODES202][STORYBOARD_MAXWIDGETS202]; + int widget_drawordergroup[STORYBOARD_MAXNODES202][STORYBOARD_MAXWIDGETS202]; + + char customprojectfolder[256]; +}; + //PE: SmallStoryboardStruct Not to be used, only for fast locating of thumbs. struct SmallStoryboardStruct { diff --git a/GameGuru Core/GameGuru/Include/Types.h b/GameGuru Core/GameGuru/Include/Types.h index 4c3d7138..db50e6ea 100644 --- a/GameGuru Core/GameGuru/Include/Types.h +++ b/GameGuru Core/GameGuru/Include/Types.h @@ -11,6 +11,10 @@ #include #include "M-CharacterCreatorPlus.h" + +//PE: MAX_PATH not defined in all source files. +#define MAXPATH 1050 + // Master settings (MAXTEXTURESIZEMULTIPLIER is 1024*? to get MAXTEXTURESIZE) #define MAXTEXTURESIZE 2048 #define MAXTEXTURESIZEMULTIPLIER 2 @@ -2894,7 +2898,7 @@ struct importertype bool bQuitForReload; int iViewCollisionShapes; bool bInvertNormalMap; - char pOrigNormalMap[MAX_PATH]; + char pOrigNormalMap[MAXPATH]; std::vector pSurfaceFilesToDelete; std::vector meshesToExclude; #endif @@ -6277,24 +6281,36 @@ struct entityprofiletype //PE: Saving memory - sizeof(PropertiesVariables) 85328 unsigned __int64 (this is per object on your level so... 5000 obj = 0.39gb.) //PE: No one is going to be feeding 80 variables into a single lua script so lowered this. //PE: Now - sizeof(PropertiesVariables) 32344 unsigned __int64 (this saving is per object added so huge 5000 obj = 0.15gb. 0.24gb saved). -#define MAXPROPERTIESVARIABLES 35 +#define MAXPROPERTIESVARIABLES 40 #define MAXVARIABLETEXTSIZE 260 #define MAXVARIABLETEXTSIZELARGE 512 -#define MAXVARIABLESIZE 100 +#define MAXVARIABLESIZE 50 + +//PE: 11/30/24 - 41160 +//PE: Necrym59 Need more, increase to 40 and decrease overall mem use. +//PE: Scanning all lua scripts MAXVARIABLESIZE = 23 , so lower it to 50. +//PE: Convert VariableSectionDescription into cstr to use min size 100 (add MAXPROPERTIESVARIABLES*100 to see less mem use) +//PE: Convert VariableSectionEndDescription to cstr. +//PE: use uint8_t VariableType[MAXPROPERTIESVARIABLES] = { 0 }; + struct PropertiesVariables { - int VariableType[MAXPROPERTIESVARIABLES] = { 0 }; + uint8_t VariableType[MAXPROPERTIESVARIABLES] = { 0 }; char Variable[MAXPROPERTIESVARIABLES][MAXVARIABLESIZE] = { "\0" }; //This can be removed later only for debug. char VariableValue[MAXPROPERTIESVARIABLES][MAXVARIABLETEXTSIZE] = { "\0" }; - char VariableSectionDescription[MAXPROPERTIESVARIABLES][MAXVARIABLETEXTSIZELARGE] = { "\0" }; - char VariableSectionEndDescription[MAXPROPERTIESVARIABLES][MAXVARIABLETEXTSIZE] = { "\0" }; + //char VariableSectionDescription[MAXPROPERTIESVARIABLES][MAXVARIABLETEXTSIZELARGE] = { "\0" }; + cStr VariableSectionDescription[MAXPROPERTIESVARIABLES] = { "" }; + //char VariableSectionEndDescription[MAXPROPERTIESVARIABLES][MAXVARIABLETEXTSIZE] = { "\0" }; + cStr VariableSectionEndDescription[MAXPROPERTIESVARIABLES] = { "" }; float VariableValueFrom[MAXPROPERTIESVARIABLES] = { 0.0f }; float VariableValueTo[MAXPROPERTIESVARIABLES] = { 0.0f }; bool bDescriptionOnly[MAXPROPERTIESVARIABLES] = { false }; - char VariableScript[MAX_PATH]; + char VariableScript[MAXPATH]; cstr VariableDescription; int iVariables = 0; }; + +//PE: 11/30/24 - 58432 // Entity Element Custom Profile Data struct entityeleproftype { @@ -6696,6 +6712,7 @@ struct entityluadatastatestype //PE: We really need to save on entitytype memory used, if you have 10000+ objects you could look at using 1gb when also in test game. //PE: Have commented out not used variables, and really tried to limit cstr that preallocate STRMINSIZE. +//PE: 11/30/24 - 59400 // Entity Elements Data (entityelement array) struct entitytype { diff --git a/GameGuru Core/GameGuru/Include/gameguru.h b/GameGuru Core/GameGuru/Include/gameguru.h index 68d82fee..5e93e2ee 100644 --- a/GameGuru Core/GameGuru/Include/gameguru.h +++ b/GameGuru Core/GameGuru/Include/gameguru.h @@ -1160,6 +1160,7 @@ struct Sglobals float grav_f; int gunmax; int gvsync; + int iEditorVSync; int hudmax; int L_Calf; int L_Hand; @@ -1341,6 +1342,7 @@ struct Sglobals L_Calf = 0; hudmax = 0; gvsync = 0; + iEditorVSync = 0; gunmax = 0; grav_f = 0.0f; flashr = 0; diff --git a/GameGuru Core/GameGuru/Include/preprocessor-moreflags.h b/GameGuru Core/GameGuru/Include/preprocessor-moreflags.h index 11dd1123..c879c0d4 100644 --- a/GameGuru Core/GameGuru/Include/preprocessor-moreflags.h +++ b/GameGuru Core/GameGuru/Include/preprocessor-moreflags.h @@ -139,6 +139,8 @@ #define NEWPROJSYSWORKINPROGRESS #define DETECTANDUSENEWPARTICLEDECALS + #define WICKEDPARTICLESYSTEM + #else // Flags to compile the Classic version of GameGuru #define FPSEXCHANGE diff --git a/GameGuru Core/GameGuru/Source/Common.cpp b/GameGuru Core/GameGuru/Source/Common.cpp index 2b7d65ca..bb74ab89 100644 --- a/GameGuru Core/GameGuru/Source/Common.cpp +++ b/GameGuru Core/GameGuru/Source/Common.cpp @@ -1493,11 +1493,15 @@ void common_init_globals ( void ) #endif Dim ( t.decalelement,g.decalelementmax ); - Dim ( t.weaponslot,10 ); + Dim ( t.weaponslot,12 ); //PE: 11 to be used for interaction hands, t.weaponammo[slot+10] still works. Dim ( t.weaponammo,20 ); Dim ( t.weaponclipammo,20 ); - Dim ( t.weaponhud,10 ); - for ( t.ws = 1 ; t.ws <= 10 ; t.ws++ ) t.weaponslot[t.ws].pref=0 ; + Dim ( t.weaponhud,12 ); + for (t.ws = 1; t.ws <= 12; t.ws++) + { + t.weaponslot[t.ws].pref = 0; + t.weaponslot[t.ws].got = 0; + } // Gun Data g.noholster = 1; @@ -2186,6 +2190,7 @@ void FPSC_SetDefaults ( void ) g.gsetupdepth = 32; g.gfullscreen = 0; g.gvsync = 1; + g.iEditorVSync = 0; g.gvrmode = 0; g.gvrmodefordevelopers = 0; g.gvrmodeoriginal = 0; @@ -2612,6 +2617,9 @@ void FPSC_LoadSETUPINI (bool bUseMySystemFolder) // DOCDOC: vsync = Enables the refresh of the render to match the current adapter refresh rate. t.tryfield_s = "vsync"; if (t.field_s == t.tryfield_s) g.gvsync = t.value1; + // DOCDOC: vsync = Enables the refresh of the render to match the current adapter refresh rate. + t.tryfield_s = "editorvsync"; if (t.field_s == t.tryfield_s) g.iEditorVSync = t.value1; + // DOCDOC: fullscreen = Attempts to request a full-screen mode from the DirectX adapter. t.tryfield_s = "fullscreen"; if (t.field_s == t.tryfield_s) g.gfullscreen = t.value1; diff --git a/GameGuru Core/GameGuru/Source/G-Gun.cpp b/GameGuru Core/GameGuru/Source/G-Gun.cpp index 5cdd116b..4c545881 100644 --- a/GameGuru Core/GameGuru/Source/G-Gun.cpp +++ b/GameGuru Core/GameGuru/Source/G-Gun.cpp @@ -31,7 +31,7 @@ void gun_restart ( void ) g.weaponammoindex=0; g.autoloadgun=-1 ; t.gunid=0; t.triggerweapononeifexists=1; - for ( t.t = 1 ; t.t<= 9; t.t++ ) + for ( t.t = 1 ; t.t<= 11; t.t++ ) { t.weaponslot[t.t].pref=0; t.weaponslot[t.t].got=0; @@ -159,7 +159,7 @@ void gun_loadonlypresent ( void ) } // And now fill in player weapon details - for ( t.tww = 1 ; t.tww<= 9; t.tww++ ) + for ( t.tww = 1 ; t.tww<= 11; t.tww++ ) { t.gunid=t.weaponslot[t.tww].pref; if ( t.gunid>0 ) @@ -778,7 +778,7 @@ void gun_change ( void ) g.weaponammoindex=0; if ( t.gunid>0 ) { - for ( t.ws = 1 ; t.ws < 10; t.ws++ ) + for ( t.ws = 1 ; t.ws < 12; t.ws++ ) { if ( t.weaponslot[t.ws].got == t.gunid ) { diff --git a/GameGuru Core/GameGuru/Source/M-Debug.cpp b/GameGuru Core/GameGuru/Source/M-Debug.cpp index ea601d00..17e47c83 100644 --- a/GameGuru Core/GameGuru/Source/M-Debug.cpp +++ b/GameGuru Core/GameGuru/Source/M-Debug.cpp @@ -85,9 +85,11 @@ void timestampactivity ( int i, char* desc_s ) Sync(); } mem = DMEMAvailable(); + float GetVramUsage(void); + float vram = GetVramUsage(); videomemdesc_s = Str((mem - g.timestampactivityvideomemthen)); videomemdesc_s = videomemdesc_s + "MB"; g.timestampactivityvideomemthen = mem; - videomemsofardesc_s = " ("; videomemsofardesc_s = videomemsofardesc_s + Str(smem / 1024) + "," + Str(DMEMAvailable()) + ")"; + videomemsofardesc_s = " ("; videomemsofardesc_s = videomemsofardesc_s + Str(smem / 1024) + "," + Str((int)vram) + ")"; tpart1_s = Str(Timer()); tpart1_s = tpart1_s + " : " + desc_s + " "; tpart2_s = "S:"; tpart2_s = tpart2_s + memdesc_s; tpart3_s = "V:"; tpart3_s = tpart3_s + videomemsofardesc_s; diff --git a/GameGuru Core/GameGuru/Source/M-Entity.cpp b/GameGuru Core/GameGuru/Source/M-Entity.cpp index b40bfa39..64c2cea8 100644 --- a/GameGuru Core/GameGuru/Source/M-Entity.cpp +++ b/GameGuru Core/GameGuru/Source/M-Entity.cpp @@ -1162,6 +1162,14 @@ bool entity_load (bool bCalledFromLibrary) t.entityprofile[t.entid].fDecalSpeed = 1.0; // ? later bNewDecal = true; } + if (sEffectLower == "effectbank\\reloaded\\decal_animate20.fx") + { + t.entityprofile[t.entid].bIsDecal = true; + t.entityprofile[t.entid].iDecalRows = 20; + t.entityprofile[t.entid].iDecalColumns = 20; + t.entityprofile[t.entid].fDecalSpeed = 1.0; // ? later + bNewDecal = true; + } if (sEffectLower == "effectbank\\reloaded\\decal_animate10.fx" || sEffectLower == "effectbank\\reloaded\\decal_animate10x10.fx") { t.entityprofile[t.entid].bIsDecal = true; @@ -9249,6 +9257,8 @@ void entity_redo ( void ) entity_undo ( ); } #endif + +//#pragma optimize("", off) std::vector delete_decal_particles; void delete_notused_decal_particles( void ) { diff --git a/GameGuru Core/GameGuru/Source/M-GridEdit.cpp b/GameGuru Core/GameGuru/Source/M-GridEdit.cpp index 8746b44b..42427071 100644 --- a/GameGuru Core/GameGuru/Source/M-GridEdit.cpp +++ b/GameGuru Core/GameGuru/Source/M-GridEdit.cpp @@ -35,6 +35,7 @@ std::vector projectbank_imageid; StoryboardStruct Storyboard; StoryboardStruct StoryboardBackup; StoryboardStruct checkproject; +StoryboardStruct202 updateproject202; std::vector< std::pair> StoryboardFonts; bool bScreen_Editor_Window = false; int iScreen_Editor_Node = -1; @@ -1463,7 +1464,8 @@ void mapeditorexecutable_loop_leavetestgame(void) bUpdateVeg = true; // set vsync back on when we return to the editor so we don't 100% the GPU - wiEvent::SetVSync(false); // see if this improves performance in the level editor, was ( true ); + if (g.iEditorVSync == 0) + wiEvent::SetVSync(false); // see if this improves performance in the level editor, was ( true ); } #endif @@ -9500,11 +9502,12 @@ void mapeditorexecutable_loop(void) // drop down to make life easier char cTmpInput[MAX_PATH]; strcpy(cTmpInput, g_collectionQuestList[iCollectionItemIndex].collectionFields[l].Get()); - const char* items[] = { "Collect", "Destroy", "Deliver" }; + const char* items[] = { "Collect", "Destroy", "Deliver", "Activate" }; int item_current = 0; if (stricmp(cTmpInput, "collect") == NULL) item_current = 0; if (stricmp(cTmpInput, "destroy") == NULL) item_current = 1; if (stricmp(cTmpInput, "deliver") == NULL) item_current = 2; + if (stricmp(cTmpInput, "activate") == NULL) item_current = 3; ImGui::SetCursorPos(ImVec2(ImGui::GetCursorPosX(), ImGui::GetCursorPosY() + 3)); ImGui::Text("Quest Type"); ImGui::SameLine(); @@ -9516,6 +9519,7 @@ void mapeditorexecutable_loop(void) if (item_current == 0) g_collectionQuestList[iCollectionItemIndex].collectionFields[l] = "collect"; if (item_current == 1) g_collectionQuestList[iCollectionItemIndex].collectionFields[l] = "destroy"; if (item_current == 2) g_collectionQuestList[iCollectionItemIndex].collectionFields[l] = "deliver"; + if (item_current == 3) g_collectionQuestList[iCollectionItemIndex].collectionFields[l] = "activate"; } ImGui::PopItemWidth(); @@ -11744,11 +11748,13 @@ void mapeditorexecutable_loop(void) strcpy(pCaptureAnyScriptDesc, t.grideleprof.PropertiesVariable.VariableDescription.Get()); for (int i = 0; i < t.grideleprof.PropertiesVariable.iVariables; i++) { - strcat(pCaptureAnyScriptDesc, t.grideleprof.PropertiesVariable.VariableSectionDescription[i]); + //strcat(pCaptureAnyScriptDesc, t.grideleprof.PropertiesVariable.VariableSectionDescription[i]); + strcat(pCaptureAnyScriptDesc, t.grideleprof.PropertiesVariable.VariableSectionDescription[i].Get()); } for (int i = 0; i < t.grideleprof.PropertiesVariable.iVariables; i++) { - strcat(pCaptureAnyScriptDesc, t.grideleprof.PropertiesVariable.VariableSectionEndDescription[i]); + //strcat(pCaptureAnyScriptDesc, t.grideleprof.PropertiesVariable.VariableSectionEndDescription[i]); + strcat(pCaptureAnyScriptDesc, t.grideleprof.PropertiesVariable.VariableSectionEndDescription[i].Get()); } if (strstr(pCaptureAnyScriptDesc, "") != 0) bSound0Mentioned = true; if (strstr(pCaptureAnyScriptDesc, "") != 0) bSound1Mentioned = true; @@ -17474,6 +17480,13 @@ void editor_previewmapormultiplayer_afterloopcode ( int iUseVRTest ) void CleanUpSpawedObject(void); CleanUpSpawedObject(); + + #ifdef WICKEDPARTICLESYSTEM + //PE: Clear all wicked particle effects created by lua. + void CleanUpEmitterEffects(void); + CleanUpEmitterEffects(); + #endif + #ifdef WICKEDENGINE WickedCall_SetEditorCameraLight(true); #endif @@ -17617,7 +17630,8 @@ void editor_previewmapormultiplayer_afterloopcode ( int iUseVRTest ) { if ( ObjectExist(t.obj) == 1 ) { - if ( t.entityprofile[t.entid].ismarker == 0 ) + //PE: Also restore moved particles. + if ( t.entityprofile[t.entid].ismarker == 0 || t.entityprofile[t.entid].ismarker == 10 ) { // reset entity PositionObject ( t.obj,t.entityelement[t.e].x,t.entityelement[t.e].y,t.entityelement[t.e].z ); diff --git a/GameGuru Core/GameGuru/Source/M-GridEditB.cpp b/GameGuru Core/GameGuru/Source/M-GridEditB.cpp index 29470492..f167102b 100644 --- a/GameGuru Core/GameGuru/Source/M-GridEditB.cpp +++ b/GameGuru Core/GameGuru/Source/M-GridEditB.cpp @@ -75,7 +75,10 @@ extern std::vector projectbank_image; extern std::vector projectbank_imageid; extern StoryboardStruct Storyboard; extern StoryboardStruct checkproject; +extern StoryboardStruct202 updateproject202; StoryboardStruct tempProjectData; +//PE: StoryboardStruct is now so huge that you get a stackoverflow if added to a function, so moved here. +StoryboardStruct templateStoryboard; extern std::vector< std::pair> StoryboardFonts; extern bool bScreen_Editor_Window; extern int iScreen_Editor_Node; @@ -540,6 +543,7 @@ bool bSortProjects = true; bool bResetProjectThumbnails = true; int g_iCheckExistingFilesModifiedDelayed = 0; ImRect g_rStealMonitorArea; +bool bUpgradeAndBackupOldProject = false; std::vector lutImages_s; @@ -2557,19 +2561,32 @@ void setpropertyfile ( int group, char* data_s, char* field_s, char* desc_s, cha } #endif -int FillWeaponList(std::vector& labels) +int FillWeaponList(std::vector& labels, char *filter) { int listmax = fillgloballistwithweaponsQuick(true, true, true, false); int iWeaponListIndex = 0; - - labels.push_back("No Weapon"); + if (filter) + { + std::string label = "No " + std::string(filter); + labels.push_back(label.c_str()); + } + else + { + labels.push_back("No Weapon"); + } iWeaponListIndex++; for (int gunid = 1; gunid <= g.gunmax; gunid++) { cstr thisLabel = t.gun[gunid].name_s; - if (strlen(thisLabel.Get()) == 0) thisLabel = "No Weapon"; - labels.push_back(thisLabel.Get()); - iWeaponListIndex++; + bool bAdd = true; + if (filter && !pestrcasestr(thisLabel.Get(), filter)) + bAdd = false; + if (bAdd) + { + if (strlen(thisLabel.Get()) == 0) thisLabel = "No Weapon"; + labels.push_back(thisLabel.Get()); + iWeaponListIndex++; + } } return(iWeaponListIndex); @@ -6307,7 +6324,8 @@ void gridedit_setvsync(bool bLevelVSyncEnabled) extern bool bImGuiInTestGame; if (t.game.gameisexe == 0 && bImGuiInTestGame == false ) { - bLevelVSyncEnabled = false; + if(g.iEditorVSync == 0) + bLevelVSyncEnabled = false; } master.bVsyncEnabled = bLevelVSyncEnabled; wiEvent::SetVSync(master.bVsyncEnabled); @@ -19671,7 +19689,8 @@ void process_entity_library_v2(void) { if (strlen(pCaptureAnyScriptDesc) < 8192) { - strcat(pCaptureAnyScriptDesc, dluaload.PropertiesVariable.VariableSectionDescription[i]); + //strcat(pCaptureAnyScriptDesc, dluaload.PropertiesVariable.VariableSectionDescription[i]); + strcat(pCaptureAnyScriptDesc, dluaload.PropertiesVariable.VariableSectionDescription[i].Get()); if (dluaload.PropertiesVariable.Variable[i] && strlen(dluaload.PropertiesVariable.Variable[i]) > 0) { //Split into segments. @@ -19679,9 +19698,13 @@ void process_entity_library_v2(void) strcat(pCaptureAnyScriptDesc, dluaload.PropertiesVariable.Variable[i]); strcat(pCaptureAnyScriptDesc, "]"); } - if (dluaload.PropertiesVariable.VariableSectionEndDescription[i] && strlen(dluaload.PropertiesVariable.VariableSectionEndDescription[i]) > 0) + //if (dluaload.PropertiesVariable.VariableSectionEndDescription[i] && strlen(dluaload.PropertiesVariable.VariableSectionEndDescription[i]) > 0) + //{ + // strcat(pCaptureAnyScriptDesc, dluaload.PropertiesVariable.VariableSectionEndDescription[i]); + //} + if (dluaload.PropertiesVariable.VariableSectionEndDescription[i].Len() > 0) { - strcat(pCaptureAnyScriptDesc, dluaload.PropertiesVariable.VariableSectionEndDescription[i]); + strcat(pCaptureAnyScriptDesc, dluaload.PropertiesVariable.VariableSectionEndDescription[i].Get()); } } } @@ -19967,7 +19990,8 @@ void process_entity_library_v2(void) { if (strlen(pCaptureAnyScriptDesc) < 8192) { - strcat(pCaptureAnyScriptDesc, dluaload.PropertiesVariable.VariableSectionDescription[i]); + //strcat(pCaptureAnyScriptDesc, dluaload.PropertiesVariable.VariableSectionDescription[i]); + strcat(pCaptureAnyScriptDesc, dluaload.PropertiesVariable.VariableSectionDescription[i].Get()); if (dluaload.PropertiesVariable.Variable[i] && strlen(dluaload.PropertiesVariable.Variable[i]) > 0) { //Split into segments. @@ -19975,9 +19999,13 @@ void process_entity_library_v2(void) strcat(pCaptureAnyScriptDesc, dluaload.PropertiesVariable.Variable[i]); strcat(pCaptureAnyScriptDesc, "]"); } - if (dluaload.PropertiesVariable.VariableSectionEndDescription[i] && strlen(dluaload.PropertiesVariable.VariableSectionEndDescription[i]) > 0) + //if (dluaload.PropertiesVariable.VariableSectionEndDescription[i] && strlen(dluaload.PropertiesVariable.VariableSectionEndDescription[i]) > 0) + //{ + // strcat(pCaptureAnyScriptDesc, dluaload.PropertiesVariable.VariableSectionEndDescription[i]); + //} + if (dluaload.PropertiesVariable.VariableSectionEndDescription[i].Len() > 0) { - strcat(pCaptureAnyScriptDesc, dluaload.PropertiesVariable.VariableSectionEndDescription[i]); + strcat(pCaptureAnyScriptDesc, dluaload.PropertiesVariable.VariableSectionEndDescription[i].Get()); } } } @@ -28184,11 +28212,13 @@ void DisplayFPEBehavior(bool readonly, int entid, entityeleproftype* edit_gridel strcpy(pCaptureAnyScriptDesc, edit_grideleprof->PropertiesVariable.VariableDescription.Get()); for (int i = 0; i < edit_grideleprof->PropertiesVariable.iVariables; i++) { - strcat(pCaptureAnyScriptDesc, edit_grideleprof->PropertiesVariable.VariableSectionDescription[i]); + //strcat(pCaptureAnyScriptDesc, edit_grideleprof->PropertiesVariable.VariableSectionDescription[i]); + strcat(pCaptureAnyScriptDesc, edit_grideleprof->PropertiesVariable.VariableSectionDescription[i].Get()); } for (int i = 0; i < edit_grideleprof->PropertiesVariable.iVariables; i++) { - strcat(pCaptureAnyScriptDesc, edit_grideleprof->PropertiesVariable.VariableSectionEndDescription[i]); + //strcat(pCaptureAnyScriptDesc, edit_grideleprof->PropertiesVariable.VariableSectionEndDescription[i]); + strcat(pCaptureAnyScriptDesc, edit_grideleprof->PropertiesVariable.VariableSectionEndDescription[i].Get()); } if (strstr(pCaptureAnyScriptDesc, "") != 0) bSound0Mentioned = true; if (strstr(pCaptureAnyScriptDesc, "") != 0) bSound1Mentioned = true; @@ -32328,11 +32358,16 @@ void GetFilesListForLibrary(char *path, bool bCreateThumbs, int win, int iThumbW vTmp.cProject = project; // quick check to see if the folder exists - char pProjFolderFile[MAX_PATH]; - strcpy(pProjFolderFile, "projectbank\\"); - strcat(pProjFolderFile, vTmp.cProject.Get()); - strcat(pProjFolderFile, "\\project.dat"); + char pProjFolderFile[MAX_PATH]; + sprintf(pProjFolderFile, "projectbank\\%s\\project%d.dat", vTmp.cProject.Get(), STORYBOARDVERSION); GG_GetRealPath(pProjFolderFile, false); + if (FileExist(pProjFolderFile) == 0) + { + strcpy(pProjFolderFile, "projectbank\\"); + strcat(pProjFolderFile, vTmp.cProject.Get()); + strcat(pProjFolderFile, "\\project.dat"); + GG_GetRealPath(pProjFolderFile, false); + } if(FileExist(pProjFolderFile)==1) vTmp.bProjectExists = true; else @@ -33259,16 +33294,26 @@ void GetProjectSortData (std::vector& output) if (folder != "." && folder != "..") { char project[MAX_PATH]; - strcpy(project, destination); - strcat(project, folder.Get()); - strcat(project, "\\project.dat"); - + sprintf(project, "%s%s\\project%d.dat", destination,folder.Get(), STORYBOARDVERSION); ProjectSortData data; data.folderName = std::string(folder.Get()); wchar_t filePath[MAX_PATH]; MultiByteToWideChar(CP_UTF8, 0, &project[0], -1, filePath, MAX_PATH); HANDLE hFile = CreateFile(filePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + strcpy(project, destination); + strcat(project, folder.Get()); + strcat(project, "\\project.dat"); + + ProjectSortData data; + data.folderName = std::string(folder.Get()); + wchar_t filePath[MAX_PATH]; + MultiByteToWideChar(CP_UTF8, 0, &project[0], -1, filePath, MAX_PATH); + hFile = CreateFile(filePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + } + if (hFile == INVALID_HANDLE_VALUE) { strcpy(project, destination); @@ -33281,13 +33326,20 @@ void GetProjectSortData (std::vector& output) strcpy(pAbsTrueProjectPath, ReadString(1)); CloseFile(1); GG_GetRealPath(pAbsTrueProjectPath, 0); - strcpy(project, pAbsTrueProjectPath); - strcat(project, folder.Get()); - strcat(project, "\\Files\\projectbank\\"); - strcat(project, folder.Get()); - strcat(project, "\\project.dat"); + + sprintf(project, "%s%s\\Files\\projectbank\\%s\\project%d.dat", pAbsTrueProjectPath,folder.Get(), folder.Get(), STORYBOARDVERSION); MultiByteToWideChar(CP_UTF8, 0, &project[0], -1, filePath, MAX_PATH); hFile = CreateFile(filePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (hFile == INVALID_HANDLE_VALUE) + { + strcpy(project, pAbsTrueProjectPath); + strcat(project, folder.Get()); + strcat(project, "\\Files\\projectbank\\"); + strcat(project, folder.Get()); + strcat(project, "\\project.dat"); + MultiByteToWideChar(CP_UTF8, 0, &project[0], -1, filePath, MAX_PATH); + hFile = CreateFile(filePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + } } } if (hFile != INVALID_HANDLE_VALUE) @@ -33403,12 +33455,29 @@ void GetProjectThumbnails() strcpy(project, "projectbank\\"); } strcat(project, projectbank_list[i].c_str()); - strcat(project, "\\project.dat"); + + char project2[MAX_PATH]; + strcpy(project2, project); + + sprintf(project, "%s\\project%d.dat", project2, STORYBOARDVERSION); projectfile = GG_fopen(project, "rb"); + if (!projectfile) + { + strcpy(project, project2); + strcat(project, "\\project.dat"); + projectfile = GG_fopen(project, "rb"); + } + if (projectfile) { + fclose(projectfile); + + //PE: Use this so we can upgrade from 202 to 203+ + bool load__storyboard_into_struct(const char*, StoryboardStruct&); + load__storyboard_into_struct(project, checkproject); + //PE: Need full load now, as we can have Game Settings. - size_t size = fread(&checkproject, 1, sizeof(checkproject), projectfile); + //size_t size = fread(&checkproject, 1, sizeof(checkproject), projectfile); char sig[12] = "Storyboard\0"; if (checkproject.sig[0] == 'S' && checkproject.sig[8] == 'r') @@ -33478,7 +33547,6 @@ void GetProjectThumbnails() { projectbank_image.push_back(""); //Just use CLICK HERE. } - fclose(projectfile); } else { @@ -36111,17 +36179,29 @@ void Welcome_Screen(void) strcpy(projectname, sCurrentGame.Get()); projectname[strlen(projectname) - 4] = 0; char project[MAX_PATH]; - strcpy(project, "projectbank\\"); - strcat(project, projectname); - strcat(project, "\\project.dat"); - + + sprintf(project, "projectbank\\%s\\project%d.dat", projectname, STORYBOARDVERSION); FILE* projectfile = GG_fopen(project, "rb"); + if (!projectfile) + { + strcpy(project, "projectbank\\"); + strcat(project, projectname); + strcat(project, "\\project.dat"); + projectfile = GG_fopen(project, "rb"); + } if (projectfile) { - tempProjectData.game_developer_desc[0] = 0; - size_t size = fread(&tempProjectData, 1, sizeof(tempProjectData), projectfile); - //Valid pref: fclose(projectfile); + + //PE: Use this so we can upgrade from 202 to 203+ + bool load__storyboard_into_struct(const char*, StoryboardStruct&); + load__storyboard_into_struct(project, tempProjectData); + + + //tempProjectData.game_developer_desc[0] = 0; + //size_t size = fread(&tempProjectData, 1, sizeof(tempProjectData), projectfile); + //Valid pref: + if(strlen(tempProjectData.game_developer_desc) > 0) sDevDescription = tempProjectData.game_developer_desc; @@ -37600,22 +37680,26 @@ void reset_single_node(int node) void storeboard_fix_uniqueids( void ) { int iUniqueId = STORYBOARD_THUMBS; + int iUniqueIdsAdd = 1000; for (int i = 0; i < STORYBOARD_MAXNODES; i++) { + if (i == 100 || i == 200) + iUniqueIdsAdd += 100000; + int node = i; for (int l = 0; l < STORYBOARD_MAXOUTPUTS; l++) { //PE: input_id,output_id ID's broken in checkproject. - if (Storyboard.Nodes[node].input_id[l] != iUniqueId + 1000 + (1000 * l) || - Storyboard.Nodes[node].output_id[l] != iUniqueId + 1000 + (1000 * l) + 500) + if (Storyboard.Nodes[node].input_id[l] != iUniqueId + iUniqueIdsAdd + (1000 * l) || + Storyboard.Nodes[node].output_id[l] != iUniqueId + iUniqueIdsAdd + (1000 * l) + 500) { //PE: Something wrong reset. bool bInputChanged = false; - if (Storyboard.Nodes[node].input_id[l] != iUniqueId + 1000 + (1000 * l)) bInputChanged = true; + if (Storyboard.Nodes[node].input_id[l] != iUniqueId + iUniqueIdsAdd + (1000 * l)) bInputChanged = true; int oldinput = Storyboard.Nodes[node].input_id[l]; - Storyboard.Nodes[node].input_id[l] = iUniqueId + 1000 + (1000 * l); - Storyboard.Nodes[node].output_id[l] = iUniqueId + 1000 + (1000 * l) + 500; + Storyboard.Nodes[node].input_id[l] = iUniqueId + iUniqueIdsAdd + (1000 * l); + Storyboard.Nodes[node].output_id[l] = iUniqueId + iUniqueIdsAdd + (1000 * l) + 500; if (bInputChanged) { @@ -37670,8 +37754,21 @@ void storeboard_init_nodes(float area_width, float node_width, float node_height strcpy(Storyboard.game_developer_desc, ""); Storyboard.project_readonly = 0; + //PE: STORYBOARD_MAXNODES = 150. Largest unique id = 199749 , lowest = 49000. + //PE: checkunique = { size=28500 } + //PE: STORYBOARD_MAXNODES = 150. STORYBOARD_MAXOUTPUTS = 30. STORYBOARD_MAXWIDGETS = 100. Largest unique id = 249949 , lowest = 49000. + //PE: checkunique = { size=54000 } + //#define TESTUNIQUEIDS + + #ifdef TESTUNIQUEIDS + std::vector checkunique; + #endif + + int iUniqueIdsAdd = 1000; for (int i = 0; i < STORYBOARD_MAXNODES; i++) { + if (i == 100 || i == 200) + iUniqueIdsAdd += 100000; reset_single_node(i); StoryboardiActiveLinksId[i] = 0; @@ -37683,15 +37780,35 @@ void storeboard_init_nodes(float area_width, float node_width, float node_height for (int l = 0; l < STORYBOARD_MAXOUTPUTS; l++) { - Storyboard.Nodes[i].input_id[l] = iUniqueIds + 1000 + (1000 * l); - Storyboard.Nodes[i].output_id[l] = iUniqueIds + 1000 + (1000 * l) + 500; + Storyboard.Nodes[i].input_id[l] = iUniqueIds + iUniqueIdsAdd + (1000 * l); + Storyboard.Nodes[i].output_id[l] = iUniqueIds + iUniqueIdsAdd + (1000 * l) + 500; + #ifdef TESTUNIQUEIDS + if (std::find(checkunique.begin(), checkunique.end(), Storyboard.Nodes[i].input_id[l]) != checkunique.end()) + printf("tmp"); + checkunique.push_back(Storyboard.Nodes[i].input_id[l]); + if (std::find(checkunique.begin(), checkunique.end(), Storyboard.Nodes[i].output_id[l]) != checkunique.end()) + printf("tmp"); + checkunique.push_back(Storyboard.Nodes[i].output_id[l]); + #endif } for (int l = 0; l < STORYBOARD_MAXWIDGETS; l++) { - Storyboard.Nodes[i].widget_normal_thumb_id[l] = iUniqueIds + 1000 + (1000 * l) + 600; - Storyboard.Nodes[i].widget_highlight_thumb_id[l] = iUniqueIds + 1000 + (1000 * l) + 700; - Storyboard.Nodes[i].widget_selected_thumb_id[l] = iUniqueIds + 1000 + (1000 * l) + 800; + Storyboard.Nodes[i].widget_normal_thumb_id[l] = iUniqueIds + iUniqueIdsAdd + (1000 * l) + 600; + Storyboard.Nodes[i].widget_highlight_thumb_id[l] = iUniqueIds + iUniqueIdsAdd + (1000 * l) + 700; + Storyboard.Nodes[i].widget_selected_thumb_id[l] = iUniqueIds + iUniqueIdsAdd + (1000 * l) + 800; + + #ifdef TESTUNIQUEIDS + if (std::find(checkunique.begin(), checkunique.end(), Storyboard.Nodes[i].widget_normal_thumb_id[l]) != checkunique.end()) + printf("tmp"); + checkunique.push_back(Storyboard.Nodes[i].widget_normal_thumb_id[l]); + if (std::find(checkunique.begin(), checkunique.end(), Storyboard.Nodes[i].widget_highlight_thumb_id[l]) != checkunique.end()) + printf("tmp"); + checkunique.push_back(Storyboard.Nodes[i].widget_highlight_thumb_id[l]); + if (std::find(checkunique.begin(), checkunique.end(), Storyboard.Nodes[i].widget_selected_thumb_id[l]) != checkunique.end()) + printf("tmp"); + checkunique.push_back(Storyboard.Nodes[i].widget_selected_thumb_id[l]); + #endif } Storyboard.Nodes[i].screen_backdrop_id = iUniqueIds + 500; @@ -39169,9 +39286,8 @@ int storyboard_add_missing_nodex(int node,float area_width, float node_width, fl // Storyboard does not yet have a HUD screen, so add one (copy from default template HUD in below filepath) // In future, any screen default states should be saved into this file - StoryboardStruct templateStoryboard; const char* filepath = "editors\\templates\\ScreenEditor\\project.dat"; - extern bool load__storyboard_into_struct(const char*, StoryboardStruct&); + bool load__storyboard_into_struct(const char*, StoryboardStruct&); if (load__storyboard_into_struct(filepath, templateStoryboard)) { StoryboardNodesStruct& thisNode = Storyboard.Nodes[node]; @@ -41481,7 +41597,7 @@ void process_storeboard(bool bInitOnly) ImVec2 vNodeAreaStart = ImGui::GetCursorScreenPos(); - int iUniqueIds = STORYBOARD_THUMBS; + //int iUniqueIds = STORYBOARD_THUMBS; //PE: Make sure if we focus another window and go back , mouse dragging is reset. extern bool g_bAppActiveStat; @@ -42548,8 +42664,13 @@ void process_storeboard(bool bInitOnly) sprintf_s(cScreenCount, "%d", iScreenCount); // Find first free storyboard node that we can use for the new screen. int node = -1; + + int iUniqueIdsAdd = 1000; for (int i = 0; i < STORYBOARD_MAXNODES; i++) { + if (i == 100 || i == 200) + iUniqueIdsAdd += 100000; + if (Storyboard.Nodes[i].used == 0) { // Reset node to default state, in case any old data remains. @@ -42563,14 +42684,14 @@ void process_storeboard(bool bInitOnly) for (int l = 0; l < STORYBOARD_MAXWIDGETS; l++) { //PE: input_id,output_id ID's broken in checkproject. - Storyboard.Nodes[node].widget_normal_thumb_id[l] = iUniqueId + 1000 + (1000 * l) + 600; - Storyboard.Nodes[node].widget_highlight_thumb_id[l] = iUniqueId + 1000 + (1000 * l) + 700; - Storyboard.Nodes[node].widget_selected_thumb_id[l] = iUniqueId + 1000 + (1000 * l) + 800; + Storyboard.Nodes[node].widget_normal_thumb_id[l] = iUniqueId + iUniqueIdsAdd + (1000 * l) + 600; + Storyboard.Nodes[node].widget_highlight_thumb_id[l] = iUniqueId + iUniqueIdsAdd + (1000 * l) + 700; + Storyboard.Nodes[node].widget_selected_thumb_id[l] = iUniqueId + iUniqueIdsAdd + (1000 * l) + 800; } for (int l = 0; l < STORYBOARD_MAXOUTPUTS; l++) { - Storyboard.Nodes[node].input_id[l] = iUniqueId + 1000 + (1000 * l); - Storyboard.Nodes[node].output_id[l] = iUniqueId + 1000 + (1000 * l) + 500; + Storyboard.Nodes[node].input_id[l] = iUniqueId + iUniqueIdsAdd + (1000 * l); + Storyboard.Nodes[node].output_id[l] = iUniqueId + iUniqueIdsAdd + (1000 * l) + 500; } Storyboard.Nodes[node].screen_backdrop_id = iUniqueId + 500; @@ -42647,8 +42768,12 @@ void process_storeboard(bool bInitOnly) sprintf_s(cLoadingScreenCount, "%d", iLoadingScreenCount); // Find first free storyboard node that we can use for the new screen. int node = -1; + + int iUniqueIdsAdd = 1000; for (int i = 0; i < STORYBOARD_MAXNODES; i++) { + if (i == 100 || i == 200) + iUniqueIdsAdd += 100000; if (Storyboard.Nodes[i].used == 0) { // Reset node to default state, in case any old data remains. @@ -42662,14 +42787,14 @@ void process_storeboard(bool bInitOnly) for (int l = 0; l < STORYBOARD_MAXWIDGETS; l++) { //PE: input_id,output_id ID's broken in checkproject. - Storyboard.Nodes[node].widget_normal_thumb_id[l] = iUniqueId + 1000 + (1000 * l) + 600; - Storyboard.Nodes[node].widget_highlight_thumb_id[l] = iUniqueId + 1000 + (1000 * l) + 700; - Storyboard.Nodes[node].widget_selected_thumb_id[l] = iUniqueId + 1000 + (1000 * l) + 800; + Storyboard.Nodes[node].widget_normal_thumb_id[l] = iUniqueId + iUniqueIdsAdd + (1000 * l) + 600; + Storyboard.Nodes[node].widget_highlight_thumb_id[l] = iUniqueId + iUniqueIdsAdd + (1000 * l) + 700; + Storyboard.Nodes[node].widget_selected_thumb_id[l] = iUniqueId + iUniqueIdsAdd + (1000 * l) + 800; } for (int l = 0; l < STORYBOARD_MAXOUTPUTS; l++) { - Storyboard.Nodes[node].input_id[l] = iUniqueId + 1000 + (1000 * l); - Storyboard.Nodes[node].output_id[l] = iUniqueId + 1000 + (1000 * l) + 500; + Storyboard.Nodes[node].input_id[l] = iUniqueId + iUniqueIdsAdd + (1000 * l); + Storyboard.Nodes[node].output_id[l] = iUniqueId + iUniqueIdsAdd + (1000 * l) + 500; } Storyboard.Nodes[node].screen_backdrop_id = iUniqueId + 500; @@ -42793,8 +42918,12 @@ void process_storeboard(bool bInitOnly) sprintf_s(cHudCount, "%d", hudScreenCount); // Find first free storyboard node that we can use for the new screen. int node = -1; + int iUniqueIdsAdd = 1000; for (int i = 0; i < STORYBOARD_MAXNODES; i++) { + if (i == 100 || i == 200) + iUniqueIdsAdd += 100000; + if (Storyboard.Nodes[i].used == 0) { // Reset node to default state, in case any old data remains. @@ -42808,14 +42937,14 @@ void process_storeboard(bool bInitOnly) for (int l = 0; l < STORYBOARD_MAXWIDGETS; l++) { //PE: input_id,output_id ID's broken in checkproject. - Storyboard.Nodes[node].widget_normal_thumb_id[l] = iUniqueId + 1000 + (1000 * l) + 600; - Storyboard.Nodes[node].widget_highlight_thumb_id[l] = iUniqueId + 1000 + (1000 * l) + 700; - Storyboard.Nodes[node].widget_selected_thumb_id[l] = iUniqueId + 1000 + (1000 * l) + 800; + Storyboard.Nodes[node].widget_normal_thumb_id[l] = iUniqueId + iUniqueIdsAdd + (1000 * l) + 600; + Storyboard.Nodes[node].widget_highlight_thumb_id[l] = iUniqueId + iUniqueIdsAdd + (1000 * l) + 700; + Storyboard.Nodes[node].widget_selected_thumb_id[l] = iUniqueId + iUniqueIdsAdd + (1000 * l) + 800; } for (int l = 0; l < STORYBOARD_MAXOUTPUTS; l++) { - Storyboard.Nodes[node].input_id[l] = iUniqueId + 1000 + (1000 * l); - Storyboard.Nodes[node].output_id[l] = iUniqueId + 1000 + (1000 * l) + 500; + Storyboard.Nodes[node].input_id[l] = iUniqueId + iUniqueIdsAdd + (1000 * l); + Storyboard.Nodes[node].output_id[l] = iUniqueId + iUniqueIdsAdd + (1000 * l) + 500; } Storyboard.Nodes[node].screen_backdrop_id = iUniqueId + 500; @@ -43642,13 +43771,27 @@ void process_storeboard(bool bInitOnly) { // load in template screens from "RPG Template" project char project[MAX_PATH]; - strcpy(project, "projectbank\\RPG Template\\project.dat"); + + sprintf(project, "projectbank\\RPG Template\\project%d.dat", STORYBOARDVERSION); FILE* projectfile = GG_fopen(project, "rb"); + if (!projectfile) + { + strcpy(project, "projectbank\\RPG Template\\project.dat"); + projectfile = GG_fopen(project, "rb"); + } if (projectfile) { - StoryboardStruct* checkproject = new StoryboardStruct; - memset(checkproject, 0, sizeof(StoryboardStruct)); - size_t size = fread(checkproject, 1, sizeof(StoryboardStruct), projectfile); + StoryboardStruct* checkproject = nullptr; + memset(&tempProjectData, 0, sizeof(StoryboardStruct)); + fclose(projectfile); + + //PE: Use this so we can upgrade from 202 to 203+ + bool load__storyboard_into_struct(const char*, StoryboardStruct&); + load__storyboard_into_struct(project, tempProjectData); + checkproject = &tempProjectData; + + + //size_t size = fread(checkproject, 1, sizeof(StoryboardStruct), projectfile); char sig[12] = "Storyboard\0"; if (checkproject->sig[0] == 'S' && checkproject->sig[8] == 'r') { @@ -43727,19 +43870,25 @@ void process_storeboard(bool bInitOnly) //PE: unique ids are wrong in checkproject so assign new here. int iUniqueId = STORYBOARD_THUMBS + newnodeid; + int iUniqueIdsAdd = 1000; + if (newnodeid >= 200) + iUniqueIdsAdd = 200000; + else if (newnodeid >= 100) + iUniqueIdsAdd = 100000; + Storyboard.Nodes[newnodeid].id = iUniqueId; Storyboard.Nodes[newnodeid].thumb_id = iUniqueId; for (int l = 0; l < STORYBOARD_MAXWIDGETS; l++) { //PE: input_id,output_id ID's broken in checkproject. - Storyboard.Nodes[newnodeid].widget_normal_thumb_id[l] = iUniqueId + 1000 + (1000 * l) + 600; - Storyboard.Nodes[newnodeid].widget_highlight_thumb_id[l] = iUniqueId + 1000 + (1000 * l) + 700; - Storyboard.Nodes[newnodeid].widget_selected_thumb_id[l] = iUniqueId + 1000 + (1000 * l) + 800; + Storyboard.Nodes[newnodeid].widget_normal_thumb_id[l] = iUniqueId + iUniqueIdsAdd + (1000 * l) + 600; + Storyboard.Nodes[newnodeid].widget_highlight_thumb_id[l] = iUniqueId + iUniqueIdsAdd + (1000 * l) + 700; + Storyboard.Nodes[newnodeid].widget_selected_thumb_id[l] = iUniqueId + iUniqueIdsAdd + (1000 * l) + 800; } for (int l = 0; l < STORYBOARD_MAXOUTPUTS; l++) { - Storyboard.Nodes[newnodeid].input_id[l] = iUniqueId + 1000 + (1000 * l); - Storyboard.Nodes[newnodeid].output_id[l] = iUniqueId + 1000 + (1000 * l) + 500; + Storyboard.Nodes[newnodeid].input_id[l] = iUniqueId + iUniqueIdsAdd + (1000 * l); + Storyboard.Nodes[newnodeid].output_id[l] = iUniqueId + iUniqueIdsAdd + (1000 * l) + 500; } Storyboard.Nodes[newnodeid].screen_backdrop_id = iUniqueId + 500; @@ -43761,13 +43910,12 @@ void process_storeboard(bool bInitOnly) } } } - fclose(projectfile); - } - if (checkproject) - { - delete checkproject; - checkproject = NULL; } + //if (checkproject) + //{ + // delete checkproject; + // checkproject = NULL; + //} } } } @@ -46028,9 +46176,16 @@ void save_storyboard(char *name,bool bSaveAs) cLastProjectList = ""; //PE: Update project files. char project[MAX_PATH]; - strcpy(project, "projectbank\\"); - strcat(project, savename.Get()); - strcat(project, "\\project.dat"); + if (STORYBOARDVERSION > 202) + { + sprintf(project, "projectbank\\%s\\project%d.dat", savename.Get(), STORYBOARDVERSION); + } + else + { + strcpy(project, "projectbank\\"); + strcat(project, savename.Get()); + strcat(project, "\\project.dat"); + } FILE* projectfile = GG_fopen(project, "wb+"); if (projectfile) { @@ -46104,10 +46259,16 @@ void load_storyboard(char *name) bool bProjectLoaded = false; char project[MAX_PATH]; - strcpy(project, "projectbank\\"); - strcat(project, name); - strcat(project, "\\project.dat"); + + sprintf(project, "projectbank\\%s\\project%d.dat", name, STORYBOARDVERSION); FILE* projectfile = GG_fopen(project, "rb"); + if (projectfile == NULL) + { + strcpy(project, "projectbank\\"); + strcat(project, name); + strcat(project, "\\project.dat"); + projectfile = GG_fopen(project, "rb"); + } if (projectfile==NULL) { // switch to remote project @@ -46125,12 +46286,17 @@ void load_storyboard(char *name) strcpy(Storyboard.customprojectfolder, pRemoteProject); switch_to_remote_project(name); - // proceed as normal, loading now from the remote folder - strcpy(project, "projectbank\\"); - strcat(project, name); - strcat(project, "\\project.dat"); + sprintf(project, "projectbank\\%s\\project%d.dat", name, STORYBOARDVERSION); projectfile = GG_fopen(project, "rb"); + if (projectfile == NULL) + { + // proceed as normal, loading now from the remote folder + strcpy(project, "projectbank\\"); + strcat(project, name); + strcat(project, "\\project.dat"); + projectfile = GG_fopen(project, "rb"); + } // remote project has own media, so update the library to include them! extern int g_iRefreshLibraryFoldersAfterDelay; g_iRefreshLibraryFoldersAfterDelay = 10; @@ -46138,10 +46304,21 @@ void load_storyboard(char *name) } if (projectfile) { + fclose(projectfile); + + //PE: Use this so we can upgrade from 202 to 203+ + //PE: Must make a backup and save out project203.dat directly. when converting from here. + bUpgradeAndBackupOldProject = true; + + bool load__storyboard_into_struct(const char*, StoryboardStruct&); + load__storyboard_into_struct(project, checkproject); + + bUpgradeAndBackupOldProject = false; + //this sets ALL fields data to zero, and only filled with known structure (members added at end not part of the copy to remain zeros) - memset(&checkproject, 0, sizeof(StoryboardStruct)); + //memset(&checkproject, 0, sizeof(StoryboardStruct)); + //size_t size = fread(&checkproject, 1, sizeof(checkproject), projectfile); - size_t size = fread(&checkproject, 1, sizeof(checkproject), projectfile); char sig[12] = "Storyboard\0"; if (checkproject.sig[0] == 'S' && checkproject.sig[8] == 'r') { @@ -46163,7 +46340,6 @@ void load_storyboard(char *name) bStoryboardFirstRunSetInitPos = false; //Load new thumbs, and reposition new nodes. Storyboard.iChanged = false; strcpy(pref.cLastUsedStoryboardProject, name); - fclose(projectfile); //PE: Check if this is a readonly project. char fullPath[MAX_PATH]; @@ -46208,15 +46384,19 @@ void load_storyboard(char *name) // Reset all node and image IDs to default - they don't need their state retained by saving, and under some circumstances when loading them, they can be duplicated, causing problems with selecting nodes and images. int iUniqueIds = STORYBOARD_THUMBS; + int iUniqueIdsAdd = 1000; for (int i = 0; i < STORYBOARD_MAXNODES; i++) { + if (i == 100 || i == 200) + iUniqueIdsAdd += 100000; + Storyboard.Nodes[i].id = iUniqueIds; Storyboard.Nodes[i].thumb_id = iUniqueIds; for (int l = 0; l < STORYBOARD_MAXWIDGETS; l++) { - Storyboard.Nodes[i].widget_normal_thumb_id[l] = iUniqueIds + 1000 + (1000 * l) + 600; - Storyboard.Nodes[i].widget_highlight_thumb_id[l] = iUniqueIds + 1000 + (1000 * l) + 700; - Storyboard.Nodes[i].widget_selected_thumb_id[l] = iUniqueIds + 1000 + (1000 * l) + 800; + Storyboard.Nodes[i].widget_normal_thumb_id[l] = iUniqueIds + iUniqueIdsAdd + (1000 * l) + 600; + Storyboard.Nodes[i].widget_highlight_thumb_id[l] = iUniqueIds + iUniqueIdsAdd + (1000 * l) + 700; + Storyboard.Nodes[i].widget_selected_thumb_id[l] = iUniqueIds + iUniqueIdsAdd + (1000 * l) + 800; } Storyboard.Nodes[i].screen_backdrop_id = iUniqueIds + 500; @@ -46266,12 +46446,17 @@ bool load_checkproject_storyboard(char *name) if (strlen(name) <= 0) return false; char project[MAX_PATH]; - strcpy(project, "projectbank\\"); - strcat(project, name); - strcat(project, "\\project.dat"); + sprintf(project, "projectbank\\%s\\project%d.dat", name, STORYBOARDVERSION); + FILE* projectfile = GG_fopen(project, "rb"); + if (!projectfile) + { + strcpy(project, "projectbank\\"); + strcat(project, name); + strcat(project, "\\project.dat"); + projectfile = GG_fopen(project, "rb"); + } bool bReadProjectDetails = false; - FILE* projectfile = GG_fopen(project, "rb"); if (projectfile) { bReadProjectDetails = true; @@ -46292,7 +46477,18 @@ bool load_checkproject_storyboard(char *name) strcat(project, "\\project.dat"); CloseFile(1); } - projectfile = GG_fopen(project, "rb"); + + char newversion[MAX_PATH]; + sprintf(newversion, "project%d.dat", STORYBOARDVERSION); + + std::string newname = project; + replaceAll(newname, "project.dat", newversion); + projectfile = GG_fopen(newname.c_str(), "rb"); + if (!projectfile) + projectfile = GG_fopen(project, "rb"); + else + strcpy(project, newname.c_str()); + if (projectfile) { bReadProjectDetails = true; @@ -46300,10 +46496,17 @@ bool load_checkproject_storyboard(char *name) } if (bReadProjectDetails==true) { - memset(&checkproject, 0, sizeof(StoryboardStruct)); - size_t size = fread(&checkproject, 1, sizeof(checkproject), projectfile); - //Valid pref: fclose(projectfile); + + //PE: Use this so we can upgrade from 202 to 203+ + bool load__storyboard_into_struct(const char*, StoryboardStruct&); + load__storyboard_into_struct(project, checkproject); + + //memset(&checkproject, 0, sizeof(StoryboardStruct)); + //size_t size = fread(&checkproject, 1, sizeof(checkproject), projectfile); + //Valid pref: + //fclose(projectfile); + char sig[12] = "Storyboard\0"; if (checkproject.sig[0] == 'S' && checkproject.sig[8] == 'r') { @@ -46318,8 +46521,16 @@ bool load__storyboard_into_struct(const char *filepath, StoryboardStruct& storyb { if (!filepath) return false; if (strlen(filepath) <= 0) return false; - - FILE* projectfile = GG_fopen(filepath, "rb"); + + char project[MAX_PATH]; + sprintf(project, "project%d.dat", STORYBOARDVERSION); + std::string newname = filepath; + replaceAll(newname, "project.dat", project); + FILE* projectfile = GG_fopen(newname.c_str(), "rb"); + if (!projectfile) + { + projectfile = GG_fopen(filepath, "rb"); + } if (projectfile) { memset(&storyboard, 0, sizeof(StoryboardStruct)); @@ -46327,8 +46538,169 @@ bool load__storyboard_into_struct(const char *filepath, StoryboardStruct& storyb //Valid pref: fclose(projectfile); char sig[12] = "Storyboard\0"; - if (checkproject.sig[0] == 'S' && checkproject.sig[8] == 'r') + if (storyboard.sig[0] == 'S' && storyboard.sig[8] == 'r') { + //PE: Need convert 202 -> 202+ + if (storyboard.iStoryboardVersion != STORYBOARDVERSION) + { + if (storyboard.iStoryboardVersion <= 202) + { + memset(&updateproject202, 0, sizeof(StoryboardStruct202)); + + FILE* projectfile = GG_fopen(filepath, "rb"); + if (projectfile) + { + memset(&storyboard, 0, sizeof(StoryboardStruct)); + size_t size = fread(&updateproject202, 1, sizeof(updateproject202), projectfile); + fclose(projectfile); + + //PE: Copy data. + strcpy(storyboard.sig, updateproject202.sig); + strcpy(storyboard.gamename, updateproject202.gamename); + storyboard.iStoryboardVersion = STORYBOARDVERSION; //PE: New version. + storyboard.iChanged = updateproject202.iChanged; + storyboard.vEditorPanning = updateproject202.vEditorPanning; + for (int i = 0; i < STORYBOARD_MAXNODES202; i++) + { + //PE: Copy old nodes. + + { + storyboard.Nodes[i].type = updateproject202.Nodes[i].type; + storyboard.Nodes[i].id = updateproject202.Nodes[i].id; + storyboard.Nodes[i].restore_position = updateproject202.Nodes[i].restore_position; + storyboard.Nodes[i].iEditEnable = updateproject202.Nodes[i].iEditEnable; + storyboard.Nodes[i].used = updateproject202.Nodes[i].used; + storyboard.Nodes[i].thumb_id = updateproject202.Nodes[i].thumb_id; + + strcpy(storyboard.Nodes[i].title, updateproject202.Nodes[i].title); + strcpy(storyboard.Nodes[i].levelnumber, updateproject202.Nodes[i].levelnumber); + strcpy(storyboard.Nodes[i].thumb, updateproject202.Nodes[i].thumb); + strcpy(storyboard.Nodes[i].level_name, updateproject202.Nodes[i].level_name); + strcpy(storyboard.Nodes[i].lua_name, updateproject202.Nodes[i].lua_name); + strcpy(storyboard.Nodes[i].scene_name, updateproject202.Nodes[i].scene_name); + + for (int b = 0; b < STORYBOARD_MAXOUTPUTS202; b++) + { + storyboard.Nodes[i].input_id[b] = updateproject202.Nodes[i].input_id[b]; + storyboard.Nodes[i].output_id[b] = updateproject202.Nodes[i].output_id[b]; + storyboard.Nodes[i].output_linkto[b] = updateproject202.Nodes[i].output_linkto[b]; + storyboard.Nodes[i].output_can_link_to_type[b] = updateproject202.Nodes[i].output_can_link_to_type[b]; + strcpy(storyboard.Nodes[i].output_action[b], updateproject202.Nodes[i].output_action[b]); + strcpy(storyboard.Nodes[i].output_title[b], updateproject202.Nodes[i].output_title[b]); + strcpy(storyboard.Nodes[i].input_title[b], updateproject202.Nodes[i].input_title[b]); + strcpy(storyboard.Nodes[i].input_action[b], updateproject202.Nodes[i].input_action[b]); + } + + strcpy(storyboard.Nodes[i].screen_title, updateproject202.Nodes[i].screen_title); + strcpy(storyboard.Nodes[i].screen_music, updateproject202.Nodes[i].screen_music); + strcpy(storyboard.Nodes[i].screen_backdrop, updateproject202.Nodes[i].screen_backdrop); + + storyboard.Nodes[i].screen_backdrop_id = updateproject202.Nodes[i].screen_backdrop_id; + + storyboard.Nodes[i].screen_back_color = updateproject202.Nodes[i].screen_back_color; + storyboard.Nodes[i].screen_backdrop_placement = updateproject202.Nodes[i].screen_backdrop_placement; + storyboard.Nodes[i].screen_grid_size = updateproject202.Nodes[i].screen_grid_size; + for(int c = 0; c < 10; c++) + storyboard.Nodes[i].screen_backdrop_ratio_placement[c] = updateproject202.Nodes[i].screen_backdrop_ratio_placement[c]; + + strcpy(storyboard.Nodes[i].screen_thumb, updateproject202.Nodes[i].screen_thumb); + + + for (int b = 0; b < STORYBOARD_MAXWIDGETS202; b++) + { + strcpy(storyboard.Nodes[i].widget_label[b], updateproject202.Nodes[i].widget_label[b]); + strcpy(storyboard.Nodes[i].widget_normal_thumb[b], updateproject202.Nodes[i].widget_normal_thumb[b]); + + strcpy(storyboard.Nodes[i].widget_highlight_thumb[b], updateproject202.Nodes[i].widget_highlight_thumb[b]); + strcpy(storyboard.Nodes[i].widget_selected_thumb[b], updateproject202.Nodes[i].widget_selected_thumb[b]); + strcpy(storyboard.Nodes[i].widget_font[b], updateproject202.Nodes[i].widget_font[b]); + strcpy(storyboard.Nodes[i].widget_name[b], updateproject202.Nodes[i].widget_name[b]); + strcpy(storyboard.Nodes[i].widget_click_sound[b], updateproject202.Nodes[i].widget_click_sound[b]); + + storyboard.Nodes[i].widget_used[b] = updateproject202.Nodes[i].widget_used[b]; + storyboard.Nodes[i].widget_size[b] = updateproject202.Nodes[i].widget_size[b]; + + storyboard.Nodes[i].widget_pos[b] = updateproject202.Nodes[i].widget_pos[b]; + storyboard.Nodes[i].widget_normal_thumb_id[b] = updateproject202.Nodes[i].widget_normal_thumb_id[b]; + storyboard.Nodes[i].widget_highlight_thumb_id[b] = updateproject202.Nodes[i].widget_highlight_thumb_id[b]; + storyboard.Nodes[i].widget_selected_thumb_id[b] = updateproject202.Nodes[i].widget_selected_thumb_id[b]; + storyboard.Nodes[i].widget_action[b] = updateproject202.Nodes[i].widget_action[b]; + storyboard.Nodes[i].widget_font_color[b] = updateproject202.Nodes[i].widget_font_color[b]; + + storyboard.Nodes[i].widget_font_size[b] = updateproject202.Nodes[i].widget_font_size[b]; + storyboard.Nodes[i].widget_type[b] = updateproject202.Nodes[i].widget_type[b]; + storyboard.Nodes[i].widget_read_only[b] = updateproject202.Nodes[i].widget_read_only[b]; + storyboard.Nodes[i].widget_layer[b] = updateproject202.Nodes[i].widget_layer[b]; + storyboard.Nodes[i].widget_initial_value[b] = updateproject202.Nodes[i].widget_initial_value[b]; + + } + + storyboard.Nodes[i].screen_backdrop_transparent = updateproject202.Nodes[i].screen_backdrop_transparent; + + storyboard.Nodes[i].readouts_available = updateproject202.Nodes[i].readouts_available; + storyboard.Nodes[i].widgets_available = updateproject202.Nodes[i].widgets_available; + storyboard.Nodes[i].toggleKey = updateproject202.Nodes[i].toggleKey; + storyboard.Nodes[i].showAtStart = updateproject202.Nodes[i].showAtStart; + } + + storyboard.NodeRadioButtonSelected[i] = updateproject202.NodeRadioButtonSelected[i]; + for (int b = 0; b < STORYBOARD_MAXWIDGETS202; b++) + { + storyboard.NodeSliderValues[i][b] = updateproject202.NodeSliderValues[i][b]; + storyboard.widget_colors[i][b] = updateproject202.widget_colors[i][b]; + strcpy(storyboard.widget_readout[i][b], updateproject202.widget_readout[i][b]); + storyboard.widget_textoffset[i][b] = updateproject202.widget_textoffset[i][b]; + storyboard.widget_ingamehidden[i][b] = updateproject202.widget_ingamehidden[i][b]; + storyboard.widget_drawordergroup[i][b] = updateproject202.widget_drawordergroup[i][b]; + } + } + strcpy(storyboard.game_icon, updateproject202.game_icon); + strcpy(storyboard.game_thumb, updateproject202.game_thumb); + strcpy(storyboard.game_description, updateproject202.game_description); + strcpy(storyboard.game_world_edge_text, updateproject202.game_world_edge_text); + strcpy(storyboard.game_developer_desc, updateproject202.game_developer_desc); + strcpy(storyboard.customprojectfolder, updateproject202.customprojectfolder); + storyboard.project_readonly = updateproject202.project_readonly; + storyboard.game_thumb_id = updateproject202.game_thumb_id; + storyboard.game_icon_id = updateproject202.game_icon_id; + + if (bUpgradeAndBackupOldProject) + { + char CopyFrom[MAX_PATH]; + strcpy(CopyFrom, filepath); + GG_GetRealPath(CopyFrom, 0); //Resolve name. need full path. + extern char szRootDir[MAX_PATH]; + int rootLen = strlen(szRootDir); + if (strnicmp(CopyFrom, szRootDir, rootLen) == 0) + { + //PE: Read only folder. + storyboard.project_readonly = 1; + } + + if (storyboard.project_readonly != 1) + { + //PE: Make backup and save project203.dat. + char CopyTo[MAX_PATH]; + strcpy(CopyTo, filepath); + strcat(CopyTo, ".bck"); + GG_GetRealPath(CopyTo, 1); //Resolve name. need full path. + bool bRet = CopyFileA(CopyFrom, CopyTo, FALSE); + + cstr savename = storyboard.gamename; + sprintf(project, "projectbank\\%s\\project%d.dat", savename.Get(), STORYBOARDVERSION); + FILE* projectfile = GG_fopen(project, "wb+"); + if (projectfile) + { + fwrite(&storyboard, 1, sizeof(Storyboard), projectfile); + fclose(projectfile); + } + } + } + + } + + } + } return true; } } @@ -46370,9 +46742,13 @@ void GetProjectList(char *path, bool bGetThumbs) bool bHaveAProject = false; char project[MAX_PATH]; - strcpy(project, destination); - strcat(project, folder.Get()); - strcat(project, "\\project.dat"); + sprintf(project, "projectbank\\%s\\project%d.dat", folder.Get(), STORYBOARDVERSION); + if (!GG_FileExists(project)) + { + strcpy(project, destination); + strcat(project, folder.Get()); + strcat(project, "\\project.dat"); + } if (GG_FileExists(project)) { bHaveAProject = true; @@ -46437,11 +46813,28 @@ void GetProjectList(char *path, bool bGetThumbs) } strcat(project, projectbank_list[i].c_str()); strcat(project, "\\project.dat"); - projectfile = GG_fopen(project, "rb"); + + std::string newname = project; + char newversion[MAX_PATH]; + sprintf(newversion, "project%d.dat", STORYBOARDVERSION); + replaceAll(newname, "project.dat", newversion); + projectfile = GG_fopen(newname.c_str(), "rb"); + + if (!projectfile) + projectfile = GG_fopen(project, "rb"); + else + strcpy(project, newname.c_str()); + if (projectfile) { + fclose(projectfile); + + //PE: Use this so we can upgrade from 202 to 203+ + bool load__storyboard_into_struct(const char*, StoryboardStruct&); + load__storyboard_into_struct(project, checkproject); + //PE: Need full load now, as we can have Game Settings. - size_t size = fread(&checkproject, 1, sizeof(checkproject), projectfile); + //size_t size = fread(&checkproject, 1, sizeof(checkproject), projectfile); char sig[12] = "Storyboard\0"; if (checkproject.sig[0] == 'S' && checkproject.sig[8] == 'r') @@ -46511,7 +46904,6 @@ void GetProjectList(char *path, bool bGetThumbs) { projectbank_image.push_back(""); //Just use CLICK HERE. } - fclose(projectfile); } else { @@ -47578,20 +47970,26 @@ int screen_editor(int nodeid, bool standalone, char *screen) { // Some users report runtime error 501, when the above code is called, regenerate unique IDs for the images just in-case int iUniqueIds = STORYBOARD_THUMBS; + int iUniqueIdsAdd = 1000; + if (nodeid >= 200) + iUniqueIdsAdd = 200000; + else if (nodeid >= 100) + iUniqueIdsAdd = 100000; + Storyboard.Nodes[nodeid].id = iUniqueIds; Storyboard.Nodes[nodeid].thumb_id = iUniqueIds; for (int l = 0; l < STORYBOARD_MAXOUTPUTS; l++) { - Storyboard.Nodes[nodeid].input_id[l] = iUniqueIds + 1000 + (1000 * l); - Storyboard.Nodes[nodeid].output_id[l] = iUniqueIds + 1000 + (1000 * l) + 500; + Storyboard.Nodes[nodeid].input_id[l] = iUniqueIds + iUniqueIdsAdd + (1000 * l); + Storyboard.Nodes[nodeid].output_id[l] = iUniqueIds + iUniqueIdsAdd + (1000 * l) + 500; } for (int l = 0; l < STORYBOARD_MAXWIDGETS; l++) { - Storyboard.Nodes[nodeid].widget_normal_thumb_id[l] = iUniqueIds + 1000 + (1000 * l) + 600; - Storyboard.Nodes[nodeid].widget_highlight_thumb_id[l] = iUniqueIds + 1000 + (1000 * l) + 700; - Storyboard.Nodes[nodeid].widget_selected_thumb_id[l] = iUniqueIds + 1000 + (1000 * l) + 800; + Storyboard.Nodes[nodeid].widget_normal_thumb_id[l] = iUniqueIds + iUniqueIdsAdd + (1000 * l) + 600; + Storyboard.Nodes[nodeid].widget_highlight_thumb_id[l] = iUniqueIds + iUniqueIdsAdd + (1000 * l) + 700; + Storyboard.Nodes[nodeid].widget_selected_thumb_id[l] = iUniqueIds + iUniqueIdsAdd + (1000 * l) + 800; } Storyboard.Nodes[nodeid].screen_backdrop_id = iUniqueIds + 500; @@ -52279,3 +52677,4 @@ void tmpdebugfunc(void) } } + diff --git a/GameGuru Core/GameGuru/Source/M-Gun.cpp b/GameGuru Core/GameGuru/Source/M-Gun.cpp index 5efbe5e1..76aa765c 100644 --- a/GameGuru Core/GameGuru/Source/M-Gun.cpp +++ b/GameGuru Core/GameGuru/Source/M-Gun.cpp @@ -113,8 +113,14 @@ void gun_loaddata ( void ) g.firemodes[t.gunid][t.i].settings.brassdelay = 0; g.firemodes[t.gunid][t.i].settings.zoombrassdelay = 0; g.firemodes[t.gunid][t.i].settings.doesnotuseammo = 0; + } + //PE: We need to always be able to locate animation like 'idle'. so. + int iCurrentGunObj = t.currentgunobj; + if (iCurrentGunObj == 0) + iCurrentGunObj = t.gun[t.gunid].obj; + // Load GUNSPEC details (270618 - increased to 1000 lines) Dim ( t.data_s, 1000 ); t.filename_s = "" ; t.filename_s=t.filename_s+"gamecore\\"+g.fpgchuds_s+"\\"+t.gun_s+"\\gunspec.txt"; @@ -540,8 +546,9 @@ void gun_loaddata ( void ) } #ifdef WICKEDENGINE + //PE: This fails when called from entity_load , and t.currentgunobj == 0. We can use t.gun[t.gunid].obj instead. // if no comma and anim field, look up start and finish frames from object directly - if (bFoundComma == false && t.currentgunobj != 0) + if (bFoundComma == false && iCurrentGunObj != 0) { int animfields = 0; bool bAnimationField = false; @@ -582,7 +589,7 @@ void gun_loaddata ( void ) if (animfields == 31) pFieldName = "pull down"; if (animfields == 32) pFieldName = "pull left"; if (animfields == 33) pFieldName = "pull right"; - if (animfields == 34) pFieldName = "useempty"; + if (animfields == 34) pFieldName = "NOTAANIMFIELD"; //PE: "useempty" never use comma. if (animfields == 35) pFieldName = "empty shotgun"; if (animfields == 36) pFieldName = "empty putaway"; if (animfields == 37) pFieldName = "empty select"; @@ -681,7 +688,7 @@ void gun_loaddata ( void ) } else { - sObject* pObject = GetObjectData(t.currentgunobj); + sObject* pObject = GetObjectData(iCurrentGunObj); float fFoundStart = 0, fFoundFinish = 0; extern int entity_lua_getanimationnamefromobject (sObject* pObject, cstr FindThisName_s, float* fFoundStart, float* fFoundFinish); if (entity_lua_getanimationnamefromobject(pObject, t.value_s, &fFoundStart, &fFoundFinish) > 0) @@ -1578,9 +1585,9 @@ void gun_loaddata ( void ) { t.gunsounditem[t.gunid][t.p].keyframe = (t.value1*t.keyframeratio); // if soundanim name specified, add that animations start frame - if (strlen(lastsoundanimname_s.Get()) > 0 && t.currentgunobj != 0 ) + if (strlen(lastsoundanimname_s.Get()) > 0 && iCurrentGunObj != 0 ) { - sObject* pObject = GetObjectData(t.currentgunobj); + sObject* pObject = GetObjectData(iCurrentGunObj); float fFoundStart = 0, fFoundFinish = 0; int entity_lua_getanimationnamefromobject (sObject* pObject, cstr FindThisName_s, float* fFoundStart, float* fFoundFinish); if (entity_lua_getanimationnamefromobject(pObject, lastsoundanimname_s, &fFoundStart, &fFoundFinish) > 0) diff --git a/GameGuru Core/GameGuru/Source/M-LUA-Entity.cpp b/GameGuru Core/GameGuru/Source/M-LUA-Entity.cpp index 9a5ff6f1..783b8914 100644 --- a/GameGuru Core/GameGuru/Source/M-LUA-Entity.cpp +++ b/GameGuru Core/GameGuru/Source/M-LUA-Entity.cpp @@ -3162,7 +3162,7 @@ void entity_lua_changeplayerweapon(void) // before force this weapon, ensure if it does NOT exist, to create it first so can have ammo too int iHaveThis = 0; - for (t.ws = 1; t.ws < 10; t.ws++) + for (t.ws = 1; t.ws < 12; t.ws++) { if (t.weaponslot[t.ws].got == t.foundgunid) { @@ -3204,7 +3204,7 @@ void entity_lua_replaceplayerweapon ( void ) if ( t.gunid>0 ) { // find swap slot for old weapon (gunid) - for ( t.ws = 1 ; t.ws < 10; t.ws++ ) + for ( t.ws = 1 ; t.ws < 12; t.ws++ ) { if ( t.weaponslot[t.ws].pref == t.gunid ) t.tswapslot = t.ws; } @@ -3218,7 +3218,8 @@ void entity_lua_replaceplayerweapon ( void ) if ( t.tswapslot>0 ) { t.weaponslot[t.tswapslot].pref = t.weaponindex; - t.weaponammo[t.tswapslot] = 0; // reset so new weapon can work out its new ammo + if(t.tswapslot < 11) + t.weaponammo[t.tswapslot] = 0; // reset so new weapon can work out its new ammo } // now collect weapon (will find freed up slot from above) t.tqty=t.entityelement[t.e].eleprof.quantity; diff --git a/GameGuru Core/GameGuru/Source/M-LUA-General.cpp b/GameGuru Core/GameGuru/Source/M-LUA-General.cpp index 489b6100..45808a24 100644 --- a/GameGuru Core/GameGuru/Source/M-LUA-General.cpp +++ b/GameGuru Core/GameGuru/Source/M-LUA-General.cpp @@ -1240,7 +1240,7 @@ void lua_removeplayerweapon ( void ) t.ws = t.v; // only if valid weapon slot - if (t.ws >= 1 && t.ws < 10) + if (t.ws >= 1 && t.ws < 12) { //PE: This could be a armour/spell/other and not a weapon. so check. Problem we cant have t.gunid=0 when we have a weapon. if (t.weaponslot[t.ws].got > 0) @@ -1249,9 +1249,11 @@ void lua_removeplayerweapon ( void ) if (t.gunid > 0) { // store ammo before remove from slot - t.gun[t.gunid].storeammo = t.weaponammo[t.ws]; - t.gun[t.gunid].storeclipammo = t.weaponclipammo[t.ws]; - + if (t.ws < 10) + { + t.gun[t.gunid].storeammo = t.weaponammo[t.ws]; + t.gun[t.gunid].storeclipammo = t.weaponclipammo[t.ws]; + } // clear weapon t.weaponindex = t.gunid; physics_player_removeweapon(); @@ -1266,17 +1268,30 @@ void lua_removeplayerweapons (void) g.autoloadgun = 0; // clear all weapons and ammo (even if not collecte yet, why we are using pref) - for (t.ws = 1; t.ws < 10; t.ws++) + for (t.ws = 1; t.ws < 12; t.ws++) { t.weaponslot[t.ws].got = 0; - t.weaponammo[t.ws] = 0; + if(t.ws < 10) + t.weaponammo[t.ws] = 0; t.tgunid = t.weaponslot[t.ws].pref; if (t.tgunid > 0) { t.tpool = g.firemodes[t.tgunid][0].settings.poolindex; t.altpool = g.firemodes[t.tgunid][1].settings.poolindex; - if (t.tpool == 0) t.weaponclipammo[t.ws] = 0; else t.ammopool[t.tpool].ammo = 0; - if (t.altpool == 0) t.weaponclipammo[t.ws + 10] = 0; else t.ammopool[t.altpool].ammo = 0; + if (t.tpool == 0) + { + if (t.ws < 10) + t.weaponclipammo[t.ws] = 0; + } + else + t.ammopool[t.tpool].ammo = 0; + if (t.altpool == 0) + { + if (t.ws < 10) + t.weaponclipammo[t.ws + 10] = 0; + } + else + t.ammopool[t.altpool].ammo = 0; t.gun[t.tgunid].storeammo = 0; t.gun[t.tgunid].storeclipammo = 0; } diff --git a/GameGuru Core/GameGuru/Source/M-Physics.cpp b/GameGuru Core/GameGuru/Source/M-Physics.cpp index 7f312762..58702656 100644 --- a/GameGuru Core/GameGuru/Source/M-Physics.cpp +++ b/GameGuru Core/GameGuru/Source/M-Physics.cpp @@ -3556,7 +3556,7 @@ bool physics_player_addweapon ( void ) // check if we have a slot preference t.tweaponisnew=1; t.gotweaponpref=0; - for ( t.ws = 1 ; t.ws < 10; t.ws++ ) + for ( t.ws = 1 ; t.ws < 12; t.ws++ ) { if ( t.weaponslot[t.ws].pref == t.weaponindex ) t.gotweaponpref = t.ws; @@ -3680,12 +3680,15 @@ bool physics_player_addweapon ( void ) // when new weapon starts, get ammo from store (in case was moved to container and is brought back) if (t.tweaponisnew == 1) { - t.weaponammo[t.gotweapon] = t.gun[t.tgunid].storeammo; - t.weaponclipammo[t.gotweapon] = t.gun[t.tgunid].storeclipammo; + if (t.gotweapon < 10) + { + t.weaponammo[t.gotweapon] = t.gun[t.tgunid].storeammo; + t.weaponclipammo[t.gotweapon] = t.gun[t.tgunid].storeclipammo; + } } t.taltqty = 0; - if (t.weaponammo[t.gotweapon] == 0 && t.tweaponisnew == 1) + if (t.gotweapon < 10 && t.weaponammo[t.gotweapon] == 0 && t.tweaponisnew == 1) { // provide some alternative ammo (weaponammo+10) if ( t.gun[t.tgunid].settings.modessharemags == 0 ) @@ -3787,31 +3790,34 @@ bool physics_player_addweapon ( void ) } else { - t.tpool=g.firemodes[t.tgunid][0].settings.poolindex; - t.altpool=g.firemodes[t.tgunid][1].settings.poolindex; - int iMaxClipCapacity = g.firemodes[t.tgunid][0].settings.clipcapacity * g.firemodes[t.tgunid][0].settings.reloadqty; - if (iMaxClipCapacity == 0) iMaxClipCapacity = 99999; - if (t.tpool == 0) - { - t.weaponclipammo[t.gotweapon] = t.weaponclipammo[t.gotweapon] + t.tqty; - if (t.weaponclipammo[t.gotweapon] > iMaxClipCapacity) t.weaponclipammo[t.gotweapon] = iMaxClipCapacity; - } - else + if (t.gotweapon < 10) { - t.ammopool[t.tpool].ammo = t.ammopool[t.tpool].ammo + t.tqty; - if (t.ammopool[t.tpool].ammo > iMaxClipCapacity) t.ammopool[t.tpool].ammo = iMaxClipCapacity; - } - iMaxClipCapacity = g.firemodes[t.tgunid][1].settings.clipcapacity * g.firemodes[t.tgunid][1].settings.reloadqty; - if (iMaxClipCapacity == 0) iMaxClipCapacity = 99999; - if (t.altpool == 0) - { - t.weaponclipammo[t.gotweapon + 10] = t.weaponclipammo[t.gotweapon + 10] + t.taltqty; - if (t.weaponclipammo[t.gotweapon + 10] > iMaxClipCapacity) t.weaponclipammo[t.gotweapon + 10] = iMaxClipCapacity; - } - else - { - t.ammopool[t.altpool].ammo = t.ammopool[t.altpool].ammo + t.taltqty; - if (t.ammopool[t.altpool].ammo > iMaxClipCapacity) t.ammopool[t.altpool].ammo = iMaxClipCapacity; + t.tpool = g.firemodes[t.tgunid][0].settings.poolindex; + t.altpool = g.firemodes[t.tgunid][1].settings.poolindex; + int iMaxClipCapacity = g.firemodes[t.tgunid][0].settings.clipcapacity * g.firemodes[t.tgunid][0].settings.reloadqty; + if (iMaxClipCapacity == 0) iMaxClipCapacity = 99999; + if (t.tpool == 0) + { + t.weaponclipammo[t.gotweapon] = t.weaponclipammo[t.gotweapon] + t.tqty; + if (t.weaponclipammo[t.gotweapon] > iMaxClipCapacity) t.weaponclipammo[t.gotweapon] = iMaxClipCapacity; + } + else + { + t.ammopool[t.tpool].ammo = t.ammopool[t.tpool].ammo + t.tqty; + if (t.ammopool[t.tpool].ammo > iMaxClipCapacity) t.ammopool[t.tpool].ammo = iMaxClipCapacity; + } + iMaxClipCapacity = g.firemodes[t.tgunid][1].settings.clipcapacity * g.firemodes[t.tgunid][1].settings.reloadqty; + if (iMaxClipCapacity == 0) iMaxClipCapacity = 99999; + if (t.altpool == 0) + { + t.weaponclipammo[t.gotweapon + 10] = t.weaponclipammo[t.gotweapon + 10] + t.taltqty; + if (t.weaponclipammo[t.gotweapon + 10] > iMaxClipCapacity) t.weaponclipammo[t.gotweapon + 10] = iMaxClipCapacity; + } + else + { + t.ammopool[t.altpool].ammo = t.ammopool[t.altpool].ammo + t.taltqty; + if (t.ammopool[t.altpool].ammo > iMaxClipCapacity) t.ammopool[t.altpool].ammo = iMaxClipCapacity; + } } } } @@ -3821,7 +3827,7 @@ bool physics_player_addweapon ( void ) physics_player_refreshcount ( ); // if collected weapon, and is empty, trigger reload if gun anim able - if ( t.gotweapon>0 ) + if ( t.gotweapon>0 && t.gotweapon < 10) { t.tgunid=t.weaponslot[t.gotweapon].pref; if ( t.weaponammo[t.gotweapon] == 0 ) @@ -3840,11 +3846,11 @@ bool physics_player_addweapon ( void ) void physics_player_removeweapon ( void ) { // check all weapon slots - for ( t.ws = 1 ; t.ws < 10; t.ws++ ) + for ( t.ws = 1 ; t.ws < 12; t.ws++ ) { if ( t.weaponslot[t.ws].got == t.weaponindex ) break; } - if ( t.ws < 10 ) + if ( t.ws < 12 ) { // Ensure gun is removed (if applicable) if ( t.gunid>0 && t.weaponslot[t.ws].got == t.gunid ) @@ -3862,7 +3868,7 @@ void physics_player_removeweapon ( void ) void physics_player_resetWeaponSlots( void ) { - for (t.ws = 1; t.ws < 10; t.ws++) + for (t.ws = 1; t.ws < 12; t.ws++) { t.weaponslot[t.ws].got = 0; t.weaponslot[t.ws].invpos = 0; diff --git a/GameGuru Core/GameGuru/Source/M-TerrainNew.cpp b/GameGuru Core/GameGuru/Source/M-TerrainNew.cpp index 0578961b..8862f221 100644 --- a/GameGuru Core/GameGuru/Source/M-TerrainNew.cpp +++ b/GameGuru Core/GameGuru/Source/M-TerrainNew.cpp @@ -10387,7 +10387,7 @@ void procedural_new_level(void) ggterrain_global_render_params2.flags2 &= ~GGTERRAIN_SHADER_FLAG2_SHOW_MINI_MAP; } - if (ImageExist(TERRAINGENERATOR_IMAGE)) DeleteImage(TERRAINGENERATOR_IMAGE); + //if (ImageExist(TERRAINGENERATOR_IMAGE)) DeleteImage(TERRAINGENERATOR_IMAGE); if (ObjectExist(TERRAINGENERATOR_OBJECT)) DeleteObject(TERRAINGENERATOR_OBJECT); if (!bPopModalOpenProceduralCameraMode) { @@ -13530,7 +13530,7 @@ void procedural_new_level(void) DeleteBitmapEx(99); } - if (ImageExist(TERRAINGENERATOR_IMAGE)) DeleteImage(TERRAINGENERATOR_IMAGE); + //if (ImageExist(TERRAINGENERATOR_IMAGE)) DeleteImage(TERRAINGENERATOR_IMAGE); if (ObjectExist(TERRAINGENERATOR_OBJECT)) DeleteObject(TERRAINGENERATOR_OBJECT); //Restore fog. diff --git a/GameGuru Core/GameGuru/Source/cStr.cpp b/GameGuru Core/GameGuru/Source/cStr.cpp index 58807f0e..81bd3056 100644 --- a/GameGuru Core/GameGuru/Source/cStr.cpp +++ b/GameGuru Core/GameGuru/Source/cStr.cpp @@ -37,6 +37,10 @@ bool noDeleteCSTR = false; #define STRMINSIZE 128 #endif +//PE: ZTEMP just use double mem, no need, use a ringbuffer instead. And we have very many of these in entityelements. +#define DISABLEZTEMP + + //#define TESTUSEOFSTRINGS #ifdef TESTUSEOFSTRINGS int CheckPreSize[5000]; @@ -56,16 +60,22 @@ cStr::cStr ( const cStr& cString ) if ( m_size >= STRMINSIZE ) { m_pString = new char [ sizeof ( char ) * ( m_size ) + 1 ]; +#ifndef DISABLEZTEMP m_szTemp = new char [ sizeof ( char ) * ( m_size ) + 1 ]; +#endif } else { m_pString = new char [ STRMINSIZE ]; +#ifndef DISABLEZTEMP m_szTemp = new char [ STRMINSIZE ]; +#endif } memset ( m_pString, 0, sizeof ( m_pString ) ); +#ifndef DISABLEZTEMP memset ( m_szTemp, 0, sizeof ( m_szTemp ) ); +#endif strcpy ( m_pString, cString.m_pString ); } @@ -80,16 +90,22 @@ cStr::cStr ( char* szString ) if ( m_size >= STRMINSIZE ) { m_pString = new char [ sizeof ( char ) * ( m_size ) + 1 ]; +#ifndef DISABLEZTEMP m_szTemp = new char [ sizeof ( char ) * ( m_size ) + 1 ]; +#endif } else { m_pString = new char [ STRMINSIZE ]; +#ifndef DISABLEZTEMP m_szTemp = new char [ STRMINSIZE ]; +#endif } memset ( m_pString, 0, sizeof ( m_pString ) ); +#ifndef DISABLEZTEMP memset ( m_szTemp, 0, sizeof ( m_szTemp ) ); +#endif strcpy ( m_pString, szString ); } @@ -100,8 +116,10 @@ cStr::cStr ( int iValue ) memset ( m_pString, 0, sizeof ( m_pString ) ); sprintf ( m_pString, "%i", iValue ); +#ifndef DISABLEZTEMP m_szTemp = new char [ STRMINSIZE ]; memset ( m_szTemp, 0, sizeof ( m_szTemp ) ); +#endif } cStr::cStr ( float fValue ) @@ -109,9 +127,10 @@ cStr::cStr ( float fValue ) m_pString = new char [ STRMINSIZE ]; memset ( m_pString, 0, sizeof ( m_pString ) ); sprintf ( m_pString, "%.2f", fValue ); - +#ifndef DISABLEZTEMP m_szTemp = new char [ STRMINSIZE ]; memset ( m_szTemp, 0, sizeof ( m_szTemp ) ); +#endif } cStr::cStr ( double dValue ) @@ -119,9 +138,10 @@ cStr::cStr ( double dValue ) m_pString = new char [ STRMINSIZE ]; memset ( m_pString, 0, sizeof ( m_pString ) ); sprintf ( m_pString, "%.2f", ( float ) dValue ); - +#ifndef DISABLEZTEMP m_szTemp = new char [ STRMINSIZE ]; memset ( m_szTemp, 0, sizeof ( m_szTemp ) ); +#endif } cStr::cStr ( ) @@ -129,9 +149,10 @@ cStr::cStr ( ) m_pString = new char [ STRMINSIZE ]; memset ( m_pString, 0, sizeof ( m_pString ) ); strcpy ( m_pString, "" ); - +#ifndef DISABLEZTEMP m_szTemp = new char [ STRMINSIZE ]; memset ( m_szTemp, 0, sizeof ( m_szTemp ) ); +#endif } cStr::~cStr ( ) @@ -140,12 +161,19 @@ cStr::~cStr ( ) { if ( m_pString ) delete [ ] m_pString; - +#ifndef DISABLEZTEMP if ( m_szTemp ) delete [] m_szTemp; //PE: Heap error here if >256 strings and using s=s+" " +#endif } } +#ifdef DISABLEZTEMP +char* m_sTemp[20] = { nullptr }; +int m_iLen[20] = { 0 }; +int m_iCurrentBuffer = 0; +#endif + cStr cStr::operator + ( const cStr& other ) { //PE: We have a bug here if using >= 256 strings and using: @@ -154,7 +182,37 @@ cStr cStr::operator + ( const cStr& other ) // s += " " // This works. m_size = (int) strlen ( other.m_pString ) + (int) strlen ( m_pString ); +#ifdef DISABLEZTEMP + + //PE: Use a ringbuffer. + m_iCurrentBuffer++; + if (m_iCurrentBuffer >= 19) + m_iCurrentBuffer = 0; + + if (m_iLen[m_iCurrentBuffer] <= (m_size + 50) || !m_sTemp[m_iCurrentBuffer]) + { + if(m_sTemp[m_iCurrentBuffer]) + delete[] m_sTemp[m_iCurrentBuffer]; + m_sTemp[m_iCurrentBuffer] = new char[sizeof(char) * ((m_size) + 51)]; + m_iLen[m_iCurrentBuffer] = (m_size + 50); + } + + if (m_sTemp[m_iCurrentBuffer]) + { + if (m_pString) + strcpy(m_sTemp[m_iCurrentBuffer], m_pString); + else + m_sTemp[m_iCurrentBuffer][0] = 0; + + if (other.m_pString) + strcat(m_sTemp[m_iCurrentBuffer], other.m_pString); + return cStr(m_sTemp[m_iCurrentBuffer]); + } + else + return(cStr("m_sTemp[m_iCurrentBuffer] alloc failed.")); //PE: Debug only should never happen. + +#else if ( m_size >= STRMINSIZE ) { #ifdef TESTUSEOFSTRINGS @@ -173,7 +231,9 @@ cStr cStr::operator + ( const cStr& other ) if ( other.m_pString ) strcat ( m_szTemp, other.m_pString ); - return cStr ( m_szTemp ); + return cStr(m_szTemp); +#endif + } cStr& cStr::operator += ( const cStr& other ) @@ -191,8 +251,10 @@ cStr& cStr::operator += ( const cStr& other ) strcpy ( newstring , m_pString ); delete[] m_pString; m_pString = newstring; +#ifndef DISABLEZTEMP delete[] m_szTemp; m_szTemp = new char [ sizeof ( char ) * ( m_size ) + 1 ]; +#endif } if ( other.m_pString ) @@ -214,8 +276,10 @@ cStr cStr::operator = ( const cStr& other ) char* newstring = new char [ sizeof ( char ) * ( m_size ) + 1 ]; delete[] m_pString; m_pString = newstring; +#ifndef DISABLEZTEMP delete[] m_szTemp; m_szTemp = new char [ sizeof ( char ) * ( m_size ) + 1 ]; +#endif } strcpy ( m_pString, other.m_pString ); @@ -243,8 +307,10 @@ cStr& cStr::operator = ( const char* other ) char* newstring = new char [ sizeof ( char ) * ( m_size ) + 1 ]; delete[] m_pString; m_pString = newstring; +#ifndef DISABLEZTEMP delete[] m_szTemp; m_szTemp = new char [ sizeof ( char ) * ( m_size ) + 1 ]; +#endif } //PE: m_pString was 0 here ? called from line (t.tfile_s="audiobank\\materials\\materialdefault.txt";) ? strcpy ( m_pString, other ); diff --git a/GameGuru Core/Guru-WickedMAX/GGTerrain/GGGrass.cpp b/GameGuru Core/Guru-WickedMAX/GGTerrain/GGGrass.cpp index 71b0bcef..4124b6cc 100644 --- a/GameGuru Core/Guru-WickedMAX/GGTerrain/GGGrass.cpp +++ b/GameGuru Core/Guru-WickedMAX/GGTerrain/GGGrass.cpp @@ -1,3 +1,6 @@ + +#define ONLYLOADWHENUSED + #include "GGGrass.h" #include "wiRenderer.h" @@ -22,6 +25,12 @@ #include "optick.h" #endif +#ifdef ONLYLOADWHENUSED +bool bGrassTextureUploaded[255]; +bool bGrassTextureForceUploaded[255]; +//extern std::string FinalGameGuruMaxFolder; +uint64_t last_paint_type; +#endif using namespace GGTerrain; using namespace wiGraphics; @@ -664,6 +673,86 @@ float GrassTimer() return (float) (i64CurrentTime / (double) i64TimeFreq); } +#ifdef ONLYLOADWHENUSED +//#pragma optimize("", off) + +void GGGrass_LoadTextures(bool bAll = false,bool bInit = false) +{ + char grassFilename[256]; + bool bChanged = false; + uint64_t values = gggrass_global_params.paint_type; + uint32_t currMat = gggrass_global_params.paint_material; + + if (bInit) + { + //PE: Defaults 0,7 + bGrassTextureUploaded[0] = true; + char szDstRoot[MAX_PATH]; + strcpy_s(szDstRoot, "files/grassbank/"); + strcpy_s(grassFilename, szDstRoot); + strcat_s(grassFilename, grassFiles[0].filename); + GGGrass_LoadTextureDDSIntoSlice(grassFilename, &texGrass, 0); + + bGrassTextureUploaded[7] = true; + strcpy_s(grassFilename, szDstRoot); + strcat_s(grassFilename, grassFiles[7].filename); + GGGrass_LoadTextureDDSIntoSlice(grassFilename, &texGrass, 7); + bChanged = true; + + } + else + { + for (uint32_t i = 0; i < GGGRASS_NUM_SELECTABLE_TYPES; i++) + { + if (values & 1) + { + uint32_t realIndex = 0; + + realIndex = GGGrass_GetRealIndex(0, i); //PE: Manual paint version + if (realIndex >= GGGRASS_NUM_TYPES) realIndex = 0; + + if (!bGrassTextureUploaded[realIndex]) + { + bGrassTextureUploaded[realIndex] = true; + char szDstRoot[MAX_PATH]; + strcpy_s(szDstRoot, "grassbank/"); + strcpy_s(grassFilename, szDstRoot); + strcat_s(grassFilename, grassFiles[realIndex].filename); + GGGrass_LoadTextureDDSIntoSlice(grassFilename, &texGrass, realIndex); + bChanged = true; + } + + realIndex = GGGrass_GetRealIndex(1, i); //PE: Auto paint version + if (realIndex >= GGGRASS_NUM_TYPES) realIndex = 0; + + if (!bGrassTextureUploaded[realIndex]) + { + bGrassTextureUploaded[realIndex] = true; + char szDstRoot[MAX_PATH]; + //sprintf_s(szDstRoot, MAX_PATH, "%sgrassbank/", FinalGameGuruMaxFolder.c_str()); + if (bInit) + strcpy_s(szDstRoot, "files/grassbank/"); + else + strcpy_s(szDstRoot, "grassbank/"); + + strcpy_s(grassFilename, szDstRoot); + strcat_s(grassFilename, grassFiles[realIndex].filename); + GGGrass_LoadTextureDDSIntoSlice(grassFilename, &texGrass, realIndex); + bChanged = true; + } + + //pGrassMap[index] &= 0x80; // keep flattened state + //pGrassMap[index] |= realIndex + 2; + } + values >>= 1; + } + } + if (bChanged) + { + ggterrain_extra_params.iUpdateGrass = 5; + } +} +#endif void GGGrass_Init_Textures ( LPSTR pRemoteGrassPath ) { char grassFilename[256]; @@ -699,7 +788,18 @@ void GGGrass_Init() GGGrass_LoadTextureDDS("Files/treebank/noise.dds", &texNoise); GGGrass_CreateEmptyTexture(1024, 1024, 9, GGGRASS_NUM_TYPES, FORMAT_BC3_UNORM_SRGB, &texGrass); +#ifdef ONLYLOADWHENUSED + for (uint32_t i = 0; i < GGGRASS_NUM_TYPES; i++) + { + bGrassTextureUploaded[i] = false; + bGrassTextureForceUploaded[i] = false; + } + last_paint_type = gggrass_global_params.paint_type; + GGGrass_LoadTextures(false,true); +#else + GGGrass_Init_Textures("Files\\"); +#endif pGrassMap = new uint8_t[ GGGRASS_MAP_SIZE * GGGRASS_MAP_SIZE ]; memset( pGrassMap, 1, GGGRASS_MAP_SIZE * GGGRASS_MAP_SIZE ); @@ -1061,6 +1161,21 @@ int GGGrass_SetData( uint32_t size, uint8_t* data, sUndoSysEventGrass* pEvent) memcpy(pGrassMap, data, size1); //wiRenderer::GetDevice()->UpdateTexture(&texGrassMap, 0, 0, NULL, pGrassMap, GGGRASS_MAP_SIZE, -1); +#ifdef ONLYLOADWHENUSED + for (uint32_t y = 0; y < GGGRASS_MAP_SIZE; y++) + { + for (uint32_t x = 0; x < GGGRASS_MAP_SIZE; x++) + { + uint32_t index = y * GGGRASS_MAP_SIZE + x; + uint8_t grassID = pGrassMap[index] & 0x7F; + if (grassID > 2) + { + bGrassTextureForceUploaded[grassID-2] = true; + } + } + } + last_paint_type = -1; +#endif return 1; } @@ -1456,6 +1571,14 @@ void GGGrass_Update( wiScene::CameraComponent* camera, CommandList cmd, bool bRe if ( !gggrass_global_params.draw_enabled ) return; +#ifdef ONLYLOADWHENUSED + if (last_paint_type != gggrass_global_params.paint_type) + { + GGGrass_LoadTextures(false,false); + last_paint_type = gggrass_global_params.paint_type; + } +#endif + //auto range = wiProfiler::BeginRangeCPU( "Max - Grass Update" ); if ( gggrass_global_params.max_height < gggrass_global_params.min_height ) gggrass_global_params.max_height = gggrass_global_params.min_height; diff --git a/GameGuru Core/Guru-WickedMAX/GGTerrain/GGTerrain.cpp b/GameGuru Core/Guru-WickedMAX/GGTerrain/GGTerrain.cpp index 64f7a67c..53b4df8f 100644 --- a/GameGuru Core/Guru-WickedMAX/GGTerrain/GGTerrain.cpp +++ b/GameGuru Core/Guru-WickedMAX/GGTerrain/GGTerrain.cpp @@ -1,6 +1,7 @@ #define PEOPTIMIZING #define TERRAINTHREADSAFE +#define ONLYLOADWHENUSED #include #include "Utility/stb_image.h" @@ -123,6 +124,11 @@ using namespace GGGrass; #define GGKEY_F7 0x76 #define GGKEY_F8 0x77 +//extern std::string FinalGameGuruMaxFolder; +#ifdef ONLYLOADWHENUSED +bool bCheckForNewTerrainTextures = false; +#endif + extern wiECS::Entity g_entitySunLight; extern bool bImGuiGotFocus; extern bool bImGuiInTestGame; @@ -4116,13 +4122,30 @@ void GGTerrain_CreateFractalTexture( Texture* tex, uint32_t size ) } */ - + uint8_t* imageData = new uint8_t[size * size]; +#ifdef ONLYLOADWHENUSED + FILE* loadfile = GG_fopen("files/treebank/FractalGenerator.dat", "rb"); + if (loadfile) + { + size_t readsize = fread(imageData, 1, size * size, loadfile); + fclose(loadfile); + } + else + { +#endif + //PE: This is slow , so cache it , it generate the same data anyway. + FractalGenerator::SetWork(imageData, size, size); + FractalGenerator::StartThreads(); + FractalGenerator::WaitForAll(); +#ifdef ONLYLOADWHENUSED + FILE* savefile = GG_fopen("files/treebank/FractalGenerator.dat", "wb+"); + if (savefile) { + size_t length = fwrite(imageData, 1, (size * size), savefile); + fclose(savefile); + } + } +#endif - uint8_t* imageData = new uint8_t[ size * size ]; - FractalGenerator::SetWork( imageData, size, size ); - FractalGenerator::StartThreads(); - FractalGenerator::WaitForAll(); - TextureDesc texDesc = {}; texDesc.BindFlags = BIND_SHADER_RESOURCE | BIND_RENDER_TARGET; // BIND_RENDER_TARGET must be set for generating mipmaps texDesc.clear.color[0] = 1.0f; @@ -4325,7 +4348,7 @@ void GGTerrain_LoadTextureDDS( const char* filename, Texture* tex ) device->SetName( tex, "imageTex" ); } -bool GGTerrain_LoadTextureDDSIntoSlice( const char* filename, Texture* tex, uint32_t arraySlice, DDSRequirements* requirements, wiGraphics::CommandList cmd) +bool GGTerrain_LoadTextureDDSIntoSlice(const char* filename, Texture* tex, uint32_t arraySlice, DDSRequirements* requirements, wiGraphics::CommandList cmd, bool bFillAllSlots = false) { GraphicsDevice* device = wiRenderer::GetDevice(); char filePath[MAX_PATH]; @@ -4364,15 +4387,32 @@ bool GGTerrain_LoadTextureDDSIntoSlice( const char* filename, Texture* tex, uint #endif - uint32_t maxMip = dds.GetMipCount(); - if ( maxMip > tex->desc.MipLevels ) maxMip = tex->desc.MipLevels; - std::vector InitData; - for (uint32_t mip = 0; mip < maxMip; ++mip) + if (bFillAllSlots) { - auto imageData = dds.GetImageData(mip, 0); - device->UpdateTexture(tex, mip, arraySlice, 0, imageData->m_mem, imageData->m_memPitch, cmd); + for (uint32_t i = 0; i < GGTERRAIN_MAX_SOURCE_TEXTURES; i++) + { + uint32_t maxMip = dds.GetMipCount(); + if (maxMip > tex->desc.MipLevels) maxMip = tex->desc.MipLevels; + std::vector InitData; + for (uint32_t mip = 0; mip < maxMip; ++mip) + { + auto imageData = dds.GetImageData(mip, 0); + device->UpdateTexture(tex, mip, i, 0, imageData->m_mem, imageData->m_memPitch, cmd); + } + break; + } + } + else + { + uint32_t maxMip = dds.GetMipCount(); + if (maxMip > tex->desc.MipLevels) maxMip = tex->desc.MipLevels; + std::vector InitData; + for (uint32_t mip = 0; mip < maxMip; ++mip) + { + auto imageData = dds.GetImageData(mip, 0); + device->UpdateTexture(tex, mip, arraySlice, 0, imageData->m_mem, imageData->m_memPitch, cmd); + } } - return true; } @@ -5499,7 +5539,9 @@ int GGTerrain_LoadSettings( const char* settingsJSON, bool bRestoreWater) } delete pObject; - +#ifdef ONLYLOADWHENUSED + bCheckForNewTerrainTextures = true; +#endif return 1; } @@ -6149,12 +6191,23 @@ void GGTerrain_CreateSphere( float diameter, int rows, int columns ) float pHeightMapEditMemMovedOutOfHeap[GGTERRAIN_HEIGHTMAP_EDIT_SIZE * GGTERRAIN_HEIGHTMAP_EDIT_SIZE]; uint8_t pMaterialMapMemMoveOutOfHeap[GGTERRAIN_MATERIALMAP_SIZE * GGTERRAIN_MATERIALMAP_SIZE]; +#ifdef ONLYLOADWHENUSED +bool bTextureUploaded[GGTERRAIN_MAX_SOURCE_TEXTURES+1]; +#endif + // initialize the system int GGTerrain_Init( wiGraphics::CommandList cmd ) { if ( ggterrain_initialised ) return 1; ggterrain_initialised = 1; +#ifdef ONLYLOADWHENUSED + for (int i = 0; i < GGTERRAIN_MAX_SOURCE_TEXTURES; i++) + { + bTextureUploaded[i] = false; + } +#endif + char pCurrDir[MAX_PATH]; GetCurrentDirectoryA(MAX_PATH, pCurrDir); g_DeferTextureUpdateMAXRootFolder_s = pCurrDir; @@ -8826,6 +8879,13 @@ void GGTerrain_Update( float playerX, float playerY, float playerZ, wiGraphics:: if (g_iDeferTextureUpdateToNow == 2) { // Update the textures for the terrain +#ifdef ONLYLOADWHENUSED + for (int i = 0; i < GGTERRAIN_MAX_SOURCE_TEXTURES; i++) + { + bTextureUploaded[i] = false; + } +#endif + g_DeferTextureUpdateIncompatibleTextures.clear(); if(strlen(g_DeferTextureUpdateCurrentFolder_s.Get())>0) SetDir(g_DeferTextureUpdateCurrentFolder_s.Get()); GGTerrain_ReloadTextures(cmd, &g_DeferTextureUpdate, &g_DeferTextureUpdateIncompatibleTextures, g_DeferTextureUpdateMAXRootFolder_s.Get());// g.fpscrootdir_s.Get()); @@ -8833,7 +8893,12 @@ void GGTerrain_Update( float playerX, float playerY, float playerZ, wiGraphics:: g_iDeferTextureUpdateToNow = 3; } } - +#ifdef ONLYLOADWHENUSED + if (bCheckForNewTerrainTextures && ggterrain_initialised) + { + GGTerrain_CheckMaterialUsed(cmd); + } +#endif if ( !bImGuiGotFocus && ggterrain_initialised) { GGTerrain_CheckKeys(); @@ -9507,6 +9572,15 @@ void GGTerrain_Update( float playerX, float playerY, float playerZ, wiGraphics:: case GGTERRAIN_EDIT_PAINT: { +#ifdef ONLYLOADWHENUSED + int mat = ggterrain_extra_params.paint_material & 0xff; + if (mat > 0 && mat <= GGTERRAIN_MAX_SOURCE_TEXTURES) + mat--; + if (mat >= 0 && !bTextureUploaded[mat]) + { + bCheckForNewTerrainTextures = true; //PE: Load texture. + } +#endif GGTerrain_Update_Painting( pickX, pickY, pickZ ); } break; @@ -9855,6 +9929,10 @@ int GGTerrain_SetPaintData( uint32_t size, uint8_t* data, sUndoSysEventTerrainPa //PE: Was needed so we can invalidate region and clear old textures. wiRenderer::GetDevice()->UpdateTexture(&texMaterialMap, 0, 0, NULL, pMaterialMap, GGTERRAIN_MATERIALMAP_SIZE, -1); +#ifdef ONLYLOADWHENUSED + bCheckForNewTerrainTextures = true; +#endif + GGTerrain_InvalidateEverything(GGTERRAIN_INVALIDATE_TEXTURES); return 1; @@ -10837,13 +10915,37 @@ void GGTerrain_ReloadTextures(wiGraphics::CommandList cmd, std::vector 0) + { + mat = ggterrain_extra_params.paint_material & 0xff; + if(mat > 0 && mat <= GGTERRAIN_MAX_SOURCE_TEXTURES) + bMaterialUsed[mat-1] = true; + } + + for (int x = 0; x < GGTERRAIN_MATERIALMAP_SIZE; x++) + { + for (int y = 0; y < GGTERRAIN_MATERIALMAP_SIZE; y++) + { + //uint8_t mat = GGTerrain_GetMaterialIndex(x, y); + uint32_t index = y * GGTERRAIN_MATERIALMAP_SIZE + x; + if (x >= 0 && y >= 0 && x < GGTERRAIN_MATERIALMAP_SIZE && y < GGTERRAIN_MATERIALMAP_SIZE) + { + uint8_t mat = pMaterialMap[index]; + if (mat > 0) + { + if (mat <= GGTERRAIN_MAX_SOURCE_TEXTURES) + bMaterialUsed[mat-1] = true; + } + } + + } + } + bool bTextChange = false; + for (uint32_t i = 0; i < GGTERRAIN_MAX_SOURCE_TEXTURES; i++) + { + if(bMaterialUsed[i] == true && bTextureUploaded[i] == false) + { + //wiGraphics::CommandList cmd = wiRenderer::GetDevice()->BeginCommandList(); + + //PE: Check all material IDs if we need to update any. + char szDstRoot[MAX_PATH]; + //sprintf_s(szDstRoot, MAX_PATH, "%sterraintextures/mat%d", FinalGameGuruMaxFolder.c_str(), i + 1); + sprintf_s(szDstRoot, MAX_PATH, "terraintextures/mat%d", i + 1); + + + char szDstColorPath[MAX_PATH]; + char szDstNormalPath[MAX_PATH]; + + sprintf_s(szDstColorPath, MAX_PATH, "%s/Color.dds", szDstRoot); + sprintf_s(szDstNormalPath, MAX_PATH, "%s/Normal.dds", szDstRoot); + bTextureUploaded[i] = true; + bMaterialUsed[i] = false; + //PE: Only upload textures that are actually in use by terrain. + GGTerrain_LoadTextureDDSIntoSlice(szDstColorPath, &texColorArray, i, &colorDDS, cmd, false); + GGTerrain_LoadTextureDDSIntoSlice(szDstNormalPath, &texNormalsArray, i, &normalDDS, cmd, false); + + char szDstSurfacePath[MAX_PATH]; + sprintf_s(szDstSurfacePath, MAX_PATH, "%s/Surface.dds", szDstRoot); + GGTerrain_LoadTextureDDSIntoSlice(szDstSurfacePath, &texSurfaceArray, i, &surfaceDDS, cmd, false); + bTextChange = true; + } + } + bCheckForNewTerrainTextures = false; + if (bTextChange) + { + //PE: update textures. + GGTerrain_InvalidateEverything(GGTERRAIN_INVALIDATE_TEXTURES); + } + } +} +#endif + + void GGTerrain_LoadDefaultTextureIntoSlot(int i, char* rootDir, wiGraphics::CommandList cmd) { // Load default texture into any unused slots diff --git a/GameGuru Core/Guru-WickedMAX/GGTerrain/GGTerrain.h b/GameGuru Core/Guru-WickedMAX/GGTerrain/GGTerrain.h index 28d5384b..65508aa7 100644 --- a/GameGuru Core/Guru-WickedMAX/GGTerrain/GGTerrain.h +++ b/GameGuru Core/Guru-WickedMAX/GGTerrain/GGTerrain.h @@ -343,7 +343,7 @@ void GGTerrain_ReloadTextures(wiGraphics::CommandList cmd = 0, std::vector treeMaxHeight) treeMaxHeight = g_GGTrees[i].height; + if (ggtrees_global_params.paint_tree_bitfield & (1ULL << i) || bTreeTextureForceUploaded[i]) + { + bTreeTextureUploaded[i] = true; + + char szDstRoot[MAX_PATH]; + //sprintf_s(szDstRoot, MAX_PATH, "%streebank/", FinalGameGuruMaxFolder.c_str()); + if(bInit) + strcpy_s(szDstRoot, "files/treebank/"); + else + strcpy_s(szDstRoot, "treebank/"); + + strcpy_s(path, szDstRoot); + strcat_s(path, "billboards/"); + strcat_s(path, g_GGTrees[i].billboardFilename); + GGTrees_LoadTextureDDSIntoSlice(path, &texTree, i); + + strcpy_s(path, szDstRoot); + strcat_s(path, "billboards/"); + strcat_s(path, g_GGTrees[i].billboardNormalFilename); + GGTrees_LoadTextureDDSIntoSlice(path, &texTreeNormal, i); + + strcpy_s(path, szDstRoot); + strcat_s(path, "textures/"); + strcat_s(path, g_GGTrees[i].trunk->textureName); + GGTrees_LoadTextureDDSIntoSlice(path, &texTreeHigh, i); + + if (g_GGTrees[i].branches) + { + strcpy_s(path, szDstRoot); + strcat_s(path, "textures/"); + strcat_s(path, g_GGTrees[i].branches->textureName); + GGTrees_LoadTextureDDSIntoSlice(path, &texBranchesHigh, i); + } + } + } + } + +} +#endif + void GGTrees_Init() { ggtrees_initialised = 1; @@ -1126,6 +1184,17 @@ void GGTrees_Init() GGTrees_CreateEmptyTexture( 1024, 1024, 9, numTreeTypes, FORMAT_BC1_UNORM_SRGB, &texTreeHigh ); GGTrees_CreateEmptyTexture( 1024, 1024, 9, numTreeTypes, FORMAT_BC3_UNORM_SRGB, &texBranchesHigh ); +#ifdef ONLYLOADWHENUSED + for (int i = 0; i < numTreeTypes; i++) + { + bTreeTextureUploaded[i] = false; + bTreeTextureForceUploaded[i] = false; + treeInstancesHigh[i] = new InstanceTreeGPU[1000]; + treeInstancesHighShadow[i] = new InstanceTreeGPU[1000]; + } + last_paint_tree_bitfield = ggtrees_global_params.paint_tree_bitfield; + GGTrees_LoadTextures(true); +#else char path[ 1024 ]; for( int i = 0; i < numTreeTypes; i++ ) { @@ -1153,6 +1222,7 @@ void GGTrees_Init() treeInstancesHigh[ i ] = new InstanceTreeGPU[ 1000 ]; treeInstancesHighShadow[ i ] = new InstanceTreeGPU[ 1000 ]; } +#endif //GGTerrain_DecompressImage( "E:/Programs/GameGuruMAX/Max/Files/pinetree_BC7.dds", "E:/Programs/GameGuruMAX/Max/Files/pinetree_RGB.dds" ); @@ -1595,6 +1665,9 @@ int GGTrees_SetData( float* data ) } else { +#ifdef ONLYLOADWHENUSED + bTreeTextureForceUploaded[type] = true; +#endif pInstance->SetType( type ); } } @@ -1623,12 +1696,18 @@ int GGTrees_SetData( float* data ) pInstance->SetFlags( oldFlags ); pInstance->SetScale( oldScale ); pInstance->SetType( newType ); +#ifdef ONLYLOADWHENUSED + bTreeTextureForceUploaded[newType] = true; +#endif } else { // this shouldn't happen MessageBoxA( NULL, "Unrecognised tree version, trees will be laid out in the default pattern", "Warning", 0 ); GGTrees_RepopulateInstances(); +#ifdef ONLYLOADWHENUSED + last_paint_tree_bitfield = -1; +#endif return 0; // version check } @@ -1650,7 +1729,9 @@ int GGTrees_SetData( float* data ) } } } - +#ifdef ONLYLOADWHENUSED + last_paint_tree_bitfield = -1; +#endif GGTrees_UpdateInstances( 1 ); return 1; } @@ -2192,6 +2273,14 @@ void GGTrees_Update( float camX, float camY, float camZ, CommandList cmd, bool b if ( !ggtrees_global_params.draw_enabled && ggtrees_global_params.hide_until_update == 0 ) return; +#ifdef ONLYLOADWHENUSED + if (last_paint_tree_bitfield != ggtrees_global_params.paint_tree_bitfield) + { + last_paint_tree_bitfield = ggtrees_global_params.paint_tree_bitfield; + GGTrees_LoadTextures(false); + } +#endif + if (ggtrees_global_params.hide_until_update) { // Trees are not drawn when choosing a new biome, so need check if we can draw them again. diff --git a/GameGuru Core/Guru-WickedMAX/master.cpp b/GameGuru Core/Guru-WickedMAX/master.cpp index b2ce7c85..6fe7541f 100644 --- a/GameGuru Core/Guru-WickedMAX/master.cpp +++ b/GameGuru Core/Guru-WickedMAX/master.cpp @@ -2285,6 +2285,10 @@ void MasterRenderer::Update(float dt) } wiProfiler::EndRange(range3); +#ifdef WICKEDPARTICLESYSTEM + WickedCall_UpdateEmitters(); +#endif + // now just prepared IMGUI, but actual render called from Wicked hook auto range2 = wiProfiler::BeginRangeCPU("Update - Render"); GuruLoopRender(); diff --git a/GameGuru Core/Guru-WickedMAX/wickedcalls.cpp b/GameGuru Core/Guru-WickedMAX/wickedcalls.cpp index 0aef1b46..2aa34b96 100644 --- a/GameGuru Core/Guru-WickedMAX/wickedcalls.cpp +++ b/GameGuru Core/Guru-WickedMAX/wickedcalls.cpp @@ -5016,6 +5016,20 @@ void WickedCall_SetObjectRenderLayer(sObject* pObject,int iLayerMask) } } + +bool Convert2Dto3D(long x , long y, float* pOutX, float* pOutY, float* pOutZ, float* pDirX, float* pDirY, float* pDirZ) +{ + //PE: Wicked Mouse is relative to windows pos. ImGui is relative to screen. + RAY pickRay = wiRenderer::GetPickRay((long)x, (long)y, master.masterrenderer); + *pOutX = pickRay.origin.x; + *pOutY = pickRay.origin.y; + *pOutZ = pickRay.origin.z; + *pDirX = pickRay.direction.x; + *pDirY = pickRay.direction.y; + *pDirZ = pickRay.direction.z; + return true; +} + float fLastTerrainHitX = 0, fLastTerrainHitY = 0, fLastTerrainHitZ = 0; bool WickedCall_GetPick2(float fMouseX, float fMouseY, float* pOutX, float* pOutY, float* pOutZ, float* pNormX, float* pNormY, float* pNormZ, uint64_t* pHitEntity, int iLayerMask) @@ -6853,4 +6867,387 @@ void WickedCall_CreateDecal(sObject* pObject) //} //} } -*/ \ No newline at end of file +*/ + +#ifdef WICKEDPARTICLESYSTEM +uint32_t WickedCall_LoadWiScene(char* filename, bool attached, char* changename, char* changenameto) +{ + Entity root = 0; + + XMMATRIX& transformMatrix = XMMatrixIdentity(); + Scene scene2; + wiArchive archive(filename, true); + if (archive.IsOpen()) + { + if (archive.IsReadMode()) + { + uint32_t reserved; + archive >> reserved; + } + else + { + uint32_t reserved = 0; + archive << reserved; + } + + //PE: Keeping this alive to keep serialized resources alive until entity serialization ends: + wiResourceManager::ResourceSerializer resource_seri; + if (archive.GetVersion() >= 63) + { + wiResourceManager::Serialize(archive, resource_seri); + } + + EntitySerializer seri; + + scene2.names.Serialize(archive, seri); + scene2.layers.Serialize(archive, seri); + scene2.transforms.Serialize(archive, seri); + scene2.prev_transforms.Serialize(archive, seri); + scene2.hierarchy.Serialize(archive, seri); + scene2.materials.Serialize(archive, seri); + scene2.meshes.Serialize(archive, seri); + scene2.impostors.Serialize(archive, seri); + scene2.objects.Serialize(archive, seri); + scene2.aabb_objects.Serialize(archive, seri); + scene2.rigidbodies.Serialize(archive, seri); + + scene2.softbodies.Serialize(archive, seri); + + scene2.armatures.Serialize(archive, seri); + scene2.lights.Serialize(archive, seri); + scene2.aabb_lights.Serialize(archive, seri); + scene2.cameras.Serialize(archive, seri); + scene2.probes.Serialize(archive, seri); + scene2.aabb_probes.Serialize(archive, seri); + scene2.forces.Serialize(archive, seri); + scene2.decals.Serialize(archive, seri); + scene2.aabb_decals.Serialize(archive, seri); + scene2.animations.Serialize(archive, seri); + scene2.emitters.Serialize(archive, seri); + scene2.hairs.Serialize(archive, seri); + scene2.weathers.Serialize(archive, seri); + if (archive.GetVersion() >= 30) + { + scene2.sounds.Serialize(archive, seri); + } + if (archive.GetVersion() >= 37) + { + scene2.inverse_kinematics.Serialize(archive, seri); + } + if (archive.GetVersion() >= 38) + { + scene2.springs.Serialize(archive, seri); + } + if (archive.GetVersion() >= 46) + { + scene2.animation_datas.Serialize(archive, seri); + } + + //PE: create new root: + root = CreateEntity(); + scene2.transforms.Create(root); + scene2.layers.Create(root).layerMask = ~0; + + //PE: Parent all unparented transforms to new root entity + for (size_t i = 0; i < scene2.transforms.GetCount() - 1; ++i) // GetCount() - 1 because the last added was the "root" + { + Entity entity = scene2.transforms.GetEntity(i); + if (!scene2.hierarchy.Contains(entity)) + { + scene2.Component_Attach(entity, root); + } + } + //PE: The root component is transformed, scene is updated: + scene2.transforms.GetComponent(root)->MatrixTransform(transformMatrix); + scene2.Update(0); + + if (!attached) + { + //PE: In this case, we don't care about the root anymore, so delete it. This will simplify overall hierarchy + scene2.Component_DetachChildren(root); + scene2.Entity_Remove(root); + root = INVALID_ENTITY; + } + } + + //PE: Fix for GG moved enums + if (pestrcasestr(filename, ".wiscene")) + { + for (int i = 0; i < scene2.materials.GetCount(); i++) + { + if (scene2.materials[i].userBlendMode == BLENDMODE_PREMULTIPLIED) + scene2.materials[i].userBlendMode = BLENDMODE_MULTIPLY; + if (scene2.materials[i].userBlendMode == BLENDMODE_ALPHA) + scene2.materials[i].userBlendMode = BLENDMODE_ADDITIVE; + if (scene2.materials[i].userBlendMode == BLENDMODE_FORCEDEPTH) + scene2.materials[i].userBlendMode = BLENDMODE_PREMULTIPLIED; + if (scene2.materials[i].userBlendMode == BLENDMODE_ALPHANOZ) + scene2.materials[i].userBlendMode = BLENDMODE_ALPHA; + scene2.materials[i].SetDirty(); + } + } + + if (changename && changenameto) + { + for (int i = 0; i < scene2.names.GetCount(); i++) + { + if (stricmp(scene2.names[i].name.c_str(), changename) == 0) + { + scene2.names[i].name = changenameto; + } + } + } + GetScene().Merge(scene2); + return root; +} + +//iAction = 1 Burst all. 2 = Pause. - 3 = Resume. - 4 = Restart +void WickedCall_PerformEmitterAction(int iAction, uint32_t emitter_root) +{ + + Scene& scene = wiScene::GetScene(); + + //PE: Scan emitters. + for (int i = 0; i < scene.emitters.GetCount(); i++) + { + Entity emitter = scene.emitters.GetEntity(i); + HierarchyComponent* hier = scene.hierarchy.GetComponent(emitter); + if (hier) + { + if (hier->parentID == emitter_root) + { + wiEmittedParticle* ec = scene.emitters.GetComponent(emitter); + switch (iAction) + { + case 1: + { + ec->Burst(0); + break; + } + case 2: + { + ec->SetPaused(true); + break; + } + case 3: + { + ec->SetPaused(false); + break; + } + case 4: + { + ec->Restart(); + break; + } + } + } + } + } + +} + +//#define WPEDebug +void WickedCall_UpdateEmitters(void) +{ + //PE: Scan emitters. + std::vector< uint32_t> parent_used; + parent_used.clear(); + Scene& scene = wiScene::GetScene(); + for (int i = 0; i < scene.emitters.GetCount(); i++) + { + Entity emitter = scene.emitters.GetEntity(i); + wiEmittedParticle* ec = scene.emitters.GetComponent(emitter); + +#ifdef WPEDebug + if (ec && ec->IsVolumeEnabled()) + { + XMFLOAT4X4 hoverBox; + wiScene::TransformComponent* pTransform = wiScene::GetScene().transforms.GetComponent(emitter); + if (pTransform) + { + if (1) + { + AABB aabb; + XMFLOAT3 pos = pTransform->GetPosition(); + //if (bIsUsingWidget && emitter_root != transform_entity) + //{ + // TransformComponent* root_tranform = scene.transforms.GetComponent(emitter_root); + // //PE: Need to add root here , as its not updated before next frame in wicked. + // if (root_tranform) + // { + // pos.x += root_tranform->GetPosition().x; + // pos.y += root_tranform->GetPosition().y; + // pos.z += root_tranform->GetPosition().z; + // } + //} + + XMFLOAT3 sca = pTransform->GetScale(); + aabb._min = XMFLOAT3(pos.x - sca.x, pos.y, pos.z - sca.z); + aabb._max = XMFLOAT3(pos.x + sca.x, pos.y + sca.y, pos.z + sca.z); + + XMStoreFloat4x4(&hoverBox, aabb.getAsBoxMatrix()); // *pTransform->GetLocalMatrix()); + XMVECTOR S, R, T; + XMMatrixDecompose(&S, &R, &T, XMLoadFloat4x4(&hoverBox)); + + //XMVECTOR R_local = XMLoadFloat4(&root_tranform->rotation_local); + XMVECTOR R_local = XMLoadFloat4(&pTransform->rotation_local); + XMStoreFloat4x4(&hoverBox, + XMMatrixScalingFromVector(S) * + XMMatrixRotationQuaternion(R_local) * + XMMatrixTranslationFromVector(T)); + + wiRenderer::DrawBox(hoverBox, XMFLOAT4(1.0f, 1.0f, 0.0f, 1.0f)); + } + } + } +#endif + + //PE: If bFollowCamera , find InDoor , OutDoor , UnderWater. + //PE: bFindFloor ONLY if ec->bFollowCamera + if (ec && (ec->bFindFloor || ec->bFollowCamera)) + { + HierarchyComponent* hier = scene.hierarchy.GetComponent(emitter); + if (hier) + { + if (hier->parentID != wiECS::INVALID_ENTITY) + { + bool bAlreadySet = false; + for (int a = 0; a > parent_used.size(); a++) + { + if (parent_used[a] == hier->parentID) + { + bAlreadySet = true; + break; + } + } + if (!bAlreadySet) + { + parent_used.push_back(hier->parentID); + TransformComponent* root_tranform = scene.transforms.GetComponent(hier->parentID); + if (root_tranform) + { + + if (ec->bFollowCamera) + { + float fX, fY, fZ; + //float PlayerHeight = 62.0f; + fX = CameraPositionX(); + //PE: PlayerHeight might have to be removed in GGM + fY = CameraPositionY(); // -PlayerHeight; + fZ = CameraPositionZ(); + root_tranform->ClearTransform(); + root_tranform->Translate(XMFLOAT3(fX, fY, fZ)); + root_tranform->UpdateTransform(); + } + if (ec->bFindFloor && ec->bFollowCamera) + { + float fX = root_tranform->GetPosition().x; + float fZ = root_tranform->GetPosition().z; + float height = BT_GetGroundHeight(t.terrain.TerrainID, CameraPositionX(), CameraPositionZ()); + root_tranform->ClearTransform(); + root_tranform->Translate(XMFLOAT3(fX, height, fZ)); + root_tranform->UpdateTransform(); + } + } + } + } + } + } + } +} + +uint32_t WickedCall_CreateEmitter(std::string& name, float posX, float posY, float posZ, uint32_t proot) +{ + XMFLOAT3 position = { posX , posY, posZ }; + + //wiScene::Scene& scene = wiScene::GetScene(); + Scene scene; + XMMATRIX& transformMatrix = XMMatrixIdentity(); + + //PE: Create emitter. + Entity entity = CreateEntity(); + + scene.names.Create(entity) = name; + scene.emitters.Create(entity).count = 10; + + wiEmittedParticle* ec; + ec = scene.emitters.GetComponent(entity); + ec->count = 40; + ec->life = 2.5f; + ec->size = 2; + //ec->random_color = 1.0f; + ec->gravity = XMFLOAT3(0, 9, 0); + + TransformComponent& transform = scene.transforms.Create(entity); + transform.ClearTransform(); + transform.Translate(position); + transform.Scale(XMFLOAT3(3, 1, 3)); + transform.UpdateTransform(); + + scene.materials.Create(entity).userBlendMode = BLENDMODE_ADDITIVE; // BLENDMODE_ALPHA; + + //PE: Create root. + Entity root; + bool bUsePrevRoot = false; + if (proot > 0) + { + root = proot; + bUsePrevRoot = true; + } + else + { + root = CreateEntity(); + scene.transforms.Create(root); + scene.layers.Create(root).layerMask = ~0; + //emitter_root = root; + } + + if (!bUsePrevRoot) + { + //PE: Parent all unparented transforms to new root entity + for (size_t i = 0; i < scene.transforms.GetCount() - 1; ++i) // GetCount() - 1 because the last added was the "root" + { + Entity entity = scene.transforms.GetEntity(i); + if (!scene.hierarchy.Contains(entity)) + { + scene.Component_Attach(entity, root); + } + } + //PE: The root component is transformed, scene is updated: + scene.transforms.GetComponent(root)->MatrixTransform(transformMatrix); + scene.Update(0); + } + GetScene().Merge(scene); + + //PE: Find name; + wiScene::Scene& sceneR = wiScene::GetScene(); + + for (int i = 0; i < sceneR.emitters.GetCount(); i++) + { + + Entity emitter = sceneR.emitters.GetEntity(i); + Entity text = sceneR.names.GetIndex(emitter); + if (text > 0) + { + if (sceneR.names[text].name == name) + { + entity = emitter; + break; + } + } + } + + if (bUsePrevRoot) + { + sceneR.Component_Attach(entity, root); + wiScene::TransformComponent* pTransform = wiScene::GetScene().transforms.GetComponent(entity); + pTransform->ClearTransform(); + pTransform->Translate(position); + pTransform->UpdateTransform(); + } + + return entity; +} + +#endif + diff --git a/GameGuru Core/Guru-WickedMAX/wickedcalls.h b/GameGuru Core/Guru-WickedMAX/wickedcalls.h index 8d5cd3a4..84654df0 100644 --- a/GameGuru Core/Guru-WickedMAX/wickedcalls.h +++ b/GameGuru Core/Guru-WickedMAX/wickedcalls.h @@ -126,6 +126,7 @@ void WickedCall_SetBip01Position(sObject* pObject, sFrame* pFrame, int iUseMode, void WickedCall_SetBip01Rotation(sObject* pObject, sFrame* pFrame, int iUseMode, float fY); void WickedCall_SetObjectPreFrames(sObject* pObject, LPSTR pParentFrameName, float fFrameToUse, float fSmoothSlerpToNextShape, int iPreFrameMode); void WickedCall_SetObjectRenderLayer ( sObject* pObject, int iLayerMask ); +bool Convert2Dto3D(long x, long y, float* pOutX, float* pOutY, float* pOutZ, float* pDirX, float* pDirY, float* pDirZ); bool WickedCall_GetPick2(float fMouseX, float fMouseY, float* pOutX, float* pOutY, float* pOutZ, float* pNormX, float* pNormY, float* pNormZ, uint64_t* pHitEntity, int iLayerMask); bool WickedCall_GetPick ( float* pOutX, float* pOutY, float* pOutZ, float* pNormalX, float* pNormalY, float* pNormalZ, uint64_t* pObject, int iLayerMask ); bool WickedCall_SentRay(float originx, float originy, float originz, float directionx, float directiony, float directionz, float* pOutX, float* pOutY, float* pOutZ, float* pNormX, float* pNormY, float* pNormZ, uint64_t* pHitEntity, int iLayerMask); @@ -213,3 +214,9 @@ void WickedCall_RemoveObjectTextures(sObject* pObject); void WickedCall_SetExposure(float exposure); void WickedCall_CreateDecal(sObject* pObject); + +uint32_t WickedCall_LoadWiScene(char* filename, bool attached, char* changename, char* changenameto); +void WickedCall_PerformEmitterAction(int iAction, uint32_t emitter_root); +void WickedCall_UpdateEmitters(void); +uint32_t WickedCall_CreateEmitter(std::string& name, float posX, float posY, float posZ, uint32_t proot); +