From 75cffa7d0b6460e78238269cd0c27e3bfdb3b57a Mon Sep 17 00:00:00 2001 From: Arseniy Shestakov Date: Mon, 19 Sep 2016 03:20:44 +0300 Subject: [PATCH] CGameHandler::arrangeStacks: honour removableUnits of CGGarrison Now server properly check allowed actions for CGGarrison. Fix issue 2303 Server now allow all stack arrangement as long as troops stay inside garrison. It's possible to put more troops inside using swap/merge/split, but not take anything out if it. --- server/CGameHandler.cpp | 46 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 9c4abe3a2..ed19e1894 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -2626,6 +2626,21 @@ bool CGameHandler::arrangeStacks( ObjectInstanceID id1, ObjectInstanceID id2, ui return false; } + // We can always put stacks into locked garrison, but not take them out of it + auto notRemovable = [&](const CArmedInstance * army) + { + if(id1 != id2) // Stack arrangement inside locked garrison is allowed + { + auto g = dynamic_cast(army); + if(g && !g->removableUnits) + { + complain("Stacks in this garrison are not removable!\n"); + return true; + } + } + return false; + }; + if(what==1) //swap { if ( ((s1->tempOwner != player && s1->tempOwner != PlayerColor::UNFLAGGABLE) && s1->getStackCount(p1)) @@ -2641,6 +2656,16 @@ bool CGameHandler::arrangeStacks( ObjectInstanceID id1, ObjectInstanceID id2, ui return false; } + if(!s1->slotEmpty(p1) && !s2->slotEmpty(p2)) + { + if(notRemovable(sl1.army) || notRemovable(sl2.army)) + return false; + } + if(s1->slotEmpty(p1) && notRemovable(sl2.army)) + return false; + else if(s2->slotEmpty(p2) && notRemovable(sl1.army)) + return false; + swapStacks(sl1, sl2); } else if(what==2)//merge @@ -2649,6 +2674,14 @@ bool CGameHandler::arrangeStacks( ObjectInstanceID id1, ObjectInstanceID id2, ui || (((s1->tempOwner != player && s1->tempOwner != PlayerColor::UNFLAGGABLE) && s2->getStackCount(p2)) && complain("Can't take troops from another player!"))) return false; + if(s1->slotEmpty(p1) || s2->slotEmpty(p2)) + { + complain("Cannot merge empty stack!"); + return false; + } + else if(notRemovable(sl1.army)) + return false; + moveStack(sl1, sl2); } else if(what==3) //split @@ -2681,6 +2714,17 @@ bool CGameHandler::arrangeStacks( ObjectInstanceID id1, ObjectInstanceID id2, ui return false; } + if(notRemovable(sl1.army)) + { + if(s1->getStackCount(p1) > countLeftOnSrc) + return false; + } + else if(notRemovable(sl2.army)) + { + if(s2->getStackCount(p1) < countLeftOnSrc) + return false; + } + moveStack(sl1, sl2, countToMove); //S2.slots[p2]->count = val; //S1.slots[p1]->count = total - val; @@ -2693,6 +2737,8 @@ bool CGameHandler::arrangeStacks( ObjectInstanceID id1, ObjectInstanceID id2, ui return false; } + if(notRemovable(sl1.army)) + return false; moveStack(sl1, sl2, val); }