Beispiel #1
0
//
// P_FakeZMovement
//
void P_FakeZMovement (mobj_t *mo)
{
    // adjust height
    mo->z += mo->momz;

    if ((mo->flags & MF_FLOAT) && mo->target)
    {
	// float down towards target if too close
	if (!(mo->flags & MF_SKULLFLY) && !(mo->flags & MF_INFLOAT))
	{
	    fixed_t delta = (mo->target->z + (mo->height >> 1) - mo->z) * 3;

	    if (P_ApproxDistance(mo->x - mo->target->x, mo->y - mo->target->y) < ABS(delta))
		mo->z += (delta < 0 ? -FLOATSPEED : FLOATSPEED);
	}
    }
Beispiel #2
0
//
// P_WallMomSlide
// Adjusts the xmove / ymove
// so that the next move will slide along the wall.
//
static void P_WallMomSlide(line_t *ld)
{
    int     side;
    angle_t lineangle;
    angle_t moveangle;
    angle_t deltaangle;
    fixed_t movelen;
    fixed_t newlen;

    // First check the simple cases.
    if(ld->slopetype == ST_HORIZONTAL)
    {
        tmymove = 0;
        return;
    }
    if(ld->slopetype == ST_VERTICAL)
    {
        tmxmove = 0;
        return;
    }

    side = P_PointOnLineSide(slidemo->x, slidemo->y, ld);
    lineangle = R_PointToAngle2(0, 0, ld->dx, ld->dy);

    if(side == 1)
        lineangle += ANG180;

    moveangle = R_PointToAngle2(0, 0, tmxmove, tmymove);
    deltaangle = moveangle - lineangle;

    if(deltaangle > ANG180)
        deltaangle += ANG180;

    lineangle >>= ANGLETOFINESHIFT;
    deltaangle >>= ANGLETOFINESHIFT;

    movelen = P_ApproxDistance(tmxmove, tmymove);
    newlen = FixedMul(movelen, finecosine[deltaangle]);

    tmxmove = FixedMul(newlen, finecosine[lineangle]);
    tmymove = FixedMul(newlen, finesine[lineangle]);
}
Beispiel #3
0
//
// PIT_CheckThing
//
boolean PIT_CheckThing (mobj_t* thing)
{
    fixed_t	newdist;
    fixed_t	olddist;
    fixed_t	blockdist;
    int		flags;
    int		damage;
    int		tradius;

    flags = thing->flags;

    if (!(flags & (MF_SOLID|MF_SPECIAL|MF_MISSILE|MF_SHOOTABLE) ))
	return true;

    /* We've changed all of the MF_SPECIAL stuff to their */
    /* actual radius rather than all being 20*FRACUNIT but */
    /* we want the original size back again when picking up. */

//  if (flags & MF_SPECIAL)
      tradius = thing->info->pickupradius;
//  else
//    tradius = thing->radius;

    blockdist = tradius + tmthing->radius;

    if ( abs(thing->x - tmx) >= blockdist
	 || abs(thing->y - tmy) >= blockdist )
    {
	// didn't hit it
	return true;
    }

    // don't clip against self
    if (thing == tmthing)
	return true;

    if (flags & MF_MISSILE)
    {
      if (!tmthing->player)
	P_ExplodeMissile (thing);

      if (!(flags & (MF_SOLID|MF_SPECIAL|MF_SHOOTABLE) ))
	return (true);
    }

    // check if a mobj passed over/under another object

    if (tmthing->flags2 & MF2_PASSMOBJ)
    {
	if (tmthing->z >= thing->z + thing->height)
	    return true;	// over thing
	else if (tmthing->z + tmthing->height <= thing->z)
	    return true;	// under thing
    }

    // check for skulls slamming into things
    if (tmthing->flags & MF_SKULLFLY)
    {
	damage = ((P_Random()%8)+1)*tmthing->info->damage;

	P_DamageMobj (thing, tmthing, tmthing, damage);

	tmthing->flags &= ~MF_SKULLFLY;
	tmthing->momx = tmthing->momy = tmthing->momz = 0;

	P_SetMobjState (tmthing, (statenum_t) tmthing->info->spawnstate);

	return false;		// stop moving
    }


    // missiles can hit other things
    if (tmthing->flags & MF_MISSILE)
    {
	// see if it went over / under
	if (tmthing->z > thing->z + thing->height)
	    return true;		// overhead
	if (tmthing->z+tmthing->height < thing->z)
	    return true;		// underneath

	if (tmthing->target && (
	    tmthing->target->type == thing->type ||
	    (tmthing->target->type == MT_KNIGHT && thing->type == MT_BRUISER)||
	    (tmthing->target->type == MT_BRUISER && thing->type == MT_KNIGHT) ) )
	{
	    // Don't hit same species as originator.
	    if (thing == tmthing->target)
		return true;

	    if ((thing->type != MT_PLAYER)
	     && (Monsters_Infight1 == false)
	     && (Monsters_Infight2 == false))
	    {
		// Explode, but do no damage.
		// Let players missile other players.
		return false;
	    }
	}

	if (! (flags & MF_SHOOTABLE) )
	{
	    // didn't do any damage
	    return (boolean)!(flags & MF_SOLID);
	}

	// damage / explode
	damage = ((P_Random()%8)+1)*tmthing->info->damage;
	P_DamageMobj (thing, tmthing, tmthing->target, damage);

	// don't traverse any more
	return false;
    }

    // check for special pickup
    if (flags & MF_SPECIAL)
    {
	if (tmflags & MF_PICKUP)
	{
	    // can remove thing
	    P_TouchSpecialThing (thing, tmthing);
	}
	return (boolean)!(flags & MF_SOLID);
    }

    // [BH] don't hit if either thing is a corpse, which may still be solid if
    // they are still going through their death sequence.
    if ((flags & MF_CORPSE) || (tmthing->flags & MF_CORPSE))
	return true;

    // check if things are stuck and allow move if it makes them further apart

    if ((tmx == tmthing->x) && (tmy == tmthing->y))
	return true;

    newdist = P_ApproxDistance(thing->x - tmx, thing->y - tmy);
    olddist = P_ApproxDistance(thing->x - tmthing->x, thing->y - tmthing->y);

    if ((newdist > olddist)
     && (!((tmthing->z >= thing->z + thing->height)
      || (tmthing->z + tmthing->height <= thing->z))))
	return true;

    // killough 3/16/98: Allow non-solid moving objects to move through solid
    // ones, by allowing the moving thing (tmthing) to move if it's non-solid,
    // despite another solid thing being in the way.
    // killough 4/11/98: Treat no-clipping things as not blocking
    return (boolean)!((flags & MF_SOLID) && !(flags & MF_NOCLIP)
		&& (tmthing->flags & MF_SOLID));
}
Beispiel #4
0
//===========================================================================
// PIT_CheckThing
//===========================================================================
static boolean PIT_CheckThing(mobj_t *thing, void *parm)
{
    checkpos_data_t *tm = parm;
    fixed_t blockdist;
    boolean overlap = false;

    // don't clip against self
    if(thing == tm->thing)
        return true;
    if(!(thing->ddflags & DDMF_SOLID))
        return true;

    blockdist = thing->radius + tm->thing->radius;

    // Only players can move under or over other things.
    if(tm->z != DDMAXINT && (tm->thing->dplayer	/* || thing->dplayer */
                             || thing->ddflags & DDMF_NOGRAVITY))
    {
        if(thing->z > tm->z + tm->height)
        {
            // We're under it.
            return true;
        }
        else if(thing->z + thing->height < tm->z)
        {
            // We're over it.
            return true;
        }
        overlap = true;
    }
    if(abs(thing->x - tm->x) >= blockdist ||
            abs(thing->y - tm->y) >= blockdist)
    {
        // Didn't hit it.
        return true;
    }
    if(overlap)
    {
        // How are we positioned?
        if(tm->z >= thing->z + thing->height - 24 * FRACUNIT)
        {
            // Above, allowing stepup.
            tm->thing->onmobj = thing;
            tm->floorz = thing->z + thing->height;
            return true;
        }

        // To prevent getting stuck, don't block if moving away from
        // the object.
        if(tm->thing->dplayer &&
                P_ApproxDistance(tm->thing->x - thing->x,
                                 tm->thing->y - thing->y) <
                P_ApproxDistance(tm->x - thing->x, tm->y - thing->y) &&
                tm->thing->momz > -12 * FRACUNIT)
        {
            // The current distance is smaller than the new one would be.
            // No blocking needs to occur.
            // The Z movement test is done to prevent a 'falling through'
            // case when a thing is moving at a high speed.
            return true;
        }

        // We're hitting this mobj.
        blockingMobj = thing;
    }
    return false;
}