From a4c804b49ec872b71bd5a0167c3ad45704a3cc30 Mon Sep 17 00:00:00 2001 From: adiblol Date: Thu, 8 Mar 2012 19:32:05 +0100 Subject: Initial commit, Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch --- src/taskflag.cpp | 305 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 305 insertions(+) create mode 100644 src/taskflag.cpp (limited to 'src/taskflag.cpp') diff --git a/src/taskflag.cpp b/src/taskflag.cpp new file mode 100644 index 0000000..a475e67 --- /dev/null +++ b/src/taskflag.cpp @@ -0,0 +1,305 @@ +// taskflag.cpp + +#define STRICT +#define D3D_OVERLOADS + +#include +#include +#include + +#include "struct.h" +#include "D3DEngine.h" +#include "D3DMath.h" +#include "math3d.h" +#include "event.h" +#include "misc.h" +#include "iman.h" +#include "terrain.h" +#include "water.h" +#include "object.h" +#include "pyro.h" +#include "physics.h" +#include "brain.h" +#include "camera.h" +#include "motion.h" +#include "motionhuman.h" +#include "sound.h" +#include "task.h" +#include "taskflag.h" + + + + + +// Constructeur de l'objet. + +CTaskFlag::CTaskFlag(CInstanceManager* iMan, CObject* object) + : CTask(iMan, object) +{ + CTask::CTask(iMan, object); +} + +// Destructeur de l'objet. + +CTaskFlag::~CTaskFlag() +{ +} + + +// Gestion d'un événement. + +BOOL CTaskFlag::EventProcess(const Event &event) +{ + if ( m_bError ) return TRUE; + if ( m_engine->RetPause() ) return TRUE; + if ( event.event != EVENT_FRAME ) return TRUE; + + m_time += event.rTime; + + return TRUE; +} + + + +// Assigne le but à atteindre. + +Error CTaskFlag::Start(TaskFlagOrder order, int rank) +{ + D3DVECTOR pos, speed; + Error err; + + m_order = order; + m_time = 0.0f; + + m_bError = TRUE; // opération impossible + if ( !m_physics->RetLand() ) + { + pos = m_object->RetPosition(0); + if ( pos.y < m_water->RetLevel() ) return ERR_FLAG_WATER; + return ERR_FLAG_FLY; + } + + speed = m_physics->RetMotorSpeed(); + if ( speed.x != 0.0f || + speed.z != 0.0f ) return ERR_FLAG_MOTOR; + + if ( m_object->RetFret() != 0 ) return ERR_FLAG_BUSY; + + if ( order == TFL_CREATE ) + { + err = CreateFlag(rank); + if ( err != ERR_OK ) return err; + } + + if ( order == TFL_DELETE ) + { + err = DeleteFlag(); + if ( err != ERR_OK ) return err; + } + + m_bError = FALSE; + + m_motion->SetAction(MHS_FLAG); // met/enlève drapeau + m_camera->StartCentering(m_object, PI*0.3f, 99.9f, 0.0f, 0.5f); + + return ERR_OK; +} + +// Indique si l'action est terminée. + +Error CTaskFlag::IsEnded() +{ + if ( m_engine->RetPause() ) return ERR_CONTINUE; + + if ( m_bError ) return ERR_STOP; + if ( m_time < 2.0f ) return ERR_CONTINUE; + + Abort(); + return ERR_STOP; +} + +// Termine brutalement l'action en cours. + +BOOL CTaskFlag::Abort() +{ + m_motion->SetAction(-1); + m_camera->StopCentering(m_object, 2.0f); + return TRUE; +} + + + +// Retourne l'objet le plus proche d'une position donnée. + +CObject* CTaskFlag::SearchNearest(D3DVECTOR pos, ObjectType type) +{ + ObjectType oType; + CObject *pObj, *pBest; + D3DVECTOR oPos; + float min, dist; + int i; + + min = 100000.0f; + pBest = 0; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetEnable() ) continue; + + oType = pObj->RetType(); + if ( type == OBJECT_NULL ) + { + if ( oType != OBJECT_FLAGb && + oType != OBJECT_FLAGr && + oType != OBJECT_FLAGg && + oType != OBJECT_FLAGy && + oType != OBJECT_FLAGv ) continue; + } + else + { + if ( oType != type ) continue; + } + + oPos = pObj->RetPosition(0); + dist = Length2d(oPos, pos); + if ( dist < min ) + { + min = dist; + pBest = pObj; + } + } + return pBest; +} + +// Compte le nombre d'objets existants. + +int CTaskFlag::CountObject(ObjectType type) +{ + ObjectType oType; + CObject *pObj; + D3DVECTOR oPos; + int i, count; + + count = 0; + for ( i=0 ; i<1000000 ; i++ ) + { + pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + if ( pObj == 0 ) break; + + if ( !pObj->RetEnable() ) continue; + + oType = pObj->RetType(); + if ( type == OBJECT_NULL ) + { + if ( oType != OBJECT_FLAGb && + oType != OBJECT_FLAGr && + oType != OBJECT_FLAGg && + oType != OBJECT_FLAGy && + oType != OBJECT_FLAGv ) continue; + } + else + { + if ( oType != type ) continue; + } + + count ++; + } + return count; +} + +// Crée un indicateur de couleur. + +Error CTaskFlag::CreateFlag(int rank) +{ + CObject* pObj; + CObject* pNew; + CPyro* pyro; + D3DMATRIX* mat; + D3DVECTOR pos; + float dist; + int i; + + ObjectType table[5] = + { + OBJECT_FLAGb, + OBJECT_FLAGr, + OBJECT_FLAGg, + OBJECT_FLAGy, + OBJECT_FLAGv, + }; + + mat = m_object->RetWorldMatrix(0); + pos = Transform(*mat, D3DVECTOR(4.0f, 0.0f, 0.0f)); + + pObj = SearchNearest(pos, OBJECT_NULL); + if ( pObj != 0 ) + { + dist = Length(pos, pObj->RetPosition(0)); + if ( dist < 10.0f ) + { + return ERR_FLAG_PROXY; + } + } + + i = rank; + if ( CountObject(table[i]) >= 5 ) + { + return ERR_FLAG_CREATE; + } + + pNew = new CObject(m_iMan); + if ( !pNew->CreateFlag(pos, 0.0f, table[i]) ) + { + delete pNew; + return ERR_TOOMANY; + } + pNew->SetZoom(0, 0.0f); + + m_sound->Play(SOUND_WAYPOINT, pos); + pyro = new CPyro(m_iMan); + pyro->Create(PT_FLCREATE, pNew); + + return ERR_OK; +} + +// Supprime un indicateur de couleur. + +Error CTaskFlag::DeleteFlag() +{ + CObject* pObj; + CPyro* pyro; + D3DVECTOR iPos, oPos; + float iAngle, angle, aLimit, dist; + + iPos = m_object->RetPosition(0); + iAngle = m_object->RetAngleY(0); + iAngle = NormAngle(iAngle); // 0..2*PI + + pObj = SearchNearest(iPos, OBJECT_NULL); + if ( pObj == 0 ) + { + return ERR_FLAG_DELETE; + } + dist = Length(iPos, pObj->RetPosition(0)); + if ( dist > 10.0f ) + { + return ERR_FLAG_DELETE; + } + + oPos = pObj->RetPosition(0); + angle = RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! + aLimit = 45.0f*PI/180.0f; + if ( !TestAngle(angle, iAngle-aLimit, iAngle+aLimit) ) + { + return ERR_FLAG_DELETE; + } + + m_sound->Play(SOUND_WAYPOINT, iPos); + pyro = new CPyro(m_iMan); + pyro->Create(PT_FLDELETE, pObj); + + return ERR_OK; +} + -- cgit v1.2.3-1-g7c22