Sunday, January 6, 2008

Delayed Death after Getting Shot

By: Lord Jesus

This cheat comes to us by way of an idea from blogger, person. Here is an excerpt of his comment to Super "Kill Me" on Demand in which he proposed the idea:

    I have a suggestion... Maybe there could be a client side delay so that when the tank detects that it has been shot, it will let you live for just a little longer, giving you a short time in which you could kill your killer before you died. Like for example. I get in a fight with a shock waver. I wait for him to land, but am hit before he lands. Instead of exploding, I would have 2 seconds to kill him first.

The delayed death cheat can also be useful for cheaters with slow connections and/or moderate to high lag since the delay can possibly be attributed to lag. Some administrators, though, may kick players who lag or seem to lag until they are able to fix the problem especially if other players are complaining about it.

Being that I'm not a software developer, this may look a bit rough; however, it works. Suggestions to clean it up or to make it easier are always welcome.

Anyway, I found in my experiments that setting the delay to 2.0f seemed a little long. It would be easily noticed, and you would be singled out shortly for cheating. In this example, I use 1.0f which turns out to be a little closer to two seconds than it does one. You can adjust that value to suit your liking. Perhaps, you can shorten it to make it less noticeable yet still give you just enough time to pop off a shot or two at the player who shot you. Additionally, my idea was to have a countdown on the display. Being that the time is short, I decided to go simply with "Death imminent" as a quick warning for you to get your shot(s) off before you blow up.

I didn't include a delay for Thief. The idea is to shoot a person who actually shot you. I also didn't include a delay for Steamroller; however, implementing a delay for that as well wouldn't be difficult.

All of the changes that we will make will be in the file, playing.cxx.

At the beginning, of playing.cxx, you will see a section for "system includes":

// system includes
#ifdef _WIN32
#include
#include
#include
#include
#else
#include
#include
#include
#include
#include
#endif
#include

At the end of that, add "int deathStart;" so that the section now reads like this:

// system includes
#ifdef _WIN32
#include
#include
#include
#include
#else
#include
#include
#include
#include
#include
#endif
#include
int deathStart;

Next, search for "destructCountdown" and you will find these lines:

float pauseCountdown = 0.0f;
float destructCountdown = 0.0f

Just below the "destructCountdown" line, add this new line:

float deathCountdown = 0.0f;

The lines should now read like this:

float pauseCountdown = 0.0f;
float destructCountdown = 0.0f;
float deathCountdown = 0.0f;

Search for "destructCountdown" again, and you will find this section:

static void updateDestructCountdown(float dt)
{
if (!myTank) {
destructCountdown = 0.0f;
}
if (destructCountdown > 0.0f && !myTank->isAlive()) {
destructCountdown = 0.0f;
hud->setAlert(1, NULL, 0.0f, true);
}
if (destructCountdown > 0.0f) {
const int oldDestructCountdown = (int)(destructCountdown + 0.99f);
destructCountdown -= dt;
if (destructCountdown <= 0.0f) {
// now actually destruct
gotBlowedUp( myTank, SelfDestruct, myTank->getId() );

hud->setAlert(1, NULL, 0.0f, true);
} else if ((int)(destructCountdown + 0.99f) != oldDestructCountdown) {
// update countdown alert
char msgBuf[40];
sprintf(msgBuf, "Self Destructing in %d", (int)(destructCountdown + 0.99f));
hud->setAlert(1, msgBuf, 1.0f, false);
}
}
return;
}

Below that, add these lines:

static void updateDeathCountdown(float dt)
{
if (!myTank) {
deathCountdown = 0.0f;
}
if (deathCountdown > 0.0f && !myTank->isAlive()) {
deathCountdown = 0.0f;
hud->setAlert(1, NULL, 0.0f, true);
}
if (deathCountdown > 0.0f) {
const int oldDeathCountdown = (int)(deathCountdown + 0.99f);
deathCountdown -= dt;
if (deathCountdown <= 0.0f) {
// blow up my tank and then reset
// deathCountdown & deathStart back to zero
gotBlowedUp(myTank,GotShot,deathStart);
deathCountdown = 0.0f;
deathStart = 0;

hud->setAlert(1, NULL, 0.0f, true);
} else if ((int)(deathCountdown + 0.99f) != oldDeathCountdown) {
// update countdown alert
char msgBuf[40];
sprintf(msgBuf, "Death imminent");
hud->setAlert(1, msgBuf, 1.0f, false);
}
}
return;
}

