void CProjectileHandler::CheckGroundCollisions(ProjectileContainer& pc) { for (size_t i = 0; i < pc.size(); ++i) { CProjectile* p = pc[i]; if (!p->checkCol) continue; // NOTE: // if <p> is a MissileProjectile and does not have // selfExplode set, tbis will cause it to never be // removed (!) if (p->GetCollisionFlags() & Collision::NOGROUND) continue; // don't collide with ground yet if last update scheduled a bounce if (p->weapon && static_cast<const CWeaponProjectile*>(p)->HasScheduledBounce()) continue; // NOTE: // don't add p->radius to groundHeight, or most (esp. modelled) // projectiles will collide with the ground one or more frames // too early const float groundHeight = CGround::GetHeightReal(p->pos.x, p->pos.z); const bool belowGround = (p->pos.y < groundHeight); const bool insideWater = (p->pos.y <= 0.0f && !belowGround); const bool ignoreWater = p->ignoreWater; if (belowGround || (insideWater && !ignoreWater)) { // if position has dropped below terrain or into water // where we can not live, adjust it and explode us now // (if the projectile does not set deleteMe = true, it // will keep hugging the terrain) p->SetPosition(p->pos * XZVector + UpVector * groundHeight * belowGround); p->Collision(); } } }
void CLaser::Fire() { //Get matrix for current player location and forward vector tlx::CMatrix4x4 matrix; GetParent()->GetMatrix(matrix.m); //Create forward vector (z axis) CVector3 direction(matrix.m[8], matrix.m[9], matrix.m[10]); //Get position from matrix //Since we've already got the matrix it's slightly more efficient than calling GetParent()->GetCenterPoint() CVector3 pos(matrix.m[12], OFF_SCREEN_Y, matrix.m[14]); //Calculate the rotation of the parent entity, just so it only needs to be calculated once float rotation = GetParent()->GetRotation(); //Makes the space between invisible bullets 2.0f instead of 1.0f direction *= 2.0f; for (int i = 0; i < 70; i++) { CProjectile* bullet = new CProjectile(); bullet->SetPosition(pos); bullet->SetRotation(rotation); bullet->SetDamage(GetDamage()); bullet->SetSpeed(GetProjSpeed()); bullet->SetParent(GetParent()); bullet->SetExplodeable(false); GetBulletList()->push_back(unique_ptr<CProjectile>(bullet)); //Increment position of next bullet pos += direction; } }