⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fxshapereplicator.cc

📁 五行MMORPG引擎系统V1.0
💻 CC
📖 第 1 页 / 共 3 页
字号:
			ShapePosition = shapePosWorld;

            // Initialise RayCast Search Start/End Positions.
            ShapeStart = ShapeEnd = ShapePosition;
            ShapeStart.z = 2000.f;
            ShapeEnd.z= -2000.f;

            // Is this the Server?
            if (isServerObject())
                // Perform Ray Cast Collision on Server Terrain.
                CollisionResult = gServerContainer.castRay(ShapeStart, ShapeEnd, FXREPLICATOR_COLLISION_MASK, &RayEvent);
            else
                // Perform Ray Cast Collision on Client Terrain.
                CollisionResult = gClientContainer.castRay( ShapeStart, ShapeEnd, FXREPLICATOR_COLLISION_MASK, &RayEvent);

            // Did we hit anything?
            if (CollisionResult)
            {
                // For now, let's pretend we didn't get a collision.
                CollisionResult = false;

                // Yes, so get it's type.
                U32 CollisionType = RayEvent.object->getTypeMask();

                // Check Illegal Placements.
                if (((CollisionType & TerrainObjectType) && !mFieldData.mAllowOnTerrain)    ||
                    ((CollisionType & InteriorObjectType) && !mFieldData.mAllowOnInteriors) ||
                    ((CollisionType & StaticTSObjectType) && !mFieldData.mAllowStatics) ||
                    ((CollisionType & WaterObjectType) && !mFieldData.mAllowOnWater) ) continue;

                // If we collided with water and are not allowing on the water surface then let's find the
                // terrain underneath and pass this on as the original collision else fail.
                //
                // NOTE:- We need to do this on the server/client as appropriate.
                if ((CollisionType & WaterObjectType) && !mFieldData.mAllowWaterSurface)
                {
                    // Is this the Server?
                    if (isServerObject())
                    {
                        // Yes, so do it on the server container.
                        if (!gServerContainer.castRay( ShapeStart, ShapeEnd, FXREPLICATOR_NOWATER_COLLISION_MASK, &RayEvent)) continue;
                    }
                    else
                    {
                        // No, so do it on the client container.
                        if (!gClientContainer.castRay( ShapeStart, ShapeEnd, FXREPLICATOR_NOWATER_COLLISION_MASK, &RayEvent)) continue;
                    }
                }

                // We passed with flying colours so carry on.
                CollisionResult = true;
            }

            // Invalidate if we are below Allowed Terrain Angle.
            if (RayEvent.normal.z < mSin(mDegToRad(90.0f-mFieldData.mAllowedTerrainSlope))) CollisionResult = false;

        // Wait until we get a collision.
        } while(!CollisionResult && --RelocationRetry);

        // Check for Relocation Problem.
        if (RelocationRetry > 0)
        {
            // Adjust Impact point.
            RayEvent.point.z += mFieldData.mOffsetZ;

            // Set New Position.
            ShapePosition = RayEvent.point;
        }
        else
        {
            // Warning.
            Con::warnf(ConsoleLogEntry::General, "[%s] - Could not find satisfactory position for shape '%s' on %s!", getName(), mFieldData.mShapeFile,isServerObject()?"Server":"Client");

            // Unregister Object.
            fxStatic->unregisterObject();

            // Destroy Shape.
            delete fxStatic;

            // Skip to next.
            continue;
        }

        // Get Shape Transform.
        MatrixF XForm = fxStatic->getTransform();

        // Are we aligning to Terrain?
        if (mFieldData.mAlignToTerrain)
        {
            // Yes, so set rotation to Terrain Impact Normal.
            ShapeRotation = RayEvent.normal * mFieldData.mTerrainAlignment;
        }
        else
        {
            // No, so choose a new Rotation (in Radians).
            ShapeRotation.set(  mDegToRad(RandomGen.randF(mFieldData.mShapeRotateMin.x, mFieldData.mShapeRotateMax.x)),
                                mDegToRad(RandomGen.randF(mFieldData.mShapeRotateMin.y, mFieldData.mShapeRotateMax.y)),
                                mDegToRad(RandomGen.randF(mFieldData.mShapeRotateMin.z, mFieldData.mShapeRotateMax.z)));
        }

        // Set Quaternion Roation.
        QRotation.set(ShapeRotation);

        // Set Transform Rotation.
        QRotation.setMatrix(&XForm);

        // Set Position.
        XForm.setColumn(3, ShapePosition);

        // Set Shape Position / Rotation.
        fxStatic->setTransform(XForm);

        // Choose a new Scale.
        F32 scaleX, scaleY, scaleZ;

        // Choose a random X-Scale.
        scaleX = RandomGen.randF(mFieldData.mShapeScaleMin.x, mFieldData.mShapeScaleMax.x);

        // Fix Shape Aspect?
        if ( mFieldData.mFixShapeAspect )
        {
            // Yes, so use Scale-X for all axis.
            scaleY = scaleZ = scaleX;
        }
        else
        {
            // No, so choose Scale-Y/Z.
            scaleY = RandomGen.randF(mFieldData.mShapeScaleMin.y, mFieldData.mShapeScaleMax.y);
            scaleZ = RandomGen.randF(mFieldData.mShapeScaleMin.z, mFieldData.mShapeScaleMax.z);
        }

        // Set Shape Scale.
        ShapeScale.set( scaleX, scaleY, scaleZ );

        // Set Shape Scale.
        fxStatic->setScale(ShapeScale);

        // Lock it.
        fxStatic->setLocked(true);

        // Store Shape in Replicated Shapes Vector.
        mReplicatedShapes[mCurrentShapeCount++] = fxStatic;

    }
}

