From f04d4c03d9afa41d9670fcfd58e7e50e9fed12d6 Mon Sep 17 00:00:00 2001 From: Areloch Date: Mon, 4 Mar 2019 22:07:55 -0600 Subject: [PATCH] Cleanup and minor tweaks to the core dir structure. --- Templates/BaseGame/game/core/Core.cs | 60 +-- Templates/BaseGame/game/core/Core.module | 13 +- .../scripts/client/connectionToServer.cs | 2 +- .../actionAnimationComponent.asset.taml | 8 + .../aiControllerComponent.asset.taml | 8 + .../armAnimationComponent.asset.taml | 8 + .../components/game/controlObject.cs | 89 --- .../game/core/utility/Core_Utility.cs | 2 + .../utility/scripts/gameObjectManagement.cs | 181 +++++++ .../game/core/utility/scripts/globals.cs | 3 - .../core/utility/scripts/helperFunctions.cs | 510 +----------------- .../utility/scripts/persistanceManagement.cs | 315 +++++++++++ 12 files changed, 539 insertions(+), 660 deletions(-) create mode 100644 Templates/BaseGame/game/core/components/components/actionAnimationComponent.asset.taml create mode 100644 Templates/BaseGame/game/core/components/components/aiControllerComponent.asset.taml create mode 100644 Templates/BaseGame/game/core/components/components/armAnimationComponent.asset.taml delete mode 100644 Templates/BaseGame/game/core/components/components/game/controlObject.cs create mode 100644 Templates/BaseGame/game/core/utility/scripts/gameObjectManagement.cs create mode 100644 Templates/BaseGame/game/core/utility/scripts/persistanceManagement.cs diff --git a/Templates/BaseGame/game/core/Core.cs b/Templates/BaseGame/game/core/Core.cs index 5559760ae..99efdd706 100644 --- a/Templates/BaseGame/game/core/Core.cs +++ b/Templates/BaseGame/game/core/Core.cs @@ -20,10 +20,11 @@ function CoreModule::onCreate(%this) ModuleDatabase.LoadExplicit( "Core_Rendering" ); ModuleDatabase.LoadExplicit( "Core_Utility" ); ModuleDatabase.LoadExplicit( "Core_GUI" ); - ModuleDatabase.LoadExplicit( "CoreModule" ); ModuleDatabase.LoadExplicit( "Core_Lighting" ); ModuleDatabase.LoadExplicit( "Core_SFX" ); ModuleDatabase.LoadExplicit( "Core_PostFX" ); + ModuleDatabase.LoadExplicit( "Core_Components" ); + ModuleDatabase.LoadExplicit( "Core_GameObjects" ); ModuleDatabase.LoadExplicit( "Core_ClientServer" ); %prefPath = getPrefpath(); @@ -32,63 +33,6 @@ function CoreModule::onCreate(%this) else exec("data/defaults.cs"); - %der = $pref::Video::displayDevice; - - //We need to hook the missing/warn material stuff early, so do it here - /*$Core::MissingTexturePath = "core/images/missingTexture"; - $Core::UnAvailableTexturePath = "core/images/unavailable"; - $Core::WarningTexturePath = "core/images/warnMat"; - $Core::CommonShaderPath = "core/shaders"; - - /*%classList = enumerateConsoleClasses( "Component" ); - - foreach$( %componentClass in %classList ) - { - echo("Native Component of type: " @ %componentClass); - }*/ - - //exec("./helperFunctions.cs"); - - // We need some of the default GUI profiles in order to get the canvas and - // other aspects of the GUI system ready. - //exec("./profiles.cs"); - - //This is a bit of a shortcut, but we'll load the client's default settings to ensure all the prefs get initialized correctly - - - // Initialization of the various subsystems requires some of the preferences - // to be loaded... so do that first. - /*exec("./globals.cs"); - - exec("./canvas.cs"); - exec("./cursor.cs"); - - exec("./renderManager.cs"); - exec("./lighting.cs"); - - exec("./audio.cs"); - exec("./sfx/audioAmbience.cs"); - exec("./sfx/audioData.cs"); - exec("./sfx/audioDescriptions.cs"); - exec("./sfx/audioEnvironments.cs"); - exec("./sfx/audioStates.cs"); - - exec("./parseArgs.cs"); - - // Materials and Shaders for rendering various object types - exec("./gfxData/commonMaterialData.cs"); - exec("./gfxData/shaders.cs"); - exec("./gfxData/terrainBlock.cs"); - exec("./gfxData/water.cs"); - exec("./gfxData/scatterSky.cs"); - exec("./gfxData/clouds.cs"); - - // Initialize all core post effects. - exec("./postFx.cs"); - - //VR stuff - exec("./oculusVR.cs");*/ - // Seed the random number generator. setRandomSeed(); diff --git a/Templates/BaseGame/game/core/Core.module b/Templates/BaseGame/game/core/Core.module index c7ab7b64b..b9a2490e3 100644 --- a/Templates/BaseGame/game/core/Core.module +++ b/Templates/BaseGame/game/core/Core.module @@ -5,15 +5,4 @@ ScriptFile="Core.cs" CreateFunction="onCreate" DestroyFunction="onDestroy" - Group="Core"> - - - \ No newline at end of file + Group="Core"/> \ No newline at end of file diff --git a/Templates/BaseGame/game/core/clientServer/scripts/client/connectionToServer.cs b/Templates/BaseGame/game/core/clientServer/scripts/client/connectionToServer.cs index 693c7fff7..11df6afd6 100644 --- a/Templates/BaseGame/game/core/clientServer/scripts/client/connectionToServer.cs +++ b/Templates/BaseGame/game/core/clientServer/scripts/client/connectionToServer.cs @@ -43,7 +43,7 @@ function GameConnection::initialControlSet(%this) // first check if the editor is active if (!isToolBuild() || !isMethod("Editor", "checkActiveLoadDone") || !Editor::checkActiveLoadDone()) { - if (Canvas.getContent() != PlayGui.getId()) + if (isObject(PlayGui) && Canvas.getContent() != PlayGui.getId()) Canvas.setContent(PlayGui); } } diff --git a/Templates/BaseGame/game/core/components/components/actionAnimationComponent.asset.taml b/Templates/BaseGame/game/core/components/components/actionAnimationComponent.asset.taml new file mode 100644 index 000000000..36d5b9a90 --- /dev/null +++ b/Templates/BaseGame/game/core/components/components/actionAnimationComponent.asset.taml @@ -0,0 +1,8 @@ + diff --git a/Templates/BaseGame/game/core/components/components/aiControllerComponent.asset.taml b/Templates/BaseGame/game/core/components/components/aiControllerComponent.asset.taml new file mode 100644 index 000000000..0111cd999 --- /dev/null +++ b/Templates/BaseGame/game/core/components/components/aiControllerComponent.asset.taml @@ -0,0 +1,8 @@ + diff --git a/Templates/BaseGame/game/core/components/components/armAnimationComponent.asset.taml b/Templates/BaseGame/game/core/components/components/armAnimationComponent.asset.taml new file mode 100644 index 000000000..d9fd4ef80 --- /dev/null +++ b/Templates/BaseGame/game/core/components/components/armAnimationComponent.asset.taml @@ -0,0 +1,8 @@ + diff --git a/Templates/BaseGame/game/core/components/components/game/controlObject.cs b/Templates/BaseGame/game/core/components/components/game/controlObject.cs deleted file mode 100644 index 7f477ecca..000000000 --- a/Templates/BaseGame/game/core/components/components/game/controlObject.cs +++ /dev/null @@ -1,89 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (c) 2012 GarageGames, LLC -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//----------------------------------------------------------------------------- - -//registerComponent("ControlObjectComponent", "Component", "Control Object", "Game", false, "Allows the behavior owner to operate as a camera."); - -function ControlObjectComponent::onAdd(%this) -{ - %this.addComponentField(clientOwner, "The shape to use for rendering", "int", "1", ""); - - %clientID = %this.getClientID(); - - if(%clientID && !isObject(%clientID.getControlObject())) - %clientID.setControlObject(%this.owner); -} - -function ControlObjectComponent::onRemove(%this) -{ - %clientID = %this.getClientID(); - - if(%clientID) - %clientID.setControlObject(0); -} - -function ControlObjectComponent::onClientConnect(%this, %client) -{ - if(%this.isControlClient(%client) && !isObject(%client.getControlObject())) - %client.setControlObject(%this.owner); -} - -function ControlObjectComponent::onClientDisconnect(%this, %client) -{ - if(%this.isControlClient(%client)) - %client.setControlObject(0); -} - -function ControlObjectComponent::getClientID(%this) -{ - return ClientGroup.getObject(%this.clientOwner-1); -} - -function ControlObjectComponent::isControlClient(%this, %client) -{ - %clientID = ClientGroup.getObject(%this.clientOwner-1); - - if(%client.getID() == %clientID) - return true; - else - return false; -} - -function ControlObjectComponent::onInspectorUpdate(%this, %field) -{ - %clientID = %this.getClientID(); - - if(%clientID && !isObject(%clientID.getControlObject())) - %clientID.setControlObject(%this.owner); -} - -function switchControlObject(%client, %newControlEntity) -{ - if(!isObject(%client) || !isObject(%newControlEntity)) - return error("SwitchControlObject: No client or target controller!"); - - %control = %newControlEntity.getComponent(ControlObjectComponent); - - if(!isObject(%control)) - return error("SwitchControlObject: Target controller has no conrol object behavior!"); - - %client.setControlObject(%newControlEntity); -} \ No newline at end of file diff --git a/Templates/BaseGame/game/core/utility/Core_Utility.cs b/Templates/BaseGame/game/core/utility/Core_Utility.cs index d412f3544..e38d474d5 100644 --- a/Templates/BaseGame/game/core/utility/Core_Utility.cs +++ b/Templates/BaseGame/game/core/utility/Core_Utility.cs @@ -4,6 +4,8 @@ function Core_Utility::onCreate(%this) exec("./scripts/parseArgs.cs"); exec("./scripts/globals.cs"); exec("./scripts/helperFunctions.cs"); + exec("./scripts/gameObjectManagement.cs"); + exec("./scripts/persistanceManagement.cs"); } function Core_Utility::onDestroy(%this) diff --git a/Templates/BaseGame/game/core/utility/scripts/gameObjectManagement.cs b/Templates/BaseGame/game/core/utility/scripts/gameObjectManagement.cs new file mode 100644 index 000000000..f496111eb --- /dev/null +++ b/Templates/BaseGame/game/core/utility/scripts/gameObjectManagement.cs @@ -0,0 +1,181 @@ + +//Game Object management +function findGameObject(%name) +{ + //find all GameObjectAssets + %assetQuery = new AssetQuery(); + if(!AssetDatabase.findAssetType(%assetQuery, "GameObjectAsset")) + return 0; //if we didn't find ANY, just exit + + %count = %assetQuery.getCount(); + + for(%i=0; %i < %count; %i++) + { + %assetId = %assetQuery.getAsset(%i); + + //%assetName = AssetDatabase.getAssetName(%assetId); + + if(%assetId $= %name) + { + %gameObjectAsset = AssetDatabase.acquireAsset(%assetId); + + %assetQuery.delete(); + return %gameObjectAsset; + } + } + + %assetQuery.delete(); + return 0; +} + +function spawnGameObject(%name, %addToScene) +{ + if(%addToScene $= "") + %addToScene = true; + + //First, check if this already exists in our GameObjectPool + if(isObject(GameObjectPool)) + { + %goCount = GameObjectPool.countKey(%name); + + //if we have some already in the pool, pull it out and use that + if(%goCount != 0) + { + %goIdx = GameObjectPool.getIndexFromKey(%name); + %go = GameObjectPool.getValue(%goIdx); + + %go.setHidden(false); + %go.setScopeAlways(); + + if(%addToMissionGroup == true) //save instance when saving level + getScene(0).add(%go); + else // clear instance on level exit + MissionCleanup.add(%go); + + //remove from the object pool's list + GameObjectPool.erase(%goIdx); + + return %go; + } + } + + //We have no existing pool, or no existing game objects of this type, so spawn a new one + + %gameObjectAsset = findGameObject(%name); + + if(isObject(%gameObjectAsset)) + { + %newSGOObject = TamlRead(%gameObjectAsset.TAMLFilePath); + + if(%addToScene == true) //save instance when saving level + getScene(0).add(%newSGOObject); + else // clear instance on level exit + MissionCleanup.add(%newSGOObject); + + return %newSGOObject; + } + + return 0; +} + +function saveGameObject(%name, %tamlPath, %scriptPath) +{ + %gameObjectAsset = findGameObject(%name); + + //find if it already exists. If it does, we'll update it, if it does not, we'll make a new asset + if(isObject(%gameObjectAsset)) + { + %assetID = %gameObjectAsset.getAssetId(); + + %gameObjectAsset.TAMLFilePath = %tamlPath; + %gameObjectAsset.scriptFilePath = %scriptPath; + + TAMLWrite(%gameObjectAsset, AssetDatabase.getAssetFilePath(%assetID)); + AssetDatabase.refreshAsset(%assetID); + } + else + { + //Doesn't exist, so make a new one + %gameObjectAsset = new GameObjectAsset() + { + assetName = %name @ "Asset"; + gameObjectName = %name; + TAMLFilePath = %tamlPath; + scriptFilePath = %scriptPath; + }; + + //Save it alongside the taml file + %path = filePath(%tamlPath); + + TAMLWrite(%gameObjectAsset, %path @ "/" @ %name @ ".asset.taml"); + AssetDatabase.refreshAllAssets(true); + } +} + +//Allocates a number of a game object into a pool to be pulled from as needed +function allocateGameObjects(%name, %amount) +{ + //First, we need to make sure our pool exists + if(!isObject(GameObjectPool)) + { + new ArrayObject(GameObjectPool); + } + + //Next, we loop and generate our game objects, and add them to the pool + for(%i=0; %i < %amount; %i++) + { + %go = spawnGameObject(%name, false); + + //When our object is in the pool, it's not "real", so we need to make sure + //that we don't ghost it to clients untill we actually spawn it. + %go.clearScopeAlways(); + + //We also hide it, so that we don't 'exist' in the scene until we spawn + %go.hidden = true; + + //Lastly, add us to the pool, with the key being our game object type + GameObjectPool.add(%name, %go); + } +} + +function Entity::delete(%this) +{ + //we want to intercept the delete call, and add it to our GameObjectPool + //if it's a game object + if(%this.gameObjectAsset !$= "") + { + %this.setHidden(true); + %this.clearScopeAlways(); + + if(!isObject(GameObjectPool)) + { + new ArrayObject(GameObjectPool); + } + + GameObjectPool.add(%this.gameObjectAsset, %this); + + %missionSet = %this.getGroup(); + %missionSet.remove(%this); + } + else + { + %this.superClass.delete(); + } +} + +function clearGameObjectPool() +{ + if(isObject(GameObjectPool)) + { + %count = GameObjectPool.count(); + + for(%i=0; %i < %count; %i++) + { + %go = GameObjectPool.getValue(%i); + + %go.superClass.delete(); + } + + GameObjectPool.empty(); + } +} \ No newline at end of file diff --git a/Templates/BaseGame/game/core/utility/scripts/globals.cs b/Templates/BaseGame/game/core/utility/scripts/globals.cs index fcf52390a..adb035fdc 100644 --- a/Templates/BaseGame/game/core/utility/scripts/globals.cs +++ b/Templates/BaseGame/game/core/utility/scripts/globals.cs @@ -36,9 +36,6 @@ $pref::Input::JoystickEnabled = 0; // Set directory paths for various data or default images. $pref::Video::ProfilePath = "core/rendering/scripts/gfxprofile"; -/*$pref::Video::missingTexturePath = "core/images/missingTexture.png"; -$pref::Video::unavailableTexturePath = "core/images/unavailable.png"; -$pref::Video::warningTexturePath = "core/images/warnMat.dds";*/ $pref::Video::disableVerticalSync = 1; $pref::Video::mode = "800 600 false 32 60 4"; diff --git a/Templates/BaseGame/game/core/utility/scripts/helperFunctions.cs b/Templates/BaseGame/game/core/utility/scripts/helperFunctions.cs index 8abe3e6e6..d620d08b1 100644 --- a/Templates/BaseGame/game/core/utility/scripts/helperFunctions.cs +++ b/Templates/BaseGame/game/core/utility/scripts/helperFunctions.cs @@ -636,503 +636,6 @@ function mvReset() // There are others. } -//Persistance Manager tests - -new PersistenceManager(TestPManager); - -function runPManTest(%test) -{ - if (!isObject(TestPManager)) - return; - - if (%test $= "") - %test = 100; - - switch(%test) - { - case 0: - TestPManager.testFieldUpdates(); - case 1: - TestPManager.testObjectRename(); - case 2: - TestPManager.testNewObject(); - case 3: - TestPManager.testNewGroup(); - case 4: - TestPManager.testMoveObject(); - case 5: - TestPManager.testObjectRemove(); - case 100: - TestPManager.testFieldUpdates(); - TestPManager.testObjectRename(); - TestPManager.testNewObject(); - TestPManager.testNewGroup(); - TestPManager.testMoveObject(); - TestPManager.testObjectRemove(); - } -} - -function TestPManager::testFieldUpdates(%doNotSave) -{ - // Set some objects as dirty - TestPManager.setDirty(AudioGui); - TestPManager.setDirty(AudioSim); - TestPManager.setDirty(AudioMessage); - - // Alter some of the existing fields - AudioEffect.isLooping = true; - AudioMessage.isLooping = true; - AudioEffect.is3D = true; - - // Test removing a field - TestPManager.removeField(AudioGui, "isLooping"); - - // Alter some of the persistent fields - AudioGui.referenceDistance = 0.8; - AudioMessage.referenceDistance = 0.8; - - // Add some new dynamic fields - AudioGui.foo = "bar"; - AudioEffect.foo = "bar"; - - // Remove an object from the dirty list - // It shouldn't get updated in the file - TestPManager.removeDirty(AudioEffect); - - // Dirty an object in another file as well - TestPManager.setDirty(WarningMaterial); - - // Update a field that doesn't exist - WarningMaterial.glow[0] = true; - - // Drity another object to test for crashes - // when a dirty object is deleted - TestPManager.setDirty(SFXPausedSet); - - // Delete the object - SFXPausedSet.delete(); - - // Unless %doNotSave is set (by a batch/combo test) - // then go ahead and save now - if (!%doNotSave) - TestPManager.saveDirty(); -} - -function TestPManager::testObjectRename(%doNotSave) -{ - // Flag an object as dirty - if (isObject(AudioGui)) - TestPManager.setDirty(AudioGui); - else if (isObject(AudioGuiFoo)) - TestPManager.setDirty(AudioGuiFoo); - - // Rename it - if (isObject(AudioGui)) - AudioGui.setName(AudioGuiFoo); - else if (isObject(AudioGuiFoo)) - AudioGuiFoo.setName(AudioGui); - - // Unless %doNotSave is set (by a batch/combo test) - // then go ahead and save now - if (!%doNotSave) - TestPManager.saveDirty(); -} - -function TestPManager::testNewObject(%doNotSave) -{ - // Test adding a new named object - new SFXDescription(AudioNew) - { - volume = 0.5; - isLooping = true; - channel = $GuiAudioType; - foo = 2; - }; - - // Flag it as dirty - TestPManager.setDirty(AudioNew, "core/scripts/client/audio.cs"); - - // Test adding a new unnamed object - %obj = new SFXDescription() - { - volume = 0.75; - isLooping = true; - bar = 3; - }; - - // Flag it as dirty - TestPManager.setDirty(%obj, "core/scripts/client/audio.cs"); - - // Test adding an "empty" object - new SFXDescription(AudioEmpty); - - TestPManager.setDirty(AudioEmpty, "core/scripts/client/audio.cs"); - - // Unless %doNotSave is set (by a batch/combo test) - // then go ahead and save now - if (!%doNotSave) - TestPManager.saveDirty(); -} - -function TestPManager::testNewGroup(%doNotSave) -{ - // Test adding a new named SimGroup - new SimGroup(TestGroup) - { - foo = "bar"; - - new SFXDescription(TestObject) - { - volume = 0.5; - isLooping = true; - channel = $GuiAudioType; - foo = 1; - }; - new SimGroup(SubGroup) - { - foo = 2; - - new SFXDescription(SubObject) - { - volume = 0.5; - isLooping = true; - channel = $GuiAudioType; - foo = 3; - }; - }; - }; - - // Flag this as dirty - TestPManager.setDirty(TestGroup, "core/scripts/client/audio.cs"); - - // Test adding a new unnamed SimGroup - %group = new SimGroup() - { - foo = "bar"; - - new SFXDescription() - { - volume = 0.75; - channel = $GuiAudioType; - foo = 4; - }; - new SimGroup() - { - foo = 5; - - new SFXDescription() - { - volume = 0.75; - isLooping = true; - channel = $GuiAudioType; - foo = 6; - }; - }; - }; - - // Flag this as dirty - TestPManager.setDirty(%group, "core/scripts/client/audio.cs"); - - // Test adding a new unnamed SimSet - %set = new SimSet() - { - foo = "bar"; - - new SFXDescription() - { - volume = 0.75; - channel = $GuiAudioType; - foo = 7; - }; - new SimGroup() - { - foo = 8; - - new SFXDescription() - { - volume = 0.75; - isLooping = true; - channel = $GuiAudioType; - foo = 9; - }; - }; - }; - - // Flag this as dirty - TestPManager.setDirty(%set, "core/scripts/client/audio.cs"); - - // Unless %doNotSave is set (by a batch/combo test) - // then go ahead and save now - if (!%doNotSave) - TestPManager.saveDirty(); -} - -function TestPManager::testMoveObject(%doNotSave) -{ - // First add a couple of groups to the file - new SimGroup(MoveGroup1) - { - foo = "bar"; - - new SFXDescription(MoveObject1) - { - volume = 0.5; - isLooping = true; - channel = $GuiAudioType; - foo = 1; - }; - - new SimSet(SubGroup1) - { - new SFXDescription(SubObject1) - { - volume = 0.75; - isLooping = true; - channel = $GuiAudioType; - foo = 2; - }; - }; - }; - - // Flag this as dirty - TestPManager.setDirty(MoveGroup1, "core/scripts/client/audio.cs"); - - new SimGroup(MoveGroup2) - { - foo = "bar"; - - new SFXDescription(MoveObject2) - { - volume = 0.5; - isLooping = true; - channel = $GuiAudioType; - foo = 3; - }; - }; - - // Flag this as dirty - TestPManager.setDirty(MoveGroup2, "core/scripts/client/audio.cs"); - - // Unless %doNotSave is set (by a batch/combo test) - // then go ahead and save now - if (!%doNotSave) - TestPManager.saveDirty(); - - // Set them as dirty again - TestPManager.setDirty(MoveGroup1); - TestPManager.setDirty(MoveGroup2); - - // Give the subobject an new value - MoveObject1.foo = 4; - - // Move it into the other group - MoveGroup1.add(MoveObject2); - - // Switch the other subobject - MoveGroup2.add(MoveObject1); - - // Also add a new unnamed object to one of the groups - %obj = new SFXDescription() - { - volume = 0.75; - isLooping = true; - bar = 5; - }; - - MoveGroup1.add(%obj); - - // Unless %doNotSave is set (by a batch/combo test) - // then go ahead and save now - if (!%doNotSave) - TestPManager.saveDirty(); -} - -function TestPManager::testObjectRemove(%doNotSave) -{ - TestPManager.removeObjectFromFile(AudioSim); -} - -//Game Object management -function findGameObject(%name) -{ - //find all GameObjectAssets - %assetQuery = new AssetQuery(); - if(!AssetDatabase.findAssetType(%assetQuery, "GameObjectAsset")) - return 0; //if we didn't find ANY, just exit - - %count = %assetQuery.getCount(); - - for(%i=0; %i < %count; %i++) - { - %assetId = %assetQuery.getAsset(%i); - - //%assetName = AssetDatabase.getAssetName(%assetId); - - if(%assetId $= %name) - { - %gameObjectAsset = AssetDatabase.acquireAsset(%assetId); - - %assetQuery.delete(); - return %gameObjectAsset; - } - } - - %assetQuery.delete(); - return 0; -} - -function spawnGameObject(%name, %addToMissionGroup) -{ - if(%addToMissionGroup $= "") - %addToMissionGroup = true; - - //First, check if this already exists in our GameObjectPool - if(isObject(GameObjectPool)) - { - %goCount = GameObjectPool.countKey(%name); - - //if we have some already in the pool, pull it out and use that - if(%goCount != 0) - { - %goIdx = GameObjectPool.getIndexFromKey(%name); - %go = GameObjectPool.getValue(%goIdx); - - %go.setHidden(false); - %go.setScopeAlways(); - - if(%addToMissionGroup == true) //save instance when saving level - MissionGroup.add(%go); - else // clear instance on level exit - MissionCleanup.add(%go); - - //remove from the object pool's list - GameObjectPool.erase(%goIdx); - - return %go; - } - } - - //We have no existing pool, or no existing game objects of this type, so spawn a new one - - %gameObjectAsset = findGameObject(%name); - - if(isObject(%gameObjectAsset)) - { - %newSGOObject = TamlRead(%gameObjectAsset.TAMLFilePath); - - if(%addToMissionGroup == true) //save instance when saving level - MissionGroup.add(%newSGOObject); - else // clear instance on level exit - MissionCleanup.add(%newSGOObject); - - return %newSGOObject; - } - - return 0; -} - -function saveGameObject(%name, %tamlPath, %scriptPath) -{ - %gameObjectAsset = findGameObject(%name); - - //find if it already exists. If it does, we'll update it, if it does not, we'll make a new asset - if(isObject(%gameObjectAsset)) - { - %assetID = %gameObjectAsset.getAssetId(); - - %gameObjectAsset.TAMLFilePath = %tamlPath; - %gameObjectAsset.scriptFilePath = %scriptPath; - - TAMLWrite(%gameObjectAsset, AssetDatabase.getAssetFilePath(%assetID)); - AssetDatabase.refreshAsset(%assetID); - } - else - { - //Doesn't exist, so make a new one - %gameObjectAsset = new GameObjectAsset() - { - assetName = %name @ "Asset"; - gameObjectName = %name; - TAMLFilePath = %tamlPath; - scriptFilePath = %scriptPath; - }; - - //Save it alongside the taml file - %path = filePath(%tamlPath); - - TAMLWrite(%gameObjectAsset, %path @ "/" @ %name @ ".asset.taml"); - AssetDatabase.refreshAllAssets(true); - } -} - -//Allocates a number of a game object into a pool to be pulled from as needed -function allocateGameObjects(%name, %amount) -{ - //First, we need to make sure our pool exists - if(!isObject(GameObjectPool)) - { - new ArrayObject(GameObjectPool); - } - - //Next, we loop and generate our game objects, and add them to the pool - for(%i=0; %i < %amount; %i++) - { - %go = spawnGameObject(%name, false); - - //When our object is in the pool, it's not "real", so we need to make sure - //that we don't ghost it to clients untill we actually spawn it. - %go.clearScopeAlways(); - - //We also hide it, so that we don't 'exist' in the scene until we spawn - %go.hidden = true; - - //Lastly, add us to the pool, with the key being our game object type - GameObjectPool.add(%name, %go); - } -} - -function Entity::delete(%this) -{ - //we want to intercept the delete call, and add it to our GameObjectPool - //if it's a game object - if(%this.gameObjectAsset !$= "") - { - %this.setHidden(true); - %this.clearScopeAlways(); - - if(!isObject(GameObjectPool)) - { - new ArrayObject(GameObjectPool); - } - - GameObjectPool.add(%this.gameObjectAsset, %this); - - %missionSet = %this.getGroup(); - %missionSet.remove(%this); - } - else - { - %this.superClass.delete(); - } -} - -function clearGameObjectPool() -{ - if(isObject(GameObjectPool)) - { - %count = GameObjectPool.count(); - - for(%i=0; %i < %count; %i++) - { - %go = GameObjectPool.getValue(%i); - - %go.superClass.delete(); - } - - GameObjectPool.empty(); - } -} - // function switchCamera(%client, %newCamEntity) { @@ -1155,4 +658,17 @@ function switchCamera(%client, %newCamEntity) %client.setControlCameraFov(%cam.FOV); %client.camera = %newCamEntity; +} + +function switchControlObject(%client, %newControlEntity) +{ + if(!isObject(%client) || !isObject(%newControlEntity)) + return error("SwitchControlObject: No client or target controller!"); + + %control = %newControlEntity.getComponent(ControlObjectComponent); + + if(!isObject(%control)) + return error("SwitchControlObject: Target controller has no conrol object behavior!"); + + %control.setConnectionControlObject(%client); } \ No newline at end of file diff --git a/Templates/BaseGame/game/core/utility/scripts/persistanceManagement.cs b/Templates/BaseGame/game/core/utility/scripts/persistanceManagement.cs new file mode 100644 index 000000000..aab054161 --- /dev/null +++ b/Templates/BaseGame/game/core/utility/scripts/persistanceManagement.cs @@ -0,0 +1,315 @@ +//Persistance Manager tests + +new PersistenceManager(TestPManager); + +function runPManTest(%test) +{ + if (!isObject(TestPManager)) + return; + + if (%test $= "") + %test = 100; + + switch(%test) + { + case 0: + TestPManager.testFieldUpdates(); + case 1: + TestPManager.testObjectRename(); + case 2: + TestPManager.testNewObject(); + case 3: + TestPManager.testNewGroup(); + case 4: + TestPManager.testMoveObject(); + case 5: + TestPManager.testObjectRemove(); + case 100: + TestPManager.testFieldUpdates(); + TestPManager.testObjectRename(); + TestPManager.testNewObject(); + TestPManager.testNewGroup(); + TestPManager.testMoveObject(); + TestPManager.testObjectRemove(); + } +} + +function TestPManager::testFieldUpdates(%doNotSave) +{ + // Set some objects as dirty + TestPManager.setDirty(AudioGui); + TestPManager.setDirty(AudioSim); + TestPManager.setDirty(AudioMessage); + + // Alter some of the existing fields + AudioEffect.isLooping = true; + AudioMessage.isLooping = true; + AudioEffect.is3D = true; + + // Test removing a field + TestPManager.removeField(AudioGui, "isLooping"); + + // Alter some of the persistent fields + AudioGui.referenceDistance = 0.8; + AudioMessage.referenceDistance = 0.8; + + // Add some new dynamic fields + AudioGui.foo = "bar"; + AudioEffect.foo = "bar"; + + // Remove an object from the dirty list + // It shouldn't get updated in the file + TestPManager.removeDirty(AudioEffect); + + // Dirty an object in another file as well + TestPManager.setDirty(WarningMaterial); + + // Update a field that doesn't exist + WarningMaterial.glow[0] = true; + + // Drity another object to test for crashes + // when a dirty object is deleted + TestPManager.setDirty(SFXPausedSet); + + // Delete the object + SFXPausedSet.delete(); + + // Unless %doNotSave is set (by a batch/combo test) + // then go ahead and save now + if (!%doNotSave) + TestPManager.saveDirty(); +} + +function TestPManager::testObjectRename(%doNotSave) +{ + // Flag an object as dirty + if (isObject(AudioGui)) + TestPManager.setDirty(AudioGui); + else if (isObject(AudioGuiFoo)) + TestPManager.setDirty(AudioGuiFoo); + + // Rename it + if (isObject(AudioGui)) + AudioGui.setName(AudioGuiFoo); + else if (isObject(AudioGuiFoo)) + AudioGuiFoo.setName(AudioGui); + + // Unless %doNotSave is set (by a batch/combo test) + // then go ahead and save now + if (!%doNotSave) + TestPManager.saveDirty(); +} + +function TestPManager::testNewObject(%doNotSave) +{ + // Test adding a new named object + new SFXDescription(AudioNew) + { + volume = 0.5; + isLooping = true; + channel = $GuiAudioType; + foo = 2; + }; + + // Flag it as dirty + TestPManager.setDirty(AudioNew, "core/scripts/client/audio.cs"); + + // Test adding a new unnamed object + %obj = new SFXDescription() + { + volume = 0.75; + isLooping = true; + bar = 3; + }; + + // Flag it as dirty + TestPManager.setDirty(%obj, "core/scripts/client/audio.cs"); + + // Test adding an "empty" object + new SFXDescription(AudioEmpty); + + TestPManager.setDirty(AudioEmpty, "core/scripts/client/audio.cs"); + + // Unless %doNotSave is set (by a batch/combo test) + // then go ahead and save now + if (!%doNotSave) + TestPManager.saveDirty(); +} + +function TestPManager::testNewGroup(%doNotSave) +{ + // Test adding a new named SimGroup + new SimGroup(TestGroup) + { + foo = "bar"; + + new SFXDescription(TestObject) + { + volume = 0.5; + isLooping = true; + channel = $GuiAudioType; + foo = 1; + }; + new SimGroup(SubGroup) + { + foo = 2; + + new SFXDescription(SubObject) + { + volume = 0.5; + isLooping = true; + channel = $GuiAudioType; + foo = 3; + }; + }; + }; + + // Flag this as dirty + TestPManager.setDirty(TestGroup, "core/scripts/client/audio.cs"); + + // Test adding a new unnamed SimGroup + %group = new SimGroup() + { + foo = "bar"; + + new SFXDescription() + { + volume = 0.75; + channel = $GuiAudioType; + foo = 4; + }; + new SimGroup() + { + foo = 5; + + new SFXDescription() + { + volume = 0.75; + isLooping = true; + channel = $GuiAudioType; + foo = 6; + }; + }; + }; + + // Flag this as dirty + TestPManager.setDirty(%group, "core/scripts/client/audio.cs"); + + // Test adding a new unnamed SimSet + %set = new SimSet() + { + foo = "bar"; + + new SFXDescription() + { + volume = 0.75; + channel = $GuiAudioType; + foo = 7; + }; + new SimGroup() + { + foo = 8; + + new SFXDescription() + { + volume = 0.75; + isLooping = true; + channel = $GuiAudioType; + foo = 9; + }; + }; + }; + + // Flag this as dirty + TestPManager.setDirty(%set, "core/scripts/client/audio.cs"); + + // Unless %doNotSave is set (by a batch/combo test) + // then go ahead and save now + if (!%doNotSave) + TestPManager.saveDirty(); +} + +function TestPManager::testMoveObject(%doNotSave) +{ + // First add a couple of groups to the file + new SimGroup(MoveGroup1) + { + foo = "bar"; + + new SFXDescription(MoveObject1) + { + volume = 0.5; + isLooping = true; + channel = $GuiAudioType; + foo = 1; + }; + + new SimSet(SubGroup1) + { + new SFXDescription(SubObject1) + { + volume = 0.75; + isLooping = true; + channel = $GuiAudioType; + foo = 2; + }; + }; + }; + + // Flag this as dirty + TestPManager.setDirty(MoveGroup1, "core/scripts/client/audio.cs"); + + new SimGroup(MoveGroup2) + { + foo = "bar"; + + new SFXDescription(MoveObject2) + { + volume = 0.5; + isLooping = true; + channel = $GuiAudioType; + foo = 3; + }; + }; + + // Flag this as dirty + TestPManager.setDirty(MoveGroup2, "core/scripts/client/audio.cs"); + + // Unless %doNotSave is set (by a batch/combo test) + // then go ahead and save now + if (!%doNotSave) + TestPManager.saveDirty(); + + // Set them as dirty again + TestPManager.setDirty(MoveGroup1); + TestPManager.setDirty(MoveGroup2); + + // Give the subobject an new value + MoveObject1.foo = 4; + + // Move it into the other group + MoveGroup1.add(MoveObject2); + + // Switch the other subobject + MoveGroup2.add(MoveObject1); + + // Also add a new unnamed object to one of the groups + %obj = new SFXDescription() + { + volume = 0.75; + isLooping = true; + bar = 5; + }; + + MoveGroup1.add(%obj); + + // Unless %doNotSave is set (by a batch/combo test) + // then go ahead and save now + if (!%doNotSave) + TestPManager.saveDirty(); +} + +function TestPManager::testObjectRemove(%doNotSave) +{ + TestPManager.removeObjectFromFile(AudioSim); +} \ No newline at end of file