00001
00002 #include "cerberus.h"
00003 #include "entities.h"
00004
00005
00009 bool cEntityBase::createEntity( eEntity entityType )
00010 {
00011
00012 if( (getType() != eElement) && (getType() != eBoulder) )
00013 return false;
00014
00015
00016 if( getNextEntity() )
00017 return false;
00018
00019
00020 if( (getType() == eElement) && !(((cElement*)this)->isFlat()) )
00021 return false;
00022
00023 cEntity* entity;
00024 switch( entityType ) {
00025 case eTree:
00026 {
00027 entity = new cEntity( eTree, mWorld, mDevice );
00028 scene::IAnimatedMeshSceneNode* Node=mDevice->getSceneManager()->addAnimatedMeshSceneNode( mWorld->getTreeMesh(), mWorld->getNode() );
00029 if( Node ) {
00030 Node->setMaterialFlag( video::EMF_LIGHTING, false );
00031 Node->setPosition( core::vector3df(mIndexI+0.5, mGroundLevel+mHeight, mIndexJ+0.5) );
00032 Node->setRotation( core::vector3df(0.0, mWorld->getRandomNumber()*360.0, 0.0) );
00033 entity->setNode( Node );
00034 entity->setIndex( mIndexI, mIndexJ );
00035 entity->setHeight( 1.767767 );
00036 entity->setGroundLevel( mGroundLevel+mHeight );
00037 setNextEntity( entity );
00038 entity->setPreviousEntity( this );
00039 } else {
00040 fprintf( stdout, "couldn't allocate tree" );
00041 }
00042 }
00043 break;
00044 case eBoulder:
00045 {
00046 entity = new cEntity( eBoulder, mWorld, mDevice );
00047 scene::IAnimatedMeshSceneNode* Node=mDevice->getSceneManager()->addAnimatedMeshSceneNode( mWorld->getBoulderMesh(), mWorld->getNode() );
00048 if( Node ) {
00049 Node->setMaterialFlag( video::EMF_LIGHTING, false );
00050 Node->setPosition( core::vector3df(mIndexI+0.5, mGroundLevel+mHeight, mIndexJ+0.5) );
00051 Node->setRotation( core::vector3df(0.0, mWorld->getRandomNumber()*360.0, 0.0) );
00052 entity->setNode( Node );
00053 entity->setIndex( mIndexI, mIndexJ );
00054 entity->setHeight( 1.0/sqrt(2.0) );
00055 entity->setGroundLevel( mGroundLevel+mHeight );
00056 setNextEntity( entity );
00057 entity->setPreviousEntity( this );
00058 scene::ITriangleSelector* entitySelector =
00059 mWorld->getSceneManager()->createTriangleSelector( mWorld->getBoulderMesh(), Node );
00060 Node->setTriangleSelector( entitySelector );
00061 entitySelector->drop();
00062 } else {
00063 fprintf( stdout, "couldn't allocate tree" );
00064 }
00065 }
00066 break;
00067 case eRobot:
00068 {
00069 entity = new cEntity( eRobot, mWorld, mDevice );
00070 scene::IAnimatedMeshSceneNode* Node=mDevice->getSceneManager()->addAnimatedMeshSceneNode( mWorld->getRobotMesh(), mWorld->getNode() );
00071 if( Node ) {
00072 Node->setMaterialFlag( video::EMF_LIGHTING, false );
00073 Node->setPosition( core::vector3df(mIndexI+0.5, mGroundLevel+mHeight, mIndexJ+0.5) );
00074 core::vector3df diffVector=mWorld->getSoul()->getPosition()-Node->getPosition();
00075 Node->setRotation( core::vector3df(0.0, 180.0-atan2( diffVector.Z, diffVector.X )*180.0/core::PI, 0.0) );
00076 entity->setNode( Node );
00077 entity->setIndex( mIndexI, mIndexJ );
00078 entity->setHeight( 1.072501 );
00079 entity->setGroundLevel( mGroundLevel+mHeight );
00080 setNextEntity( entity );
00081 entity->setPreviousEntity( this );
00082 } else {
00083 fprintf( stdout, "couldn't allocate robot" );
00084 }
00085 }
00086 break;
00087 default:
00088 return NULL;
00089 }
00090
00091 return true;
00092 }
00093
00094
00095 int cEntityBase::getEnergy()
00096 {
00097 int energy;
00098
00099 switch( mType )
00100 {
00101 case eTree: energy = eTreeNrg; break;
00102 case eBoulder: energy = eBoulderNrg; break;
00103 case eRobot: energy = eRobotNrg; break;
00104 default: energy = 0; break;
00105 }
00106
00107 return energy;
00108 }
00109
00113 cEntity::cEntity( eEntity type, cWorld* world, IrrlichtDevice* device ) :
00114 cEntityBase( type, world, device ), mNode( NULL )
00115 {
00116 }
00117
00118
00122 cEntity::~cEntity()
00123 {
00124 if( mNode )
00125 mNode->remove();
00126 }
00127
00128
00132 cElement::cElement( cWorld* world, IrrlichtDevice* device ) : cEntityBase( eElement, world, device )
00133 {
00134 setIndex( 0, 0 );
00135 mLevel=0;
00136 mHeight = 0;
00137 mGroundLevel = 0.0;
00138
00139 mNode=NULL;
00140 mFlat=false;
00141
00142 mLogger = mDevice->getLogger();
00143 }
00144
00145
00149 cElement::~cElement()
00150 {
00151
00152 cEntityBase* entity = getNextEntity();
00153 while( entity ) {
00154 cEntityBase* temp = entity->getNextEntity();
00155 delete entity;
00156 entity = temp;
00157 }
00158 setNextEntity( NULL );
00159
00160 if( mNode )
00161 mNode->remove();
00162 }
00163
00164
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00183 cSoul::cSoul( scene::ICameraSceneNode* camera ) : mCamera( camera ), mTheta( core::PI/2.0 ),
00184 mThetaMin( 2.0f/180.0f*core::PI ), mThetaMax( 178.0f/180.0f*core::PI )
00185 {
00186
00187 mRotateSpeed=1.0f;
00188 mCamera->setNearValue( 0.1f );
00189 mCamera->setFarValue( 12000.0f );
00190
00191
00192 mEnergy = 7;
00193
00194
00195 mPhi=atan2( (double)(16-mIndexJ), (double)(16-mIndexI) );
00196
00197
00198 updateView();
00199 }
00200
00201
00205 void cSoul::updateView()
00206 {
00207 mCamera->setPosition( core::vector3df( mIndexI+0.5, mGroundLevel+1.0, mIndexJ+0.5 ) );
00208 mCamera->setTarget( mCamera->getPosition() +
00209 core::vector3df(cos(mPhi)*sin(mTheta), cos(mTheta), sin(mPhi)*sin(mTheta)) );
00210 mCamera->setUpVector( core::vector3df(-cos(mPhi)*cos(mTheta), sin(mTheta), -sin(mPhi)*cos(mTheta)) );
00211 }
00212
00213
00217 void cSoul::setTarget( core::vector3df target )
00218 {
00219 core::vector3df diffVector=target-getPosition();
00220
00221 mPhi=atan2( diffVector.Z, diffVector.X );
00222 mTheta=atan2( sqrt(diffVector.X*diffVector.X+diffVector.Z*diffVector.Z), diffVector.Y );
00223 }
00224
00225
00229 void cSoul::changeView( f32 px, f32 py )
00230 {
00231
00232 mPhi -= px*mRotateSpeed;
00233 mTheta += py*mRotateSpeed;
00234 if( mTheta<mThetaMin ) mTheta=mThetaMin;
00235 if( mTheta>mThetaMax ) mTheta=mThetaMax;
00236 if( mPhi<0.0 ) mPhi+=2.0f*core::PI;
00237 if( mPhi>2*core::PI ) mPhi-=2.0f*core::PI;
00238
00239 updateView();
00240 }
00241
00242
00246 void cSoul::turnAround()
00247 {
00248
00249 mPhi += core::PI;
00250 if( mPhi>2*core::PI ) mPhi-=2.0f*core::PI;
00251 mTheta = core::PI/2;
00252
00253 updateView();
00254 }
00255
00256
00265 bool cSoul::substractFromEnergy( int sub )
00266 {
00267 mEnergy -= sub;
00268
00269 if( mEnergy<=0 )
00270 return false;
00271
00272 return true;
00273 }