Search for "destructCountdown" one more time, and you will find this section:

// update the countdowns
updatePauseCountdown(dt);
updateDestructCountdown(dt);

Below that, add "updateDeathCountdown(dt);" so that the section now reads like this:

// update the countdowns
updatePauseCountdown(dt);
updateDestructCountdown(dt);
updateDeathCountdown(dt);

Now, search for "used later", and you will find this section:

// used later
float waterLevel = World::getWorld()->getWaterLevel();

if (hit) {
// i got shot! terminate the shot that hit me and blow up.
// force shot to terminate locally immediately (no server round trip);
// this is to ensure that we don't get shot again by the same shot
// after dropping our shield flag.
if (hit->isStoppedByHit())
serverLink->sendEndShot(hit->getPlayer(), hit->getShotId(), 1);

FlagType* killerFlag = hit->getFlag();
bool stopShot;

if (killerFlag == Flags::Thief) {
if (myTank->getFlag() != Flags::Null) {
serverLink->sendTransferFlag(myTank->getId(), hit->getPlayer());
}
stopShot = true;
}
else {
stopShot = gotBlowedUp(myTank, GotShot, hit->getPlayer(), hit);
}

if (stopShot || hit->isStoppedByHit()) {
Player* hitter = lookupPlayer(hit->getPlayer());
if (hitter) hitter->endShot(hit->getShotId());
}
}
// if not dead yet, see if i'm sitting on death

Just after the comments at the beginning of the "if (hit)" section, add these lines:

// skip this if the Death Counter is counting
if (deathCountdown > 0.0f) return;

The section should now read like this:

if (hit) {
// i got shot! terminate the shot that hit me and blow up.
// force shot to terminate locally immediately (no server round trip);
// this is to ensure that we don't get shot again by the same shot
// after dropping our shield flag.

// skip this if the Death Counter is counting
if (deathCountdown > 0.0f) return;

Next, notice these lines in particular in the "if (hit)" section:

else {
stopShot = gotBlowedUp(myTank, GotShot, hit->getPlayer(), hit);
}

Replace "stopShot = gotBlowedUp(myTank, GotShot, hit->getPlayer(), hit);" with these lines:

deathCountdown = 1.0f;
deathStart = hit->getPlayer();

// imminent death alert
char msgBuf[40];
sprintf(msgBuf, "Death imminent");
hud->setAlert(1, msgBuf, 1.0f, false);

The section should now read like this:

else {
deathCountdown = 1.0f;
deathStart = hit->getPlayer();

// imminent death alert
char msgBuf[40];
sprintf(msgBuf, "Death imminent");
hud->setAlert(1, msgBuf, 1.0f, false);
}

The entire section after your changes should now look like this:

// used later
float waterLevel = World::getWorld()->getWaterLevel();

if (hit) {
// i got shot! terminate the shot that hit me and blow up.
// force shot to terminate locally immediately (no server round trip);
// this is to ensure that we don't get shot again by the same shot
// after dropping our shield flag.

// skip this if the Death Counter is counting
if (deathCountdown > 0.0f) return;

if (hit->isStoppedByHit())
serverLink->sendEndShot(hit->getPlayer(), hit->getShotId(), 1);

FlagType* killerFlag = hit->getFlag();
bool stopShot;

if (killerFlag == Flags::Thief) {
if (myTank->getFlag() != Flags::Null) {
serverLink->sendTransferFlag(myTank->getId(), hit->getPlayer());
}
stopShot = true;
}
else {
deathCountdown = 1.0f;
deathStart = hit->getPlayer();

// imminent death alert
char msgBuf[40];
sprintf(msgBuf, "Death imminent");
hud->setAlert(1, msgBuf, 1.0f, false);
}

if (stopShot || hit->isStoppedByHit()) {
Player* hitter = lookupPlayer(hit->getPlayer());
if (hitter) hitter->endShot(hit->getShotId());
}
}
// if not dead yet, see if i'm sitting on death

I realize that the HUD alert is redundant. I noticed that there was a delay in the alert so I added it in the above section, as well, so that it would display more quickly.

What we've established so far is the creation of a couple of values, deathCountdown and deathStart, which we will use for our countdown, and we set their defaults (e.g., deathCountdown = 0.0f). We also added the the code for the actual countdown and time keeping. Next, we initiate the countdown when we get shot by setting deathCountdown to 1.0f, and we display an alert for "Death imminent". We also retain the identity of the player who initially shot us and started the countdown by setting the value of deathStart to represent the identity of that player so that we can use it later for blowing up when the countdown completes. We skip the "if (hit)" section if there is already a countdown in progress so that we don't start a new countdown for each shot that hits us once a countdown has already started (i.e., we ignore all other shots that may hit us after the countdown begins). When the countdown finishes, we blow up (and as a result lose a point, and the killer gets his or her point), and the countdown values, deathCountdown and deathStart, are then set back to 0.0f and 0, respectively.

Notice that we use "return" to skip the "if (hit)" section. We do that since using a line such as "stopShot = true" when deathCountdown > 0.0f will get us kicked for wrong end shot detections. Essentially, the server will kick us if we are ending other players' shots that hit us without our tank blowing up. That technique of avoiding getting blown up was utilized by cheaters of yore, and it was known as end shot cheating. I know that because I, myself, used to be one of the culprits long ago. Anyway, it is better to ignore a shot altogether rather than try to end it without blowing up. That's why god mode cheating works and end shot cheating no longer does.

This next part is left over from when I was experimenting with a previous revision of this cheat. The idea was to bypass blowing up until a countdown had finished. It may not be necessary (I haven't tried it without it); but, this cheat works with it in place. So, if it ain't broke, don't fix it :P If anyone wants to experiment with it, let us know how it worked.

Search for "tank && (tank->getTeam() == ObserverTeam" and you will find this section:

static bool gotBlowedUp(BaseLocalPlayer* tank,
BlowedUpReason reason,
PlayerId killer,
const ShotPath* hit, int phydrv)
{
if (tank && (tank->getTeam() == ObserverTeam || !tank->isAlive()))
return false;

Change "(tank && (tank->getTeam() == ObserverTeam || !tank->isAlive()))" to this:

((tank && (tank->getTeam() == ObserverTeam || !tank->isAlive()) || deathCountdown > 0.0f))

Yeah, I know it's "fugly". Anyway, the section should now read like this:

static bool gotBlowedUp(BaseLocalPlayer* tank,
BlowedUpReason reason,
PlayerId killer,
const ShotPath* hit, int phydrv)
{
if ((tank && (tank->getTeam() == ObserverTeam || !tank->isAlive()) || deathCountdown > 0.0f))
return false;

Save the file, compile your new client, and you're finished. Thank you to blogger, person, for bringing this idea to us.

As always...

Have fun!

>:)

**********

Related posts:

Instant Self Destruct
Ultimate Pausing

Thursday, January 3, 2008

Using God Mode with Choose Who Kills You

By: Lord Jesus

With Choose Who Kills You and Super "Kill Me" on Demand, you could not use god mode if you had either or both cheats enabled. Here's a simple edit that will now allow you to have the best of both worlds. You can drive around in god mode and only blow up when you initiate killMe (Choose Who Kills You) or SuperkillMe (Super "Kill Me" on Demand). I was considering making this an additional update to Super "Kill Me" on Demand; however, I decided to make it a separate entry for the benefit of those who choose not to use god mode.

First, let's revisit Classic God Mode. In the God Mode cheat, we added this line in several locations within playing.cxx:

// skip this if i'm alive
if (myTank->isAlive()) return;

So that it will not interfere with killMe and/or SuperkillMe, we change it to this:

// skip this if i'm alive and we have not initiated getting killed
if (myTank->isAlive() && killMe == 0 && SuperkillMe == 0) return;

If you do not use both dead-on-demand cheats, you can edit the above to match which cheat you are using. Basically, we skip the check to see if we should be dead if we are alive AND killMe and SuperkillMe are zero (i.e., we haven't selected to be killed by someone). If we have initiated a "Kill Me", then we continue with the checks and we are allowed to blow up.

When you've completed your edits, save your file, compile your client, and ...

Have fun!

**********

Related posts:

Classic God Mode
Choose Who Kills You
Super "Kill Me" on Demand

Jump Fix for DUB Pillbox

By: Lord Jesus

Some of you may have noticed that you can no longer cheat on DUB Pillbox by jumping on the no-jumping server (see Flying Without Wings for information about jumping on no-jump servers). In addition to updating to a newer version server which prevents sending flags to teammates (or someone on the other team, for that matter) or observers, jump velocity was set to zero. The fix for that is to use a custom value if the server value is set to zero or less. Here, we use 19. You can experiment to find a value that most suits your liking.

To do that, let's go to LocalPlayer.cxx. Search for "newVelocity[2] = BZDB.eval(StateDatabase::BZDB_JUMPVELOCITY)", and you will find this section:

// add jump velocity (actually, set the vertical component since you
// can only jump if resting on something)
const float* oldVelocity = getVelocity();
float newVelocity[3];
newVelocity[0] = oldVelocity[0];
newVelocity[1] = oldVelocity[1];
if (flag == Flags::Wings) {
newVelocity[2] = BZDB.eval(StateDatabase::BZDB_WINGSJUMPVELOCITY);
} else if (flag == Flags::Bouncy) {
const float factor = 0.25f + ((float)bzfrand() * 0.75f);
newVelocity[2] = factor * BZDB.eval(StateDatabase::BZDB_JUMPVELOCITY);
} else {
newVelocity[2] = BZDB.eval(StateDatabase::BZDB_JUMPVELOCITY);
}

In particular, look at these lines:

} else {
newVelocity[2] = BZDB.eval(StateDatabase::BZDB_JUMPVELOCITY);
}

Just below "} else {", add this line:

if(BZDB.eval(StateDatabase::BZDB_JUMPVELOCITY) <=0 ) BZDB.setFloat(StateDatabase::BZDB_JUMPVELOCITY, 19);

The edited section should now read like this:

} else {
if(BZDB.eval(StateDatabase::BZDB_JUMPVELOCITY) <=0 ) BZDB.setFloat(StateDatabase::BZDB_JUMPVELOCITY, 19);
newVelocity[2] = BZDB.eval(StateDatabase::BZDB_JUMPVELOCITY);
}

Save the file, compile your client, and you're ready once more to raise hell on DUB Pillbox. Yes, now you can start dropping flags on towers again. For added laughs, be sure to check out Flying Without Wings and Guided Bullets ;) Also be sure to check out Teleport Behind Somebody (handy when someone on the other team has your flag).

I wouldn't be surprised if DUB Pillbox and/or other servers tweak various other server values in attempts to thwart cheating. We'll update here as necessary, so stay tuned ;)

Again...

dj28: "Have fun pissing people off and ruining their fun."

>:)

