276 lines
6.9 KiB
C++
276 lines
6.9 KiB
C++
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
|
|
// Copyright (C) 2010 Winch Gate Property Limited
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as
|
|
// published by the Free Software Foundation, either version 3 of the
|
|
// License, or (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
#include "stdpch.h"
|
|
|
|
#include "fx_cl.h"
|
|
#include "fx_manager.h"
|
|
#include "ingame_database_manager.h"
|
|
#include "pacs_client.h"
|
|
#include "misc.h"
|
|
#include "debug_client.h"
|
|
#include "client_sheets/fx_sheet.h"
|
|
|
|
#include "nel/3d/u_driver.h"
|
|
#include "nel/3d/u_scene.h"
|
|
#include "nel/misc/path.h"
|
|
|
|
using namespace NL3D;
|
|
using namespace NLMISC;
|
|
|
|
|
|
////////////
|
|
// EXTERN //
|
|
////////////
|
|
extern UDriver *Driver;
|
|
extern UScene *Scene;
|
|
|
|
/*
|
|
* Constructor
|
|
*/
|
|
CFxCL::CFxCL() : CEntityCL(), _FXSheet(NULL), _BadBuild(false)
|
|
{
|
|
init();
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
* init :
|
|
* Initialize the Object with this function for all constructors.
|
|
*/
|
|
void CFxCL::init()
|
|
{
|
|
//_CrtCheckMemory();
|
|
CEntityCL::init();
|
|
//_CrtCheckMemory();
|
|
}
|
|
|
|
|
|
/*
|
|
* Build the entity from a sheet.
|
|
*/
|
|
bool CFxCL::build( const CEntitySheet *sheet )
|
|
{
|
|
//_CrtCheckMemory();
|
|
|
|
// Get the FX filename and user params from the sheet (only the first one of PSList)
|
|
_FXSheet = dynamic_cast<const CFXSheet*>(sheet);
|
|
if ( (! _FXSheet) || (_FXSheet->PSList.empty()) )
|
|
{
|
|
_BadBuild = true;
|
|
nlwarning( "Bad sheet %s for fx", sheet->Id.toString().c_str() );
|
|
return false;
|
|
}
|
|
|
|
// Base class init
|
|
initialize();
|
|
Type = Entity;
|
|
if(IngameDbMngr.getNodePtr())
|
|
{
|
|
CCDBNodeBranch *nodeRoot = dynamic_cast<CCDBNodeBranch *>(IngameDbMngr.getNodePtr()->getNode(0));
|
|
if(nodeRoot)
|
|
{
|
|
_DBEntry = dynamic_cast<CCDBNodeBranch *>(nodeRoot->getNode(_Slot));
|
|
if(_DBEntry == 0)
|
|
pushDebugStr("Cannot get a pointer on the DB entry.");
|
|
}
|
|
}
|
|
|
|
//_CrtCheckMemory();
|
|
return true;
|
|
}
|
|
|
|
|
|
/*
|
|
* setFx :
|
|
* Initialize properties of the entity (according to the class).
|
|
*/
|
|
bool CFxCL::setFx( const std::string &fileName )
|
|
{
|
|
//_CrtCheckMemory();
|
|
// Delete the old _Instance if needed
|
|
if(!_Instance.empty())
|
|
{
|
|
if ( Scene )
|
|
Scene->deleteInstance(_Instance);
|
|
_Instance = NULL;
|
|
}
|
|
|
|
// Create the FX object and insert it into the scene
|
|
_Instance = Scene->createInstance( fileName );
|
|
UParticleSystemInstance fxInst;
|
|
fxInst.cast (_Instance);
|
|
if (fxInst.empty())
|
|
{
|
|
Scene->deleteInstance( _Instance );
|
|
_Instance = NULL;
|
|
nlwarning( "FX file '%s' not found.", fileName.c_str()) ;
|
|
return false;
|
|
}
|
|
//_CrtCheckMemory();
|
|
return true;
|
|
}
|
|
|
|
|
|
/*
|
|
* Update the item position.
|
|
*/
|
|
void CFxCL::updateVisualPropertyPos(const NLMISC::TGameCycle &/* gameCycle */, const sint64 &prop, const NLMISC::TGameCycle &/* pI */)
|
|
{
|
|
//_CrtCheckMemory();
|
|
// Check the DB entry (the warning is already done in the build method).
|
|
if(_DBEntry == 0)
|
|
return;
|
|
// Get The property 'Y'.
|
|
CCDBNodeLeaf *nodeY = dynamic_cast<CCDBNodeLeaf *>(_DBEntry->getNode(CLFECOMMON::PROPERTY_POSY));
|
|
if(nodeY == 0)
|
|
{
|
|
nlwarning("ITM:updtVPPos:%d: Cannot find the property 'PROPERTY_POSY(%d)'.", _Slot, CLFECOMMON::PROPERTY_POSY);
|
|
return;
|
|
}
|
|
// Get The property 'Z'.
|
|
CCDBNodeLeaf *nodeZ = dynamic_cast<CCDBNodeLeaf *>(_DBEntry->getNode(CLFECOMMON::PROPERTY_POSZ));
|
|
if(nodeZ == 0)
|
|
{
|
|
nlwarning("ITM:updtVPPos:%d: Cannot find the property 'PROPERTY_POSZ(%d)'.", _Slot, CLFECOMMON::PROPERTY_POSZ);
|
|
return;
|
|
}
|
|
// Insert the primitive into the world.
|
|
if(_Primitive)
|
|
_Primitive->insertInWorldImage(dynamicWI);
|
|
|
|
// Set the primitive position and snap the entity to the ground.
|
|
CVectorD requestedPos( (float)(prop)/1000.0f,
|
|
(float)(nodeY->getValue64())/1000.0f,
|
|
(float)(nodeZ->getValue64())/1000.0f );
|
|
pacsPos( requestedPos );
|
|
snapToGround();
|
|
|
|
// Set normal mode and unflag _FirsPos to prevent the fx to be clipped out
|
|
_Mode = MBEHAV::NORMAL;
|
|
_First_Pos = false;
|
|
|
|
if (_BadBuild) return;
|
|
|
|
if (_Instance.empty())
|
|
{
|
|
if ( ! setFx( _FXSheet->PSList[0].PSName ) )
|
|
{
|
|
_BadBuild = true;
|
|
return;
|
|
}
|
|
UParticleSystemInstance fxInst;
|
|
fxInst.cast (_Instance);
|
|
fxInst.setUserParam( 0, _FXSheet->PSList[0].Power[CFXSheet::CPSStruct::StandardIndex].UserParam0 );
|
|
fxInst.setUserParam( 1, _FXSheet->PSList[0].Power[CFXSheet::CPSStruct::StandardIndex].UserParam1 );
|
|
|
|
|
|
}
|
|
|
|
// Change the instance position.
|
|
if (!_Instance.empty())
|
|
{
|
|
CVector prevPos;
|
|
_Instance.getPos(prevPos);
|
|
_Instance.setPos( pos() );
|
|
UParticleSystemInstance fxInst;
|
|
fxInst.cast (_Instance);
|
|
fxInst.getShapeAABBox( _SelectBox );
|
|
_SelectBox.setCenter( pos() + _SelectBox.getCenter() );
|
|
//nldebug( "SelectBox: %s %s", _SelectBox.getCenter().asString().c_str(), _SelectBox.getHalfSize().asString().c_str() );
|
|
|
|
// Adjust the collision.
|
|
if( _Primitive )
|
|
{
|
|
_Primitive->setRadius(std::min(std::max((_SelectBox.getHalfSize()).x, (_SelectBox.getHalfSize()).y), (float)(RYZOM_ENTITY_SIZE_MAX/2)));
|
|
_Primitive->setHeight((_SelectBox.getHalfSize()).z);
|
|
}
|
|
|
|
if (_Instance.getPos() != prevPos)
|
|
{
|
|
// a move or init occured -> must update cluster system
|
|
UGlobalPosition gPos;
|
|
if( _Primitive )
|
|
{
|
|
_Primitive->getGlobalPosition(gPos, dynamicWI);
|
|
}
|
|
else
|
|
{
|
|
GR->retrievePosition(pos());
|
|
}
|
|
UInstanceGroup *clusterSystem = getCluster(gPos);
|
|
_Instance.setClusterSystem(clusterSystem);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
//_CrtCheckMemory();
|
|
}
|
|
|
|
|
|
/*
|
|
* Update the position of the entity after the motion.
|
|
*/
|
|
/*void CFxCL::updatePos( const NLMISC::TTime &time, CEntityCL *target )
|
|
{
|
|
CEntityCL::updatePos( time, target );
|
|
}*/
|
|
/*
|
|
* updateDisplay : get the entity position and set all visual stuff with it.
|
|
*/
|
|
/*void CFxCL::updateVisible( const NLMISC::TTime &time, CEntityCL *target )
|
|
{
|
|
CEntityCL::updateVisible( time, target );
|
|
}*/
|
|
|
|
|
|
/*
|
|
* Draw the selection Box.
|
|
*/
|
|
void CFxCL::drawBox()
|
|
{
|
|
::drawBox(selectBox().getMin(), selectBox().getMax(), CRGBA(250,250,0));
|
|
}// drawBox //
|
|
|
|
|
|
/*
|
|
* Destructor
|
|
*/
|
|
CFxCL::~CFxCL()
|
|
{
|
|
//_CrtCheckMemory();
|
|
if (_Instance.empty())
|
|
return;
|
|
|
|
// Stop emitters
|
|
UParticleSystemInstance fxInst;
|
|
fxInst.cast (_Instance);
|
|
if (!fxInst.removeByID( 'STOP' ) && !fxInst.removeByID( 'main' ) )
|
|
{
|
|
fxInst.activateEmitters( false );
|
|
}
|
|
|
|
// Delegate the clean removal of the fx to the fx manager
|
|
FXMngr.fx2remove( fxInst );
|
|
// The fx manager now has ownership on the fx, so set the pointer to NULL,
|
|
// (otherwise it is delete in CentityCL dtor)
|
|
_Instance = NULL;
|
|
}
|