DieHard Wolfers Forum Index DieHard Wolfers
A Wolfenstein 3d Fan Community


  Hosted by: MCS & Areyep.com - Designed by: BrotherTank

Original Yahoo Forum - Die Hard Archives

AReyeP HomepageAreyep Homepage DieHard Wolfenstein BunkerDieHard Wolfenstein Bunker Log inLog in RegisterRegister Banlist FAQFAQ Search ForumsSearch

  Username:    Password:      Remember me       

Pushwall running over enemies
Page 1 of 1
DieHard Wolfers Forum Index -> SDL Code Crackers View Previous TopicRefresh this PageAdd Topic to your Browser FavoritesSearch ForumsPrint this TopicE-mail TopicGoto Page BottomView Next Topic
Post new topicReply to topic
Author Message
ronwolf1705
Moderator
<B>Moderator</B>


Joined: 31 Jul 2006
Last Visit: 4:07 ago.

Topics: 73
Posts: 3774

blank.gif

PostPosted: Mon Sep 08, 2014 7:29 am
   Subject: Pushwall running over enemies
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Next PostGoto Bottom of Posts

I tried adding AlumiuN's 'pushwalls kill' feature from the MMC to my project (#ifdef PUSHWALLSKILL). However, I couldn't get it to work properly yet. So far, it runs over a guard when there's space inbetween. However, when the pushwall is directly against the guard, it just kills him without moving, as if it is blocked by the guard when the pushwall is set directly against it. Any ideas how to fix this?

EDIT: updated with Chris' fix, this should enable you to have pushwalls that can both run over enemies or, if you get in the way, kill the player. Credit goes to AlumiuN.

::: CODE :::
/*
===============
=
= PushWall
=
===============
*/

void PushWall (int checkx, int checky, int dir)
{
    int oldtile, dx, dy;

    if (pwallstate)
        return;

    oldtile = tilemap[checkx][checky];
    if (!oldtile)
        return;

    dx = dirs[dir][0];
    dy = dirs[dir][1];

#ifdef PUSHWALLSKILL
   int xl,yl,xh,yh;
    xl = (player->x-PLAYERSIZE) >> TILESHIFT;
    yl = (player->y-PLAYERSIZE) >> TILESHIFT;
    xh = (player->x+PLAYERSIZE) >> TILESHIFT;
   yh = (player->y+PLAYERSIZE) >> TILESHIFT;

    if (xl <= checkx+dx && checkx+dx <= xh && yl <= checky+dy && checky+dy <= yh && !godmode)
        playstate = ex_died;
#endif

    if (actorat[checkx+dx][checky+dy])
    {
#ifdef PUSHWALLSKILL
        objtype *check = (objtype *)actorat[checkx+dx][checky+dy];
        if (ISPOINTER(check))
        {
            if (check->flags & FL_SHOOTABLE)
                KillActor(check);
        }
        else
        {
#endif
        SD_PlaySound (NOWAYSND);
        return;
#ifdef PUSHWALLSKILL
      }
#endif
    }
    actorat[checkx+dx][checky+dy] = (objtype *)(uintptr_t) (tilemap[checkx+dx][checky+dy] = oldtile);

    gamestate.secretcount++;
    pwallx = checkx;
    pwally = checky;
    pwalldir = dir;
    pwallstate = 1;
    pwallpos = 0;
    pwalltile = tilemap[pwallx][pwally];
    tilemap[pwallx][pwally] = BIT_WALL;
    tilemap[pwallx+dx][pwally+dy] = BIT_WALL;
    *(mapsegs[1]+(pwally<<mapshift)+pwallx) = 0;   // remove P tile info
    *(mapsegs[0]+(pwally<<mapshift)+pwallx) = *(mapsegs[0]+(player->tiley<<mapshift)+player->tilex); // set correct floorcode (BrotherTank's fix)

    SD_PlaySound (PUSHWALLSND);
}



/*
=================
=
= MovePWalls
=
=================
*/

