1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-12 02:28:11 +02:00

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.
This commit is contained in:
Arseniy Shestakov 2016-09-19 03:20:44 +03:00
parent 540d239df6
commit 75cffa7d0b

View File

@ -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<const CGGarrison *>(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);
}