Resolve "Toggle Free Look with Hotkey"
[ryzomcore.git] / ryzom / server / src / sabrina / magic_action.h
blobd5c31632c3db7b3c4c3e1401e3d8192d8df42afe
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #ifndef RY_MAGIC_ACTION_H
20 #define RY_MAGIC_ACTION_H
22 #include "nel/misc/types_nl.h"
23 #include "game_share/brick_families.h"
24 #include "game_share/egs_sheets/egs_sheets.h"
25 #include "game_share/mode_and_behaviour.h"
26 #include "phrase_utilities_functions.h"
28 class CMagicPhrase;
29 extern NLMISC::CRandom RandomGenerator;
32 /// Macro used to declare a Sabrina Magic action ( i.e. : effects represented by active bricks in a spell )
33 #define BEGIN_MAGIC_ACTION_FACTORY(_class_) \
34 class _class_##Factory : public IMagicActionFactory \
36 public:\
37 _class_##Factory()\
39 IMagicActionFactory::init(); \
41 #define ADD_MAGIC_ACTION_TYPE(_type_)\
42 for (uint i = 0; i < Factories->size(); i++ )\
44 if ( (*Factories)[i].first == _type_ )\
46 nlstop;\
49 Factories->push_back(std::make_pair( std::string(_type_) ,this));
51 #define END_MAGIC_ACTION_FACTORY(_class_) \
52 };\
53 IMagicAction * build( const TDataSetRow & actorRowId, const std::vector< const CStaticBrick* >& bricks, uint & brickIndex, CMagicPhrase * phrase )\
55 _class_ *inst = new _class_;\
56 if ( !inst->build( actorRowId, bricks, brickIndex, phrase ) ){delete inst;return NULL;} \
57 return inst;\
59 };\
60 _class_##Factory* _class_##FactoryInstance = new _class_##Factory;
63 /**
64 * Interface for magic actions
65 * \author Nicolas Brigand
66 * \author Nevrax France
67 * \date 2003
69 class IMagicAction
71 public:
73 /// build the action basic params, the call the addBrick virtual method to retrieve the specific params
74 bool build( const TDataSetRow & actorRowId, const std::vector< const CStaticBrick* >& bricks, uint & index, CMagicPhrase* phrase )
76 // get the skill
77 if ( ! bricks.empty() )
79 _Skill = bricks[index]->Skill;
80 if ( _Skill == SKILLS::unknown )
82 uint idx = index;
83 nlwarning( "<IMagicAction build> invalid skill in brick %s. We will iterate backwards through the brick queue to get a skill",bricks[index]->SheetId.toString().c_str() );
84 while ( _Skill == SKILLS::unknown && idx > 0 )
85 _Skill = bricks[idx--]->Skill;
86 if ( _Skill == SKILLS::unknown)
88 nlwarning( "<IMagicAction build> no valid skill found in brick %s.",bricks[idx]->SheetId.toString().c_str() );
89 return false;
93 else
95 nlwarning("<IMagicAction build> no brick in action...");
96 return false;
98 while(1)
100 if ( index >= bricks.size() )
102 nlwarning("<IMagicAction build> index %u > bricks.size() %u",index, bricks.size());
103 break;
105 if ( !bricks[index] )
107 nlwarning("<IMagicAction build> index %u> bricks.size() %u",index, bricks.size());
108 break;
110 INFOLOG("IN MAGIC ACTIOND : Parsing brick index %u value %s",index,bricks[index]->SheetId.toString().c_str() );
112 bool end = false;;
113 if ( !addBrick( *bricks[index], phrase,end ) )
114 return false;
115 index++;
116 if ( end )
117 break;
119 return true;
121 ///\name virtual action methods
122 //@{
123 /// validate the action
124 virtual bool validate(CMagicPhrase * phrase) = 0;
125 /// apply the action
126 virtual void apply( CMagicPhrase * phrase, float successFactor,MBEHAV::CBehaviour & behav, bool isMad ) = 0;
127 /// add a brick to build the action
128 virtual bool addBrick( const CStaticBrick & brick, CMagicPhrase * phrase, bool &effectEnd ) = 0;
129 //@}
130 protected:
131 /// the skill used in that action
132 SKILLS::ESkills _Skill;
136 * class factory for sabrina Magic Effect
137 * \author Nicolas Brigand
138 * \author Nevrax France
139 * \date 2003
141 class IMagicActionFactory
143 public:
144 /// clear the class factory
145 static void clear();
148 * Build the desired step from a primitive node
149 * \param prim : the primitive node used to build the step
150 * \return a pointer on the built step (NULL if failure)
152 inline static IMagicAction * buildAction( const TDataSetRow & actorRowId, const std::vector< const CStaticBrick* >& bricks, uint & brickIndex, CMagicPhrase * phrase )
154 // check validity
155 if ( bricks.size()<=brickIndex )
157 nlwarning("<IMagicActionFactory buildAction> brick index %u and size is %u !",brickIndex, bricks.size());
158 return NULL;
160 if ( !bricks[brickIndex] )
162 nlwarning("<IMagicActionFactory buildAction> brick index %u is NULL",brickIndex);
163 return NULL;
165 if ( bricks[brickIndex]->Params.empty() )
167 nlwarning("<IMagicActionFactory buildAction>NASTY BUG: no param in brick %u : if we are there there is at least1 param for the effect type",brickIndex);
168 return NULL;
170 if ( bricks[brickIndex]->Params[0]->id() != TBrickParam::MA )
172 nlwarning("<IMagicActionFactory buildAction>NASTY BUG: no param in brick %u : if we are there the first param should be a TBrickParam::MA",brickIndex);
173 return NULL;
175 INFOLOG("MA: %s",((CSBrickParamMaType *)bricks[brickIndex]->Params[0])->Type.c_str());
176 const std::string & type = ((CSBrickParamMaType *)bricks[brickIndex]->Params[0])->Type;
178 //get appropriate factory
179 for ( uint i = 0; i < Factories->size(); i++ )
181 if ( !NLMISC::nlstricmp( (*Factories)[i].first , type) )
183 INFOLOG("MA: %s is managed by the system. Building action...",((CSBrickParamMaType *)bricks[brickIndex]->Params[0])->Type.c_str());
184 return (*Factories)[i].second->build( actorRowId, bricks, brickIndex, phrase);
187 nlwarning( "<IMagicActionFactory buildAction> the type MA:%s has no corresponding magic action class", type.c_str() );
188 return NULL;
190 protected:
191 ///\init the factories
192 inline static void init()
193 { if( !Factories )
194 Factories = new std::vector< std::pair< std::string , IMagicActionFactory* > >;
197 * Create a step from parameters
198 * \param params : a vector of vector of strings describing the step params
199 * \return a pointer on the built step (NULL if failure)
201 virtual IMagicAction * build( const TDataSetRow & actorRowId, const std::vector< const CStaticBrick* >& brickIds, uint & index, CMagicPhrase * phrase ) = 0;
203 ///the phrase factories. We use a pointer here because we cant control the order inwhich ctor of static members are called
204 static std::vector< std::pair< std::string , IMagicActionFactory* > >* Factories;
207 #endif // RY_MAGIC_ACTION_H
209 /* End of magic_action.h */