components/prboom/p_spec.c
/////////////////////////////
//
// T_Pusher looks for all objects that are inside the radius of
// the effect.
//
T_Pusher looks for all objects that are inside the radius of
the effect.
T_Pusher looks for all objects that are inside the radius of the effect .
void T_Pusher(pusher_t *p)
    {
    sector_t *sec;
    mobj_t   *thing;
    msecnode_t* node;
    int xspeed,yspeed;
    int xl,xh,yl,yh,bx,by;
    int radius;
    int ht = 0;
    if (!allow_pushers)
        return;
    sec = sectors + p->affectee;
    if (!(sec->special & PUSH_MASK))
        return;
     1) Affected Thing is above the floor.
        Apply the full force if wind, no force if current.
     2) Affected Thing is on the ground.
        Apply half force if wind, full force if current.
     3) Affected Thing is below the ground (underwater effect).
        Apply no force if wind, full force if current.
    if (p->type == p_push)
        {
         Seek out all pushable things within the force radius of this
         point pusher. Crosses sectors, so use blockmap.
        tmpusher = p;  MT_PUSH/MT_PULL point source
        radius = p->radius;  where force goes to zero
        tmbbox[BOXTOP]    = p->y + radius;
        tmbbox[BOXBOTTOM] = p->y - radius;
        tmbbox[BOXRIGHT]  = p->x + radius;
        tmbbox[BOXLEFT]   = p->x - radius;
        xl = (tmbbox[BOXLEFT] - bmaporgx - MAXRADIUS)>>MAPBLOCKSHIFT;
        xh = (tmbbox[BOXRIGHT] - bmaporgx + MAXRADIUS)>>MAPBLOCKSHIFT;
        yl = (tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT;
        yh = (tmbbox[BOXTOP] - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT;
        for (bx=xl ; bx<=xh ; bx++)
            for (by=yl ; by<=yh ; by++)
                P_BlockThingsIterator(bx,by,PIT_PushThing);
        return;
        }
     constant pushers p_wind and p_current
    if (sec->heightsec != -1)  special water sector?
        ht = sectors[sec->heightsec].floorheight;
    node = sec->touching_thinglist;  things touching this sector
    for ( ; node ; node = node->m_snext)
        {
        thing = node->m_thing;
        if (!thing->player || (thing->flags & (MF_NOGRAVITY | MF_NOCLIP)))
            continue;
        if (p->type == p_wind)
            {
            if (sec->heightsec == -1)  NOT special water sector
                if (thing->z > thing->floorz)  above ground
                    {
                    xspeed = p->x_mag;  full force
                    yspeed = p->y_mag;
                    }
                else  on ground
                    {
                    xspeed = (p->x_mag)>>1;  half force
                    yspeed = (p->y_mag)>>1;
                    }
            else  special water sector
                {
                if (thing->z > ht)  above ground
                    {
                    xspeed = p->x_mag;  full force
                    yspeed = p->y_mag;
                    }
                else if (thing->player->viewz < ht)  underwater
                    xspeed = yspeed = 0;  no force
                else  wading in water
                    {
                    xspeed = (p->x_mag)>>1;  half force
                    yspeed = (p->y_mag)>>1;
                    }
                }
            }
        else  p_current
            {
            if (sec->heightsec == -1)  NOT special water sector
                if (thing->z > sec->floorheight)  above ground
                    xspeed = yspeed = 0;  no force
                else  on ground
                    {
                    xspeed = p->x_mag;  full force
                    yspeed = p->y_mag;
                    }
            else  special water sector
                if (thing->z > ht)  above ground
                    xspeed = yspeed = 0;  no force
                else  underwater
                    {
                    xspeed = p->x_mag;  full force
                    yspeed = p->y_mag;
                    }
            }
        thing->momx += xspeed<<(FRACBITS-PUSH_FACTOR);
        thing->momy += yspeed<<(FRACBITS-PUSH_FACTOR);
        }
    }
void T_Pusher ( pusher_t * p ) { sector_t * sec ; mobj_t * thing ; msecnode_t * node ; int xspeed , yspeed ; int xl , xh , yl , yh , bx , by ; int radius ; int ht = 0 ; if ( ! allow_pushers ) return ; sec = sectors + p -> affectee ; if ( ! ( sec -> special & PUSH_MASK ) ) return ; if ( p -> type == p_push ) { tmpusher = p ; radius = p -> radius ; tmbbox [ BOXTOP ] = p -> y + radius ; tmbbox [ BOXBOTTOM ] = p -> y - radius ; tmbbox [ BOXRIGHT ] = p -> x + radius ; tmbbox [ BOXLEFT ] = p -> x - radius ; xl = ( tmbbox [ BOXLEFT ] - bmaporgx - MAXRADIUS ) >> MAPBLOCKSHIFT ; xh = ( tmbbox [ BOXRIGHT ] - bmaporgx + MAXRADIUS ) >> MAPBLOCKSHIFT ; yl = ( tmbbox [ BOXBOTTOM ] - bmaporgy - MAXRADIUS ) >> MAPBLOCKSHIFT ; yh = ( tmbbox [ BOXTOP ] - bmaporgy + MAXRADIUS ) >> MAPBLOCKSHIFT ; for ( bx = xl ; bx <= xh ; bx ++ ) for ( by = yl ; by <= yh ; by ++ ) P_BlockThingsIterator ( bx , by , PIT_PushThing ) ; return ; } if ( sec -> heightsec != -1 ) ht = sectors [ sec -> heightsec ] . floorheight ; node = sec -> touching_thinglist ; for ( ; node ; node = node -> m_snext ) { thing = node -> m_thing ; if ( ! thing -> player || ( thing -> flags & ( MF_NOGRAVITY | MF_NOCLIP ) ) ) continue ; if ( p -> type == p_wind ) { if ( sec -> heightsec == -1 ) if ( thing -> z > thing -> floorz ) { xspeed = p -> x_mag ; yspeed = p -> y_mag ; } else { xspeed = ( p -> x_mag ) >> 1 ; yspeed = ( p -> y_mag ) >> 1 ; } else { if ( thing -> z > ht ) { xspeed = p -> x_mag ; yspeed = p -> y_mag ; } else if ( thing -> player -> viewz < ht ) xspeed = yspeed = 0 ; else { xspeed = ( p -> x_mag ) >> 1 ; yspeed = ( p -> y_mag ) >> 1 ; } } } else { if ( sec -> heightsec == -1 ) if ( thing -> z > sec -> floorheight ) xspeed = yspeed = 0 ; else { xspeed = p -> x_mag ; yspeed = p -> y_mag ; } else if ( thing -> z > ht ) xspeed = yspeed = 0 ; else { xspeed = p -> x_mag ; yspeed = p -> y_mag ; } } thing -> momx += xspeed << ( FRACBITS - PUSH_FACTOR ) ; thing -> momy += yspeed << ( FRACBITS - PUSH_FACTOR ) ; } }
T_Pusher looks for all objects that are inside the radius of
the effect.
T_Pusher looks for all objects that are inside the radius of the effect .
// Be sure the special sector type is still turned on. If so, proceed. // Else, bail out; the sector type has been changed on us. // For constant pushers (wind/current) there are 3 situations: // // 1) Affected Thing is above the floor. // //    Apply the full force if wind, no force if current. // // 2) Affected Thing is on the ground. // //    Apply half force if wind, full force if current. // // 3) Affected Thing is below the ground (underwater effect). // //    Apply no force if wind, full force if current. // Seek out all pushable things within the force radius of this // point pusher. Crosses sectors, so use blockmap. // MT_PUSH/MT_PULL point source // where force goes to zero // constant pushers p_wind and p_current // special water sector? // things touching this sector // NOT special water sector // above ground // full force // on ground // half force // special water sector // above ground // full force // underwater // no force // wading in water // half force // p_current // NOT special water sector // above ground // no force // on ground // full force // special water sector // above ground // no force // underwater // full force