Пример #1
0
float			RadarRenderer::transScale(const Obstacle& o)
{
  float scaleColor;
  const LocalPlayer* myTank = LocalPlayer::getMyTank();

  // Scale color so that objects that are close to tank's level are opaque
  const float zTank = myTank->getPosition()[2];
  const float zObstacle = o.getPosition()[2];
  const float hObstacle = o.getHeight();
  if (zTank >= (zObstacle + hObstacle))
    scaleColor = 1.0f - (zTank - (zObstacle + hObstacle)) / colorFactor;
  else if (zTank <= zObstacle)
    scaleColor = 1.0f - (zObstacle - zTank) / colorFactor;
  else
    scaleColor = 1.0f;

  if (scaleColor < 0.5f)
    scaleColor = 0.5f;

  return scaleColor;
}
void			SegmentedShotStrategy::makeSegments(ObstacleEffect e)
{
  // compute segments of shot until total length of segments exceeds the
  // lifetime of the shot.
  const ShotPath& path = getPath();
  const float* v = path.getVelocity();
  TimeKeeper startTime = path.getStartTime();
  float timeLeft = path.getLifetime();
  float minTime = BZDB.eval(StateDatabase::BZDB_MUZZLEFRONT) / hypotf(v[0], hypotf(v[1], v[2]));

  // if all shots ricochet and obstacle effect is stop, then make it ricochet
  if (e == Stop && World::getWorld()->allShotsRicochet())
    e = Reflect;

  // prepare first segment
  float o[3], d[3];
  d[0] = v[0];
  d[1] = v[1];
  d[2] = v[2];		// use v[2] to have jumping affect shot velocity
  o[0] = path.getPosition()[0];
  o[1] = path.getPosition()[1];
  o[2] = path.getPosition()[2];

  segments.clear();
  ShotPathSegment::Reason reason = ShotPathSegment::Initial;
  int i;
  const int maxSegment = 100;
  for (i = 0; (i < maxSegment) && (timeLeft > Epsilon); i++) {
    // construct ray and find the first building, teleporter, or outer wall
    float o2[3];
    o2[0] = o[0] - minTime * d[0];
    o2[1] = o[1] - minTime * d[1];
    o2[2] = o[2] - minTime * d[2];
    Ray r(o2, d);
    Ray rs(o, d);
    float t = timeLeft + minTime;
    int face;
    bool hitGround = getGround(r, Epsilon, t);
    Obstacle* building = (Obstacle*)((e != Through) ? getFirstBuilding(r, Epsilon, t) : NULL);
    const Teleporter* teleporter = getFirstTeleporter(r, Epsilon, t, face);
	t -= minTime;
	minTime = 0.0f;

	// if hit outer wall with ricochet and hit is above top of wall
	// then ignore hit.
	if (!teleporter && building && e == Reflect &&
	building->getType() == WallObstacle::getClassName() &&
	o[2] + t * d[2] > building->getHeight())
	  t = timeLeft;

	// construct next shot segment and add it to list
	TimeKeeper endTime(startTime);
	if (t < 0.0f) endTime += Epsilon;
	else endTime += t;
	ShotPathSegment segment(startTime, endTime, rs, reason);
	segments.push_back(segment);
	startTime = endTime;

	// used up this much time in segment
	if (t < 0.0f) timeLeft -= Epsilon;
	else timeLeft -= t;

	// check in reverse order to see what we hit first
	reason = ShotPathSegment::Through;
	if (teleporter) {
	  // entered teleporter -- teleport it
	  int source = World::getWorld()->getTeleporter(teleporter, face);
	  int target = World::getWorld()->getTeleportTarget(source);
	  if (target == randomTeleporter) {
	    unsigned int tmp = path.getShotId() + i;
            tmp = (tmp * 1103515245 + 12345) >> 8; // from POSIX rand() example
            tmp = tmp % (2 * World::getWorld()->getTeleporters().size());
            target = tmp;
          }
      
	  int outFace;
	  const Teleporter* outTeleporter =
			World::getWorld()->getTeleporter(target, outFace);
	  o[0] += t * d[0];
	  o[1] += t * d[1];
	  o[2] += t * d[2];
	  teleporter->getPointWRT(*outTeleporter, face, outFace,
						o, d, 0.0f, o, d, NULL);
	  reason = ShotPathSegment::Teleport;
	}
	else if (building) {