void MovePWalls (void)
{
    int oldblock,oldtile;

    if (!pwallstate)
        return;

    oldblock = pwallstate/128;

    pwallstate += (word)tics;

#ifdef PUSHWALLSKILL
        for (objtype *ob = objlist; ob; ob = ob->next)
        {
            if (ob->tilex == pwallx && ob->tiley == pwally && ob->flags & FL_SHOOTABLE)
                KillActor(ob);
        }
#endif

    if (pwallstate/128 != oldblock)
    {
        // block crossed into a new block
        oldtile = pwalltile;

        //
        // the tile can now be walked into
        //
        tilemap[pwallx][pwally] = 0;
        actorat[pwallx][pwally] = 0;
        *(mapsegs[0]+(pwally<<mapshift)+pwallx) = player->areanumber+AREATILE;

        int dx=dirs[pwalldir][0], dy=dirs[pwalldir][1];
        //
        // see if it should be pushed farther
        //
#ifdef THREESQUARES
        if (pwallstate>=384)            // only move two tiles fix
#else
        if (pwallstate>=256)            // only move two tiles fix
#endif
        {
            //
            // the block has been pushed two tiles
            //
            pwallstate = 0;
            tilemap[pwallx+dx][pwally+dy] = oldtile;
            return;
        }
        else
        {
            int xl,yl,xh,yh;
            xl = (player->x-PLAYERSIZE) >> TILESHIFT;
            yl = (player->y-PLAYERSIZE) >> TILESHIFT;
            xh = (player->x+PLAYERSIZE) >> TILESHIFT;
            yh = (player->y+PLAYERSIZE) >> TILESHIFT;

            pwallx += dx;
            pwally += dy;

#ifdef PUSHWALLSKILL
                if (xl <= pwallx+dx && pwallx+dx <= xh && yl <= pwally+dy && pwally+dy <= yh && !godmode)
                    playstate = ex_died;
                objtype *check = (objtype *)actorat[pwallx+dx][pwally+dy];
                if (ISPOINTER(check))
                {
                    if (check->flags & FL_SHOOTABLE)
                        KillActor(check);
                }
                else
#endif

            if (actorat[pwallx+dx][pwally+dy]
                || xl<=pwallx+dx && pwallx+dx<=xh && yl<=pwally+dy && pwally+dy<=yh)
            {
                pwallstate = 0;
                tilemap[pwallx][pwally] = oldtile;
                return;
            }
            actorat[pwallx+dx][pwally+dy] = (objtype *)(uintptr_t) (tilemap[pwallx+dx][pwally+dy] = oldtile);
            tilemap[pwallx+dx][pwally+dy] = BIT_WALL;
        }
    }

    pwallpos = (pwallstate/2)&63;
}


Last edited by ronwolf1705 on Mon Sep 08, 2014 12:02 pm; edited 1 time in total
Chris
DieHard Wolfer
DieHard Wolfer


Joined: 11 Mar 2003
Last Visit: 14 Dec 2018

Topics: 55
Posts: 2153
Location: Canada
blank.gif

PostPosted: Mon Sep 08, 2014 11:39 am
   Subject: Re: Pushwall running over enemies
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

What happens if you add opening/closing braces around the else of Pushwall() ?

::: CODE :::
#ifdef PUSHWALLSKILL
      objtype *check = (objtype *)actorat[checkx+dx][checky+dy];
      if (ISPOINTER(check))
      {
         if (check->flags & FL_SHOOTABLE)
            KillActor(check);
      }
      else
      {
#endif
         SD_PlaySound (NOWAYSND);
         return;
#ifdef PUSHWALLSKILL
      }
#endif

   }
   actorat[checkx+dx][checky+dy] = (objtype *)(uintptr_t) (tilemap[checkx+dx][checky+dy] = oldtile);
ronwolf1705
Moderator
<B>Moderator</B>


Joined: 31 Jul 2006
Last Visit: 4:07 ago.

Topics: 73
Posts: 3774

blank.gif

PostPosted: Mon Sep 08, 2014 12:00 pm
   Subject: Re: Pushwall running over enemies
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Next PostGoto Bottom of Posts

That fixes it! Thanks a lot, Chris Smile
Aryan_Wolf3D
DieHard Guard
DieHard Guard


Joined: 21 Jul 2011
Last Visit: 15 Dec 2018

Topics: 6
Posts: 202

blank.gif

PostPosted: Sat Jul 14, 2018 12:20 am
   Subject: Re: Pushwall running over enemies
   [ IP : Logged ]
Reply with quote
Goto Top of PostsGoto Previous PostGoto Bottom of Posts

