/* Autor: Leandro Bernsmuller
Possui as acoes comuns a todos os agentes interventores.
Esta classe apenas tem utilidade se especializada. */



#include <windows.h>
#include <windowsx.h>
#include <ddraw.h>
#include <d3drmwin.h>
#include "..\..\..\princip\defs.h"
#include "..\..\..\cenario\cenario.h"
#include "..\..\..\cenario\cenfis.h"
#include "..\acao.h"
#include "..\..\dados\dados.h"
#include "..\..\dados\dadosfis.h"
#include "..\..\agente.h"
#include "interv.h"



/* construtor
**********************************************************/
CIntervir::CIntervir ()
{
   m_dwTipoAcao = ID_ACAO_INTERVIR;
   m_fPassou = 0;
   m_dwBordaRemove = 0;
   m_fDirecaoX = 1;
   m_fDirecaoY = 0;

   // originalmente nao muda fome dos agentes
   for ( int ncT = 0; ncT < NUM_MODELOS + NUM_MODELOS_ESP; ncT ++ )
      m_afTaxasFome [ ncT ] = 0;
}

   

/* Testa colisao com o cenario
pFlagColisao - indica onde colidiu:
**********************************************************/
void CIntervir::mTestaColisao ( PTRVAL pFlagColisao )
{
   // verifica os flags de colisao com o cenario
   // borda direita - 8, esquerda - 4, inferior - 2, superior - 1
   // Se colidiu deve remover agente
   if ( pFlagColisao & m_dwBordaRemove )
      // substitui atividade 1 pela acao de morrer
      m_poMeuAgente->mPreparaSubstituirPos ( NDX_EVENTO_ATIVIDADE_1, ID_ACAO_MORRE, ID_ACAO_MORRE );
}

   

/* Remove energia dos elementos do cenario, se jah nao removeu
**********************************************************/
void CIntervir::mRemoveEnergia ()
{
   CDadosFisicos
      *poDados = (CDadosFisicos*) m_poMeuAgente->m_poDados;

   // remove energia dos elementos do cenario conforme especificado
   for ( int  ncA = 0; ncA < MAX_AGENTES; ncA ++ ) {

      // pega dados de um agente
      CDados
         *poDadosAg = (CDados*) m_poMeuAgente->m_paoOsAgentes [ ncA ].m_poDados;

      // se nao tem informacoes fisicas, ignora ocorrencia
      if ( poDadosAg != NULL && poDadosAg->m_dwTipoDado == TIPO_FISICO ) {

         // tenta acessar dados fisicos
         CDadosFisicos
            *poDadosFisicosAg = (CDadosFisicos*) poDadosAg;

         // retira energia do organismo ("tantos porcento")

         // qual taxa usar
         int
            nNdx = poDadosFisicosAg->m_dwTipoCorpo;
         if ( nNdx > NUM_MODELOS )   // se indicar modelo invisivel
            nNdx = NUM_MODELOS + nNdx - NDX_MODELO_NULO - 1 - 1;

         // altera fome
         poDadosFisicosAg->m_fFome += ( TX_MORRE_FOME - TX_INICIAL_FOME ) * m_afTaxasFome [ nNdx ];
      }
   }
}

   

/* Anima
**********************************************************/
void CIntervir::mAnimaInterventor ()
{
   CDadosFisicos
      *poDados = (CDadosFisicos*) m_poMeuAgente->m_poDados;

   // atualiza direcao
   m_poMeuAgente->m_poCenario->mMudaDirecaoDeslocamentoObjeto ( poDados->m_dwGrupo, poDados->m_dwNdxObjeto, m_fDirecaoX, m_fDirecaoY, 0.0 );
}



/* Acao.
pDado1 - flags informando se colidiu com limites do cenario
         (ver cenfis.cpp, mDetectaColisaoComBordas)
pDado2 - 0 - testa colisao (de acordo com pDado1)
         1 - remove energia dos elementos do cenario
         2 - anima elemento interventor
return TRUE - certo / FALSE - erro
**********************************************************/
BOOL CIntervir::mAtiva ( PTRVAL pDado1, PTRVAL pDado2 )
{
   switch ( pDado2 ) {

      case 0:
         mTestaColisao ( pDado1 );
         break;

      case 1:
         mRemoveEnergia ();
         break;

      case 2:
         mAnimaInterventor ();
         break;
   }

   return TRUE;
}
