summaryrefslogtreecommitdiffstats
path: root/src/Copie de taskgoto.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/Copie de taskgoto.cpp')
-rw-r--r--src/Copie de taskgoto.cpp2136
1 files changed, 0 insertions, 2136 deletions
diff --git a/src/Copie de taskgoto.cpp b/src/Copie de taskgoto.cpp
deleted file mode 100644
index ddb9a40..0000000
--- a/src/Copie de taskgoto.cpp
+++ /dev/null
@@ -1,2136 +0,0 @@
-// taskgoto.cpp
-
-#define STRICT
-#define D3D_OVERLOADS
-
-#include <windows.h>
-#include <stdio.h>
-#include <d3d.h>
-
-#include "struct.h"
-#include "D3DEngine.h"
-#include "math3d.h"
-#include "event.h"
-#include "misc.h"
-#include "iman.h"
-#include "terrain.h"
-#include "water.h"
-#include "object.h"
-#include "physics.h"
-#include "brain.h"
-#include "task.h"
-#include "taskgoto.h"
-
-
-
-#define BM_DIM_STEP 5.0f
-
-
-
-
-// Constructeur de l'objet.
-
-CTaskGoto::CTaskGoto(CInstanceManager* iMan, CObject* object)
- : CTask(iMan, object)
-{
- CTask::CTask(iMan, object);
-
- m_bmArray = 0;
-}
-
-// Destructeur de l'objet.
-
-CTaskGoto::~CTaskGoto()
-{
- BitmapClose();
-}
-
-
-// Gestion d'un événement.
-
-BOOL CTaskGoto::EventProcess(const Event &event)
-{
- D3DVECTOR pos, goal;
- FPOINT rot, repulse;
- float a, g, dist, linSpeed, cirSpeed, h, w, factor, dir, floor;
- Error ret;
-
- if ( m_engine->RetPause() ) return TRUE;
- if ( event.event != EVENT_FRAME ) return TRUE;
-
- // Objet momentanément immobile (fourmi sur le dos) ?
- if ( m_object->RetFixed() )
- {
- m_physics->SetMotorSpeedX(0.0f); // stoppe l'avance
- m_physics->SetMotorSpeedZ(0.0f); // stoppe la rotation
- return TRUE;
- }
-
- if ( m_error != ERR_OK ) return FALSE;
-
- if ( m_bWorm )
- {
- WormFrame(event.rTime);
- }
-
- if ( m_phase == TGP_BEAMLEAK ) // fuite ?
- {
- m_leakTime += event.rTime;
-
- pos = m_object->RetPosition(0);
-
- rot.x = m_leakPos.x-pos.x;
- rot.y = m_leakPos.z-pos.z;
- dist = Length(rot.x, rot.y);
- rot.x /= dist;
- rot.y /= dist;
-
- a = m_object->RetAngleY(0);
- g = RotateAngle(rot.x, -rot.y); // CW !
- a = Direction(a, g)*1.0f;
- cirSpeed = a;
- if ( cirSpeed > 1.0f ) cirSpeed = 1.0f;
- if ( cirSpeed < -1.0f ) cirSpeed = -1.0f;
-
- a = NormAngle(a);
- if ( a > PI*0.5f && a < PI*1.5f )
- {
- linSpeed = 1.0f; // obstacle derrière -> avance
- cirSpeed = -cirSpeed;
- }
- else
- {
- linSpeed = -1.0f; // obstacle devant -> recule
- }
-
- m_physics->SetMotorSpeedZ(cirSpeed); // tourne à gauche/droite
- m_physics->SetMotorSpeedX(linSpeed); // avance
- return TRUE;
- }
-
- if ( m_phase == TGP_BEAMSEARCH ) // recherche chemin ?
- {
-//? OutputDebugString("CTaskGoto::EventProcess TGP_BEAMSEARCH\n");
-
- pos = m_object->RetPosition(0);
-
- if ( m_bmFretObject == 0 )
- {
- goal = m_goal;
- dist = 0.0f;
- }
- else
- {
- goal = m_goalObject;
- dist = TAKE_DIST;
- }
-
- ret = BeamSearch(pos, goal, dist);
- if ( ret == ERR_OK )
- {
-#if 1
- D3DVECTOR min, max;
- min = pos;
- max = m_goal;
- if ( min.x > max.x ) Swap(min.x, max.x);
- if ( min.z > max.z ) Swap(min.z, max.z);
- min.x -= 50.0f;
- min.z -= 50.0f;
- max.x += 50.0f;
- max.z += 50.0f;
- BitmapDebug(min, max, m_object->RetPosition(0), m_goal);
-#endif
- m_phase = TGP_BEAMUP;
- m_bmIndex = 0;
- m_bmWatchDogPos = m_object->RetPosition(0);
- m_bmWatchDogTime = 0.0f;
- }
- if ( ret == ERR_GOTO_IMPOSSIBLE || ret == ERR_GOTO_ITER )
- {
-#if 1
- D3DVECTOR min, max;
- min = pos;
- max = m_goal;
- if ( min.x > max.x ) Swap(min.x, max.x);
- if ( min.z > max.z ) Swap(min.z, max.z);
- min.x -= 50.0f;
- min.z -= 50.0f;
- max.x += 50.0f;
- max.z += 50.0f;
- BitmapDebug(min, max, m_object->RetPosition(0), m_goal);
-#endif
- m_error = ret;
- return FALSE;
- }
- return TRUE;
- }
-
- if ( m_phase == TGP_BEAMUP ) // décolle ?
- {
- m_physics->SetMotorSpeedY(1.0f); // monte
- return TRUE;
- }
-
- if ( m_phase == TGP_BEAMGOTO ) // goto dot list ?
- {
- if ( m_physics->RetCollision() ) // collision ?
- {
- m_physics->SetCollision(FALSE); // y'a plus
- }
-
- pos = m_object->RetPosition(0);
-
- if ( m_physics->RetType() == TYPE_FLYING && m_altitude > 0.0f )
- {
- goal = m_bmPoints[m_bmIndex];
- dist = Length2d(pos, goal);
- if ( dist != 0.0f ) // anticipe ?
- {
- linSpeed = m_physics->RetLinMotionX(MO_REASPEED);
- linSpeed /= m_physics->RetLinMotionX(MO_ADVSPEED);
- goal.x = pos.x + (goal.x-pos.x)*linSpeed*20.0f/dist;
- goal.z = pos.z + (goal.z-pos.z)*linSpeed*20.0f/dist;
- }
- floor = m_terrain->RetFloorLevel(goal, TRUE);
- w = m_water->RetLevel();
- if ( floor < w ) floor = w; // jamais en-dessous de l'eau
- h = pos.y-floor; // h <- hauteur jusqu'au sol
-
- linSpeed = 0.0f;
- if ( h < m_altitude-1.0f )
- {
- linSpeed = 0.2f+((m_altitude-1.0f)-h)*0.1f; // monte
- if ( linSpeed > 1.0f ) linSpeed = 1.0f;
- }
- if ( h > m_altitude+1.0f )
- {
- linSpeed = -0.2f; // descend
- }
- m_physics->SetMotorSpeedY(linSpeed);
- }
-
- dist = Length2d(pos, m_bmWatchDogPos);
- if ( dist < 1.0f )
- {
- m_bmWatchDogTime += event.rTime;
- }
- else
- {
- m_bmWatchDogTime = 0.0f;
- m_bmWatchDogPos = pos;
- }
-
- if ( m_bmWatchDogTime >= 1.0f ) // immobile depuis longtemps ?
- {
- m_physics->SetMotorSpeedX(0.0f); // stoppe l'avance
- m_physics->SetMotorSpeedZ(0.0f); // stoppe la rotation
- BeamStart();
- return TRUE;
- }
-
- rot.x = m_bmPoints[m_bmIndex].x-pos.x;
- rot.y = m_bmPoints[m_bmIndex].z-pos.z;
- dist = Length(rot.x, rot.y);
- rot.x /= dist;
- rot.y /= dist;
-
- a = m_object->RetAngleY(0);
- g = RotateAngle(rot.x, -rot.y); // CW !
- cirSpeed = Direction(a, g)*1.0f;
- if ( cirSpeed > 1.0f ) cirSpeed = 1.0f;
- if ( cirSpeed < -1.0f ) cirSpeed = -1.0f;
-
- if ( m_bmIndex == m_bmTotal ) // dernier point ?
- {
- dist = Length2d(m_bmPoints[m_bmIndex], pos);
- linSpeed = dist/(m_physics->RetLinStopLength()*1.5f);
- if ( linSpeed > 1.0f ) linSpeed = 1.0f;
- }
- else
- {
- linSpeed = 1.0f; // fonce sans s'arrêter
- }
-
- linSpeed *= 1.0f-(1.0f-0.3f)*Abs(cirSpeed);
-
- if ( dist < 20.0f && Abs(cirSpeed) >= 0.5f )
- {
- linSpeed = 0.0f; // tourne d'abord, puis avance
- }
-
- m_physics->SetMotorSpeedZ(cirSpeed); // tourne à gauche/droite
- m_physics->SetMotorSpeedX(linSpeed); // avance
- return TRUE;
- }
-
- if ( m_phase == TGP_BEAMDOWN ) // atterri ?
- {
- m_physics->SetMotorSpeedY(-0.5f); // tombe
- return TRUE;
- }
-
- if ( m_phase == TGP_LAND ) // atterri ?
- {
- m_physics->SetMotorSpeedY(-0.5f); // tombe
- return TRUE;
- }
-
- if ( m_goalMode == TGG_EXPRESS )
- {
- if ( m_crashMode == TGC_HALT )
- {
- if ( m_physics->RetCollision() ) // collision ?
- {
- m_physics->SetCollision(FALSE); // y'a plus
- m_error = ERR_STOP;
- return TRUE;
- }
- }
-
- pos = m_object->RetPosition(0);
-
- if ( m_altitude > 0.0f )
- {
- h = m_terrain->RetFloorHeight(pos, TRUE);
- linSpeed = 0.0f;
- if ( h < m_altitude )
- {
- linSpeed = 0.1f; // monte
- }
- if ( h > m_altitude )
- {
- linSpeed = -0.2f; // descend
- }
- m_physics->SetMotorSpeedY(linSpeed);
- }
-
- rot.x = m_goal.x-pos.x;
- rot.y = m_goal.z-pos.z;
- a = m_object->RetAngleY(0);
- g = RotateAngle(rot.x, -rot.y); // CW !
- cirSpeed = Direction(a, g)*1.0f;
- if ( cirSpeed > 1.0f ) cirSpeed = 1.0f;
- if ( cirSpeed < -1.0f ) cirSpeed = -1.0f;
-
- m_physics->SetMotorSpeedZ(cirSpeed); // tourne à gauche/droite
- m_physics->SetMotorSpeedX(1.0f); // avance
- return TRUE;
- }
-
- if ( m_phase != TGP_TURN &&
- m_physics->RetType() == TYPE_FLYING &&
- m_altitude > 0.0f )
- {
- pos = m_object->RetPosition(0);
- dist = Length2d(m_goal, pos);
- factor = (dist-20.0f)/20.0f;
- if ( factor < 0.0f ) factor = 0.0f;
- if ( factor > 1.0f ) factor = 1.0f;
-
- h = m_terrain->RetFloorHeight(m_object->RetPosition(0), TRUE);
- linSpeed = 0.0f;
- if ( h < (m_altitude-0.5f)*factor && factor == 1.0f )
- {
- linSpeed = 0.1f; // monte
- }
- if ( h > m_altitude*factor )
- {
- linSpeed = -0.2f; // descend
- }
- ComputeFlyingRepulse(dir);
- linSpeed += dir*0.2f;
-
- m_physics->SetMotorSpeedY(linSpeed);
- }
-
- if ( m_phase == TGP_ADVANCE ) // va vers l'objectif ?
- {
- if ( m_physics->RetCollision() ) // collision ?
- {
- m_physics->SetCollision(FALSE); // y'a plus
- m_time = 0.0f;
- m_phase = TGP_CRWAIT;
- return TRUE;
- }
-
-#if 0
- pos = m_object->RetPosition(0);
- a = m_object->RetAngleY(0);
- g = RotateAngle(m_goal.x-pos.x, pos.z-m_goal.z); // CW !
- cirSpeed = Direction(a, g)*1.0f;
- if ( cirSpeed > 1.0f ) cirSpeed = 1.0f;
- if ( cirSpeed < -1.0f ) cirSpeed = -1.0f;
-
- dist = Length2d(m_goal, pos);
- linSpeed = dist/(m_physics->RetLinStopLength()*1.5f);
- if ( linSpeed > 1.0f ) linSpeed = 1.0f;
-
- if ( dist < 20.0f && Abs(cirSpeed) >= 0.5f )
- {
- linSpeed = 0.0f; // tourne d'abord, puis avance
- }
-#else
- pos = m_object->RetPosition(0);
-
- rot.x = m_goal.x-pos.x;
- rot.y = m_goal.z-pos.z;
- dist = Length(rot.x, rot.y);
- rot.x /= dist;
- rot.y /= dist;
-
- ComputeRepulse(repulse);
- rot.x += repulse.x*2.0f;
- rot.y += repulse.y*2.0f;
-
- a = m_object->RetAngleY(0);
- g = RotateAngle(rot.x, -rot.y); // CW !
- cirSpeed = Direction(a, g)*1.0f;
-//? if ( m_physics->RetType() == TYPE_FLYING &&
-//? m_physics->RetLand() ) // volant au sol ?
-//? {
-//? cirSpeed *= 4.0f; // plus de pèche
-//? }
- if ( cirSpeed > 1.0f ) cirSpeed = 1.0f;
- if ( cirSpeed < -1.0f ) cirSpeed = -1.0f;
-
- dist = Length2d(m_goal, pos);
- linSpeed = dist/(m_physics->RetLinStopLength()*1.5f);
-//? if ( m_physics->RetType() == TYPE_FLYING &&
-//? m_physics->RetLand() ) // volant au sol ?
-//? {
-//? linSpeed *= 8.0f; // plus de pèche
-//? }
- if ( linSpeed > 1.0f ) linSpeed = 1.0f;
-
- linSpeed *= 1.0f-(1.0f-0.3f)*Abs(cirSpeed);
-
- if ( dist < 20.0f && Abs(cirSpeed) >= 0.5f )
- {
- linSpeed = 0.0f; // tourne d'abord, puis avance
- }
-#endif
-
- m_physics->SetMotorSpeedZ(cirSpeed); // tourne à gauche/droite
- m_physics->SetMotorSpeedX(linSpeed); // avance
- }
-
- if ( m_phase == TGP_TURN || // tourne vers l'objet ?
- m_phase == TGP_CRTURN || // tourne après collision ?
- m_phase == TGP_CLTURN ) // tourne après collision ?
- {
- a = m_object->RetAngleY(0);
- g = m_angle;
- cirSpeed = Direction(a, g)*1.0f;
- if ( cirSpeed > 1.0f ) cirSpeed = 1.0f;
- if ( cirSpeed < -1.0f ) cirSpeed = -1.0f;
-
- m_physics->SetMotorSpeedZ(cirSpeed); // tourne à gauche/droite
- }
-
- if ( m_phase == TGP_CRWAIT || // attend après collision ?
- m_phase == TGP_CLWAIT ) // attend après collision ?
- {
- m_time += event.rTime;
- m_physics->SetMotorSpeedX(0.0f); // stoppe l'avance
- m_physics->SetMotorSpeedZ(0.0f); // stoppe la rotation
- }
-
- if ( m_phase == TGP_CRADVANCE ) // avance après collision ?
- {
- if ( m_physics->RetCollision() ) // collision ?
- {
- m_physics->SetCollision(FALSE); // y'a plus
- m_time = 0.0f;
- m_phase = TGP_CLWAIT;
- return TRUE;
- }
- m_physics->SetMotorSpeedX(0.5f); // avance mollo
- }
-
- if ( m_phase == TGP_CLADVANCE ) // avance après collision ?
- {
- if ( m_physics->RetCollision() ) // collision ?
- {
- m_physics->SetCollision(FALSE); // y'a plus
- m_time = 0.0f;
- m_phase = TGP_CRWAIT;
- return TRUE;
- }
- m_physics->SetMotorSpeedX(0.5f); // avance mollo
- }
-
- if ( m_phase == TGP_MOVE ) // avance finale ?
- {
- m_bmTimeLimit -= event.rTime;
- m_physics->SetMotorSpeedX(1.0f);
- }
-
- return TRUE;
-}
-
-
-// Cherche une cible pour le ver.
-
-CObject* CTaskGoto::WormSearch(D3DVECTOR &impact)
-{
- CObject* pObj;
- CObject* pBest = 0;
- D3DVECTOR iPos, oPos;
- ObjectType oType;
- float distance, min, radius;
- int i;
-
- iPos = m_object->RetPosition(0);
- min = 1000000.0f;
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- oType = pObj->RetType();
- if ( oType != OBJECT_MOBILEfa &&
- oType != OBJECT_MOBILEta &&
- oType != OBJECT_MOBILEwa &&
- oType != OBJECT_MOBILEia &&
- oType != OBJECT_MOBILEfc &&
- oType != OBJECT_MOBILEtc &&
- oType != OBJECT_MOBILEwc &&
- oType != OBJECT_MOBILEic &&
- oType != OBJECT_MOBILEfi &&
- oType != OBJECT_MOBILEti &&
- oType != OBJECT_MOBILEwi &&
- oType != OBJECT_MOBILEii &&
- oType != OBJECT_MOBILEfs &&
- oType != OBJECT_MOBILEts &&
- oType != OBJECT_MOBILEws &&
- oType != OBJECT_MOBILEis &&
- oType != OBJECT_MOBILErt &&
- oType != OBJECT_MOBILErc &&
- oType != OBJECT_MOBILErr &&
- oType != OBJECT_MOBILErs &&
- oType != OBJECT_MOBILEsa &&
- oType != OBJECT_MOBILEtg &&
- oType != OBJECT_MOBILEft &&
- oType != OBJECT_MOBILEtt &&
- oType != OBJECT_MOBILEwt &&
- oType != OBJECT_MOBILEit &&
- oType != OBJECT_DERRICK &&
- oType != OBJECT_STATION &&
- oType != OBJECT_FACTORY &&
- oType != OBJECT_REPAIR &&
- oType != OBJECT_CONVERT &&
- oType != OBJECT_TOWER &&
- oType != OBJECT_RESEARCH &&
- oType != OBJECT_RADAR &&
- oType != OBJECT_INFO &&
- oType != OBJECT_ENERGY &&
- oType != OBJECT_LABO &&
- oType != OBJECT_NUCLEAR &&
- oType != OBJECT_PARA &&
- oType != OBJECT_SAFE &&
- oType != OBJECT_HUSTON ) continue;
-
- if ( pObj->RetVirusMode() ) continue; // objet infecté ?
-
- if ( !pObj->GetCrashSphere(0, oPos, radius) ) continue;
- distance = Length2d(oPos, iPos);
- if ( distance < min )
- {
- min = distance;
- pBest = pObj;
- }
- }
- if ( pBest == 0 ) return 0;
-
- impact = pBest->RetPosition(0);
- return pBest;
-}
-
-// Contamine les objets proches du ver.
-
-void CTaskGoto::WormFrame(float rTime)
-{
- CObject* pObj;
- D3DVECTOR impact, pos;
- float dist;
-
- m_wormLastTime += rTime;
-
- if ( m_wormLastTime >= 0.5f )
- {
- m_wormLastTime = 0.0f;
-
- pObj = WormSearch(impact);
- if ( pObj != 0 )
- {
- pos = m_object->RetPosition(0);
- dist = Length(pos, impact);
- if ( dist <= 15.0f )
- {
- pObj->SetVirusMode(TRUE); // paf, infecté !
- }
- }
- }
-}
-
-
-
-// Assigne le but à atteindre.
-// "dist" est la distance de laquelle il faut s'éloigner pour
-// prendre ou déposer un objet.
-
-Error CTaskGoto::Start(D3DVECTOR goal, float altitude,
- TaskGotoGoal goalMode, TaskGotoCrash crashMode)
-{
- D3DVECTOR pos;
- CObject* target;
- ObjectType type;
- float dist;
- int x, y;
-
- type = m_object->RetType();
-
- if ( goalMode == TGG_DEFAULT )
- {
- goalMode = TGG_STOP;
- if ( type == OBJECT_MOTHER ||
- type == OBJECT_ANT ||
- type == OBJECT_SPIDER ||
- type == OBJECT_WORM )
- {
- goalMode = TGG_EXPRESS;
- }
- }
-
- if ( crashMode == TGC_DEFAULT )
- {
-//? crashMode = TGC_RIGHTLEFT;
- crashMode = TGC_BEAM;
- if ( type == OBJECT_ANT ||
- type == OBJECT_SPIDER ||
- type == OBJECT_WORM ||
- type == OBJECT_BEE )
- {
- crashMode = TGC_HALT;
- }
- }
-
- m_altitude = altitude;
- m_goalMode = goalMode;
- m_crashMode = crashMode;
- m_goalObject = goal;
- m_goal = goal;
-
- m_bTake = FALSE;
- m_phase = TGP_ADVANCE;
- m_error = ERR_OK;
- m_try = 0;
- m_bmFretObject = 0;
- m_bmFinalMove = 0.0f;
-
- pos = m_object->RetPosition(0);
- dist = Length2d(pos, m_goal);
- if ( dist < 10.0f && m_crashMode == TGC_BEAM )
- {
- m_crashMode = TGC_RIGHTLEFT;
- }
-
- m_bWorm = FALSE;
- if ( type == OBJECT_WORM )
- {
- m_bWorm = TRUE;
- m_wormLastTime = 0.0f;
- }
-
- m_bApprox = FALSE;
- if ( type == OBJECT_HUMAN ||
- type == OBJECT_TECH ||
- type == OBJECT_MOTHER ||
- type == OBJECT_ANT ||
- type == OBJECT_SPIDER ||
- type == OBJECT_BEE ||
- type == OBJECT_WORM ||
- type == OBJECT_MOBILErt ||
- type == OBJECT_MOBILErc ||
- type == OBJECT_MOBILErr ||
- type == OBJECT_MOBILErs )
- {
- m_bApprox = TRUE;
- }
-
- if ( !m_bApprox && m_crashMode != TGC_BEAM )
- {
- target = SearchTarget(goal, 1.0f);
- if ( target != 0 )
- {
- m_goal = target->RetPosition(0);
- dist = 0.0f;
- if ( !AdjustBuilding(m_goal, 1.0f, dist) )
- {
- dist = 0.0f;
- AdjustTarget(target, m_goal, dist);
- }
- m_bTake = TRUE; // objet à prendre à l'arrivée (rotation finale)
- }
- }
-
- m_lastDistance = 1000.0f;
- m_physics->SetCollision(FALSE);
-
- if ( m_crashMode == TGC_BEAM )
- {
- target = SearchTarget(goal, 1.0f);
- if ( target != 0 )
- {
- m_goal = target->RetPosition(0);
- dist = 4.0f;
- if ( AdjustBuilding(m_goal, 1.0f, dist) )
- {
- m_bmFinalMove = dist;
- }
- else
- {
- dist = 4.0f;
- if ( AdjustTarget(target, m_goal, dist) )
- {
- m_bmFretObject = target; // fret posé au sol
- }
- else
- {
- m_bmFinalMove = dist;
- }
- }
- m_bTake = TRUE; // objet à prendre à l'arrivée (rotation finale)
- }
-
- if ( m_physics->RetType() == TYPE_FLYING && m_altitude == 0.0f )
- {
- pos = m_object->RetPosition(0);
- dist = Length2d(pos, m_goal);
- if ( dist > 40.0f ) // plus de 10 mètres ?
- {
- m_altitude = 20.0f; // altitude par défaut
- }
- }
-
- BeamStart();
-
- if ( m_bmFretObject == 0 )
- {
- x = (int)((m_goal.x+1600.0f)/BM_DIM_STEP);
- y = (int)((m_goal.z+1600.0f)/BM_DIM_STEP);
- if ( BitmapTestDot(0, x, y) ) // arrivée occupée ?
- {
- m_error = ERR_GOTO_IMPOSSIBLE;
- return m_error;
- }
- }
- }
-
- return ERR_OK;
-}
-
-// Indique si l'action est terminée.
-
-Error CTaskGoto::IsEnded()
-{
- D3DVECTOR pos;
- float limit, angle, dist, h;
-
- if ( m_engine->RetPause() ) return ERR_CONTINUE;
- if ( m_error != ERR_OK ) return m_error;
-
- pos = m_object->RetPosition(0);
-
- if ( m_phase == TGP_BEAMLEAK ) // fuite ?
- {
- if ( m_leakTime >= m_leakDelay )
- {
- m_physics->SetMotorSpeedX(0.0f); // stoppe l'avance
- m_physics->SetMotorSpeedZ(0.0f); // stoppe la rotation
- BeamInit();
- m_phase = TGP_BEAMSEARCH; // faudra chercher le chemin
- }
- return ERR_CONTINUE;
- }
-
- if ( m_phase == TGP_BEAMSEARCH ) // recherche du chemin ?
- {
- return ERR_CONTINUE;
- }
-
- if ( m_phase == TGP_BEAMUP ) // décolle ?
- {
- if ( m_physics->RetType() == TYPE_FLYING && m_altitude > 0.0f )
- {
- h = m_terrain->RetFloorHeight(pos, TRUE);
- if ( h < m_altitude-20.0f ) return ERR_CONTINUE;
- m_physics->SetMotorSpeedY(0.0f); // stoppe la montée
- }
- m_phase = TGP_BEAMGOTO;
- }
-
- if ( m_phase == TGP_BEAMGOTO ) // goto dot list ?
- {
- if ( m_physics->RetLand() ) // au sol ?
- {
- limit = 1.0f;
- }
- else // en vol ?
- {
- limit = 2.0f;
- if ( m_bmIndex < m_bmTotal ) limit *= 2.0f; // point intermédiaire
- }
- if ( m_bApprox ) limit = 2.0f;
-
- if ( Abs(pos.x - m_bmPoints[m_bmIndex].x) < limit &&
- Abs(pos.z - m_bmPoints[m_bmIndex].z) < limit )
- {
- m_physics->SetMotorSpeedX(0.0f); // stoppe l'avance
- m_physics->SetMotorSpeedZ(0.0f); // stoppe la rotation
-
- m_bmIndex = BeamShortcut();
-
- if ( m_bmIndex > m_bmTotal )
- {
- m_phase = TGP_BEAMDOWN;
- }
- }
- }
-
- if ( m_phase == TGP_BEAMDOWN ) // atteri ?
- {
- if ( m_physics->RetType() == TYPE_FLYING && m_altitude > 0.0f )
- {
- if ( !m_physics->RetLand() ) return ERR_CONTINUE;
- m_physics->SetMotorSpeedY(0.0f); // stoppe la descente
- }
-
- if ( m_bTake )
- {
- m_angle = RotateAngle(m_goalObject.x-pos.x, pos.z-m_goalObject.z);
- m_phase = TGP_TURN;
- }
- else
- {
- return ERR_STOP;
- }
- }
-
- if ( m_goalMode == TGG_EXPRESS )
- {
- dist = Length2d(m_goal, pos);
- if ( dist < 10.0f && dist > m_lastDistance )
- {
- return ERR_STOP;
- }
- m_lastDistance = dist;
- }
-
- if ( m_phase == TGP_ADVANCE ) // va vers l'objectif ?
- {
- if ( m_physics->RetLand() ) limit = 0.1f; // au sol
- else limit = 1.0f; // en vol
- if ( m_bApprox ) limit = 2.0f;
-
- if ( Abs(pos.x - m_goal.x) < limit &&
- Abs(pos.z - m_goal.z) < limit )
- {
- m_physics->SetMotorSpeedX(0.0f); // stoppe l'avance
- m_physics->SetMotorSpeedZ(0.0f); // stoppe la rotation
- m_phase = TGP_LAND;
- }
- }
-
- if ( m_phase == TGP_LAND ) // atterri ?
- {
- if ( m_physics->RetType() == TYPE_FLYING && m_altitude > 0.0f )
- {
- if ( !m_physics->RetLand() ) return ERR_CONTINUE;
- m_physics->SetMotorSpeedY(0.0f);
- }
-
- if ( m_bTake )
- {
- m_angle = RotateAngle(m_goalObject.x-pos.x, pos.z-m_goalObject.z);
- m_phase = TGP_TURN;
- }
- else
- {
- return ERR_STOP;
- }
- }
-
- if ( m_phase == TGP_TURN ) // tourne vers l'objet ?
- {
- angle = NormAngle(m_object->RetAngleY(0));
- limit = 0.02f;
- if ( m_bApprox ) limit = 0.10f;
- if ( Abs(angle-m_angle) < limit )
- {
- m_physics->SetMotorSpeedZ(0.0f); // stoppe la rotation
- if ( m_bmFinalMove == 0.0f ) return ERR_STOP;
-
- m_bmFinalPos = m_object->RetPosition(0);
- m_bmFinalDist = m_physics->RetLinLength(m_bmFinalMove);
- m_bmTimeLimit = m_physics->RetLinTimeLength(Abs(m_bmFinalMove))*1.5f;
- if ( m_bmTimeLimit < 0.5f ) m_bmTimeLimit = 0.5f;
- m_phase = TGP_MOVE;
- }
- }
-
- if ( m_phase == TGP_CRWAIT ) // attend après collision ?
- {
- if ( m_crashMode == TGC_HALT )
- {
- m_physics->SetMotorSpeedX(0.0f); // stoppe l'avance
- m_physics->SetMotorSpeedZ(0.0f); // stoppe la rotation
- m_error = ERR_GENERIC;
- return m_error;
- }
- if ( m_time >= 1.0f )
- {
- if ( m_crashMode == TGC_RIGHTLEFT ||
- m_crashMode == TGC_RIGHT ) angle = PI/2.0f; // 90 à droite
- else angle = -PI/2.0f; // 90 à gauche
- m_angle = NormAngle(m_object->RetAngleY(0)+angle);
- m_phase = TGP_CRTURN;
-//? m_phase = TGP_ADVANCE;
- }
- }
-
- if ( m_phase == TGP_CRTURN ) // tourne après collision ?
- {
- angle = NormAngle(m_object->RetAngleY(0));
- limit = 0.1f;
- if ( Abs(angle-m_angle) < limit )
- {
- m_physics->SetMotorSpeedZ(0.0f); // stoppe la rotation
- m_pos = pos;
- m_phase = TGP_CRADVANCE;
- }
- }
-
- if ( m_phase == TGP_CRADVANCE ) // avance après collision ?
- {
- if ( Length(pos, m_pos) >= 5.0f )
- {
- m_phase = TGP_ADVANCE;
- }
- }
-
- if ( m_phase == TGP_CLWAIT ) // attend après collision ?
- {
- if ( m_time >= 1.0f )
- {
- if ( m_crashMode == TGC_RIGHTLEFT ) angle = -PI;
- if ( m_crashMode == TGC_LEFTRIGHT ) angle = PI;
- if ( m_crashMode == TGC_RIGHT ) angle = PI/2.0f;
- if ( m_crashMode == TGC_LEFT ) angle = -PI/2.0f;
- m_angle = NormAngle(m_object->RetAngleY(0)+angle);
- m_phase = TGP_CLTURN;
- }
- }
-
- if ( m_phase == TGP_CLTURN ) // tourne après collision ?
- {
- angle = NormAngle(m_object->RetAngleY(0));
- limit = 0.1f;
- if ( Abs(angle-m_angle) < limit )
- {
- m_physics->SetMotorSpeedZ(0.0f); // stoppe la rotation
- m_pos = pos;
- m_phase = TGP_CLADVANCE;
- }
- }
-
- if ( m_phase == TGP_CLADVANCE ) // avance après collision ?
- {
- if ( Length(pos, m_pos) >= 10.0f )
- {
- m_phase = TGP_ADVANCE;
- m_try ++;
- }
- }
-
- if ( m_phase == TGP_MOVE ) // avance finale ?
- {
- if ( m_bmTimeLimit <= 0.0f )
- {
- m_physics->SetMotorSpeedX(0.0f); // stoppe
- Abort();
- return ERR_STOP;
- }
-
- dist = Length(m_bmFinalPos, m_object->RetPosition(0));
- if ( dist < m_bmFinalDist ) return ERR_CONTINUE;
- m_physics->SetMotorSpeedX(0.0f); // stoppe l'avance
- return ERR_STOP;
- }
-
- return ERR_CONTINUE;
-}
-
-
-// Cherche l'objet à la position cible.
-
-CObject* CTaskGoto::SearchTarget(D3DVECTOR pos, float margin)
-{
- CObject* pObj;
- D3DVECTOR oPos;
- float dist;
- int i;
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- if ( !pObj->RetActif() ) continue;
- if ( pObj->RetTruck() != 0 ) continue; // objet porté ?
-
- oPos = pObj->RetPosition(0);
- dist = Length2d(pos, oPos);
-
- if ( dist <= margin ) return pObj;
- }
-
- return 0;
-}
-
-// Ajuste la cible en fonction de l'objet.
-// Retourne TRUE s'il s'agit de fret posé au sol.
-
-BOOL CTaskGoto::AdjustTarget(CObject* pObj, D3DVECTOR &pos, float &distance)
-{
- ObjectType type;
- Character* character;
- D3DMATRIX* mat;
- D3DVECTOR goal;
- float dist, suppl;
-
- type = m_object->RetType();
- if ( type == OBJECT_BEE ||
- type == OBJECT_WORM )
- {
- pos = pObj->RetPosition(0);
- return FALSE;
- }
-
- type = pObj->RetType();
-
- if ( type == OBJECT_FRET ||
- type == OBJECT_STONE ||
- type == OBJECT_URANIUM ||
- type == OBJECT_METAL ||
- type == OBJECT_POWER ||
- type == OBJECT_ATOMIC ||
- type == OBJECT_BULLET ||
- type == OBJECT_BBOX ||
- type == OBJECT_KEYa ||
- type == OBJECT_KEYb ||
- type == OBJECT_KEYc ||
- type == OBJECT_KEYd ||
- type == OBJECT_TNT ||
- type == OBJECT_BOMB )
- {
- pos = m_object->RetPosition(0);
- goal = pObj->RetPosition(0);
- dist = Length(goal, pos);
- pos = (pos-goal)*(TAKE_DIST+distance)/dist + goal;
- return TRUE;
- }
-
- if ( type == OBJECT_MOBILEfa ||
- type == OBJECT_MOBILEta ||
- type == OBJECT_MOBILEwa ||
- type == OBJECT_MOBILEia ||
- type == OBJECT_MOBILEfs ||
- type == OBJECT_MOBILEts ||
- type == OBJECT_MOBILEws ||
- type == OBJECT_MOBILEis ||
- type == OBJECT_MOBILEfc ||
- type == OBJECT_MOBILEtc ||
- type == OBJECT_MOBILEwc ||
- type == OBJECT_MOBILEic ||
- type == OBJECT_MOBILEfi ||
- type == OBJECT_MOBILEti ||
- type == OBJECT_MOBILEwi ||
- type == OBJECT_MOBILEii ||
- type == OBJECT_MOBILErt ||
- type == OBJECT_MOBILErc ||
- type == OBJECT_MOBILErr ||
- type == OBJECT_MOBILErs ||
- type == OBJECT_MOBILEsa ||
- type == OBJECT_MOBILEtg ||
- type == OBJECT_MOBILEft ||
- type == OBJECT_MOBILEtt ||
- type == OBJECT_MOBILEwt ||
- type == OBJECT_MOBILEit )
- {
- character = pObj->RetCharacter();
- pos = character->posPower;
- pos.x -= TAKE_DIST+TAKE_DIST_OTHER+distance;
- mat = pObj->RetWorldMatrix(0);
- pos = Transform(*mat, pos);
- return FALSE;
- }
-
- if ( GetHotPoint(pObj, goal, TRUE, distance, suppl) )
- {
- pos = goal;
- distance += suppl;
- return FALSE;
- }
-
- pos = pObj->RetPosition(0);
- return FALSE;
-}
-
-// S'il on est sur un objet produit par un bâtiment (minerai produit
-// par derrick), modifie la position par-rapport au bâtiment.
-
-BOOL CTaskGoto::AdjustBuilding(D3DVECTOR &pos, float margin, float &distance)
-{
- CObject* pObj;
- D3DVECTOR oPos;
- float dist, suppl;
- int i;
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- if ( !pObj->RetActif() ) continue;
- if ( pObj->RetTruck() != 0 ) continue; // objet porté ?
-
- if ( !GetHotPoint(pObj, oPos, FALSE, 0.0f, suppl) ) continue;
- dist = Length2d(pos, oPos);
- if ( dist <= margin )
- {
- GetHotPoint(pObj, pos, TRUE, distance, suppl);
- distance += suppl;
- return TRUE;
- }
- }
- return FALSE;
-}
-
-// Retourne le point où est produit ou posé qq chose sur un bâtiment.
-
-BOOL CTaskGoto::GetHotPoint(CObject *pObj, D3DVECTOR &pos,
- BOOL bTake, float distance, float &suppl)
-{
- ObjectType type;
- D3DMATRIX* mat;
-
- pos = D3DVECTOR(0.0f, 0.0f, 0.0f);
- suppl = 0.0f;
- type = pObj->RetType();
-
- if ( type == OBJECT_DERRICK )
- {
- mat = pObj->RetWorldMatrix(0);
- pos.x += 7.0f;
- if ( bTake && distance != 0.0f ) suppl = 4.0f;
- if ( bTake ) pos.x += TAKE_DIST+distance+suppl;
- pos = Transform(*mat, pos);
- return TRUE;
- }
-
- if ( type == OBJECT_CONVERT )
- {
- mat = pObj->RetWorldMatrix(0);
- pos.x += 0.0f;
- if ( bTake && distance != 0.0f ) suppl = 4.0f;
- if ( bTake ) pos.x += TAKE_DIST+distance+suppl;
- pos = Transform(*mat, pos);
- return TRUE;
- }
-
- if ( type == OBJECT_RESEARCH )
- {
- mat = pObj->RetWorldMatrix(0);
- pos.x += 7.5f;
- if ( bTake ) pos.x += TAKE_DIST+TAKE_DIST_OTHER+distance;
- pos = Transform(*mat, pos);
- return TRUE;
- }
-
- if ( type == OBJECT_ENERGY )
- {
- mat = pObj->RetWorldMatrix(0);
- pos.x += 0.0f;
- if ( bTake ) pos.x += TAKE_DIST+TAKE_DIST_OTHER+distance;
- pos = Transform(*mat, pos);
- return TRUE;
- }
-
- if ( type == OBJECT_TOWER )
- {
- mat = pObj->RetWorldMatrix(0);
- pos.x += 5.0f;
- if ( bTake && distance != 0.0f ) suppl = 4.0f;
- if ( bTake ) pos.x += TAKE_DIST+TAKE_DIST_OTHER+distance+suppl;
- pos = Transform(*mat, pos);
- return TRUE;
- }
-
- if ( type == OBJECT_LABO )
- {
- mat = pObj->RetWorldMatrix(0);
- pos.x += 0.0f;
- if ( bTake ) pos.x += TAKE_DIST+TAKE_DIST_OTHER+distance;
- pos = Transform(*mat, pos);
- return TRUE;
- }
-
- if ( type == OBJECT_NUCLEAR )
- {
- mat = pObj->RetWorldMatrix(0);
- pos.x += 22.0f;
- if ( bTake && distance != 0.0f ) suppl = 4.0f;
- if ( bTake ) pos.x += TAKE_DIST+TAKE_DIST_OTHER+distance+suppl;
- pos = Transform(*mat, pos);
- return TRUE;
- }
-
- if ( type == OBJECT_FACTORY )
- {
- mat = pObj->RetWorldMatrix(0);
- pos.x += 4.0f;
- if ( bTake && distance != 0.0f ) suppl = 3.0f;
- if ( bTake ) pos.x += TAKE_DIST+distance+suppl;
- pos = Transform(*mat, pos);
- return TRUE;
- }
-
- if ( type == OBJECT_STATION )
- {
- mat = pObj->RetWorldMatrix(0);
- if ( bTake ) pos.x += distance;
- pos = Transform(*mat, pos);
- return TRUE;
- }
-
- suppl = 0.0f;
- return FALSE;
-}
-
-
-// Cherche un objet trop proche qu'il faut fuire.
-
-BOOL CTaskGoto::LeakSearch(D3DVECTOR &pos, float &delay)
-{
- CObject* pObj;
- D3DVECTOR iPos, oPos, bPos;
- float iRadius, oRadius, bRadius, dist, min;
- int i, j;
-
- m_object->GetCrashSphere(0, iPos, iRadius);
-
- min = 100000.0f;
- bRadius = 0.0f;
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- if ( pObj == m_object ) continue;
- if ( !pObj->RetActif() ) continue;
- if ( pObj->RetTruck() != 0 ) continue; // objet porté ?
-
- j = 0;
- while ( pObj->GetCrashSphere(j++, oPos, oRadius) )
- {
- dist = Length2d(oPos, iPos);
- if ( dist < min )
- {
- min = dist;
- bPos = oPos;
- bRadius = oRadius;
- }
- }
- }
- if ( min > iRadius+bRadius+4.0f ) return FALSE;
-
- pos = bPos;
- delay = m_physics->RetLinTimeLength(4.0f);
- return TRUE;
-}
-
-
-// Calcule la force de répulsion en fonction des obstacles.
-// La longueur du vecteur rendu est comprise entre 0 et 1.
-
-void CTaskGoto::ComputeRepulse(FPOINT &dir)
-{
-#if 0
- D3DVECTOR iPos, oPos;
- FPOINT repulse;
- CObject *pObj;
- float dist, iRadius, oRadius;
- int i;
-
- dir.x = 0.0f;
- dir.y = 0.0f;
-
- m_object->GetCrashSphere(0, iPos, iRadius);
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- if ( pObj == m_object ) continue;
- if ( pObj->RetTruck() != 0 ) continue;
-
- oPos = pObj->RetPosition(0);
- dist = Length(oPos, m_goalObject);
- if ( dist <= 1.0f ) continue;
-
- pObj->GetGlobalSphere(oPos, oRadius);
- oRadius += iRadius+m_physics->RetLinStopLength()*1.1f;
- dist = Length2d(oPos, iPos);
- if ( dist <= oRadius )
- {
- repulse.x = iPos.x-oPos.x;
- repulse.y = iPos.z-oPos.z;
-
-//? dist = 0.2f-(0.2f*dist/oRadius);
- dist = powf(dist/oRadius, 2.0f);
- dist = 0.2f-0.2f*dist;
- repulse.x *= dist;
- repulse.y *= dist;
-//? repulse.x /= dist;
-//? repulse.y /= dist;
-
- dir.x += repulse.x;
- dir.y += repulse.y;
- }
- }
-#else
- ObjectType iType, oType;
- D3DVECTOR iPos, oPos;
- FPOINT repulse;
- CObject *pObj;
- float gDist, add, addi, fac, dist, iRadius, oRadius;
- int i, j;
- BOOL bAlien;
-
- dir.x = 0.0f;
- dir.y = 0.0f;
-
- // Le ver passe partout et à travers tout !
- iType = m_object->RetType();
- if ( iType == OBJECT_WORM ) return;
-
- m_object->GetCrashSphere(0, iPos, iRadius);
- gDist = Length(iPos, m_goal);
-
- add = m_physics->RetLinStopLength()*1.1f; // distance de freinage
- fac = 2.0f;
-
- if ( iType == OBJECT_MOBILEwa ||
- iType == OBJECT_MOBILEwc ||
- iType == OBJECT_MOBILEwi ||
- iType == OBJECT_MOBILEws ||
- iType == OBJECT_MOBILEwt ) // roues ?
- {
- add = 5.0f;
- fac = 1.5f;
- }
- if ( iType == OBJECT_MOBILEta ||
- iType == OBJECT_MOBILEtc ||
- iType == OBJECT_MOBILEti ||
- iType == OBJECT_MOBILEts ||
- iType == OBJECT_MOBILEtt ) // chenilles ?
- {
- add = 4.0f;
- fac = 1.5f;
- }
- if ( iType == OBJECT_MOBILEfa ||
- iType == OBJECT_MOBILEfc ||
- iType == OBJECT_MOBILEfi ||
- iType == OBJECT_MOBILEfs ||
- iType == OBJECT_MOBILEft ) // volant ?
- {
- if ( m_physics->RetLand() )
- {
- add = 5.0f;
- fac = 1.5f;
- }
- else
- {
- add = 10.0f;
- fac = 1.5f;
- }
- }
- if ( iType == OBJECT_MOBILEia ||
- iType == OBJECT_MOBILEic ||
- iType == OBJECT_MOBILEii ||
- iType == OBJECT_MOBILEis ||
- iType == OBJECT_MOBILEit ) // pattes ?
- {
- add = 4.0f;
- fac = 1.5f;
- }
- if ( iType == OBJECT_BEE ) // guêpe ?
- {
- if ( m_physics->RetLand() )
- {
- add = 3.0f;
- fac = 1.5f;
- }
- else
- {
- add = 5.0f;
- fac = 1.5f;
- }
- }
-
- bAlien = FALSE;
- if ( iType == OBJECT_MOTHER ||
- iType == OBJECT_ANT ||
- iType == OBJECT_SPIDER ||
- iType == OBJECT_BEE ||
- iType == OBJECT_WORM )
- {
- bAlien = TRUE;
- }
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- if ( pObj == m_object ) continue;
- if ( pObj->RetTruck() != 0 ) continue;
-
- oType = pObj->RetType();
-
- if ( oType == OBJECT_WORM ) continue;
-
- if ( bAlien )
- {
- if ( oType == OBJECT_STONE ||
- oType == OBJECT_URANIUM ||
- oType == OBJECT_METAL ||
- oType == OBJECT_POWER ||
- oType == OBJECT_ATOMIC ||
- oType == OBJECT_BULLET ||
- oType == OBJECT_BBOX ||
- oType == OBJECT_KEYa ||
- oType == OBJECT_KEYb ||
- oType == OBJECT_KEYc ||
- oType == OBJECT_KEYd ||
- oType == OBJECT_TNT ||
- oType == OBJECT_BOMB ||
- (oType >= OBJECT_PLANT0 &&
- oType <= OBJECT_PLANT19 ) ||
- (oType >= OBJECT_MUSHROOM0 &&
- oType <= OBJECT_MUSHROOM9 ) ) continue;
- }
-
- addi = add;
- if ( iType == OBJECT_BEE &&
- oType == OBJECT_BEE )
- {
- addi = 2.0f; // entre guèpes, faut pas trop s'embêter
- }
-
- j = 0;
- while ( pObj->GetCrashSphere(j++, oPos, oRadius) )
- {
- if ( oPos.y-oRadius > iPos.y+iRadius ) continue;
- if ( oPos.y+oRadius < iPos.y-iRadius ) continue;
-
- dist = Length(oPos, m_goal);
- if ( dist <= 1.0f ) continue; // sur le but ?
-
- oRadius += iRadius+addi;
- dist = Length2d(oPos, iPos);
- if ( dist > gDist ) continue; // plus loin que le but ?
- if ( dist <= oRadius )
- {
- repulse.x = iPos.x-oPos.x;
- repulse.y = iPos.z-oPos.z;
-
- dist = powf(dist/oRadius, fac);
- dist = 0.2f-0.2f*dist;
- repulse.x *= dist;
- repulse.y *= dist;
-
- dir.x += repulse.x;
- dir.y += repulse.y;
- }
- }
- }
-#endif
-}
-
-// Calcule la force de répulsion verticale en fonction des obstacles.
-// La longueur du vecteur rendu est comprise entre -1 et 1.
-
-void CTaskGoto::ComputeFlyingRepulse(float &dir)
-{
- ObjectType oType;
- D3DVECTOR iPos, oPos;
- CObject *pObj;
- float add, fac, dist, iRadius, oRadius, repulse;
- int i, j;
-
- m_object->GetCrashSphere(0, iPos, iRadius);
-
- add = 0.0f;
- fac = 1.5f;
- dir = 0.0f;
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- if ( pObj == m_object ) continue;
- if ( pObj->RetTruck() != 0 ) continue;
-
- oType = pObj->RetType();
-
- if ( oType == OBJECT_WORM ) continue;
-
- j = 0;
- while ( pObj->GetCrashSphere(j++, oPos, oRadius) )
- {
- oRadius += iRadius+add;
- dist = Length2d(oPos, iPos);
- if ( dist <= oRadius )
- {
- repulse = iPos.y-oPos.y;
-
- dist = powf(dist/oRadius, fac);
- dist = 0.2f-0.2f*dist;
- repulse *= dist;
-
- dir += repulse;
- }
- }
- }
-
- if ( dir < -1.0f ) dir = -1.0f;
- if ( dir > 1.0f ) dir = 1.0f;
-}
-
-
-
-// Parmi tous les points suivants, cherche s'il en existe un qui
-// permet d'y aller directement à vol d'oiseau. Si oui, saute tous
-// les points intermédiaires inutiles.
-
-int CTaskGoto::BeamShortcut()
-{
- int i;
-
- for ( i=m_bmTotal ; i>=m_bmIndex+2 ; i-- ) // cherche depuis le dernier
- {
- if ( BitmapTestLine(m_bmPoints[m_bmIndex], m_bmPoints[i], 0.0f, FALSE) )
- {
- return i; // bingo, trouvé
- }
- }
-
- return m_bmIndex+1; // va simplement au point suivant
-}
-
-// C'est le grand départ.
-
-void CTaskGoto::BeamStart()
-{
- D3DVECTOR min, max;
-
-//? OutputDebugString("CTaskGoto::Start TGC_BEAM\n");
- BitmapOpen();
- BitmapObject();
-
- min = m_object->RetPosition(0);
- max = m_goal;
- if ( min.x > max.x ) Swap(min.x, max.x);
- if ( min.z > max.z ) Swap(min.z, max.z);
- min.x -= 10.0f*BM_DIM_STEP;
- min.z -= 10.0f*BM_DIM_STEP;
- max.x += 10.0f*BM_DIM_STEP;
- max.z += 10.0f*BM_DIM_STEP;
- BitmapTerrain(min, max);
-
- if ( LeakSearch(m_leakPos, m_leakDelay) )
- {
- m_phase = TGP_BEAMLEAK; // il faut d'abord fuire
- m_leakTime = 0.0f;
- }
- else
- {
- m_physics->SetMotorSpeedX(0.0f); // stoppe l'avance
- m_physics->SetMotorSpeedZ(0.0f); // stoppe la rotation
- BeamInit();
- m_phase = TGP_BEAMSEARCH; // faudra chercher le chemin
- }
-}
-
-// Initialisation avant le premier BeamSearch.
-
-void CTaskGoto::BeamInit()
-{
- int i;
-
- for ( i=0 ; i<MAXPOINTS ; i++ )
- {
- m_bmIter[i] = -1;
- }
-}
-
-// Calcule les points par où passer pour aller de start à goal.
-// Retourne :
-// ERR_OK si c'est bon
-// ERR_GOTO_IMPOSSIBLE si impossible
-// ERR_GOTO_ITER si avorté car trop de récursions
-// ERR_CONTINUE si pas encore fini
-// goalRadius: distance à laquelle il faut s'approcher du but
-
-Error CTaskGoto::BeamSearch(const D3DVECTOR &start, const D3DVECTOR &goal,
- float goalRadius)
-{
- float step, len;
- int nbIter;
-
- len = Length2d(start, goal);
- step = len/5.0f;
- if ( step < BM_DIM_STEP*2.0f ) step = BM_DIM_STEP*2.0f;
- if ( step > 20.0f ) step = 20.0f;
- nbIter = 200; // pour ne pas trop baisser le framerate
- m_bmIterCounter = 0;
- return BeamExplore(start, start, goal, goalRadius, 165.0f*PI/180.0f, 22, step, 0, nbIter);
-}
-
-// prevPos: position précédente
-// curPos: position courante
-// goalPos: position qu'on cherche à atteindre
-// angle: angle par rapport au but qu'on explore
-// nbDiv: nombre du sous-divisions qu'on fait avec angle
-// step longuer d'un pas
-// i nombre de récursions effectuées
-// nbIter nombre max. d'iterations qu'on a le droit de faire avant d'interrompre provisoirement
-
-Error CTaskGoto::BeamExplore(const D3DVECTOR &prevPos, const D3DVECTOR &curPos,
- const D3DVECTOR &goalPos, float goalRadius,
- float angle, int nbDiv, float step,
- int i, int nbIter)
-{
- D3DVECTOR newPos;
- Error ret;
- int iDiv, iClear, iLar;
-
- iLar = 0;
- if ( i >= MAXPOINTS ) return ERR_GOTO_ITER; // trop de récursion
-
- if ( m_bmIter[i] == -1 )
- {
- m_bmIter[i] = 0;
-
- if ( i == 0 )
- {
- m_bmPoints[i] = curPos;
- }
- else
- {
- if ( !BitmapTestLine(prevPos, curPos, angle/nbDiv, TRUE) ) return ERR_GOTO_IMPOSSIBLE;
-
- m_bmPoints[i] = curPos;
-
- if ( Length2d(curPos, goalPos)-goalRadius <= step )
- {
- if ( goalRadius == 0.0f )
- {
- newPos = goalPos;
- }
- else
- {
- newPos = BeamPoint(curPos, goalPos, 0, Length2d(curPos, curPos)-goalRadius);
- }
- if ( BitmapTestLine(curPos, newPos, angle/nbDiv, FALSE) )
- {
- m_bmPoints[i+1] = newPos;
- m_bmTotal = i+1;
- return ERR_OK;
- }
- }
- }
- }
-
- if ( iLar >= m_bmIter[i] )
- {
- newPos = BeamPoint(curPos, goalPos, 0, step);
- ret = BeamExplore(curPos, newPos, goalPos, goalRadius, angle, nbDiv, step, i+1, nbIter);
- if ( ret != ERR_GOTO_IMPOSSIBLE ) return ret;
- m_bmIter[i] = iLar+1;
- for ( iClear=i+1 ; iClear<=MAXPOINTS ; iClear++ ) m_bmIter[iClear] = -1;
- m_bmIterCounter ++;
- if ( m_bmIterCounter >= nbIter ) return ERR_CONTINUE;
- }
- iLar ++;
-
- for ( iDiv=1 ; iDiv<=nbDiv ; iDiv++ )
- {
- if ( iLar >= m_bmIter[i] )
- {
- newPos = BeamPoint(curPos, goalPos, angle*iDiv/nbDiv, step);
- ret = BeamExplore(curPos, newPos, goalPos, goalRadius, angle, nbDiv, step, i+1, nbIter);
- if ( ret != ERR_GOTO_IMPOSSIBLE ) return ret;
- m_bmIter[i] = iLar+1;
- for ( iClear=i+1 ; iClear<=MAXPOINTS ; iClear++ ) m_bmIter[iClear] = -1;
- m_bmIterCounter ++;
- if ( m_bmIterCounter >= nbIter ) return ERR_CONTINUE;
- }
- iLar ++;
-
- if ( iLar >= m_bmIter[i] )
- {
- newPos = BeamPoint(curPos, goalPos, -angle*iDiv/nbDiv, step);
- ret = BeamExplore(curPos, newPos, goalPos, goalRadius, angle, nbDiv, step, i+1, nbIter);
- if ( ret != ERR_GOTO_IMPOSSIBLE ) return ret;
- m_bmIter[i] = iLar+1;
- for ( iClear=i+1 ; iClear<=MAXPOINTS ; iClear++ ) m_bmIter[iClear] = -1;
- m_bmIterCounter ++;
- if ( m_bmIterCounter >= nbIter ) return ERR_CONTINUE;
- }
- iLar ++;
- }
-
- return ERR_GOTO_IMPOSSIBLE;
-}
-
-// Soit une droite "start-goal". Calcule le point situé à la distance
-// "step" du point "start" et faisant un angle "angle" avec la droite.
-
-D3DVECTOR CTaskGoto::BeamPoint(const D3DVECTOR &startPoint,
- const D3DVECTOR &goalPoint,
- float angle, float step)
-{
- D3DVECTOR resPoint;
- float goalAngle;
-
- goalAngle = RotateAngle(goalPoint.x-startPoint.x, goalPoint.z-startPoint.z);
-
- resPoint.x = startPoint.x + cosf(goalAngle+angle)*step;
- resPoint.z = startPoint.z + sinf(goalAngle+angle)*step;
- resPoint.y = 0.0f;
-
- return resPoint;
-}
-
-// Affiche une partion de bitmap.
-
-void CTaskGoto::BitmapDebug(const D3DVECTOR &min, const D3DVECTOR &max,
- const D3DVECTOR &start, const D3DVECTOR &goal)
-{
- int minx, miny, maxx, maxy, x, y, i ,n;
- char s[2000];
-
- minx = (int)((min.x+1600.0f)/BM_DIM_STEP);
- miny = (int)((min.z+1600.0f)/BM_DIM_STEP);
- maxx = (int)((max.x+1600.0f)/BM_DIM_STEP);
- maxy = (int)((max.z+1600.0f)/BM_DIM_STEP);
-
- if ( minx > maxx ) Swap(minx, maxx);
- if ( miny > maxy ) Swap(miny, maxy);
-
- OutputDebugString("Bitmap :\n");
- for ( y=miny ; y<=maxy ; y++ )
- {
- s[0] = 0;
- for ( x=minx ; x<=maxx ; x++ )
- {
- n = -1;
- for ( i=0 ; i<=m_bmTotal ; i++ )
- {
- if ( x == (int)((m_bmPoints[i].x+1600.0f)/BM_DIM_STEP) &&
- y == (int)((m_bmPoints[i].z+1600.0f)/BM_DIM_STEP) )
- {
- n = i;
- break;
- }
- }
-
- if ( BitmapTestDot(0, x,y) )
- {
- strcat(s, "o");
- }
- else
- {
- if ( BitmapTestDot(1, x,y) )
- {
- strcat(s, "-");
- }
- else
- {
- strcat(s, ".");
- }
- }
-
- if ( x == (int)((start.x+1600.0f)/BM_DIM_STEP) &&
- y == (int)((start.z+1600.0f)/BM_DIM_STEP) )
- {
- strcat(s, "s");
- }
- else
- if ( x == (int)((goal.x+1600.0f)/BM_DIM_STEP) &&
- y == (int)((goal.z+1600.0f)/BM_DIM_STEP) )
- {
- strcat(s, "g");
- }
- else
- if ( n != -1 )
- {
- char ss[2];
- ss[0] = 'A'+n;
- ss[1] = 0;
- strcat(s, ss);
- }
- else
- {
- strcat(s, " ");
- }
- }
- strcat(s, "\n");
- OutputDebugString(s);
- }
-}
-
-// Teste si un chemin le long d'une droite est possible.
-
-BOOL CTaskGoto::BitmapTestLine(const D3DVECTOR &start, const D3DVECTOR &goal,
- float stepAngle, BOOL bSecond)
-{
- D3DVECTOR pos, inc;
- float dist, step;
- float distNoB2;
- int i, max, x, y;
-
- if ( m_bmArray == 0 ) return TRUE;
-
- dist = Length2d(start, goal);
- if ( dist == 0.0f ) return TRUE;
- step = BM_DIM_STEP*0.5f;
-
- inc.x = (goal.x-start.x)*step/dist;
- inc.z = (goal.z-start.z)*step/dist;
-
- pos = start;
-
- if ( bSecond )
- {
- x = (int)((pos.x+1600.0f)/BM_DIM_STEP);
- y = (int)((pos.z+1600.0f)/BM_DIM_STEP);
- BitmapSetDot(1, x, y); // met le flag du point de départ
- }
-
- max = (int)(dist/step);
- if ( max == 0 ) max = 1;
- distNoB2 = BM_DIM_STEP*sqrtf(2.0f)/sinf(stepAngle);
- for ( i=0 ; i<max ; i++ )
- {
- if ( i == max-1 )
- {
- pos = goal; // teste le point d'arrivée
- }
- else
- {
- pos.x += inc.x;
- pos.z += inc.z;
- }
-
- x = (int)((pos.x+1600.0f)/BM_DIM_STEP);
- y = (int)((pos.z+1600.0f)/BM_DIM_STEP);
-
- if ( bSecond )
- {
- if ( i > 2 && BitmapTestDot(1, x, y) ) return FALSE;
-
- if ( step*(i+1) > distNoB2 && i < max-2 )
- {
- BitmapSetDot(1, x, y);
- }
- }
-
- if ( BitmapTestDot(0, x, y) ) return FALSE;
- }
- return TRUE;
-}
-
-// Ajoute les objets dans le bitmap.
-
-void CTaskGoto::BitmapObject()
-{
- CObject *pObj;
- D3DVECTOR iPos, oPos;
- float iRadius, oRadius, h;
- int i, j;
-
- m_object->GetCrashSphere(0, iPos, iRadius);
-
- for ( i=0 ; i<1000000 ; i++ )
- {
- pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i);
- if ( pObj == 0 ) break;
-
- if ( pObj == m_object ) continue;
- if ( pObj == m_bmFretObject ) continue;
- if ( pObj->RetTruck() != 0 ) continue;
-
- h = m_terrain->RetFloorLevel(pObj->RetPosition(0), TRUE);
- if ( m_physics->RetType() == TYPE_FLYING && m_altitude > 0.0f )
- {
- h += m_altitude;
- }
-
- j = 0;
- while ( pObj->GetCrashSphere(j++, oPos, oRadius) )
- {
- if ( m_physics->RetType() == TYPE_FLYING && m_altitude > 0.0f ) // volant ?
- {
- if ( oPos.y-oRadius > h+8.0f ||
- oPos.y+oRadius < h-8.0f ) continue;
- }
- else // rampant ?
- {
- if ( oPos.y-oRadius > h+8.0f ) continue;
- }
-
- BitmapSetCircle(oPos, oRadius+iRadius+4.0f);
- }
- }
-}
-
-// Ajoute une portion de terrain dans le bitmap.
-
-void CTaskGoto::BitmapTerrain(const D3DVECTOR &min, const D3DVECTOR &max)
-{
- int minx, miny, maxx, maxy;
-
- minx = (int)((min.x+1600.0f)/BM_DIM_STEP);
- miny = (int)((min.z+1600.0f)/BM_DIM_STEP);
- maxx = (int)((max.x+1600.0f)/BM_DIM_STEP);
- maxy = (int)((max.z+1600.0f)/BM_DIM_STEP);
-
- BitmapTerrain(minx, miny, maxx, maxy);
-}
-
-// Ajoute une portion de terrain dans le bitmap.
-
-void CTaskGoto::BitmapTerrain(int minx, int miny, int maxx, int maxy)
-{
- ObjectType type;
- D3DVECTOR p;
- float aLimit, angle, h;
- int x, y;
- BOOL bAcceptWater, bFly;
-
- if ( minx > maxx ) Swap(minx, maxx);
- if ( miny > maxy ) Swap(miny, maxy);
-
- if ( minx < 0 ) minx = 0;
- if ( miny < 0 ) miny = 0;
- if ( maxx > m_bmSize-1 ) maxx = m_bmSize-1;
- if ( maxy > m_bmSize-1 ) maxy = m_bmSize-1;
-
- if ( minx > m_bmMinX ) minx = m_bmMinX;
- if ( miny > m_bmMinY ) miny = m_bmMinY;
- if ( maxx < m_bmMaxX ) maxx = m_bmMaxX;
- if ( maxy < m_bmMaxY ) maxy = m_bmMaxY;
-
- if ( minx >= m_bmMinX && maxx <= m_bmMaxX &&
- miny >= m_bmMinY && maxy <= m_bmMaxY ) return;
-
- aLimit = 20.0f*PI/180.0f;
- bAcceptWater = FALSE;
- bFly = FALSE;
-
- type = m_object->RetType();
-
- if ( type == OBJECT_MOBILEwa ||
- type == OBJECT_MOBILEwc ||
- type == OBJECT_MOBILEws ||
- type == OBJECT_MOBILEwi ||
- type == OBJECT_MOBILEwt ||
- type == OBJECT_MOBILEtg ) // roues ?
- {
- aLimit = 20.0f*PI/180.0f;
- }
-
- if ( type == OBJECT_MOBILEta ||
- type == OBJECT_MOBILEtc ||
- type == OBJECT_MOBILEti ||
- type == OBJECT_MOBILEts ) // chenilles ?
- {
- aLimit = 35.0f*PI/180.0f;
- }
-
- if ( type == OBJECT_MOBILErt ||
- type == OBJECT_MOBILErc ||
- type == OBJECT_MOBILErr ||
- type == OBJECT_MOBILErs ) // grosses chenilles ?
- {
- aLimit = 35.0f*PI/180.0f;
- }
-
- if ( type == OBJECT_MOBILEsa ) // chenilles sous-marin ?
- {
- aLimit = 35.0f*PI/180.0f;
- bAcceptWater = TRUE;
- }
-
- if ( type == OBJECT_MOBILEfa ||
- type == OBJECT_MOBILEfc ||
- type == OBJECT_MOBILEfs ||
- type == OBJECT_MOBILEfi ||
- type == OBJECT_MOBILEft ) // volant ?
- {
- aLimit = 15.0f*PI/180.0f;
- bFly = TRUE;
- }
-
- if ( type == OBJECT_MOBILEia ||
- type == OBJECT_MOBILEic ||
- type == OBJECT_MOBILEis ||
- type == OBJECT_MOBILEii ) // pattes d'insecte ?
- {
- aLimit = 60.0f*PI/180.0f;
- }
-
- for ( y=miny ; y<=maxy ; y++ )
- {
- for ( x=minx ; x<=maxx ; x++ )
- {
- if ( x >= m_bmMinX && x <= m_bmMaxX &&
- y >= m_bmMinY && y <= m_bmMaxY ) continue;
-
- p.x = x*BM_DIM_STEP-1600.0f;
- p.z = y*BM_DIM_STEP-1600.0f;
-
- if ( bFly ) // robot volant ?
- {
- h = m_terrain->RetFloorLevel(p, TRUE);
- if ( h >= m_terrain->RetFlyingMaxHeight()-5.0f )
- {
- BitmapSetDot(0, x, y);
- }
- continue;
- }
-
- if ( !bAcceptWater ) // ne va pas sous l'eau ?
- {
- h = m_terrain->RetFloorLevel(p, TRUE);
-//? if ( h <= m_water->RetLevel()+1.0f ) // sous l'eau ?
- if ( h < m_water->RetLevel()-2.0f ) // sous l'eau ?
- {
-//? BitmapSetDot(0, x, y);
- BitmapSetCircle(p, BM_DIM_STEP*1.0f);
- continue;
- }
- }
-
- angle = m_terrain->RetFineSlope(p);
- if ( angle > aLimit )
- {
- BitmapSetDot(0, x, y);
- }
- }
- }
-
- m_bmMinX = minx;
- m_bmMinY = miny;
- m_bmMaxX = maxx;
- m_bmMaxY = maxy;
-}
-
-// Ouvre un bitmap vide.
-
-BOOL CTaskGoto::BitmapOpen()
-{
- BitmapClose();
-
- m_bmSize = (int)(3200.0f/BM_DIM_STEP);
- m_bmArray = (unsigned char*)malloc(m_bmSize*m_bmSize/8*2);
- ZeroMemory(m_bmArray, m_bmSize*m_bmSize/8*2);
-
- m_bmOffset = m_bmSize/2;
- m_bmLine = m_bmSize/8;
-
- m_bmMinX = m_bmSize;
- m_bmMinY = m_bmSize;
- m_bmMaxX = 0;
- m_bmMaxY = 0;
-
- return TRUE;
-}
-
-// Ferme le bitmap.
-
-BOOL CTaskGoto::BitmapClose()
-{
- free(m_bmArray);
- m_bmArray = 0;
- return TRUE;
-}
-
-// Met un cercle dans le bitmap.
-
-void CTaskGoto::BitmapSetCircle(const D3DVECTOR &pos, float radius)
-{
- float d, r;
- int cx, cy, ix, iy;
-
- cx = (int)((pos.x+1600.0f)/BM_DIM_STEP);
- cy = (int)((pos.z+1600.0f)/BM_DIM_STEP);
- r = radius/BM_DIM_STEP;
-
- for ( iy=cy-(int)r ; iy<=cy+(int)r ; iy++ )
- {
- for ( ix=cx-(int)r ; ix<=cx+(int)r ; ix++ )
- {
- d = Length((float)(ix-cx), (float)(iy-cy));
- if ( d > r ) continue;
- BitmapSetDot(0, ix, iy);
- }
- }
-}
-
-// Met un point dans le bitmap.
-// x:y: 0..m_bmSize-1
-
-void CTaskGoto::BitmapSetDot(int rank, int x, int y)
-{
- if ( x < 0 || x >= m_bmSize ||
- y < 0 || y >= m_bmSize ) return;
-
- m_bmArray[rank*m_bmLine*m_bmSize + m_bmLine*y + x/8] |= (1<<x%8);
-}
-
-// Teste un point dans le bitmap.
-// x:y: 0..m_bmSize-1
-
-BOOL CTaskGoto::BitmapTestDot(int rank, int x, int y)
-{
- if ( x < 0 || x >= m_bmSize ||
- y < 0 || y >= m_bmSize ) return FALSE;
-
- if ( x < m_bmMinX || x > m_bmMaxX ||
- y < m_bmMinY || y > m_bmMaxY )
- {
- BitmapTerrain(x-10,y-10, x+10,y+10); // refait une couche
- }
-
- return m_bmArray[rank*m_bmLine*m_bmSize + m_bmLine*y + x/8] & (1<<x%8);
-}
-
-