Here's a little add-on to this tutorial... While this feature is nice, it lacks precision when checking if it should kill enemies, because it checks to see if the pushwall's tile coordinates are the same as the actor's. That works fine for stationary actors, but for moving ones, the pushwall can appear to go through them when the actor's tilex/tiley coords have moved to another spot. Just for fun, I had a look at the Rise of the Triad source to see what they used for their "pushwalls running over enemies" method, and it's actually very easy to port it into Wolf...

In MovePWalls, declare these at the top of the function:
::: CODE :::
void MovePWalls (void)
{
    #define PWALLRAD  0xD800      // you can use MINACTORDIST, but 0xD800 is a little better in my opinion
    #define PWALLTOL  0xC000

    fixed       px,py;
    int32_t    actrad,deltax,deltay;
    bool        killactor;

    int          oldblock,oldtile;

    if (!pwallstate)
        return;

Next, delete this:
::: CODE :::
#ifdef PUSHWALLSKILL
        for (objtype *ob = objlist; ob; ob = ob->next)
        {
            if (ob->tilex == pwallx && ob->tiley == pwally && ob->flags & FL_SHOOTABLE)
                KillActor(ob);
        }
#endif

And replace it with this:
::: CODE :::
#ifdef PUSHWALLSKILL         
        //
        // kill blocking actors
        //
        actrad = PWALLRAD + 0x5000;

        for (objtype *obj = player; obj; obj = obj->next)
        {
            px = ((fixed)pwallx << TILESHIFT) + 0x8000;
            py = ((fixed)pwally << TILESHIFT) + 0x8000;
           
            deltax = labs(px - obj->x);
            deltay = labs(py - obj->y);

            if (deltax > actrad || deltay > actrad)
               continue;

            killactor = false;

            switch (pwalldir)
            {
                case di_north:
                    if (obj->y < py && deltax < PWALLTOL)
                        killactor = true;
                    break;

                case di_east:
                    if (obj->x > px && deltay < PWALLTOL)
                        killactor = true;
                    break;

                case di_south:
                    if (obj->y > py && deltax < PWALLTOL)
                        killactor = true;
                    break;

                case di_west:
                    if (obj->x < px && deltay < PWALLTOL)
                        killactor = true;
                    break;
            }

            if (killactor)
            {
                if (obj->flags & FL_SHOOTABLE)
                    KillActor (obj);
            }
        }
#endif

That should be it. Just to be clear, this code is intended to work with the rest of the tutorial, not replace it. Make only the changes that I showed (besides any other custom behaviour that you want, feel free to experiment with this.)

Be sure to credit 3D Realms if you use this.

Cheers,
AryanWolf3D

_________________
"Way too many #ifdefs in the code!" - John Carmack
Display posts from previous:   
Post new topicReply to topic Time synchronized with the forum server time
DieHard Wolfers Forum Index -> SDL Code Crackers View Previous TopicRefresh this PageAdd Topic to your Browser FavoritesSearch ForumsPrint this TopicE-mail TopicGoto Page TopView Next Topic
Page 1 of 1
Jump to:  

Related topics
 Topics   Replies   Views   Last Post 
No new posts Announcement: Wolf3d & Spear of Destiny Shareware SDL Downloads
Author: BrotherTank
10 16492 Tue Aug 24, 2010 10:18 am
dcbasic View latest post
No new posts [help] Adding teleporters in wolf4sdl
Author: Mortimer
35 12227 Fri May 26, 2017 8:19 am
Military View latest post
No new posts [help] adding music and seamless levels, textured ceilings
Author: lilmanjs
34 6660 Fri Aug 22, 2008 1:12 pm
lilmanjs View latest post
No new posts [Help] Adding a weapon problem
Author: Zombie_Plan
10 2347 Thu Jul 24, 2008 4:26 pm
RichterBelmont12 View latest post
No new posts [SDL-Help] Wall patches fix
Author: insurrectionman
0 1293 Tue Jul 15, 2008 11:12 am
insurrectionman View latest post
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
   You cannot delete your posts in this forum
You cannot vote in polls in this forum


Copyright ©2003-2008 DieHard Wolfers
A Modified subBunker Theme by BrotherTank
Powered by phpBB © 2001, 2005 phpBB Group