diff --git a/Engine/source/T3D/assets/ImageAsset.cpp b/Engine/source/T3D/assets/ImageAsset.cpp index 3e29b0bdf..ff4c3ac70 100644 --- a/Engine/source/T3D/assets/ImageAsset.cpp +++ b/Engine/source/T3D/assets/ImageAsset.cpp @@ -90,14 +90,9 @@ ConsoleSetType(TypeImageAssetPtr) //----------------------------------------------------------------------------- -ImageAsset::ImageAsset() +ImageAsset::ImageAsset() : AssetBase(), mImage(nullptr), mUseMips(true), mIsHDRImage(false), mIsValidImage(false) { mImageFileName = StringTable->EmptyString(); - - mImage = NULL; - mUseMips = true; - mIsHDRImage = false; - mIsValidImage = false; } //----------------------------------------------------------------------------- diff --git a/Engine/source/T3D/assets/ImageAsset.h b/Engine/source/T3D/assets/ImageAsset.h index d289ac195..f5b52db07 100644 --- a/Engine/source/T3D/assets/ImageAsset.h +++ b/Engine/source/T3D/assets/ImageAsset.h @@ -47,11 +47,6 @@ class ImageAsset : public AssetBase { typedef AssetBase Parent; - AssetManager* mpOwningAssetManager; - bool mAssetInitialized; - AssetDefinition* mpAssetDefinition; - U32 mAcquireReferenceCount; - StringTableEntry mImageFileName; GFXTexHandle mImage; diff --git a/Engine/source/T3D/assets/LevelAsset.cpp b/Engine/source/T3D/assets/LevelAsset.cpp index 849cdc8d7..34084924a 100644 --- a/Engine/source/T3D/assets/LevelAsset.cpp +++ b/Engine/source/T3D/assets/LevelAsset.cpp @@ -90,10 +90,12 @@ ConsoleSetType(TypeLevelAssetPtr) //----------------------------------------------------------------------------- -LevelAsset::LevelAsset() +LevelAsset::LevelAsset() : AssetBase(), mIsSubLevel(false) { mLevelFile = StringTable->EmptyString(); mPreviewImage = StringTable->EmptyString(); + + mMainLevelAsset = StringTable->EmptyString(); } //----------------------------------------------------------------------------- diff --git a/Engine/source/T3D/assets/ScriptAsset.cpp b/Engine/source/T3D/assets/ScriptAsset.cpp index dbc5e7a2e..10c3be777 100644 --- a/Engine/source/T3D/assets/ScriptAsset.cpp +++ b/Engine/source/T3D/assets/ScriptAsset.cpp @@ -89,7 +89,7 @@ ConsoleSetType(TypeScriptAssetPtr) //----------------------------------------------------------------------------- -ScriptAsset::ScriptAsset() +ScriptAsset::ScriptAsset() : AssetBase(), mIsServerSide(true) { mScriptFilePath = StringTable->EmptyString(); } diff --git a/Engine/source/T3D/assets/ShapeAnimationAsset.cpp b/Engine/source/T3D/assets/ShapeAnimationAsset.cpp index ee10bbe40..4c2b0283e 100644 --- a/Engine/source/T3D/assets/ShapeAnimationAsset.cpp +++ b/Engine/source/T3D/assets/ShapeAnimationAsset.cpp @@ -92,8 +92,13 @@ ConsoleSetType(TypeShapeAnimationAssetPtr) //----------------------------------------------------------------------------- -ShapeAnimationAsset::ShapeAnimationAsset() +ShapeAnimationAsset::ShapeAnimationAsset() : + mIsEmbedded(false), mIsCyclical(true), mIsBlend(false), mBlendFrame(0), mStartFrame(0), mEndFrame(-1), mPadRotation(true), mPadTransforms(false) { + mFileName = StringTable->EmptyString(); + mAnimationName = StringTable->EmptyString(); + + mBlendAnimAssetName = StringTable->EmptyString(); } //----------------------------------------------------------------------------- @@ -116,6 +121,14 @@ void ShapeAnimationAsset::initPersistFields() addField("animationFile", TypeFilename, Offset(mFileName, ShapeAnimationAsset), "Path to the file name containing the animation"); addField("animationName", TypeString, Offset(mAnimationName, ShapeAnimationAsset), "Name of the animation"); + addField("isEmbedded", TypeBool, Offset(mIsEmbedded, ShapeAnimationAsset), "If true, this animation asset just referrs to an embedded animation of a regular shape mesh. If false, it is a self-contained animation file"); + + addField("isCyclic", TypeBool, Offset(mIsCyclical, ShapeAnimationAsset), "Is this animation looping?"); + + addField("isBlend", TypeBool, Offset(mIsBlend, ShapeAnimationAsset), "Is this animation blended with another?"); + addField("blendRefAnimation", TypeString, Offset(mBlendAnimAssetName, ShapeAnimationAsset), "AssetID of the animation to reference for our blending"); + addField("blendFrame", TypeS32, Offset(mBlendFrame, ShapeAnimationAsset), "Which frame of the reference animation do we use for our blending"); + addField("startFrame", TypeS32, Offset(mStartFrame, ShapeAnimationAsset), "What frame does this animation clip start on"); addField("endFrame", TypeS32, Offset(mEndFrame, ShapeAnimationAsset), "What fram does this animation clip end on"); addField("padRotation", TypeBool, Offset(mPadRotation, ShapeAnimationAsset), "Are the rotation values padded"); @@ -128,4 +141,35 @@ void ShapeAnimationAsset::copyTo(SimObject* object) { // Call to parent. Parent::copyTo(object); +} + +void ShapeAnimationAsset::initializeAsset(void) +{ + if (!mIsEmbedded) + { + //If we're not embedded, we need to load in our initial shape and do some prepwork + + char filenameBuf[1024]; + Con::expandScriptFilename(filenameBuf, sizeof(filenameBuf), mFileName); + + mSourceShape = ResourceManager::get().load(filenameBuf); + + if (!mSourceShape->addSequence("ambient", "", mAnimationName, mStartFrame, mEndFrame, mPadRotation, mPadTransforms)) + { + Con::errorf("ShapeAnimationAsset::initializeAsset - Unable to do initial setup of the animation clip named %s for asset %s", mAnimationName, getAssetName()); + return; + } + + S32 sequenceId = mSourceShape->findSequence(mAnimationName); + + if(mIsCyclical) + mSourceShape->sequences[sequenceId].flags |= TSShape::Cyclic; + else + mSourceShape->sequences[sequenceId].flags &= (~(TSShape::Cyclic)); + } +} + +void ShapeAnimationAsset::onAssetRefresh(void) +{ + } \ No newline at end of file diff --git a/Engine/source/T3D/assets/ShapeAnimationAsset.h b/Engine/source/T3D/assets/ShapeAnimationAsset.h index 673607d53..0b7bf1790 100644 --- a/Engine/source/T3D/assets/ShapeAnimationAsset.h +++ b/Engine/source/T3D/assets/ShapeAnimationAsset.h @@ -37,6 +37,12 @@ #ifndef _ASSET_FIELD_TYPES_H_ #include "assets/assetFieldTypes.h" #endif +#ifndef _TSSHAPE_H_ +#include "ts/tsShape.h" +#endif +#ifndef __RESOURCE_H__ +#include "core/resource.h" +#endif //----------------------------------------------------------------------------- class ShapeAnimationAsset : public AssetBase @@ -46,6 +52,15 @@ class ShapeAnimationAsset : public AssetBase protected: StringTableEntry mFileName; + bool mIsEmbedded; + bool mIsCyclical; + + bool mIsBlend; + + StringTableEntry mBlendAnimAssetName; + + S32 mBlendFrame; + // StringTableEntry mAnimationName; S32 mStartFrame; @@ -53,6 +68,8 @@ protected: bool mPadRotation; bool mPadTransforms; + Resource mSourceShape; + public: ShapeAnimationAsset(); virtual ~ShapeAnimationAsset(); @@ -65,18 +82,25 @@ public: DECLARE_CONOBJECT(ShapeAnimationAsset); protected: - virtual void initializeAsset(void) {} - virtual void onAssetRefresh(void) {} + virtual void initializeAsset(void); + virtual void onAssetRefresh(void); public: StringTableEntry getAnimationFilename() { return mFileName; } StringTableEntry getAnimationName() { return mAnimationName; } + StringTableEntry getBlendAnimationName() { return mBlendAnimAssetName; } S32 getStartFrame() { return mStartFrame; } S32 getEndFrame() { return mEndFrame; } bool getPadRotation() { return mPadRotation; } bool getPadTransforms() { return mPadTransforms; } + + bool isEmbedded() { return mIsEmbedded; } + bool isCyclic() { return mIsCyclical; } + bool isBlend() { return mIsBlend; } + + S32 getBlendFrame() { return mBlendFrame; } }; DefineConsoleType(TypeShapeAnimationAssetPtr, ShapeAnimationAsset) diff --git a/Engine/source/T3D/assets/ShapeAsset.cpp b/Engine/source/T3D/assets/ShapeAsset.cpp index 099c3c117..2bce369ea 100644 --- a/Engine/source/T3D/assets/ShapeAsset.cpp +++ b/Engine/source/T3D/assets/ShapeAsset.cpp @@ -182,17 +182,49 @@ bool ShapeAsset::loadShape() return false; //if it failed to load, bail out } + bool hasBlends = false; + //Now that we've successfully loaded our shape and have any materials and animations loaded //we need to set up the animations we're using on our shape - for (U32 i = 0; i < mAnimationAssets.size(); i++) + for (S32 i = mAnimationAssets.size()-1; i >= 0; --i) { - String srcName; + String srcName = mAnimationAssets[i]->getAnimationName(); String srcPath(mAnimationAssets[i]->getAnimationFilename()); - SplitSequencePathAndName(srcPath, srcName); + //SplitSequencePathAndName(srcPath, srcName); - if (!mShape->addSequence(srcPath, srcName, mAnimationAssets[i]->getAnimationName(), + if (!mShape->addSequence(srcPath, srcName, srcName, mAnimationAssets[i]->getStartFrame(), mAnimationAssets[i]->getEndFrame(), mAnimationAssets[i]->getPadRotation(), mAnimationAssets[i]->getPadTransforms())) return false; + + if (mAnimationAssets[i]->isBlend()) + hasBlends = true; + } + + //if any of our animations are blends, set those up now + if (hasBlends) + { + for (U32 i=0; i < mAnimationAssets.size(); ++i) + { + if (mAnimationAssets[i]->isBlend() && mAnimationAssets[i]->getBlendAnimationName() != StringTable->EmptyString()) + { + //gotta do a bit of logic here. + //First, we need to make sure the anim asset we depend on for our blend is loaded + AssetPtr blendAnimAsset = mAnimationAssets[i]->getBlendAnimationName(); + + if (blendAnimAsset.isNull()) + { + Con::errorf("ShapeAsset::initializeAsset - Unable to acquire reference animation asset %s for asset %s to blend!", mAnimationAssets[i]->getBlendAnimationName(), mAnimationAssets[i]->getAssetName()); + return false; + } + + String refAnimName = blendAnimAsset->getAnimationName(); + if (!mShape->setSequenceBlend(mAnimationAssets[i]->getAnimationName(), true, blendAnimAsset->getAnimationName(), mAnimationAssets[i]->getBlendFrame())) + { + Con::errorf("ShapeAnimationAsset::initializeAsset - Unable to set animation clip %s for asset %s to blend!", mAnimationAssets[i]->getAnimationName(), mAnimationAssets[i]->getAssetName()); + return false; + } + } + } } return true; diff --git a/Engine/source/T3D/components/animation/animationComponent.cpp b/Engine/source/T3D/components/animation/animationComponent.cpp index c8fd645d0..42871259d 100644 --- a/Engine/source/T3D/components/animation/animationComponent.cpp +++ b/Engine/source/T3D/components/animation/animationComponent.cpp @@ -222,7 +222,7 @@ U32 AnimationComponent::packUpdate(NetConnection *con, U32 mask, BitStream *stre { U32 retMask = Parent::packUpdate(con, mask, stream); - /*for (int i = 0; i < MaxScriptThreads; i++) + for (int i = 0; i < MaxScriptThreads; i++) { Thread& st = mAnimationThreads[i]; if (stream->writeFlag((st.sequence != -1 || st.state == Thread::Destroy) && (mask & (ThreadMaskN << i)))) @@ -234,7 +234,7 @@ U32 AnimationComponent::packUpdate(NetConnection *con, U32 mask, BitStream *stre stream->writeFlag(st.atEnd); stream->writeFlag(st.transition); } - }*/ + } return retMask; } @@ -243,7 +243,7 @@ void AnimationComponent::unpackUpdate(NetConnection *con, BitStream *stream) { Parent::unpackUpdate(con, stream); - /*for (S32 i = 0; i < MaxScriptThreads; i++) + for (S32 i = 0; i < MaxScriptThreads; i++) { if (stream->readFlag()) { @@ -260,7 +260,7 @@ void AnimationComponent::unpackUpdate(NetConnection *con, BitStream *stream) else updateThread(st); } - }*/ + } } void AnimationComponent::processTick() @@ -613,6 +613,9 @@ void AnimationComponent::advanceThreads(F32 dt) if (!mOwnerRenderInst) return; + if (mOwnerShapeInstance == nullptr || !getShape()) + return; + for (U32 i = 0; i < MaxScriptThreads; i++) { Thread& st = mAnimationThreads[i]; diff --git a/Engine/source/T3D/components/collision/collisionComponent.cpp b/Engine/source/T3D/components/collision/collisionComponent.cpp index ccdf818f1..3736fbe04 100644 --- a/Engine/source/T3D/components/collision/collisionComponent.cpp +++ b/Engine/source/T3D/components/collision/collisionComponent.cpp @@ -142,10 +142,12 @@ CollisionComponent::CollisionComponent() : Component() StaticShapeObjectType | VehicleObjectType | VehicleBlockerObjectType | DynamicShapeObjectType | StaticObjectType | EntityObjectType | TriggerObjectType); - mPhysicsRep = NULL; - mPhysicsWorld = NULL; + mPhysicsRep = nullptr; + mPhysicsWorld = nullptr; - mTimeoutList = NULL; + mTimeoutList = nullptr; + + mAnimated = false; } CollisionComponent::~CollisionComponent() diff --git a/Engine/source/T3D/components/component.cpp b/Engine/source/T3D/components/component.cpp index ff207d2c1..181c892e5 100644 --- a/Engine/source/T3D/components/component.cpp +++ b/Engine/source/T3D/components/component.cpp @@ -67,6 +67,13 @@ Component::Component() mOriginatingAssetId = StringTable->EmptyString(); mIsServerObject = true; + + componentIdx = 0; + + mHidden = false; + mEnabled = true; + + mDirtyMaskBits = 0; } Component::~Component() @@ -535,7 +542,7 @@ const char * Component::getDescriptionText(const char *desc) if (desc == NULL) return NULL; - char *newDesc; + char *newDesc = ""; // [tom, 1/12/2007] If it isn't a file, just do it the easy way if (!Platform::isFile(desc)) @@ -568,7 +575,7 @@ const char * Component::getDescriptionText(const char *desc) } str.close(); - delete stream; + //delete stream; return newDesc; } diff --git a/Engine/source/T3D/components/game/stateMachine.cpp b/Engine/source/T3D/components/game/stateMachine.cpp index 335b69db3..fd1ef8505 100644 --- a/Engine/source/T3D/components/game/stateMachine.cpp +++ b/Engine/source/T3D/components/game/stateMachine.cpp @@ -30,6 +30,10 @@ StateMachine::StateMachine() mStartingState = ""; mCurCreateState = NULL; + + mStateMachineFile = StringTable->EmptyString(); + + mCurCreateState = nullptr; } StateMachine::~StateMachine() diff --git a/Engine/source/T3D/components/game/stateMachine.h b/Engine/source/T3D/components/game/stateMachine.h index 9ccc540e8..b440ab7fa 100644 --- a/Engine/source/T3D/components/game/stateMachine.h +++ b/Engine/source/T3D/components/game/stateMachine.h @@ -158,6 +158,8 @@ public: { if (index <= mFields.size()) return mFields[index]; + + return StateField(); //return a blank one } Signal< void(StateMachine*, S32 stateIdx) > onStateChanged; diff --git a/Engine/source/T3D/components/physics/playerControllerComponent.cpp b/Engine/source/T3D/components/physics/playerControllerComponent.cpp index 2c6cea6e9..761ac570c 100644 --- a/Engine/source/T3D/components/physics/playerControllerComponent.cpp +++ b/Engine/source/T3D/components/physics/playerControllerComponent.cpp @@ -119,8 +119,11 @@ PlayerControllerComponent::PlayerControllerComponent() : Component() mInputVelocity = Point3F(0, 0, 0); - mPhysicsRep = NULL; - mPhysicsWorld = NULL; + mPhysicsRep = nullptr; + mPhysicsWorld = nullptr; + + mOwnerCollisionInterface = nullptr; + mIntegrationCount = 0; } PlayerControllerComponent::~PlayerControllerComponent() diff --git a/Engine/source/T3D/components/render/meshComponent.cpp b/Engine/source/T3D/components/render/meshComponent.cpp index 10186c873..c87733bf8 100644 --- a/Engine/source/T3D/components/render/meshComponent.cpp +++ b/Engine/source/T3D/components/render/meshComponent.cpp @@ -59,7 +59,7 @@ ImplementEnumType(BatchingMode, ////////////////////////////////////////////////////////////////////////// // Constructor/Destructor ////////////////////////////////////////////////////////////////////////// -MeshComponent::MeshComponent() : Component() +MeshComponent::MeshComponent() : Component(), mShape(nullptr), mRenderMode(Individual) { mFriendlyName = "Mesh Component"; mComponentType = "Render"; diff --git a/Engine/source/T3D/entity.cpp b/Engine/source/T3D/entity.cpp index a7af19b33..62c0b031f 100644 --- a/Engine/source/T3D/entity.cpp +++ b/Engine/source/T3D/entity.cpp @@ -850,7 +850,7 @@ void Entity::setTransform(const MatrixF &mat) } } -void Entity::setTransform(Point3F position, RotationF rotation) +void Entity::setTransform(const Point3F& position, const RotationF& rotation) { MatrixF oldTransform = getTransform(); @@ -922,7 +922,7 @@ void Entity::setRenderTransform(const MatrixF &mat) Parent::setRenderTransform(mat); } -void Entity::setRenderTransform(Point3F position, RotationF rotation) +void Entity::setRenderTransform(const Point3F& position, const RotationF& rotation) { if (isMounted()) { @@ -977,7 +977,7 @@ MatrixF Entity::getTransform() } } -void Entity::setMountOffset(Point3F posOffset) +void Entity::setMountOffset(const Point3F& posOffset) { if (isMounted()) { @@ -987,7 +987,7 @@ void Entity::setMountOffset(Point3F posOffset) } } -void Entity::setMountRotation(EulerF rotOffset) +void Entity::setMountRotation(const EulerF& rotOffset) { if (isMounted()) { @@ -1111,11 +1111,12 @@ bool Entity::castRayRendered(const Point3F &start, const Point3F &end, RayInfo * bool Entity::buildPolyList(PolyListContext context, AbstractPolyList* polyList, const Box3F &box, const SphereF &sphere) { - Vector updaters = getComponents(); + Con::errorf("Build Poly List not yet implemented as a passthrough for Entity"); + /*Vector updaters = getComponents(); for (Vector::iterator it = updaters.begin(); it != updaters.end(); it++) { return (*it)->buildPolyList(context, polyList, box, sphere); - } + }*/ return false; } @@ -1131,7 +1132,7 @@ void Entity::buildConvex(const Box3F& box, Convex* convex) // // Mounting and heirarchy manipulation -void Entity::mountObject(SceneObject* objB, MatrixF txfm) +void Entity::mountObject(SceneObject* objB, const MatrixF& txfm) { Parent::mountObject(objB, -1, txfm); Parent::addObject(objB); @@ -1604,7 +1605,7 @@ void Entity::onCameraScopeQuery(NetConnection* connection, CameraScopeQuery* que } } // -void Entity::setObjectBox(Box3F objBox) +void Entity::setObjectBox(const Box3F& objBox) { mObjBox = objBox; resetWorldBox(); @@ -1705,8 +1706,8 @@ void Entity::setComponentDirty(Component *comp, bool forceUpdate) } } - if (!found) - return; + //if (!found) + // return; //if(mToLoadComponents.empty()) // mStartComponentUpdate = true; diff --git a/Engine/source/T3D/entity.h b/Engine/source/T3D/entity.h index db65f2866..5bf9898ea 100644 --- a/Engine/source/T3D/entity.h +++ b/Engine/source/T3D/entity.h @@ -152,14 +152,14 @@ public: virtual void setTransform(const MatrixF &mat); virtual void setRenderTransform(const MatrixF &mat); - void setTransform(Point3F position, RotationF rotation); + void setTransform(const Point3F& position, const RotationF& rotation); - void setRenderTransform(Point3F position, RotationF rotation); + void setRenderTransform(const Point3F& position, const RotationF& rotation); virtual MatrixF getTransform(); virtual Point3F getPosition() const { return mPos; } - void setRotation(RotationF rotation) { + void setRotation(const RotationF& rotation) { mRot = rotation; setMaskBits(TransformMask); }; @@ -167,8 +167,8 @@ public: static bool _setGameObject(void *object, const char *index, const char *data); - void setMountOffset(Point3F posOffset); - void setMountRotation(EulerF rotOffset); + void setMountOffset(const Point3F& posOffset); + void setMountRotation(const EulerF& rotOffset); //static bool _setEulerRotation( void *object, const char *index, const char *data ); static bool _setPosition(void *object, const char *index, const char *data); @@ -181,7 +181,7 @@ public: virtual void getRenderMountTransform(F32 delta, S32 index, const MatrixF &xfm, MatrixF *outMat); virtual void mountObject(SceneObject *obj, S32 node, const MatrixF &xfm = MatrixF::Identity); - void mountObject(SceneObject* objB, MatrixF txfm); + void mountObject(SceneObject* objB, const MatrixF& txfm); void onMount(SceneObject *obj, S32 node); void onUnmount(SceneObject *obj, S32 node); @@ -218,7 +218,7 @@ public: return mComponents.size(); } - virtual void setObjectBox(Box3F objBox); + virtual void setObjectBox(const Box3F& objBox); void resetWorldBox() { Parent::resetWorldBox(); } void resetObjectBox() { Parent::resetObjectBox(); } diff --git a/Engine/source/T3D/systems/render/meshRenderSystem.cpp b/Engine/source/T3D/systems/render/meshRenderSystem.cpp index 214a63dfe..fe1ec6f84 100644 --- a/Engine/source/T3D/systems/render/meshRenderSystem.cpp +++ b/Engine/source/T3D/systems/render/meshRenderSystem.cpp @@ -11,6 +11,9 @@ Vector MeshRenderSystem::mStaticBuffers(0); void MeshRenderSystem::render(SceneManager *sceneManager, SceneRenderState* state) { + if (sceneManager == nullptr || state == nullptr) + return; + Frustum viewFrustum = state->getCullingFrustum(); MatrixF camTransform = state->getCameraTransform(); @@ -129,7 +132,7 @@ void MeshRenderSystem::render(SceneManager *sceneManager, SceneRenderState* stat // We sort by the material then vertex buffer ri->defaultKey = matInst->getStateHint(); - ri->defaultKey2 = (uintptr_t)ri->vertBuff; // Not 64bit safe! + ri->defaultKey2 = (uintptr_t)ri->vertBuff; // Submit our RenderInst to the RenderPassManager state->getRenderPass()->addInst(ri); @@ -372,4 +375,4 @@ U32 MeshRenderSystem::findBufferSetByMaterial(U32 matId) } return -1; -} \ No newline at end of file +} diff --git a/Engine/source/console/consoleObject.cpp b/Engine/source/console/consoleObject.cpp index d75405376..e1744c5e1 100644 --- a/Engine/source/console/consoleObject.cpp +++ b/Engine/source/console/consoleObject.cpp @@ -37,6 +37,7 @@ #include "console/engineTypes.h" #include "console/engineAPI.h" +#include "sim/netObject.h" IMPLEMENT_SCOPE( ConsoleAPI, Console,, "Functionality related to the legacy TorqueScript console system." ); @@ -372,6 +373,7 @@ void ConsoleObject::addGroup(const char* in_pGroupname, const char* in_pGroupDoc f.setDataFn = &defaultProtectedSetFn; f.getDataFn = &defaultProtectedGetFn; f.writeDataFn = &defaultProtectedWriteFn; + f.networkMask = 0; // Add to field list. sg_tempFieldList.push_back(f); @@ -396,6 +398,7 @@ void ConsoleObject::endGroup(const char* in_pGroupname) f.getDataFn = &defaultProtectedGetFn; f.writeDataFn = &defaultProtectedWriteFn; f.elementCount = 0; + f.networkMask = 0; // Add to field list. sg_tempFieldList.push_back(f); @@ -418,6 +421,7 @@ void ConsoleObject::addArray( const char *arrayName, S32 count ) f.setDataFn = &defaultProtectedSetFn; f.getDataFn = &defaultProtectedGetFn; f.writeDataFn = &defaultProtectedWriteFn; + f.networkMask = 0; // Add to field list. sg_tempFieldList.push_back(f); @@ -439,6 +443,7 @@ void ConsoleObject::endArray( const char *arrayName ) f.getDataFn = &defaultProtectedGetFn; f.writeDataFn = &defaultProtectedWriteFn; f.elementCount = 0; + f.networkMask = 0; // Add to field list. sg_tempFieldList.push_back(f); @@ -515,6 +520,7 @@ void ConsoleObject::addField(const char* in_pFieldname, f.setDataFn = &defaultProtectedSetFn; f.getDataFn = &defaultProtectedGetFn; f.writeDataFn = in_writeDataFn; + f.networkMask = 0; ConsoleBaseType* conType = ConsoleBaseType::getType(in_fieldType); AssertFatal(conType, "ConsoleObject::addField - invalid console type"); @@ -609,6 +615,7 @@ void ConsoleObject::addProtectedField(const char* in_pFieldname, f.setDataFn = in_setDataFn; f.getDataFn = in_getDataFn; f.writeDataFn = in_writeDataFn; + f.networkMask = 0; ConsoleBaseType* conType = ConsoleBaseType::getType(in_fieldType); AssertFatal(conType, "ConsoleObject::addProtectedField - invalid console type"); @@ -635,6 +642,7 @@ void ConsoleObject::addFieldV(const char* in_pFieldname, f.getDataFn = &defaultProtectedGetFn; f.writeDataFn = &defaultProtectedWriteFn; f.validator = v; + f.networkMask = 0; v->fieldIndex = sg_tempFieldList.size(); sg_tempFieldList.push_back(f); @@ -652,11 +660,12 @@ void ConsoleObject::addDeprecatedField(const char *fieldName) f.setDataFn = &defaultProtectedSetFn; f.getDataFn = &defaultProtectedGetFn; f.writeDataFn = &defaultProtectedWriteFn; + f.networkMask = 0; sg_tempFieldList.push_back(f); } - +//------------------------------------------------------------------ bool ConsoleObject::removeField(const char* in_pFieldname) { for (U32 i = 0; i < sg_tempFieldList.size(); i++) { diff --git a/Engine/source/console/consoleObject.h b/Engine/source/console/consoleObject.h index 0cf34e237..7eea3144e 100644 --- a/Engine/source/console/consoleObject.h +++ b/Engine/source/console/consoleObject.h @@ -495,7 +495,8 @@ public: table( NULL ), validator( NULL ), setDataFn( NULL ), - getDataFn( NULL ) + getDataFn( NULL ), + networkMask(0) { doNotSubstitute = keepClearSubsOnly = false; } @@ -515,9 +516,11 @@ public: TypeValidator *validator; ///< Validator, if any. SetDataNotify setDataFn; ///< Set data notify Fn GetDataNotify getDataFn; ///< Get data notify Fn - WriteDataNotify writeDataFn; ///< Function to determine whether data should be written or not. + WriteDataNotify writeDataFn; ///< Function to determine whether data should be written or not. bool doNotSubstitute; bool keepClearSubsOnly; + + U32 networkMask; }; typedef Vector FieldList; @@ -1263,10 +1266,6 @@ inline bool& ConsoleObject::getDynamicGroupExpand() EnginePropertyTable _propTable( sizeof( _props ) / sizeof( _props[ 0 ] ) - 1, _props ); \ } } -/// Add an auto-doc for a class. -#define ConsoleDocClass( className, docString ) \ - CLASSDOC( className, docString ) - /// @} //------------------------------------------------------------------------------ diff --git a/Engine/source/console/engineTypes.h b/Engine/source/console/engineTypes.h index 321e39686..2217ee770 100644 --- a/Engine/source/console/engineTypes.h +++ b/Engine/source/console/engineTypes.h @@ -576,7 +576,7 @@ namespace _Private { uintptr_t( ( ( const char* ) &( ( ( ThisType* ) 16 )->fieldName ) ) - 16 ) // Artificial offset to avoid compiler warnings. /// -#define CLASSDOC( className, doc ) \ +#define ConsoleDocClass( className, doc ) \ template<> const char* EngineClassTypeInfo< className, className::_ClassBase >::smDocString = doc; diff --git a/Engine/source/console/simObject.cpp b/Engine/source/console/simObject.cpp index 0583606b0..ef688228f 100644 --- a/Engine/source/console/simObject.cpp +++ b/Engine/source/console/simObject.cpp @@ -41,6 +41,8 @@ #include "core/fileObject.h" #include "persistence/taml/tamlCustom.h" +#include "sim/netObject.h" + IMPLEMENT_CONOBJECT( SimObject ); // See full description in the new CHM manual @@ -912,6 +914,12 @@ void SimObject::assignFieldsFrom(SimObject *parent) if((*f->setDataFn)( this, NULL, bufferSecure ) ) Con::setData(f->type, (void *) (((const char *)this) + f->offset), j, 1, &fieldVal, f->table); + + if (f->networkMask != 0) + { + NetObject* netObj = static_cast(this); + netObj->setMaskBits(f->networkMask); + } } } } @@ -988,6 +996,12 @@ void SimObject::setDataField(StringTableEntry slotName, const char *array, const if(fld->validator) fld->validator->validateType(this, (void *) (((const char *)this) + fld->offset)); + if (fld->networkMask != 0) + { + NetObject* netObj = static_cast(this); + netObj->setMaskBits(fld->networkMask); + } + onStaticModified( slotName, value ); return; diff --git a/Engine/source/console/typeValidators.h b/Engine/source/console/typeValidators.h index 414721f5d..9ca949fa7 100644 --- a/Engine/source/console/typeValidators.h +++ b/Engine/source/console/typeValidators.h @@ -53,6 +53,8 @@ public: maxV = maxValue; } void validateType(SimObject *object, void *typePtr); + F32 getMin() { return minV; }; + F32 getMax() { return maxV; }; }; /// Signed integer min/max range validator @@ -66,6 +68,8 @@ public: maxV = maxValue; } void validateType(SimObject *object, void *typePtr); + F32 getMin() { return minV; }; + F32 getMax() { return maxV; }; }; /// Scaled integer field validator @@ -93,6 +97,7 @@ class Point3NormalizeValidator : public TypeValidator public: Point3NormalizeValidator(F32 normalizeLength = 1.0f) : length(normalizeLength) { } void validateType(SimObject *object, void *typePtr); + F32 getLength() { return length; }; }; namespace CommonValidators diff --git a/Engine/source/gfx/sim/cubemapData.cpp b/Engine/source/gfx/sim/cubemapData.cpp index 35e921b5b..647615263 100644 --- a/Engine/source/gfx/sim/cubemapData.cpp +++ b/Engine/source/gfx/sim/cubemapData.cpp @@ -111,7 +111,7 @@ void CubemapData::createMap() { if (!mCubeFaceFile[i].isEmpty()) { - if (!mCubeFace[i].set(mCubeFaceFile[i], &GFXStaticTextureSRGBProfile, avar("%s() - mCubeFace[%d] (line %d)", __FUNCTION__, i, __LINE__))) + if (!mCubeFace[i].set(mCubeFaceFile[i], &GFXStaticTextureProfile, avar("%s() - mCubeFace[%d] (line %d)", __FUNCTION__, i, __LINE__))) { Con::errorf("CubemapData::createMap - Failed to load texture '%s'", mCubeFaceFile[i].c_str()); initSuccess = false; diff --git a/Engine/source/gui/buttons/guiBitmapButtonCtrl.cpp b/Engine/source/gui/buttons/guiBitmapButtonCtrl.cpp index b357fc3b5..2e9b6d0aa 100644 --- a/Engine/source/gui/buttons/guiBitmapButtonCtrl.cpp +++ b/Engine/source/gui/buttons/guiBitmapButtonCtrl.cpp @@ -307,22 +307,22 @@ void GuiBitmapButtonCtrl::setBitmap( const String& name ) if( mUseModifiers ) baseName += modifiers[ i ]; - mTextures[ i ].mTextureNormal = GFXTexHandle( baseName, &GFXTexturePersistentSRGBProfile, avar("%s() - mTextureNormal (line %d)", __FUNCTION__, __LINE__)); + mTextures[ i ].mTextureNormal = GFXTexHandle( baseName, &GFXDefaultGUIProfile, avar("%s() - mTextureNormal (line %d)", __FUNCTION__, __LINE__)); if( mUseStates ) { if( !mTextures[ i ].mTextureNormal ) - mTextures[ i ].mTextureNormal = GFXTexHandle( baseName + s_n, &GFXTexturePersistentSRGBProfile, avar("%s() - mTextureNormal (line %d)", __FUNCTION__, __LINE__)); + mTextures[ i ].mTextureNormal = GFXTexHandle( baseName + s_n, &GFXDefaultGUIProfile, avar("%s() - mTextureNormal (line %d)", __FUNCTION__, __LINE__)); - mTextures[ i ].mTextureHilight = GFXTexHandle( baseName + s_h, &GFXTexturePersistentSRGBProfile, avar("%s() - mTextureHighlight (line %d)", __FUNCTION__, __LINE__)); + mTextures[ i ].mTextureHilight = GFXTexHandle( baseName + s_h, &GFXDefaultGUIProfile, avar("%s() - mTextureHighlight (line %d)", __FUNCTION__, __LINE__)); if( !mTextures[ i ].mTextureHilight ) mTextures[ i ].mTextureHilight = mTextures[ i ].mTextureNormal; - mTextures[ i ].mTextureDepressed = GFXTexHandle( baseName + s_d, &GFXTexturePersistentSRGBProfile, avar("%s() - mTextureDepressed (line %d)", __FUNCTION__, __LINE__)); + mTextures[ i ].mTextureDepressed = GFXTexHandle( baseName + s_d, &GFXDefaultGUIProfile, avar("%s() - mTextureDepressed (line %d)", __FUNCTION__, __LINE__)); if( !mTextures[ i ].mTextureDepressed ) mTextures[ i ].mTextureDepressed = mTextures[ i ].mTextureHilight; - mTextures[ i ].mTextureInactive = GFXTexHandle( baseName + s_i, &GFXTexturePersistentSRGBProfile, avar("%s() - mTextureInactive (line %d)", __FUNCTION__, __LINE__)); + mTextures[ i ].mTextureInactive = GFXTexHandle( baseName + s_i, &GFXDefaultGUIProfile, avar("%s() - mTextureInactive (line %d)", __FUNCTION__, __LINE__)); if( !mTextures[ i ].mTextureInactive ) mTextures[ i ].mTextureInactive = mTextures[ i ].mTextureNormal; } diff --git a/Engine/source/gui/core/guiCanvas.cpp b/Engine/source/gui/core/guiCanvas.cpp index 5202e57bf..efb0674ea 100644 --- a/Engine/source/gui/core/guiCanvas.cpp +++ b/Engine/source/gui/core/guiCanvas.cpp @@ -133,7 +133,8 @@ GuiCanvas::GuiCanvas(): GuiControl(), mLastRenderMs(0), mPlatformWindow(NULL), mDisplayWindow(true), - mMenuBarCtrl(NULL) + mMenuBarCtrl(nullptr), + mMenuBackground(nullptr) { setBounds(0, 0, 640, 480); mAwake = true; @@ -296,8 +297,11 @@ void GuiCanvas::setMenuBar(SimObject *obj) mMenuBarCtrl = dynamic_cast(obj); //remove old menubar - if( oldMenuBar ) - Parent::removeObject( oldMenuBar ); + if (oldMenuBar) + { + Parent::removeObject(oldMenuBar); + Parent::removeObject(mMenuBackground); //also remove the modeless wrapper + } // set new menubar if (mMenuBarCtrl) @@ -312,14 +316,17 @@ void GuiCanvas::setMenuBar(SimObject *obj) return; } - GuiControl* menuBackground = new GuiControl(); - menuBackground->registerObject(); + if (mMenuBackground == nullptr) + { + mMenuBackground = new GuiControl(); + mMenuBackground->registerObject(); - menuBackground->setControlProfile(profile); + mMenuBackground->setControlProfile(profile); + } - menuBackground->addObject(mMenuBarCtrl); + mMenuBackground->addObject(mMenuBarCtrl); - Parent::addObject(menuBackground); + Parent::addObject(mMenuBackground); } // update window accelerator keys diff --git a/Engine/source/gui/core/guiCanvas.h b/Engine/source/gui/core/guiCanvas.h index b193bfbf1..f9f4a37af 100644 --- a/Engine/source/gui/core/guiCanvas.h +++ b/Engine/source/gui/core/guiCanvas.h @@ -198,6 +198,7 @@ protected: static CanvasSizeChangeSignal smCanvasSizeChangeSignal; GuiControl *mMenuBarCtrl; + GuiControl* mMenuBackground; public: DECLARE_CONOBJECT(GuiCanvas); diff --git a/Engine/source/gui/editor/guiMenuBar.cpp b/Engine/source/gui/editor/guiMenuBar.cpp index fc9623498..dc168436b 100644 --- a/Engine/source/gui/editor/guiMenuBar.cpp +++ b/Engine/source/gui/editor/guiMenuBar.cpp @@ -1519,9 +1519,10 @@ DefineConsoleMethod(GuiMenuBar, insert, void, (SimObject* pObject, S32 pos), (nu object->insert(pObject, pos); } -DefineConsoleMethod(GuiMenuBar, findMenu, S32, (StringTableEntry barTitle), (""), "(barTitle)") +DefineConsoleMethod(GuiMenuBar, findMenu, S32, (const char* barTitle), (""), "(barTitle)") { - PopupMenu* menu = object->findMenu(barTitle); + StringTableEntry barTitleStr = StringTable->insert(barTitle); + PopupMenu* menu = object->findMenu(barTitleStr); if (menu) return menu->getId(); diff --git a/Engine/source/gui/editor/inspector/entityGroup.cpp b/Engine/source/gui/editor/inspector/entityGroup.cpp index c833d336d..7b7559833 100644 --- a/Engine/source/gui/editor/inspector/entityGroup.cpp +++ b/Engine/source/gui/editor/inspector/entityGroup.cpp @@ -70,7 +70,8 @@ bool GuiInspectorEntityGroup::inspectGroup() { Entity* target = dynamic_cast(mParent->getInspectObject(0)); - Con::executef(this, "inspectObject", target->getIdString()); + if(target) + Con::executef(this, "inspectObject", target->getIdString()); } return true; diff --git a/Engine/source/materials/processedMaterial.cpp b/Engine/source/materials/processedMaterial.cpp index 1622d50e6..b38e0a400 100644 --- a/Engine/source/materials/processedMaterial.cpp +++ b/Engine/source/materials/processedMaterial.cpp @@ -456,7 +456,7 @@ void ProcessedMaterial::_setStageData() // SpecularMap if( mMaterial->mSpecularMapFilename[i].isNotEmpty() ) { - mStages[i].setTex( MFT_SpecularMap, _createTexture( mMaterial->mSpecularMapFilename[i], &GFXStaticTextureProfile) ); + mStages[i].setTex( MFT_SpecularMap, _createTexture( mMaterial->mSpecularMapFilename[i], &GFXStaticTextureSRGBProfile) ); if(!mStages[i].getTex( MFT_SpecularMap )) mMaterial->logError("Failed to load specular map %s for stage %i", _getTexturePath(mMaterial->mSpecularMapFilename[i]).c_str(), i); } diff --git a/Engine/source/math/mConsoleFunctions.cpp b/Engine/source/math/mConsoleFunctions.cpp index 651889539..c9a1f4622 100644 --- a/Engine/source/math/mConsoleFunctions.cpp +++ b/Engine/source/math/mConsoleFunctions.cpp @@ -288,6 +288,29 @@ DefineConsoleFunction( mSaturate, F32, ( F32 v ),, return mClampF( v, 0.0f, 1.0f ); } +DefineConsoleFunction(mWrapF, F32, (F32 v, F32 min, F32 max), , + "Wrap the specified value between two bounds.\n" + "@param v Input value." + "@param min Minimum Bound." + "@param max Maximum Bound." + "@returns The specified value wrapped to the specified bounds." + "@ingroup Math") +{ + return mWrapF(v, min, max); +} + +DefineConsoleFunction(mWrap, S32, (S32 v, S32 min, S32 max), , + "Wrap the specified value between two bounds.\n" + "@param v Input value." + "@param min Minimum Bound." + "@param max Maximum Bound." + "@returns The specified value wrapped to the specified bounds." + "@ingroup Math") +{ + return mWrap(v, min, max); +} + + DefineConsoleFunction( getMax, F32, ( F32 v1, F32 v2 ),, "Calculate the greater of two specified numbers.\n" "@param v1 Input value." diff --git a/Engine/source/math/mMathFn.h b/Engine/source/math/mMathFn.h index 93596f63f..a5d2b6ebb 100644 --- a/Engine/source/math/mMathFn.h +++ b/Engine/source/math/mMathFn.h @@ -237,6 +237,19 @@ inline F32 mClampF(F32 val, F32 low, F32 high) return (F32) getMax(getMin(val, high), low); } +inline S32 mWrap(S32 val, S32 low, S32 high) +{ + int len = high - low; + return low + (val >= 0 ? val % len : -val % len ? len - (-val % len) : 0); + +} + +inline F32 mWrapF(F32 val, F32 low, F32 high) +{ + F32 t = fmod(val - low, high - low); + return t < 0 ? t + high : t + low; +} + /// Template function for doing a linear interpolation between any two /// types which implement operators for scalar multiply and addition. template diff --git a/Engine/source/sim/actionMap.cpp b/Engine/source/sim/actionMap.cpp index f96e02585..841f3e39b 100644 --- a/Engine/source/sim/actionMap.cpp +++ b/Engine/source/sim/actionMap.cpp @@ -269,7 +269,13 @@ void ActionMap::dumpActionMap(const char* fileName, const bool append) const if (getKeyString(rNode.action, objectbuffer) == false) continue; - const char* command = (rNode.flags & Node::BindCmd) ? "bindCmd" : "bind"; + const char* command; + if (rNode.flags & Node::BindCmd) + command = "bindCmd"; + else if (rNode.flags & Node::Held) + command = "held"; + else + command = "bind"; dSprintf(lineBuffer, 1023, "%s.%s(%s, \"%s%s\"", getName(), @@ -324,7 +330,16 @@ void ActionMap::dumpActionMap(const char* fileName, const bool append) const } else dStrcat(lineBuffer, ", \"\""); - } else { + } + else if (rNode.flags & Node::Held) + { + dStrcat(lineBuffer, ", "); + dStrcat(lineBuffer, rNode.consoleFunction); + + dStrcat(lineBuffer, ", "); + dStrcat(lineBuffer, rNode.contextEvent->mConsoleFunctionHeld); + } + else { dStrcat(lineBuffer, ", "); dStrcat(lineBuffer, rNode.consoleFunction); } @@ -353,7 +368,13 @@ void ActionMap::dumpActionMap(const char* fileName, const bool append) const if (getKeyString(rNode.action, keybuffer) == false) continue; - const char* command = (rNode.flags & Node::BindCmd) ? "bindCmd" : "bind"; + const char* command; + if (rNode.flags & Node::BindCmd) + command = "bindCmd"; + else if (rNode.flags & Node::Held) + command = "held"; + else + command = "bind"; char finalBuffer[1024]; dSprintf(finalBuffer, 1023, "%s.%s(%s, \"%s%s\"", @@ -407,7 +428,16 @@ void ActionMap::dumpActionMap(const char* fileName, const bool append) const } else dStrcat(finalBuffer, ", \"\""); - } else { + } + else if (rNode.flags & Node::Held) + { + dStrcat(finalBuffer, ", "); + dStrcat(finalBuffer, rNode.consoleFunction); + + dStrcat(finalBuffer, ", "); + dStrcat(finalBuffer, rNode.contextEvent->mConsoleFunctionHeld); + } + else { dStrcat(finalBuffer, ", "); dStrcat(finalBuffer, rNode.consoleFunction); } @@ -794,6 +824,17 @@ const char* ActionMap::getCommand( const char* device, const char* action ) ( mapNode->breakConsoleCommand ? mapNode->breakConsoleCommand : "" ) ); return( returnString ); } + if (mapNode->flags & Node::Held) + { + S32 bufferLen = dStrlen(mapNode->consoleFunction) + dStrlen(mapNode->contextEvent->mConsoleFunctionHeld) + 2; + char* returnString = Con::getReturnBuffer(bufferLen); + + dSprintf(returnString, bufferLen, "%st%s", + (mapNode->consoleFunction ? mapNode->consoleFunction : ""), + (mapNode->contextEvent->mConsoleFunctionHeld ? mapNode->contextEvent->mConsoleFunctionHeld : "")); + + return(returnString); + } else return( mapNode->consoleFunction ); } @@ -1310,6 +1351,76 @@ bool ActionMap::processBind(const U32 argc, const char** argv, SimObject* object return true; } +//------------------------------------------------------------------------------ +bool ActionMap::processHoldBind(const char *device, const char *action, const char *holdFunc, const char *tapFunc, const U32 holdTime, const bool holdOnly, const bool retHoldTime) +{ + U32 deviceType; + U32 deviceInst; + + if (!getDeviceTypeAndInstance(device, deviceType, deviceInst)) + { + Con::printf("processBindCmd: unknown device: %s", device); + return false; + } + + // Ok, we now have the deviceType and instance. Create an event descriptor + // for the bind... + // + EventDescriptor eventDescriptor; + if (createEventDescriptor(action, &eventDescriptor) == false) { + Con::printf("Could not create a description for binding: %s", action); + return false; + } + + // SI_POV == SI_MOVE, and the POV works fine with bindCmd, so we have to add these manually. + if ((eventDescriptor.eventCode == SI_XAXIS) || + (eventDescriptor.eventCode == SI_YAXIS) || + (eventDescriptor.eventCode == SI_ZAXIS) || + (eventDescriptor.eventCode == SI_RXAXIS) || + (eventDescriptor.eventCode == SI_RYAXIS) || + (eventDescriptor.eventCode == SI_RZAXIS) || + (eventDescriptor.eventCode == SI_SLIDER) || + (eventDescriptor.eventCode == SI_XPOV) || + (eventDescriptor.eventCode == SI_YPOV) || + (eventDescriptor.eventCode == SI_XPOV2) || + (eventDescriptor.eventCode == SI_YPOV2)) + { + Con::warnf("ActionMap::processBindCmd - Cannot use 'bindCmd' with a move event type. Use 'bind' instead."); + return false; + } + + // Event has now been described, and device determined. we need now to extract + // any modifiers that the action map will apply to incoming events before + // calling the bound function... + // + // DMMTODO + F32 deadZoneBegin = 0.0f; + F32 deadZoneEnd = 0.0f; + F32 scaleFactor = 1.0f; + + // Ensure that the console function is properly specified? + // + // DMMTODO + + // Create the full bind entry, and place it in the map + // + // DMMTODO + Node* pBindNode = getNode(deviceType, deviceInst, + eventDescriptor.flags, + eventDescriptor.eventCode); + + pBindNode->flags = Node::Held; + pBindNode->deadZoneBegin = deadZoneBegin; + pBindNode->deadZoneEnd = deadZoneEnd; + pBindNode->scaleFactor = scaleFactor; + pBindNode->consoleFunction = StringTable->insert(dStrdup(tapFunc)); + + pBindNode->contextEvent = new ContextAction(StringTable->insert(dStrdup(holdFunc)), holdTime, pBindNode, holdOnly); + pBindNode->contextEvent->mReturnHoldTime = retHoldTime; + + return true; +} + //------------------------------------------------------------------------------ bool ActionMap::processAction(const InputEventInfo* pEvent) { @@ -1328,7 +1439,9 @@ bool ActionMap::processAction(const InputEventInfo* pEvent) // Enter the break into the table if this is a make event... // Do this now rather than after command is processed because // command might add a binding which can move the vector of nodes. - enterBreakEvent(pEvent, pNode); + // Filter to prevent Hold buttons from being eaten + if (!(pNode->flags & Node::Held)) + enterBreakEvent(pEvent, pNode); // Whadda ya know, we have this bound. Set up, and call the console // function associated with it... @@ -1369,6 +1482,15 @@ bool ActionMap::processAction(const InputEventInfo* pEvent) if(pNode->makeConsoleCommand) Con::evaluate(pNode->makeConsoleCommand); } + else if (pNode->flags & Node::Held) + { + //check if we're already holding, if not, start our timer + if (!pNode->contextEvent->mActive) { + pNode->contextEvent->mActive = true; + pNode->contextEvent->mStartTime = Sim::getCurrentTime(); + pNode->contextEvent->mEventValue = value; + } + } else if ( pNode->consoleFunction[0] ) { argv[0] = pNode->consoleFunction; @@ -1529,6 +1651,20 @@ bool ActionMap::processAction(const InputEventInfo* pEvent) } else if (pEvent->action == SI_BREAK) { + const Node* button = findNode(pEvent->deviceType, pEvent->deviceInst, + pEvent->modifier, pEvent->objInst); + + if (button != NULL) + { + if (button->flags == Node::Held) + { + if (!button->contextEvent->mBreakEvent) + button->contextEvent->mBreakEvent = true; + + return true; + } + } + return checkBreakTable(pEvent); } else if (pEvent->action == SI_VALUE) @@ -1808,6 +1944,78 @@ void ActionMap::fireBreakEvent( U32 i, F32 fValue ) smBreakTable.erase(i); } +//------------------------------------------------------------------------------ +//Context actions +ContextAction::ContextAction(StringTableEntry func, F32 minHoldTime, ActionMap::Node* button, bool holdOnly) + : mStartTime(0), mEventValue(1.0f), mBreakEvent(false), mDidHold(false), mActive(false), mReturnHoldTime(false) +{ + mButton = button; + mMinHoldTime = minHoldTime; + mConsoleFunctionHeld = func; + + mHoldOnly = holdOnly; +} + +void ContextAction::processTick() +{ + if (mActive) + { + F32 currTime = Sim::getCurrentTime(); + static const char *argv[2]; + + //see if this key even is still active + if (!mBreakEvent) + { + //are we only checking if it's holding? + if (mHoldOnly) + { + //yes, we are, and since it's held, we fire off our function + if (mReturnHoldTime) + { + argv[0] = mConsoleFunctionHeld; + argv[1] = Con::getFloatArg(mEventValue); + argv[2] = Con::getFloatArg((currTime - mStartTime)); + Con::execute(3, argv); + } + else + { + argv[0] = mConsoleFunctionHeld; + argv[1] = Con::getFloatArg(mEventValue); + Con::execute(2, argv); + } + } + //if we don't care if we're just holding, check our time + //have we passed our min limit? + else if ((currTime - mStartTime) >= mMinHoldTime) + { + //holy crap, we have, fire off our hold function + mDidHold = true; + argv[0] = mConsoleFunctionHeld; + argv[1] = Con::getFloatArg(mEventValue); + Con::execute(2, argv); + } + //otherwise we haven't yet, so keep our active status + return; + } + //hmm, apparently not, so see if we tapped the key instead + else + { + if (!mHoldOnly && !mDidHold) + { + //yes, we tapped and we care, so fire off the tap function. + argv[0] = mButton->consoleFunction; + argv[1] = Con::getFloatArg(mEventValue); + Con::execute(2, argv); + } + //otherwise we don't care and we're done, so reset everything + mActive = false; + mStartTime = 0; + mBreakEvent = false; + mDidHold = false; + } + } +} + //------------------------------------------------------------------------------ // Console interop version. @@ -1959,6 +2167,18 @@ DefineEngineMethod( ActionMap, bindCmd, bool, ( const char* device, const char* return object->processBindCmd( device, action, makeCmd, breakCmd ); } +DefineEngineMethod(ActionMap, bindContext, void, (const char* device, const char* action, const char* holdFunction, const char* tapFunction, U32 holdTime), + ("", "", "", "", 0), "actionMap.bindCmd( device, action, holdFunction, tapFunction, holdTime)") +{ + object->processHoldBind(device, action, holdFunction, tapFunction, holdTime, false); +} + +DefineEngineMethod(ActionMap, bindHold, void, (const char* device, const char* action, const char* holdFunction, bool returnHoldTime), + ("", "", "", false), "actionMap.bindCmd( device, action, holdFunction, returnHoldTime)") +{ + object->processHoldBind(device, action, holdFunction, "", 0, true, returnHoldTime); +} + DefineEngineMethod( ActionMap, unbind, bool, ( const char* device, const char* action ),, "@brief Removes the binding on an input device and action.\n" "@param device The device to unbind from. Can be a keyboard, mouse, joystick or a gamepad.\n" diff --git a/Engine/source/sim/actionMap.h b/Engine/source/sim/actionMap.h index 7b3d55261..c2c4cbd72 100644 --- a/Engine/source/sim/actionMap.h +++ b/Engine/source/sim/actionMap.h @@ -32,7 +32,11 @@ #ifndef _SIMBASE_H_ #include "console/simBase.h" #endif +#ifndef _ITICKABLE_H_ +#include "core/iTickable.h" +#endif +class ContextAction; struct InputEventInfo; struct EventDescriptor @@ -48,6 +52,7 @@ struct EventDescriptor class ActionMap : public SimObject { typedef SimObject Parent; + friend class ContextAction; protected: bool onAdd(); @@ -62,7 +67,9 @@ class ActionMap : public SimObject HasDeadZone = BIT(2), ///< Dead zone is present. Inverted = BIT(3), ///< Input is inverted. NonLinear = BIT(4), ///< Input should be re-fit to a non-linear scale - BindCmd = BIT(5) ///< Bind a console command to this. + BindCmd = BIT(5), ///< Bind a console command to this. + Held = BIT(6), + DoubleTap = BIT(7) }; U32 flags; ///< @see Node::Flags @@ -75,6 +82,7 @@ class ActionMap : public SimObject char *makeConsoleCommand; ///< Console command to execute when we make this command. char *breakConsoleCommand; ///< Console command to execute when we break this command. + ContextAction* contextEvent; ///< Event that kicks off via context-keybind actions such as holding or double-tapping }; /// Used to represent a devices. @@ -143,6 +151,7 @@ class ActionMap : public SimObject bool processBind(const U32 argc, const char** argv, SimObject* object = NULL); bool processBindCmd(const char *device, const char *action, const char *makeCmd, const char *breakCmd); bool processUnbind(const char *device, const char *action, SimObject* object = NULL); + bool processHoldBind(const char *device, const char *action, const char *holdFunc, const char *tapFunc, const U32 holdTime, const bool holdOnly, const bool returnHoldTime = false); /// @name Console Interface Functions /// @{ @@ -185,4 +194,28 @@ class ActionMap : public SimObject DECLARE_CONOBJECT(ActionMap); }; +class ContextAction : public ITickable +{ + ActionMap::Node* mButton; ///< our button we're holding + F32 mMinHoldTime; ///< minimum time to qualify as 'held'. If we hold less than this, + ///< it's a 'press', otherwise it's a 'held' +public: + F32 mStartTime; ///< Our timestamp when we first pressed. + F32 mEventValue; ///< Event value from our key event. + StringTableEntry mConsoleFunctionHeld; ///< Console function to call with new values if we held over + ///< a certain time. + + bool mHoldOnly; ///< does this only care if we're holding? + ///< true means that it only fires a function while holding + ///< false time-contexts it + bool mBreakEvent; ///< Button is no longer being pressed! + bool mDidHold; ///< did we, at some point in the process, hold the button? + bool mActive; ///< do we be tickin? + bool mReturnHoldTime; ///< Do we return back our time held? + + ContextAction(StringTableEntry func, F32 minHoldTime, ActionMap::Node* button, bool holdOnly); + virtual void processTick(); + virtual void interpolateTick(F32 delta) {} + virtual void advanceTime(F32 timeDelta) {} +}; #endif // _ACTIONMAP_H_ diff --git a/Engine/source/sim/netObject.cpp b/Engine/source/sim/netObject.cpp index 9a7618d08..a77869883 100644 --- a/Engine/source/sim/netObject.cpp +++ b/Engine/source/sim/netObject.cpp @@ -500,6 +500,96 @@ void NetObject::removeScopeRef() } #endif +//Networked fields +//------------------------------------------------------------------ +void NetObject::addNetworkedField(const char* in_pFieldname, + const U32 in_fieldType, + const dsize_t in_fieldOffset, + const char* in_pFieldDocs, + U32 flags, + U32 networkMask) +{ + addNetworkedField( + in_pFieldname, + in_fieldType, + in_fieldOffset, + 1, + in_pFieldDocs, + flags, + networkMask); +} + +void NetObject::addNetworkedField(const char* in_pFieldname, + const U32 in_fieldType, + const dsize_t in_fieldOffset, + AbstractClassRep::WriteDataNotify in_writeDataFn, + const char* in_pFieldDocs, + U32 flags, + U32 networkMask) +{ + addNetworkedField( + in_pFieldname, + in_fieldType, + in_fieldOffset, + in_writeDataFn, + 1, + in_pFieldDocs, + flags, + networkMask); +} + +void NetObject::addNetworkedField(const char* in_pFieldname, + const U32 in_fieldType, + const dsize_t in_fieldOffset, + const U32 in_elementCount, + const char* in_pFieldDocs, + U32 flags, + U32 networkMask) +{ + addNetworkedField(in_pFieldname, + in_fieldType, + in_fieldOffset, + &defaultProtectedWriteFn, + in_elementCount, + in_pFieldDocs, + flags, + networkMask); +} + +void NetObject::addNetworkedField(const char* in_pFieldname, + const U32 in_fieldType, + const dsize_t in_fieldOffset, + AbstractClassRep::WriteDataNotify in_writeDataFn, + const U32 in_elementCount, + const char* in_pFieldDocs, + U32 flags, + U32 networkMask) +{ + AbstractClassRep::Field f; + f.pFieldname = StringTable->insert(in_pFieldname); + + if (in_pFieldDocs) + f.pFieldDocs = in_pFieldDocs; + + f.type = in_fieldType; + f.offset = in_fieldOffset; + f.elementCount = in_elementCount; + f.validator = NULL; + f.flag = flags; + + f.setDataFn = &defaultProtectedSetFn; + f.getDataFn = &defaultProtectedGetFn; + f.writeDataFn = in_writeDataFn; + + f.networkMask = networkMask; + + ConsoleBaseType* conType = ConsoleBaseType::getType(in_fieldType); + AssertFatal(conType, "ConsoleObject::addField - invalid console type"); + f.table = conType->getEnumTable(); + + sg_tempFieldList.push_back(f); +} + DefineEngineMethod(NetObject, clearScopeAlways, void, (), , "@brief Clears the scope always flag on this object.\n\n") { diff --git a/Engine/source/sim/netObject.h b/Engine/source/sim/netObject.h index a486936be..7ea1283c4 100644 --- a/Engine/source/sim/netObject.h +++ b/Engine/source/sim/netObject.h @@ -422,6 +422,57 @@ public: void removeScopeRef(); void setScopeRegistered(bool flag) { scope_registered = flag; } bool getScopeRegistered() const { return scope_registered; } + +protected: + /// Add a networked field + /// + /// A networked field is a regular field but with a bitmask flag associated to it. + /// When the field is set, it automatically triggers a call to setMaskBits with the mask associated to the field + /// in order to streamline simple networking code + /// Register a complex field. + /// + /// @param in_pFieldname Name of the field. + /// @param in_fieldType Type of the field. @see ConsoleDynamicTypes + /// @param in_fieldOffset Offset to the field from the start of the class; calculated using the Offset() macro. + /// @param in_elementCount Number of elements in this field. Arrays of elements are assumed to be contiguous in memory. + /// @param in_pFieldDocs Usage string for this field. @see console_autodoc + static void addNetworkedField(const char* in_pFieldname, + const U32 in_fieldType, + const dsize_t in_fieldOffset, + const U32 in_elementCount = 1, + const char* in_pFieldDocs = NULL, + U32 flags = 0, + U32 networkMask = 0); + + static void addNetworkedField(const char* in_pFieldname, + const U32 in_fieldType, + const dsize_t in_fieldOffset, + AbstractClassRep::WriteDataNotify in_writeDataFn, + const U32 in_elementCount = 1, + const char* in_pFieldDocs = NULL, + U32 flags = 0, + U32 networkMask = 0); + + /// Register a simple field. + /// + /// @param in_pFieldname Name of the field. + /// @param in_fieldType Type of the field. @see ConsoleDynamicTypes + /// @param in_fieldOffset Offset to the field from the start of the class; calculated using the Offset() macro. + /// @param in_pFieldDocs Usage string for this field. @see console_autodoc + static void addNetworkedField(const char* in_pFieldname, + const U32 in_fieldType, + const dsize_t in_fieldOffset, + const char* in_pFieldDocs, + U32 flags = 0, + U32 networkMask = 0); + + static void addNetworkedField(const char* in_pFieldname, + const U32 in_fieldType, + const dsize_t in_fieldOffset, + AbstractClassRep::WriteDataNotify in_writeDataFn, + const char* in_pFieldDocs, + U32 flags = 0, + U32 networkMask = 0); }; //----------------------------------------------------------------------------- diff --git a/Engine/source/ts/collada/colladaImport.cpp b/Engine/source/ts/collada/colladaImport.cpp index f3aea309e..1cc2909b0 100644 --- a/Engine/source/ts/collada/colladaImport.cpp +++ b/Engine/source/ts/collada/colladaImport.cpp @@ -198,7 +198,7 @@ DefineConsoleFunction( enumColladaForImport, bool, (const char * shapePath, cons for (S32 j = 0; j < libraryMats->getMaterial_array().getCount(); j++) { domMaterial* mat = libraryMats->getMaterial_array()[j]; - tree->insertItem(matsID, _GetNameOrId(mat), _GetNameOrId(mat), "", 0, 0); + tree->insertItem(matsID, _GetNameOrId(mat), "", "", 0, 0); } } @@ -256,5 +256,16 @@ DefineConsoleFunction( enumColladaForImport, bool, (const char * shapePath, cons else tree->setDataField(StringTable->insert("_upAxis"), 0, "Z_AXIS"); + char shapesStr[16]; + dSprintf(shapesStr, 16, "%i", stats.numMeshes); + char materialsStr[16]; + dSprintf(materialsStr, 16, "%i", stats.numMaterials); + char animationsStr[16]; + dSprintf(animationsStr, 16, "%i", stats.numClips); + + tree->setItemValue(nodesID, StringTable->insert(shapesStr)); + tree->setItemValue(matsID, StringTable->insert(materialsStr)); + tree->setItemValue(animsID, StringTable->insert(animationsStr)); + return true; } diff --git a/Templates/BaseGame/game/tools/base/images/sky_skybox.dml b/Templates/BaseGame/game/tools/base/images/sky_skybox.dml deleted file mode 100644 index 5ca0a1cb6..000000000 --- a/Templates/BaseGame/game/tools/base/images/sky_skybox.dml +++ /dev/null @@ -1,7 +0,0 @@ -skybox_1 -skybox_2 -skybox_3 -skybox_4 -skybox_5 -skybox_6 -skybox_6 \ No newline at end of file diff --git a/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditorActions.ed.cs b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditorActions.ed.cs index 3847226f6..15bd4cc9b 100644 --- a/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditorActions.ed.cs +++ b/Templates/BaseGame/game/tools/shapeEditor/scripts/shapeEditorActions.ed.cs @@ -346,10 +346,11 @@ function ActionAddSequence::doit( %this ) %assetDef = AssetDatabase.acquireAsset(%this.seqName); %moduleName = getWord(getToken(%this.seqName, ":", 0),0); - %idx = ShapeEdSequenceList.rowCount(); + //TODO, properly ignore and ambient entries for our idx values, but only if they're there! + %idx = ShapeEdSequenceList.rowCount() - 2; - %matSet = "ShapeEditorPlugin.selectedAssetDef.animationSequence"@%idx@"=\"@Asset="@%moduleName@":"@%this.seqName.assetName@"\";"; - eval(%matSet); + %animSet = "ShapeEditorPlugin.selectedAssetDef.animationSequence"@%idx@"=\"@Asset="@%moduleName@":"@%assetDef.assetName@"\";"; + eval(%animSet); %assetPath = AssetDatabase.getAssetFilePath(ShapeEditorPlugin.selectedAssetId); @@ -357,6 +358,9 @@ function ActionAddSequence::doit( %this ) AssetDatabase.refreshAsset(ShapeEditorPlugin.selectedAssetId); + //force a refresh + ShapeEdPropWindow.update_onShapeSelectionChanged(); + return true; } return false; diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/editorPrefs.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/editorPrefs.ed.cs index 1704e06ad..876ae120a 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/editorPrefs.ed.cs +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/editorPrefs.ed.cs @@ -34,7 +34,6 @@ EditorSettings.setDefaultValue( "orthoFOV", "50" ); EditorSettings.setDefaultValue( "orthoShowGrid", "1" ); EditorSettings.setDefaultValue( "currentEditor", "WorldEditorInspectorPlugin" ); EditorSettings.setDefaultValue( "newLevelFile", "tools/levels/BlankRoom.mis" ); -EditorSettings.setDefaultValue( "newGameObjectDir", "scripts/server/gameObjects" ); if( isFile( "C:/Program Files/Torsion/Torsion.exe" ) ) EditorSettings.setDefaultValue( "torsionPath", "C:/Program Files/Torsion/Torsion.exe" ); @@ -128,7 +127,7 @@ EditorSettings.setDefaultValue( "renderInfoText", "1" ); EditorSettings.beginGroup( "Grid" ); EditorSettings.setDefaultValue( "gridColor", "255 255 255 20" ); -EditorSettings.setDefaultValue( "gridSize", "10 10 10" ); +EditorSettings.setDefaultValue( "gridSize", "1 1 1" ); EditorSettings.setDefaultValue( "snapToGrid", "0" ); //<-- Not currently used EditorSettings.setDefaultValue( "renderPlane", "0" ); EditorSettings.setDefaultValue( "renderPlaneHashes", "0" ); diff --git a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.cs b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.cs index 0e2813d57..006031668 100644 --- a/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.cs +++ b/Templates/BaseGame/game/tools/worldEditor/scripts/editors/creator.ed.cs @@ -304,36 +304,6 @@ function EWCreatorWindow::navigate( %this, %address ) %this.addShapeIcon( %obj ); } } - - //Add a separate folder for Game Objects - if(isClass("Entity")) - { - if(%address $= "") - { - %this.addFolderIcon("GameObjects"); - } - else - { - //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); - - %gameObjectAsset = AssetDatabase.acquireAsset(%assetId); - - if(isFile(%gameObjectAsset.TAMLFilePath)) - { - %this.addGameObjectIcon( %gameObjectAsset.gameObjectName ); - } - } - } - } } if ( %this.tab $= "Meshes" ) @@ -768,22 +738,6 @@ function EWCreatorWindow::addPrefabIcon( %this, %fullPath ) %this.contentCtrl.addGuiControl( %ctrl ); } -function EWCreatorWindow::addGameObjectIcon( %this, %gameObjectName ) -{ - %ctrl = %this.createIcon(); - - %ctrl.altCommand = "spawnGameObject( \"" @ %gameObjectName @ "\", true );"; - %ctrl.iconBitmap = EditorIconRegistry::findIconByClassName( "Prefab" ); - %ctrl.text = %gameObjectName; - %ctrl.class = "CreatorGameObjectIconBtn"; - %ctrl.tooltip = "Spawn the " @ %gameObjectName @ " GameObject"; - - %ctrl.buttonType = "radioButton"; - %ctrl.groupNum = "-1"; - - %this.contentCtrl.addGuiControl( %ctrl ); -} - function CreatorPopupMenu::onSelect( %this, %id, %text ) { %split = strreplace( %text, "/", " " ); diff --git a/Templates/Full/game/art/shapes/weapons/Ryder/TP_Ryder_S.dds b/Templates/Full/game/art/shapes/weapons/Ryder/TP_Ryder_S.dds new file mode 100644 index 000000000..9b7688e7e Binary files /dev/null and b/Templates/Full/game/art/shapes/weapons/Ryder/TP_Ryder_S.dds differ diff --git a/Templates/Full/game/art/shapes/weapons/Ryder/materials.cs b/Templates/Full/game/art/shapes/weapons/Ryder/materials.cs index 3661bcae1..47dc020ea 100644 --- a/Templates/Full/game/art/shapes/weapons/Ryder/materials.cs +++ b/Templates/Full/game/art/shapes/weapons/Ryder/materials.cs @@ -39,7 +39,7 @@ singleton Material(TP_Ryder_Base) mapTo = "TP_Ryder_Base"; diffuseMap[0] = "./TP_Ryder_D.dds"; normalMap[0] = "./TP_Ryder_N.dds"; - specularMap[0] = "./TP_Ryder_D.dds"; + specularMap[0] = "./TP_Ryder_S.dds"; specular[0] = "1.0 1.0 1.0 1"; specularPower[0] = "10"; translucentBlendOp = "None"; diff --git a/Templates/Full/game/art/shapes/weapons/Turret/materials.cs b/Templates/Full/game/art/shapes/weapons/Turret/materials.cs index 4ed4768d9..95b361714 100644 --- a/Templates/Full/game/art/shapes/weapons/Turret/materials.cs +++ b/Templates/Full/game/art/shapes/weapons/Turret/materials.cs @@ -29,7 +29,7 @@ singleton Material(Turret_Base) translucentBlendOp = "None"; normalMap[0] = "art/shapes/weapons/Turret/Turret_N.dds"; pixelSpecular[0] = "1"; - specularMap[0] = "art/shapes/weapons/Turret/Turret_D.dds"; + specularMap[0] = "art/shapes/weapons/Turret/Turret_S.dds"; useAnisotropic[0] = "1"; castDynamicShadows = true; materialTag0 = "Weapon"; diff --git a/Templates/Full/game/tools/worldEditor/scripts/EditorGui.ed.cs b/Templates/Full/game/tools/worldEditor/scripts/EditorGui.ed.cs index 535d00880..2d9e2ec53 100644 --- a/Templates/Full/game/tools/worldEditor/scripts/EditorGui.ed.cs +++ b/Templates/Full/game/tools/worldEditor/scripts/EditorGui.ed.cs @@ -1302,6 +1302,7 @@ function VisibilityDropdownToggle() { EVisibility.setVisible(true); visibilityToggleBtn.setStateOn(1); + EVisibility.setExtent("200 540"); } } @@ -1569,6 +1570,27 @@ function EditorTree::onRightMouseUp( %this, %itemId, %mouse, %obj ) %haveObjectEntries = false; %haveLockAndHideEntries = true; + //Set up the generic pop-up pre-emptively if we haven't already + if( !isObject( ETContextPopup ) ) + { + %popup = new PopupMenu( ETContextPopup ) + { + superClass = "MenuBuilder"; + isPopup = "1"; + + item[ 0 ] = "Rename" TAB "" TAB "EditorTree.showItemRenameCtrl( EditorTree.findItemByObjectId( %this.object ) );"; + item[ 1 ] = "Delete" TAB "" TAB "EWorldEditor.deleteMissionObject( %this.object );"; + item[ 2 ] = "Inspect" TAB "" TAB "inspectObject( %this.object );"; + item[ 3 ] = "-"; + item[ 4 ] = "Locked" TAB "" TAB "%this.object.setLocked( !%this.object.locked ); EWorldEditor.syncGui();"; + item[ 5 ] = "Hidden" TAB "" TAB "EWorldEditor.hideObject( %this.object, !%this.object.hidden ); EWorldEditor.syncGui();"; + item[ 6 ] = "-"; + item[ 7 ] = "Group" TAB "" TAB "EWorldEditor.addSimGroup( true );"; + + object = -1; + }; + } + // Handle multi-selection. if( %this.getSelectedItemsCount() > 1 ) { @@ -1615,12 +1637,67 @@ function EditorTree::onRightMouseUp( %this, %itemId, %mouse, %obj ) item[ 0 ] = "Add Camera Bookmark" TAB "" TAB "EditorGui.addCameraBookmarkByGui();"; }; } + + else if(%obj.isMemberOfClass("Entity")) + { + %popup = EntityObjectPopup; + if(!isObject(EntityObjectPopup)) + { + %popup = new PopupMenu( EntityObjectPopup ) + { + superClass = "MenuBuilder"; + isPopup = "1"; + + item[ 0 ] = "Rename" TAB "" TAB "EditorTree.showItemRenameCtrl( EditorTree.findItemByObjectId( %this.object ) );"; + item[ 1 ] = "Delete" TAB "" TAB "EWorldEditor.deleteMissionObject( %this.object );"; + item[ 2 ] = "Inspect" TAB "" TAB "inspectObject( %this.object );"; + item[ 3 ] = "-"; + item[ 4 ] = "Toggle Lock Children" TAB "" TAB "EWorldEditor.toggleLockChildren( %this.object );"; + item[ 5 ] = "Toggle Hide Children" TAB "" TAB "EWorldEditor.toggleHideChildren( %this.object );"; + item[ 6 ] = "-"; + item[ 7 ] = "Group" TAB "" TAB "EWorldEditor.addSimGroup( true );"; + item[ 8 ] = "-"; + item[ 9 ] = "Add New Objects Here" TAB "" TAB "EWCreatorWindow.setNewObjectGroup( %this.object );"; + item[ 10 ] = "Add Children to Selection" TAB "" TAB "EWorldEditor.selectAllObjectsInSet( %this.object, false );"; + item[ 11 ] = "Remove Children from Selection" TAB "" TAB "EWorldEditor.selectAllObjectsInSet( %this.object, true );"; + item[ 12 ] = "-"; + item[ 13 ] = "Convert to Game Object" TAB "" TAB "EWorldEditor.createGameObject( %this.object );"; + item[ 14 ] = "Duplicate Game Object" TAB "" TAB "EWorldEditor.duplicateGameObject( %this.object );"; + item[ 15 ] = "Show in Asset Browser" TAB "" TAB "EWorldEditor.showGameObjectInAssetBrowser( %this.object );"; + + object = -1; + }; + } + + if(!isObject(AssetDatabase.acquireAsset(%obj.gameObjectAsset))) + { + EntityObjectPopup.enableItem(13, true); + EntityObjectPopup.enableItem(14, false); + EntityObjectPopup.enableItem(15, false); + } + else + { + EntityObjectPopup.enableItem(13, false); + EntityObjectPopup.enableItem(14, true); + EntityObjectPopup.enableItem(15, true); + } + + %popup.object = %obj; + + %hasChildren = %obj.getCount() > 0; + %popup.enableItem( 10, %hasChildren ); + %popup.enableItem( 11, %hasChildren ); + + %haveObjectEntries = true; + %haveLockAndHideEntries = false; + } // Open context menu if this is a SimGroup else if( !%obj.isMemberOfClass( "SceneObject" ) ) { %popup = ETSimGroupContextPopup; if( !isObject( %popup ) ) + { %popup = new PopupMenu( ETSimGroupContextPopup ) { superClass = "MenuBuilder"; @@ -1641,6 +1718,7 @@ function EditorTree::onRightMouseUp( %this, %itemId, %mouse, %obj ) object = -1; }; + } %popup.object = %obj; @@ -1652,77 +1730,56 @@ function EditorTree::onRightMouseUp( %this, %itemId, %mouse, %obj ) %haveLockAndHideEntries = false; } - // Open generic context menu. - else + // Specialized version for ConvexShapes. + else if( %obj.isMemberOfClass( "ConvexShape" ) ) { - %popup = ETContextPopup; + %popup = ETConvexShapeContextPopup; if( !isObject( %popup ) ) - %popup = new PopupMenu( ETContextPopup ) + { + %popup = new PopupMenu( ETConvexShapeContextPopup : ETContextPopup ) { superClass = "MenuBuilder"; isPopup = "1"; - item[ 0 ] = "Rename" TAB "" TAB "EditorTree.showItemRenameCtrl( EditorTree.findItemByObjectId( %this.object ) );"; - item[ 1 ] = "Delete" TAB "" TAB "EWorldEditor.deleteMissionObject( %this.object );"; - item[ 2 ] = "Inspect" TAB "" TAB "inspectObject( %this.object );"; - item[ 3 ] = "-"; - item[ 4 ] = "Locked" TAB "" TAB "%this.object.setLocked( !%this.object.locked ); EWorldEditor.syncGui();"; - item[ 5 ] = "Hidden" TAB "" TAB "EWorldEditor.hideObject( %this.object, !%this.object.hidden ); EWorldEditor.syncGui();"; - item[ 6 ] = "-"; - item[ 7 ] = "Group" TAB "" TAB "EWorldEditor.addSimGroup( true );"; - - object = -1; + item[ 8 ] = "-"; + item[ 9 ] = "Convert to Zone" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"Zone\" );"; + item[ 10 ] = "Convert to Portal" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"Portal\" );"; + item[ 11 ] = "Convert to Occluder" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"OcclusionVolume\" );"; + item[ 12 ] = "Convert to Sound Space" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"SFXSpace\" );"; }; - - if(%obj.isMemberOfClass("Entity")) - { - %popup = ETEntityContextPopup; - if( !isObject( %popup ) ) - %popup = new PopupMenu( ETEntityContextPopup : ETSimGroupContextPopup ) - { - superClass = "MenuBuilder"; - isPopup = "1"; - - item[ 12 ] = "-"; - item[ 13 ] = "Convert to Game Object" TAB "" TAB "EWorldEditor.createGameObject( %this.object );"; - }; - } - - // Specialized version for ConvexShapes. - else if( %obj.isMemberOfClass( "ConvexShape" ) ) - { - %popup = ETConvexShapeContextPopup; - if( !isObject( %popup ) ) - %popup = new PopupMenu( ETConvexShapeContextPopup : ETContextPopup ) - { - superClass = "MenuBuilder"; - isPopup = "1"; - - item[ 8 ] = "-"; - item[ 9 ] = "Convert to Zone" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"Zone\" );"; - item[ 10 ] = "Convert to Portal" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"Portal\" );"; - item[ 11 ] = "Convert to Occluder" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"OcclusionVolume\" );"; - item[ 12 ] = "Convert to Sound Space" TAB "" TAB "EWorldEditor.convertSelectionToPolyhedralObjects( \"SFXSpace\" );"; - }; } - // Specialized version for polyhedral objects. - else if( %obj.isMemberOfClass( "Zone" ) || - %obj.isMemberOfClass( "Portal" ) || - %obj.isMemberOfClass( "OcclusionVolume" ) || - %obj.isMemberOfClass( "SFXSpace" ) ) + %popup.object = %obj; + %haveObjectEntries = true; + } + + // Specialized version for polyhedral objects. + else if( %obj.isMemberOfClass( "Zone" ) || + %obj.isMemberOfClass( "Portal" ) || + %obj.isMemberOfClass( "OcclusionVolume" ) || + %obj.isMemberOfClass( "SFXSpace" ) ) + { + %popup = ETPolyObjectContextPopup; + if( !isObject( %popup ) ) { - %popup = ETPolyObjectContextPopup; - if( !isObject( %popup ) ) - %popup = new PopupMenu( ETPolyObjectContextPopup : ETContextPopup ) - { - superClass = "MenuBuilder"; - isPopup = "1"; + %popup = new PopupMenu( ETPolyObjectContextPopup : ETContextPopup ) + { + superClass = "MenuBuilder"; + isPopup = "1"; - item[ 8 ] = "-"; - item[ 9 ] = "Convert to ConvexShape" TAB "" TAB "EWorldEditor.convertSelectionToConvexShape();"; - }; + item[ 8 ] = "-"; + item[ 9 ] = "Convert to ConvexShape" TAB "" TAB "EWorldEditor.convertSelectionToConvexShape();"; + }; } + + %popup.object = %obj; + %haveObjectEntries = true; + } + + // Open generic context menu. + else + { + %popup = ETContextPopup; %popup.object = %obj; %haveObjectEntries = true; @@ -2253,155 +2310,6 @@ function EWorldEditor::deleteMissionObject( %this, %object ) EditorTree.buildVisibleTree( true ); } -function EWorldEditor::createGameObject( %this, %entity ) -{ - if(!isObject(GameObjectBuilder)) - { - new GuiControl(GameObjectBuilder, EditorGuiGroup) { - profile = "ToolsGuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "0 0"; - extent = "800 600"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - - new GuiWindowCtrl(GameObjectBuilderTargetWindow) { - profile = "ToolsGuiWindowProfile"; - horizSizing = "center"; - vertSizing = "center"; - position = "384 205"; - extent = "256 102"; - minExtent = "256 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - resizeWidth = "1"; - resizeHeight = "1"; - canMove = "1"; - canClose = "0"; - canMinimize = "0"; - canMaximize = "0"; - minSize = "50 50"; - text = "Create Object"; - - new GuiTextCtrl() { - profile = "GuiCenterTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "9 26"; - extent = "84 16"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - text = "Object Name:"; - }; - new GuiTextEditCtrl(GameObjectBuilderObjectName) { - class = ObjectBuilderGuiTextEditCtrl; - profile = "ToolsGuiTextEditProfile"; - horizSizing = "width"; - vertSizing = "bottom"; - position = "78 26"; - extent = "172 18"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - helpTag = "0"; - historySize = "0"; - }; - new GuiButtonCtrl(GameObjectBuilderOKButton) { - profile = "ToolsGuiButtonProfile"; - horizSizing = "width"; - vertSizing = "bottom"; - position = "7 250"; - extent = "156 24"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - command = "EWorldEditor.buildGameObject();"; - helpTag = "0"; - text = "Create New"; - Accelerator = "return"; - }; - new GuiButtonCtrl(GameObjectBuilderCancelButton) { - profile = "ToolsGuiButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "170 250"; - extent = "80 24"; - minExtent = "8 8"; - visible = "1"; - setFirstResponder = "0"; - modal = "1"; - command = "Canvas.popDialog(GameObjectBuilder);"; - helpTag = "0"; - text = "Cancel"; - Accelerator = "escape"; - }; - }; - }; - - GameObjectBuilderTargetWindow.extent = getWord(GameObjectBuilderTargetWindow.extent, 0) SPC 88; - GameObjectBuilderOKButton.position = getWord(GameObjectBuilderOKButton.position, 0) SPC 57; - GameObjectBuilderCancelButton.position = getWord(GameObjectBuilderCancelButton.position, 0) SPC 57; - } - - GameObjectBuilderObjectName.text = ""; - GameObjectBuilder.selectedEntity = %entity; - - Canvas.pushDialog(GameObjectBuilder); -} - -function EWorldEditor::buildGameObject(%this) -{ - if(GameObjectBuilderObjectName.getText() $= "") - { - error("Attempted to make a new Game Object with no name!"); - Canvas.popDialog(GameObjectBuilder); - return; - } - - %path = EditorSettings.value( "WorldEditor/newGameObjectDir" ); - %className = GameObjectBuilderObjectName.getText(); - GameObjectBuilder.selectedEntity.class = %className; - Inspector.inspect(GameObjectBuilder.selectedEntity); - - %file = new FileObject(); - - if(%file.openForWrite(%path @ "\\" @ %className @ ".cs")) - { - %file.writeline("function " @ %className @ "::onAdd(%this)\n{\n\n}\n"); - %file.writeline("function " @ %className @ "::onRemove(%this)\n{\n\n}\n"); - - //todo, pre-write any event functions of interest - - %file.close(); - } - - //set up the paths - %tamlPath = %path @ "/" @ %className @ ".taml"; - %scriptPath = %path @ "/" @ %className @ ".cs"; - saveGameObject(%className, %tamlPath, %scriptPath); - - //reload it - execGameObjects(); - - //now, add the script file and a ref to the taml into our SGO manifest so we can readily spawn it later. - TamlWrite(GameObjectBuilder.selectedEntity, %tamlpath); - - GameObjectBuilder.selectedEntity = ""; - - Canvas.popDialog(GameObjectBuilder); -} - function EWorldEditor::selectAllObjectsInSet( %this, %set, %deselect ) { if( !isObject( %set ) ) diff --git a/Templates/Full/game/tools/worldEditor/scripts/editorPrefs.ed.cs b/Templates/Full/game/tools/worldEditor/scripts/editorPrefs.ed.cs index 35cc85edb..876ae120a 100644 --- a/Templates/Full/game/tools/worldEditor/scripts/editorPrefs.ed.cs +++ b/Templates/Full/game/tools/worldEditor/scripts/editorPrefs.ed.cs @@ -34,7 +34,6 @@ EditorSettings.setDefaultValue( "orthoFOV", "50" ); EditorSettings.setDefaultValue( "orthoShowGrid", "1" ); EditorSettings.setDefaultValue( "currentEditor", "WorldEditorInspectorPlugin" ); EditorSettings.setDefaultValue( "newLevelFile", "tools/levels/BlankRoom.mis" ); -EditorSettings.setDefaultValue( "newGameObjectDir", "scripts/server/gameObjects" ); if( isFile( "C:/Program Files/Torsion/Torsion.exe" ) ) EditorSettings.setDefaultValue( "torsionPath", "C:/Program Files/Torsion/Torsion.exe" ); diff --git a/Templates/Full/game/tools/worldEditor/scripts/editors/creator.ed.cs b/Templates/Full/game/tools/worldEditor/scripts/editors/creator.ed.cs index 0e2813d57..006031668 100644 --- a/Templates/Full/game/tools/worldEditor/scripts/editors/creator.ed.cs +++ b/Templates/Full/game/tools/worldEditor/scripts/editors/creator.ed.cs @@ -304,36 +304,6 @@ function EWCreatorWindow::navigate( %this, %address ) %this.addShapeIcon( %obj ); } } - - //Add a separate folder for Game Objects - if(isClass("Entity")) - { - if(%address $= "") - { - %this.addFolderIcon("GameObjects"); - } - else - { - //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); - - %gameObjectAsset = AssetDatabase.acquireAsset(%assetId); - - if(isFile(%gameObjectAsset.TAMLFilePath)) - { - %this.addGameObjectIcon( %gameObjectAsset.gameObjectName ); - } - } - } - } } if ( %this.tab $= "Meshes" ) @@ -768,22 +738,6 @@ function EWCreatorWindow::addPrefabIcon( %this, %fullPath ) %this.contentCtrl.addGuiControl( %ctrl ); } -function EWCreatorWindow::addGameObjectIcon( %this, %gameObjectName ) -{ - %ctrl = %this.createIcon(); - - %ctrl.altCommand = "spawnGameObject( \"" @ %gameObjectName @ "\", true );"; - %ctrl.iconBitmap = EditorIconRegistry::findIconByClassName( "Prefab" ); - %ctrl.text = %gameObjectName; - %ctrl.class = "CreatorGameObjectIconBtn"; - %ctrl.tooltip = "Spawn the " @ %gameObjectName @ " GameObject"; - - %ctrl.buttonType = "radioButton"; - %ctrl.groupNum = "-1"; - - %this.contentCtrl.addGuiControl( %ctrl ); -} - function CreatorPopupMenu::onSelect( %this, %id, %text ) { %split = strreplace( %text, "/", " " ); diff --git a/Templates/Modules/FPSGameplay/art/environment/precipitation/rain.dml b/Templates/Modules/FPSGameplay/art/environment/precipitation/rain.dml deleted file mode 100644 index 3893393dd..000000000 --- a/Templates/Modules/FPSGameplay/art/environment/precipitation/rain.dml +++ /dev/null @@ -1 +0,0 @@ -rain diff --git a/Templates/Modules/FPSGameplay/art/shapes/weapons/Ryder/TP_Ryder_S.dds b/Templates/Modules/FPSGameplay/art/shapes/weapons/Ryder/TP_Ryder_S.dds new file mode 100644 index 000000000..9b7688e7e Binary files /dev/null and b/Templates/Modules/FPSGameplay/art/shapes/weapons/Ryder/TP_Ryder_S.dds differ diff --git a/Templates/Modules/FPSGameplay/art/shapes/weapons/Ryder/materials.cs b/Templates/Modules/FPSGameplay/art/shapes/weapons/Ryder/materials.cs index 3661bcae1..47dc020ea 100644 --- a/Templates/Modules/FPSGameplay/art/shapes/weapons/Ryder/materials.cs +++ b/Templates/Modules/FPSGameplay/art/shapes/weapons/Ryder/materials.cs @@ -39,7 +39,7 @@ singleton Material(TP_Ryder_Base) mapTo = "TP_Ryder_Base"; diffuseMap[0] = "./TP_Ryder_D.dds"; normalMap[0] = "./TP_Ryder_N.dds"; - specularMap[0] = "./TP_Ryder_D.dds"; + specularMap[0] = "./TP_Ryder_S.dds"; specular[0] = "1.0 1.0 1.0 1"; specularPower[0] = "10"; translucentBlendOp = "None"; diff --git a/Templates/Modules/FPSGameplay/art/shapes/weapons/Turret/materials.cs b/Templates/Modules/FPSGameplay/art/shapes/weapons/Turret/materials.cs index 3e632d323..f6e8908a9 100644 --- a/Templates/Modules/FPSGameplay/art/shapes/weapons/Turret/materials.cs +++ b/Templates/Modules/FPSGameplay/art/shapes/weapons/Turret/materials.cs @@ -29,7 +29,7 @@ singleton Material(Turret_Base) translucentBlendOp = "None"; normalMap[0] = "data/FPSGameplay/art/shapes/weapons/Turret/Turret_N.dds"; pixelSpecular[0] = "1"; - specularMap[0] = "data/FPSGameplay/art/shapes/weapons/Turret/Turret_D.dds"; + specularMap[0] = "data/FPSGameplay/art/shapes/weapons/Turret/Turret_S.dds"; useAnisotropic[0] = "1"; castDynamicShadows = true; materialTag0 = "Weapon"; diff --git a/Templates/Modules/FPSGameplay/art/skies/Blank_sky/sky_skybox.dml b/Templates/Modules/FPSGameplay/art/skies/Blank_sky/sky_skybox.dml deleted file mode 100644 index 5ca0a1cb6..000000000 --- a/Templates/Modules/FPSGameplay/art/skies/Blank_sky/sky_skybox.dml +++ /dev/null @@ -1,7 +0,0 @@ -skybox_1 -skybox_2 -skybox_3 -skybox_4 -skybox_5 -skybox_6 -skybox_6 \ No newline at end of file diff --git a/Templates/Modules/spectatorGameplay/art/skies/Blank_sky/sky_skybox.dml b/Templates/Modules/spectatorGameplay/art/skies/Blank_sky/sky_skybox.dml deleted file mode 100644 index 5ca0a1cb6..000000000 --- a/Templates/Modules/spectatorGameplay/art/skies/Blank_sky/sky_skybox.dml +++ /dev/null @@ -1,7 +0,0 @@ -skybox_1 -skybox_2 -skybox_3 -skybox_4 -skybox_5 -skybox_6 -skybox_6 \ No newline at end of file