1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "fx_manager.h"
26 #include "ingame_database_manager.h"
27 #include "pacs_client.h"
29 #include "debug_client.h"
30 #include "client_sheets/fx_sheet.h"
32 #include "nel/3d/u_driver.h"
33 #include "nel/3d/u_scene.h"
34 #include "nel/misc/path.h"
37 using namespace NLMISC
;
43 extern UDriver
*Driver
;
49 CFxCL::CFxCL() : CEntityCL(), _FXSheet(NULL
), _BadBuild(false)
59 * Initialize the Object with this function for all constructors.
70 * Build the entity from a sheet.
72 bool CFxCL::build( const CEntitySheet
*sheet
)
76 // Get the FX filename and user params from the sheet (only the first one of PSList)
77 _FXSheet
= dynamic_cast<const CFXSheet
*>(sheet
);
78 if ( (! _FXSheet
) || (_FXSheet
->PSList
.empty()) )
81 nlwarning( "Bad sheet %s for fx", sheet
? sheet
->Id
.toString().c_str() : "NULL" );
88 if(IngameDbMngr
.getNodePtr())
90 CCDBNodeBranch
*nodeRoot
= dynamic_cast<CCDBNodeBranch
*>(IngameDbMngr
.getNodePtr()->getNode(0));
93 _DBEntry
= dynamic_cast<CCDBNodeBranch
*>(nodeRoot
->getNode(_Slot
));
95 pushDebugStr("Cannot get a pointer on the DB entry.");
106 * Initialize properties of the entity (according to the class).
108 bool CFxCL::setFx( const std::string
&fileName
)
111 // Delete the old _Instance if needed
112 if(!_Instance
.empty())
115 Scene
->deleteInstance(_Instance
);
119 // Create the FX object and insert it into the scene
120 _Instance
= Scene
->createInstance( fileName
);
121 UParticleSystemInstance fxInst
;
122 fxInst
.cast (_Instance
);
125 Scene
->deleteInstance( _Instance
);
127 nlwarning( "FX file '%s' not found.", fileName
.c_str()) ;
136 * Update the item position.
138 void CFxCL::updateVisualPropertyPos(const NLMISC::TGameCycle
&/* gameCycle */, const sint64
&prop
, const NLMISC::TGameCycle
&/* pI */)
141 // Check the DB entry (the warning is already done in the build method).
144 // Get The property 'Y'.
145 CCDBNodeLeaf
*nodeY
= dynamic_cast<CCDBNodeLeaf
*>(_DBEntry
->getNode(CLFECOMMON::PROPERTY_POSY
));
148 nlwarning("ITM:updtVPPos:%d: Cannot find the property 'PROPERTY_POSY(%d)'.", _Slot
, CLFECOMMON::PROPERTY_POSY
);
151 // Get The property 'Z'.
152 CCDBNodeLeaf
*nodeZ
= dynamic_cast<CCDBNodeLeaf
*>(_DBEntry
->getNode(CLFECOMMON::PROPERTY_POSZ
));
155 nlwarning("ITM:updtVPPos:%d: Cannot find the property 'PROPERTY_POSZ(%d)'.", _Slot
, CLFECOMMON::PROPERTY_POSZ
);
158 // Insert the primitive into the world.
160 _Primitive
->insertInWorldImage(dynamicWI
);
162 // Set the primitive position and snap the entity to the ground.
163 CVectorD
requestedPos( (float)(prop
)/1000.0f
,
164 (float)(nodeY
->getValue64())/1000.0f
,
165 (float)(nodeZ
->getValue64())/1000.0f
);
166 pacsPos( requestedPos
);
169 // Set normal mode and unflag _FirsPos to prevent the fx to be clipped out
170 _Mode
= MBEHAV::NORMAL
;
173 if (_BadBuild
) return;
175 if (_Instance
.empty())
177 if ( ! setFx( _FXSheet
->PSList
[0].PSName
) )
182 UParticleSystemInstance fxInst
;
183 fxInst
.cast (_Instance
);
184 fxInst
.setUserParam( 0, _FXSheet
->PSList
[0].Power
[CFXSheet::CPSStruct::StandardIndex
].UserParam0
);
185 fxInst
.setUserParam( 1, _FXSheet
->PSList
[0].Power
[CFXSheet::CPSStruct::StandardIndex
].UserParam1
);
190 // Change the instance position.
191 if (!_Instance
.empty())
194 _Instance
.getPos(prevPos
);
195 _Instance
.setPos( pos() );
196 UParticleSystemInstance fxInst
;
197 fxInst
.cast (_Instance
);
198 fxInst
.getShapeAABBox( _SelectBox
);
199 _SelectBox
.setCenter( pos() + _SelectBox
.getCenter() );
200 //nldebug( "SelectBox: %s %s", _SelectBox.getCenter().asString().c_str(), _SelectBox.getHalfSize().asString().c_str() );
202 // Adjust the collision.
205 _Primitive
->setRadius(std::min(std::max((_SelectBox
.getHalfSize()).x
, (_SelectBox
.getHalfSize()).y
), (float)(RYZOM_ENTITY_SIZE_MAX
/2)));
206 _Primitive
->setHeight((_SelectBox
.getHalfSize()).z
);
209 if (_Instance
.getPos() != prevPos
)
211 // a move or init occurred -> must update cluster system
212 UGlobalPosition gPos
;
215 _Primitive
->getGlobalPosition(gPos
, dynamicWI
);
219 GR
->retrievePosition(pos());
221 UInstanceGroup
*clusterSystem
= getCluster(gPos
);
222 _Instance
.setClusterSystem(clusterSystem
);
233 * Update the position of the entity after the motion.
235 /*void CFxCL::updatePos( const NLMISC::TTime &time, CEntityCL *target )
237 CEntityCL::updatePos( time, target );
240 * updateDisplay : get the entity position and set all visual stuff with it.
242 /*void CFxCL::updateVisible( const NLMISC::TTime &time, CEntityCL *target )
244 CEntityCL::updateVisible( time, target );
249 * Draw the selection Box.
251 void CFxCL::drawBox()
253 ::drawBox(selectBox().getMin(), selectBox().getMax(), CRGBA(250,250,0));
263 if (_Instance
.empty())
267 UParticleSystemInstance fxInst
;
268 fxInst
.cast (_Instance
);
269 if (!fxInst
.removeByID(NELID("STOP")) && !fxInst
.removeByID(NELID("main")))
271 fxInst
.activateEmitters( false );
274 // Delegate the clean removal of the fx to the fx manager
275 FXMngr
.fx2remove( fxInst
);
276 // The fx manager now has ownership on the fx, so set the pointer to NULL,
277 // (otherwise it is delete in CentityCL dtor)