Merge branch '138-toggle-free-look-with-hotkey' into main/gingo-test
[ryzomcore.git] / ryzom / client / src / interface_v3 / sphrase_manager.h
blobad8abee80b0165bf75517ca4f1f68b2773b1916e
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010-2014 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
6 // Copyright (C) 2013-2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 //
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as
10 // published by the Free Software Foundation, either version 3 of the
11 // License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #ifndef RY_SPHRASE_MANAGER_H
22 #define RY_SPHRASE_MANAGER_H
24 #include "nel/misc/types_nl.h"
25 #include "game_share/sphrase_com.h"
26 #include "game_share/skills.h"
27 #include "game_share/brick_types.h"
28 #include "game_share/resistance_type.h"
29 #include "req_skill_formula.h"
30 #include "brick_learned_callback.h"
31 #include "skill_change_callback.h"
32 #include "trade_common.h"
33 #include "nel/gui/interface_element.h"
34 #include "../time_client.h"
37 // ***************************************************************************
38 const std::string PHRASE_DB_BOOK="UI:PHRASE:BOOK";
39 const std::string PHRASE_DB_PROGRESSION[2]= {"UI:PHRASE:PROGRESS_ACTIONS", "UI:PHRASE:PROGRESS_UPGRADES"};
40 const std::string PHRASE_DB_MEMORY="UI:PHRASE:MEMORY";
41 const std::string PHRASE_DB_MEMORY_ALT="UI:PHRASE:MEMORY_ALT";
42 const std::string PHRASE_DB_EXECUTE_NEXT="UI:PHRASE:EXECUTE_NEXT:PHRASE";
43 const std::string PHRASE_DB_EXECUTE_NEXT_IS_CYCLIC="UI:PHRASE:EXECUTE_NEXT:ISCYCLIC";
44 const std::string PHRASE_DB_BOTCHAT="LOCAL:TRADING";
45 #define PHRASE_MAX_BOOK_SLOT 512
46 #define PHRASE_MAX_PROGRESSION_SLOT 512
47 #define PHRASE_MAX_MEMORY_SLOT 20
48 #define PHRASE_MAX_BOTCHAT_SLOT TRADE_MAX_ENTRIES
49 // u16 only for client/server com.
50 #define PHRASE_MAX_ID 65535
52 // For phrase execution counter
53 #define PHRASE_EXECUTE_COUNTER_MASK 255
54 const std::string PHRASE_DB_COUNTER_NEXT="SERVER:EXECUTE_PHRASE:NEXT_COUNTER";
55 const std::string PHRASE_DB_COUNTER_CYCLE="SERVER:EXECUTE_PHRASE:CYCLE_COUNTER";
58 // TODO_OPTIM: too big test for the list_sheet* each frame with 512 entries!!!
60 class CSuccessTableSheet;
61 namespace NLMISC{
62 class CCDBNodeLeaf;
66 /** Special helper class for lua export : enclose a phrase into an object accessible to lua
67 * This way we can setup the phrase tooltip in lua code instead of hardcoded C++ stuff letting
68 * the possibility to the user to customize it to his liking.
70 class CSPhraseComAdpater : public CReflectableRefPtrTarget
72 public:
73 CSPhraseCom Phrase;
74 REFLECT_EXPORT_START(CSPhraseComAdpater, CInterfaceElement)
75 REFLECT_LUA_METHOD("getCastTime", luaGetCastTime)
76 REFLECT_LUA_METHOD("getCastRange", luaGetCastRange)
77 REFLECT_LUA_METHOD("getHpCost", luaGetHpCost)
78 REFLECT_LUA_METHOD("getSapCost", luaGetSapCost)
79 REFLECT_LUA_METHOD("getFocusCost", luaGetFocusCost)
80 REFLECT_LUA_METHOD("getStaCost", luaGetStaCost)
81 REFLECT_LUA_METHOD("getName", luaGetName)
82 REFLECT_LUA_METHOD("getDesc", luaGetDesc)
83 REFLECT_LUA_METHOD("getSuccessRate", luaGetSuccessRate)
84 REFLECT_LUA_METHOD("isMagicPhrase", luaIsMagicPhrase)
85 REFLECT_LUA_METHOD("isCombatPhrase", luaIsCombatPhrase)
86 REFLECT_LUA_METHOD("isPowerPhrase", luaIsPowerPhrase)
87 REFLECT_LUA_METHOD("getRegenTime", luaGetRegenTime)
88 REFLECT_LUA_METHOD("getTotalRegenTime", luaGetTotalRegenTime)
89 REFLECT_LUA_METHOD("getPowerDisableTime", luaGetPowerDisableTime)
90 REFLECT_EXPORT_END
91 int luaGetCastTime(CLuaState &ls);
92 int luaGetCastRange(CLuaState &ls);
93 int luaGetHpCost(CLuaState &ls);
94 int luaGetSapCost(CLuaState &ls);
95 int luaGetSuccessRate(CLuaState &ls);
96 int luaGetFocusCost(CLuaState &ls);
97 int luaGetStaCost(CLuaState &ls);
98 int luaGetName(CLuaState &ls);
99 int luaGetDesc(CLuaState &ls);
100 int luaIsMagicPhrase(CLuaState &ls);
101 int luaIsCombatPhrase(CLuaState &ls);
102 int luaIsPowerPhrase(CLuaState &ls);
103 int luaGetRegenTime(CLuaState &ls);
104 int luaGetTotalRegenTime(CLuaState &ls);
105 int luaGetPowerDisableTime(CLuaState &ls);
110 // ***************************************************************************
112 * Singleton to Get/Set Sabrina Phrase in SpellBook / Memory.
113 * NB: you MUST create it (getInstance()), before loading of ingame.xmls.
114 * \author Lionel Berenguier
115 * \author Nevrax France
116 * \date 2003
118 class CSPhraseManager
120 public:
121 static CSPhraseManager *getInstance()
123 if(!_Instance)
124 _Instance= new CSPhraseManager;
125 return _Instance;
128 // release singleton
129 static void releaseInstance();
131 // The Slot 0 of the Book indicate "NoPhrase".
132 // The Slot 1 indicate the Edited Phrase for phrase composition, and is not "really" a part of the book.
133 enum {EditionSlot= 1, BookStartSlot= 2};
135 /// To call when The DB inGame is setup. Else, no write is made to it before. (NB: DB is updated here)
136 void initInGame();
138 /// Reset
139 void reset();
141 /// Call juste once when interface is built
142 void updateMemoryBar();
144 /// Call once per pass
145 void update();
147 // \name Book Edition
148 // @{
149 /** set a phrase on a slot.
150 * \param lock special for BotChat phrase buy. when true, the phrase is never written in the book DB
151 * the server has to unlock it (or delete if not confirmed)
152 * NO MSG SENT
154 void setPhrase(uint32 slot, const CSPhraseCom &phrase, bool lock= false);
156 /** Same as setPhrase() but do not update the DB of book now
157 * User can use this if lot of phrase must be chaned in one time.
158 * User must call updateBookDB() after setting all those phrases.
159 * Nb: suppose lock==false.
161 void setPhraseNoUpdateDB(uint32 slot, const CSPhraseCom &phrase);
163 /// update Action Book Database. You need only to use it in conjunction with setPhraseNoUpdateDB()
164 void updateBookDB();
166 /// erase a phrase on a slot. NO MSG SENT
167 void erasePhrase(uint32 slot);
169 /// get a phrase for a slot. Empty Phrase returned if don't exist. O(logN)
170 const CSPhraseCom &getPhrase(uint32 slot) const;
172 /// get the number of memory lines.
173 uint32 getNbMemoryLines() const { return (uint32)_Memories.size(); }
175 /** Allocate a Free Slot (for NEW phrase setup). 0 is not a free slot
176 * NB: the slot is not still correctly filled(), and getPhrase() will return Empty. use setPhrase() just after
177 * \return 0 if not possible (eg too big)
179 uint32 allocatePhraseSlot();
181 /// true if a free slot is available (don't allocate)
182 bool hasFreeSlot() const;
184 /// get a phrase version for a slot. -1 if phrase not present. O(1)
185 sint32 getPhraseVersion(uint32 slot) const;
187 // Receive a BotChat phrase Buy confirmation: NB: memorize it (and server send) if possible
188 void receiveBotChatConfirmBuy(uint16 phraseId, bool confirm);
190 // test if the given phrase is known
191 bool isPhraseKnown(const CSPhraseCom &phrase) const;
193 /** Filter the BOOK DB with this brickType or skill.
194 * NB: if brickTypeFilter is UNKNOWN then filtered by skill
195 * il filterSkill is unknown, then not filtered (all match). This is the default.
197 void setBookFilter(BRICK_TYPE::EBrickType brickTypeFilter, SKILLS::ESkills skillFilter);
199 /// get the book skill filter
200 SKILLS::ESkills getBookSkillFilter() const {return _BookSkillFitler;}
202 /// Send the PHRASE:DELETE message to the server
203 void sendDeleteToServer(uint32 slot);
205 /// Send the PHRASE:LEARN message to the server
206 void sendLearnToServer(uint32 slot);
208 /// This is a clean full delete: forget all phrase before, erase the phrase, send msg to server
209 void fullDelete(uint32 slot);
211 /** Do it only if the phrase id is only used in this memory slot
212 * This is a clean full delete: forget all phrase before, erase the phrase, send msg to server
214 void fullDeletePhraseIfLast(uint32 memoryLine, uint32 memorySlot);
216 // @}
219 // \name Memory Edition
220 // @{
222 /// Memorize a phrase (no MSG send)
223 void memorizePhrase(uint32 memoryLine, uint32 memorySlot, uint32 slot);
224 /// Forget a phrase (no MSG send). NB: no-op if it is a macro
225 void forgetPhrase(uint32 memoryLine, uint32 memorySlot);
226 /// Get the phrase memorized. 0 if not found or if it is a macro
227 uint32 getMemorizedPhrase(uint32 memoryLine, uint32 memorySlot) const;
229 /// Memorize a macro (no MSG send). if was a phrase, forget first (client and server)
230 void memorizeMacro(uint32 memoryLine, uint32 memorySlot, uint32 macroId);
231 /// Forget a macro. NB: no-op if it is a phrase
232 void forgetMacro(uint32 memoryLine, uint32 memorySlot);
233 /// Get the phrase memorized. 0 if not found or if it is a macro
234 uint32 getMemorizedMacro(uint32 memoryLine, uint32 memorySlot) const;
235 /// return true if it is a memorized macro. false if empty or if it is a phrase
236 bool isMemorizedMacro(uint32 memoryLine, uint32 memorySlot) const;
237 /// To Be called when the macro visual changes
238 void updateMacroShortcuts(sint32 macroId);
239 /// To be called when the Id changes
240 void deleteMacroShortcuts(sint32 macroId);
242 /// Only one memory line is displayed in the Memory DB. if -1, erased.
243 void selectMemoryLineDB(sint32 memoryLine);
244 void selectMemoryLineDBalt(sint32 memoryLine);
245 /// get the selected memory line.
246 sint32 getSelectedMemoryLineDB() const {return _SelectedMemoryDB;}
247 sint32 getSelectedMemoryAltLineDB() const {return _SelectedMemoryDBalt;}
248 /// Common Method to send the Memorize msg to server
249 void sendMemorizeToServer(uint32 memoryLine, uint32 memorySlot, uint32 phraseId);
250 /// Common Method to send the Forget msg to server
251 void sendForgetToServer(uint32 memoryLine, uint32 memorySlot);
253 /// count all memories that use this phrase
254 uint countAllThatUsePhrase(uint32 slot);
255 /// Forget all Memories that use this phrase slot, AND send appropriate message to server. if sendMsgOnly==true, only the msg is sent to server (no modification to local)
256 void forgetAllThatUsePhrase(uint32 slot, bool sendMsgOnly= false);
257 /// Rememorize all memories that use this slot
258 void rememorizeAllThatUsePhrase(uint32 slot);
260 /// Update all Ctrl State of the action Bar, according to macro/itemInRightHand/available states
261 void updateAllMemoryCtrlState();
263 /// Load or save the macro
264 void serialMacroMemory(NLMISC::IStream &f);
266 /// is this phrase sheet can be memorized / casted?
267 bool isPhraseCastable(uint32 sheetId) const;
268 bool isPhraseCastable(class CSPhraseSheet *phraseSheet) const;
269 bool isPhraseCharacBuying(uint32 sheetId) const;
270 bool isPhraseCharacBuying(class CSPhraseSheet *phraseSheet) const;
272 /** return getMemorizedPhrase(memoryLine, memoryIndex), only if this phrase is only used in this memory slot
273 * else return allocatePhraseSlot()
275 uint32 getMemorizedPhraseIfLastOrNewSlot(uint32 memoryLine, uint32 memoryIndex);
277 // @}
280 // \name Phrase composition
281 // @{
282 // The phrase edited/created. If 0, it may be a phrase newly created, but not still assigned.
283 uint32 CompositionPhraseId;
284 // For phrase created only. If not -1, then at creation, will be auto-memorized to this slot
285 sint32 CompositionPhraseMemoryLineDest;
286 sint32 CompositionPhraseMemorySlotDest;
289 /// For BotChat learning, build a phrase from .sphrase sheetId
290 void buildPhraseFromSheet(CSPhraseCom &phrase, sint32 sheetId);
292 /** For a given phrase, see if there's a matching sheet, or 0 else.
293 * NB : O(1) algo with respect to the number of phrase sheets
295 sint32 getSheetFromPhrase(const CSPhraseCom &phrase) const;
297 // @}
300 // \name Phrase Execution
301 // @{
302 /// Start execution from Client. Only the bitmaps are displayed. A sendExecuteToServer() or a cancelClientExecution() must follow for each clientExecute
303 void clientExecute(uint32 memoryLine, uint32 memorySlot, bool cyclic);
304 /// Common Method to send the execution msg to server
305 void sendExecuteToServer(uint32 memoryLine, uint32 memorySlot, bool cyclic);
306 /// Cancel the client execution (case when used with Move in combat for instance)
307 void cancelClientExecute(bool cyclic);
308 /// Execute a craft action (after selecting the plan and MPs), on both client and server side
309 void executeCraft(uint32 memoryLine, uint32 memorySlot, uint32 planSheetId,
310 std::vector<CFaberMsgItem> &mpItemPartList, std::vector<CFaberMsgItem> specificItemList);
311 /// Execute a cristalize action on both client and server side
312 void executeCristalize(uint32 memoryLine, uint32 memorySlot);
313 /** Execute a default attack, on both client and server side.
314 * NB: try first to launch a standard action "default attack" if found,
315 * calling clientExecute() and sendExecuteToServer()
317 void executeDefaultAttack();
318 /// Search the default attack like on client. false if not found. NB: find preferly in current memoryLine
319 bool findDefaultAttack(uint32 &memoryLine, uint32 &memorySlot);
321 uint getPhraseNextExecuteCounter() const {return _PhraseNextExecuteCounter;}
322 uint getPhraseCycleExecuteCounter() const {return _PhraseCycleExecuteCounter;}
324 /// Server Execution ACK
325 void receiveAckExecuteFromServer(bool cyclic, uint counterValue, bool ok);
327 /// get the Next PhraseId Executed (0 if none)
328 uint32 getNextExecutePhraseId() const {return _CurrentExecutePhraseIdNext;}
329 /// get the Cycle PhraseId Executed (0 if none)
330 uint32 getCycleExecutePhraseId() const {return _CurrentExecutePhraseIdCycle;}
332 // @}
334 // \name Misc
335 // @{
336 /** Build the Text description of a phrase (spell). NB: this is a TagFormated text
337 * \phraseSheetId not 0 if comes from a .sphrase Sheet => used to show progression info, and display phrase description
338 * \specialPhraseFormat if empty, format is auto selected. if "composition", same but the text is cut under the %compostart tag.
339 * else take directly this format.
341 void buildPhraseDesc(std::string &text, const CSPhraseCom &phrase, uint32 phraseSheetId, bool wantRequirement, const std::string &specialPhraseFormat= std::string());
342 // Get the Phrase Success Rate %
343 sint getPhraseSuccessRate(const CSPhraseCom &phrase);
344 // Get the Phrase Success Rate %. Manually gives the Skill to do the comparison (for craft)
345 sint getCraftPhraseSuccessRate(const CSPhraseCom &phrase, SKILLS::ESkills skill, uint minMpLevel, sint successModifier);
346 // Get the Phrase Success Rate %. Manually gives the Skill to do the comparison (for Forage Extraction)
347 sint getForageExtractionPhraseSuccessRate(const CSPhraseCom &phrase, SKILLS::ESkills skill);
348 // return the fmt according to forage terrain specializing
349 std::string getForageExtractionPhraseEcotypeFmt(const CSPhraseCom &phrase);
350 // Get the Phrase Sap Cost
351 void getPhraseSapCost(const CSPhraseCom &phrase, uint32 totalActionMalus, sint &cost, sint &costMalus);
352 // Get the Phrase Sta Cost
353 void getPhraseStaCost(const CSPhraseCom &phrase, uint32 totalActionMalus, sint &cost, sint &costMalus);
354 // Get the Phrase Focus Cost
355 void getPhraseFocusCost(const CSPhraseCom &phrase, uint32 totalActionMalus, sint &cost, sint &costMalus);
356 // Get the Phrase Hp Cost
357 void getPhraseHpCost(const CSPhraseCom &phrase, uint32 totalActionMalus, sint &cost, sint &costMalus);
358 // Get the Phrase Cast Time
359 void getPhraseCastTime(const CSPhraseCom &phrase, uint32 totalActionMalus, float &castTime, float &castTimeMalus);
360 // Get the Phrase Range
361 void getPhraseMagicRange(const CSPhraseCom &phrase, uint32 totalActionMalus, sint &range, sint &rangeMalus);
362 // For all bricks, get the sum of the propId property
363 float getPhraseSumBrickProp(const CSPhraseCom &phrase, uint propId, bool doAbs=false);
364 /// If the temporary inventory is opened so we cant execute action
365 bool isExecutionInvalidCauseTempInv() const;
366 /// build a list of bricks that are needed in order to learn this phrase. NB: any brick already contained in the phrase are removed
367 void buildPhraseBrickRequirement(uint32 phraseSheetId, std::vector<NLMISC::CSheetId> &bricks);
368 /// check if all bricks of phrase meet fame requirement
369 bool fameRequirementOk(uint32 phraseSheetId);
370 /// true if interesting to list the bricks of this phrase in help
371 bool allowListBrickInHelp(const CSPhraseCom &phrase) const;
372 /// return the combat restriction text (empty if not combat)
373 void getCombatWeaponRestriction(std::string &text, const CSPhraseCom &phrase, bool& usableWithMelee, bool& usableWithRange);
374 void getCombatWeaponRestriction(std::string &text, sint32 phraseSheetId, bool& usableWithMelee, bool& usableWithRange);
375 // return true if any of the Bricks contains AvoidCyclic==true (the phrase cannot be cyclic)
376 bool avoidCyclicForPhrase(const CSPhraseCom &phrase) const;
377 bool avoidCyclicForPhrase(sint32 phraseSheetId) const;
378 // Get total regeneration time for a power/aura phrase, in tick (0 if not a power/aura)
379 NLMISC::TGameCycle getPowerDisableTime(const CSPhraseCom &phrase) const;
380 // Get current time left for a power/aura phrase, in ticks (0 if not a power/aura)
381 NLMISC::TGameCycle getRegenTime(const CSPhraseCom &phrase) const;
382 // Get total time span necessary for a power/aura phrase to be available again (in ticks)
383 NLMISC::TGameCycle getTotalRegenTime(const CSPhraseCom &phrase) const;
385 /// Lookup a SuccessTable and return chance
386 enum TSuccessTable
388 STCombat= 0,
389 STOffensiveMagic,
390 STCurativeMagic,
391 STCraft,
392 STExtract,
393 STResistMagic,
394 STResistMagicLink,
395 STDodgeParry,
396 NumSuccessTable
398 sint getSuccessRate(TSuccessTable st, sint level, bool partialSuccess= false);
399 // @}
401 // \name Phrase Execution invalidation cause of Equip
402 // @{
403 void setEquipInvalidation(sint64 serverTick, sint invalidTickTime);
404 void updateEquipInvalidation(sint64 serverTick);
405 bool isExecutionInvalidCauseEquip() const;
406 // @}
410 // \name BotChat special
411 // @{
412 // get the current skill point price of a phrase sheet
413 uint32 getCurrentPhraseSheetPrice(uint32 phraseSheetId);
414 // get the base skill point price of a phrase sheet (ie don't check if bricks learned or not)
415 uint32 getBasePhraseSheetPrice(uint32 phraseSheetId);
416 // update bot chat prices in the range [start, end[
417 void updateBotChatPhrasePrice(uint start, uint end);
419 // From a phrase required level, retrieve its section (for interface listing)
420 uint32 getPhraseSectionFromLevel(uint32 level);
421 // inverse
422 void getPhraseLevelFromSection(uint32 section, uint32 &minLevel, uint32 &maxLevel);
423 // For book display of section
424 void getPhraseSectionBoundFromSkillFilter(sint &minSectionId, sint &maxSectionId);
426 // Client Side Rolemaster phrase generation. return the number of db node filled
427 uint fillRoleMasterGenericPhrase(uint32 rmFlags, uint32 rmRace);
429 // @}
432 /// true if the compareSkill is compatible with this combat phrase, eg more restrictive for instance
433 bool skillCompatibleWithCombatPhrase(SKILLS::ESkills compareSkill, const std::vector<NLMISC::CSheetId> &phraseBricks) const;
434 bool skillCompatibleWithSpecialPowerPhrase(SKILLS::ESkills compareSkill, const std::vector<NLMISC::CSheetId> &phraseBricks) const;
436 /// true if phrase is usable with empty hands
437 bool phraseUsableWithEmptyHands(const std::vector<NLMISC::CSheetId> &phraseBricks) const;
439 // get total action malus
440 uint32 getTotalActionMalus(const CSPhraseCom &phrase) const;
442 void updateAllActionRegen();
444 void touchRegenTickRangeFlag() { _RegenTickRangeTouched = true; }
446 static uint64 getPhraseRequiredFlags(const CSPhraseCom &phrase);
448 // ****************
449 private:
450 /// Constructor
451 CSPhraseManager();
452 ~CSPhraseManager();
453 static CSPhraseManager *_Instance;
455 typedef std::map<uint32, CSPhraseCom> TPhraseMap;
456 typedef TPhraseMap::iterator ItPhraseMap;
457 typedef std::map<CSPhraseCom, uint32> TPhraseToSheet; // map each phrase to its sheet id
458 // Map of All Phrase. Contains the Book + some system phrase (1: the Edition Phrase)
459 TPhraseMap _PhraseMap;
460 TPhraseToSheet _PhraseToSheet;
461 std::set<sint32> _RegenPhrases;
463 // timeouts for the power / auras bricks
464 CTickRange _BrickRegenRange[64];
466 // Shortcut To Phrases Leaves
467 std::vector<NLMISC::CCDBNodeLeaf*> _BookDbLeaves;
468 std::vector<NLMISC::CCDBNodeLeaf*> _MemoryDbLeaves;
469 std::vector<NLMISC::CCDBNodeLeaf*> _MemoryAltDbLeaves;
470 NLMISC::CCDBNodeLeaf *_NextExecuteLeaf;
471 NLMISC::CCDBNodeLeaf *_NextExecuteIsCyclicLeaf;
473 // extra client data
474 struct CPhraseClient
476 sint32 Version;
477 bool Lock;
478 CPhraseClient()
480 Version= 0;
481 Lock= false;
484 std::vector<CPhraseClient> _PhraseClient;
485 uint32 _MaxSlotSet;
486 std::vector<uint32> _FreeSlots;
488 bool _RegenTickRangeTouched;
490 // Memory
491 struct CMemorySlot
493 // Is this a macro
494 bool IsMacro;
495 // Is his visual dirty?
496 bool IsMacroVisualDirty;
497 // Macro or PhraseId
498 uint32 Id;
499 CMemorySlot()
501 IsMacro= false;
502 IsMacroVisualDirty= false;
503 Id= 0;
506 // suppose Id==0 is valid for a macro, but not for a phrase
507 bool isEmpty() const
509 return Id==0 && IsMacro==false;
511 // Macro possible only if IsMacro==true
512 bool isMacro() const
514 return IsMacro;
516 // phrase only if not macro, and Id!=0
517 bool isPhrase() const
519 return !IsMacro && Id!=0;
522 struct CMemoryLine
524 CMemorySlot Slot[PHRASE_MAX_MEMORY_SLOT];
526 std::vector<CMemoryLine> _Memories;
527 sint32 _SelectedMemoryDB;
528 sint32 _SelectedMemoryDBalt;
530 void updateMemoryDBAll();
531 void updateMemoryDBSlot(uint32 memorySlot);
533 // The number of entries setuped to not 0
534 uint _LastBookNumDbFill;
535 // The Book filter.
536 SKILLS::ESkills _BookSkillFitler;
537 BRICK_TYPE::EBrickType _BookBrickTypeFilter;
538 // true if the phrase is "compatbile" with _BookSkillFitler
539 bool matchBookSkillFilter(const CSPhraseCom &phrase) const;
541 uint32 _PhraseNextExecuteCounter;
542 uint32 _PhraseCycleExecuteCounter;
544 bool _InitInGameDone;
546 /// unlock a phrase (for BotChat Phrase buy confirmation)
547 void unlockPhrase(uint32 slot);
549 // Phrase compute related
550 CSuccessTableSheet *_SuccessTableSheet[NumSuccessTable];
551 void loadSuccessTable();
553 // The user was indoor
554 bool _UserIndoor;
556 // called by getPhraseSuccessRate() public
557 sint getPhraseSuccessRate(TSuccessTable st, const CSPhraseCom &phrase, sint skillValue, uint minMpLevel);
559 // real stuff
560 void setPhraseInternal(uint32 slot, const CSPhraseCom &phrase, bool lock, bool updateDB);
562 // If the local counter and server counter are same, then view will be hid.
563 bool isPhraseNextExecuteCounterSync() const;
564 bool isPhraseCycleExecuteCounterSync() const;
566 // setup by AH. -1 if not activated
567 sint32 _CurrentExecuteLineNext;
568 sint32 _CurrentExecuteSlotNext;
569 uint32 _CurrentExecutePhraseIdNext;
570 sint32 _CurrentExecuteLineCycle;
571 sint32 _CurrentExecuteSlotCycle;
572 uint32 _CurrentExecutePhraseIdCycle;
573 // For debug only. setuped by sendExecuteToServer() in local mode only
574 sint64 _PhraseDebugEndNextAction;
575 sint64 _PhraseDebugEndCyclicAction;
577 friend class CHandlerPhraseCounterUpdate;
578 friend class CHandlerPhraseDebugClient;
580 // Equip invalidation
581 sint64 _EquipInvalidationEnd;
582 sint64 _CurrentServerTick;
584 // update the execution views
585 void updateExecutionDisplay();
587 // update the memory ctrl
588 void updateMemoryCtrlState(uint memorySlot, class CDBCtrlSheet *ctrl, SKILLS::ESkills itemSkill);
589 // update the ith memory ctrl in the action bar
590 void updateMemoryCtrlState(uint memorySlot);
592 // Shortcut To PhraseSheets Leaves in BotChat
593 std::vector<NLMISC::CCDBNodeLeaf*> _BotChatPhraseSheetLeaves;
594 std::vector<NLMISC::CCDBNodeLeaf*> _BotChatPhrasePriceLeaves;
596 // For phrase compatibility with enchant weapon special power
597 NLMISC::CSheetId _EnchantWeaponMainBrick;
599 // \name Phrase sheet progression
600 // @{
601 enum TProgressType
603 ActionProgress= 0,
604 UpgradeProgress,
606 NumProgressType
608 std::vector<NLMISC::CCDBNodeLeaf*> _ProgressionDbSheets[NumProgressType];
609 std::vector<NLMISC::CCDBNodeLeaf*> _ProgressionDbLevels[NumProgressType];
610 std::vector<NLMISC::CCDBNodeLeaf*> _ProgressionDbLocks[NumProgressType];
612 // For each skill, which phrase are learned when the skill is gained
613 class CPhraseProgressInfo
615 public:
616 uint32 SheetId;
617 uint32 Level;
619 friend class CPhraseSortEntry;
620 class CPhraseProgression
622 public:
623 // All the phrase that can be learned at this level, anbd the required level of the skill
624 std::vector<CPhraseProgressInfo> Phrases;
626 CPhraseProgression _ProgressionPhrases[SKILLS::NUM_SKILLS];
628 // For each phrase SheetId, gives the required Skill formula (for help)
629 typedef std::map<uint32, CReqSkillFormula> TPhraseReqSkillMap;
630 TPhraseReqSkillMap _PhraseReqSkillMap;
632 // For db fill
633 uint _LastProgressionNumDbFill[NumProgressType];
634 // For db update when a brick is learned
635 class CProgressionUpdate : public IBrickLearnedCallback, public ISkillChangeCallback
637 public:
638 virtual void onBrickLearned()
640 CSPhraseManager *pPM= CSPhraseManager::getInstance();
641 pPM->updatePhraseProgressionDB();
643 virtual void onSkillChange()
645 CSPhraseManager *pPM= CSPhraseManager::getInstance();
646 pPM->updatePhraseProgressionDB();
649 friend class CProgressionUpdate;
650 CProgressionUpdate _ProgressionUpdate;
652 // methods
653 void updatePhraseProgressionDB();
654 // called at initInGame
655 void computePhraseProgression();
656 void insertProgressionSkillRecurs(SKILLS::ESkills skill, uint32 value, sint *skillReqLevel, std::vector<SKILLS::ESkills> &skillsToInsert);
658 mutable NLMISC::CRefPtr<NLMISC::CCDBNodeLeaf> _TotalMalusEquipLeaf;
660 NLMISC::CRefPtr<NLMISC::CCDBNodeLeaf> _ServerUserDefaultWeightHandsLeaf;
662 // @}
664 /// return the skill of the root
665 SKILLS::ESkills getPhraseRootSkill(const std::vector<NLMISC::CSheetId> &phraseBricks) const;
667 /// return true if all the requirement in order to learn this prhase are met.
668 bool phraseRequirementOk(uint32 phraseSheetId);
671 /// Execution ACK reception
672 // @{
673 struct CAckExecuteEntry
675 enum TState
677 WaitAck= 0,
681 TState State;
682 uint32 Counter;
683 sint32 MemoryLine;
684 sint32 MemorySlot;
685 uint32 PhraseId;
687 typedef std::deque<CAckExecuteEntry> TAckExecuteList;
688 TAckExecuteList _AckExecuteCycleList;
689 TAckExecuteList _AckExecuteNextList;
691 void appendCurrentToAckExecute(bool cyclic);
692 void resetAckExecuteList(bool cyclic);
694 // @}
696 std::string formatMalus(sint base, sint malus);
697 std::string formatMalus(float base, float malus);
698 std::string formatBonusMalus(sint32 base, sint32 mod);
700 // Special for combat: Build the "phrase skill compatible" formula
701 // NB: Use a ReqSkillFormula, but don't use the value part, cause no requirement is made on it
702 CReqSkillFormula buildCombatPhraseSkillFormula(const std::vector<NLMISC::CSheetId> &phraseBricks) const;
704 // For Magic and Magic Staff
705 uint32 getSpellLevel(const std::vector<NLMISC::CSheetId> &phraseBricks) const;
707 // For Magic
708 void getResistMagic(bool resistMagic[RESISTANCE_TYPE::NB_RESISTANCE_TYPE], const std::vector<NLMISC::CSheetId> &phraseBricks);
710 void updateAllMemoryCtrlRegenTickRange();
711 void updateMemoryCtrlRegenTickRange(uint memorySlot, CDBCtrlSheet *ctrl);
712 void updateMemoryCtrlRegenTickRange(uint memorySlot);
714 CDBCtrlSheet *getMemorySlotCtrl(uint memorySlot);
715 CDBCtrlSheet *getMemoryAltSlotCtrl(uint memorySlot);
717 CTickRange getRegenTickRange(const CSPhraseCom &phrase) const;
719 NLMISC::CCDBNodeLeaf *getRegenTickRangeDbLeaf(uint powerIndex) const;
720 // get regen tick range for a specific power, from the database
721 CTickRange getRegenTickRange(uint powerIndex) const;
722 public:
723 // tmp for test : set regen tick range locally
724 void setRegenTickRange(uint powerIndex, const CTickRange &tickRange);
727 #endif // NL_SPHRASE_MANAGER_H
729 /* End of sphrase_manager.h */