**********

Related posts:

Wings Gravity Fix for BloodBath
Flying Without Wings
Guided Bullets
Teleport Behind Somebody
Teleport in FRONT of your opponent.

Tuesday, January 1, 2008

Super "Kill Me" on Demand

By: Lord Jesus

Got an annoying teammate that needs to be kicked (if the server kicks for team kills)? Perhaps that annoying teammate simply needs calibration with a point reduction... Or, how would you like to be able to hook up your buddies with some mad points?

Here's a modification to Choose Who Kills You brought to you by a collaboration between blogger,Someone, and BZFlag Cheat's newest team member, NightMare.

With "Choose Who Kills You", you enter in your command to be killed by another player on demand (e.g., "/k"). The getting killed ends after you blow up and the point is transferred. Let's say, though, that you would like to do it over and over again without having to enter the command manually each and every time. One way might be to set up a macro such as ctrl+k to enter "." + /k + [Enter] to facilitate rapid keystroke entries. Another way might be to set up a key command and select victims similar to the way in which one uses "k" to silence or "unsilence" other players. There are a variety of ways which are possible. After all, there are usually more than one way to skin a cat, as the old saying goes.

The technique that we will use here is to set up a command for it. A separate command is used to terminate the automatic suicide, as it were. Additionally, this particular method works separately from killMe, so you can use either one without conflict. The example that we use here will show lines of code for both. The single killMe is optional, of course, but highly recommended :)

