Resolve "Toggle Free Look with Hotkey"
[ryzomcore.git] / ryzom / client / src / attack_list.cpp
blobc748e58327e0d578dc03ad906129bde9af6ed7eb
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 #include "stdpch.h"
20 #include "attack_list.h"
21 #include "sheet_manager.h"
22 #include "global.h"
24 #include "client_sheets/attack_list_sheet.h"
26 #include "nel/3d/u_scene.h"
28 #include "nel/misc/sheet_id.h"
30 #include <utility>
32 #ifdef DEBUG_NEW
33 #define new DEBUG_NEW
34 #endif
36 H_AUTO_DECL(RZ_AttackList)
38 using namespace NLMISC;
39 using namespace std::rel_ops;
41 extern NL3D::UScene *Scene;
43 CAttackListManager *CAttackListManager::_Instance = NULL;
46 // get a .animation_fx sheet from its name (NULL if not found)
47 static CAnimationFXSetSheet *getAnimFXSetSheetFromName(const std::string &name)
49 CEntitySheet *sheet = SheetMngr.get(NLMISC::CSheetId(name));
50 if (!sheet) return NULL;
51 if (sheet->Type == CEntitySheet::ANIMATION_FX_SET) return static_cast<CAnimationFXSetSheet *>(sheet);
52 return NULL;
55 // build an attack part
56 static void buildAttackPart(const std::string &sheetName, CAnimationFXSet &fxSet, NL3D::UAnimationSet *as)
58 if (!sheetName.empty())
60 CAnimationFXSetSheet *sheet = getAnimFXSetSheetFromName(sheetName);
61 if (sheet)
63 fxSet.init(sheet, as);
65 else
67 nlwarning("Sheet %s not found", sheetName.c_str());
72 // ***********************************************************************************************
73 CAttack::CAttack()
75 Sheet = NULL;
78 // ***********************************************************************************************
79 void CAttack::init(const CAttackSheet *sheet, NL3D::UAnimationSet *as)
81 nlassert(!Sheet); // init already done
82 if (!sheet) return;
83 Sheet = sheet;
85 buildAttackPart(Sheet->AttackBeginFX, AttackBeginFX, as);
86 buildAttackPart(Sheet->AttackLoopFX, AttackLoopFX, as);
87 buildAttackPart(Sheet->AttackEndFX, AttackEndFX, as);
88 buildAttackPart(Sheet->AttackStaticObjectCastFX, AttackStaticObjectCastFX, as);
89 buildAttackPart(Sheet->AttackFailFX, AttackFailFX, as);
90 buildAttackPart(Sheet->ProjectileFX, ProjectileFX, as);
91 buildAttackPart(Sheet->ImpactFX, ImpactFX, as);
94 // ***********************************************************************************************
95 void CAttackList::init(const CAttackListSheet *attackList, NL3D::UAnimationSet *as)
97 nlassert(_Attacks.empty());
98 if (!attackList) return;
99 _Attacks.resize(attackList->Attacks.size());
100 for(uint k = 0; k < _Attacks.size(); ++k)
102 _Attacks[k].ID = &attackList->Attacks[k].ID;
103 _Attacks[k].Attack.init(&(attackList->Attacks[k].Attack), as);
105 // sort all attacks for fast retrieval
106 std::sort(_Attacks.begin(), _Attacks.end());
111 struct CAttackEntryComp
113 bool operator()(const CAttackListEntry &lhs, const CAttackIDSheet &rhs) const
115 nlassert(lhs.ID);
116 return *lhs.ID < rhs;
121 struct CAttackEntryComp2
123 bool operator()(const CAttackListEntry &lhs, const CAttackListEntry &rhs) const
125 nlassert(lhs.ID);
126 nlassert(rhs.ID);
127 return *lhs.ID < *rhs.ID;
131 // ***********************************************************************************************
132 const CAttack *CAttackList::getAttackFromID(const CAttackIDSheet &id) const
134 H_AUTO_USE(RZ_AttackList);
135 // vl: changed, this line only work with stlport
136 // std::vector<CAttackListEntry>::const_iterator it = std::lower_bound(_Attacks.begin(), _Attacks.end(), id, CAttackEntryComp());
138 CAttackListEntry ale(&id);
139 std::vector<CAttackListEntry>::const_iterator it = std::lower_bound(_Attacks.begin(), _Attacks.end(), ale, CAttackEntryComp2());
140 if (it == _Attacks.end()) return NULL;
141 if (*(it->ID) != id) return NULL;
142 return &(it->Attack);
145 // ***********************************************************************************************
146 CAttackListManager &CAttackListManager::getInstance()
148 H_AUTO_USE(RZ_AttackList)
149 if (_Instance) return *_Instance;
150 _Instance = new CAttackListManager();
151 return *_Instance;
154 // ***********************************************************************************************
155 void CAttackListManager::releaseInstance()
157 if( _Instance )
158 delete _Instance;
159 _Instance = NULL;
162 // ***********************************************************************************************
163 void CAttackListManager::init()
165 if (_AnimationSet) return; // init already done
166 if (!Scene) return; // no scene, can't build anything
167 _AnimationSet = Driver->createAnimationSet();
168 if (!_AnimationSet) return;
169 std::vector<CSheetId> result;
170 std::vector<std::string> filenames;
171 NLMISC::CSheetId::buildIdVector(result, filenames, "attack_list");
172 for(uint k = 0; k < result.size(); ++k)
174 const CAttackListSheet *sheet = dynamic_cast<const CAttackListSheet *>(SheetMngr.get(result[k]));
175 if (sheet)
177 TAttackListMap::iterator it = _AttackMap.find(filenames[k]);
178 if (it != _AttackMap.end())
180 nlwarning("attack list duplicated : %s", filenames[k].c_str());
182 CAttackList &al = _AttackMap[filenames[k]];
183 al.init(sheet, _AnimationSet);
186 // auras and links
187 buildAurasFXs();
188 buildLinkFXs();
191 // ***********************************************************************************************
192 void CAttackListManager::release()
194 if (!_AnimationSet) return;
195 _AttackMap.clear();
196 if (Driver) Driver->deleteAnimationSet(_AnimationSet);
197 _Auras.release();
198 _Links.release();
199 delete _Instance;
200 _Instance = NULL;
203 // ***********************************************************************************************
204 const CAttackList *CAttackListManager::getAttackList(const std::string &name) const
206 H_AUTO_USE(RZ_AttackList)
207 TAttackListMap::const_iterator it = _AttackMap.find(name);
208 if (it != _AttackMap.end()) return &(it->second);
209 return NULL;
212 // ***********************************************************************************************
213 CAttackListManager::CAttackListManager()
215 _AnimationSet = NULL;
218 // *******************************************************************************************
219 void CAttackListManager::buildAurasFXs()
221 _Auras.init("auras.id_to_string_array", _AnimationSet, false /* must not delete animset, owned by this object */);
224 // *******************************************************************************************
225 void CAttackListManager::buildLinkFXs()
227 _Links.init("links.id_to_string_array", _AnimationSet, false /* must not delete animset, owned by this object */);