| 1129 | } |
| 1130 | |
| 1131 | void Projectile::simulate( F32 dt ) |
| 1132 | { |
| 1133 | if ( isServerObject() && mCurrTick >= mDataBlock->lifetime ) |
| 1134 | { |
| 1135 | deleteObject(); |
| 1136 | return; |
| 1137 | } |
| 1138 | |
| 1139 | if ( mHasExploded ) |
| 1140 | return; |
| 1141 | |
| 1142 | // ... otherwise, we have to do some simulation work. |
| 1143 | RayInfo rInfo; |
| 1144 | Point3F oldPosition; |
| 1145 | Point3F newPosition; |
| 1146 | |
| 1147 | oldPosition = mCurrPosition; |
| 1148 | if ( mDataBlock->isBallistic ) |
| 1149 | mCurrVelocity.z -= 9.81 * mDataBlock->gravityMod * dt; |
| 1150 | |
| 1151 | newPosition = oldPosition + mCurrVelocity * dt; |
| 1152 | |
| 1153 | // disable the source objects collision reponse for a short time while we |
| 1154 | // determine if the projectile is capable of moving from the old position |
| 1155 | // to the new position, otherwise we'll hit ourself |
| 1156 | bool disableSourceObjCollision = (mSourceObject.isValid() && (ignoreSourceTimeout || mCurrTick <= SourceIdTimeoutTicks)); |
| 1157 | if ( disableSourceObjCollision ) |
| 1158 | mSourceObject->disableCollision(); |
| 1159 | disableCollision(); |
| 1160 | |
| 1161 | // Determine if the projectile is going to hit any object between the previous |
| 1162 | // position and the new position. This code is executed both on the server |
| 1163 | // and on the client (for prediction purposes). It is possible that the server |
| 1164 | // will have registered a collision while the client prediction has not. If this |
| 1165 | // happens the client will be corrected in the next packet update. |
| 1166 | |
| 1167 | // Raycast the abstract PhysicsWorld if a PhysicsPlugin exists. |
| 1168 | bool hit = false; |
| 1169 | |
| 1170 | if ( mPhysicsWorld ) |
| 1171 | hit = mPhysicsWorld->castRay( oldPosition, newPosition, &rInfo, Point3F( newPosition - oldPosition) * mDataBlock->impactForce ); |
| 1172 | else |
| 1173 | hit = getContainer()->castRay(oldPosition, newPosition, dynamicCollisionMask | staticCollisionMask, &rInfo); |
| 1174 | |
| 1175 | if ( hit ) |
| 1176 | { |
| 1177 | // make sure the client knows to bounce |
| 1178 | if(isServerObject() && (rInfo.object->getTypeMask() & staticCollisionMask) == 0) |
| 1179 | setMaskBits( BounceMask ); |
| 1180 | |
| 1181 | MatrixF xform( true ); |
| 1182 | xform.setColumn( 3, rInfo.point ); |
| 1183 | setTransform( xform ); |
| 1184 | mCurrPosition = rInfo.point; |
| 1185 | |
| 1186 | // Get the object type before the onCollision call, in case |
| 1187 | // the object is destroyed. |
| 1188 | U32 objectType = rInfo.object->getTypeMask(); |
no test coverage detected