Monday, December 31, 2007

Guided Bullets

Ok this code is pretty nice, just lock onto your opponent and it shoots in the direction they're going or right at them pretty accurately. I didn't create this code, but I'm not sure who gave it to me but here it is:


You might have trouble if you have guided lasers.

In src/bzflag/playing.cxx find:

// see if it's inside lock-on angle (if we're trying to lock-on)
if (a <>getFlag() == Flags::GuidedMissile) // am i locking on?
tankHasShotType(myTank, Flags::GuidedMissile)) &&
player[i]->getFlag() != Flags::Stealth && // can't lock on stealth
!player[i]->isPaused() && // can't lock on paused
!player[i]->isNotResponding() && // can't lock on not responding
d < besttarget =" player[i];" bestdistance =" d;" lockedon =" true;">getFlag() == Flags::GuidedMissile) // am i locking on?

To:

(1 // am i locking on?

In src/bzflag/LocalPlayer.cxx find:

// Set _shotsKeepVerticalVelocity on the server if you want shots
// to have the same vertical velocity as the tank when fired.
// keeping shots moving horizontally makes the game more playable.
firingInfo.shot.vel[2] = 0.0f;

Add this after it:

if (getTarget()) {
const Player * targ = getTarget();
double myx = LocalPlayer::getMyTank()->getPosition()[0];
double myy = LocalPlayer::getMyTank()->getPosition()[1];
double myz = LocalPlayer::getMyTank()->getPosition()[2] +
LocalPlayer::getMyTank()->getMuzzleHeight();
double hisx = targ->getPosition()[0];
double hisy = targ->getPosition()[1];
double hisz = targ->getPosition()[2] + targ->getMuzzleHeight();
double hisvx = targ->getVelocity()[0];
double hisvy = targ->getVelocity()[1];
double hisvz = targ->getVelocity()[2];
double deltax = hisx - myx;
double deltay = hisy - myy;
double distance = hypotf(deltax,deltay)- BZDBCache::tankRadius;
// - BZDB.eval(StateDatabase::BZDB_MUZZLEFRONT);
if (distance <= 0) distance = 0; double shotspeed = BZDB.eval(StateDatabase::BZDB_SHOTSPEED)*( LocalPlayer::getMyTank()->getFlag() == Flags::Laser ?
BZDB.eval(StateDatabase::BZDB_LASERADVEL) :
LocalPlayer::getMyTank()->getFlag() == Flags::RapidFire ?
BZDB.eval(StateDatabase::BZDB_RFIREADVEL) :
LocalPlayer::getMyTank()->getFlag() == Flags::MachineGun ?
BZDB.eval(StateDatabase::BZDB_MGUNADVEL) : 1);
double errdistance = 1.0;
float tx, ty, tz;
for (int tries=0 ; errdistance > 0.05 && tries < t =" (float)distance" omega="fabs(targ-">getAngularVelocity());
double sx,sy;
if ((targ->getStatus() & PlayerState::Falling) fabs(omega)
< sx="t*hisvx;" sy="t*hisvy;" hisspeed =" hypotf(hisvx," alfa =" omega" r =" hisspeed" dx =" r" dy2 =" r" beta =" atan2(dy2,">getAngularVelocity() >
0 ? 1 : -1);
double gamma = atan2(hisvy, hisvx);
double rho = gamma+beta;
sx = hisspeed * t * cos(rho);
sy = hisspeed * t * sin(rho);
}
tx=(float)hisx+(float)sx;
ty=(float)hisy+(float)sy;
tz=(float)hisz+(float)hisvz*t;
if (targ->getStatus() & PlayerState::Falling)
tz += 0.5f * BZDBCache::gravity * t * t;
if (tz < 0) tz = 0;
double distance2 = hypotf(tx - myx, ty - myy);
errdistance = fabs(distance2-distance) / (distance + ZERO_TOLERANCE);
distance = distance2;
}
float projpos[3];
projpos[0] = tx; projpos[1] = ty; projpos[2] = tz;
float heading = atan2f(projpos[1] - myy, projpos[0] - myx);
firingInfo.shot.vel[0] = cosf(heading) *
BZDB.eval(StateDatabase::BZDB_SHOTSPEED);
firingInfo.shot.vel[1] = sinf(heading) *
BZDB.eval(StateDatabase::BZDB_SHOTSPEED);
firingInfo.shot.vel[2] = sinf(atan2f(projpos[2]-myz,
hypotf(projpos[1]-myy,
projpos[0]-myx)))*BZDB.eval(StateDatabase::BZDB_SHOTSPEED);
firingInfo.shot.pos[0] = myx;
firingInfo.shot.pos[1] = myy;
firingInfo.shot.pos[2] = myz;
}

There you go.

-NightMare

1 comment:

Anonymous said...
This comment has been removed by a blog administrator.