Wednesday, August 8, 2007

Quick Guide to Toggling Cheats and Wallwalking

By: Phasmophage

Many of you have asked how to toggle cheats. It is one of the most important things cheaters should know how to do. Having a phase cheat is pretty frustrating without being able to turn it off to land on buildings. It's also nice to turn off the wings cheat on servers like Bloodbath, where they reversed wings gravity to make cheaters with wings shoot up into the air until they are autokicked. So here's a non-specific guide on cheat toggling.
Now, the method I use for toggling toggles cheats when you say certain commands by pressing "z", "n", "m", "," or "." So, for example, to toggle god mode I would say "/god" to my teammates, or whoever. The program then recognizes "/god" as a keyword, toggles the cheat, and prevents "/god" from actually being sent. The file that controls sending messages to others is "ComposeDefaultKey.cxx". My personal ComposeDefaultKey.cxx is probably two times bigger than the original.

So let's get started, shall we? Open up "ComposeDefaultKey.cxx" and find these lines of code:
if (sendIt) {
std::string message = hud->getComposeString();
if (message.length() > 0) {
const char* cmd = message.c_str();
if (LocalCommand::execute(cmd)) {
;
} else if (serverLink) {

Let's focus on this line, for a second:
std::string message = hud->getComposeString();

"message" is our message (duh) that we're about to send out, so the "message" string is going to be very important to us later. But first, let me explain boolean variables. Boolean variables, or the "bool" type in C++ (the language used to create BZFlag) can only be true or false. This is the data type we will use to turn our cheats off and on. Now to access these variables from other files, (For example, we need to switch the variable in ComposeDefaultKey.cxx but perhaps the actual cheat is in playing.cxx) we need to declare a variable "extern" in some files.
Argh, I'm bad at explaining, so here's an example:
Open up playing.cxx and find these lines of code:

#ifdef ROBOT
static void handleMyTankKilled(int reason);
static ServerLink* robotServer[MAX_ROBOTS];
#endif


Right after those lines, put this:

bool bCheatOO = false;

That variable is our on and off switch that will let us walk through walls. The b is for "boolean" and the OO is for Oscillation Overthruster, and the "cheat" because we're cheating. You can name it whatever you want.

Now to access it in another file, like ComposeDefaultKey.cxx, find these lines of code:

#define MAX_MESSAGE_HISTORY (20)

MessageQueue messageHistory;
unsigned int messageHistoryIndex = 0;

and put this right after:
extern bool bCheatOO;

"Extern" tells us that this variable is defined elsewhere, but allows us to use it.
Now let's go back to these lines of code:

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

And change it to this:

if (sendIt) {
std::string message = hud->getComposeString();
if (message.length() > 0) {
const char* cmd = message.c_str();
if(message=="/oo")bCheatOO = !bCheatOO; //We added this line, which toggles bCheatOO
else if (LocalCommand::execute(cmd)) { //And put an "else" before "if"
;
} else if (serverLink) {

So if you enter "/oo" you'll switch the cheat to its opposite state.

Now, since the actual Oscillation Overthruster stuff is in LocalPlayer.cxx, let's open that up and find these lines of code:

/* local implementation headers */
#include "World.h"
#include "sound.h"
#include "ForceFeedback.h"
#include "effectsRenderer.h"

and put this right after:
extern bool bCheatOO;

Now for the real cheats. Find these lines of code:
// phased means we can pass through buildings
const bool phased = ((location == Dead) || (location == Exploding) ||
(getFlag() == Flags::OscillationOverthruster) ||
isPhantomZoned());

and change it to this:
const bool phased = ((location == Dead) || (location == Exploding) ||
(getFlag() == Flags::OscillationOverthruster) ||
isPhantomZoned() || bCheatOO);

See how we added "|| bCheatOO" to the end? This means if we have Oscillation Overthruster, Phantom Zone, OR if bCheatOO is turned on, then we can pass through buildings.

Find this line of code:
if (location == InBuilding && getFlag() == Flags::OscillationOverthruster) {

And change it to this:
if (location == InBuilding && (getFlag() == Flags::OscillationOverthruster || bCheatOO)) {

Actually, that line isn't too important, it just shows the the weird effects when you're crossing a wall.

Now find this:
if (expelled && phased)
expelled = (obstacle->getType() == WallObstacle::getClassName() ||
obstacle->getType() == Teleporter::getClassName() ||
(getFlag() == Flags::OscillationOverthruster && desiredSpeed < 0.0f &&
p[2] == 0.0f));

and change it to this:
if (expelled && phased)
expelled = (obstacle->getType() == WallObstacle::getClassName() ||
obstacle->getType() == Teleporter::getClassName() ||
(getFlag() == Flags::OscillationOverthruster && !bCheatOO && desiredSpeed < 0.0f &&
p[2] == 0.0f));

This time, we added "&& !bCheatOO" meaning "And bCheatOO is NOT turned on" because what these lines of code do is make sure that we can't back up in buildings. And we do want to.
Find these lines of code:

expelled = (obstacle != NULL);
if (expelled && phased)
expelled = (obstacle->getType() == WallObstacle::getClassName() ||
obstacle->getType() == Teleporter::getClassName() ||
(hasOOflag && desiredSpeed < 0.0f && p[2] == 0.0f));

And change it to this:
expelled = (obstacle != NULL);
if (expelled && phased)
expelled = (obstacle->getType() == WallObstacle::getClassName() ||
(!bCheatOO && obstacle->getType() == Teleporter::getClassName()) ||
(hasOOflag && desiredSpeed < 0.0f && !bCheatOO && p[2] == 0.0f));

Find these lines of code:
// oscillation overthruster tank in building can't back up
if (fracOfMaxSpeed < 0.0f && getLocation() == InBuilding &&
flag == Flags::OscillationOverthruster) {
fracOfMaxSpeed = 0.0f;
}


And change it to this:
// oscillation overthruster tank in building can't back up
if (fracOfMaxSpeed < 0.0f && getLocation() == InBuilding &&
flag == Flags::OscillationOverthruster && !bCheatOO) {
fracOfMaxSpeed = 0.0f;
}

Find this line of code:
if (! (firingStatus == Ready || firingStatus == Zoned))
return false;


Which doesn't let us fire if we we're sealed, and change it to this:
if (! (firingStatus == Ready || bCheatOO || firingStatus == Zoned))
return false;


Also find this:
// make sure we're allowed to shoot
if (!isAlive() || isPaused() ||
((location == InBuilding) && !isPhantomZoned())) {
return false;
}

And change it to this:
// make sure we're allowed to shoot
if (!isAlive() || isPaused() ||
((location == InBuilding) && !isPhantomZoned() && !bCheatOO)) {
return false;
}


And that's all of it. I think. If this doesn't work, let me know. Hopefully, this will teach you how to toggle your cheats. Again, every cheater needs to know how to do this. Seriously. Have fun with this! And if you have any ideas, critiques, or if you enjoyed this not-so-quick cheat guide: Please, leave a comment. ;)
And I am out!
-Phaz

11 comments:

Someone said...

Wow... thats complicated.

I was about to release my way:

To toggle wall-walking:

In src/bzflag/LocalPlayer.cxx add this to the top:

===

#include "SDL_keyboard.h"

===

Find this:

===

// phased means we can pass through buildings
const bool phased = ((location == Dead) || (location == Exploding) ||
(getFlag() == Flags::OscillationOverthruster) ||
isPhantomZoned());

===

Replace with:

===

// phased means we can pass through buildings
bool phased = ((location == Dead) || (location == Exploding) ||
(getFlag() == Flags::OscillationOverthruster) ||
isPhantomZoned());
if (SDL_GetModState() & 64)
phased = 1;

===

Control will make you be able to wall walk.

The code for shift is:
if (SDL_GetModState() & 1)
The code for ctrl is:
if (SDL_GetModState() & 64)
The code for alt is:
if (SDL_GetModState() & 256)

Someone said...

This is a really really good, anonymous one. When you have the Shield flag, all shots on the map stop. Tanks can only shoot a few feet, depending on lag.

Don't be tempted to remove the if (flag == Flags::Shield) because you will be autokicked.

In src/bzflag/playing.cxx find:

===

// skip this if i'm dead or paused
if (!myTank->isAlive() || myTank->isPaused()) return;

===

After that add this:

===
if (myTank->getFlag() == Flags::Shield)
for (int i = 0; i < curMaxPlayers; i++)
if (player[i])
for (int sc = 0; sc < player[i]->getMaxShots(); sc++) {
const ShotPath* shot = player[i]->getShot(sc);
if (!shot || shot->isExpired())
continue;
serverLink->sendEndShot(shot->getPlayer(), shot->getShotId(), 1)
}

phasmophage said...

Yikes! I actually have the end bullet cheat too. How did you know about the shield thing? Did you look in the bzfs source too, for the endshotcredit--?
How did you get the codes for getModState?

Unknown said...

kewl, so for toggle the wings cheat, the line.

// can't control motion in air unless have wings
if (getFlag() == Flags::Wings) {
float speed = desiredSpeed;


Should be replaced with:


// can't control motion in air unless have wings
if (SDL_GetModState() & 1) {
float speed = desiredSpeed;


Where did you get de SDL_GetModState codes ?

Someone said...

phasmophage: i've had the endshot cheat for a long time. yes, i did look in the bzfs source.
recently, i though someone was doing it on mofo. was that you?
for the SDL codes, i found them by using a printf statement.

phasmophage said...

Yeah, that was probably me. ;)
Nice job reading the BZFS code.
Sorry my post was too complicated, I now found a way to bind the phasing command to a key. (I had to take out toggleradar, but I never toggle it off anyway.)
Damn someone, you're pretty darn good!

randomdude said...

I'm having troubles getting this to work, i'm using 2.0.9 not .8, does that make a difference?

My error is to do with the fact that sdl_keyboard doesn't exist.

When i tried phaz's tut, i got error messages about MessageQueue. Ended up having to revert my composedefaultkey file :(.

phasmophage said...

I don't know much about the SDL_keyboard thing, but have you downloaded SDL?
Sorry about you having to revert your composedefaultkey.cxx
If you try again and it doesn't work, I'll take a look at it.
You might want to try binding toggling to less used commmands in clientcommands.cxx like "toggleRadar" because I never turn it off.
Just take out the CMDMGR.run() and warnaboutradar() and put bcheatoo = !bcheatoo.

person said...
This comment has been removed by the author.
person said...
This comment has been removed by the author.
Spazman said...

wat program do i use to open up playing.cxx and other .cxx files