Ejemplo n.º 1
0
/*** GetFMFromFile - Generate a FILEMARKS for marks in a file region
*
* Purpose:
*
*   Generates a subset of a FILEMARKS structure whose marks fall
*   within a certain range.  Needed by MarkCopy*.
*
* Input:
*   pFile	    - File to get marks from
*   xLeft, yTop     - Start of range
*   xRight, yBottom - End of range
*
* Output:
*
*   Returns Pointer to new structure, NULL if there are no marks in range
*
*************************************************************************/
FILEMARKS *
GetFMFromFile (
    PFILE   pFile,
    COL     xLeft,
    LINE    yTop,
    COL     xRight,
    LINE    yBottom
    )
{

    FILEMARKS UNALIGNED * pfm = NULL;
    REGISTER MARK UNALIGNED * pm;
    fl       flStart;
    fl       flEnd;
    flagType fInRange = FALSE;

    if (!fCacheMarks (pFile)) {
        return NULL;
    }

    flStart.lin = yTop;
    flStart.col = xLeft;
    flEnd.lin = yBottom;
    flEnd.col = xRight;

    for (pm = pfmCache->marks; !TESTFLAG(pm->flags, MF_DUMMY); (char *)pm += pm->cb) {
        if ((fInRange || flcmp (&flStart, (fl *) &pm->fl) < 1) &&
            (flcmp ((fl *) &pm->fl, &flEnd) < 1)) {
            fInRange = TRUE;
            if ((pm->fl.col >= xLeft && pm->fl.col <= xRight)) {
                UpdMark (   (FILEMARKS **) &pfm,
                            pm->szName,
                            pm->fl.lin - yTop + 1,
                            pm->fl.col - xLeft + 1,
                            (flagType)pm->flags);
            }
        } else {
            break;  /* We're out of range again*/
        }
    }
    return (FILEMARKS *) pfm;
}
Ejemplo n.º 2
0
/*** UpdMark - Add a mark to a FILEMARKS
*
* Purpose:
*
*   This creates the FILEMARKS structure, adds marks to it and
*   updates existing marks in it.  The caller does not need to
*   know which of these is going to happen.
*
* Input:
*   ppfm    - Pointer to a pointer to FILEMARKS.
*   pszMark - Mark name.
*   yMark   - Mark location (1-based)
*   xMark
*   fTemp   - TRUE => This marks should not be written to the markfile
*
* Output: None.  *ppfm may be changed
*
* Notes:
*
*   The first argument is a ** because the * will be updated when a
*   re-LMAlloc is required.
*
*************************************************************************/
void
UpdMark (
    FILEMARKS ** ppfm,
    char       * pszMark,
    LINE         yMark,
    COL          xMark,
    flagType     flags
    ) {

    FILEMARKS UNALIGNED * pfm;
    FILEMARKS UNALIGNED * pfmOld;         /* pfm prior to realloc     */
    REGISTER MARK UNALIGNED * pm;
    int      cbNewMark;
    fl       flMark;
    flagType fExist = FALSE;

    assert (ppfm);

    /* Convert to 0-based */
    flMark.lin = yMark-1;
    flMark.col = xMark-1;
    cbNewMark  = sizeof(MARK) + strlen(pszMark);

    // If we already have a FILEMARKS structure,
    // we look for the slot in pfm->marks
    // where the new mark will go.
    //
    if (pfm = *ppfm) {
        for (pm = pfm->marks; !TESTFLAG(pm->flags, MF_DUMMY); (char *)pm += pm->cb) {
            if (!_stricmp (pszMark, pm->szName)) {
                fExist = TRUE;
                break;
            }

            // Check for current mark coming later than
            // new mark
            //
            if (flcmp ((fl *) &pm->fl, &flMark) > 0) {
                break;
            }
        }
    } else {
        // New structure.  Allocate mem and create
        // a dummy mark.
        //
        pfm = (FILEMARKS *)ZEROMALLOC (sizeof(FILEMARKS));
        pfm->cb = sizeof(FILEMARKS);
        pm = pfm->marks;
        pm->cb = sizeof(MARK);
        pm->fl.lin = 0x7FFFFFFF;
        pm->fl.col = 0x7FFF;
        pm->szName[0] = '\0';
        pm->flags = MF_DUMMY;
    }

    // At this point, pfm points to the current FILEMARKS
    // structure, and pm points into that structure at
    // the place where the new mark will go, or the existing
    // mark be updated.
    //
    if (!fExist) {

        pfmOld = pfm;

        // First, get enough extra space for a new mark, adjusting pm
        // if a new alloc was required
        //
		pfm = (FILEMARKS *)ZEROREALLOC((PVOID)pfm, pfm->cb + cbNewMark);
        if (pfmOld != pfm) {
            pm = (MARK *)((char *)pfm + ((char *)pm - (char *)pfmOld));
        }

        // Now pm points to the location in pfm where
        // our new mark should go.  We will move the
        // original filemarks up to leave space for the
        // new one.
        //
        memmove ((char *)((char *)pm + cbNewMark),
                (char *)pm,
                pfm->cb - ((char *)pm - (char *)pfm));

        strcpy (pm->szName, pszMark);
        pm->flags = 0;
        pm->cb = cbNewMark;

        pfm->cb += cbNewMark;
    }

    if (pfm == pfmCache) {
        fCacheDirty = TRUE;
    }
    pm->flags = flags;
    pm->fl = flMark;

    *ppfm = (FILEMARKS *)pfm;
}
Ejemplo n.º 3
0
/*** MarkDelBox - Adjust Marks after a DelBox
*
* Purpose:
*
*   After deleting a box of text, we must remove any marks that are
*   defined inside it, then shift left any marks that are to the
*   right of it.
*
* Input:
*   pFile - Affected file
*   xLeft, yTop - Upper left hand corner of box
*   xRight, yBottom - Lower right hand corner of box
*
* Output: None
*
*************************************************************************/
void
MarkDelBox (
    PFILE pFile,
    COL  xLeft,
    LINE yTop,
    COL  xRight,
    LINE yBottom
    ) {

    MARK UNALIGNED *   pm;
    MARK UNALIGNED *   pmStart = NULL;
    MARK UNALIGNED *   pmEnd = NULL;
    fl       flUpLeft;
    fl       flLoRight;
    flagType fAgain;
    flagType fInBox = FALSE;	/* Marks are within box top/bottom */

    if (!fCacheMarks (pFile)) {
        return;
    }

    /* yBottom++;  WHY? */
    flUpLeft.lin = yTop;
    flUpLeft.col = xLeft;
    flLoRight.lin = yBottom;
    flLoRight.col = xRight;


    for (pm = pfmCache->marks; !TESTFLAG(pm->flags, MF_DUMMY) ; !fAgain && ((char *)pm += pm->cb)) {
        /* First, look for lowest possible mark */
        fAgain = FALSE;
        if (!fInBox) {
            if (flcmp (&flUpLeft, (fl *) &pm->fl) < 1) {
                fAgain = TRUE;
                fInBox = TRUE;
            } else {
                ;
            }
        } else if (flcmp ((fl *) &pm->fl, &flLoRight) < 1) {
            /* Now we're in range.  Check
            ** for being inside the box.
            */
            if (pm->fl.col >= xLeft) {
                if (pm->fl.col <= xRight) {
                    DelPMark ((MARK *) pm);
                    fAgain = TRUE;
                } else {   /* Mark to the right of box */
                    pm->fl.col -= xRight - xLeft + 1;
                }
            } else {
                ;
            }
        } else {
            if (pm->fl.lin == yBottom) {
                pm->fl.col -= xRight - xLeft + 1;
            } else {
                break;      /* We've gone past the box */
            }
        }
    }
}
Ejemplo n.º 4
0
/*** MarkDelStream - Adjust Marks after a DelStream
*
* Purpose:
*
*   After DelStream or DelLines removes a stream (DelLine removes a
*   "stream" with the beginning and ending points at the left and right
*   edges of the file), this takes care of updating any remaining
*   marks.
*
* Input:
*   pFile  - Affected file
*   xStart - 0-based starting point
*   yStart
*   xEnd   - 0-based ending point
*   yEnd
*
* Output: None
*
*************************************************************************/
void
MarkDelStream (
    PFILE pFile,
    COL  xStart,
    LINE yStart,
    COL  xEnd,
    LINE yEnd
    ) {

    REGISTER MARK UNALIGNED * pm;
    MARK UNALIGNED *      pmStart = NULL;
    MARK UNALIGNED *      pmEnd = NULL;
    fl          flStart;
    fl          flEnd;
    flagType    fAgain = FALSE;

    if (!fCacheMarks (pFile)) {
        return;
    }

    /* yEnd++;  WHY? */
    flStart.lin = yStart;
    flStart.col = xStart;
    flEnd.lin = yEnd;
    flEnd.col = xEnd;

    for (pm = pfmCache->marks; pmEnd == NULL ; (char *)pm += pm->cb) {
        // Look for first mark past beginning
        // of stream. Assume for the moment that
        // it is inside the stream
        //
        if (pmStart == NULL) {
            if (flcmp (&flStart, (fl *) &pm->fl) < 1) {
                pmStart = pm;
            } else {
                continue;
            }
        }

        // A first mark has been found. We start
        // looking for the first mark past the end
        // of the stream.  If these are the same,
        // there are no marks to remove.
        //
        if (flcmp (&flEnd, (fl *) &pm->fl) < 1) {
            // We know that we will end up here
            // because the last "mark" is higher
            // than any real mark
            //
            if ((pmEnd = pm) != pmStart)
                // We're here if there were
                // any marks inside the deleted
                // stream
                //
                memmove ((char *)pmStart,
                         (char *)pmEnd,
                        ((char *)pfmCache + pfmCache->cb) - (char *)pmEnd );

            if (pmStart->fl.lin == yEnd) {
                pmStart->fl.col -= xEnd;
            }
            AdjustMarks ((MARK *)pmStart, yStart - (yEnd + 1));
        }

        assert (pm->cb ||
                (TESTFLAG(pm->flags, MF_DUMMY) &&
                pm->fl.lin == 0x7FFFFFFF &&
                pm->fl.col == 0x7FFF));
    }
}
Ejemplo n.º 5
0
void NPC_Probe_Pain( gentity_t *self, gentity_t *attacker, int damage ) {
	float	pain_chance;
	gentity_t *other = attacker;
	int mod = gPainMOD;

	VectorCopy( &self->NPC->lastPathAngles, &self->s.angles );

	if ( self->health < 30 || mod == MOD_DEMP2 || mod == MOD_DEMP2_ALT ) // demp2 always messes them up real good
	{
		vector3 endPos;
		trace_t	trace;

		VectorSet( &endPos, self->r.currentOrigin.x, self->r.currentOrigin.y, self->r.currentOrigin.z - 128 );
		trap->Trace( &trace, &self->r.currentOrigin, NULL, NULL, &endPos, self->s.number, MASK_SOLID, qfalse, 0, 0 );

		if ( flcmp( trace.fraction, 1.0f, 0.001f ) || mod == MOD_DEMP2 ) // demp2 always does this
		{
			/*
			if (self->client->clientInfo.headModel != 0)
			{
			vector3 origin;

			VectorCopy(self->r.currentOrigin,origin);
			origin.z +=50;
			//				G_PlayEffect( "small_chunks", origin );
			G_PlayEffect( "chunks/probehead", origin );
			G_PlayEffect( "env/med_explode2", origin );
			self->client->clientInfo.headModel = 0;
			self->client->moveType = MT_RUNJUMP;
			self->client->ps.gravity = g_gravity->value*.1f;
			}
			*/

			if ( (mod == MOD_DEMP2 || mod == MOD_DEMP2_ALT) && other ) {
				vector3 dir;

				NPC_SetAnim( self, SETANIM_BOTH, BOTH_PAIN1, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD );

				VectorSubtract( &self->r.currentOrigin, &other->r.currentOrigin, &dir );
				VectorNormalize( &dir );

				VectorMA( &self->client->ps.velocity, 550, &dir, &self->client->ps.velocity );
				self->client->ps.velocity.z -= 127;
			}

			//self->s.powerups |= ( 1 << PW_SHOCKED );
			//self->client->ps.powerups[PW_SHOCKED] = level.time + 3000;
			self->client->ps.electrifyTime = level.time + 3000;

			self->NPC->localState = LSTATE_DROP;
		}
	}
	else {
		pain_chance = NPC_GetPainChance( self, damage );

		if ( random() < pain_chance )	// Spin around in pain?
		{
			NPC_SetAnim( self, SETANIM_BOTH, BOTH_PAIN1, SETANIM_FLAG_OVERRIDE );
		}
	}

	NPC_Pain( self, attacker, damage );
}
Ejemplo n.º 6
0
void NPC_BSSniper_Attack( void ) {
	//Don't do anything if we're hurt
	if ( NPC->painDebounceTime > level.time ) {
		NPC_UpdateAngles( qtrue, qtrue );
		return;
	}

	//NPC_CheckEnemy( qtrue, qfalse );
	//If we don't have an enemy, just idle
	if ( NPC_CheckEnemyExt( qfalse ) == qfalse )//!NPC->enemy )//
	{
		NPC->enemy = NULL;
		NPC_BSSniper_Patrol();//FIXME: or patrol?
		return;
	}

	if ( TIMER_Done( NPC, "flee" ) && NPC_CheckForDanger( NPC_CheckAlertEvents( qtrue, qtrue, -1, qfalse, AEL_DANGER ) ) ) {//going to run
		NPC_UpdateAngles( qtrue, qtrue );
		return;
	}

	if ( !NPC->enemy ) {//WTF?  somehow we lost our enemy?
		NPC_BSSniper_Patrol();//FIXME: or patrol?
		return;
	}

	enemyLOS2 = enemyCS2 = qfalse;
	move2 = qtrue;
	faceEnemy2 = qfalse;
	shoot2 = qfalse;
	enemyDist2 = DistanceSquared( &NPC->r.currentOrigin, &NPC->enemy->r.currentOrigin );
	if ( enemyDist2 < 16384 )//128 squared
	{//too close, so switch to primary fire
		if ( NPC->client->ps.weapon == WP_DISRUPTOR ) {//sniping... should be assumed
			if ( NPCInfo->scriptFlags & SCF_ALT_FIRE ) {//use primary fire
				trace_t	trace;
				trap->Trace( &trace, &NPC->enemy->r.currentOrigin, &NPC->enemy->r.mins, &NPC->enemy->r.maxs, &NPC->r.currentOrigin, NPC->enemy->s.number, NPC->enemy->clipmask, qfalse, 0, 0 );
				if ( !trace.allsolid && !trace.startsolid && (flcmp( trace.fraction, 1.0f, 0.001f ) || trace.entityNum == NPC->s.number) ) {//he can get right to me
					NPCInfo->scriptFlags &= ~SCF_ALT_FIRE;
					//reset fire-timing variables
					NPC_ChangeWeapon( WP_DISRUPTOR );
					NPC_UpdateAngles( qtrue, qtrue );
					return;
				}
			}
			//FIXME: switch back if he gets far away again?
		}
	}
	else if ( enemyDist2 > 65536 )//256 squared
	{
		if ( NPC->client->ps.weapon == WP_DISRUPTOR ) {//sniping... should be assumed
			if ( !(NPCInfo->scriptFlags&SCF_ALT_FIRE) ) {//use primary fire
				NPCInfo->scriptFlags |= SCF_ALT_FIRE;
				//reset fire-timing variables
				NPC_ChangeWeapon( WP_DISRUPTOR );
				NPC_UpdateAngles( qtrue, qtrue );
				return;
			}
		}
	}

	Sniper_UpdateEnemyPos();
	//can we see our target?
	if ( NPC_ClearLOS4( NPC->enemy ) )//|| (NPCInfo->stats.aim >= 5 && gi.inPVS( NPC->client->renderInfo.eyePoint, NPC->enemy->currentOrigin )) )
	{
		float maxShootDist;

		NPCInfo->enemyLastSeenTime = level.time;
		VectorCopy( &NPC->enemy->r.currentOrigin, &NPCInfo->enemyLastSeenLocation );
		enemyLOS2 = qtrue;
		maxShootDist = NPC_MaxDistSquaredForWeapon();
		if ( enemyDist2 < maxShootDist ) {
			vector3 fwd, right, up, muzzle, end;
			trace_t	tr;
			int hit;

			AngleVectors( &NPC->client->ps.viewangles, &fwd, &right, &up );
			CalcMuzzlePoint( NPC, &fwd, &right, &up, &muzzle );
			VectorMA( &muzzle, 8192, &fwd, &end );
			trap->Trace( &tr, &muzzle, NULL, NULL, &end, NPC->s.number, MASK_SHOT, qfalse, 0, 0 );

			hit = tr.entityNum;
			//can we shoot our target?
			if ( Sniper_EvaluateShot( hit ) ) {
				enemyCS2 = qtrue;
			}
		}
	}
	/*
	else if ( gi.inPVS( NPC->enemy->currentOrigin, NPC->currentOrigin ) )
	{
	NPCInfo->enemyLastSeenTime = level.time;
	faceEnemy2 = qtrue;
	}
	*/

	if ( enemyLOS2 ) {//FIXME: no need to face enemy if we're moving to some other goal and he's too far away to shoot?
		faceEnemy2 = qtrue;
	}
	if ( enemyCS2 ) {
		shoot2 = qtrue;
	}
	else if ( level.time - NPCInfo->enemyLastSeenTime > 3000 ) {//Hmm, have to get around this bastard... FIXME: this NPCInfo->enemyLastSeenTime builds up when ducked seems to make them want to run when they uncrouch
		Sniper_ResolveBlockedShot();
	}

	//Check for movement to take care of
	Sniper_CheckMoveState();

	//See if we should override shooting decision with any special considerations
	Sniper_CheckFireState();

	if ( move2 ) {//move toward goal
		if ( NPCInfo->goalEntity )//&& ( NPCInfo->goalEntity != NPC->enemy || enemyDist2 > 10000 ) )//100 squared
		{
			move2 = Sniper_Move();
		}
		else {
			move2 = qfalse;
		}
	}

	if ( !move2 ) {
		if ( !TIMER_Done( NPC, "duck" ) ) {
			if ( TIMER_Done( NPC, "watch" ) ) {//not while watching
				ucmd.upmove = -127;
			}
		}
		//FIXME: what about leaning?
		//FIXME: also, when stop ducking, start looking, if enemy can see me, chance of ducking back down again
	}
	else {//stop ducking!
		TIMER_Set( NPC, "duck", -1 );
	}

	if ( TIMER_Done( NPC, "duck" )
		&& TIMER_Done( NPC, "watch" )
		&& (TIMER_Get( NPC, "attackDelay" ) - level.time) > 1000
		&& NPC->attackDebounceTime < level.time ) {
		if ( enemyLOS2 && (NPCInfo->scriptFlags&SCF_ALT_FIRE) ) {
			if ( NPC->fly_sound_debounce_time < level.time ) {
				NPC->fly_sound_debounce_time = level.time + 2000;
			}
		}
	}

	if ( !faceEnemy2 ) {//we want to face in the dir we're running
		if ( move2 ) {//don't run away and shoot
			NPCInfo->desiredYaw = NPCInfo->lastPathAngles.yaw;
			NPCInfo->desiredPitch = 0;
			shoot2 = qfalse;
		}
		NPC_UpdateAngles( qtrue, qtrue );
	}
	else// if ( faceEnemy2 )
	{//face the enemy
		Sniper_FaceEnemy();
	}

	if ( NPCInfo->scriptFlags&SCF_DONT_FIRE ) {
		shoot2 = qfalse;
	}

	//FIXME: don't shoot right away!
	if ( shoot2 ) {//try to shoot if it's time
		if ( TIMER_Done( NPC, "attackDelay" ) ) {
			WeaponThink( qtrue );
			if ( ucmd.buttons&(BUTTON_ATTACK | BUTTON_ALT_ATTACK) ) {
				G_SoundOnEnt( NPC, CHAN_WEAPON, "sound/null.wav" );
			}

			//took a shot, now hide
			if ( !(NPC->spawnflags&SPF_NO_HIDE) && !Q_irand( 0, 1 ) ) {
				//FIXME: do this if in combat point and combat point has duck-type cover... also handle lean-type cover
				Sniper_StartHide();
			}
			else {
				TIMER_Set( NPC, "attackDelay", NPCInfo->shotTime - level.time );
			}
		}
	}
}