コード例 #1
0
ファイル: Aiscan.c プロジェクト: ForsakenW/forsaken
/*-------------------------------------------------------------------
    Procedure   :   AI for a Crawling Enemy while its SCANNING..
    Output      :   ENEMY   *   Enemy 
    Output      :   Nothing
-------------------------------------------------------------------*/
void AI_CRAWL_SCAN( register ENEMY * Enemy )
{

    if( Enemy->Object.Animating )
    {
        return;
    }
    
    if ( Enemy->Timer )
    {
        Enemy->Timer -= framelag;

      
        if ( Enemy->Timer < 0.0F )
        {
            //------------------------------------------------------------------------------
            // Switch to AIMODE_IDLE
            //------------------------------------------------------------------------------
            Enemy->Object.AI_Mode = AIMODE_IDLE;
            Enemy->Timer  = RESET_SCAN_TIME + (float) Random_Range( (uint16) RESET_SCAN_TIME );
            return;         
        }
    }         


}
コード例 #2
0
ファイル: botai_path.c プロジェクト: DUANISTON/forsaken
void BOTAI_GetNextNodeAlpha()
{
	// random choice to go left or right at the rocks
	if( CurrentNode == 11 && ReverseNetwork )
	{
		if(Random_Range(2) > 0)
			CurrentNode = 4;
		else
			CurrentNode--;
		return;
	}

	// random choice to go down or straight at the light room
	if( CurrentNode == 4 && !ReverseNetwork )
	{
		if(Random_Range(2) > 0)
			CurrentNode = 11;
		else
			CurrentNode++;
		return;
	}

	CurrentNode++;

	// following the main network in reverse
	if( ReverseNetwork )
		CurrentNode -= 2;

	// in the lower pit
	if( CurrentNode > ALPHA_NUM_NODES_MAIN )
		CurrentNode = ALPHA_TOP_OF_PIT_NODE;	

	// looping over the node network
	else if( CurrentNode > ALPHA_NUM_NODES_MAIN-1 )
	{
		ReverseNetwork = true;
		CurrentNode = ALPHA_NUM_NODES_MAIN-1;
	}
	else if( CurrentNode < 0 )
	{
		ReverseNetwork = false;
		CurrentNode = 0;
	}
}
コード例 #3
0
ファイル: aifire.c プロジェクト: DUANISTON/forsaken
/*===================================================================
	Procedure	:	TURRET Fire At Target..
	Input		:	ENEMY * Enemy
	Output		:	Nothing
===================================================================*/
void AI_TURRET_FIREATTARGET( register ENEMY * Enemy )
{
	OBJECT * TObject;

	TObject = (OBJECT*) Enemy->TShip;


	if( (Enemy->Type != ENEMY_MissileTurret) )
	{
		if( Enemy->Object.Animating && !(Enemy->Object.CurAnimSeq == TURRETSEQ_Fire) )
		{
			return;
		}
	}else{
		if( Enemy->Object.Animating && (Enemy->Object.CurAnimSeq == TURRETSEQ_Opening ) )
		{

		}else{

			if( !Enemy->Object.Animating )
			{
				SetCurAnimSeq( TURRETSEQ_Open, &Enemy->Object );
			}
		}
	}
	
	
	
	AI_THINK( Enemy , true , true );


	// Is it time to validate target ?
	if ( Enemy->Timer == 0.0F )
	{
		if( !( Enemy->AIFlags & AI_ANYPLAYERINRANGE ) || !AI_ClearLOS( &Enemy->Object.Pos ,Enemy->Object.Group , &TObject->Pos ) )
		{
			Enemy->AIFlags &= ~AI_ICANSEEPLAYER;
			SetCurAnimSeq( TURRETSEQ_Closing, &Enemy->Object );
			AI_SetSCAN( Enemy );
			return;
		}
		Enemy->Timer  =	RESET_VALIDATE_TIME + (float) Random_Range( (u_int16_t) RESET_VALIDATE_TIME );

	}else{
		Enemy->Timer -= framelag;
		if( Enemy->Timer < 0.0F )
			Enemy->Timer = 0.0F;
	}

	Enemy->AIFlags |= AI_ICANSEEPLAYER;
	AI_UPDATEGUNS( Enemy );
}
コード例 #4
0
ファイル: AIExogenon.c プロジェクト: ForsakenW/forsaken
/*-------------------------------------------------------------------
    Procedure   :   Exogenon Idle
    Input       :   ENEMY * Enemy
    Output      :   Nothing
-------------------------------------------------------------------*/
void AI_EXOGENON_IDLE( register ENEMY * Enemy )
{
    int i;
    int startpos = 0;
    float   Distance = 0.0F;
    AI_THINK( Enemy , TRUE , TRUE );

    if( Enemy->Object.CurAnimSeq != EXOGENONSEQ_Stop_Up )
    {
        SetCurAnimSeq( EXOGENONSEQ_Stop_Up, &Enemy->Object );
        return;
    }
    
    Enemy->Object.Pos = Exogenon_StartPos[0];
    Enemy->Object.Pos.y += 256.0F * 10.0F;
    if( !(Enemy->AIFlags & AI_ANYPLAYERINRANGE) )
        return;

    if( Enemy->Timer )
    {
        Enemy->Timer -= framelag;
        if( Enemy->Timer <= 0.0F )
        {
            Enemy->Timer = 0.0F;
        }
        return;
    }

    startpos = Random_Range( (uint16) Exogenon_Num_StartPos);
    i = Exogenon_Num_StartPos;

    while( Distance < (SHIP_RADIUS * 3.0F ) && i >= 0 )
    {
        Enemy->Object.Pos = Exogenon_StartPos[startpos];
        startpos++;
        if( startpos >= Exogenon_Num_StartPos )
            startpos = 0;
        Distance = DistanceVector2Vector( &Enemy->Object.Pos,&Ships[WhoIAm].Object.Pos );
        i--;
    }

    
    SetCurAnimSeq( EXOGENONSEQ_Move_Down, &Enemy->Object );
    Enemy->Object.AI_Mode = AIMODE_EXOGENON_MOVEDOWN;
}
コード例 #5
0
ファイル: Particle.c プロジェクト: Jjp137/ClassicalSharp
void Particles_RainSnowEffect(Vector3 pos) {
	Vector3 startPos = pos;
	Int32 i;
	for (i = 0; i < 2; i++) {
		Real32 velX = Random_Float(&rnd) * 0.8f - 0.4f; /* [-0.4, 0.4] */
		Real32 velZ = Random_Float(&rnd) * 0.8f - 0.4f;
		Real32 velY = Random_Float(&rnd) + 0.4f;
		Vector3 velocity = Vector3_Create3(velX, velY, velZ);

		Vector3 offset;
		offset.X = Random_Float(&rnd);  /* [0.0, 1.0] */
		offset.Y = Random_Float(&rnd) * 0.1f + 0.01f;
		offset.Z = Random_Float(&rnd);

		if (Rain_Count == PARTICLES_MAX) Rain_RemoveAt(0);
		RainParticle* p = &Rain_Particles[Rain_Count++];

		Vector3_Add(&pos, &startPos, &offset);
		Particle_Reset(&p->Base, pos, velocity, 40.0f);
		Int32 type = Random_Range(&rnd, 0, 30);
		p->Base.Size = (UInt8)(type >= 28 ? 2 : (type >= 25 ? 4 : 3));
	}
}
コード例 #6
0
ファイル: AIExogenon.c プロジェクト: ForsakenW/forsaken
/*-------------------------------------------------------------------
    Procedure   :   Exogenon Move Down
    Input       :   ENEMY * Enemy
    Output      :   Nothing
-------------------------------------------------------------------*/
void AI_EXOGENON_MOVEDOWN( register ENEMY * Enemy )
{
    VECTOR  TempUpVector;
    VECTOR  FireDir;

    BOOL    ClearLos = TRUE;
    VECTOR  TempOffset = { 0.0F, 0.0F, 180.0F };
    ExogenonAim( Enemy );

    Enemy->Object.AnimSpeed = 1.5F;
    if( Enemy->Object.Animating )
    {
        return;
    }

    if( !(ClearLos = AI_ClearLOSNonZeroNonObject( &Enemy->Object.Pos,Enemy->Object.Group, &Ships[WhoIAm].Object.Pos , SHIP_RADIUS))
        || (Random_Range(10) > 5 ) )
    {
        Enemy->Object.AI_Mode = AIMODE_EXOGENON_MOVEUP;
        SetCurAnimSeq( EXOGENONSEQ_Move_Up, &Enemy->Object );

        if( ClearLos )
        {
            ApplyMatrix( &Enemy->Object.Mat, &SlideUp, &TempUpVector );
            ApplyMatrix( &Enemy->Object.Mat, &Forward, &FireDir );
            // Fire a homing missile Forward...
            InitOneSecBull( OWNER_ENEMY, Enemy->Index, ++Enemy->BulletID, Enemy->Object.Group,
                &Enemy->Object.Pos, &TempOffset, &FireDir, &TempUpVector,
                &TempOffset, ENEMYBLUEHOMINGMISSILE, FALSE );
        }
        ExogenonFireLeftRight( Enemy );
    }else{
        Enemy->Object.AI_Mode = AIMODE_EXOGENON_SCAN;
        SetCurAnimSeq( EXOGENONSEQ_Idle, &Enemy->Object );
    }
}
コード例 #7
0
ファイル: teleport.c プロジェクト: DUANISTON/forsaken
/*===================================================================
	Procedure	:	Check if im in an Active Teleport....
	Input		:	void
	Output		:	true/false
===================================================================*/
bool TeleportsAreaCheck( VECTOR * NewPos , VECTOR * OldPos ,u_int16_t Group, OBJECT *obj )
{
	TELEPORT * TPpnt;
	TELEPORT * newTPpnt;

	TPpnt = TeleportsGroupLink[Group];
	
	while( TPpnt )
	{
		if( TPpnt->Status == TELEPORTACTIVE )
		{
			TeleportsZoneCheck( OldPos , NewPos , TPpnt );
			if( Entry )
			{

				PlaySfx( SFX_Teleport, 1.0F );

//				StartShipScreenShake( 10.0F );
				
				
				// Were in the Zone....
				newTPpnt = Teleports;
				newTPpnt += TPpnt->Links[Random_Range(TPpnt->num_links)];
				obj->Group = newTPpnt->Group;
				obj->Pos = newTPpnt->Pos;
#if TELEPORTS_VERSION_NUMBER >= 2
				QuatFromDirAndUp( &newTPpnt->Dir, &newTPpnt->Up, &obj->Quat);
				QuatToMatrix( &obj->Quat, &obj->Mat );
#endif
				return true;
			}
		}
		TPpnt = TPpnt->NextInGroup;
	}
	return false;
}
コード例 #8
0
ファイル: Triggers.c プロジェクト: ForsakenW/forsaken
/*-------------------------------------------------------------------
    Procedure   :       Update a trigger var..and then checks to see if 
                        all the triggers associated with any condition that this
                        trigger is used in is complete if it is Set the events off...
    Input       :       TRIGGERVAR * TrigVar
                        int Op
                        int Val
    Output      :       nothing
-------------------------------------------------------------------*/
void ModifyTriggerVar( TRIGGERVAR * TrigVar , int Op , int Val )
{
    BOOL    Doit;
    int     i;
    TRIGGER * Trig;
    int     old_state;
    uint32  flags;
    int     count;

    old_state = TrigVar->State;
    switch( Op )
    {
    case TRIGGEROP_Set:
        TrigVar->State = Val;
        break;
    case TRIGGEROP_Reset:
        TrigVar->State = TrigVar->InitState;
        break;
    case TRIGGEROP_Inc:
        TrigVar->State += Val;
        break;
    case TRIGGEROP_Dec:
        TrigVar->State -= Val;
        break;
    case TRIGGEROP_Or:
        TrigVar->State |= Val;
        break;
    case TRIGGEROP_And:
        TrigVar->State &= Val;
        break;
    case TRIGGEROP_Xor:
        TrigVar->State ^= Val;
        break;
    case TRIGGEROP_Multiply:
        TrigVar->State *= Val;
        break;
    case TRIGGEROP_Divide:
        TrigVar->State /= Val;
        break;
    case TRIGGEROP_Random:
        TrigVar->State = (int) Random_Range( (uint16) Val );
        break;
    case TRIGGEROP_Setflag:
        TrigVar->State |= FLAG_MASK( Val );
        break;
    case TRIGGEROP_Clearflag:
        TrigVar->State &= ~FLAG_MASK( Val );
        break;
    }

    if( TrigVar->State == old_state ) return;

#ifdef DEBUG_TRIGGERS
    DebugPrintf( "modifytrigvar: var=%s(=%d) op=%d val=%d -> %d\n",
        TrigVar->Name, old_state, Op, Val, TrigVar->State );
#endif

    for( i = 0 ; i < TrigVar->NumOfTriggers ; i++ )
    {
        Trig = TrigVar->Triggers[i];
        Doit = FALSE;

        switch( Trig->Type )
        {
        case TRIGGERTYPE_Equal:
            if( TrigVar->State == Trig->ActiveState )
                Doit = TRUE;
            break;
        case TRIGGERTYPE_NotEqual:
            if( TrigVar->State != Trig->ActiveState )
                Doit = TRUE;
            break;
        case TRIGGERTYPE_Less:
            if( TrigVar->State < Trig->ActiveState )
                Doit = TRUE;
            break;
        case TRIGGERTYPE_Greater:
            if( TrigVar->State > Trig->ActiveState )
                Doit = TRUE;
            break;
        case TRIGGERTYPE_LessEqual:
            if( TrigVar->State <= Trig->ActiveState )
                Doit = TRUE;
            break;
        case TRIGGERTYPE_GreaterEqual:
            if( TrigVar->State >= Trig->ActiveState )
                Doit = TRUE;
            break;
        case TRIGGERTYPE_FlagCount:
            count = 0;
            for ( flags = TrigVar->State; flags; flags >>= 1 )
            {
                if ( flags & 1 )
                    count++;
            }
            if ( count == Trig->ActiveState )
                Doit = TRUE;
            break;
        case TRIGGERTYPE_FlagTest:
            if ( TrigVar->State & FLAG_MASK( Trig->ActiveState ) )
                Doit = TRUE;
            break;
        }

        if ( Doit )
        {
#ifdef DEBUG_TRIGGERS
            DebugPrintf( "modifytrigvar: trigger %d (type=%d, activestate=%d) activated (was %d)\n",
                Trig - Triggers, (int) Trig->Type, Trig->ActiveState, Trig->Active );
#endif
            if( !(_strnicmp( "secret" , &TrigVar->Name[0], 6 ) ) )
            {
                PlaySfx( SFX_Secret, 1.0F );
            }
        }

        Trig->Active = Doit;

        if( Trig->Active )
        {
            TestAllConditions( Trig );
        }
    }
}
コード例 #9
0
ファイル: aiformation.c プロジェクト: DUANISTON/forsaken
/*===================================================================
	Procedure	:	AIR Formation Flying
	Input		:	ENEMY * Enemy
	Output		:	Nothing
===================================================================*/
void AI_AIR_FORMATION( register ENEMY * Enemy )
{
	float	Dist;
	OBJECT * TObject;
	OBJECT * SObject;
	VECTOR		NewPos;
	VECTOR		TempVector;
	VECTOR		TempUpVector;
	VECTOR		TempOffset = { 0.0F, 0.0F, 0.0F };
	VECTOR		Offset;
	VECTOR		TargetPos;
	VECTOR		TempDir;
	ENEMY * LinkEnemy;

	SObject = &Enemy->Object;
	// Is it time to think???
	AI_THINK( Enemy , false ,false);

	LinkEnemy = Enemy->FormationLink;

	if( !LinkEnemy || ( LinkEnemy->Object.AI_Mode == AIMODE_RETREAT ) )
	{
		if( Enemy->AIFlags & ( AI_ICANSEEPLAYER + AI_ICANHEARPLAYER ) )
		{
			AI_SetDOGFIGHT( Enemy );
			return;
		}else{
			AI_SetFOLLOWPATH( Enemy );
			return;
		}
	}

	TObject = (OBJECT*) Enemy->TShip;

	
	Enemy->Timer -= framelag;
	if( Enemy->Timer < 0.0F )
		Enemy->Timer = 0.0F;

	Enemy->PrimaryFireTimer -= framelag;
	if( Enemy->PrimaryFireTimer < 0.0F )
		Enemy->PrimaryFireTimer = 0.0F;
	Enemy->SecondaryFireTimer -= framelag;
	if( Enemy->SecondaryFireTimer < 0.0F )
		Enemy->SecondaryFireTimer = 0.0F;

	if( Enemy->AIFlags & ( AI_ICANSEEPLAYER + AI_ICANHEARPLAYER ) )
	{
		Enemy->TNode = NULL;
		if( !(Enemy->Object.Flags & SHIP_Scattered ) && (Enemy->AIFlags & AI_ICANSEEPLAYER) && !(Enemy->AIFlags & AI_FRIENDLYFIRE) )
		{
			ApplyMatrix( &SObject->Mat, &Forward, &TempVector );
			ApplyMatrix( &SObject->Mat, &SlideUp, &TempUpVector );

			if( (Enemy->PrimaryFireTimer == 0.0F) && ( EnemyTypes[Enemy->Type].PrimaryWeaponType != NO_PRIMARY )  )
			{
				Enemy->PrimaryFireTimer = EnemyTypes[Enemy->Type].PrimaryFireRate + (float) Random_Range( (u_int16_t) EnemyTypes[Enemy->Type].PrimaryFireRate );
				EnemyFirePrimary( OWNER_ENEMY, Enemy->Index, ++Enemy->BulletID, EnemyTypes[Enemy->Type].PrimaryWeaponType,
					Enemy->Object.Group, &Enemy->Object.Pos, &TempOffset, &TempVector, &TempUpVector,
					EnemyTypes[Enemy->Type].PowerLevel, 0.0F, false, NULL );
			}
		}
	}

	if( (Enemy->Object.Flags & SHIP_Scattered ) || ( (EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_RETREAT) && ( Enemy->Object.Shield <= (EnemyTypes[Enemy->Type].Shield * 0.15 ) ) ) )
	{
		// we should get out of hear..
		Enemy->FormationLink = NULL;
		AI_SetRETREAT( Enemy );
		return;
	}
	
	AI_UPDATEGUNS( Enemy );
	// Aim at target

	if( TObject && ( Enemy->AIFlags & AI_ICANSEEPLAYER ) )
	{
		if( EnemyTypes[Enemy->Type].PrimaryWeaponType != NO_PRIMARY )
		{
			AI_LookAhead( EnemyTypes[Enemy->Type].Behave.Anticipate_Move , &Enemy->Object.Pos , TObject , &NewPos ,   PrimaryWeaponAttribs[EnemyTypes[Enemy->Type].PrimaryWeaponType].Speed[0] );
		}else{
			NewPos = TObject->Pos;
		}
		AI_AimAtTarget( &Enemy->Object.InvMat , &Enemy->Object.Pos, &NewPos );
		
		if( !( EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_ICANTPITCH ) )
		{
			Enemy->AIMoveFlags |= AimData.Flags;
		}else{
			//This enemy cant look up or down so it has to move up and down to compensate....
			Enemy->AIMoveFlags |= ( AimData.Flags & ( AI_CONTROL_TURNLEFT + AI_CONTROL_TURNRIGHT ) );
			if( AimData.Flags & AI_CONTROL_TURNUP )
			{
				Enemy->AIMoveFlags |=  AI_CONTROL_UP;
			}else if( AimData.Flags & AI_CONTROL_TURNDOWN )
			{
				Enemy->AIMoveFlags |=  AI_CONTROL_DOWN;
			}
			
		}
		
		Enemy->AI_Angle = AimData.Angle;
	}else{
		ApplyMatrix( &LinkEnemy->Object.Mat, &Forward, &TempDir );
		TempDir.x *= 1024.0F * GLOBAL_SCALE * 5.0F;
		TempDir.y *= 1024.0F * GLOBAL_SCALE * 5.0F;
		TempDir.z *= 1024.0F * GLOBAL_SCALE * 5.0F;
		NewPos.x = LinkEnemy->Object.Pos.x + TempDir.x;
		NewPos.y = LinkEnemy->Object.Pos.y + TempDir.y;
		NewPos.z = LinkEnemy->Object.Pos.z + TempDir.z;

		AI_AimAtTarget( &Enemy->Object.InvMat , &Enemy->Object.Pos, &NewPos );
		if( !( EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_ICANTPITCH ) )
		{
			Enemy->AIMoveFlags |= AimData.Flags;
		}else{
			//This enemy cant look up or down so it has to move up and down to compensate....
			Enemy->AIMoveFlags |= ( AimData.Flags & ( AI_CONTROL_TURNLEFT + AI_CONTROL_TURNRIGHT ) );
			if( AimData.Flags & AI_CONTROL_TURNUP )
			{
				Enemy->AIMoveFlags |=  AI_CONTROL_UP;
			}else if( AimData.Flags & AI_CONTROL_TURNDOWN )
			{
				Enemy->AIMoveFlags |=  AI_CONTROL_DOWN;
			}
			
		}
		
		Enemy->AI_Angle = AimData.Angle;
	}

	if( Enemy->AvoidTimer )
	{
		Enemy->AIMoveFlags = Enemy->AvoidType;
	}else{

		Offset = Enemy->FormationOffset;
		ApplyMatrix( &LinkEnemy->Object.Mat, &Offset, &TargetPos );
		TargetPos.x += LinkEnemy->Object.Pos.x;
		TargetPos.y += LinkEnemy->Object.Pos.y;
		TargetPos.z += LinkEnemy->Object.Pos.z;

		Dist = DistanceVector2Vector( &TargetPos , &Enemy->Object.Pos);

		if( Dist > (EnemyTypes[Enemy->Type].Radius * 0.75F) )
		{
			Offset.x = TargetPos.x - Enemy->Object.Pos.x;
			Offset.y = TargetPos.y - Enemy->Object.Pos.y;
			Offset.z = TargetPos.z - Enemy->Object.Pos.z;

			ApplyMatrix( &Enemy->Object.InvMat, &Offset, &TargetPos );

			if( TargetPos.x < -(EnemyTypes[Enemy->Type].Radius * 0.25F) )
			{
				Enemy->AIMoveFlags |= AI_CONTROL_LEFT;
			}
			if( TargetPos.x > (EnemyTypes[Enemy->Type].Radius * 0.25F) )
			{
				Enemy->AIMoveFlags |= AI_CONTROL_RIGHT;
			}
			if( TargetPos.y < -(EnemyTypes[Enemy->Type].Radius * 0.25F) )
			{
				Enemy->AIMoveFlags |= AI_CONTROL_DOWN;
			}
			if( TargetPos.y > (EnemyTypes[Enemy->Type].Radius * 0.25F) )
			{
				Enemy->AIMoveFlags |= AI_CONTROL_UP;
			}
			if( TargetPos.z < -(EnemyTypes[Enemy->Type].Radius * 0.25F) )
			{
				Enemy->AIMoveFlags |= AI_CONTROL_BACK;
			}
			if( TargetPos.z > (EnemyTypes[Enemy->Type].Radius * 0.25F) )
			{
				Enemy->AIMoveFlags |= AI_CONTROL_FORWARD;
			}

		}
	}
}
コード例 #10
0
ファイル: botai_sensors.c プロジェクト: DUANISTON/forsaken
void BOTAI_UpdateSensors()
{
	int CurrentDeaths = GetTotalDeaths(WhoIAm);
	int CurrentKills = GetTotalKills(WhoIAm);
	int i;

	// i died or killed someone
	if( CurrentDeaths > PrevDeaths || CurrentKills > PrevKills )
	{
		// mix up the route
		if(Random_Range(2) > 0)
			ReverseNetwork = true;
		else
			ReverseNetwork = false;

		// i died, reset flags 
		if( CurrentDeaths > PrevDeaths )
		{
			//DebugPrintf("i died\n");
			CurrentNode = -1;
			GettingPickup = -1;
			IFiredTitan = -1.0F;
			TargetMine = -1;
			HomingMissile = -1;
			PrevHomingMissile = -1;
			MissileAvoidanceSet = false;
			PrevHull = MAX_HULL+1.0F;
			PrevShield = MAX_SHIELD+1.0F;
		}

		PrevDeaths = CurrentDeaths;
		PrevKills = CurrentKills;
	}

	// i got hit
	if( Ships[WhoIAm].Object.Hull < PrevHull || Ships[WhoIAm].Object.Shield < PrevShield )
	{
		PrevHull = Ships[WhoIAm].Object.Hull;
		PrevShield = Ships[WhoIAm].Object.Shield;

		// debugging stuff
		if(!initialised)
			initialised = true;
		else
			DEBUG_AVOIDANCE = false;
	}

	// -- update sensors
	// up, down, left, right, forward, backward
	DistWall[0] = BOTAI_DistanceToWall(false,false,false,true,false,false); // right
	DistWall[1] = BOTAI_DistanceToWall(false,false,true,false,false,false); // left
	DistWall[2] = BOTAI_DistanceToWall(true,false,false,false,false,false); // up 
	DistWall[3] = BOTAI_DistanceToWall(false,true,false,false,false,false); // down
	DistWall[4] = BOTAI_DistanceToWall(true,false,false,true,false,false); // up right
	DistWall[5] = BOTAI_DistanceToWall(true,false,true,false,false,false); // up left
	DistWall[6] = BOTAI_DistanceToWall(false,true,false,true,false,false); // down right
	DistWall[7] = BOTAI_DistanceToWall(false,true,true,false,false,false); // down left
	DistWall[8] = BOTAI_DistanceToWall(false,false,false,false,true,false); // forward
	DistWall[9] = BOTAI_DistanceToWall(false,false,false,false,false,true); // backward
	DistWall[10] = BOTAI_DistanceToWall(false,false,false,true,false,true); // right backward
	DistWall[11] = BOTAI_DistanceToWall(false,false,true,false,false,true); // left backward
	DistWall[12] = BOTAI_DistanceToWall(true,false,false,false,false,true); // up backward
	DistWall[13] = BOTAI_DistanceToWall(false,true,false,false,false,true); // down backward
	DistWall[14] = BOTAI_DistanceToWall(true,false,false,true,false,true); // up right backward
	DistWall[15] = BOTAI_DistanceToWall(true,false,true,false,false,true); // up left backward
	DistWall[16] = BOTAI_DistanceToWall(false,true,false,true,false,true); // down right backward
	DistWall[17] = BOTAI_DistanceToWall(false,true,true,false,false,true); // down left backward
	DistWall[18] = BOTAI_DistanceToWall(false,false,false,true,true,false); // right forward
	DistWall[19] = BOTAI_DistanceToWall(false,false,true,false,true,false); // left forward
	DistWall[20] = BOTAI_DistanceToWall(true,false,false,false,true,false); // up forward
	DistWall[21] = BOTAI_DistanceToWall(false,true,false,false,true,false); // down forward
	DistWall[22] = BOTAI_DistanceToWall(true,false,false,true,true,false); // up right forward
	DistWall[23] = BOTAI_DistanceToWall(true,false,true,false,true,false); // up left forward
	DistWall[24] = BOTAI_DistanceToWall(false,true,false,true,true,false); // down right forward
	DistWall[25] = BOTAI_DistanceToWall(false,true,true,false,true,false); // down left forward

	AllSensorsClear = true;
	WhenWillHitSlide[0] = BOTAI_WhenWillBulletHitSlide(false,false,false,true,false,false); // r
	WhenWillHitSlide[1] = BOTAI_WhenWillBulletHitSlide(false,false,true,false,false,false); // l
	WhenWillHitSlide[2] = BOTAI_WhenWillBulletHitSlide(true,false,false,false,false,false); // u
	WhenWillHitSlide[3] = BOTAI_WhenWillBulletHitSlide(false,true,false,false,false,false); // d
	WhenWillHitSlide[4] = BOTAI_WhenWillBulletHitSlide(true,false,false,true,false,false); // u r
	WhenWillHitSlide[5] = BOTAI_WhenWillBulletHitSlide(true,false,true,false,false,false); // u l
	WhenWillHitSlide[6] = BOTAI_WhenWillBulletHitSlide(false,true,false,true,false,false); // d r
	WhenWillHitSlide[7] = BOTAI_WhenWillBulletHitSlide(false,true,true,false,false,false); // d l
	WhenWillHitSlide[8] = BOTAI_WhenWillBulletHitSlide(false,false,false,false,true,false); // f
	WhenWillHitSlide[9] = BOTAI_WhenWillBulletHitSlide(false,false,false,false,false,true); // b
	WhenWillHitSlide[10] = BOTAI_WhenWillBulletHitSlide(false,false,false,true,false,true); // r b
	WhenWillHitSlide[11] = BOTAI_WhenWillBulletHitSlide(false,false,true,false,false,true); // l b
	WhenWillHitSlide[12] = BOTAI_WhenWillBulletHitSlide(true,false,false,false,false,true); // u b
	WhenWillHitSlide[13] = BOTAI_WhenWillBulletHitSlide(false,true,false,false,false,true); // d b
	WhenWillHitSlide[14] = BOTAI_WhenWillBulletHitSlide(true,false,false,true,false,true); // u r b
	WhenWillHitSlide[15] = BOTAI_WhenWillBulletHitSlide(true,false,true,false,false,true); // u l b
	WhenWillHitSlide[16] = BOTAI_WhenWillBulletHitSlide(false,true,false,true,false,true); // d r b
	WhenWillHitSlide[17] = BOTAI_WhenWillBulletHitSlide(false,true,true,false,false,true); // d l b
	WhenWillHitSlide[18] = BOTAI_WhenWillBulletHitSlide(false,false,false,true,true,false); // r f
	WhenWillHitSlide[19] = BOTAI_WhenWillBulletHitSlide(false,false,true,false,true,false); // l f
	WhenWillHitSlide[20] = BOTAI_WhenWillBulletHitSlide(true,false,false,false,true,false); // u f
	WhenWillHitSlide[21] = BOTAI_WhenWillBulletHitSlide(false,true,false,false,true,false); // d f
	WhenWillHitSlide[22] = BOTAI_WhenWillBulletHitSlide(true,false,false,true,true,false); // u r f
	WhenWillHitSlide[23] = BOTAI_WhenWillBulletHitSlide(true,false,true,false,true,false); // u l f
	WhenWillHitSlide[24] = BOTAI_WhenWillBulletHitSlide(false,true,false,true,true,false); // d r f
	WhenWillHitSlide[25] = BOTAI_WhenWillBulletHitSlide(false,true,true,false,true,false); // d l f

	// time since i last fired titan
	// used so i don't move into the blast
	IFiredTitan -= framelag;

	BOTAI_GetNearestPickup();
	FriendlyFire = BOTAI_FriendlyFireCheck();
	BOTAI_GetSHIPTarget();

	//DebugPrintf("r: %.1f l: %.1f u: %.1f d: %.1f f: %.1f b: %.1f\n", DistWall[0], DistWall[1], DistWall[2], DistWall[3], DistWall[8], DistWall[9]);
	//DebugPrintf("ur: %.1f ul: %.1f dr: %.1f dl: %.1f\n", DistWall[22], DistWall[23], DistWall[24], DistWall[25]);
	//DebugPrintf("%f %f %f\n", Ships[WhoIAm].Object.Pos.x, Ships[WhoIAm].Object.Pos.y, Ships[WhoIAm].Object.Pos.z); 
	//DebugPrintf("Level: %s\n", ShortLevelNames[LevelNum]);
	//DebugPrintf("nearest node = %d\n", BOTAI_GetNearestNode(&Ships[WhoIAm].Object));

	// if there is a target
	if(TargetShipID > - 1)
	{
		// distance to target
		TargetShipDistance = DistanceVector2Vector(&Ships[WhoIAm].Object.Pos, &Ships[TargetShipID].Object.Pos);

		// health of target
		TargetShipHealth = PlayerHealths[TargetShipID].Shield + PlayerHealths[TargetShipID].Hull;
	}
}
コード例 #11
0
ファイル: aispline.c プロジェクト: DUANISTON/forsaken
/*===================================================================
	Procedure	:	AI Spline Movement....
	Input		:	ENEMY * Enemy
	Output		:	Nothing
===================================================================*/
void AI_SPLINE_FOLLOWPATH( register ENEMY * Enemy )
{
	NODE * TNode;
	NODE * Node1;
	NODE * Node2;
	NODE * Node3;
	NODE * Node4;
	VECTOR	OldPos;
	VECTOR	MoveOffset;
	float	Distance;
	float	WantedDistance;
	float	Time;
	float	Tstep;
	VECTOR	TempPos;
	int Count;

	OldPos = Enemy->Object.Pos;

	if( !Enemy->SplineNode1 )
	{
		//We have to start
		TNode = Enemy->Object.NearestNode;

		Enemy->SplineNode1 = (void*) TNode;
		Enemy->SplineNode2 = (void*) TNode;
		Node1 = (NODE*)Enemy->SplineNode1;
		Node2 = (NODE*)Enemy->SplineNode2;
		Enemy->SplineNode3 = (void*) FindSuitableSplineNode( Enemy->Object.NodeNetwork ,Node2 , Node1 , Node2 , NULL , NULL );
		Node3 = (NODE*)Enemy->SplineNode3;
		Enemy->SplineNode4 = (void*) FindSuitableSplineNode( Enemy->Object.NodeNetwork ,Node3 , Node1 , Node2 , Node3 , NULL );

	}
	Node1 = (NODE*)Enemy->SplineNode1;
	Node2 = (NODE*)Enemy->SplineNode2;
	Node3 = (NODE*)Enemy->SplineNode3;
	Node4 = (NODE*)Enemy->SplineNode4;


	WantedDistance = (EnemyTypes[Enemy->Type].MaxMoveRate*0.65F) * framelag;

	Tstep = ( WantedDistance / DistanceVector2Vector( &Node2->Pos , &Node3->Pos ) ) * 0.1F;

	Distance = DistanceVector2Vector( &Node2->Pos , &Node3->Pos );
	Time = (Distance / (EnemyTypes[Enemy->Type].MaxMoveRate * 0.65F) );
	
	Distance = 0.0F;
	Count = 0;
	do
	{
		Enemy->Timer += Tstep;

		if( Enemy->Timer >= 1.0F )
		{
			Enemy->SplineNode1 = Enemy->SplineNode2;
			Enemy->SplineNode2 = Enemy->SplineNode3;
			Enemy->SplineNode3 = Enemy->SplineNode4;
			Node1 = (NODE*)Enemy->SplineNode1;
			Node2 = (NODE*)Enemy->SplineNode2;
			Node3 = (NODE*)Enemy->SplineNode3;
			
			Enemy->Timer = ((Enemy->Timer - 1.0F) * Time);
			Distance = DistanceVector2Vector( &Node2->Pos , &Node3->Pos );
			Time = (Distance / (EnemyTypes[Enemy->Type].MaxMoveRate*0.65F) );
			Enemy->Timer /= Time;
			
			Enemy->SplineNode4 = (void*) FindSuitableSplineNodeRandom( Enemy->Object.NodeNetwork ,Node3 , Node1 , Node2 , Node3 , NULL );
			Node4 = (NODE*)Enemy->SplineNode4;
			Tstep = ( WantedDistance / DistanceVector2Vector( &Node2->Pos , &Node3->Pos ) ) * 0.1F;

			if( Node3 && (Node3->Flags&NODE_TERMINATE) )
			{
				KillUsedEnemy( Enemy );
				return;
			}
		}
	
		
		TempPos = Enemy->Object.Pos;

		spline(&Enemy->Object.Pos, Enemy->Timer, &Node1->Pos, &Node2->Pos, &Node3->Pos, &Node4->Pos);

		Distance += DistanceVector2Vector( &Enemy->Object.Pos , &TempPos);
		Count++;

	}while( ( Distance < WantedDistance ) && (Count < 100) );
	

	AI_THINK( Enemy , true , true);

	if( (Enemy->AIFlags & AI_ANYPLAYERINRANGE) )
	{
		Enemy->PrimaryFireTimer -= framelag;
		if( Enemy->PrimaryFireTimer < 0.0F )
			Enemy->PrimaryFireTimer = 0.0F;
		
		if(Enemy->PrimaryFireTimer == 0.0F)
		{
			if( !Enemy->TShip )
			{
				AI_DO_SCAN( Enemy );
			}
			Enemy->PrimaryFireTimer  =	RESET_VALIDATE_TIME + (float) Random_Range( (u_int16_t) RESET_VALIDATE_TIME );
		}
	}
	AI_UPDATEGUNS( Enemy );

	MoveOffset.x = Enemy->Object.Pos.x - OldPos.x;
	MoveOffset.y = Enemy->Object.Pos.y - OldPos.y;
	MoveOffset.z = Enemy->Object.Pos.z - OldPos.z;

	Enemy->Object.Group = MoveGroup( &Mloadheader, &OldPos, Enemy->Object.Group, &MoveOffset );


}
コード例 #12
0
ファイル: Builder.c プロジェクト: Jjp137/ClassicalSharp
static void Builder_DrawSprite(Int32 count) {
	TextureLoc texLoc = Block_GetTexLoc(Builder_Block, FACE_XMAX);
	Int32 i = Atlas1D_Index(texLoc);
	Real32 vOrigin = Atlas1D_RowId(texLoc) * Atlas1D_InvTileSize;
	Real32 X = (Real32)Builder_X, Y = (Real32)Builder_Y, Z = (Real32)Builder_Z;

#define u1 0.0f
#define u2 UV2_Scale
	Real32 x1 = (Real32)X + 2.50f / 16.0f, y1 = (Real32)Y,        z1 = (Real32)Z + 2.50f / 16.0f;
	Real32 x2 = (Real32)X + 13.5f / 16.0f, y2 = (Real32)Y + 1.0f, z2 = (Real32)Z + 13.5f / 16.0f;
	Real32 v1 = vOrigin, v2 = vOrigin + Atlas1D_InvTileSize * UV2_Scale;

	UInt8 offsetType = Block_SpriteOffset[Builder_Block];
	if (offsetType >= 6 && offsetType <= 7) {
		Random_SetSeed(&spriteRng, (Builder_X + 1217 * Builder_Z) & 0x7fffffff);
		Real32 valX = Random_Range(&spriteRng, -3, 3 + 1) / 16.0f;
		Real32 valY = Random_Range(&spriteRng, 0,  3 + 1) / 16.0f;
		Real32 valZ = Random_Range(&spriteRng, -3, 3 + 1) / 16.0f;

#define stretch 1.7f / 16.0f
		x1 += valX - stretch; x2 += valX + stretch;
		z1 += valZ - stretch; z2 += valZ + stretch;
		if (offsetType == 7) { y1 -= valY; y2 -= valY; }
	}
	
	Builder1DPart* part = &Builder_Parts[i];
	PackedCol white = PACKEDCOL_WHITE;
	PackedCol col = Builder_FullBright ? white : Lighting_Col_Sprite_Fast(Builder_X, Builder_Y, Builder_Z);
	Block_Tint(col, Builder_Block);
	VertexP3fT2fC4b v; v.Col = col;

	/* Draw Z axis */
	Int32 index = part->sOffset;
	v.X = x1; v.Y = y1; v.Z = z1; v.U = u2; v.V = v2; Builder_Vertices[index + 0] = v;
	          v.Y = y2;                     v.V = v1; Builder_Vertices[index + 1] = v;
	v.X = x2;           v.Z = z2; v.U = u1;           Builder_Vertices[index + 2] = v;
	          v.Y = y1;                     v.V = v2; Builder_Vertices[index + 3] = v;

	/* Draw Z axis mirrored */
	index += part->sAdvance;
	v.X = x2; v.Y = y1; v.Z = z2; v.U = u2;           Builder_Vertices[index + 0] = v;
	          v.Y = y2;                     v.V = v1; Builder_Vertices[index + 1] = v;
	v.X = x1;           v.Z = z1; v.U = u1;           Builder_Vertices[index + 2] = v;
	          v.Y = y1;                     v.V = v2; Builder_Vertices[index + 3] = v;

	/* Draw X axis */
	index += part->sAdvance;
	v.X = x1; v.Y = y1; v.Z = z2; v.U = u2;           Builder_Vertices[index + 0] = v;
	          v.Y = y2;                     v.V = v1; Builder_Vertices[index + 1] = v;
	v.X = x2;           v.Z = z1; v.U = u1;           Builder_Vertices[index + 2] = v;
	          v.Y = y1;                     v.V = v2; Builder_Vertices[index + 3] = v;

	/* Draw X axis mirrored */
	index += part->sAdvance;
	v.X = x2; v.Y = y1; v.Z = z1; v.U = u2;           Builder_Vertices[index + 0] = v;
	          v.Y = y2;                     v.V = v1; Builder_Vertices[index + 1] = v;
	v.X = x1;           v.Z = z2; v.U = u1;           Builder_Vertices[index + 2] = v;
	          v.Y = y1;                     v.V = v2; Builder_Vertices[index + 3] = v;

	part->sOffset += 4;
}
コード例 #13
0
ファイル: Particle.c プロジェクト: Jjp137/ClassicalSharp
void Particles_BreakBlockEffect(Vector3I coords, BlockID oldBlock, BlockID block) {
	if (block != BLOCK_AIR || Block_Draw[oldBlock] == DRAW_GAS) return;
	block = oldBlock;

	Vector3 worldPos;
	Vector3I_ToVector3(&worldPos, &coords);
	TextureLoc texLoc = Block_GetTexLoc(block, FACE_XMIN);
	Int32 texIndex;
	TextureRec baseRec = Atlas1D_TexRec(texLoc, 1, &texIndex);
	Real32 uScale = (1.0f / 16.0f), vScale = (1.0f / 16.0f) * Atlas1D_InvTileSize;

	Vector3 minBB = Block_MinBB[block];
	Vector3 maxBB = Block_MaxBB[block];
	Int32 minX = (Int32)(minBB.X * 16), minZ = (Int32)(minBB.Z * 16);
	Int32 maxX = (Int32)(maxBB.X * 16), maxZ = (Int32)(maxBB.Z * 16);

	Int32 minU = min(minX, minZ), maxU = min(maxX, maxZ);
	Int32 minV = (Int32)(16 - maxBB.Y * 16), maxV = (Int32)(16 - minBB.Y * 16);
	Int32 maxUsedU = maxU, maxUsedV = maxV;
	/* This way we can avoid creating particles which outside the bounds and need to be clamped */
	if (minU < 12 && maxU > 12) maxUsedU = 12;
	if (minV < 12 && maxV > 12) maxUsedV = 12;

	#define GRID_SIZE 4
	/* gridOffset gives the centre of the cell on a grid */
	#define CELL_CENTRE ((1.0f / GRID_SIZE) * 0.5f)

	Int32 x, y, z;
	Real32 maxU2 = baseRec.U1 + maxU * uScale;
	Real32 maxV2 = baseRec.V1 + maxV * vScale;
	for (x = 0; x < GRID_SIZE; x++) {
		for (y = 0; y < GRID_SIZE; y++) {
			for (z = 0; z < GRID_SIZE; z++) {
				Real32 cellX = (Real32)x / GRID_SIZE, cellY = (Real32)y / GRID_SIZE, cellZ = (Real32)z / GRID_SIZE;
				Vector3 cell = Vector3_Create3(CELL_CENTRE + cellX, CELL_CENTRE / 2 + cellY, CELL_CENTRE + cellZ);
				if (cell.X < minBB.X || cell.X > maxBB.X || cell.Y < minBB.Y
					|| cell.Y > maxBB.Y || cell.Z < minBB.Z || cell.Z > maxBB.Z) continue;

				Vector3 velocity; /* centre random offset around [-0.2, 0.2] */
				velocity.X = CELL_CENTRE + (cellX - 0.5f) + (Random_Float(&rnd) * 0.4f - 0.2f);
				velocity.Y = CELL_CENTRE + (cellY - 0.0f) + (Random_Float(&rnd) * 0.4f - 0.2f);
				velocity.Z = CELL_CENTRE + (cellZ - 0.5f) + (Random_Float(&rnd) * 0.4f - 0.2f);

				TextureRec rec = baseRec;
				rec.U1 = baseRec.U1 + Random_Range(&rnd, minU, maxUsedU) * uScale;
				rec.V1 = baseRec.V1 + Random_Range(&rnd, minV, maxUsedV) * vScale;
				rec.U2 = rec.U1 + 4 * uScale;
				rec.V2 = rec.V1 + 4 * vScale;
				rec.U2 = min(rec.U2, maxU2) - 0.01f * uScale;
				rec.V2 = min(rec.V2, maxV2) - 0.01f * vScale;

				if (Terrain_Count == PARTICLES_MAX) Terrain_RemoveAt(0);
				TerrainParticle* p = &Terrain_Particles[Terrain_Count++];
				Real32 life = 0.3f + Random_Float(&rnd) * 1.2f;

				Vector3 pos;
				Vector3_Add(&pos, &worldPos, &cell);
				Particle_Reset(&p->Base, pos, velocity, life);
				p->Rec = rec;
				p->TexLoc = (TextureLoc)texLoc;
				p->Block = block;
				Int32 type = Random_Range(&rnd, 0, 30);
				p->Base.Size = (UInt8)(type >= 28 ? 12 : (type >= 25 ? 10 : 8));
			}
		}
	}
}
コード例 #14
0
ファイル: botai_path.c プロジェクト: DUANISTON/forsaken
void BOTAI_GetNextNodeFourball()
{
	int random;
	if( !ReverseNetwork )
	{
		switch( CurrentNode )
		{
			case 0: CurrentNode = 1; break;
			case 1: CurrentNode = 5; break;
			case 2: CurrentNode = 1; break;
			case 3: CurrentNode = 2; break;
			case 4: CurrentNode = 0; break;
			case 5: CurrentNode = 10; break;
			case 6: CurrentNode = 2; break;
			case 7: CurrentNode = 3; break;
			case 8: CurrentNode = 4; break;
			case 9: CurrentNode = 8; break;
			case 10: CurrentNode = 11; break;
			case 11: CurrentNode = 12; break;
			case 12:
					 random = Random_Range(3);
					 if(random == 0) CurrentNode = 20;
					 else if(random == 1) CurrentNode = 13;
					 else CurrentNode = 16;
					 break;
			case 13: CurrentNode = 14; break;
			case 14: CurrentNode = 15; break;
			case 15: CurrentNode = 6; break;
			case 16: CurrentNode = 17; break;
			case 17: CurrentNode = 18; break;
			case 18: CurrentNode = 9; break;
			case 19: CurrentNode = 18; break;
			case 20: CurrentNode = 19; break;
		}
	}
	else
	{
		switch( CurrentNode )
		{
			case 0: CurrentNode = 4; break;
			case 1: CurrentNode = 0; break;
			case 2: CurrentNode = 1; break;
			case 3: CurrentNode = 2; break;
			case 4: CurrentNode = 8; break;
			case 5: CurrentNode = 1; break;
			case 6: CurrentNode = 2; break;
			case 7: CurrentNode = 15; break;
			case 8:
					random = Random_Range(2);
					if(random == 0) CurrentNode = 9;
					else CurrentNode = 7;
					break;
			case 9: CurrentNode = 18; break;
			case 10: CurrentNode = 5; break;
			case 11: CurrentNode = 10; break;
			case 12: CurrentNode = 11; break;
			case 13: CurrentNode = 12; break;
			case 14: CurrentNode = 13; break;
			case 15: CurrentNode = 14; break;
			case 16: CurrentNode = 12; break;
			case 17: CurrentNode = 16; break;
			case 18: 
					 random = Random_Range(2);
					 if(random == 0) CurrentNode = 19;
					 else CurrentNode = 17;
					 break;
			case 19: CurrentNode = 20; break;
			case 20: CurrentNode = 12; break;
		}
	}
}
コード例 #15
0
ファイル: aifollow.c プロジェクト: DUANISTON/forsaken
/*===================================================================
	Procedure	:	AIR Follow Path
	Input		:	ENEMY * Enemy
	Output		:	Nothing
===================================================================*/
void AI_AIR_FOLLOWPATH( register ENEMY * Enemy )
{
	OBJECT * SObject;
	NODE * TNode;
	VECTOR	TempVector = { 0.0F , 0.0F , 0.0F };
	VECTOR	TempUpVector;
	VECTOR	TempForwardVector;
	u_int16_t	MineIndex;

	SObject = &Enemy->Object;

	AI_THINK( Enemy , false , false );

	if( !(Enemy->AIFlags & AI_ANYPLAYERINRANGE) )
		return;

	if( EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_ATTACK_ONSITE )
	{
		Tinfo->Flags = 0;
		SET_TARGET_PLAYERS;
		AI_GetDistToNearestTarget( Enemy );
		Enemy->TShip = Tinfo->TObject;
	}

	if( Enemy->TShip && ( EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_ATTACK_ONSITE ) )
	{
		if( Enemy->AIFlags&AI_ICANSEEPLAYER )
		{
			AI_SetDOGFIGHT( Enemy );
			return;
		}else if( Enemy->AIFlags&AI_ICANHEARPLAYER )
		{
			AI_SetMOVETOTARGET( Enemy );
			return;
		}
	}


	if( (Enemy->AIFlags&AI_MINEAVOID) && (EnemyTypes[Enemy->Type].Behave.Flags&AI_BEHAVIOUR_ATTACKMINES) )
	{
		Enemy->AvoidTimer = 0.0F;
		Enemy->AvoidType = 0;
		AI_SetKILLMINE( Enemy );
		return;
	}
	
	
	if( TNode = (NODE*) Enemy->TNode )
	{
		if( !(Enemy->Object.NodeNetwork&TNode->NetMask) )
		{
			// The node Im Targetting is not on my network...Better try and find one...
			if( Enemy->Object.LastNearestNode )
			{
				TNode = (NODE*) ( Enemy->TNode = WhichNode( 1 , Enemy->Object.NearestNode , Enemy->Object.LastNearestNode ) );
				
				if( !TNode )
				{
					AI_SetSCAN( Enemy );
					return;
				}
				
				if( !AI_ClearLOSNonZero( &Enemy->Object, &TNode->Pos , EnemyTypes[Enemy->Type].Radius  ) )
				{
					// couldnt find a node that will take me to my target so go back to my nearest...
					TNode = (NODE*) ( Enemy->TNode = Enemy->Object.NearestNode );
				}
			}
		}

		AI_AimAtTarget( &Enemy->Object.InvMat , &Enemy->Object.Pos, &TNode->Pos );
		Enemy->AI_Angle = AimData.Angle;

		if( !( EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_ICANTPITCH ) )
		{
			Enemy->AIMoveFlags |= AimData.Flags;
			if( ( EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_DONTSTOPANDTURN ) || ( (AimData.Angle.x < 15.0F) && (AimData.Angle.x > -15.0F) &&	(AimData.Angle.y < 15.0F) && (AimData.Angle.y > -15.0F) ) )
				Enemy->AIMoveFlags |= AI_CONTROL_FORWARD;
		}else{
			//This enemy cant look up or down so it has to move up and down to compensate....
			if( ( EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_DONTSTOPANDTURN ) || ( (AimData.Angle.x < 15.0F) && (AimData.Angle.x > -15.0F) &&	(AimData.Angle.y < 15.0F) && (AimData.Angle.y > -15.0F) && (AimData.Angle.y < 3.0F) && (AimData.Angle.y > -3.0F)) )
				Enemy->AIMoveFlags |= AI_CONTROL_FORWARD;
			Enemy->AIMoveFlags |= ( AimData.Flags & ( AI_CONTROL_TURNLEFT + AI_CONTROL_TURNRIGHT ) );
			if( AimData.Flags & AI_CONTROL_TURNUP )
			{
				Enemy->AIMoveFlags |=  AI_CONTROL_UP;
			}else if( AimData.Flags & AI_CONTROL_TURNDOWN )
			{
				Enemy->AIMoveFlags |=  AI_CONTROL_DOWN;
			}

		}

		
		if( DistanceVector2Vector( &Enemy->Object.Pos , &TNode->Pos ) < 64.0F )
		{
			Tinfo->Flags = 0;
			SET_TARGET_NODES;
			AI_GetDistToNearestTarget( Enemy );
			Enemy->TNode = Tinfo->TObject;
		}
		// MINES........
		if(	(Enemy->AIFlags&AI_MINEAVOID) && (EnemyTypes[Enemy->Type].Behave.Flags&AI_BEHAVIOUR_AVOIDMINES) )
		{
			// A Mine is close....And I can See it...
			TNode = ChooseAlternateNode( Enemy->Object.NodeNetwork , Enemy->Object.NearestNode , Enemy->TNode );
			Enemy->TNode = TNode;
			Enemy->AIFlags &= ~AI_MINEAVOID;
			Enemy->AIMoveFlags &= ~AI_CONTROL_FORWARD;
		}

		if( !Enemy->AvoidTimer)
		{
			TNode = Enemy->Object.NearestNode;
			if( (TNode->Flags&NODE_DROPMINES) && (EnemyTypes[Enemy->Type].Behave.Flags&AI_BEHAVIOUR_DROPMINES) ) 
			{
				Enemy->SecondaryFireTimer -= framelag;
				if( Enemy->SecondaryFireTimer < 0.0F )
					Enemy->SecondaryFireTimer = 0.0F;
				
				if( (Enemy->SecondaryFireTimer == 0.0F) )
				{
					Enemy->SecondaryFireTimer = EnemyTypes[Enemy->Type].SecondaryFireRate + (float) Random_Range( (u_int16_t) EnemyTypes[Enemy->Type].SecondaryFireRate );
					//This is where we Lay Mines....
					
					ApplyMatrix( &Enemy->Object.Mat, &Forward, &TempForwardVector );
					ApplyMatrix( &Enemy->Object.Mat, &SlideUp, &TempUpVector );
					
					MineIndex = InitOneSecBull( OWNER_ENEMY, Enemy->Index, ++Enemy->BulletID, Enemy->Object.Group,
								&Enemy->Object.Pos, &TempVector, &TempForwardVector, &TempUpVector,
								&TempVector, EnemyTypes[Enemy->Type].SecondaryWeaponType, false );

					if( MineIndex != (u_int16_t) -1 )
					{
						SecBulls[MineIndex].LifeSpan = 10.0F * 60.0F;
					}
				}
			}
		}
	}else{
		// If no target node has been found yet go to the nearest one...
		Enemy->TNode = Enemy->Object.NearestNode;
	}
}
コード例 #16
0
ファイル: aifollow.c プロジェクト: DUANISTON/forsaken
/*===================================================================
	Procedure	:	CRAWL Follow Path
	Input		:	ENEMY * Enemy
	Output		:	Nothing
===================================================================*/
void AI_CRAWL_FOLLOWPATH( register ENEMY * Enemy )
{
	OBJECT * SObject;
	NODE * TNode;

	SObject = &Enemy->Object;

	AI_THINK( Enemy , false , false);

	if( !(Enemy->AIFlags & AI_ANYPLAYERINRANGE) )
		return;

	Enemy->Timer -= framelag;

	if( Enemy->Timer < 0.0F )
		Enemy->Timer = 0.0F;
	
	if(Enemy->Timer == 0.0F)
	{
		if( !(Enemy->AIFlags & AI_ICANSEEPLAYER ))
		{
			if( !Enemy->TShip )
			{
				AI_DO_SCAN( Enemy );
			}
		}
		Enemy->Timer  =	RESET_VALIDATE_TIME + (float) Random_Range( (u_int16_t) RESET_VALIDATE_TIME );
	}
	
	AI_UPDATEGUNS( Enemy );


	if( (Enemy->Type == ENEMY_Legz) || (Enemy->Type == ENEMY_LEADER_Legz) )
	{
		if( !Enemy->Object.Animating )
		{
			SetCurAnimSeq( 0, &Enemy->Object );
		}
		Enemy->Object.AnimSpeed = 0.5F + ( ( Enemy->Object.Speed.z / EnemyTypes[Enemy->Type].MaxMoveRate ) * 2.0F );
	}

	
	if( TNode = (NODE*) Enemy->TNode )
	{

		if( !(EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_NOTURN) )
		{
			AI_AimAtTarget( &Enemy->Object.InvMat , &Enemy->Object.Pos, &TNode->SolidPos );
			Enemy->AIMoveFlags |= AimData.Flags;
			Enemy->AI_Angle = AimData.Angle;

 
			if( ( EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_DONTSTOPANDTURN ) || ( (AimData.Angle.y < 10.0F) && (AimData.Angle.y > -10.0F) ) )
			{
				Enemy->AIMoveFlags |= AI_CONTROL_FORWARD;
			}
		}else{
			Enemy->AIMoveFlags |= AI_CONTROL_FORWARD;
		}

		if(Enemy->PickNewNodeNow)
		{
			Enemy->PickNewNodeNow = false;

			Enemy->LastTNode = TNode;


			if( !Enemy->NextTNode )
			{
				Enemy->Object.NearestNode = TNode;
				Enemy->NextTNode = FindSuitableSplineNode( Enemy->Object.NodeNetwork, Enemy->Object.NearestNode , Enemy->Object.NearestNode , Enemy->LastTNode , Enemy->NextTNode , Enemy->TNode );
			}
			
			TNode = Enemy->NextTNode;
			Enemy->TNode = TNode;


			if( TNode )
			{
				Enemy->Object.NearestNode = TNode;
				Enemy->NextTNode = FindSuitableSplineNode( Enemy->Object.NodeNetwork, Enemy->Object.NearestNode , Enemy->Object.NearestNode , Enemy->LastTNode , Enemy->NextTNode , Enemy->TNode );
			}
			return;
		}
	}else{
		// If no target node has been found yet go to the nearest one...
		Enemy->TNode = Enemy->Object.NearestNode;
		Enemy->NextTNode = NULL;
	}


}