Adversary mod explanation

Hi,

In this post I try to explain how we can use the adversary car in one race!,

The main idea is making the game believes that we are the driver with more points to make the game set the first driver as the Adversary. In this case we need to be the first driver, so, we can play with the adversary car.

The savegame I’ve created it’s very simple. We are the second driver with more points adn out rank is 0 (this is basic to use the adversary car). Rank positions are between 1 and 19, so, position 0 is a shortcut to achieve our objetive. Also, a drivre like Farmed Ted have more point than anyone and rank equals to 1. Later we’ll see why I’ve selected Farmed Ted with rank 1.

Now, I will show up, the decompilated code when you press the continue button in the black market:

case CONTINUE:
 
 if ( drivers[driverId].damage != 100 || useWeapons )
 {
    if ( isMultiplayerGame )
    {
       selectedRace_462CE8 = 0;
       v91 = setUndergroundMarketPrices();
       undergroundPricesSet_456B84 = v91;
       if (useWeapons && v91 )
       {
          enterBlackMarketScreen();
          dword_456B58 = 1;
       }
       else
       {
          loadMenuSoundEffect(1u, 24, 0, configuration.musicVolume, dword_445190);
          previewRaceScreen(raceDrivers_456758);
          dword_456B58 = 1;
       }
   }
   else
  {
       v92 = setUndergroundMarketPrices();
       undergroundPricesSet_456B84 = v92;
       if (useWeapons && v92 )
       {
          enterBlackMarketScreen();
       }
       else
       {
          loadMenuSoundEffect(1u, 24, 0, configuration.musicVolume, dword_445190);
          v93 = 0;
          v94 = 2;
          v95 = (int)dword_4608F0;
          do
          {
              if ( *(_DWORD *)(v95 - 108) > v93 )
              {
                   v5 = v94 - 2;
                   if ( v94 - 2 != driverId )
                       v93 = *(_DWORD *)(v95 - 108);
               }
               if ( *(_DWORD *)v95 > v93 )
               {
                    v5 = v94 - 1;
                    if ( v94 - 1 != driverId )
                    v93 = *(_DWORD *)v95;
               }
               if ( *(_DWORD *)(v95 + 108) > v93 && v94 != driverId )
                    v93 = *(_DWORD *)(v95 + 108);
               if ( *(_DWORD *)(v95 + 216) > v93 )
              {
                    v5 = v94 + 1;
                    if ( v94 + 1 != driverId )
                        v93 = *(_DWORD *)(v95 + 216);
              }
              if ( *(_DWORD *)(v95 + 324) > v93 )
              {
                    v5 = v94 + 2;
                    if ( v94 + 2 != driverId )
                    v93 = *(_DWORD *)(v95 + 324);
              }
              v94 += 5;
              v95 += 540;
          }
          while ( v94 - 2 < 20 );
          if ( drivers[ driverId].points <= v93 )
               selectRaceScreen();
          else
               adversaryPreviewScreen((const char **)v5);
      }
   }
   else
   {
         createPopup(144, 114, 384, 119, 1);
         writeTextInScreen("[Repair your car first.", 79530);
         writeTextInScreen((const char *)&unk_444160, 89770);
         writeTextInScreen("What'cha gonna do with that pile of", 100010);
         writeTextInScreen("junk, carry it around? Let me spell", 110250);
         writeTextInScreen("this out for you: R-E-P-A-I-R.", 120490);
         refreshAllScreen();
        loadMenuSoundEffect(2u, 23, 0, configuration.musicVolume, dword_44518C);
   }

 

Firstable, when you click in the continue button, the program checks if your car is not totally damaged, in this case, the program shows a popup noticing that you have your car broken and you need to repair it.

Next the program checks if you are in the black market or in the shop screen. If you are in the shop screen, the black market prices are recalculated and the screen is refreshed. In case that you are in the black market screen, the program calculates if you are the driver with more points (with the adversary savegame, Farmed Ted is the driver with more points 🙂 ). Depending on the result of this condition the program shows the selectRaceScreen (where you can select easy, medium or hard race) or the adversaryPreviewScreen (no circuit seleccion, and only two drivers in the race).

Well, this case is not new, normally we are not the driver with more points!, but all is based on this condition.

Now, we can are going to see in depth the code that sets the firsts driver as the adversary:

 

 maxPoints = 0;
 v119 = 0;
 if (numberOfParticipants > 0 )
 {
      int driverIndex = 0;
      do
      {
           if (drivers[driverIndex].points > maxPoints && v119 != v96 )
               maxPoints = drivers[driverIndex].points;
           ++v119;
           driverIndex = driverIndex + 1;
      }
      while ( v119 < numberOfParticipants);
 }
 v121 = v96;
 userPoints = drivers[v121].points;
 if (userPoints > maxPoints && !isMultiplayerGame )
   { 
        strcpy(raceParticipant[0].name, "Adversary");
        raceParticipant[0].difficulty = configuration.difficulty;
        raceParticipant[0].damage = 0;
        raceParticipant[0].rocket = 0;
        raceParticipant[0].carType = 6;
        raceParticipant[0].spikes = 1;
        raceParticipant[0].useWeapons = useWeapons;
        raceParticipant[0].mines = useWeapons != 0 ? 8 : 0;
        raceParticipant[2].r = *((byte *)v112 + 30);
        raceParticipant[2].g = *((byte *)v112 + 31);
        raceParticipant[2].b = *((byte *)v112 + 32);
        raceParticipant[3].r = *((byte *)v112 + 30);
        raceParticipant[3].g = *((byte *)v112 + 31);
        raceParticipant[3].b = *((byte *)v112 + 32);
 }

This code obtains if we are the driver with more points (note that only checks the first numberOfParticipants, normally 4, so only checks Duke Nukem, Jane Honda, Nasty Nick and Motor Mary)  and in this case sets the first participan name as Adversary, sets the carType as Adversary Car!, add spikes to this car (althouhg we can’t see it), and if we are using weapons, our car will contain 8 mines  :).

Also the program sets the 3th and 4th car color to grey, this is the reason because we see this cars with this colour.

 

In conclusion, since I’ve decompiled the code, I can test some cases and find out this kind of behaviour.  Probably, when I implement a Death Rally launcher, this program can change the oponents colours from grey to their original colour, and add rocket the adversary car.

 

 

Leave a Reply

Polls
Sorry, there are no polls available at the moment.
Donate

Help us to mantain this web and develop DreeRally