Before we begin, let's review some limitations. This method described here (as well as single killMe) will NOT work if you:
    1. have god mode enabled. This is highly important. If you can toggle god mode, ensure that it is toggled off. Otherwise, you will need to build without the god mode cheat or nothing will happen when you try to use the Super killMe (or single killMe, for that matter). UPDATE: See Using God Mode with Choose Who Kills You if you want to use (or would like to continue to use) god mode.

    2. are an observer. Note, though, that you can choose to be killed by an observer. You just can't be killed while YOU are an observer.

    3. have not yet spawned (e.g., when you first join a server).

    4. are dead. For the automatic Super killMe, I strongly recommend that you utilize Respawn Instantly.

Additionally, I have noticed that commonly at least one player on a server is not affected by either killMe or Super killMe. So, if you go to try it out and it doesn't work on the first victim, try some others just to be sure. Also, if a victim leaves the server during the automatic Super killMe (e.g., getting kicked for team killing, just simply leaving, and so on), then the killed message will reflect that you have been killed by the server. This occurs when you are killed by an unknown player (a player who has signed off is a player that no longer exists).

playing.cxx

Let's begin now by going back to playing.cxx. Do you remember where we added "int killMe"? Let's add another one so that the section looks like this (from the beginning of the file):

/* bzflag
* Copyright (c) 1993 - 2006 Tim Riker
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the license found in the file
* named COPYING that should have accompanied this file.
*
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/

// interface header
#include "playing.h"

// system includes
#ifdef _WIN32
#include
#include
#include
#include
#else
#include
#include
#include
#include
#include
#endif
#include
int killMe;
int SuperkillMe;

Next, search for "used later", and you will find this section:

// used later
float waterLevel = World::getWorld()->getWaterLevel();

if (hit) {
// i got shot! terminate the shot that hit me and blow up.

Look at the second line:

float waterLevel = World::getWorld()->getWaterLevel();

Below that, let's add our lines of code:

if (killMe)
{
gotBlowedUp(myTank,GotShot,killMe);
killMe = 0;
}

if (SuperkillMe)
{
gotBlowedUp(myTank,GotShot,SuperkillMe);
}

Look at the line below the addition above:

if (message.length() > 0) {

Add "else" at teh beginning of the line so that it now reads like this:

else if (message.length() > 0) {

The edited section should now look like this:

// used later
float waterLevel = World::getWorld()->getWaterLevel();

if (killMe)
{
gotBlowedUp(myTank,GotShot,killMe);
killMe = 0;
}

if (SuperkillMe)
{
gotBlowedUp(myTank,GotShot,SuperkillMe);
}
else if (message.length() > 0) {

if (hit) {
// i got shot! terminate the shot that hit me and blow up.

Notice that in the killMe section you see "killMe=0" but SuperkillMe does not have a corresponding line. The line resets killMe so that the process of getting blown up doesn't keep going and going. This allows you to have single use killMe. Since we want the automatic killMe (i.e., SuperkillMe) to keep going, there is no line resetting that value back to 0.

UPDATE: As mentioned previously, this cheat would continue the SuperkillMe even after the player signs off or gets kicked. Thus, the killer is then unknown and the killed message is "Killed by the server", and you would have to use your command to end it (such as /ks) to stop the SuperkillMe. Here's a simple fix to end the SuperkillMe automatically when the player no longer on the server.

Let's continue with playing.cxx and search for "Killed by the server". You will will find this section:

} else {
// 1-4 are messages sent when the player dies because of someone else
if (reason >= GotShot && reason <= GenocideEffect) {
Player *killerPlayer = lookupPlayer(killer);
if (!killerPlayer) {
blowedUpNotice = "Killed by the server";
} else {

Notice this line: blowedUpNotice = "Killed by the server";

After that line, add this line:

SuperkillMe = 0;

The section should now look like this:

} else {
// 1-4 are messages sent when the player dies because of someone else
if (reason >= GotShot && reason <= GenocideEffect) {
Player *killerPlayer = lookupPlayer(killer);
if (!killerPlayer) {
blowedUpNotice = "Killed by the server";
SuperkillMe = 0;
} else {

At this point, we are finished with editing playing.cxx.

ComposeDefaultKey.cxx

Next, let's go to setting up the actual commands. For this we go to ComposeDefaultKey.cxx. Do you recall where we put "extern int killMe;"? Search for "MAX_MESSAGE_HISTORY (20)", and you will come to this section:

#define MAX_MESSAGE_HISTORY (20)

MessageQueue messageHistory;
unsigned int messageHistoryIndex = 0;


static bool isWordCompletion(const BzfKeyEvent& key)

Notice the line "unsigned int messageHistoryIndex = 0;". Below that, we will add our lines of code:

extern int killMe;
extern int SuperkillMe;

The edited section should look like this:

#define MAX_MESSAGE_HISTORY (20)

MessageQueue messageHistory;
unsigned int messageHistoryIndex = 0;
extern int killMe;
extern int SuperkillMe;

static bool isWordCompletion(const BzfKeyEvent& key)

Next, let's set up our commands. Here, we use "/k" for a single killMe, and we use "/kk" for SuperkillMe. Keep in mind that you are free to use any command that you desire. For example, if you prefer /killme over /k, then edit that line accordingly. Search for "if (sendIt) {", and you will see this section:

if (sendIt) {
std::string message = hud->getComposeString();
if (message.length() > 0) {
const char* cmd = message.c_str();
if (LocalCommand::execute(cmd)) {
;
} else if (serverLink) {

Notice the line "std::string message = hud->getComposeString();". Below that, we will add our lines of code:

if(message=="/kk") {
const Player *someOther = LocalPlayer::getMyTank()->getRecipient();
if (someOther)
{
SuperkillMe = someOther->getId();
}
}

else if(message=="/ks") {
SuperkillMe = 0;
}

else if(message=="/k") {
const Player *Other = LocalPlayer::getMyTank()->getRecipient();
if(Other)
{
killMe = Other->getId();
}
}

The next line after our addition is "if (message.length() > 0) {". Let's add "else" in front of that so that the line now reads like this:

else if (message.length() > 0) {

The section after our change should now read like this:

if (sendIt) {
std::string message = hud->getComposeString();

if(message=="/kk") {
const Player *someOther = LocalPlayer::getMyTank()->getRecipient();
if (someOther)
{
SuperkillMe = someOther->getId();
}
}

else if(message=="/ks") {
SuperkillMe = 0;
}

else if(message=="/k") {
const Player *Other = LocalPlayer::getMyTank()->getRecipient();
if(Other)
{
killMe = Other->getId();
}
}

else if (message.length() > 0) {
const char* cmd = message.c_str();
if (LocalCommand::execute(cmd)) {
;
} else if (serverLink) {
char messageBuffer[MessageLen];

In the example above, we used "/ks" as the command to terminate the automatic getting killed on demand, or SuperkillMe. When we enter the command "/ks", SuperkillMe is set to 0, and automatic getting killed is over until we initiate it again.

After you make your changes, save your files, compile your new client, and you're done. Watching dead or paused players rack up points or team kills can be quite amusing... as well as observers going on killing sprees :P

In the immortal words of dj28:

"Have fun pissing people off and ruining their fun."

>:)

**********

Related posts:

Choose Who Kills You
Using God Mode with Choose Who Kills You