void Turret::updateMove (PlayerMove *move, float interval) { if (data->isSustained == false) { if (getControlClient() && state != EXTENDED) { if (!isGhost()) extend (interval); } if (state != EXTENDED) move = NULL; float oTR = turretRotation; float oTE = turretElevation; if (move && (!animThread || animThread->getPriority() != -1 || animThread->getPosition() >= 1.0)) { #if 0 float maxSpeed = data->speed * data->speedModifier * interval; float moveFrac = interval * 32; #else float maxSpeed = data->speed * data->speedModifier; float moveFrac = interval * 16; #endif float pitch = m_clamp(move->pitch,-maxSpeed,maxSpeed); float turn = m_clamp(move->turnRot,-maxSpeed,maxSpeed); turretElevation += pitch * moveFrac; turretRotation += turn * moveFrac; wrapElevation (); if (maxElevation != minElevation) { if (turretElevation > maxElevation) turretElevation = maxElevation; if (turretElevation < minElevation) turretElevation = minElevation; } wrapRotation (); if (maxRotation != minRotation) { if (turretRotation > maxRotation) turretRotation = maxRotation; if (turretRotation < minRotation) turretRotation = minRotation; } if (move->trigger) { if (!isGhost ()) shoot (true); } if (move->jumpAction && !isGhost()) { const char *fn = scriptName("jump"); if(fn) Console->executef(2, fn, scriptThis()); } } if (elevationThread && maxElevation != minElevation) elevationThread->SetPosition ((turretElevation - minElevation) / (maxElevation - minElevation)); if (rotationThread) { if (!isEqual (maxRotation, minRotation)) rotationThread->SetPosition ((turretRotation - minRotation) / (maxRotation - minRotation)); else rotationThread->SetPosition (turretRotation / M_2PI); } // this is for the firing anim... if (animThread && state == EXTENDED) animThread->AdvanceTime (interval); // this is for the power anim... if (animThread && isGhost()) { if (state == EXTENDING) extend (interval); else if (state == RETRACTING) retract (interval); } if (!isGhost ()) { // Need to animate on the server to get the // node transforms. image.shape->animate (); if (oTE != turretElevation) setMaskBits (ElevationMask); if (oTR != turretRotation) setMaskBits (TRotationMask); } } else { if (getControlClient() && state != EXTENDED) { if (!isGhost()) extend (interval); } if (state != EXTENDED) move = NULL; float oTR = turretRotation; float oTE = turretElevation; if (move && (!animThread || animThread->getPriority() != -1 || animThread->getPosition() >= 1.0)) { float maxSpeed = data->speed * interval; float pitch = m_clamp(move->pitch,-maxSpeed,maxSpeed); float turn = m_clamp(move->turnRot,-maxSpeed,maxSpeed); float moveFrac = interval * 32; turretElevation += pitch * moveFrac; turretRotation += turn * moveFrac; wrapElevation (); if (maxElevation != minElevation) { if (turretElevation > maxElevation) turretElevation = maxElevation; if (turretElevation < minElevation) turretElevation = minElevation; } wrapRotation (); if (maxRotation != minRotation) { if (turretRotation > maxRotation) turretRotation = maxRotation; if (turretRotation < minRotation) turretRotation = minRotation; } if (move->trigger && m_fireState == Waiting) { if (!isGhost ()) shoot(true, NULL); } else if (!move->trigger && m_fireState == Firing) { if (!isGhost()) unshoot(); } if (move->jumpAction && !isGhost()) { if (m_fireState == Firing) unshoot(); const char *fn = scriptName("jump"); if(fn) Console->executef(2, fn, scriptThis()); } } if (elevationThread && maxElevation != minElevation) elevationThread->SetPosition ((turretElevation - minElevation) / (maxElevation - minElevation)); if (rotationThread) { if (!isEqual (maxRotation, minRotation)) rotationThread->SetPosition ((turretRotation - minRotation) / (maxRotation - minRotation)); else rotationThread->SetPosition (turretRotation / M_2PI); } // this is for the firing anim... if (animThread && state == EXTENDED) animThread->AdvanceTime (interval); // this is for the power anim... if (animThread && isGhost()) { if (state == EXTENDING) extend (interval); else if (state == RETRACTING) retract (interval); } if (!isGhost ()) { // Need to animate on the server to get the // node transforms. image.shape->animate (); if (oTE != turretElevation) setMaskBits (ElevationMask); if (oTR != turretRotation) setMaskBits (TRotationMask); } } }
void Sun::inspectPostApply() { _conformLights(); setMaskBits(UpdateMask); }
void Sun::setElevation( F32 elevation ) { mSunElevation = elevation; _conformLights(); setMaskBits( UpdateMask ); // TODO: Break out the masks to save some space! }
void AITurretShape::setTurretState(U32 newState, bool force) { setMaskBits(TurretStateMask); // If going back into the same state, just reset the timer // and invoke the script callback if (!force && mState == &mDataBlock->state[newState]) { mStateDelayTime = mState->timeoutValue; if (mState->script && !isGhost()) _scriptCallback(mState->script); return; } mState = &mDataBlock->state[newState]; // Reset cyclic sequences back to the first frame to turn it off // (the first key frame should be it's off state). if (mStateAnimThread && mStateAnimThread->getSequence()->isCyclic()) { mShapeInstance->setPos(mStateAnimThread,0); mShapeInstance->setTimeScale(mStateAnimThread,0); } AITurretShapeData::StateData& stateData = *mState; // Check for immediate transitions S32 ns; if ((ns = stateData.transition.rest[mAtRest]) != -1) { setTurretState(ns); return; } if ((ns = stateData.transition.target[mTarget.isValid()]) != -1) { setTurretState(ns); return; } if ((ns = stateData.transition.activated[mStateActive]) != -1) { setTurretState(ns); return; } // // Initialize the new state... // mStateDelayTime = stateData.timeoutValue; // Play animation if (mStateAnimThread && stateData.sequence != -1) { mShapeInstance->setSequence(mStateAnimThread,stateData.sequence, stateData.direction ? 0.0f : 1.0f); F32 timeScale = (stateData.scaleAnimation && stateData.timeoutValue) ? mShapeInstance->getDuration(mStateAnimThread) / stateData.timeoutValue : 1.0f; mShapeInstance->setTimeScale(mStateAnimThread, stateData.direction ? timeScale : -timeScale); } // Script callback on server if (stateData.script && stateData.script[0] && !isGhost()) _scriptCallback(stateData.script); // If there is a zero timeout, and a timeout transition, then // go ahead and transition imediately. if (!mStateDelayTime) { if ((ns = stateData.transition.timeout) != -1) { setTurretState(ns); return; } } }
void BasicClouds::inspectPostApply() { Parent::inspectPostApply(); setMaskBits( BasicCloudsMask ); }
void DecalRoad::regenerate() { _generateEdges(); _captureVerts(); setMaskBits( NodeMask | GenEdgesMask | ReClipMask ); }
void PathCamera::setState(State s) { mState = s; setMaskBits(StateMask); }
void CoverPoint::setTransform(const MatrixF & mat) { Parent::setTransform(mat); setMaskBits(TransformMask); }
void CoverPoint::inspectPostApply() { setMaskBits(TransformMask); }
void Turret::trackAndFire (Player *closePlayer, float interval) { if (data->isSustained == false) { Vector3F rot = getAngulerPosition(); int aimed = 0; float old_rot = turretRotation; float increment = data->speed * interval; float des_z; Point3F playerPos; float dist = m_distf (getBoxCenter(), closePlayer->getLeadCenter()); leadPosition (closePlayer->getLeadCenter(), closePlayer->getLeadVelocity(), dist, &playerPos); TMat3F invMat; getNodeOffset (&invMat, "dummy muzzle", gunNode); invMat.inverse(); m_mul (Point3F (playerPos.x, playerPos.y, playerPos.z), invMat, &playerPos); des_z = rotation (-playerPos.x, -playerPos.y); while (des_z < 0) des_z += (float)M_2PI; while (des_z > M_2PI) des_z -= (float)M_2PI; float diff = des_z - turretRotation; if (diff > M_PI || diff < -M_PI) increment = -increment; if (diff < increment && diff > -increment) { turretRotation = des_z; aimed += 1; } else if (diff < 0) turretRotation -= increment; else turretRotation += increment; wrapRotation (); if (turretRotation != old_rot) setMaskBits (TRotationMask); float old_elevation = turretElevation; float des_y; increment = data->speed * interval; des_y = elevation (playerPos.x, playerPos.y, playerPos.z); diff = des_y - turretElevation; if (diff > M_PI || diff < -M_PI) increment = -increment; if (diff < increment && diff > -increment) { turretElevation = des_y; aimed += 1; } else if (diff < 0) turretElevation -= increment; else turretElevation += increment; wrapElevation (); if (old_elevation != turretElevation) setMaskBits (ElevationMask); if (closePlayer && aimed >= 2 && waitTime <= manager->getCurrentTime()) shoot (false, closePlayer); } else { Vector3F rot = getAngulerPosition(); int aimed = 0; float old_rot = turretRotation; float increment = data->speed * interval; float des_z; Point3F playerPos; float dist = m_distf (getBoxCenter(), closePlayer->getLeadCenter()); leadPosition (closePlayer->getLeadCenter(), closePlayer->getLeadVelocity(), dist, &playerPos); TMat3F invMat; getNodeOffset (&invMat, "dummy muzzle", gunNode); invMat.inverse(); m_mul (Point3F (playerPos.x, playerPos.y, playerPos.z), invMat, &playerPos); des_z = rotation (-playerPos.x, -playerPos.y); while (des_z < 0) des_z += (float)M_2PI; while (des_z > M_2PI) des_z -= (float)M_2PI; float diff = des_z - turretRotation; if (diff > M_PI || diff < -M_PI) increment = -increment; if (diff < increment && diff > -increment) { turretRotation = des_z; aimed += 1; } else if (diff < 0) turretRotation -= increment; else turretRotation += increment; wrapRotation (); if (turretRotation != old_rot) setMaskBits (TRotationMask); float old_elevation = turretElevation; float des_y; increment = data->speed * interval; des_y = elevation (playerPos.x, playerPos.y, playerPos.z); diff = des_y - turretElevation; if (diff > M_PI || diff < -M_PI) increment = -increment; if (diff < increment && diff > -increment) { turretElevation = des_y; aimed += 1; } else if (diff < 0) turretElevation -= increment; else turretElevation += increment; wrapElevation (); if (old_elevation != turretElevation) setMaskBits (ElevationMask); if (closePlayer && aimed >= 2 && waitTime <= manager->getCurrentTime()) { shoot (false, closePlayer); } } }
void Turret::retract (float interval) { if (!isGhost() && state != RETRACTED && state != RETRACTING) setMaskBits (StateMask); if (!animThread || !setPowerThread ()) state = RETRACTED; else { if (state == EXTENDED) animThread->SetPosition (1.0); state = RETRACTING; if (turretRotation == 0) { if (!isGhost()) setMaskBits (TRotationMask); if (animThread->getPosition () == 1.0 && data && data->deactivateSound != -1) { if(isGhost()) TSFX::PlayAt(data->deactivateSound, getTransform(), Point3F(0, 0, 0)); if (whirSound) { Sfx::Manager::Stop (manager, whirSound); whirSound = 0; } } animThread->AdvanceTime (-interval); if (animThread->getPosition () <= 0.0) { // setFireThread (); state = RETRACTED; if (!isGhost()) setMaskBits (StateMask); } } else { if (isGhost()) { if (whirSound) { Sfx::Manager *man = Sfx::Manager::find (manager); man->selectHandle(whirSound); if (man->isDone ()) whirSound = TSFX::PlayAt(data->whirSound, getTransform(), Point3F(0, 0, 0)); // man->play (); } else if (data && data->whirSound != -1) whirSound = TSFX::PlayAt(data->whirSound, getTransform(), Point3F(0, 0, 0)); } else setMaskBits (TRotationMask); float tr = turretRotation; while (tr > M_PI) tr -= M_2PI; if (tr > 0) { turretRotation -= data->speed * interval; tr -= data->speed * interval; if (tr < 0) turretRotation = 0; } else { turretRotation += data->speed * interval; tr += data->speed * interval; if (tr > 0) turretRotation = 0; } } } }
void Turret::shoot (bool playerControlled, Player* targetPlayer) { if (data && data->isSustained == false) { if (data && data->projectile.type == -1) { if (!isGhost()) if (const char* script = scriptName("onFire")) Console->executef(2, script, scriptThis()); } else { float energy = getEnergy(); if (waitTime <= manager->getCurrentTime() && data && energy >= data->minGunEnergy && data->projectile.type != -1) { TMat3F muzzleTransform; getMuzzleTransform(0, &muzzleTransform); Projectile* bullet = createProjectile(data->projectile); if (!playerControlled && data->deflection) { static Random random; EulerF angles; muzzleTransform.angles (&angles); angles.x += (random.getFloat() - 0.5) * M_2PI * data->deflection; angles.z += (random.getFloat() - 0.5) * M_2PI * data->deflection; muzzleTransform.set (angles, muzzleTransform.p); } else if (playerControlled) { Point3F start = muzzleTransform.p; muzzleTransform = getEyeTransform (); aimedTransform (&muzzleTransform, start); muzzleTransform.p = start; } bullet->initProjectile (muzzleTransform, Point3F (0, 0, 0), getId()); if (bullet->isTargetable() == true) { if (targetPlayer != NULL) { if (GameBase* mo = targetPlayer->getMountObject()) bullet->setTarget(static_cast<ShapeBase*>(mo)); else bullet->setTarget(targetPlayer); } else if (playerControlled) { ShapeBase* pClosest = NULL; Point3F closeHisPos; float closestVal = -2.0f; SimSet::iterator itr; Point3F lookDir; getEyeTransform().getRow(1, &lookDir); lookDir.normalize(); SimContainerQuery collisionQuery; SimCollisionInfo info; collisionQuery.id = getId(); collisionQuery.type = -1; collisionQuery.mask = Projectile::csm_collisionMask; collisionQuery.detail = SimContainerQuery::DefaultDetail; collisionQuery.box.fMin = getEyeTransform().p; SimContainer* pRoot = (SimContainer*)manager->findObject(SimRootContainerId); SimSet* pSet = dynamic_cast<SimSet*>(manager->findObject(PlayerSetId)); AssertFatal(pSet != NULL, "No player set?"); for (itr = pSet->begin(); itr != pSet->end(); itr++) { Player* pPlayer = dynamic_cast<Player*>(*itr); if (!pPlayer || pPlayer->getVisibleToTeam(getTeam()) == false) continue; collisionQuery.box.fMax = pPlayer->getBoxCenter(); if (pRoot->findLOS(collisionQuery, &info, SimCollisionImageQuery::High) == true) { if (info.object != (SimObject*)pPlayer) continue; } Point3F hisPos = pPlayer->getBoxCenter(); hisPos -= getLinearPosition(); hisPos.normalize(); float prod = m_dot(hisPos, lookDir); if (prod > 0.0f && prod > closestVal) { closestVal = prod; pClosest = pPlayer; closeHisPos = hisPos; } } pSet = dynamic_cast<SimSet*>(manager->findObject(MoveableSetId)); AssertFatal(pSet != NULL, "No moveable set?"); for (itr = pSet->begin(); itr != pSet->end(); itr++) { if (((*itr)->getType() & VehicleObjectType) == 0) continue; ShapeBase* pObject = dynamic_cast<ShapeBase*>(*itr); if (pObject->getVisibleToTeam(getTeam()) == false) continue; collisionQuery.box.fMax = pObject->getBoxCenter(); if (pRoot->findLOS(collisionQuery, &info, SimCollisionImageQuery::High) == true) { if (info.object != (SimObject*)pObject) continue; } Point3F hisPos = pObject->getBoxCenter(); hisPos -= getLinearPosition(); hisPos.normalize(); float prod = m_dot(hisPos, lookDir); if (prod > 0.0f && prod > closestVal) { closestVal = prod; closeHisPos = hisPos; pClosest = pObject; } } // We need to find the current FOV, and take the percentage of // it specified in the .dat file for this turret. Only if the // do product is greater than this, do we allow the target to // be set... // float myFov = (fov / 2.0) * data->targetableFovRatio; float compCos = cos(myFov); if (compCos > 0.996f) // hack for single precision math. It's very compCos = 0.996; // hard to get more precise answers from the dot prod. if (pClosest != NULL && closestVal > compCos) bullet->setTarget(pClosest); } } if (data->maxGunEnergy) { float e; e = energy > data->maxGunEnergy ? data->maxGunEnergy : energy; float pofm = e / float(data->maxGunEnergy); bullet->setEnergy (e, pofm); energy -= e; setEnergy (energy); } SimGroup *grp = NULL; if(SimObject *obj = manager->findObject("MissionCleanup")) grp = dynamic_cast<SimGroup*>(obj); if(!manager->registerObject(bullet)) delete bullet; else { if(grp) grp->addObject(bullet); else manager->addObject(bullet); } waitTime = manager->getCurrentTime() + data->reloadDelay; if (animThread) { setFireThread (); animThread->SetPosition (0.0); } fireCount++; setMaskBits (ShootingMask); } } } else { if (data && data->projectile.type == -1) { if (!isGhost()) if (const char* script = scriptName("onFire")) Console->executef(2, script, scriptThis()); } else { float energy = getEnergy(); if (waitTime <= manager->getCurrentTime() && data && energy >= data->minGunEnergy && data->projectile.type != -1) { TMat3F muzzleTransform; getMuzzleTransform(0, &muzzleTransform); Projectile* bullet = createProjectile(data->projectile); if (!playerControlled && data->deflection) { static Random random; EulerF angles; muzzleTransform.angles (&angles); angles.x += (random.getFloat() - 0.5) * M_2PI * data->deflection; angles.z += (random.getFloat() - 0.5) * M_2PI * data->deflection; muzzleTransform.set (angles, muzzleTransform.p); } else if (playerControlled) { Point3F start = muzzleTransform.p; muzzleTransform = getEyeTransform (); aimedTransform (&muzzleTransform, start); muzzleTransform.p = start; } bullet->initProjectile (muzzleTransform, Point3F (0, 0, 0), getId()); AssertFatal(bullet->isSustained() == true, "Error, must be sustained bullet"); SimGroup *grp = NULL; if(SimObject *obj = manager->findObject("MissionCleanup")) grp = dynamic_cast<SimGroup*>(obj); if(!manager->registerObject(bullet)) delete bullet; else { if(grp) grp->addObject(bullet); else manager->addObject(bullet); } if (animThread) { setFireThread (); animThread->SetPosition (0.0); } fireCount++; setMaskBits (ShootingMask); m_fireState = Firing; m_beganState = wg->currentTime; m_pProjectile = bullet; m_pTarget = targetPlayer; if (m_pTarget) deleteNotify(m_pTarget); } } } }
void Turret::serverProcessFiring(DWORD in_currTime) { if (!getControlClient() && getState () == StaticBase::Enabled && isActive()) { AssertFatal(m_pProjectile != NULL, "Must have projectile"); if (m_pTarget == NULL) { // Lost our target, or player mount just ended... unshoot(); return; } if (in_currTime >= m_beganState + data->firingTime) { // If the firing time runs out, we switch to reloading... unshoot(); return; } float useRange = data->gunRange == -1 ? data->iRange : data->gunRange; float minDist = useRange; if (isTargetable(m_pTarget, &minDist, useRange) == false) { unshoot(); return; } // Guess we're still good, track the player... float interval = 0.032; Vector3F rot = getAngulerPosition(); int aimed = 0; float old_rot = turretRotation; float increment = data->speed * interval; float des_z; Point3F playerPos; float dist = m_distf (getBoxCenter(), m_pTarget->getLeadCenter()); leadPosition (m_pTarget->getLeadCenter(), m_pTarget->getLeadVelocity(), dist, &playerPos); TMat3F invMat; getNodeOffset (&invMat, "dummy muzzle", gunNode); invMat.inverse(); m_mul (Point3F (playerPos.x, playerPos.y, playerPos.z), invMat, &playerPos); des_z = rotation (-playerPos.x, -playerPos.y); while (des_z < 0) des_z += (float)M_2PI; while (des_z > M_2PI) des_z -= (float)M_2PI; float diff = des_z - turretRotation; if (diff > M_PI || diff < -M_PI) increment = -increment; if (diff < increment && diff > -increment) { turretRotation = des_z; aimed += 1; } else if (diff < 0) turretRotation -= increment; else turretRotation += increment; wrapRotation (); if (turretRotation != old_rot) setMaskBits (TRotationMask); float old_elevation = turretElevation; float des_y; increment = data->speed * interval; des_y = elevation (playerPos.x, playerPos.y, playerPos.z); diff = des_y - turretElevation; if (diff > M_PI || diff < -M_PI) increment = -increment; if (diff < increment && diff > -increment) { turretElevation = des_y; aimed += 1; } else if (diff < 0) turretElevation -= increment; else turretElevation += increment; wrapElevation (); if (old_elevation != turretElevation) setMaskBits (ElevationMask); } if (m_pProjectile) m_pProjectile->updateImageTransform(getEyeTransform()); }
void Turret::onDamageStateChange(DamageState oldState) { Parent::onDamageStateChange(oldState); if (!isGhost()) setMaskBits (StateMask); }
void Projectile::simulate( F32 dt ) { if ( isServerObject() && mCurrTick >= mDataBlock->lifetime ) { deleteObject(); return; } if ( mHasExploded ) return; // ... otherwise, we have to do some simulation work. RayInfo rInfo; Point3F oldPosition; Point3F newPosition; oldPosition = mCurrPosition; if ( mDataBlock->isBallistic ) mCurrVelocity.z -= 9.81 * mDataBlock->gravityMod * dt; newPosition = oldPosition + mCurrVelocity * dt; // disable the source objects collision reponse for a short time while we // determine if the projectile is capable of moving from the old position // to the new position, otherwise we'll hit ourself bool disableSourceObjCollision = (mSourceObject.isValid() && mCurrTick <= SourceIdTimeoutTicks); if ( disableSourceObjCollision ) mSourceObject->disableCollision(); disableCollision(); // Determine if the projectile is going to hit any object between the previous // position and the new position. This code is executed both on the server // and on the client (for prediction purposes). It is possible that the server // will have registered a collision while the client prediction has not. If this // happens the client will be corrected in the next packet update. // Raycast the abstract PhysicsWorld if a PhysicsPlugin exists. bool hit = false; if ( mPhysicsWorld ) hit = mPhysicsWorld->castRay( oldPosition, newPosition, &rInfo, Point3F( newPosition - oldPosition) * mDataBlock->impactForce ); else hit = getContainer()->castRay(oldPosition, newPosition, csmDynamicCollisionMask | csmStaticCollisionMask, &rInfo); if ( hit ) { // make sure the client knows to bounce if ( isServerObject() && ( rInfo.object->getTypeMask() & csmStaticCollisionMask ) == 0 ) setMaskBits( BounceMask ); MatrixF xform( true ); xform.setColumn( 3, rInfo.point ); setTransform( xform ); mCurrPosition = rInfo.point; // Get the object type before the onCollision call, in case // the object is destroyed. U32 objectType = rInfo.object->getTypeMask(); // re-enable the collision response on the source object since // we need to process the onCollision and explode calls if ( disableSourceObjCollision ) mSourceObject->enableCollision(); // Ok, here is how this works: // onCollision is called to notify the server scripts that a collision has occurred, then // a call to explode is made to start the explosion process. The call to explode is made // twice, once on the server and once on the client. // The server process is responsible for two things: // 1) setting the ExplosionMask network bit to guarantee that the client calls explode // 2) initiate the explosion process on the server scripts // The client process is responsible for only one thing: // 1) drawing the appropriate explosion // It is possible that during the processTick the server may have decided that a hit // has occurred while the client prediction has decided that a hit has not occurred. // In this particular scenario the client will have failed to call onCollision and // explode during the processTick. However, the explode function will be called // during the next packet update, due to the ExplosionMask network bit being set. // onCollision will remain uncalled on the client however, therefore no client // specific code should be placed inside the function! onCollision( rInfo.point, rInfo.normal, rInfo.object ); // Next order of business: do we explode on this hit? if ( mCurrTick > mDataBlock->armingDelay || mDataBlock->armingDelay == 0 ) { mCurrVelocity = Point3F::Zero; explode( rInfo.point, rInfo.normal, objectType ); } if ( mDataBlock->isBallistic ) { // Otherwise, this represents a bounce. First, reflect our velocity // around the normal... Point3F bounceVel = mCurrVelocity - rInfo.normal * (mDot( mCurrVelocity, rInfo.normal ) * 2.0); mCurrVelocity = bounceVel; // Add in surface friction... Point3F tangent = bounceVel - rInfo.normal * mDot(bounceVel, rInfo.normal); mCurrVelocity -= tangent * mDataBlock->bounceFriction; // Now, take elasticity into account for modulating the speed of the grenade mCurrVelocity *= mDataBlock->bounceElasticity; // Set the new position to the impact and the bounce // will apply on the next frame. //F32 timeLeft = 1.0f - rInfo.t; newPosition = oldPosition = rInfo.point + rInfo.normal * 0.05f; } else { mCurrVelocity = Point3F::Zero; } } // re-enable the collision response on the source object now // that we are done processing the ballistic movement if ( disableSourceObjCollision ) mSourceObject->enableCollision(); enableCollision(); if ( isClientObject() ) { emitParticles( mCurrPosition, newPosition, mCurrVelocity, U32( dt * 1000.0f ) ); updateSound(); } mCurrDeltaBase = newPosition; mCurrBackDelta = mCurrPosition - newPosition; mCurrPosition = newPosition; MatrixF xform( true ); xform.setColumn( 3, mCurrPosition ); setTransform( xform ); }
// start jc void PxCloth::setAttachmentPointScale( const Point3F &scale ) { mAttachmentPointScale = scale; setMaskBits( ScaleAttachmentPointsMask ); }
void Projectile::explode( const Point3F &p, const Point3F &n, const U32 collideType ) { // Make sure we don't explode twice... if ( mHasExploded ) return; mHasExploded = true; // Move the explosion point slightly off the surface to avoid problems with radius damage Point3F explodePos = p + n * 0.001f; if ( isServerObject() ) { // Do what the server needs to do, damage the surrounding objects, etc. mExplosionPosition = explodePos; mExplosionNormal = n; mCollideHitType = collideType; mDataBlock->onExplode_callback( this, mExplosionPosition, mFadeValue ); setMaskBits(ExplosionMask); // Just wait till the timeout to self delete. This // gives server object time to get ghosted to the client. } else { // Client just plays the explosion at the right place... // Explosion* pExplosion = NULL; if (mDataBlock->waterExplosion && pointInWater(p)) { pExplosion = new Explosion; pExplosion->onNewDataBlock(mDataBlock->waterExplosion, false); } else if (mDataBlock->explosion) { pExplosion = new Explosion; pExplosion->onNewDataBlock(mDataBlock->explosion, false); } if( pExplosion ) { MatrixF xform(true); xform.setPosition(explodePos); pExplosion->setTransform(xform); pExplosion->setInitialState(explodePos, n); pExplosion->setCollideType( collideType ); if (pExplosion->registerObject() == false) { Con::errorf(ConsoleLogEntry::General, "Projectile(%s)::explode: couldn't register explosion", mDataBlock->getName() ); delete pExplosion; pExplosion = NULL; } } // Client (impact) decal. if ( mDataBlock->decal ) gDecalManager->addDecal(p, n, mRandF(0.0f, M_2PI_F), mDataBlock->decal); // Client object updateSound(); } /* // Client and Server both should apply forces to PhysicsWorld objects // within the explosion. if ( false && mPhysicsWorld ) { F32 force = 200.0f; mPhysicsWorld->explosion( p, 15.0f, force ); } */ }
void ReplicatedObject::setValue(QString value) { qDebug() << "Value Set"; _value = value; setMaskBits(Value); }
void DecalRoad::inspectPostApply() { Parent::inspectPostApply(); setMaskBits( DecalRoadMask ); }
void Projectile::explode(const Point3F& p, const Point3F& n, const U32 collideType) { // Make sure we don't explode twice... if (mHidden == true) return; mHidden = true; if (isServerObject()) { // Do what the server needs to do, damage the surrounding objects, etc. mExplosionPosition = p; mExplosionNormal = n; mCollideHitType = collideType; char buffer[128]; dSprintf(buffer, sizeof(buffer), "%g %g %g", mExplosionPosition.x, mExplosionPosition.y, mExplosionPosition.z); Con::executef(mDataBlock, "onExplode", scriptThis(), buffer, Con::getFloatArg(mFadeValue)); setMaskBits(ExplosionMask); safeDeleteObject(); } else { // Client just plays the explosion at the right place... // Explosion* pExplosion = NULL; if (mDataBlock->waterExplosion && pointInWater(p)) { pExplosion = new Explosion; pExplosion->onNewDataBlock(mDataBlock->waterExplosion); } else if (mDataBlock->explosion) { pExplosion = new Explosion; pExplosion->onNewDataBlock(mDataBlock->explosion); } if( pExplosion ) { MatrixF xform(true); xform.setPosition(p); pExplosion->setTransform(xform); pExplosion->setInitialState(p, n); pExplosion->setCollideType( collideType ); if (pExplosion->registerObject() == false) { Con::errorf(ConsoleLogEntry::General, "Projectile(%s)::explode: couldn't register explosion", mDataBlock->getName() ); delete pExplosion; pExplosion = NULL; } } // Client (impact) decal. if ( mDataBlock->decal ) gDecalManager->addDecal( p, n, 0.0f, mDataBlock->decal ); // Client object updateSound(); } /* // Client and Server both should apply forces to PhysicsWorld objects // within the explosion. if ( false && mPhysicsWorld ) { F32 force = 200.0f; mPhysicsWorld->explosion( p, 15.0f, force ); } */ }
void AITurretShape::recenterTurret() { mRot.set(0,0,0); _setRotation( mRot ); setMaskBits(TurretUpdateMask); }
void ForestWindEmitter::inspectPostApply() { // Force the client update! setMaskBits(0xffffffff); }
void AITurretShape::_trackTarget(F32 dt) { // Only on server if (isClientObject()) return; // We can only track a target if we have one if (!mTarget.isValid()) return; Point3F targetPos = mTarget.target->getBoxCenter(); // Can we see the target? MatrixF aimMat; getAimTransform(aimMat); Point3F start; aimMat.getColumn(3, &start); RayInfo ri; Point3F sightPoint; disableCollision(); bool los = _testTargetLineOfSight(start, mTarget.target, sightPoint); enableCollision(); if (!los) { // Target is blocked. Should we try to track from its last // known position and velocity? SimTime curTime = Sim::getCurrentTime(); if ( (curTime - mTarget.lastSightTime) > (mDataBlock->trackLostTargetTime * 1000.0f) ) { // Time's up. Stop tracking. _cleanupTargetAndTurret(); return; } // Use last known information to attempt to // continue to track target for a while. targetPos = mTarget.lastPos + mTarget.lastVel * F32(curTime - mTarget.lastSightTime) / 1000.0f; } else { // Target is visible // We only track targets that are alive if (mTarget.target->getDamageState() != Enabled) { // We can't track any more _cleanupTargetAndTurret(); return; } targetPos = sightPoint; // Store latest target info mTarget.lastPos = targetPos; mTarget.lastVel = mTarget.target->getVelocity(); mTarget.lastSightTime = Sim::getCurrentTime(); } // Calculate angles to face the target, specifically the part that we can see VectorF toTarget; MatrixF mat; S32 node = mDataBlock->aimNode; if (node != -1) { // Get the current position of our node MatrixF* nodeTrans = &mShapeInstance->mNodeTransforms[node]; Point3F currentPos; nodeTrans->getColumn(3, ¤tPos); // Turn this into a matrix we can use to put the target // position into our space. MatrixF nodeMat(true); nodeMat.setColumn(3, currentPos); mat.mul(mObjToWorld, nodeMat); mat.affineInverse(); } else { mat = mWorldToObj; } mat.mulP(targetPos, &toTarget); // lead the target F32 timeToTargetSquared = (mWeaponLeadVelocitySquared > 0) ? toTarget.lenSquared() / mWeaponLeadVelocitySquared : 0; if (timeToTargetSquared > 1.0) { targetPos = targetPos + (mTarget.lastVel * mSqrt(timeToTargetSquared)); mat.mulP(targetPos, &toTarget); } F32 yaw, pitch; MathUtils::getAnglesFromVector(toTarget, yaw, pitch); if (yaw > M_PI_F) yaw = yaw - M_2PI_F; //if (pitch > M_PI_F) // pitch = -(pitch - M_2PI_F); Point3F rot(pitch, 0.0f, -yaw); // If we have a rotation rate make sure we follow it if (mHeadingRate > 0) { F32 rate = mHeadingRate * dt; F32 rateCheck = mFabs(rot.z - mRot.z); if (rateCheck > rate) { // This will clamp the new value to the rate regardless if it // is increasing or decreasing. rot.z = mClampF(rot.z, mRot.z-rate, mRot.z+rate); } } if (mPitchRate > 0) { F32 rate = mPitchRate * dt; F32 rateCheck = mFabs(rot.x - mRot.x); if (rateCheck > rate) { // This will clamp the new value to the rate regardless if it // is increasing or decreasing. rot.x = mClampF(rot.x, mRot.x-rate, mRot.x+rate); } } // Test if the rotation to the target is outside of our limits if (_outsideLimits(rot)) { // We can't track any more _cleanupTargetAndTurret(); return; } // Test if the target is out of weapons range if (toTarget.lenSquared() > mWeaponRangeSquared) { // We can't track any more _cleanupTargetAndTurret(); return; } mRot = rot; _setRotation( mRot ); setMaskBits(TurretUpdateMask); }
void VolumetricFog::inspectPostApply() { Parent::inspectPostApply(); mSpeed.set(mSpeed1.x, mSpeed1.y, mSpeed2.x, mSpeed2.y); setMaskBits(VolumetricFogMask | FogColorMask | FogDensityMask | FogModulationMask | FogPostFXMask | FogShapeMask); }
void WaterObject::inspectPostApply() { Parent::inspectPostApply(); setMaskBits( UpdateMask | WaveMask | TextureMask | SoundMask ); }
void WaterPlane::inspectPostApply() { Parent::inspectPostApply(); setMaskBits( UpdateMask ); }
void Sun::setAzimuth( F32 azimuth ) { mSunAzimuth = azimuth; _conformLights(); setMaskBits( UpdateMask ); // TODO: Break out the masks to save bandwidth! }
void GameBase::inspectPostApply() { Parent::inspectPostApply(); setMaskBits(ExtendedInfoMask); }
void Sun::setColor( const ColorF &color ) { mLightColor = color; _conformLights(); setMaskBits( UpdateMask ); // TODO: Break out the masks to save some space! }
void LightBase::setTransform( const MatrixF &mat ) { setMaskBits( TransformMask ); Parent::setTransform( mat ); }