diff --git a/client/widgets/CGarrisonInt.cpp b/client/widgets/CGarrisonInt.cpp index 92cffa6a9..d09affdcf 100644 --- a/client/widgets/CGarrisonInt.cpp +++ b/client/widgets/CGarrisonInt.cpp @@ -281,7 +281,10 @@ void CGarrisonSlot::clickLeft(tribool down, bool previousState) bool refr = false; const CGarrisonSlot * selection = owner->getSelection(); if(!selection) + { refr = highlightOrDropArtifact(); + handleSplittingShortcuts(); + } else if(selection == this) refr = viewInfo(); // Re-highlight if troops aren't removable or not ours. @@ -396,6 +399,35 @@ CGarrisonSlot::CGarrisonSlot(CGarrisonInt *Owner, int x, int y, SlotID IID, CGar stackCount->setText(boost::lexical_cast(myStack->count)); } +void CGarrisonSlot::splitIntoParts(CGarrisonSlot::EGarrisonType type, int amount, int maxOfSplittedSlots) +{ + owner->pb = type; + for(CGarrisonSlot * slot : owner->getEmptySlots(type)) + { + owner->p2 = slot->ID; + owner->splitStacks(1, amount); + maxOfSplittedSlots--; + if(!maxOfSplittedSlots || owner->getSelection()->myStack->count <= 1) + break; + } +} + +void CGarrisonSlot::handleSplittingShortcuts() +{ + const Uint8 * state = SDL_GetKeyboardState(NULL); + if(owner->getSelection() && owner->getEmptySlots(owner->getSelection()->upg).size() && owner->getSelection()->myStack->count > 1){ + if (state[SDL_SCANCODE_LCTRL] && state[SDL_SCANCODE_LSHIFT]) + splitIntoParts(owner->getSelection()->upg, 1, 7); + else if(state[SDL_SCANCODE_LCTRL]) + splitIntoParts(owner->getSelection()->upg, 1, 1); + else if(state[SDL_SCANCODE_LSHIFT]) + splitIntoParts(owner->getSelection()->upg, owner->getSelection()->myStack->count/2 , 1); + else + return; + owner->selectSlot(nullptr); + } +} + void CGarrisonInt::addSplitBtn(CButton * button) { addChild(button); @@ -519,6 +551,17 @@ bool CGarrisonInt::getSplittingMode() return inSplittingMode; } +std::vector CGarrisonInt::getEmptySlots(CGarrisonSlot::EGarrisonType type) +{ + std::vector emptySlots; + for(CGarrisonSlot * slot : availableSlots) + { + if(type == slot->upg && ((slot->our() || slot->ally()) && slot->creature == nullptr)) + emptySlots.push_back(slot); + } + return emptySlots; +} + void CGarrisonInt::setArmy(const CArmedInstance *army, bool bottomGarrison) { owned[bottomGarrison] = army ? (army->tempOwner == LOCPLINT->playerID || army->tempOwner == PlayerColor::UNFLAGGABLE) : false; diff --git a/client/widgets/CGarrisonInt.h b/client/widgets/CGarrisonInt.h index 84f59f206..27d6547b6 100644 --- a/client/widgets/CGarrisonInt.h +++ b/client/widgets/CGarrisonInt.h @@ -55,6 +55,9 @@ public: void update(); CGarrisonSlot(CGarrisonInt *Owner, int x, int y, SlotID IID, EGarrisonType Upg=EGarrisonType::UP, const CStackInstance * Creature=nullptr); + void splitIntoParts(EGarrisonType type, int amount, int maxOfSplittedSlots); + void handleSplittingShortcuts(); + friend class CGarrisonInt; }; @@ -83,7 +86,8 @@ public: twoRows, ///< slots Will be placed in 2 rows owned[2]; ///< player Owns up or down army ([0] upper, [1] lower) - std::vector availableSlots; ///< Slots of upper and lower garrison + std::vector availableSlots; ///< Slots of upper and lower garrison + std::vector getEmptySlots(CGarrisonSlot::EGarrisonType type); const CArmedInstance *armedObjs[2]; ///< [0] is upper, [1] is down