bool TimeOfDay::onAdd() { if ( !Parent::onAdd() ) return false; // The server initializes to the specified starting values. // The client initializes itself to the server time from // unpackUpdate. if ( isServerObject() ) { mTimeOfDay = mStartTimeOfDay; } // We don't use a bounds. setGlobalBounds(); resetWorldBox(); addToScene(); // Lets receive ghost events so we can resolve // the sun object. if ( isClientObject() ) NetConnection::smGhostAlwaysDone.notify( this, &TimeOfDay::_onGhostAlwaysDone ); if ( isServerObject() ) Con::executef( this, "onAdd" ); return true; }
//.logicking >> void StaticShape::updatePhysics() { SAFE_DELETE(mPhysicsRep); if ( PHYSICSMGR) { mShapeInstance->animate(); // Get the interior collision geometry. ConcretePolyList polylist; if (buildPolyList(PLC_Collision, &polylist, getWorldBox(), getWorldSphere())) { polylist.triangulate(); PhysicsCollision *colShape = PHYSICSMGR->createCollision(); colShape->addTriangleMesh( polylist.mVertexList.address(), polylist.mVertexList.size(), polylist.mIndexList.address(), polylist.mIndexList.size() / 3, MatrixF::Identity ); PhysicsWorld *world = PHYSICSMGR->getWorld( isServerObject() ? "server" : "client" ); mPhysicsRep = PHYSICSMGR->createBody(); //.hack - set kinematic flag to prevent crash on deleting static shape in character sweep(deleting Doors) mPhysicsRep->init( colShape, 0, PhysicsBody::BF_KINEMATIC, this, world ); } if (isServerObject()) setMaskBits(PhysicsMask); } }
void Trigger::potentialEnterObject(GameBase* enter) { if( (!mDataBlock || mDataBlock->isClientSide) && isServerObject() ) return; if( (mDataBlock && !mDataBlock->isClientSide) && isGhost() ) return; for (U32 i = 0; i < mObjects.size(); i++) { if (mObjects[i] == enter) return; } if (testObject(enter) == true) { mObjects.push_back(enter); deleteNotify(enter); if(!mEnterCommand.isEmpty()) { String command = String("%obj = ") + enter->getIdString() + ";" + mEnterCommand; Con::evaluate(command.c_str()); } if( mDataBlock ) mDataBlock->onEnterTrigger_callback( this, enter ); } }
void Etherform::addLaserTrailNode(const Point3F& pos) { if( isServerObject() ) return; for(S32 i = 0; i < NUM_ETHERFORM_LASERTRAILS; i++) { if( mLaserTrailList[i] == NULL ) { // set up laserTrail... if( mDataBlock->laserTrailList[i] ) { mLaserTrailList[i] = new MultiNodeLaserBeam(); mLaserTrailList[i]->setPalette(this->getPalette()); mLaserTrailList[i]->onNewDataBlock(mDataBlock->laserTrailList[i], false); if( !mLaserTrailList[i]->registerObject() ) { Con::warnf( ConsoleLogEntry::General, "Could not register laserTrail %d for class: %s",i, mDataBlock->getName() ); delete mLaserTrailList[i]; mLaserTrailList[i] = NULL; } else { mLaserTrailList[i]->addNodes(pos); mLaserTrailList[i]->setRender(true); mLaserTrailList[i]->fade(); } } } else { mLaserTrailList[i]->addNodes(pos); } } }
void WayPoint::setHidden(bool hidden) { // Skip ShapeBase::setHidden (only ever added to scene if in the editor) ShapeBase::Parent::setHidden( hidden ); if(isServerObject()) setMaskBits(UpdateHiddenMask); }
bool GroundPlane::onAdd() { if( !Parent::onAdd() ) return false; if( isClientObject() ) _updateMaterial(); if( mSquareSize < sMIN_SQUARE_SIZE ) { Con::errorf( "GroundPlane - squareSize below threshold; re-setting to %.02f", sMIN_SQUARE_SIZE ); mSquareSize = sMIN_SQUARE_SIZE; } Parent::setScale( VectorF( 1.0f, 1.0f, 1.0f ) ); Parent::setTransform( MatrixF::Identity ); setGlobalBounds(); resetWorldBox(); addToScene(); if ( PHYSICSMGR ) { PhysicsCollision *colShape = PHYSICSMGR->createCollision(); colShape->addPlane( PlaneF( Point3F::Zero, Point3F( 0, 0, 1 ) ) ); PhysicsWorld *world = PHYSICSMGR->getWorld( isServerObject() ? "server" : "client" ); mPhysicsRep = PHYSICSMGR->createBody(); mPhysicsRep->init( colShape, 0, 0, this, world ); } return true; }
bool SFXEmitter::onAdd() { if ( !Parent::onAdd() ) return false; if ( isServerObject() ) { // Validate the data we'll be passing across // the network to the client. mDescription.validate(); } else { _update(); // Do we need to start playback? if ( mPlayOnAdd && mSource ) mSource->play(); } // Setup the bounds. mObjBox.maxExtents = mObjScale; mObjBox.minExtents = mObjScale; mObjBox.minExtents.neg(); resetWorldBox(); addToScene(); return true; }
bool Item::onAdd() { if (!Parent::onAdd() || !mDataBlock) return false; if (mStatic) mAtRest = true; mObjToWorld.getColumn(3,&delta.pos); // Setup the box for our convex object... mObjBox.getCenter(&mConvex.mCenter); mConvex.mSize.x = mObjBox.len_x() / 2.0; mConvex.mSize.y = mObjBox.len_y() / 2.0; mConvex.mSize.z = mObjBox.len_z() / 2.0; mWorkingQueryBox.minExtents.set(-1e9, -1e9, -1e9); mWorkingQueryBox.maxExtents.set(-1e9, -1e9, -1e9); if( !isHidden() && !mSubclassItemHandlesScene ) addToScene(); if (isServerObject()) { if (!mSubclassItemHandlesScene) scriptOnAdd(); } else if (mDataBlock->lightType != NoLight) { mDropTime = Sim::getCurrentTime(); } _updatePhysics(); return true; }
bool PxSingleActor::onNewDataBlock( GameBaseData *dptr ) { // Since onNewDataBlock is actually called before onAdd for client objects // we need to initialize this here. mWorld = dynamic_cast<PxWorld*>( gPhysicsPlugin->getWorld( isServerObject() ? "server" : "client" ) ); if ( !mWorld ) return false; mDataBlock = dynamic_cast<PxSingleActorData*>(dptr); if ( !mDataBlock || !Parent::onNewDataBlock( dptr ) ) return false; if ( isClientObject() ) { if ( mShapeInstance ) SAFE_DELETE(mShapeInstance); mShapeInstance = new TSShapeInstance( mDataBlock->shape, isClientObject() ); } mObjBox = mDataBlock->shape->bounds; resetWorldBox(); // Create the actor. _createActor(); // Must be called by the leaf class (of GameBase) once everything is loaded. scriptOnNewDataBlock(); return true; }
bool NavMesh::onAdd() { if(!Parent::onAdd()) return false; mObjBox.set(Point3F(-1.0f, -1.0f, -1.0f), Point3F( 1.0f, 1.0f, 1.0f)); resetWorldBox(); addToScene(); if(gEditingMission) mNetFlags.set(Ghostable); if(isServerObject()) { mEventManager = new EventManager(); if(!mEventManager->registerObject()) { Con::errorf("Could not register EventManager for NavMesh %d!", getId()); delete mEventManager; } else { mEventManager->setMessageQueue(mEventManager->getIdString()); mEventManager->registerEvent("NavMeshLoad"); mEventManager->registerEvent("NavMeshBuild"); } } load(); return true; }
void SoftBody::createPhysShape() { Physics* physics = Physics::getPhysics(isServerObject()); if (physics) { createUniqVertexList(); PhysSoftInfo physDescr; physDescr.shapeType = PhysInfo::ST_SOFTMESH; physDescr.physPolyList = mPhysPolyList; physDescr.owner = this; physDescr.mass = mDataBlock->mass; physDescr.poseMatchKoef = mDataBlock->poseMatchKoef; for(U8 i=0;i<mDataBlock->attachedPointsNum;i++) { physDescr.attachPoints.push_back(mDataBlock->attachedPoints[i]); } mPhysShape = physics->createPhysShapeSoft(physDescr); mPhysShape->setTransform(mObjToWorld); } }
void Sun::_initCorona() { if ( isServerObject() ) return; // Load texture... if ( mCoronaTextureName.isNotEmpty() ) mCoronaTexture.set( mCoronaTextureName, &GFXDefaultStaticDiffuseProfile, "CoronaTexture" ); // Make stateblock... if ( mCoronaSB.isNull() ) { GFXStateBlockDesc desc; desc.setCullMode( GFXCullNone ); desc.setAlphaTest( true, GFXCmpGreaterEqual, 1 ); desc.setZReadWrite( false, false ); desc.setBlend( true, GFXBlendSrcColor, GFXBlendOne ); desc.samplersDefined = true; desc.samplers[0].textureColorOp = GFXTOPModulate; desc.samplers[0].colorArg1 = GFXTATexture; desc.samplers[0].colorArg2 = GFXTADiffuse; desc.samplers[0].alphaOp = GFXTOPModulate; desc.samplers[0].alphaArg1 = GFXTATexture; desc.samplers[0].alphaArg2 = GFXTADiffuse; mCoronaSB = GFX->createStateBlock(desc); desc.setFillModeWireframe(); mCoronaWireframeSB = GFX->createStateBlock(desc); } }
void TSStatic::processTick( const Move *move ) { AssertFatal( mPlayAmbient && mAmbientThread, "TSSTatic::adanceTime called with nothing to play." ); if ( isServerObject() ) mShapeInstance->advanceTime( TickSec, mAmbientThread ); }
void TSStatic::_updatePhysics() { SAFE_DELETE( mPhysicsRep ); if ( !PHYSICSMGR || mCollisionType == None ) return; PhysicsCollision *colShape = NULL; if ( mCollisionType == Bounds ) { MatrixF offset( true ); offset.setPosition( mShape->center ); colShape = PHYSICSMGR->createCollision(); colShape->addBox( getObjBox().getExtents() * 0.5f * mObjScale, offset ); } else colShape = mShape->buildColShape( mCollisionType == VisibleMesh, getScale() ); if ( colShape ) { PhysicsWorld *world = PHYSICSMGR->getWorld( isServerObject() ? "server" : "client" ); mPhysicsRep = PHYSICSMGR->createBody(); mPhysicsRep->init( colShape, 0, 0, this, world ); mPhysicsRep->setTransform( getTransform() ); } }
void DecalRoad::_onTerrainChanged( U32 type, TerrainBlock* tblock, const Point2I &min, const Point2I &max ) { // The client side object just stores the area that has changed // and waits for the (delayed) update event from the server // to actually perform the update. if ( isClientObject() && tblock->isClientObject() ) { // Convert the min and max into world space. const F32 size = tblock->getSquareSize(); const Point3F pos = tblock->getPosition(); // TODO: I don't think this works right with tiling! Box3F dirty( F32( min.x * size ) + pos.x, F32( min.y * size ) + pos.y, -F32_MAX, F32( max.x * size ) + pos.x, F32( max.y * size ) + pos.y, F32_MAX ); if ( !mTerrainUpdateRect.isValidBox() ) mTerrainUpdateRect = dirty; else mTerrainUpdateRect.intersect( dirty ); } // The server object only updates edges (doesn't clip to geometry) // and schedules an update to be sent to the client. else if ( isServerObject() && tblock->isServerObject() ) { //_generateEdges(); scheduleUpdate( TerrainChangedMask ); } }
//---------------------------------------------------------------------------- U32 FlyingVehicle::getCollisionMask() { if (isServerObject()) return sServerCollisionMask; else return sClientCollisionMask; }
void Forest::applyRadialImpulse( const Point3F &origin, F32 radius, F32 magnitude ) { if ( isServerObject() ) return; // Find all the trees in the radius // then get their accumulators and // push our impulse into them. VectorF impulse( 0, 0, 0 ); ForestWindAccumulator *accumulator = NULL; Vector<TreePlacementInfo> trees; getLocalWindTrees( origin, radius, &trees ); for ( U32 i = 0; i < trees.size(); i++ ) { const TreePlacementInfo &treeInfo = trees[i]; accumulator = WINDMGR->getLocalWind( treeInfo.itemKey ); if ( !accumulator ) continue; impulse = treeInfo.pos - origin; impulse.normalize(); impulse *= magnitude; accumulator->applyImpulse( impulse ); } }
//----------------------------------------------------------------------------- // setRibbonDatablock //----------------------------------------------------------------------------- void RibbonNode::setRibbonDatablock(RibbonData* data) { if ( isServerObject() ) { setMaskBits( EmitterDBMask ); } else { Ribbon* pRibbon = NULL; if ( data ) { // Create emitter with new datablock pRibbon = new Ribbon; pRibbon->onNewDataBlock( data, false ); if( pRibbon->registerObject() == false ) { Con::warnf(ConsoleLogEntry::General, "Could not register base ribbon of class: %s", data->getName() ? data->getName() : data->getIdString() ); delete pRibbon; return; } } // Replace emitter if ( mRibbon ) mRibbon->deleteOnEnd(); mRibbon = pRibbon; } mRibbonDatablock = data; }
void AITurretShape::processTick(const Move* move) { Parent::processTick(move); if (isServerObject() && mDamageState == Enabled) { _updateTurretState(TickSec); if (mScanForTargets) { // Perform a scan for targets _performScan(); // If we found one, turn off the scan if (mTarget.isValid()) { mScanForTargets = false; } } if (mTrackTarget) { _trackTarget(TickSec); // If the target is lost, no longer track it if (!mTarget.isValid()) { mTrackTarget = false; } } } }
void SceneObject::inspectPostApply() { if( isServerObject() ) setMaskBits( MountedMask ); Parent::inspectPostApply(); }
void SceneObject::mountObject( SceneObject *obj, S32 node, const MatrixF &xfm ) { if ( obj->mMount.object == this ) { // Already mounted to this // So update our node and xfm which may have changed. obj->mMount.node = node; obj->mMount.xfm = xfm; } else { if ( obj->mMount.object ) obj->unmount(); obj->mMount.object = this; obj->mMount.node = node; obj->mMount.link = mMount.list; obj->mMount.xfm = xfm; mMount.list = obj; // Assign PIDs to both objects if ( isServerObject() ) { obj->getOrCreatePersistentId(); if ( !obj->mMountPID ) { obj->mMountPID = getOrCreatePersistentId(); obj->mMountPID->incRefCount(); } } obj->onMount( this, node ); } }
void SceneSpace::setTransform(const MatrixF & mat) { Parent::setTransform( mat ); if( isServerObject() ) setMaskBits( TransformMask ); }
void ParticleEmitterNode::setEmitterDataBlock(ParticleEmitterData* data) { if ( isServerObject() ) { setMaskBits( EmitterDBMask ); } else { ParticleEmitter* pEmitter = NULL; if ( data ) { // Create emitter with new datablock pEmitter = new ParticleEmitter; pEmitter->onNewDataBlock( data, false ); if( pEmitter->registerObject() == false ) { Con::warnf(ConsoleLogEntry::General, "Could not register base emitter for particle of class: %s", data->getName() ? data->getName() : data->getIdString() ); delete pEmitter; return; } } // Replace emitter if ( mEmitter ) mEmitter->deleteWhenEmpty(); mEmitter = pEmitter; } mEmitterDatablock = data; }
bool SceneObject::onAdd() { if ( !Parent::onAdd() ) return false; mIsScopeAlways = mNetFlags.test( ScopeAlways ); mWorldToObj = mObjToWorld; mWorldToObj.affineInverse(); resetWorldBox(); setRenderTransform(mObjToWorld); resolveMountPID(); smSceneObjectAdd.trigger(this); //.logicking guidebot >> if (isServerObject()) createWorldObject(); //.logicking guidebot << return true; return true; }
bool AITurretShape::onAdd() { if( !Parent::onAdd() ) return false; // Add this object to the scene addToScene(); _setScanBox(); if (isServerObject()) _initState(); if (isServerObject()) scriptOnAdd(); return true; }
void RigidBody::applyImpulse(const Point3F &pos, const Point3F &impulse) { //Con::printf("RigidBody::applyImpulse: %p isServer :%d tick: %d",this,isServerObject(),isServerObject()? gServerProcessList.getTotalTicks():gClientProcessList.getTotalTicks()); //Con::printf("applyImpulse"); if(SimComponent().mEnabled && mPhysShape && (isServerObject() || !mHasServerPhysic)) { mPhysShape->addForce(impulse,pos); } }
void MissionArea::setArea(const RectI & area) { // set it mArea = MissionArea::smMissionArea = area; // pass along.. if(isServerObject()) mNetFlags.set(UpdateMask); }
bool AIPlayer::setPathDestination(const Point3F &pos) { // Pathfinding only happens on the server. if(!isServerObject()) return false; if(!getNavMesh()) updateNavMesh(); // If we can't find a mesh, just move regularly. if(!getNavMesh()) { //setMoveDestination(pos); throwCallback("onPathFailed"); return false; } // Create a new path. NavPath *path = new NavPath(); path->mMesh = getNavMesh(); path->mFrom = getPosition(); path->mTo = pos; path->mFromSet = path->mToSet = true; path->mAlwaysRender = true; path->mLinkTypes = mLinkTypes; path->mXray = true; // Paths plan automatically upon being registered. if(!path->registerObject()) { delete path; return false; } if(path->success()) { // Clear any current path we might have. clearPath(); clearCover(); clearFollow(); // Store new path. mPathData.path = path; mPathData.owned = true; // Skip node 0, which we are currently standing on. moveToNode(1); throwCallback("onPathSuccess"); return true; } else { // Just move normally if we can't path. //setMoveDestination(pos, true); //return; throwCallback("onPathFailed"); path->deleteObject(); return false; } }
void SpawnSphere::processTick( const Move *move ) { if ( isServerObject() && isMounted() ) { MatrixF mat( true ); mMount.object->getRenderMountTransform( 0.f, mMount.node, mMount.xfm, &mat ); setTransform( mat ); } }
void TurretShape::updateMove(const Move* move) { PROFILE_SCOPE( TurretShape_UpdateMove ); if (!move) return; Point3F vec, pos; // Update orientation mTurretDelta.rotVec = mRot; VectorF rotVec(0, 0, 0); if (getAllowManualRotation()) { if (mPitchAllowed) { rotVec.x = move->pitch * 2.0f; // Assume that our -2PI to 2PI range was clamped to -PI to PI in script; if (mPitchRate > 0) { rotVec.x *= mPitchRate * TickSec; } } if (mHeadingAllowed) { rotVec.z = move->yaw * 2.0f; // Assume that our -2PI to 2PI range was clamped to -PI to PI in script if (mHeadingRate > 0) { rotVec.z *= mHeadingRate * TickSec; } } } mRot.x += rotVec.x; mRot.z += rotVec.z; _applyLimits(mRot); if (isServerObject()) { // As this ends up animating shape nodes, we have no sense of a transform and // render transform. Therefore we treat this as the true transform and leave the // client shape node changes to interpolateTick() as the render transform. Otherwise // on the client we'll have this node change from processTick() and then backstepping // and catching up to the true node change in interpolateTick(), which causes the // turret to stutter. _setRotation( mRot ); } else { // If on the client, calc delta for backstepping mTurretDelta.rot = mRot; mTurretDelta.rotVec = mTurretDelta.rotVec - mTurretDelta.rot; } setMaskBits(TurretUpdateMask); }