• View unanswered postsView active topics

  • [tutorial] Interactive Wall Patches in Wolf4SDL

    Discuss Wolf3D and Wolf3D modding/ports

    Postby Tricob1974 22 Nov 2011, 08:27

    In this tutorial, you'll be shown how to make your Wall Patches interactive in Wolf4SDL. The tutorial assumes you've enabled the Wall Patches using Haasboy's tutorial.

    First off, for the Wall Patches marked as "used", you'll want them to stay "used" when you save a game and load it again. So, go into WL_MAIN.CPP. Do a search for "SaveTheGame". You should see this:
    Code: Select all
    /*
    ==================
    =
    = SaveTheGame
    =
    ==================
    */

    Insert this just below it:
    Code: Select all
    // originally coded by Adam Biser
    #define objplanesize  MAPSIZE*MAPSIZE*2
    extern word *mapsegs[MAPPLANES];

    Next, do a search for "tilemap". You should see this code:
    Code: Select all
        DiskFlopAnim(x,y);
        fwrite(tilemap,sizeof(tilemap),1,file);
        checksum = DoChecksum((byte *)tilemap,sizeof(tilemap),checksum);
        DiskFlopAnim(x,y);

    This should be inserted just above that code:
    Code: Select all
        DiskFlopAnim(x,y);
        fwrite(mapsegs[1],objplanesize,1,file);
        checksum = DoChecksum((byte *)mapsegs[1],objplanesize,checksum);

    Now do a search for "SetupGameLevel". You should see this:
    Code: Select all
        DiskFlopAnim(x,y);
        SetupGameLevel ();

    This should be inserted just below it:
    Code: Select all
        DiskFlopAnim(x,y);
        fread(mapsegs[1],objplanesize,1,file);
        checksum = DoChecksum((byte *)mapsegs[1],objplanesize,checksum);

    You see, all the Wall Patches data is located in the 2nd Plane. What this added code does is tell the game to save and load that data with your saved game. So whenever the Wall Patches data is changed, any game you save will reflect those changes.

    Okay, the way the Wolf4SDL code is written, if you change a square on the map in WL_AGENT or WL_PLAY, the game will "forget" the square is changed after it updates the screen. There's probably a better way to do this, but I do have a workaround. Go into WL_DEF.H, and do a search for "void PushWall". You should see this code:
    Code: Select all
    void OpenDoor (int door);
    void PlaceItemType (int itemtype, int tilex, int tiley);
    void PushWall (int checkx, int checky, int dir);

    Immediately below that, insert this line of code:
    Code: Select all
    void MapSquareChange (int checkx, int checky, int32_t value, int PlaneNumber);


    Okay, now go into WL_ACT1.CPP. Do a search for "PUSHWALLSND". You see this code:
    Code: Select all
        *(mapsegs[0]+(pwally<<mapshift)+pwallx) = *(mapsegs[0]+(player->tiley<<mapshift)+player->tilex); // set correct floorcode (BrotherTank's fix)

        SD_PlaySound (PUSHWALLSND);
    }

    Insert this code just below it:
    Code: Select all
    // Map Square Change - change the specified square of the Objects Plane to the value you specify.
    // Example:  MapSquareChange (31, 32, 255, 0) will turn square (31,32) of the map to value 255, located in Plane Zero.

    void MapSquareChange (int checkx, int checky, int32_t value, int PlaneNumber)
    {
         *(mapsegs[PlaneNumber]+(checky<<mapshift)+checkx) = value;
    }

    You now have "the power" to change any square on the map - in any map plane - to another value, and do so from *any* source CPP file in the game, without having to add "extern" commands all over the place.

    Finally, go into WL_AGENT.CPP. We're about to put in the fun part of the code, where we make the Wall Patches interactive. Do a search for "pushable wall". You should see this:
    Code: Select all
            //
            // pushable wall
            //

            PushWall (checkx,checky,dir);
            return;
        }

    Insert this just below that code:
    Code: Select all
        if (!buttonheld[bt_use])
           switch (*(mapsegs[1]+(checky<<mapshift)+checkx))
                  {
                    case 256:
                            buttonheld[bt_use] = true;
                            GiveKey (0);
                            SD_PlaySound (GETKEYSND);
                            MapSquareChange(checkx,checky,255,1);
                            StartBonusFlash ();
                            break;
                  }

    Now, in this example, if the Wall Patch has the value 256, the code will regard it as a Gold Key, "pick it up", and mark the Wall Patch as "used", changing the square's value to 255, so the Wall Patch can't be used again unless you "die" or warp to that same level again.

    I believe that covers everything. Hope the tutorial proves useful to someone. :)
    Tricob1974

     
    Posts: 1382
    Location: Huntsville, Alabama

        

    Return to General Wolf3D/modding Discussion and tutorials


    Who is online

    Users browsing this forum: No registered users and 1 guest

    cron