Beispiel #1
0
void script_mover_spawn(gentity_t *ent) {
	if (ent->spawnflags & 128) {
		gentity_t *tent = G_FindByTargetname(NULL, ent->tagBuffer);

		if (!tent) {
			ent->nextTrain = ent;
		} else {
			ent->nextTrain = tent;
		}

		ent->s.effect3Time = ent->nextTrain - g_entities;
	}

	if (ent->spawnflags & 2) {
		ent->clipmask   = CONTENTS_SOLID;
		ent->r.contents = CONTENTS_SOLID;
	} else {
		ent->s.eFlags  |= EF_NONSOLID_BMODEL;
		ent->clipmask   = 0;
		ent->r.contents = 0;
	}

	script_linkentity(ent);

	// now start thinking process which controls AAS interaction
	ent->think     = script_mover_aas_blocking;
	ent->nextthink = level.time + 200;
}
/*
====================
G_ScriptAction_Halt

  syntax: halt

  Stop moving.
====================
*/
qboolean G_ScriptAction_Halt( gentity_t *ent, char *params ) {
    if ( level.time == ent->scriptStatus.scriptStackChangeTime ) {
        ent->scriptStatus.scriptFlags &= ~SCFL_GOING_TO_MARKER;

        // stop the angles
        BG_EvaluateTrajectory( &ent->s.apos, level.time, ent->s.angles );
        VectorCopy( ent->s.angles, ent->s.apos.trBase );
        VectorCopy( ent->s.angles, ent->r.currentAngles );
        ent->s.apos.trTime = level.time;
        ent->s.apos.trDuration = 0;
        ent->s.apos.trType = TR_STATIONARY;
        VectorClear( ent->s.apos.trDelta );

        // stop moving
        BG_EvaluateTrajectory( &ent->s.pos, level.time, ent->s.origin );
        VectorCopy( ent->s.origin, ent->s.pos.trBase );
        VectorCopy( ent->s.origin, ent->r.currentOrigin );
        ent->s.pos.trTime = level.time;
        ent->s.pos.trDuration = 0;
        ent->s.pos.trType = TR_STATIONARY;
        VectorClear( ent->s.pos.trDelta );

        script_linkentity( ent );

        return qfalse;  // kill any currently running script
    } else {
        return qtrue;
    }
}
Beispiel #3
0
void script_mover_spawn( gentity_t *ent ) {
	if ( ent->spawnflags & 2 ) {
		ent->clipmask = CONTENTS_SOLID;
		ent->r.contents = CONTENTS_SOLID;
	} else {
		ent->s.eFlags |= EF_NONSOLID_BMODEL;
		ent->clipmask = 0;
		ent->r.contents = 0;
	}
	//ent->s.eType = ET_GENERAL;

	//ent->s.modelindex = G_ModelIndex (ent->model);
	//ent->s.frame = 0;

	//VectorCopy( ent->s.origin, ent->s.pos.trBase );
	//ent->s.pos.trType = TR_STATIONARY;

	script_linkentity( ent );
}
/*
=================
G_ScriptAction_BackupScript

  backs up the current state of the scripting, so we can restore it later and resume
  were we left off (useful if player gets in our way)
=================
*/
qboolean G_ScriptAction_BackupScript( gentity_t *ent, char *params ) {

    // if we're not at the top of an event, then something is _probably_ wrong with the script
//	if (ent->scriptStatus.scriptStackHead > 0) {
//		G_Printf( "ENTITY SCRIPT: WARNING: backupscript not at start of event, possibly harmful.\n");
//	}

    if ( !( ent->scriptStatus.scriptFlags & SCFL_WAITING_RESTORE ) ) {

        // if we are moving, stop here
        if ( ent->scriptStatus.scriptFlags & SCFL_GOING_TO_MARKER ) {
            ent->scriptStatus.scriptFlags &= ~SCFL_GOING_TO_MARKER;

            // set the angles at the destination
            BG_EvaluateTrajectory( &ent->s.apos, level.time, ent->s.angles );
            VectorCopy( ent->s.angles, ent->s.apos.trBase );
            VectorCopy( ent->s.angles, ent->r.currentAngles );
            ent->s.apos.trTime = level.time;
            ent->s.apos.trDuration = 0;
            ent->s.apos.trType = TR_STATIONARY;
            VectorClear( ent->s.apos.trDelta );

            // stop moving
            BG_EvaluateTrajectory( &ent->s.pos, level.time, ent->s.origin );
            VectorCopy( ent->s.origin, ent->s.pos.trBase );
            VectorCopy( ent->s.origin, ent->r.currentOrigin );
            ent->s.pos.trTime = level.time;
            ent->s.pos.trDuration = 0;
            ent->s.pos.trType = TR_STATIONARY;
            VectorClear( ent->s.pos.trDelta );

            script_linkentity( ent );
        }

        ent->scriptStatusBackup = ent->scriptStatusCurrent;
        ent->scriptStatus.scriptFlags |= SCFL_WAITING_RESTORE;
    }

    return qtrue;
}
/*
=================
G_ScriptAction_FaceAngles

  syntax: faceangles <pitch> <yaw> <roll> <duration/GOTOTIME> [ACCEL/DECCEL]

  The entity will face the given angles, taking <duration> to get there. If the
  GOTOTIME is given instead of a timed duration, the duration calculated from the
  last gotomarker command will be used instead.
=================
*/
qboolean G_ScriptAction_FaceAngles( gentity_t *ent, char *params ) {
    char *pString, *token;
    int duration, i;
    vec3_t diff;
    vec3_t angles;
    int trType = TR_LINEAR_STOP;

    if ( !params || !params[0] ) {
        G_Error( "G_Scripting: syntax: faceangles <pitch> <yaw> <roll> <duration/GOTOTIME>\n" );
    }

    if ( ent->scriptStatus.scriptStackChangeTime == level.time ) {
        pString = params;
        for ( i = 0; i < 3; i++ ) {
            token = COM_Parse( &pString );
            if ( !token || !token[0] ) {
                G_Error( "G_Scripting: syntax: faceangles <pitch> <yaw> <roll> <duration/GOTOTIME>\n" );
            }
            angles[i] = atoi( token );
        }

        token = COM_Parse( &pString );
        if ( !token || !token[0] ) {
            G_Error( "G_Scripting: faceangles requires a <pitch> <yaw> <roll> <duration/GOTOTIME>\n" );
        }
        if ( !Q_strcasecmp( token, "gototime" ) ) {
            duration = ent->s.pos.trDuration;
        } else {
            duration = atoi( token );
        }

        token = COM_Parse( &pString );
        if ( token && token[0] ) {
            if ( !Q_strcasecmp( token, "accel" ) ) {
                trType = TR_ACCELERATE;
            }
            if ( !Q_strcasecmp( token, "deccel" ) ) {
                trType = TR_DECCELERATE;
            }
        }

        for ( i = 0; i < 3; i++ ) {
            diff[i] = AngleDifference( angles[i], ent->s.angles[i] );
            while ( diff[i] > 180 )
                diff[i] -= 360;
            while ( diff[i] < -180 )
                diff[i] += 360;
        }

        VectorCopy( ent->s.angles, ent->s.apos.trBase );
        if ( duration ) {
            VectorScale( diff, 1000.0 / (float)duration, ent->s.apos.trDelta );
        } else {
            VectorClear( ent->s.apos.trDelta );
        }
        ent->s.apos.trDuration = duration;
        ent->s.apos.trTime = level.time;
        ent->s.apos.trType = TR_LINEAR_STOP;

        if ( trType != TR_LINEAR_STOP ) { // accel / deccel logic
            // calc the speed from duration and start/end delta
            for ( i = 0; i < 3; i++ ) {
                ent->s.apos.trDelta[i] = 2.0 * 1000.0 * diff[i] / (float)duration;
            }
            ent->s.apos.trType = trType;
        }

    } else if ( ent->s.apos.trTime + ent->s.apos.trDuration <= level.time ) {
        // finished turning
        BG_EvaluateTrajectory( &ent->s.apos, ent->s.apos.trTime + ent->s.apos.trDuration, ent->s.angles );
        VectorCopy( ent->s.angles, ent->s.apos.trBase );
        VectorCopy( ent->s.angles, ent->r.currentAngles );
        ent->s.apos.trTime = level.time;
        ent->s.apos.trDuration = 0;
        ent->s.apos.trType = TR_STATIONARY;
        VectorClear( ent->s.apos.trDelta );

        script_linkentity( ent );

        return qtrue;
    }

    BG_EvaluateTrajectory( &ent->s.apos, level.time, ent->r.currentAngles );
    script_linkentity( ent );

    return qfalse;
}
/*
===============
G_ScriptAction_GotoMarker

  syntax: gotomarker <targetname> <speed> [accel/deccel] [turntotarget] [wait]

  NOTE: speed may be modified to round the duration to the next 50ms for smooth
  transitions
===============
*/
qboolean G_ScriptAction_GotoMarker( gentity_t *ent, char *params ) {
    char    *pString, *token;
    gentity_t *target;
    vec3_t vec;
    float speed, dist;
    qboolean wait = qfalse, turntotarget = qfalse;
    int trType;
    int duration, i;
    vec3_t diff;
    vec3_t angles;

    if ( params && ( ent->scriptStatus.scriptFlags & SCFL_GOING_TO_MARKER ) ) {
        // we can't process a new movement until the last one has finished
        return qfalse;
    }

    if ( !params || ent->scriptStatus.scriptStackChangeTime < level.time ) {          // we are waiting for it to reach destination
        if ( ent->s.pos.trTime + ent->s.pos.trDuration <= level.time ) {  // we made it
            ent->scriptStatus.scriptFlags &= ~SCFL_GOING_TO_MARKER;

            // set the angles at the destination
            BG_EvaluateTrajectory( &ent->s.apos, ent->s.apos.trTime + ent->s.apos.trDuration, ent->s.angles );
            VectorCopy( ent->s.angles, ent->s.apos.trBase );
            VectorCopy( ent->s.angles, ent->r.currentAngles );
            ent->s.apos.trTime = level.time;
            ent->s.apos.trDuration = 0;
            ent->s.apos.trType = TR_STATIONARY;
            VectorClear( ent->s.apos.trDelta );

            // stop moving
            BG_EvaluateTrajectory( &ent->s.pos, level.time, ent->s.origin );
            VectorCopy( ent->s.origin, ent->s.pos.trBase );
            VectorCopy( ent->s.origin, ent->r.currentOrigin );
            ent->s.pos.trTime = level.time;
            ent->s.pos.trDuration = 0;
            ent->s.pos.trType = TR_STATIONARY;
            VectorClear( ent->s.pos.trDelta );

            script_linkentity( ent );

            return qtrue;
        }
    } else {    // we have just started this command

        pString = params;
        token = COM_ParseExt( &pString, qfalse );
        if ( !token[0] ) {
            G_Error( "G_Scripting: gotomarker must have an targetname\n" );
        }

        // find the entity with the given "targetname"
        target = G_Find( NULL, FOFS( targetname ), token );

        if ( !target ) {
            G_Error( "G_Scripting: can't find entity with \"targetname\" = \"%s\"\n", token );
        }

        VectorSubtract( target->r.currentOrigin, ent->r.currentOrigin, vec );

        token = COM_ParseExt( &pString, qfalse );
        if ( !token[0] ) {
            G_Error( "G_Scripting: gotomarker must have a speed\n" );
        }

        speed = atof( token );
        trType = TR_LINEAR_STOP;

        while ( token[0] ) {
            token = COM_ParseExt( &pString, qfalse );
            if ( token[0] ) {
                if ( !Q_stricmp( token, "accel" ) ) {
                    trType = TR_ACCELERATE;
                } else if ( !Q_stricmp( token, "deccel" ) )      {
                    trType = TR_DECCELERATE;
                } else if ( !Q_stricmp( token, "wait" ) )      {
                    wait = qtrue;
                } else if ( !Q_stricmp( token, "turntotarget" ) )      {
                    turntotarget = qtrue;
                }
            }
        }

        // start the movement
        if ( ent->s.eType == ET_MOVER ) {

            VectorCopy( vec, ent->movedir );
            VectorCopy( ent->r.currentOrigin, ent->pos1 );
            VectorCopy( target->r.currentOrigin, ent->pos2 );
            ent->speed = speed;
            dist = VectorDistance( ent->pos1, ent->pos2 );
            // setup the movement with the new parameters
            InitMover( ent );

            // start the movement

            SetMoverState( ent, MOVER_1TO2, level.time );
            if ( trType != TR_LINEAR_STOP ) { // allow for acceleration/decceleration
                ent->s.pos.trDuration = 1000.0 * dist / ( speed / 2.0 );
                ent->s.pos.trType = trType;
            }
            ent->reached = NULL;

            if ( turntotarget ) {
                duration = ent->s.pos.trDuration;
                VectorCopy( target->s.angles, angles );

                for ( i = 0; i < 3; i++ ) {
                    diff[i] = AngleDifference( angles[i], ent->s.angles[i] );
                    while ( diff[i] > 180 )
                        diff[i] -= 360;
                    while ( diff[i] < -180 )
                        diff[i] += 360;
                }
                VectorCopy( ent->s.angles, ent->s.apos.trBase );
                if ( duration ) {
                    VectorScale( diff, 1000.0 / (float)duration, ent->s.apos.trDelta );
                } else {
                    VectorClear( ent->s.apos.trDelta );
                }
                ent->s.apos.trDuration = duration;
                ent->s.apos.trTime = level.time;
                ent->s.apos.trType = TR_LINEAR_STOP;
                if ( trType != TR_LINEAR_STOP ) { // allow for acceleration/decceleration
                    ent->s.pos.trDuration = 1000.0 * dist / ( speed / 2.0 );
                    ent->s.pos.trType = trType;
                }
            }

        } else {
            // calculate the trajectory
            ent->s.pos.trType = TR_LINEAR_STOP;
            ent->s.pos.trTime = level.time;
            VectorCopy( ent->r.currentOrigin, ent->s.pos.trBase );
            dist = VectorNormalize( vec );
            VectorScale( vec, speed, ent->s.pos.trDelta );
            ent->s.pos.trDuration = 1000 * ( dist / speed );

            if ( turntotarget ) {
                duration = ent->s.pos.trDuration;
                VectorCopy( target->s.angles, angles );

                for ( i = 0; i < 3; i++ ) {
                    diff[i] = AngleDifference( angles[i], ent->s.angles[i] );
                    while ( diff[i] > 180 )
                        diff[i] -= 360;
                    while ( diff[i] < -180 )
                        diff[i] += 360;
                }
                VectorCopy( ent->s.angles, ent->s.apos.trBase );
                if ( duration ) {
                    VectorScale( diff, 1000.0 / (float)duration, ent->s.apos.trDelta );
                } else {
                    VectorClear( ent->s.apos.trDelta );
                }
                ent->s.apos.trDuration = duration;
                ent->s.apos.trTime = level.time;
                ent->s.apos.trType = TR_LINEAR_STOP;
            }

        }

        if ( !wait ) {
            // round the duration to the next 50ms
            if ( ent->s.pos.trDuration % 50 ) {
                float frac;

                frac = (float)( ( ( ent->s.pos.trDuration / 50 ) * 50 + 50 ) - ent->s.pos.trDuration ) / (float)( ent->s.pos.trDuration );
                if ( frac < 1 ) {
                    VectorScale( ent->s.pos.trDelta, 1.0 / ( 1.0 + frac ), ent->s.pos.trDelta );
                    ent->s.pos.trDuration = ( ent->s.pos.trDuration / 50 ) * 50 + 50;
                }
            }

            // set the goto flag, so we can keep processing the move until we reach the destination
            ent->scriptStatus.scriptFlags |= SCFL_GOING_TO_MARKER;
            return qtrue;   // continue to next command
        }

    }

    BG_EvaluateTrajectory( &ent->s.pos, level.time, ent->r.currentOrigin );
    BG_EvaluateTrajectory( &ent->s.apos, level.time, ent->r.currentAngles );
    script_linkentity( ent );

    return qfalse;
}