//------------------------------------------------------------------------------

void fxShapeReplicator::DestroyShapes(void)
{
    // Finish if we didn't create any shapes.
    if (mCurrentShapeCount == 0) return;

    // Remove shapes.
    for (U32 idx = 0; idx < mCurrentShapeCount; idx++)
    {
        fxShapeReplicatedStatic* fxStatic;

        // Fetch the Shape Object.
        fxStatic = mReplicatedShapes[idx];

        // Got a Shape?
        if (fxStatic)
        {
            // Unlock it.
            fxStatic->setLocked(false);

            // Unregister the object.
            fxStatic->unregisterObject();

            // Delete it.
            delete fxStatic;
        }
    }

    // Empty the Replicated Shapes Vector.
    mReplicatedShapes.empty();

    // Reset Shape Count.
    mCurrentShapeCount = 0;
}

//------------------------------------------------------------------------------

void fxShapeReplicator::RenewShapes(void)
{
    // Destroy any shapes.
    DestroyShapes();

    // Don't create shapes on the Server if we don't need interactions.
#ifdef TGE_RPGCLIENT2 /// TGE_RPGIsServerObject
    if (!mFieldData.mInteractions) return;
#else
    if (isServerObject() && !mFieldData.mInteractions) return;
#endif

    // Create Shapes.
    CreateShapes();
}

//------------------------------------------------------------------------------

void fxShapeReplicator::StartUp(void)
{
    // Flag, Client Replication Started.
    mClientReplicationStarted = true;

    // Renew shapes.
    RenewShapes();
}

//------------------------------------------------------------------------------

bool fxShapeReplicator::onAdd()
{
    if(!Parent::onAdd()) return(false);

    // Add the Replicator to the Replicator Set.
    dynamic_cast<SimSet*>(Sim::findObject("fxReplicatorSet"))->addObject(this);

    // Set Default Object Box.
    mObjBox.min.set( -0.5, -0.5, -0.5 );
    mObjBox.max.set(  0.5,  0.5,  0.5 );

    // Reset the World Box.
    resetWorldBox();

    // Are we editing the Mission?
    if(gEditingMission)
    {
        // Yes, so set the Render Transform.
        setRenderTransform(mObjToWorld);

        // Add to Scene.
        addToScene();
        mAddedToScene = true;

        // If we are in the editor and we are on the client then
        // we can manually startup replication.
        if (isClientObject()) mClientReplicationStarted = true;
    }

    // Renew shapes on Server.
    if (isServerObject()) RenewShapes();

    // Return OK.
    return(true);
}

//------------------------------------------------------------------------------

void fxShapeReplicator::onRemove()
{
    // Remove the Replicator from the Replicator Set.
    dynamic_cast<SimSet*>(Sim::findObject("fxReplicatorSet"))->removeObject(this);

    // Are we editing the Mission?
    if(gEditingMission)
    {
        // Yes, so remove from Scene.
        removeFromScene();
        mAddedToScene = false;
    }

    // Destroy Shapes.
    DestroyShapes();

    // Do Parent.
    Parent::onRemove();
}

//------------------------------------------------------------------------------

void fxShapeReplicator::inspectPostApply()
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -