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";
48 // ***************************************************************************
50 NLMISC_REGISTER_OBJECT(CViewBase
, CDBGroupBuildPhrase
, std::string
, "build_phrase");
52 CDBGroupBuildPhrase::CDBGroupBuildPhrase(const TCtorParam
¶m
)
53 :CInterfaceGroup(param
)
56 _ValidateButton
= NULL
;
62 _TextureIdSlotDisabled
= 0;
64 // Name of the magic sentence
65 _UserSentenceName
= NULL
;
70 _TextPhraseDesc
= NULL
;
72 nlctassert(MaxRootBrickTypeFilter
>0);
73 for(uint i
=0;i
<MaxRootBrickTypeFilter
;i
++)
75 _RootBrickTypeFilter
[i
]= BRICK_TYPE::UNKNOWN
;
79 // ***************************************************************************
80 CDBGroupBuildPhrase::~CDBGroupBuildPhrase()
85 // ***************************************************************************
86 // ***************************************************************************
88 // ***************************************************************************
89 // ***************************************************************************
92 // ***************************************************************************
93 bool CDBGroupBuildPhrase::parse (xmlNodePtr cur
, CInterfaceGroup
*parentGroup
)
95 if(!CInterfaceGroup::parse(cur
, parentGroup
))
98 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
100 // Init the disabled texture id
101 CViewRenderer
&rVR
= *CViewRenderer::getInstance();
102 _TextureIdSlotDisabled
= rVR
.getTextureIdFromName ("w_slot_brick_disabled.tga");
104 // Create now (before sons ctrl sheet parsing) the variables
106 // Bricks and their Params
107 for(i
=0;i
<MaxBricks
;i
++)
109 NLGUI::CDBManager::getInstance()->getDbProp(BrickBuildDB
+ ":MAIN:" + toString(i
)+":SHEET");
110 for(uint j
=0;j
<MaxParam
;j
++)
111 NLGUI::CDBManager::getInstance()->getDbProp(BrickBuildDB
+ ":PARAM:" + toString(i
) + ":" + toString(j
) + ":SHEET");
114 // spellView: to update the icon, use a special phrase manager entry
115 NLGUI::CDBManager::getInstance()->getDbProp(BrickBuildDB
+ ":EDITION_PHRASE:PHRASE")->setValue32(CSPhraseManager::EditionSlot
);
120 // ***************************************************************************
121 void CDBGroupBuildPhrase::updateCoords ()
124 setupBuildSentence();
126 CInterfaceGroup::updateCoords();
129 // ***************************************************************************
130 void CDBGroupBuildPhrase::setupBuildSentence()
132 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
136 // Get the widget controls
137 _ValidateButton
= dynamic_cast<CCtrlBaseButton
*>(CInterfaceGroup::getCtrl("ok_cancel:ok"));
139 _ValidateButton
->setFrozen(true);
141 _TextPhraseDesc
= dynamic_cast<CViewText
*>(CInterfaceGroup::getView("infos:phrase_desc"));
143 // retrieved brick view/ctrls
144 string idCtrl
, idBack
, idCost
, idCredit
, idInfo
;
152 // **** get all bricks (including root)
157 idCtrl
= string("bricks:main_brick")+toString(index
);
158 idBack
= string("bricks:main_back")+toString(index
);
159 idCost
= string("bricks:main_cost")+toString(index
);
160 idCredit
= string("bricks:main_credit")+toString(index
);
161 idInfo
= string("bricks:main_info")+toString(index
);
162 ctrl
= dynamic_cast<CDBCtrlSheet
*>(CInterfaceGroup::getCtrl( idCtrl
));
163 back
= dynamic_cast<CViewBitmap
*>(CInterfaceGroup::getView( idBack
));
164 cost
= dynamic_cast<CViewText
*>(CInterfaceGroup::getView( idCost
));
165 credit
= dynamic_cast<CViewText
*>(CInterfaceGroup::getView( idCredit
));
166 info
= dynamic_cast<CViewText
*>(CInterfaceGroup::getView( idInfo
));
167 // A brick Slot is valid only if all Ctrl/View are ok, same for its param.
170 if(ctrl
&& back
&& cost
&& info
)
172 newWord
.Slot
.Brick
= ctrl
;
173 newWord
.Slot
.Back
= back
;
174 newWord
.CostView
= cost
;
175 newWord
.CreditView
= credit
;
176 newWord
.InfoView
= info
;
177 // Must have all params
178 for(uint i
=0;i
<MaxParam
;i
++)
180 idCtrl
= string("bricks:param_brick") + toString(index
) + "_" + toString(i
);
181 idBack
= string("bricks:param_back") + toString(index
) + "_" + toString(i
);
182 ctrl
= dynamic_cast<CDBCtrlSheet
*>(CInterfaceGroup::getCtrl( idCtrl
));
183 back
= dynamic_cast<CViewBitmap
*>(CInterfaceGroup::getView( idBack
));
186 newWord
.ParamSlot
[i
].Brick
= ctrl
;
187 newWord
.ParamSlot
[i
].Back
= back
;
191 // fails to find all params!
199 // ok with this ctrl?
205 _MainWords
.push_back(newWord
);
216 // If not at least find the root, error!
219 nlwarning("ERROR: RootBrick not found!");
225 // Active at least the root brick.
226 _MainWords
[0].setBrick(0);
229 // Setup special for Root
233 fromString(CWidgetManager::getInstance()->getParser()->getDefine("phrase_build_root_info_maxw"), rootTextMaxw
);
234 _MainWords
[0].InfoView
->setLineMaxW(rootTextMaxw
);
237 // Get the sentence texts
238 _UserSentenceName
= dynamic_cast<CGroupEditBox
*>(CInterfaceGroup::getGroup("eb_spell_name:eb"));
241 _SpellView
= dynamic_cast<CDBCtrlSheet
*>(CInterfaceGroup::getCtrl( "spell_view" ));
245 // ***************************************************************************
246 void CDBGroupBuildPhrase::draw ()
248 CInterfaceGroup::draw();
252 // ***************************************************************************
253 const CSBrickSheet
*CDBGroupBuildPhrase::getRootBrick()
258 return _MainWords
[0].Slot
.Brick
->asSBrickSheet();
262 // ***************************************************************************
263 // ***************************************************************************
265 // ***************************************************************************
266 // ***************************************************************************
269 // ***************************************************************************
270 void CDBGroupBuildPhrase::clearBuildingPhrase()
276 _MainWords
[0].reset();
277 _MainWords
[0].setBrick(0);
278 updateDisplayFromRootBrick();
281 if(_UserSentenceName
)
283 _UserSentenceName
->setInputString(std::string());
291 // ***************************************************************************
292 void CDBGroupBuildPhrase::startComposition(const CSPhraseCom
&phrase
)
296 CSBrickManager
*pBM
= CSBrickManager::getInstance();
301 // if phrase empty (new phrase), invent a new name
304 // build a default name
305 name
= CI18N::get("uimPhraseNew");
306 // Append a dummy number
308 name
+= " " + toString(_NewSpellNumber
);
313 name
= phrase
.Name
.toUtf8();
315 // get the root Brick. Must exist.
316 CSBrickSheet
*rootBrick
= pBM
->getBrick(phrase
.Bricks
[0]);
319 // Phrase to Ctrls: simulate clicks!
320 uint curBrickIndex
= 1;
321 uint brickIndexForParam
= 0;
325 // simulate a root selection
326 validateRoot(rootBrick
);
327 // setup params of the root
328 numParam
= (uint
)rootBrick
->ParameterFamilies
.size();
329 brickIndexForParam
= 0;
331 // For all brick not the root
332 for(uint i
=1;i
<phrase
.Bricks
.size();i
++)
334 CSBrickSheet
*brick
= pBM
->getBrick(phrase
.Bricks
[i
]);
336 /* NB: the ORDER is important for grammar checkup
337 Must come first Root / Mandatory, then credit or optionals.
338 Each params must follow its related brick
339 Parameters May also have their own parameters
340 This is recursive, param sons may have params sons.
344 if(curParam
<numParam
)
346 validateParam(brickIndexForParam
, curParam
, brick
);
348 // If this parameter has additonal parameter they follow
349 if( brick
&& !brick
->ParameterFamilies
.empty() )
350 numParam
+= (uint
)brick
->ParameterFamilies
.size();
352 // a mandatory/optional/credit?
355 // must be a mandatory?
356 if(curBrickIndex
<1+_NumMandatories
)
357 validateMain(curBrickIndex
, brick
);
358 // create a new optional/credit
360 validateNewOpCredit(brick
);
362 // bkup index for param, and increment
363 brickIndexForParam
= curBrickIndex
;
365 // following bricks are its param!
369 numParam
= (uint
)brick
->ParameterFamilies
.size();
375 // set the editable name.
376 if(_UserSentenceName
)
377 _UserSentenceName
->setInputString(name
);
381 // ***************************************************************************
382 // ***************************************************************************
383 // Start Selection of Bricks
384 // ***************************************************************************
385 // ***************************************************************************
388 // ***************************************************************************
389 void CDBGroupBuildPhrase::fillSelectionRoot()
391 // the root must be OK.
392 if(!_GroupValid
) return;
393 CSBrickManager
*pBM
= CSBrickManager::getInstance();
395 // fillSelection with all root
396 std::vector
<CSheetId
> bricks
;
397 bricks
= pBM
->getRootBricks();
398 // get only ones known
399 filterKnownBricks(bricks
);
400 // get only ones that match The BrickType filter
401 filterRootBrickType(bricks
);
402 // some additional root filter
403 filterRootPossibles(bricks
);
405 fillSelection(bricks
);
407 // ***************************************************************************
408 void CDBGroupBuildPhrase::fillSelectionMain(uint index
)
411 // the root must be OK.
412 if(!_GroupValid
) return;
413 const CSBrickSheet
*rootBrick
= getRootBrick();
414 if(!rootBrick
) return;
415 CSBrickManager
*pBM
= CSBrickManager::getInstance();
418 if(index
>=_MainWords
.size())
424 // get the current Brick.
425 std::vector
<CSheetId
> bricks
;
426 const CSBrickSheet
*brick
= _MainWords
[index
].Slot
.Brick
->asSBrickSheet();
429 // It is possible for Mandatory that this brick is still not validated
430 if(index
<1+_NumMandatories
)
432 // get the related family and bricks associated to it
433 bricks
= pBM
->getFamilyBricks(rootBrick
->MandatoryFamilies
[index
-1]);
443 // fill selection with all bricks of the same family (whatever the main brick)
444 bricks
= pBM
->getFamilyBricks(brick
->BrickFamily
);
447 // get only ones known
448 filterKnownBricks(bricks
);
450 // For mandatories, filter effects
451 CSPhraseCom currentPhrase
;
452 buildCurrentPhrase(currentPhrase
);
453 pBM
->getSabrinaCom().filterMandatoryComposition(currentPhrase
.Bricks
, bricks
);
455 // For Combat Optional, must filter by exclusion and combat exclusion
456 if(brick
&& brick
->isCombat() && brick
->isOptional() )
458 // Ensure not same bricks are setuped. Also don't insert me since I am already here...
459 filterBrickSetuped(bricks
);
460 // Ensure only optional of compatible Skill are inserted. Don't test with me, since i may be removed!
461 filterSkillSetuped(bricks
, true, false, index
);
463 // for power optional, must filter by brick
464 else if(brick
&& brick
->isSpecialPower() && (brick
->isOptional()||brick
->isMandatory()) )
466 // Ensure not same bricks are setuped. Also don't insert me since I am already here...
467 filterBrickSetuped(bricks
);
470 // For optional or credit, filter by BrickExclusion.
471 if(index
>=1/*+_NumMandatories*/)
472 filterBrickExclusion(bricks
, index
);
474 // For Optional/Credits, must append first the special "Remove Brick" choice
475 if(index
>=1+_NumMandatories
)
477 bricks
.insert(bricks
.begin(), pBM
->getInterfaceRemoveBrick());
481 fillSelection(bricks
);
484 // ***************************************************************************
485 void CDBGroupBuildPhrase::fillSelectionParam(uint index
, uint paramIndex
)
487 // the root must be OK.
488 if(!_GroupValid
) return;
489 const CSBrickSheet
*rootBrick
= getRootBrick();
490 if(!rootBrick
) return;
491 CSBrickManager
*pBM
= CSBrickManager::getInstance();
494 if( index
>=_MainWords
.size() || paramIndex
>=MaxParam
)
500 // get the current Brick.
501 const CSBrickSheet
*brick
;
502 brick
= _MainWords
[index
].ParamSlot
[paramIndex
].Brick
->asSBrickSheet();
508 // fill selection with all bricks of the same family (whatever the root)
509 std::vector
<CSheetId
> bricks
;
510 bricks
= pBM
->getFamilyBricks(brick
->BrickFamily
);
511 // get only ones known
512 filterKnownBricks(bricks
);
514 fillSelection(bricks
);
517 // ***************************************************************************
518 void CDBGroupBuildPhrase::fillSelectionNewOp()
520 // the root must be OK.
521 if(!_GroupValid
) return;
522 const CSBrickSheet
*rootBrick
= getRootBrick();
523 if(!rootBrick
) return;
525 // Build a brick array of possible new bricks.
526 std::vector
<NLMISC::CSheetId
> bricks
;
527 fillNewOptionalBricks(bricks
);
530 fillSelection(bricks
);
534 // ***************************************************************************
535 void CDBGroupBuildPhrase::fillSelectionNewCredit()
537 // the root must be OK.
538 if(!_GroupValid
) return;
539 const CSBrickSheet
*rootBrick
= getRootBrick();
540 if(!rootBrick
) return;
542 // Build a brick array of possible new bricks.
543 std::vector
<NLMISC::CSheetId
> bricks
;
544 fillNewCreditBricks(bricks
);
547 fillSelection(bricks
);
551 // ***************************************************************************
552 // ***************************************************************************
553 // Validate Selection of Bricks
554 // ***************************************************************************
555 // ***************************************************************************
558 // ***************************************************************************
559 void CDBGroupBuildPhrase::validateRoot(const CSBrickSheet
*sheet
)
561 // the root must be OK.
562 if(!_GroupValid
) return;
564 // If same brick no op
565 if(getRootBrick() == sheet
)
568 // reset the whole sentence with default values
569 resetSentence(sheet
->Id
.asInt());
571 // update the display
576 // ***************************************************************************
577 void CDBGroupBuildPhrase::validateMain(uint index
, const CSBrickSheet
*sheet
)
580 // the root must be OK.
581 if(!_GroupValid
) return;
582 const CSBrickSheet
*rootBrick
= getRootBrick();
583 if(!rootBrick
) return;
584 CSBrickManager
*pBM
= CSBrickManager::getInstance();
586 // If the brick chosen is actually the "Remove Brick", then call the correct method
587 if(sheet
->Id
== pBM
->getInterfaceRemoveBrick())
589 deleteOpCredit(index
);
595 _MainWords
[index
].setBrick(sheet
->Id
.asInt());
597 // must update params if change!
600 // update the display
604 // ***************************************************************************
605 void CDBGroupBuildPhrase::validateParam(uint index
, uint paramIndex
, const CSBrickSheet
*sheet
)
607 // the root must be OK.
608 if(!_GroupValid
) return;
609 const CSBrickSheet
*rootBrick
= getRootBrick();
610 if(!rootBrick
) return;
611 if(paramIndex
>=MaxParam
) return;
613 // The setuped parameter may have also parameter sons
614 bool mustResetParamHrc
= false;
615 vector
<uint16
> newParamSons
;
616 if(sheet
) newParamSons
= sheet
->ParameterFamilies
;
617 mustResetParamHrc
= newParamSons
!= _MainWords
[index
].ParamSlot
[paramIndex
].ViewParamFamilies
;
622 _MainWords
[index
].setParamBrick(paramIndex
, sheet
->Id
.asInt());
625 // update the param sons
626 if(mustResetParamHrc
)
627 updateParamHrc(index
);
629 // update the display
633 // ***************************************************************************
634 void CDBGroupBuildPhrase::validateNewOpCredit(const CSBrickSheet
*sheet
)
636 // the root must be OK.
637 if(!_GroupValid
) return;
638 const CSBrickSheet
*rootBrick
= getRootBrick();
639 if(!rootBrick
) return;
644 // we should not have to do this test...
645 if(getNumMainBricks()>=_MainWords
.size())
648 // get the dest index.
651 if(sheet
->isCredit())
652 index
= 1+_NumMandatories
+_NumOptionals
+_NumCredits
;
653 // else optional brick
655 index
= 1+_NumMandatories
+_NumOptionals
;
657 // Shift Optional Row. Copy the Brick setup from index to index+1.
658 for(uint i
= getNumMainBricks();i
>index
;i
--)
660 _MainWords
[i
].copySetup(_MainWords
[i
-1]);
664 _MainWords
[index
].setBrick(sheet
->Id
.asInt());
666 // Increment the number of options/credits setuped!
667 if(sheet
->isCredit())
672 // update the NewOp controler
675 // must update params if change!
678 // update the display
682 // ***************************************************************************
683 void CDBGroupBuildPhrase::deleteOpCredit(uint index
)
686 // the root must be OK.
687 if(!_GroupValid
) return;
688 const CSBrickSheet
*rootBrick
= getRootBrick();
689 if(!rootBrick
) return;
693 if(index
>=1+_NumMandatories
&& index
<1+_NumMandatories
+_NumOptionals
)
695 else if(index
>=1+_NumMandatories
+_NumOptionals
&& index
<getNumMainBricks() )
700 // Shift Optional Row. Copy the Brick setup from index+1 to index.
701 for(uint i
= index
+1;i
<getNumMainBricks();i
++)
703 _MainWords
[i
-1].copySetup(_MainWords
[i
]);
706 // reset the last row display
707 _MainWords
[getNumMainBricks()-1].reset();
709 // an optional/credit is removed!
715 // update the NewOp ctrl
718 // update the display
723 // ***************************************************************************
724 // ***************************************************************************
726 // ***************************************************************************
727 // ***************************************************************************
730 // ***************************************************************************
731 static uint
getLowestBit(uint64 val
)
745 // ***************************************************************************
746 static void getDefaultSheetForFamily(uint familyId
, sint32
&sheet
, bool &valid
)
748 CSBrickManager
*pBM
= CSBrickManager::getInstance();
750 uint64 knownBF
= pBM
->getKnownBrickBitField(familyId
);
754 // default: get the lowest sheet
755 sint posInFamily
= getLowestBit(knownBF
);
758 sheet
= pBM
->getBrickSheet(familyId
, posInFamily
).asInt();
763 // setup the Sheet with the lowest brick
764 sheet
= pBM
->getBrickSheet(familyId
, 0).asInt();
765 // invalidate the word
771 // ***************************************************************************
772 void CDBGroupBuildPhrase::updateParams(uint index
)
776 if(index
<_MainWords
.size())
777 word
= &_MainWords
[index
];
781 // Get the Brick setuped. may be NULL for unsetuped mandatories
782 const CSBrickSheet
*brick
= word
->Slot
.Brick
->asSBrickSheet();
784 // retrieve brick paramFamilies
785 vector
<uint16
> paramFamilies
;
787 paramFamilies
= brick
->ParameterFamilies
;
789 // if param families of the new brick different from what setuped in view, reset all param hierachy
790 if(word
->Slot
.ViewParamFamilies
!= paramFamilies
)
792 // must reset the view of parameters
795 // and compute all from setuped main brick
796 updateParamHrc(index
);
801 // ***************************************************************************
802 /* used for updateParamHrc()
808 const CSBrickSheet
*Brick
;
810 std::vector
<uint16
> ViewParamFamilies
;
811 CParamTreeNode
*Parent
;
812 std::vector
<CParamTreeNode
*> Sons
;
815 CParamTreeNode(CParamTreeNode
*parent
) : Brick(NULL
), Valid(true), Parent(parent
) {}
826 for(uint i
=0;i
<Sons
.size();i
++) delete Sons
[i
];
830 // rebuild default param sons (recurs) if BrickParamFamilies and ViewParamFamilies differ.
831 // return false if error
832 bool synchronizeParams(uint maxDepth
)
837 // get the brick Parameter Families.
838 vector
<uint16
> brickParamFamilies
;
840 brickParamFamilies
= Brick
->ParameterFamilies
;
841 // compare with the current View one. if equals then OK! just recurs test sons
842 if(brickParamFamilies
== ViewParamFamilies
)
844 for(uint i
=0;i
<Sons
.size();i
++)
846 if(!Sons
[i
]->synchronizeParams(maxDepth
-1))
851 // else must rebuild all this branch
854 return buildSonsFromBrick(maxDepth
);
858 // build the son list from brick Setup, and recurs
859 // return false if error
860 bool buildSonsFromBrick(uint maxDepth
)
865 CSBrickManager
*pBM
= CSBrickManager::getInstance();
867 // first delete my sons, and any old view setup
869 ViewParamFamilies
.clear();
871 // then copy brick families to view families (=> view synchronized to brick)
873 ViewParamFamilies
= Brick
->ParameterFamilies
;
875 // Add a default Son for each family
877 for(i
=0;i
<ViewParamFamilies
.size();i
++)
879 uint familyId
= ViewParamFamilies
[i
];
882 // bkup the valid state in this node
883 getDefaultSheetForFamily(familyId
, sheet
, sonValid
);
886 CParamTreeNode
*sonNode
= new CParamTreeNode(this);
887 sonNode
->Brick
= pBM
->getBrick(CSheetId(sheet
));
888 sonNode
->Valid
= sonValid
;
889 // add this son to its father
890 Sons
.push_back(sonNode
);
894 for(i
=0;i
<Sons
.size();i
++)
896 if(!Sons
[i
]->buildSonsFromBrick(maxDepth
- 1))
903 // build the word raw param list from hierarchy
904 // return false if error
905 bool buildRawParamList(CDBGroupBuildPhrase::CWord
&word
, uint
&rawParamIndex
)
907 // If this is the root
910 // just copy the ViewParamFamilies
911 word
.Slot
.ViewParamFamilies
= ViewParamFamilies
;
913 // else, add this parameter to list
916 // Check possible Brick Data error
917 if(rawParamIndex
>= CDBGroupBuildPhrase::MaxParam
)
919 nlwarning("BRICK ERROR: Not enough param Space (%d) to add all son parameter", CDBGroupBuildPhrase::MaxParam
);
923 // Setup this brick in the param list
927 word
.setParamBrick(rawParamIndex
, sheet
.asInt());
928 word
.ParamSlot
[rawParamIndex
].Valid
= Valid
;
929 word
.ParamSlot
[rawParamIndex
].Brick
->setGrayed( !Valid
);
931 // bkup its ViewParameters
932 word
.ParamSlot
[rawParamIndex
].ViewParamFamilies
= ViewParamFamilies
;
938 // for all sons, recurs
939 for(uint i
=0;i
<Sons
.size();i
++)
942 if(!Sons
[i
]->buildRawParamList(word
, rawParamIndex
))
951 // ***************************************************************************
952 void CDBGroupBuildPhrase::updateParamHrc(uint index
)
955 When we are here, we may have some Parameter Hierarchy inconsitency between the ViewParameterFamilies and
956 the Brick parameter Families.
957 we must fix them and rebuild all the raw param list
961 if(index
<_MainWords
.size())
962 word
= &_MainWords
[index
];
966 // If a Param error has already been detected on this Slot, no-op
971 // **** From the current View setup of 'word', build the Parameter Hierarchy (in simple tree form)
972 CParamTreeNode
rootNode(NULL
);
973 // NB: here rootNode represent the Main (ie mandatory, optional or credit) brick. Therefore, it is not a real parameter.
974 rootNode
.Brick
= word
->Slot
.Brick
->asSBrickSheet();
975 rootNode
.Valid
= true;
976 rootNode
.ViewParamFamilies
= word
->Slot
.ViewParamFamilies
;
977 uint rawParamIndex
= 0;
978 CParamTreeNode
*curNode
= &rootNode
;
981 // if this node still need sons, then the next raw index param must be a son of curNode
982 if(curNode
->Sons
.size() < curNode
->ViewParamFamilies
.size())
984 nlassert(rawParamIndex
< word
->NumTotalParams
);
985 // create a son node, and fill from rawList
986 CParamTreeNode
*sonNode
= new CParamTreeNode(curNode
);
987 sonNode
->Brick
= word
->ParamSlot
[rawParamIndex
].Brick
->asSBrickSheet();
988 sonNode
->Valid
= word
->ParamSlot
[rawParamIndex
].Valid
;
989 sonNode
->ViewParamFamilies
= word
->ParamSlot
[rawParamIndex
].ViewParamFamilies
;
990 // append to the sons
991 curNode
->Sons
.push_back(sonNode
);
997 // else the next must be a brother: return to parent
999 curNode
= curNode
->Parent
;
1001 // we must have run all the raw list
1002 nlassert(rawParamIndex
== word
->NumTotalParams
);
1003 nlassert(rootNode
.Sons
.size() == word
->Slot
.ViewParamFamilies
.size());
1006 // **** Parse the Parameter tree, and invalidate each branch where View families and Brick families differs.
1007 // Avoid .sbrick data erros: allow only a max recurs level of 10
1008 if(!rootNode
.synchronizeParams(10))
1010 // in this case, ABORT, but don't crash: setup 0 parameters...
1011 word
->resetParams();
1012 word
->ParamError
= true;
1017 // **** rebuild completely the parameter list from the parameter tree.
1019 word
->resetParams();
1022 if(rootNode
.buildRawParamList(*word
, rawParamIndex
))
1024 // then the new NumTotalParams is....
1025 word
->NumTotalParams
= rawParamIndex
;
1030 // in this case, ABORT, but don't crash: setup 0 parameters...
1031 word
->resetParams();
1032 word
->ParamError
= true;
1039 // ***************************************************************************
1040 void CDBGroupBuildPhrase::updateAllDisplay(const CSPhraseCom
&phrase
)
1042 // NB: phrase MUST COME FROM buildCurrentPhrase() else doesn't work.
1044 CSBrickManager
*pBM
= CSBrickManager::getInstance();
1045 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1046 CSPhraseManager
*pPM
= CSPhraseManager::getInstance();
1048 // **** update total cost
1049 // get the cost and credit
1050 uint32 totalCost
, totalCredit
;
1051 pBM
->getSabrinaCom().getPhraseCost(phrase
.Bricks
, totalCost
, totalCredit
);
1054 NLGUI::CDBManager::getInstance()->getDbProp("UI:PHRASE:BUILD:TOTAL_COST")->setValue32(totalCost
);
1055 NLGUI::CDBManager::getInstance()->getDbProp("UI:PHRASE:BUILD:TOTAL_CREDIT")->setValue32(totalCredit
);
1057 // **** Update the Cost of All Root/Mandat/ops/Credits.
1058 if(phrase
.Bricks
.size())
1060 // Parse the phrase, and setup the related Cost.
1061 uint curBrickIndex
= 0;
1062 for(uint i
=0;i
<phrase
.Bricks
.size();)
1065 CSBrickSheet
*brick
= pBM
->getBrick(phrase
.Bricks
[i
]);
1066 // if not found, skip it (eg important for mandatories not setuped)
1073 // get the cost for this brick and its params.
1075 float relative_cost
;
1076 cost
= pBM
->getSabrinaCom().getPhraseBrickAndParamCost(phrase
.Bricks
, i
);
1077 relative_cost
= pBM
->getSabrinaCom().getPhraseBrickAndParamRelativeCost(phrase
.Bricks
, i
);
1078 std::string costText
;
1079 if( cost
== 0 && relative_cost
!= 0.f
)
1081 cost
= (sint32
)(relative_cost
* 100.f
);
1082 costText
= toString("%+d", cost
) + string("%");
1085 costText
= toString("%+d", cost
);
1087 // set the MainWord cost
1090 _MainWords
[curBrickIndex
].CostView
->setActive(true);
1091 _MainWords
[curBrickIndex
].CreditView
->setActive(false);
1092 _MainWords
[curBrickIndex
].CostView
->setText(costText
);
1096 _MainWords
[curBrickIndex
].CreditView
->setActive(true);
1097 _MainWords
[curBrickIndex
].CostView
->setActive(false);
1098 _MainWords
[curBrickIndex
].CreditView
->setText(costText
);
1101 // Next brick: skip me and my params
1102 i
+= 1 + _MainWords
[curBrickIndex
].NumTotalParams
;
1105 // next slot to setup. if all slots setuped, break.
1107 if(curBrickIndex
>=getNumMainBricks())
1112 // **** Additionaly Update the Info Text
1113 for(uint i
=0;i
<1+_NumMandatories
;i
++)
1115 CWord
&word
= _MainWords
[i
];
1116 // If the brick is setuped, hide the info text, else display
1117 if( word
.Slot
.Brick
->asSBrickSheet() )
1118 word
.InfoView
->setActive(false);
1121 word
.InfoView
->setActive(true);
1123 word
.InfoView
->setText( CI18N::get("uiTextHelpSelectRootBrick") );
1125 // start effect index at 1 (human readable :) )
1126 word
.InfoView
->setText( CI18N::get("uiTextHelpSelectEffectBrick") + toString(i
) );
1130 // **** Additionaly Update the New Buttons
1131 bool mandatOk
= true;
1132 // If only one of root effect is not setuped...
1133 for(uint i
=0;i
<1+_NumMandatories
;i
++)
1135 CWord
&word
= _MainWords
[i
];
1136 if( !word
.Slot
.Brick
->asSBrickSheet() )
1139 // set DB value accordeing to it.
1140 NLGUI::CDBManager::getInstance()->getDbProp("UI:PHRASE:BUILD:ROOT_EFFECT_VALID")->setValue32(mandatOk
);
1142 // update valid button
1147 // valid only if all mandat active and cost ok
1148 active
= totalCredit
>=totalCost
&& mandatOk
;
1150 // valid only if All bricks exist, and are known
1152 for(i
=0;i
<phrase
.Bricks
.size();i
++)
1155 CSBrickSheet
*brick
= pBM
->getBrick(phrase
.Bricks
[i
]);
1156 if(!brick
|| !pBM
->isBrickKnown(brick
->Id
))
1163 // valid only if no parameter error has been encountered
1164 for(i
=0;i
<1+_NumMandatories
+_NumOptionals
+_NumCredits
;i
++)
1166 if(_MainWords
[i
].ParamError
)
1173 // If OK, still do some check
1176 const CSBrickSheet
*brick
= getRootBrick();
1180 else if( brick
->MandatoryFamilies
.size()+1>_MainWords
.size() )
1184 _ValidateButton
->setFrozen(!active
);
1188 // **** Additionaly Update the Combat Restrict options
1189 // Get the rootBrick
1190 const CSBrickSheet
*rootBrick
= getRootBrick();
1191 if(rootBrick
&& rootBrick
->isCombat())
1193 // show the weapon restriction interface
1194 NLGUI::CDBManager::getInstance()->getDbProp("UI:PHRASE:BUILD:RESTRICT_COMBAT:ENABLED")->setValue32(1);
1196 // If not already done, retrieve the weapon skills, and fill the sbricks SHEET
1197 if(_WeaponSkills
.empty())
1199 // get define, and verify data
1200 uint numWeaponSkill
;
1201 fromString(CWidgetManager::getInstance()->getParser()->getDefine("phrase_max_restrict_combat"), numWeaponSkill
);
1202 string strWeaponSkill
= CWidgetManager::getInstance()->getParser()->getDefine("phrase_def_skill_restrict_combat");
1203 vector
<string
> weaponSkillList
;
1204 splitString(strWeaponSkill
, " ", weaponSkillList
);
1205 nlassert(weaponSkillList
.size()==numWeaponSkill
);
1207 // NOTE TO CODER WHO CHANGE SKILLS::ESkill. If you change combat skills, ask yoyo for modification
1208 // or search "phrase_def_skill_restrict_combat" and "phrase_max_restrict_combat" in XML.
1209 nlctassert( SKILLS::SFM1SSM
&& SKILLS::SFM1SAM
&& SKILLS::SFM1BMM
&& SKILLS::SFM1BSM
&&
1210 SKILLS::SFM1PSM
&& SKILLS::SFM2SSM
&& SKILLS::SFM2SAM
&& SKILLS::SFM2BMM
&&
1211 SKILLS::SFM2PPM
&& SKILLS::SFMCADM
&& SKILLS::SFMCAHM
&& SKILLS::SFR1APM
&&
1212 SKILLS::SFR2AAM
&& SKILLS::SFR2ALM
&& SKILLS::SFR2ARM
);
1213 nlctassert(SKILLS::SH
- SKILLS::SF
== 47);
1215 // backup the skill array, and fill the associated brick in interface
1216 _WeaponSkills
.resize(numWeaponSkill
);
1217 for(uint i
=0;i
<numWeaponSkill
;i
++)
1219 _WeaponSkills
[i
]= SKILLS::toSkill(weaponSkillList
[i
]);
1221 // Get the associated brick
1222 uint32 viewBrickCombatSheetId
= pBM
->getVisualBrickForSkill(_WeaponSkills
[i
]).asInt();
1225 NLGUI::CDBManager::getInstance()->getDbProp(toString("UI:PHRASE:BUILD:RESTRICT_COMBAT:%d:SHEET", i
))->setValue32(viewBrickCombatSheetId
);
1229 // For each weapon skill, test if match or not the current phrase
1230 for(uint i
=0;i
<_WeaponSkills
.size();i
++)
1232 bool ok
= pPM
->skillCompatibleWithCombatPhrase(_WeaponSkills
[i
], phrase
.Bricks
);
1233 NLGUI::CDBManager::getInstance()->getDbProp(toString("UI:PHRASE:BUILD:RESTRICT_COMBAT:%d:LOCKED", i
))->setValue32(!ok
);
1238 // hide the weapon restriction interface
1239 NLGUI::CDBManager::getInstance()->getDbProp("UI:PHRASE:BUILD:RESTRICT_COMBAT:ENABLED")->setValue32(0);
1242 // **** Setup the phrase Desc
1246 pPM
->buildPhraseDesc(text
, phrase
, 0, false, "composition");
1247 _TextPhraseDesc
->setTextFormatTaged(text
);
1251 // **** Since some bricks may have changed, update the spell view
1257 // ***************************************************************************
1258 void CDBGroupBuildPhrase::updateAllDisplay()
1260 // build the current phrase
1261 CSPhraseCom newPhrase
;
1262 buildCurrentPhrase(newPhrase
);
1263 updateAllDisplay(newPhrase
);
1267 // ***************************************************************************
1268 void CDBGroupBuildPhrase::resetSelection()
1270 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1272 for(uint i
=0;i
<MaxSelection
;i
++)
1274 NLGUI::CDBManager::getInstance()->getDbProp(BrickSelectionDB
+ ":" + toString(i
) + ":SHEET")->setValue32(0);
1278 // ***************************************************************************
1279 void CDBGroupBuildPhrase::fillSelection(const std::vector
<CSheetId
> &bricks
)
1281 CInterfaceManager
*pIM
= CInterfaceManager::getInstance();
1283 uint num
= min((uint
)MaxSelection
, (uint
)bricks
.size());
1284 for(uint i
=0;i
<MaxSelection
;i
++)
1287 NLGUI::CDBManager::getInstance()->getDbProp(BrickSelectionDB
+ ":" + toString(i
) + ":SHEET")->setValue32(bricks
[i
].asInt());
1289 NLGUI::CDBManager::getInstance()->getDbProp(BrickSelectionDB
+ ":" + toString(i
) + ":SHEET")->setValue32(0);
1293 // ***************************************************************************
1294 void CDBGroupBuildPhrase::filterKnownBricks(std::vector
<CSheetId
> &bricks
)
1296 CSBrickManager
*pBM
= CSBrickManager::getInstance();
1298 pBM
->filterKnownBricks(bricks
);
1301 // ***************************************************************************
1302 void CDBGroupBuildPhrase::filterBrickExclusion(std::vector
<CSheetId
> &bricks
, uint16 indexToSkip
)
1304 CSBrickManager
*pBM
= CSBrickManager::getInstance();
1306 std::vector
<CSheetId
> res
;
1307 res
.reserve(bricks
.size());
1309 static vector
<string
> forbidWords(30);
1311 // For All optionals/credits setuped, build the Exclude Set
1312 set
<string
> excludeSet
;
1313 // test for all bricks
1314 for(uint j
=1/*+_NumMandatories*/;j
<1+_NumMandatories
+_NumOptionals
+_NumCredits
;j
++)
1316 // skip brick at index indexToSkip (if replacing a brick for example, don't consider it's forbiden flags)
1317 if (j
== indexToSkip
)
1320 const CSBrickSheet
*brick
= _MainWords
[j
].Slot
.Brick
->asSBrickSheet();
1324 forbidWords
.clear();
1325 splitString(brick
->getForbiddenExclude(), ":", forbidWords
);
1326 // for all words, insert in the set.
1327 for(uint j
=0;j
<forbidWords
.size();j
++)
1328 excludeSet
.insert(forbidWords
[j
]);
1332 // keep only unfiltered ones
1333 for(uint i
=0;i
<bricks
.size();i
++)
1335 const CSBrickSheet
*brick
= pBM
->getBrick(bricks
[i
]);
1338 // For all define words, search if excluded from the current set of optional setup
1339 forbidWords
.clear();
1340 splitString(brick
->getForbiddenDef(), ":", forbidWords
);
1342 for(uint j
=0;j
<forbidWords
.size();j
++)
1344 if(excludeSet
.find(forbidWords
[j
]) != excludeSet
.end() )
1353 res
.push_back(bricks
[i
]);
1357 // replace with filtered one
1362 // ***************************************************************************
1363 void CDBGroupBuildPhrase::filterFamilySetuped(std::vector
<uint16
> &families
)
1365 std::vector
<uint16
> res
;
1366 res
.reserve(families
.size());
1368 // keep only unsetuped ones
1369 for(uint i
=0;i
<families
.size();i
++)
1371 uint family
= families
[i
];
1374 // test for all opionals/Credits
1375 for(uint j
=1+_NumMandatories
;j
<getNumMainBricks();j
++)
1377 const CSBrickSheet
*brick
= _MainWords
[j
].Slot
.Brick
->asSBrickSheet();
1378 if(brick
&& brick
->BrickFamily
==(sint
)family
)
1385 // insert only if not found
1388 res
.push_back(family
);
1392 // replace with filtered one
1396 // ***************************************************************************
1397 void CDBGroupBuildPhrase::filterBrickSetuped(std::vector
<NLMISC::CSheetId
> &bricks
)
1399 std::vector
<CSheetId
> res
;
1400 res
.reserve(bricks
.size());
1402 // keep only unsetuped ones
1403 for(uint i
=0;i
<bricks
.size();i
++)
1405 CSheetId brick
= bricks
[i
];
1408 // test for all bricks
1409 for(uint j
=1/*+_NumMandatories*/;j
<getNumMainBricks();j
++)
1411 if(brick
== CSheetId(_MainWords
[j
].Slot
.Brick
->getSheetId()) )
1418 // insert only if not found
1421 res
.push_back(brick
);
1425 // replace with filtered one
1430 // ***************************************************************************
1431 void CDBGroupBuildPhrase::filterSkillSetuped(std::vector
<NLMISC::CSheetId
> &bricks
, bool checkOptional
, bool checkCredit
, sint avoidCheckIndex
)
1433 // check nothing => return.
1434 if(!checkOptional
&& !checkCredit
)
1437 CSBrickManager
*pBM
= CSBrickManager::getInstance();
1440 // **** build the compatible skill formula for the bricks we want to check
1441 CReqSkillFormula testFormula
;
1442 uint checkStart
= checkOptional
? 1+_NumMandatories
: 1+_NumMandatories
+_NumOptionals
;
1443 uint checkEnd
= checkCredit
? 1+_NumMandatories
+_NumOptionals
: getNumMainBricks();
1445 // test for all optionals and/or Credits
1447 for(uint i
= checkStart
;i
<checkEnd
;i
++)
1449 // For Replacement of brick, don't test with the brick replaced (suppose will be removed!)
1450 if(avoidCheckIndex
==(sint
)i
)
1453 const CSBrickSheet
*brick
= _MainWords
[i
].Slot
.Brick
->asSBrickSheet();
1454 // If bricks use a skill, and with the formula
1455 if(brick
&& brick
->getSkill()!=SKILLS::unknown
)
1457 CReqSkillFormula brickFormula
;
1458 for(uint j
=0;j
<brick
->UsedSkills
.size();j
++)
1460 brickFormula
.orV(CSkillValue(brick
->UsedSkills
[j
]));
1463 // and with the phraseFormula
1464 testFormula
.andV(brickFormula
);
1469 // **** check for each brick if compatible with this formula
1470 std::vector
<CSheetId
> res
;
1471 res
.reserve(bricks
.size());
1473 // keep only unsetuped ones
1474 for(i
=0;i
<bricks
.size();i
++)
1476 const CSBrickSheet
*brick
= pBM
->getBrick(bricks
[i
]);
1477 if(brick
&& brick
->getSkill()!=SKILLS::unknown
)
1479 // simulate a choose of this brick, ie AND its skill formula with the current phrase formula
1480 CReqSkillFormula brickFormula
;
1481 for(uint j
=0;j
<brick
->UsedSkills
.size();j
++)
1483 brickFormula
.orV(CSkillValue(brick
->UsedSkills
[j
]));
1486 CReqSkillFormula tempFormula
= testFormula
;
1487 tempFormula
.andV(brickFormula
);
1489 // Nb: the following test works if testFormula is empty(), because in this case
1490 // tempFormula.and(brickFormula)==brickFormula and hence is of form SFR | SFM | ....
1492 // if one of the ored skill has a size 1 (eg SFR&SFM fails), then it's ok!
1493 // else it's mean that there is no "skill on same branch solution".
1495 std::list
<CReqSkillFormula::CSkillValueAnd
>::iterator
it(tempFormula
.OrSkills
.begin()),
1496 end(tempFormula
.OrSkills
.end());
1499 CReqSkillFormula::CSkillValueAnd skillAnd
= *it
;
1500 // ok, there is still one usable skill
1501 if(skillAnd
.AndSkills
.size()==1)
1508 // insert only if ok
1511 res
.push_back(bricks
[i
]);
1516 // replace with filtered one
1522 // ***************************************************************************
1523 void CDBGroupBuildPhrase::filterRootBrickType(std::vector
<NLMISC::CSheetId
> &bricks
)
1526 if(_RootBrickTypeFilter
[0]==BRICK_TYPE::UNKNOWN
)
1529 CSBrickManager
*pBM
= CSBrickManager::getInstance();
1530 std::vector
<CSheetId
> res
;
1531 res
.reserve(bricks
.size());
1533 // keep only match ones
1534 for(uint i
=0;i
<bricks
.size();i
++)
1536 const CSBrickSheet
*brick0
= pBM
->getBrick(bricks
[i
]);
1539 // insert if one filter match (OR)
1540 for(uint j
=0;j
<MaxRootBrickTypeFilter
;j
++)
1542 if( _RootBrickTypeFilter
[j
] != BRICK_TYPE::UNKNOWN
&&
1543 _RootBrickTypeFilter
[j
] == BRICK_FAMILIES::brickType(brick0
->BrickFamily
) )
1545 res
.push_back(bricks
[i
]);
1552 // replace with filtered one
1557 // ***************************************************************************
1558 void CDBGroupBuildPhrase::filterRootPossibles(std::vector
<NLMISC::CSheetId
> &bricks
)
1560 CSBrickManager
*pBM
= CSBrickManager::getInstance();
1561 std::vector
<CSheetId
> res
;
1562 res
.reserve(bricks
.size());
1564 // keep only match ones
1565 for(uint i
=0;i
<bricks
.size();i
++)
1567 const CSBrickSheet
*brick0
= pBM
->getBrick(bricks
[i
]);
1570 // insert only if not a proc enchantment
1571 if(!brick0
->isProcEnchantment())
1572 res
.push_back(bricks
[i
]);
1576 // replace with filtered one
1581 // ***************************************************************************
1582 void CDBGroupBuildPhrase::CSlot::reset()
1584 // Must do the test for credits not setuped.
1587 Brick
->setActive(false);
1588 Brick
->setSheetId(0);
1589 Back
->setActive(false);
1593 ViewParamFamilies
.clear();
1596 // ***************************************************************************
1597 void CDBGroupBuildPhrase::CWord::resetParams()
1599 for(uint i
=0;i
<MaxParam
;i
++)
1600 ParamSlot
[i
].reset();
1601 // reset numParams to 0
1602 Slot
.ViewParamFamilies
.clear();
1607 // ***************************************************************************
1608 void CDBGroupBuildPhrase::CWord::reset()
1611 // reset also all params
1613 // Hide the Cost View
1614 CostView
->setActive(false);
1615 CreditView
->setActive(false);
1616 InfoView
->setActive(false);
1619 // ***************************************************************************
1620 void CDBGroupBuildPhrase::CWord::setBrick(uint32 sheetId
)
1622 Slot
.Brick
->setActive(true);
1623 Slot
.Brick
->setSheetId(sheetId
);
1624 Slot
.Back
->setActive(true);
1627 // ***************************************************************************
1628 void CDBGroupBuildPhrase::CWord::setParamBrick(uint param
, uint32 sheetId
)
1633 ParamSlot
[param
].Brick
->setActive(true);
1634 ParamSlot
[param
].Brick
->setSheetId(sheetId
);
1635 ParamSlot
[param
].Back
->setActive(true);
1638 // ***************************************************************************
1639 void CDBGroupBuildPhrase::CWord::copySetup(const CWord
&w
)
1645 setBrick(w
.Slot
.Brick
->getSheetId());
1646 Slot
.Valid
= w
.Slot
.Valid
;
1647 Slot
.ViewParamFamilies
= w
.Slot
.ViewParamFamilies
;
1650 NumTotalParams
= w
.NumTotalParams
;
1651 ParamError
= w
.ParamError
;
1652 for(uint i
=0;i
<NumTotalParams
;i
++)
1654 setParamBrick(i
, w
.ParamSlot
[i
].Brick
->getSheetId());
1655 ParamSlot
[i
].Valid
= w
.ParamSlot
[i
].Valid
;
1656 ParamSlot
[i
].ViewParamFamilies
= w
.ParamSlot
[i
].ViewParamFamilies
;
1660 CostView
->setText(w
.CostView
->getText());
1661 CostView
->setActive(w
.CostView
->getActive());
1662 CreditView
->setText(w
.CreditView
->getText());
1663 CreditView
->setActive(w
.CreditView
->getActive());
1664 InfoView
->setText(w
.InfoView
->getText());
1665 InfoView
->setActive(w
.InfoView
->getActive());
1669 // ***************************************************************************
1670 void CDBGroupBuildPhrase::resetSentence(sint32 rootSheetId
)
1677 // first update the root brick
1678 _MainWords
[0].setBrick(rootSheetId
);
1679 // then update display for others
1680 updateDisplayFromRootBrick();
1682 // get the root brick
1683 const CSBrickSheet
*rootBrick
= getRootBrick();
1688 // update parameters of the root
1691 // *** Init Mandatories
1692 for(i
=1;i
<1+_NumMandatories
;i
++)
1694 // get the family Known BitField
1695 uint familyId
= rootBrick
->MandatoryFamilies
[i
-1];
1698 getDefaultSheetForFamily(familyId
, sheet
, valid
);
1700 // Setup the ctrl sheet of mandatory to 0 by default!
1701 _MainWords
[i
].setBrick(0);
1702 _MainWords
[i
].Slot
.Valid
= valid
;
1704 // set the ctrl sheet display
1705 _MainWords
[i
].Slot
.Brick
->setGrayed( !valid
);
1707 // update the parameters of this main brick
1711 // *** Init Optional/Credits
1712 // ungray all optional slots.
1713 for(i
=1+_NumMandatories
;i
<_MainWords
.size();i
++)
1715 _MainWords
[i
].Slot
.Brick
->setGrayed( false );
1718 // update the NewOp controler
1723 // ***************************************************************************
1724 void CDBGroupBuildPhrase::updateDisplayFromRootBrick()
1731 // get the root bricks
1732 const CSBrickSheet
*brick
= getRootBrick();
1734 // Reset the Root params only (don't reset the sheetId setuped!)
1735 _MainWords
[0].resetParams();
1737 // Hide all other slots by default
1738 for(i
=1;i
<_MainWords
.size();i
++)
1740 _MainWords
[i
].reset();
1746 // if brick not found, or if not enough ctrl, hide all
1747 if(!brick
|| brick
->MandatoryFamilies
.size()+1>_MainWords
.size() )
1750 _MainWords
[0].Slot
.Brick
->setSheetId(0);
1752 // else ok, setup the composition
1755 _NumMandatories
= (uint32
)brick
->MandatoryFamilies
.size();
1756 // Don't enable any optional/credit by default
1761 // update the group and sons coords
1765 // ***************************************************************************
1766 void CDBGroupBuildPhrase::buildCurrentPhrase(CSPhraseCom
&newPhrase
)
1768 /* Word Order: Root/Mandatory/Optional/Credits (with all their params)
1772 newPhrase
.Name
.clear();
1773 newPhrase
.Bricks
.clear();
1775 const CSBrickSheet
*brick
;
1777 // Add All bricks with their parameters
1778 for(i
=0;i
<getNumMainBricks();i
++)
1780 CWord
&word
= _MainWords
[i
];
1781 brick
= word
.Slot
.Brick
->asSBrickSheet();
1782 newPhrase
.Bricks
.push_back(brick
?brick
->Id
:CSheetId());
1783 // For all its params.
1784 for(uint j
=0;j
<word
.NumTotalParams
;j
++)
1786 brick
= word
.ParamSlot
[j
].Brick
->asSBrickSheet();
1787 newPhrase
.Bricks
.push_back(brick
?brick
->Id
:CSheetId());
1792 if(_UserSentenceName
)
1794 newPhrase
.Name
= ucstring::makeFromUtf8(_UserSentenceName
->getInputString());
1799 // ***************************************************************************
1800 void CDBGroupBuildPhrase::updateNewButtons()
1802 // TODO_BRICK: have I to hide button and their text if not possible to add any op/credit?
1807 uint newOpIndex= _NumMandatories+_NumOptionals;
1809 // if some place for a new optional, show and place the NewOpButton
1810 if(newOpIndex<_MandOpWords.size())
1812 // if comes from a delete, ensure the back+1 is hidden
1813 if(newOpIndex+1<_MandOpWords.size())
1815 _MandOpWords[newOpIndex+1].Slot.Back->setActive(false);
1818 // Show a new Optional possibilty ONLY if really possible!!
1819 std::vector<NLMISC::CSheetId> bricks;
1820 fillNewOptionalBricks(bricks);
1821 // if no choice possible
1824 _NewOpButton->setActive(false);
1828 // show the Back under the button
1829 _MandOpWords[newOpIndex].Slot.Back->setActive(true);
1830 // And move the button under it
1831 _NewOpButton->setParentPos(_MandOpWords[newOpIndex].Slot.Back);
1832 _NewOpButton->setActive(true);
1837 _NewOpButton->setActive(false);
1841 invalidateCoords();*/
1844 // ***************************************************************************
1845 void CDBGroupBuildPhrase::updateSpellView()
1849 // Build the current phrase
1850 CSPhraseCom newPhrase
;
1851 buildCurrentPhrase(newPhrase
);
1853 // Set the edited version to the phrase Manager => auto updated in icon
1854 CSPhraseManager
*pPM
= CSPhraseManager::getInstance();
1856 // replace the content of the edited phrase.
1857 pPM
->setPhrase(CSPhraseManager::EditionSlot
, newPhrase
);
1862 // ***************************************************************************
1863 void CDBGroupBuildPhrase::fillNewOptionalBricks(std::vector
<NLMISC::CSheetId
> &bricks
)
1865 if(!_GroupValid
) return;
1866 const CSBrickSheet
*rootBrick
= getRootBrick();
1867 if(!rootBrick
) return;
1868 CSBrickManager
*pBM
= CSBrickManager::getInstance();
1870 // get all possible newFamilies
1871 vector
<uint16
> optionalFamilies
;
1872 optionalFamilies
= rootBrick
->OptionalFamilies
;
1873 // Filter ones that already exist in the composition
1874 // Don't filter Combat and Power optional families (Use Brick exclusion system instead)
1875 if( !rootBrick
->isCombat() && !rootBrick
->isSpecialPower())
1876 filterFamilySetuped(optionalFamilies
);
1878 // Select all bricks for those families.
1879 for(uint i
=0;i
<optionalFamilies
.size();i
++)
1881 const vector
<CSheetId
> &famBricks
= pBM
->getFamilyBricks(optionalFamilies
[i
]);
1882 bricks
.insert(bricks
.end(), famBricks
.begin(), famBricks
.end());
1885 // get only ones known
1886 filterKnownBricks(bricks
);
1889 if( rootBrick
->isCombat() )
1891 // Ensure not same bricks are setuped
1892 filterBrickSetuped(bricks
);
1893 // Ensure only optional of compatible Skill are inserted
1894 filterSkillSetuped(bricks
, true, false);
1896 else if ( rootBrick
->isSpecialPower() )
1898 // Ensure not same bricks are setuped
1899 filterBrickSetuped(bricks
);
1901 // filter by BrickExclusion
1902 filterBrickExclusion(bricks
);
1905 // ***************************************************************************
1906 void CDBGroupBuildPhrase::fillNewCreditBricks(std::vector
<NLMISC::CSheetId
> &bricks
)
1908 if(!_GroupValid
) return;
1909 const CSBrickSheet
*rootBrick
= getRootBrick();
1910 if(!rootBrick
) return;
1911 CSBrickManager
*pBM
= CSBrickManager::getInstance();
1913 // get all possible newFamilies
1914 vector
<uint16
> creditFamilies
;
1915 creditFamilies
= rootBrick
->CreditFamilies
;
1916 // Filter ones that already exist in the composition
1917 filterFamilySetuped(creditFamilies
);
1919 // Select all bricks for those families.
1920 for(uint i
=0;i
<creditFamilies
.size();i
++)
1922 const vector
<CSheetId
> &famBricks
= pBM
->getFamilyBricks(creditFamilies
[i
]);
1923 bricks
.insert(bricks
.end(), famBricks
.begin(), famBricks
.end());
1926 // get only ones known
1927 filterKnownBricks(bricks
);
1929 // filter by BrickExclusion
1930 filterBrickExclusion(bricks
);
1934 // ***************************************************************************
1935 void CDBGroupBuildPhrase::setRootBrickTypeFilter(BRICK_TYPE::EBrickType rootBtFilter
,
1936 BRICK_TYPE::EBrickType rootBtFilter2
, BRICK_TYPE::EBrickType rootBtFilter3
, BRICK_TYPE::EBrickType rootBtFilter4
)
1938 nlctassert(MaxRootBrickTypeFilter
==4);
1939 _RootBrickTypeFilter
[0]= rootBtFilter
;
1940 _RootBrickTypeFilter
[1]= rootBtFilter2
;
1941 _RootBrickTypeFilter
[2]= rootBtFilter3
;
1942 _RootBrickTypeFilter
[3]= rootBtFilter4
;