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) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
6 // Copyright (C) 2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
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/>.
24 #include "dbgroup_build_phrase.h"
25 #include "sbrick_manager.h"
26 #include "sphrase_manager.h"
27 #include "interface_manager.h"
28 #include "dbctrl_sheet.h"
29 #include "nel/gui/view_bitmap.h"
30 #include "nel/gui/ctrl_button.h"
31 #include "nel/gui/group_editbox.h"
32 #include "../client_cfg.h"
33 #include "nel/gui/view_text.h"
34 #include "skill_manager.h"
35 #include "../string_manager_client.h"
39 using namespace NLMISC
;
42 // ***************************************************************************
43 const std::string
CDBGroupBuildPhrase::BrickSelectionModal
= "ui:interface:build_phrase_select_brick";
44 const std::string
CDBGroupBuildPhrase::BrickSelectionDB
= "UI:PHRASE:SELECT";
45 const std::string
CDBGroupBuildPhrase::BrickBuildDB
= "UI:PHRASE:BUILD";
46 const std::string
CDBGroupBuildPhrase::BrickIconSelectionModal
= "ui:interface:build_phrase_select_icon";
49 // ***************************************************************************
51 NLMISC_REGISTER_OBJECT(CViewBase
, CDBGroupBuildPhrase
, std::string
, "build_phrase");
53 CDBGroupBuildPhrase::CDBGroupBuildPhrase(const TCtorParam
¶m
)
54 :CInterfaceGroup(param
)
57 _ValidateButton
= NULL
;
63 _TextureIdSlotDisabled
= 0;
65 // Name of the magic sentence
66 _UserSentenceName
= NULL
;
71 _TextPhraseDesc
= NULL
;
73 nlctassert(MaxRootBrickTypeFilter
>0);
74 for(uint i
=0;i
<MaxRootBrickTypeFilter
;i
++)
76 _RootBrickTypeFilter
[i
]= BRICK_TYPE::UNKNOWN
;
79 m_IconIndex
= std::numeric_limits
<uint8
>::max();
82 // ***************************************************************************
83 CDBGroupBuildPhrase::~CDBGroupBuildPhrase()
88 // ***************************************************************************
89 // ***************************************************************************
91 // ***************************************************************************
92 // ***************************************************************************
95 // ***************************************************************************
96 bool CDBGroupBuildPhrase::parse (xmlNodePtr cur
, CInterfaceGroup
*parentGroup
)
98 if(!CInterfaceGroup::parse(cur
, parentGroup
))
101 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
103 // Init the disabled texture id
104 CViewRenderer
&rVR
= *CViewRenderer::getInstance();
105 _TextureIdSlotDisabled
= rVR
.getTextureIdFromName ("w_slot_brick_disabled.tga");
107 // Create now (before sons ctrl sheet parsing) the variables
109 // Bricks and their Params
110 for(i
=0;i
<MaxBricks
;i
++)
112 NLGUI::CDBManager::getInstance()->getDbProp(BrickBuildDB
+ ":MAIN:" + toString(i
)+":SHEET");
113 for(uint j
=0;j
<MaxParam
;j
++)
114 NLGUI::CDBManager::getInstance()->getDbProp(BrickBuildDB
+ ":PARAM:" + toString(i
) + ":" + toString(j
) + ":SHEET");
117 // spellView: to update the icon, use a special phrase manager entry
118 NLGUI::CDBManager::getInstance()->getDbProp(BrickBuildDB
+ ":EDITION_PHRASE:PHRASE")->setValue32(CSPhraseManager::EditionSlot
);
123 // ***************************************************************************
124 void CDBGroupBuildPhrase::updateCoords ()
127 setupBuildSentence();
129 CInterfaceGroup::updateCoords();
132 // ***************************************************************************
133 void CDBGroupBuildPhrase::setupBuildSentence()
135 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
139 // Get the widget controls
140 _ValidateButton
= dynamic_cast<CCtrlBaseButton
*>(CInterfaceGroup::getCtrl("ok_cancel:ok"));
142 _ValidateButton
->setFrozen(true);
144 _TextPhraseDesc
= dynamic_cast<CViewText
*>(CInterfaceGroup::getView("infos:phrase_desc"));
146 // retrieved brick view/ctrls
147 string idCtrl
, idBack
, idCost
, idCredit
, idInfo
;
155 // **** get all bricks (including root)
160 idCtrl
= string("bricks:main_brick")+toString(index
);
161 idBack
= string("bricks:main_back")+toString(index
);
162 idCost
= string("bricks:main_cost")+toString(index
);
163 idCredit
= string("bricks:main_credit")+toString(index
);
164 idInfo
= string("bricks:main_info")+toString(index
);
165 ctrl
= dynamic_cast<CDBCtrlSheet
*>(CInterfaceGroup::getCtrl( idCtrl
));
166 back
= dynamic_cast<CViewBitmap
*>(CInterfaceGroup::getView( idBack
));
167 cost
= dynamic_cast<CViewText
*>(CInterfaceGroup::getView( idCost
));
168 credit
= dynamic_cast<CViewText
*>(CInterfaceGroup::getView( idCredit
));
169 info
= dynamic_cast<CViewText
*>(CInterfaceGroup::getView( idInfo
));
170 // A brick Slot is valid only if all Ctrl/View are ok, same for its param.
173 if(ctrl
&& back
&& cost
&& info
)
175 newWord
.Slot
.Brick
= ctrl
;
176 newWord
.Slot
.Back
= back
;
177 newWord
.CostView
= cost
;
178 newWord
.CreditView
= credit
;
179 newWord
.InfoView
= info
;
180 // Must have all params
181 for(uint i
=0;i
<MaxParam
;i
++)
183 idCtrl
= string("bricks:param_brick") + toString(index
) + "_" + toString(i
);
184 idBack
= string("bricks:param_back") + toString(index
) + "_" + toString(i
);
185 ctrl
= dynamic_cast<CDBCtrlSheet
*>(CInterfaceGroup::getCtrl( idCtrl
));
186 back
= dynamic_cast<CViewBitmap
*>(CInterfaceGroup::getView( idBack
));
189 newWord
.ParamSlot
[i
].Brick
= ctrl
;
190 newWord
.ParamSlot
[i
].Back
= back
;
194 // fails to find all params!
202 // ok with this ctrl?
208 _MainWords
.push_back(newWord
);
219 // If not at least find the root, error!
222 nlwarning("ERROR: RootBrick not found!");
228 // Active at least the root brick.
229 _MainWords
[0].setBrick(0);
232 // Setup special for Root
236 fromString(CWidgetManager::getInstance()->getParser()->getDefine("phrase_build_root_info_maxw"), rootTextMaxw
);
237 _MainWords
[0].InfoView
->setLineMaxW(rootTextMaxw
);
240 // Get the sentence texts
241 _UserSentenceName
= dynamic_cast<CGroupEditBox
*>(CInterfaceGroup::getGroup("eb_spell_name:eb"));
244 _SpellView
= dynamic_cast<CDBCtrlSheet
*>(CInterfaceGroup::getCtrl( "spell_view" ));
248 // ***************************************************************************
249 void CDBGroupBuildPhrase::draw ()
251 CInterfaceGroup::draw();
255 // ***************************************************************************
256 const CSBrickSheet
*CDBGroupBuildPhrase::getRootBrick()
261 return _MainWords
[0].Slot
.Brick
->asSBrickSheet();
265 // ***************************************************************************
266 // ***************************************************************************
268 // ***************************************************************************
269 // ***************************************************************************
272 // ***************************************************************************
273 void CDBGroupBuildPhrase::clearBuildingPhrase()
279 _MainWords
[0].reset();
280 _MainWords
[0].setBrick(0);
281 updateDisplayFromRootBrick();
284 if(_UserSentenceName
)
286 _UserSentenceName
->setInputString(std::string());
294 // ***************************************************************************
295 void CDBGroupBuildPhrase::startComposition(const CSPhraseCom
&phrase
)
299 CSBrickManager
*pBM
= CSBrickManager::getInstance();
304 // if phrase empty (new phrase), invent a new name
307 // build a default name
308 name
= CI18N::get("uimPhraseNew");
309 // Append a dummy number
311 name
+= " " + toString(_NewSpellNumber
);
313 m_IconIndex
= std::numeric_limits
<uint8
>::max();
318 name
= phrase
.Name
.toUtf8();
319 m_IconIndex
= phrase
.IconIndex
;
321 // get the root Brick. Must exist.
322 CSBrickSheet
*rootBrick
= pBM
->getBrick(phrase
.Bricks
[0]);
325 // Phrase to Ctrls: simulate clicks!
326 uint curBrickIndex
= 1;
327 uint brickIndexForParam
= 0;
331 // simulate a root selection
332 validateRoot(rootBrick
);
333 // setup params of the root
334 numParam
= (uint
)rootBrick
->ParameterFamilies
.size();
335 brickIndexForParam
= 0;
337 // For all brick not the root
338 for(uint i
=1;i
<phrase
.Bricks
.size();i
++)
340 CSBrickSheet
*brick
= pBM
->getBrick(phrase
.Bricks
[i
]);
342 /* NB: the ORDER is important for grammar checkup
343 Must come first Root / Mandatory, then credit or optionals.
344 Each params must follow its related brick
345 Parameters May also have their own parameters
346 This is recursive, param sons may have params sons.
350 if(curParam
<numParam
)
352 validateParam(brickIndexForParam
, curParam
, brick
);
354 // If this parameter has additonal parameter they follow
355 if( brick
&& !brick
->ParameterFamilies
.empty() )
356 numParam
+= (uint
)brick
->ParameterFamilies
.size();
358 // a mandatory/optional/credit?
361 // must be a mandatory?
362 if(curBrickIndex
<1+_NumMandatories
)
363 validateMain(curBrickIndex
, brick
);
364 // create a new optional/credit
366 validateNewOpCredit(brick
);
368 // bkup index for param, and increment
369 brickIndexForParam
= curBrickIndex
;
371 // following bricks are its param!
375 numParam
= (uint
)brick
->ParameterFamilies
.size();
381 // set the editable name.
382 if(_UserSentenceName
)
383 _UserSentenceName
->setInputString(name
);
387 // ***************************************************************************
388 // ***************************************************************************
389 // Start Selection of Bricks
390 // ***************************************************************************
391 // ***************************************************************************
394 // ***************************************************************************
395 void CDBGroupBuildPhrase::fillSelectionRoot()
397 // the root must be OK.
398 if(!_GroupValid
) return;
399 CSBrickManager
*pBM
= CSBrickManager::getInstance();
401 // fillSelection with all root
402 std::vector
<CSheetId
> bricks
;
403 bricks
= pBM
->getRootBricks();
404 // get only ones known
405 filterKnownBricks(bricks
);
406 // get only ones that match The BrickType filter
407 filterRootBrickType(bricks
);
408 // some additional root filter
409 filterRootPossibles(bricks
);
411 fillSelection(bricks
);
413 // ***************************************************************************
414 void CDBGroupBuildPhrase::fillSelectionMain(uint index
)
417 // the root must be OK.
418 if(!_GroupValid
) return;
419 const CSBrickSheet
*rootBrick
= getRootBrick();
420 if(!rootBrick
) return;
421 CSBrickManager
*pBM
= CSBrickManager::getInstance();
424 if(index
>=_MainWords
.size())
430 // get the current Brick.
431 std::vector
<CSheetId
> bricks
;
432 const CSBrickSheet
*brick
= _MainWords
[index
].Slot
.Brick
->asSBrickSheet();
435 // It is possible for Mandatory that this brick is still not validated
436 if(index
<1+_NumMandatories
)
438 // get the related family and bricks associated to it
439 bricks
= pBM
->getFamilyBricks(rootBrick
->MandatoryFamilies
[index
-1]);
449 // fill selection with all bricks of the same family (whatever the main brick)
450 bricks
= pBM
->getFamilyBricks(brick
->BrickFamily
);
453 // get only ones known
454 filterKnownBricks(bricks
);
456 // For mandatories, filter effects
457 CSPhraseCom currentPhrase
;
458 buildCurrentPhrase(currentPhrase
);
459 pBM
->getSabrinaCom().filterMandatoryComposition(currentPhrase
.Bricks
, bricks
);
461 // For Combat Optional, must filter by exclusion and combat exclusion
462 if(brick
&& brick
->isCombat() && brick
->isOptional() )
464 // Ensure not same bricks are setuped. Also don't insert me since I am already here...
465 filterBrickSetuped(bricks
);
466 // Ensure only optional of compatible Skill are inserted. Don't test with me, since i may be removed!
467 filterSkillSetuped(bricks
, true, false, index
);
469 // for power optional, must filter by brick
470 else if(brick
&& brick
->isSpecialPower() && (brick
->isOptional()||brick
->isMandatory()) )
472 // Ensure not same bricks are setuped. Also don't insert me since I am already here...
473 filterBrickSetuped(bricks
);
476 // For optional or credit, filter by BrickExclusion.
477 if(index
>=1/*+_NumMandatories*/)
478 filterBrickExclusion(bricks
, index
);
480 // For Optional/Credits, must append first the special "Remove Brick" choice
481 if(index
>=1+_NumMandatories
)
483 bricks
.insert(bricks
.begin(), pBM
->getInterfaceRemoveBrick());
487 fillSelection(bricks
);
490 // ***************************************************************************
491 void CDBGroupBuildPhrase::fillSelectionParam(uint index
, uint paramIndex
)
493 // the root must be OK.
494 if(!_GroupValid
) return;
495 const CSBrickSheet
*rootBrick
= getRootBrick();
496 if(!rootBrick
) return;
497 CSBrickManager
*pBM
= CSBrickManager::getInstance();
500 if( index
>=_MainWords
.size() || paramIndex
>=MaxParam
)
506 // get the current Brick.
507 const CSBrickSheet
*brick
;
508 brick
= _MainWords
[index
].ParamSlot
[paramIndex
].Brick
->asSBrickSheet();
514 // fill selection with all bricks of the same family (whatever the root)
515 std::vector
<CSheetId
> bricks
;
516 bricks
= pBM
->getFamilyBricks(brick
->BrickFamily
);
517 // get only ones known
518 filterKnownBricks(bricks
);
520 fillSelection(bricks
);
523 // ***************************************************************************
524 void CDBGroupBuildPhrase::fillSelectionNewOp()
526 // the root must be OK.
527 if(!_GroupValid
) return;
528 const CSBrickSheet
*rootBrick
= getRootBrick();
529 if(!rootBrick
) return;
531 // Build a brick array of possible new bricks.
532 std::vector
<NLMISC::CSheetId
> bricks
;
533 fillNewOptionalBricks(bricks
);
536 fillSelection(bricks
);
540 // ***************************************************************************
541 void CDBGroupBuildPhrase::fillSelectionNewCredit()
543 // the root must be OK.
544 if(!_GroupValid
) return;
545 const CSBrickSheet
*rootBrick
= getRootBrick();
546 if(!rootBrick
) return;
548 // Build a brick array of possible new bricks.
549 std::vector
<NLMISC::CSheetId
> bricks
;
550 fillNewCreditBricks(bricks
);
553 fillSelection(bricks
);
557 // ***************************************************************************
558 // ***************************************************************************
559 // Validate Selection of Bricks
560 // ***************************************************************************
561 // ***************************************************************************
564 // ***************************************************************************
565 void CDBGroupBuildPhrase::validateRoot(const CSBrickSheet
*sheet
)
567 // the root must be OK.
568 if(!_GroupValid
) return;
570 // If same brick no op
571 if(getRootBrick() == sheet
)
574 // reset the whole sentence with default values
575 resetSentence(sheet
->Id
.asInt());
577 // update the display
582 // ***************************************************************************
583 void CDBGroupBuildPhrase::validateMain(uint index
, const CSBrickSheet
*sheet
)
586 // the root must be OK.
587 if(!_GroupValid
) return;
588 const CSBrickSheet
*rootBrick
= getRootBrick();
589 if(!rootBrick
) return;
590 CSBrickManager
*pBM
= CSBrickManager::getInstance();
592 // If the brick chosen is actually the "Remove Brick", then call the correct method
593 if(sheet
->Id
== pBM
->getInterfaceRemoveBrick())
595 deleteOpCredit(index
);
601 _MainWords
[index
].setBrick(sheet
->Id
.asInt());
603 // must update params if change!
606 // update the display
610 // ***************************************************************************
611 void CDBGroupBuildPhrase::validateParam(uint index
, uint paramIndex
, const CSBrickSheet
*sheet
)
613 // the root must be OK.
614 if(!_GroupValid
) return;
615 const CSBrickSheet
*rootBrick
= getRootBrick();
616 if(!rootBrick
) return;
617 if(paramIndex
>=MaxParam
) return;
619 // The setuped parameter may have also parameter sons
620 bool mustResetParamHrc
= false;
621 vector
<uint16
> newParamSons
;
622 if(sheet
) newParamSons
= sheet
->ParameterFamilies
;
623 mustResetParamHrc
= newParamSons
!= _MainWords
[index
].ParamSlot
[paramIndex
].ViewParamFamilies
;
628 _MainWords
[index
].setParamBrick(paramIndex
, sheet
->Id
.asInt());
631 // update the param sons
632 if(mustResetParamHrc
)
633 updateParamHrc(index
);
635 // update the display
639 // ***************************************************************************
640 void CDBGroupBuildPhrase::validateNewOpCredit(const CSBrickSheet
*sheet
)
642 // the root must be OK.
643 if(!_GroupValid
) return;
644 const CSBrickSheet
*rootBrick
= getRootBrick();
645 if(!rootBrick
) return;
650 // we should not have to do this test...
651 if(getNumMainBricks()>=_MainWords
.size())
654 // get the dest index.
657 if(sheet
->isCredit())
658 index
= 1+_NumMandatories
+_NumOptionals
+_NumCredits
;
659 // else optional brick
661 index
= 1+_NumMandatories
+_NumOptionals
;
663 // Shift Optional Row. Copy the Brick setup from index to index+1.
664 for(uint i
= getNumMainBricks();i
>index
;i
--)
666 _MainWords
[i
].copySetup(_MainWords
[i
-1]);
670 _MainWords
[index
].setBrick(sheet
->Id
.asInt());
672 // Increment the number of options/credits setuped!
673 if(sheet
->isCredit())
678 // update the NewOp controler
681 // must update params if change!
684 // update the display
688 // ***************************************************************************
689 void CDBGroupBuildPhrase::deleteOpCredit(uint index
)
692 // the root must be OK.
693 if(!_GroupValid
) return;
694 const CSBrickSheet
*rootBrick
= getRootBrick();
695 if(!rootBrick
) return;
699 if(index
>=1+_NumMandatories
&& index
<1+_NumMandatories
+_NumOptionals
)
701 else if(index
>=1+_NumMandatories
+_NumOptionals
&& index
<getNumMainBricks() )
706 // Shift Optional Row. Copy the Brick setup from index+1 to index.
707 for(uint i
= index
+1;i
<getNumMainBricks();i
++)
709 _MainWords
[i
-1].copySetup(_MainWords
[i
]);
712 // reset the last row display
713 _MainWords
[getNumMainBricks()-1].reset();
715 // an optional/credit is removed!
721 // update the NewOp ctrl
724 // update the display
728 // ***************************************************************************
729 void CDBGroupBuildPhrase::setPhraseIcon(uint8 index
)
732 buildCurrentPhrase(phrase
);
734 if (index
< phrase
.Bricks
.size())
737 m_IconIndex
= std::numeric_limits
<uint8
>::max();
743 // ***************************************************************************
744 // ***************************************************************************
746 // ***************************************************************************
747 // ***************************************************************************
750 // ***************************************************************************
751 static uint
getLowestBit(uint64 val
)
765 // ***************************************************************************
766 static void getDefaultSheetForFamily(uint familyId
, sint32
&sheet
, bool &valid
)
768 CSBrickManager
*pBM
= CSBrickManager::getInstance();
770 uint64 knownBF
= pBM
->getKnownBrickBitField(familyId
);
774 // default: get the lowest sheet
775 sint posInFamily
= getLowestBit(knownBF
);
778 sheet
= pBM
->getBrickSheet(familyId
, posInFamily
).asInt();
783 // setup the Sheet with the lowest brick
784 sheet
= pBM
->getBrickSheet(familyId
, 0).asInt();
785 // invalidate the word
791 // ***************************************************************************
792 void CDBGroupBuildPhrase::updateParams(uint index
)
796 if(index
<_MainWords
.size())
797 word
= &_MainWords
[index
];
801 // Get the Brick setuped. may be NULL for unsetuped mandatories
802 const CSBrickSheet
*brick
= word
->Slot
.Brick
->asSBrickSheet();
804 // retrieve brick paramFamilies
805 vector
<uint16
> paramFamilies
;
807 paramFamilies
= brick
->ParameterFamilies
;
809 // if param families of the new brick different from what setuped in view, reset all param hierachy
810 if(word
->Slot
.ViewParamFamilies
!= paramFamilies
)
812 // must reset the view of parameters
815 // and compute all from setuped main brick
816 updateParamHrc(index
);
821 // ***************************************************************************
822 /* used for updateParamHrc()
828 const CSBrickSheet
*Brick
;
830 std::vector
<uint16
> ViewParamFamilies
;
831 CParamTreeNode
*Parent
;
832 std::vector
<CParamTreeNode
*> Sons
;
835 CParamTreeNode(CParamTreeNode
*parent
) : Brick(NULL
), Valid(true), Parent(parent
) {}
846 for(uint i
=0;i
<Sons
.size();i
++) delete Sons
[i
];
850 // rebuild default param sons (recurs) if BrickParamFamilies and ViewParamFamilies differ.
851 // return false if error
852 bool synchronizeParams(uint maxDepth
)
857 // get the brick Parameter Families.
858 vector
<uint16
> brickParamFamilies
;
860 brickParamFamilies
= Brick
->ParameterFamilies
;
861 // compare with the current View one. if equals then OK! just recurs test sons
862 if(brickParamFamilies
== ViewParamFamilies
)
864 for(uint i
=0;i
<Sons
.size();i
++)
866 if(!Sons
[i
]->synchronizeParams(maxDepth
-1))
871 // else must rebuild all this branch
874 return buildSonsFromBrick(maxDepth
);
878 // build the son list from brick Setup, and recurs
879 // return false if error
880 bool buildSonsFromBrick(uint maxDepth
)
885 CSBrickManager
*pBM
= CSBrickManager::getInstance();
887 // first delete my sons, and any old view setup
889 ViewParamFamilies
.clear();
891 // then copy brick families to view families (=> view synchronized to brick)
893 ViewParamFamilies
= Brick
->ParameterFamilies
;
895 // Add a default Son for each family
897 for(i
=0;i
<ViewParamFamilies
.size();i
++)
899 uint familyId
= ViewParamFamilies
[i
];
902 // bkup the valid state in this node
903 getDefaultSheetForFamily(familyId
, sheet
, sonValid
);
906 CParamTreeNode
*sonNode
= new CParamTreeNode(this);
907 sonNode
->Brick
= pBM
->getBrick(CSheetId(sheet
));
908 sonNode
->Valid
= sonValid
;
909 // add this son to its father
910 Sons
.push_back(sonNode
);
914 for(i
=0;i
<Sons
.size();i
++)
916 if(!Sons
[i
]->buildSonsFromBrick(maxDepth
- 1))
923 // build the word raw param list from hierarchy
924 // return false if error
925 bool buildRawParamList(CDBGroupBuildPhrase::CWord
&word
, uint
&rawParamIndex
)
927 // If this is the root
930 // just copy the ViewParamFamilies
931 word
.Slot
.ViewParamFamilies
= ViewParamFamilies
;
933 // else, add this parameter to list
936 // Check possible Brick Data error
937 if(rawParamIndex
>= CDBGroupBuildPhrase::MaxParam
)
939 nlwarning("BRICK ERROR: Not enough param Space (%d) to add all son parameter", CDBGroupBuildPhrase::MaxParam
);
943 // Setup this brick in the param list
947 word
.setParamBrick(rawParamIndex
, sheet
.asInt());
948 word
.ParamSlot
[rawParamIndex
].Valid
= Valid
;
949 word
.ParamSlot
[rawParamIndex
].Brick
->setGrayed( !Valid
);
951 // bkup its ViewParameters
952 word
.ParamSlot
[rawParamIndex
].ViewParamFamilies
= ViewParamFamilies
;
958 // for all sons, recurs
959 for(uint i
=0;i
<Sons
.size();i
++)
962 if(!Sons
[i
]->buildRawParamList(word
, rawParamIndex
))
971 // ***************************************************************************
972 void CDBGroupBuildPhrase::updateParamHrc(uint index
)
975 When we are here, we may have some Parameter Hierarchy inconsitency between the ViewParameterFamilies and
976 the Brick parameter Families.
977 we must fix them and rebuild all the raw param list
981 if(index
<_MainWords
.size())
982 word
= &_MainWords
[index
];
986 // If a Param error has already been detected on this Slot, no-op
991 // **** From the current View setup of 'word', build the Parameter Hierarchy (in simple tree form)
992 CParamTreeNode
rootNode(NULL
);
993 // NB: here rootNode represent the Main (ie mandatory, optional or credit) brick. Therefore, it is not a real parameter.
994 rootNode
.Brick
= word
->Slot
.Brick
->asSBrickSheet();
995 rootNode
.Valid
= true;
996 rootNode
.ViewParamFamilies
= word
->Slot
.ViewParamFamilies
;
997 uint rawParamIndex
= 0;
998 CParamTreeNode
*curNode
= &rootNode
;
1001 // if this node still need sons, then the next raw index param must be a son of curNode
1002 if(curNode
->Sons
.size() < curNode
->ViewParamFamilies
.size())
1004 nlassert(rawParamIndex
< word
->NumTotalParams
);
1005 // create a son node, and fill from rawList
1006 CParamTreeNode
*sonNode
= new CParamTreeNode(curNode
);
1007 sonNode
->Brick
= word
->ParamSlot
[rawParamIndex
].Brick
->asSBrickSheet();
1008 sonNode
->Valid
= word
->ParamSlot
[rawParamIndex
].Valid
;
1009 sonNode
->ViewParamFamilies
= word
->ParamSlot
[rawParamIndex
].ViewParamFamilies
;
1010 // append to the sons
1011 curNode
->Sons
.push_back(sonNode
);
1017 // else the next must be a brother: return to parent
1019 curNode
= curNode
->Parent
;
1021 // we must have run all the raw list
1022 nlassert(rawParamIndex
== word
->NumTotalParams
);
1023 nlassert(rootNode
.Sons
.size() == word
->Slot
.ViewParamFamilies
.size());
1026 // **** Parse the Parameter tree, and invalidate each branch where View families and Brick families differs.
1027 // Avoid .sbrick data erros: allow only a max recurs level of 10
1028 if(!rootNode
.synchronizeParams(10))
1030 // in this case, ABORT, but don't crash: setup 0 parameters...
1031 word
->resetParams();
1032 word
->ParamError
= true;
1037 // **** rebuild completely the parameter list from the parameter tree.
1039 word
->resetParams();
1042 if(rootNode
.buildRawParamList(*word
, rawParamIndex
))
1044 // then the new NumTotalParams is....
1045 word
->NumTotalParams
= rawParamIndex
;
1050 // in this case, ABORT, but don't crash: setup 0 parameters...
1051 word
->resetParams();
1052 word
->ParamError
= true;
1059 // ***************************************************************************
1060 void CDBGroupBuildPhrase::updateAllDisplay(const CSPhraseCom
&phrase
)
1062 // NB: phrase MUST COME FROM buildCurrentPhrase() else doesn't work.
1064 CSBrickManager
*pBM
= CSBrickManager::getInstance();
1065 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1066 CSPhraseManager
*pPM
= CSPhraseManager::getInstance();
1068 // **** update total cost
1069 // get the cost and credit
1070 uint32 totalCost
, totalCredit
;
1071 pBM
->getSabrinaCom().getPhraseCost(phrase
.Bricks
, totalCost
, totalCredit
);
1074 NLGUI::CDBManager::getInstance()->getDbProp("UI:PHRASE:BUILD:TOTAL_COST")->setValue32(totalCost
);
1075 NLGUI::CDBManager::getInstance()->getDbProp("UI:PHRASE:BUILD:TOTAL_CREDIT")->setValue32(totalCredit
);
1077 // **** Update the Cost of All Root/Mandat/ops/Credits.
1078 if(phrase
.Bricks
.size())
1080 // Parse the phrase, and setup the related Cost.
1081 uint curBrickIndex
= 0;
1082 for(uint i
=0;i
<phrase
.Bricks
.size();)
1085 CSBrickSheet
*brick
= pBM
->getBrick(phrase
.Bricks
[i
]);
1086 // if not found, skip it (eg important for mandatories not setuped)
1093 // get the cost for this brick and its params.
1095 float relative_cost
;
1096 cost
= pBM
->getSabrinaCom().getPhraseBrickAndParamCost(phrase
.Bricks
, i
);
1097 relative_cost
= pBM
->getSabrinaCom().getPhraseBrickAndParamRelativeCost(phrase
.Bricks
, i
);
1098 std::string costText
;
1099 if( cost
== 0 && relative_cost
!= 0.f
)
1101 cost
= (sint32
)(relative_cost
* 100.f
);
1102 costText
= toString("%+d", cost
) + string("%");
1105 costText
= toString("%+d", cost
);
1107 // set the MainWord cost
1110 _MainWords
[curBrickIndex
].CostView
->setActive(true);
1111 _MainWords
[curBrickIndex
].CreditView
->setActive(false);
1112 _MainWords
[curBrickIndex
].CostView
->setText(costText
);
1116 _MainWords
[curBrickIndex
].CreditView
->setActive(true);
1117 _MainWords
[curBrickIndex
].CostView
->setActive(false);
1118 _MainWords
[curBrickIndex
].CreditView
->setText(costText
);
1121 // Next brick: skip me and my params
1122 i
+= 1 + _MainWords
[curBrickIndex
].NumTotalParams
;
1125 // next slot to setup. if all slots setuped, break.
1127 if(curBrickIndex
>=getNumMainBricks())
1132 // **** Additionaly Update the Info Text
1133 for(uint i
=0;i
<1+_NumMandatories
;i
++)
1135 CWord
&word
= _MainWords
[i
];
1136 // If the brick is setuped, hide the info text, else display
1137 if( word
.Slot
.Brick
->asSBrickSheet() )
1138 word
.InfoView
->setActive(false);
1141 word
.InfoView
->setActive(true);
1143 word
.InfoView
->setText( CI18N::get("uiTextHelpSelectRootBrick") );
1145 // start effect index at 1 (human readable :) )
1146 word
.InfoView
->setText( CI18N::get("uiTextHelpSelectEffectBrick") + toString(i
) );
1150 // **** Additionaly Update the New Buttons
1151 bool mandatOk
= true;
1152 // If only one of root effect is not setuped...
1153 for(uint i
=0;i
<1+_NumMandatories
;i
++)
1155 CWord
&word
= _MainWords
[i
];
1156 if( !word
.Slot
.Brick
->asSBrickSheet() )
1159 // set DB value accordeing to it.
1160 NLGUI::CDBManager::getInstance()->getDbProp("UI:PHRASE:BUILD:ROOT_EFFECT_VALID")->setValue32(mandatOk
);
1162 // update valid button
1167 // valid only if all mandat active and cost ok
1168 active
= totalCredit
>=totalCost
&& mandatOk
;
1170 // valid only if All bricks exist, and are known
1172 for(i
=0;i
<phrase
.Bricks
.size();i
++)
1175 CSBrickSheet
*brick
= pBM
->getBrick(phrase
.Bricks
[i
]);
1176 if(!brick
|| !pBM
->isBrickKnown(brick
->Id
))
1183 // valid only if no parameter error has been encountered
1184 for(i
=0;i
<1+_NumMandatories
+_NumOptionals
+_NumCredits
;i
++)
1186 if(_MainWords
[i
].ParamError
)
1193 // If OK, still do some check
1196 const CSBrickSheet
*brick
= getRootBrick();
1200 else if( brick
->MandatoryFamilies
.size()+1>_MainWords
.size() )
1204 _ValidateButton
->setFrozen(!active
);
1208 // **** Additionaly Update the Combat Restrict options
1209 // Get the rootBrick
1210 const CSBrickSheet
*rootBrick
= getRootBrick();
1211 if(rootBrick
&& rootBrick
->isCombat())
1213 // show the weapon restriction interface
1214 NLGUI::CDBManager::getInstance()->getDbProp("UI:PHRASE:BUILD:RESTRICT_COMBAT:ENABLED")->setValue32(1);
1216 // If not already done, retrieve the weapon skills, and fill the sbricks SHEET
1217 if(_WeaponSkills
.empty())
1219 // get define, and verify data
1220 uint numWeaponSkill
;
1221 fromString(CWidgetManager::getInstance()->getParser()->getDefine("phrase_max_restrict_combat"), numWeaponSkill
);
1222 string strWeaponSkill
= CWidgetManager::getInstance()->getParser()->getDefine("phrase_def_skill_restrict_combat");
1223 vector
<string
> weaponSkillList
;
1224 splitString(strWeaponSkill
, " ", weaponSkillList
);
1225 nlassert(weaponSkillList
.size()==numWeaponSkill
);
1227 // NOTE TO CODER WHO CHANGE SKILLS::ESkill. If you change combat skills, ask yoyo for modification
1228 // or search "phrase_def_skill_restrict_combat" and "phrase_max_restrict_combat" in XML.
1229 nlctassert( SKILLS::SFM1SSM
&& SKILLS::SFM1SAM
&& SKILLS::SFM1BMM
&& SKILLS::SFM1BSM
&&
1230 SKILLS::SFM1PSM
&& SKILLS::SFM2SSM
&& SKILLS::SFM2SAM
&& SKILLS::SFM2BMM
&&
1231 SKILLS::SFM2PPM
&& SKILLS::SFMCADM
&& SKILLS::SFMCAHM
&& SKILLS::SFR1APM
&&
1232 SKILLS::SFR2AAM
&& SKILLS::SFR2ALM
&& SKILLS::SFR2ARM
);
1233 nlctassert(SKILLS::SH
- SKILLS::SF
== 47);
1235 // backup the skill array, and fill the associated brick in interface
1236 _WeaponSkills
.resize(numWeaponSkill
);
1237 for(uint i
=0;i
<numWeaponSkill
;i
++)
1239 _WeaponSkills
[i
]= SKILLS::toSkill(weaponSkillList
[i
]);
1241 // Get the associated brick
1242 uint32 viewBrickCombatSheetId
= pBM
->getVisualBrickForSkill(_WeaponSkills
[i
]).asInt();
1245 NLGUI::CDBManager::getInstance()->getDbProp(toString("UI:PHRASE:BUILD:RESTRICT_COMBAT:%d:SHEET", i
))->setValue32(viewBrickCombatSheetId
);
1249 // For each weapon skill, test if match or not the current phrase
1250 for(uint i
=0;i
<_WeaponSkills
.size();i
++)
1252 bool ok
= pPM
->skillCompatibleWithCombatPhrase(_WeaponSkills
[i
], phrase
.Bricks
);
1253 NLGUI::CDBManager::getInstance()->getDbProp(toString("UI:PHRASE:BUILD:RESTRICT_COMBAT:%d:LOCKED", i
))->setValue32(!ok
);
1258 // hide the weapon restriction interface
1259 NLGUI::CDBManager::getInstance()->getDbProp("UI:PHRASE:BUILD:RESTRICT_COMBAT:ENABLED")->setValue32(0);
1262 // **** Setup the phrase Desc
1266 pPM
->buildPhraseDesc(text
, phrase
, 0, false, "composition");
1267 _TextPhraseDesc
->setTextFormatTaged(text
);
1271 uint nbBricks
= phrase
.Bricks
.size();
1273 fromString(CWidgetManager::getInstance()->getParser()->getDefine("phrase_max_brick"), maxBricks
);
1275 NLGUI::CDBManager::getInstance()->getDbProp("UI:PHRASE:BUILD:ICON:0:SHEET")->setValue32(pBM
->getInterfaceRemoveBrick().asInt());
1276 NLGUI::CDBManager::getInstance()->getDbProp("UI:PHRASE:BUILD:ICON:0:INDEX")->setValue32(maxBricks
);
1278 std::set
< std::pair
<uint64
, uint64
> > dupcheck
;
1279 for(uint i
= 0, j
= 1; i
< maxBricks
; i
++)
1283 CSBrickSheet
*pBR
= pBM
->getBrick(phrase
.Bricks
[i
]);
1286 // ignore back icon, as its replaced anyway
1287 uint64 key1
= ((uint64
)pBR
->IdIcon
<< 32) | pBR
->IconColor
.getPacked();
1288 uint64 key2
= ((uint64
)pBR
->IdIconOver
<< 32) | pBR
->IdIconOver2
;
1290 if (dupcheck
.insert(make_pair(key1
, key2
)).second
)
1292 NLGUI::CDBManager::getInstance()->getDbProp(toString("UI:PHRASE:BUILD:ICON:%d:SHEET", j
))->setValue32(phrase
.Bricks
[i
].asInt());
1293 NLGUI::CDBManager::getInstance()->getDbProp(toString("UI:PHRASE:BUILD:ICON:%d:INDEX", j
))->setValue32(i
);
1299 nlwarning("Invalid CSBrickSheet (%d:%s)", phrase
.Bricks
[i
].asInt(), phrase
.Bricks
[i
].toString().c_str());
1304 NLGUI::CDBManager::getInstance()->getDbProp(toString("UI:PHRASE:BUILD:ICON:%d:SHEET", j
))->setValue32(0);
1310 // **** Since some bricks may have changed, update the spell view
1316 // ***************************************************************************
1317 void CDBGroupBuildPhrase::updateAllDisplay()
1319 // build the current phrase
1320 CSPhraseCom newPhrase
;
1321 buildCurrentPhrase(newPhrase
);
1322 updateAllDisplay(newPhrase
);
1326 // ***************************************************************************
1327 void CDBGroupBuildPhrase::resetSelection()
1329 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1331 for(uint i
=0;i
<MaxSelection
;i
++)
1333 NLGUI::CDBManager::getInstance()->getDbProp(BrickSelectionDB
+ ":" + toString(i
) + ":SHEET")->setValue32(0);
1337 // ***************************************************************************
1338 void CDBGroupBuildPhrase::fillSelection(const std::vector
<CSheetId
> &bricks
)
1340 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1342 uint num
= min((uint
)MaxSelection
, (uint
)bricks
.size());
1343 for(uint i
=0;i
<MaxSelection
;i
++)
1346 NLGUI::CDBManager::getInstance()->getDbProp(BrickSelectionDB
+ ":" + toString(i
) + ":SHEET")->setValue32(bricks
[i
].asInt());
1348 NLGUI::CDBManager::getInstance()->getDbProp(BrickSelectionDB
+ ":" + toString(i
) + ":SHEET")->setValue32(0);
1352 // ***************************************************************************
1353 void CDBGroupBuildPhrase::filterKnownBricks(std::vector
<CSheetId
> &bricks
)
1355 CSBrickManager
*pBM
= CSBrickManager::getInstance();
1357 pBM
->filterKnownBricks(bricks
);
1360 // ***************************************************************************
1361 void CDBGroupBuildPhrase::filterBrickExclusion(std::vector
<CSheetId
> &bricks
, uint16 indexToSkip
)
1363 CSBrickManager
*pBM
= CSBrickManager::getInstance();
1365 std::vector
<CSheetId
> res
;
1366 res
.reserve(bricks
.size());
1368 static vector
<string
> forbidWords(30);
1370 // For All optionals/credits setuped, build the Exclude Set
1371 set
<string
> excludeSet
;
1372 // test for all bricks
1373 for(uint j
=1/*+_NumMandatories*/;j
<1+_NumMandatories
+_NumOptionals
+_NumCredits
;j
++)
1375 // skip brick at index indexToSkip (if replacing a brick for example, don't consider it's forbiden flags)
1376 if (j
== indexToSkip
)
1379 const CSBrickSheet
*brick
= _MainWords
[j
].Slot
.Brick
->asSBrickSheet();
1383 forbidWords
.clear();
1384 splitString(brick
->getForbiddenExclude(), ":", forbidWords
);
1385 // for all words, insert in the set.
1386 for(uint j
=0;j
<forbidWords
.size();j
++)
1387 excludeSet
.insert(forbidWords
[j
]);
1391 // keep only unfiltered ones
1392 for(uint i
=0;i
<bricks
.size();i
++)
1394 const CSBrickSheet
*brick
= pBM
->getBrick(bricks
[i
]);
1397 // For all define words, search if excluded from the current set of optional setup
1398 forbidWords
.clear();
1399 splitString(brick
->getForbiddenDef(), ":", forbidWords
);
1401 for(uint j
=0;j
<forbidWords
.size();j
++)
1403 if(excludeSet
.find(forbidWords
[j
]) != excludeSet
.end() )
1412 res
.push_back(bricks
[i
]);
1416 // replace with filtered one
1421 // ***************************************************************************
1422 void CDBGroupBuildPhrase::filterFamilySetuped(std::vector
<uint16
> &families
)
1424 std::vector
<uint16
> res
;
1425 res
.reserve(families
.size());
1427 // keep only unsetuped ones
1428 for(uint i
=0;i
<families
.size();i
++)
1430 uint family
= families
[i
];
1433 // test for all opionals/Credits
1434 for(uint j
=1+_NumMandatories
;j
<getNumMainBricks();j
++)
1436 const CSBrickSheet
*brick
= _MainWords
[j
].Slot
.Brick
->asSBrickSheet();
1437 if(brick
&& brick
->BrickFamily
==(sint
)family
)
1444 // insert only if not found
1447 res
.push_back(family
);
1451 // replace with filtered one
1455 // ***************************************************************************
1456 void CDBGroupBuildPhrase::filterBrickSetuped(std::vector
<NLMISC::CSheetId
> &bricks
)
1458 std::vector
<CSheetId
> res
;
1459 res
.reserve(bricks
.size());
1461 // keep only unsetuped ones
1462 for(uint i
=0;i
<bricks
.size();i
++)
1464 CSheetId brick
= bricks
[i
];
1467 // test for all bricks
1468 for(uint j
=1/*+_NumMandatories*/;j
<getNumMainBricks();j
++)
1470 if(brick
== CSheetId(_MainWords
[j
].Slot
.Brick
->getSheetId()) )
1477 // insert only if not found
1480 res
.push_back(brick
);
1484 // replace with filtered one
1489 // ***************************************************************************
1490 void CDBGroupBuildPhrase::filterSkillSetuped(std::vector
<NLMISC::CSheetId
> &bricks
, bool checkOptional
, bool checkCredit
, sint avoidCheckIndex
)
1492 // check nothing => return.
1493 if(!checkOptional
&& !checkCredit
)
1496 CSBrickManager
*pBM
= CSBrickManager::getInstance();
1499 // **** build the compatible skill formula for the bricks we want to check
1500 CReqSkillFormula testFormula
;
1501 uint checkStart
= checkOptional
? 1+_NumMandatories
: 1+_NumMandatories
+_NumOptionals
;
1502 uint checkEnd
= checkCredit
? 1+_NumMandatories
+_NumOptionals
: getNumMainBricks();
1504 // test for all optionals and/or Credits
1506 for(uint i
= checkStart
;i
<checkEnd
;i
++)
1508 // For Replacement of brick, don't test with the brick replaced (suppose will be removed!)
1509 if(avoidCheckIndex
==(sint
)i
)
1512 const CSBrickSheet
*brick
= _MainWords
[i
].Slot
.Brick
->asSBrickSheet();
1513 // If bricks use a skill, and with the formula
1514 if(brick
&& brick
->getSkill()!=SKILLS::unknown
)
1516 CReqSkillFormula brickFormula
;
1517 for(uint j
=0;j
<brick
->UsedSkills
.size();j
++)
1519 brickFormula
.orV(CSkillValue(brick
->UsedSkills
[j
]));
1522 // and with the phraseFormula
1523 testFormula
.andV(brickFormula
);
1528 // **** check for each brick if compatible with this formula
1529 std::vector
<CSheetId
> res
;
1530 res
.reserve(bricks
.size());
1532 // keep only unsetuped ones
1533 for(i
=0;i
<bricks
.size();i
++)
1535 const CSBrickSheet
*brick
= pBM
->getBrick(bricks
[i
]);
1536 if(brick
&& brick
->getSkill()!=SKILLS::unknown
)
1538 // simulate a choose of this brick, ie AND its skill formula with the current phrase formula
1539 CReqSkillFormula brickFormula
;
1540 for(uint j
=0;j
<brick
->UsedSkills
.size();j
++)
1542 brickFormula
.orV(CSkillValue(brick
->UsedSkills
[j
]));
1545 CReqSkillFormula tempFormula
= testFormula
;
1546 tempFormula
.andV(brickFormula
);
1548 // Nb: the following test works if testFormula is empty(), because in this case
1549 // tempFormula.and(brickFormula)==brickFormula and hence is of form SFR | SFM | ....
1551 // if one of the ored skill has a size 1 (eg SFR&SFM fails), then it's ok!
1552 // else it's mean that there is no "skill on same branch solution".
1554 std::list
<CReqSkillFormula::CSkillValueAnd
>::iterator
it(tempFormula
.OrSkills
.begin()),
1555 end(tempFormula
.OrSkills
.end());
1558 CReqSkillFormula::CSkillValueAnd skillAnd
= *it
;
1559 // ok, there is still one usable skill
1560 if(skillAnd
.AndSkills
.size()==1)
1567 // insert only if ok
1570 res
.push_back(bricks
[i
]);
1575 // replace with filtered one
1581 // ***************************************************************************
1582 void CDBGroupBuildPhrase::filterRootBrickType(std::vector
<NLMISC::CSheetId
> &bricks
)
1585 if(_RootBrickTypeFilter
[0]==BRICK_TYPE::UNKNOWN
)
1588 CSBrickManager
*pBM
= CSBrickManager::getInstance();
1589 std::vector
<CSheetId
> res
;
1590 res
.reserve(bricks
.size());
1592 // keep only match ones
1593 for(uint i
=0;i
<bricks
.size();i
++)
1595 const CSBrickSheet
*brick0
= pBM
->getBrick(bricks
[i
]);
1598 // insert if one filter match (OR)
1599 for(uint j
=0;j
<MaxRootBrickTypeFilter
;j
++)
1601 if( _RootBrickTypeFilter
[j
] != BRICK_TYPE::UNKNOWN
&&
1602 _RootBrickTypeFilter
[j
] == BRICK_FAMILIES::brickType(brick0
->BrickFamily
) )
1604 res
.push_back(bricks
[i
]);
1611 // replace with filtered one
1616 // ***************************************************************************
1617 void CDBGroupBuildPhrase::filterRootPossibles(std::vector
<NLMISC::CSheetId
> &bricks
)
1619 CSBrickManager
*pBM
= CSBrickManager::getInstance();
1620 std::vector
<CSheetId
> res
;
1621 res
.reserve(bricks
.size());
1623 // keep only match ones
1624 for(uint i
=0;i
<bricks
.size();i
++)
1626 const CSBrickSheet
*brick0
= pBM
->getBrick(bricks
[i
]);
1629 // insert only if not a proc enchantment
1630 if(!brick0
->isProcEnchantment())
1631 res
.push_back(bricks
[i
]);
1635 // replace with filtered one
1640 // ***************************************************************************
1641 void CDBGroupBuildPhrase::CSlot::reset()
1643 // Must do the test for credits not setuped.
1646 Brick
->setActive(false);
1647 Brick
->setSheetId(0);
1648 Back
->setActive(false);
1652 ViewParamFamilies
.clear();
1655 // ***************************************************************************
1656 void CDBGroupBuildPhrase::CWord::resetParams()
1658 for(uint i
=0;i
<MaxParam
;i
++)
1659 ParamSlot
[i
].reset();
1660 // reset numParams to 0
1661 Slot
.ViewParamFamilies
.clear();
1666 // ***************************************************************************
1667 void CDBGroupBuildPhrase::CWord::reset()
1670 // reset also all params
1672 // Hide the Cost View
1673 CostView
->setActive(false);
1674 CreditView
->setActive(false);
1675 InfoView
->setActive(false);
1678 // ***************************************************************************
1679 void CDBGroupBuildPhrase::CWord::setBrick(uint32 sheetId
)
1681 Slot
.Brick
->setActive(true);
1682 Slot
.Brick
->setSheetId(sheetId
);
1683 Slot
.Back
->setActive(true);
1686 // ***************************************************************************
1687 void CDBGroupBuildPhrase::CWord::setParamBrick(uint param
, uint32 sheetId
)
1692 ParamSlot
[param
].Brick
->setActive(true);
1693 ParamSlot
[param
].Brick
->setSheetId(sheetId
);
1694 ParamSlot
[param
].Back
->setActive(true);
1697 // ***************************************************************************
1698 void CDBGroupBuildPhrase::CWord::copySetup(const CWord
&w
)
1704 setBrick(w
.Slot
.Brick
->getSheetId());
1705 Slot
.Valid
= w
.Slot
.Valid
;
1706 Slot
.ViewParamFamilies
= w
.Slot
.ViewParamFamilies
;
1709 NumTotalParams
= w
.NumTotalParams
;
1710 ParamError
= w
.ParamError
;
1711 for(uint i
=0;i
<NumTotalParams
;i
++)
1713 setParamBrick(i
, w
.ParamSlot
[i
].Brick
->getSheetId());
1714 ParamSlot
[i
].Valid
= w
.ParamSlot
[i
].Valid
;
1715 ParamSlot
[i
].ViewParamFamilies
= w
.ParamSlot
[i
].ViewParamFamilies
;
1719 CostView
->setText(w
.CostView
->getText());
1720 CostView
->setActive(w
.CostView
->getActive());
1721 CreditView
->setText(w
.CreditView
->getText());
1722 CreditView
->setActive(w
.CreditView
->getActive());
1723 InfoView
->setText(w
.InfoView
->getText());
1724 InfoView
->setActive(w
.InfoView
->getActive());
1728 // ***************************************************************************
1729 void CDBGroupBuildPhrase::resetSentence(sint32 rootSheetId
)
1736 // first update the root brick
1737 _MainWords
[0].setBrick(rootSheetId
);
1738 // then update display for others
1739 updateDisplayFromRootBrick();
1741 // get the root brick
1742 const CSBrickSheet
*rootBrick
= getRootBrick();
1747 // update parameters of the root
1750 // *** Init Mandatories
1751 for(i
=1;i
<1+_NumMandatories
;i
++)
1753 // get the family Known BitField
1754 uint familyId
= rootBrick
->MandatoryFamilies
[i
-1];
1757 getDefaultSheetForFamily(familyId
, sheet
, valid
);
1759 // Setup the ctrl sheet of mandatory to 0 by default!
1760 _MainWords
[i
].setBrick(0);
1761 _MainWords
[i
].Slot
.Valid
= valid
;
1763 // set the ctrl sheet display
1764 _MainWords
[i
].Slot
.Brick
->setGrayed( !valid
);
1766 // update the parameters of this main brick
1770 // *** Init Optional/Credits
1771 // ungray all optional slots.
1772 for(i
=1+_NumMandatories
;i
<_MainWords
.size();i
++)
1774 _MainWords
[i
].Slot
.Brick
->setGrayed( false );
1777 // update the NewOp controler
1782 // ***************************************************************************
1783 void CDBGroupBuildPhrase::updateDisplayFromRootBrick()
1790 // get the root bricks
1791 const CSBrickSheet
*brick
= getRootBrick();
1793 // Reset the Root params only (don't reset the sheetId setuped!)
1794 _MainWords
[0].resetParams();
1796 // Hide all other slots by default
1797 for(i
=1;i
<_MainWords
.size();i
++)
1799 _MainWords
[i
].reset();
1805 // if brick not found, or if not enough ctrl, hide all
1806 if(!brick
|| brick
->MandatoryFamilies
.size()+1>_MainWords
.size() )
1809 _MainWords
[0].Slot
.Brick
->setSheetId(0);
1811 // else ok, setup the composition
1814 _NumMandatories
= (uint32
)brick
->MandatoryFamilies
.size();
1815 // Don't enable any optional/credit by default
1820 // update the group and sons coords
1824 // ***************************************************************************
1825 void CDBGroupBuildPhrase::buildCurrentPhrase(CSPhraseCom
&newPhrase
)
1827 /* Word Order: Root/Mandatory/Optional/Credits (with all their params)
1831 newPhrase
.Name
.clear();
1832 newPhrase
.Bricks
.clear();
1834 const CSBrickSheet
*brick
;
1836 // Add All bricks with their parameters
1837 for(i
=0;i
<getNumMainBricks();i
++)
1839 CWord
&word
= _MainWords
[i
];
1840 brick
= word
.Slot
.Brick
->asSBrickSheet();
1841 newPhrase
.Bricks
.push_back(brick
?brick
->Id
:CSheetId());
1842 // For all its params.
1843 for(uint j
=0;j
<word
.NumTotalParams
;j
++)
1845 brick
= word
.ParamSlot
[j
].Brick
->asSBrickSheet();
1846 newPhrase
.Bricks
.push_back(brick
?brick
->Id
:CSheetId());
1851 if(_UserSentenceName
)
1853 newPhrase
.Name
= ucstring::makeFromUtf8(_UserSentenceName
->getInputString());
1856 newPhrase
.IconIndex
= m_IconIndex
;
1860 // ***************************************************************************
1861 void CDBGroupBuildPhrase::updateNewButtons()
1863 // TODO_BRICK: have I to hide button and their text if not possible to add any op/credit?
1868 uint newOpIndex= _NumMandatories+_NumOptionals;
1870 // if some place for a new optional, show and place the NewOpButton
1871 if(newOpIndex<_MandOpWords.size())
1873 // if comes from a delete, ensure the back+1 is hidden
1874 if(newOpIndex+1<_MandOpWords.size())
1876 _MandOpWords[newOpIndex+1].Slot.Back->setActive(false);
1879 // Show a new Optional possibilty ONLY if really possible!!
1880 std::vector<NLMISC::CSheetId> bricks;
1881 fillNewOptionalBricks(bricks);
1882 // if no choice possible
1885 _NewOpButton->setActive(false);
1889 // show the Back under the button
1890 _MandOpWords[newOpIndex].Slot.Back->setActive(true);
1891 // And move the button under it
1892 _NewOpButton->setParentPos(_MandOpWords[newOpIndex].Slot.Back);
1893 _NewOpButton->setActive(true);
1898 _NewOpButton->setActive(false);
1902 invalidateCoords();*/
1905 // ***************************************************************************
1906 void CDBGroupBuildPhrase::updateSpellView()
1910 // Build the current phrase
1911 CSPhraseCom newPhrase
;
1912 buildCurrentPhrase(newPhrase
);
1914 // Set the edited version to the phrase Manager => auto updated in icon
1915 CSPhraseManager
*pPM
= CSPhraseManager::getInstance();
1917 // replace the content of the edited phrase.
1918 pPM
->setPhrase(CSPhraseManager::EditionSlot
, newPhrase
);
1923 // ***************************************************************************
1924 void CDBGroupBuildPhrase::fillNewOptionalBricks(std::vector
<NLMISC::CSheetId
> &bricks
)
1926 if(!_GroupValid
) return;
1927 const CSBrickSheet
*rootBrick
= getRootBrick();
1928 if(!rootBrick
) return;
1929 CSBrickManager
*pBM
= CSBrickManager::getInstance();
1931 // get all possible newFamilies
1932 vector
<uint16
> optionalFamilies
;
1933 optionalFamilies
= rootBrick
->OptionalFamilies
;
1934 // Filter ones that already exist in the composition
1935 // Don't filter Combat and Power optional families (Use Brick exclusion system instead)
1936 if( !rootBrick
->isCombat() && !rootBrick
->isSpecialPower())
1937 filterFamilySetuped(optionalFamilies
);
1939 // Select all bricks for those families.
1940 for(uint i
=0;i
<optionalFamilies
.size();i
++)
1942 const vector
<CSheetId
> &famBricks
= pBM
->getFamilyBricks(optionalFamilies
[i
]);
1943 bricks
.insert(bricks
.end(), famBricks
.begin(), famBricks
.end());
1946 // get only ones known
1947 filterKnownBricks(bricks
);
1950 if( rootBrick
->isCombat() )
1952 // Ensure not same bricks are setuped
1953 filterBrickSetuped(bricks
);
1954 // Ensure only optional of compatible Skill are inserted
1955 filterSkillSetuped(bricks
, true, false);
1957 else if ( rootBrick
->isSpecialPower() )
1959 // Ensure not same bricks are setuped
1960 filterBrickSetuped(bricks
);
1962 // filter by BrickExclusion
1963 filterBrickExclusion(bricks
);
1966 // ***************************************************************************
1967 void CDBGroupBuildPhrase::fillNewCreditBricks(std::vector
<NLMISC::CSheetId
> &bricks
)
1969 if(!_GroupValid
) return;
1970 const CSBrickSheet
*rootBrick
= getRootBrick();
1971 if(!rootBrick
) return;
1972 CSBrickManager
*pBM
= CSBrickManager::getInstance();
1974 // get all possible newFamilies
1975 vector
<uint16
> creditFamilies
;
1976 creditFamilies
= rootBrick
->CreditFamilies
;
1977 // Filter ones that already exist in the composition
1978 filterFamilySetuped(creditFamilies
);
1980 // Select all bricks for those families.
1981 for(uint i
=0;i
<creditFamilies
.size();i
++)
1983 const vector
<CSheetId
> &famBricks
= pBM
->getFamilyBricks(creditFamilies
[i
]);
1984 bricks
.insert(bricks
.end(), famBricks
.begin(), famBricks
.end());
1987 // get only ones known
1988 filterKnownBricks(bricks
);
1990 // filter by BrickExclusion
1991 filterBrickExclusion(bricks
);
1995 // ***************************************************************************
1996 void CDBGroupBuildPhrase::setRootBrickTypeFilter(BRICK_TYPE::EBrickType rootBtFilter
,
1997 BRICK_TYPE::EBrickType rootBtFilter2
, BRICK_TYPE::EBrickType rootBtFilter3
, BRICK_TYPE::EBrickType rootBtFilter4
)
1999 nlctassert(MaxRootBrickTypeFilter
==4);
2000 _RootBrickTypeFilter
[0]= rootBtFilter
;
2001 _RootBrickTypeFilter
[1]= rootBtFilter2
;
2002 _RootBrickTypeFilter
[2]= rootBtFilter3
;
2003 _RootBrickTypeFilter
[3]= rootBtFilter4
;