mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
* servers will not allow using out-of-range slots ( #1061 )
* server won't crash on some scenarios when they're used * fixed some minor discrepancies with creature placement in creature banks
This commit is contained in:
parent
838c226a31
commit
6530e7a1e1
@ -159,7 +159,7 @@ SDL_Surface * BitmapHandler::loadBitmap(std::string fname, bool setKey)
|
||||
|
||||
if (!(bitmap = loadBitmapFromDir("DATA/", fname, setKey)) &&
|
||||
!(bitmap = loadBitmapFromDir("SPRITES/", fname, setKey)))
|
||||
tlog0<<"Error: Failed to find file "<<fname<<"\n";
|
||||
tlog1<<"Error: Failed to find file "<<fname<<"\n";
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
@ -82,6 +82,12 @@ void CArmyTooltip::init(const InfoAboutArmy &army)
|
||||
|
||||
BOOST_FOREACH(auto & slot, army.army)
|
||||
{
|
||||
if(slot.first >= GameConstants::ARMY_SIZE)
|
||||
{
|
||||
tlog3 << "Warning: " << army.name << " has stack in slot " << slot.first << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
new CAnimImage("CPRSMALL", slot.second.type->idNumber + 2, 0, slotsPos[slot.first].x, slotsPos[slot.first].y);
|
||||
|
||||
std::string subtitle;
|
||||
|
@ -71,11 +71,11 @@
|
||||
"levels": [
|
||||
[ 15 ],
|
||||
[ 15, 185 ],
|
||||
[ 15, 185, 171 ],
|
||||
[ 15, 185, 171, 1 ],
|
||||
[ 15, 185, 171, 1, 100 ],
|
||||
[ 15, 185, 171, 1, 100, 86 ],
|
||||
[ 15, 185, 171, 1, 100, 86, 8 ]
|
||||
[ 15, 185, 172 ],
|
||||
[ 15, 185, 172, 2 ],
|
||||
[ 15, 185, 172, 2, 100 ],
|
||||
[ 15, 185, 172, 2, 100, 86 ],
|
||||
[ 15, 185, 172, 2, 100, 86, 8 ]
|
||||
]
|
||||
}
|
||||
],
|
||||
|
@ -911,17 +911,17 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, int terrain, int battlefieldTyp
|
||||
|
||||
//reading battleStartpos - add creatures AFTER random obstacles are generated
|
||||
//TODO: parse once to some structure
|
||||
std::vector< std::vector<int> > attackerLoose, defenderLoose, attackerTight, defenderTight, attackerCreBank, defenderCreBank;
|
||||
std::vector< std::vector<int> > looseFormations[2], tightFormations[2], creBankFormations[2];
|
||||
std::vector <int> commanderField, commanderBank;
|
||||
const JsonNode config(ResourceID("config/battleStartpos.json"));
|
||||
const JsonVector &positions = config["battle_positions"].Vector();
|
||||
|
||||
CGH::readBattlePositions(positions[0]["levels"], attackerLoose);
|
||||
CGH::readBattlePositions(positions[1]["levels"], defenderLoose);
|
||||
CGH::readBattlePositions(positions[2]["levels"], attackerTight);
|
||||
CGH::readBattlePositions(positions[3]["levels"], defenderTight);
|
||||
CGH::readBattlePositions(positions[4]["levels"], attackerCreBank);
|
||||
CGH::readBattlePositions(positions[5]["levels"], defenderCreBank);
|
||||
CGH::readBattlePositions(positions[0]["levels"], looseFormations[0]);
|
||||
CGH::readBattlePositions(positions[1]["levels"], looseFormations[1]);
|
||||
CGH::readBattlePositions(positions[2]["levels"], tightFormations[0]);
|
||||
CGH::readBattlePositions(positions[3]["levels"], tightFormations[1]);
|
||||
CGH::readBattlePositions(positions[4]["levels"], creBankFormations[0]);
|
||||
CGH::readBattlePositions(positions[5]["levels"], creBankFormations[1]);
|
||||
|
||||
BOOST_FOREACH (auto position, config["commanderPositions"]["field"].Vector())
|
||||
{
|
||||
@ -957,52 +957,31 @@ BattleInfo * BattleInfo::setupBattle( int3 tile, int terrain, int battlefieldTyp
|
||||
//war machines added
|
||||
|
||||
//battleStartpos read
|
||||
for(int side = 0; side < 2; side++)
|
||||
{
|
||||
int formationNo = armies[side]->stacksCount() - 1;
|
||||
vstd::abetween(formationNo, 0, GameConstants::ARMY_SIZE - 1);
|
||||
|
||||
int k = 0; //stack serial
|
||||
for(TSlots::const_iterator i = armies[0]->Slots().begin(); i!=armies[0]->Slots().end(); i++, k++)
|
||||
for(TSlots::const_iterator i = armies[side]->Slots().begin(); i != armies[side]->Slots().end(); i++, k++)
|
||||
{
|
||||
int pos;
|
||||
std::vector<int> *formationVector = nullptr;
|
||||
if(creatureBank)
|
||||
pos = attackerCreBank[armies[0]->stacksCount()-1][k];
|
||||
else if(armies[0]->formation)
|
||||
pos = attackerTight[armies[0]->stacksCount()-1][k];
|
||||
formationVector = &creBankFormations[side][formationNo];
|
||||
else if(armies[side]->formation)
|
||||
formationVector = &tightFormations[side][formationNo];
|
||||
else
|
||||
pos = attackerLoose[armies[0]->stacksCount()-1][k];
|
||||
formationVector = &looseFormations[side][formationNo];
|
||||
|
||||
CStack * stack = curB->generateNewStack(*i->second, true, i->first, pos);
|
||||
BattleHex pos = (k < formationVector->size() ? formationVector->at(k) : 0);
|
||||
if(creatureBank && i->second->type->isDoubleWide())
|
||||
pos += side ? BattleHex::LEFT : BattleHex::RIGHT;
|
||||
|
||||
CStack * stack = curB->generateNewStack(*i->second, !side, i->first, pos);
|
||||
stacks.push_back(stack);
|
||||
}
|
||||
|
||||
k = 0;
|
||||
for(TSlots::const_iterator i = armies[1]->Slots().begin(); i!=armies[1]->Slots().end(); i++, k++)
|
||||
{
|
||||
int pos;
|
||||
if(creatureBank)
|
||||
pos = defenderCreBank[armies[1]->stacksCount()-1][k];
|
||||
else if(armies[1]->formation)
|
||||
pos = defenderTight[armies[1]->stacksCount()-1][k];
|
||||
else
|
||||
pos = defenderLoose[armies[1]->stacksCount()-1][k];
|
||||
|
||||
CStack * stack = curB->generateNewStack(*i->second, false, i->first, pos);
|
||||
stacks.push_back(stack);
|
||||
}
|
||||
|
||||
// //shifting positions of two-hex creatures
|
||||
// for(unsigned g=0; g<stacks.size(); ++g)
|
||||
// {
|
||||
// //we should do that for creature bank too
|
||||
// if(stacks[g]->doubleWide() && stacks[g]->attackerOwned)
|
||||
// {
|
||||
// stacks[g]->position += BattleHex::RIGHT;
|
||||
// }
|
||||
// else if(stacks[g]->doubleWide() && !stacks[g]->attackerOwned)
|
||||
// {
|
||||
// if (stacks[g]->position.getX() > 1)
|
||||
// stacks[g]->position += BattleHex::LEFT;
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
//adding commanders
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
|
@ -348,7 +348,7 @@ bool CBattleInfoEssentials::battleCanSurrender(int player) const
|
||||
{
|
||||
RETURN_IF_NOT_BATTLE(false);
|
||||
//conditions like for fleeing + enemy must have a hero
|
||||
return battleCanFlee(player) && battleGetFightingHero(!playerToSide(player));
|
||||
return battleCanFlee(player) && battleHasHero(!playerToSide(player));
|
||||
}
|
||||
|
||||
bool CBattleInfoEssentials::battleHasHero(ui8 side) const
|
||||
|
@ -322,6 +322,7 @@ CArmedInstance * CCreatureSet::castToArmyObj()
|
||||
|
||||
void CCreatureSet::putStack(TSlot slot, CStackInstance *stack)
|
||||
{
|
||||
assert(slot < GameConstants::ARMY_SIZE);
|
||||
assert(!hasStackAtSlot(slot));
|
||||
stacks[slot] = stack;
|
||||
stack->setArmyObj(castToArmyObj());
|
||||
|
@ -185,6 +185,12 @@ struct StackLocation
|
||||
army = const_cast<CArmedInstance*>(Army); //we are allowed here to const cast -> change will go through one of our packages... do not abuse!
|
||||
slot = Slot;
|
||||
}
|
||||
|
||||
bool validSlot() const
|
||||
{
|
||||
return slot >= 0 && slot < GameConstants::ARMY_SIZE;
|
||||
}
|
||||
|
||||
DLL_LINKAGE const CStackInstance *getStack();
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
|
@ -2299,6 +2299,11 @@ bool CGameHandler::arrangeStacks( si32 id1, si32 id2, ui8 what, ui8 p1, ui8 p2,
|
||||
*s2 = static_cast<CArmedInstance*>(gs->map->objects[id2].get());
|
||||
const CCreatureSet &S1 = *s1, &S2 = *s2;
|
||||
StackLocation sl1(s1, p1), sl2(s2, p2);
|
||||
if(!sl1.validSlot() || !sl2.validSlot())
|
||||
{
|
||||
complain("Invalid slot accessed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!isAllowedExchange(id1,id2))
|
||||
{
|
||||
@ -5616,6 +5621,9 @@ bool CGameHandler::insertNewStack(const StackLocation &sl, const CCreature *c, T
|
||||
if(sl.army->hasStackAtSlot(sl.slot))
|
||||
COMPLAIN_RET("Slot is already taken!");
|
||||
|
||||
if(!sl.validSlot())
|
||||
COMPLAIN_RET("Cannot insert stack to that slot!");
|
||||
|
||||
InsertNewStack ins;
|
||||
ins.sl = sl;
|
||||
ins.stack = CStackBasicDescriptor(c, count);
|
||||
@ -5723,6 +5731,9 @@ bool CGameHandler::moveStack(const StackLocation &src, const StackLocation &dst,
|
||||
if(dst.army->hasStackAtSlot(dst.slot) && dst.army->getCreature(dst.slot) != src.army->getCreature(src.slot))
|
||||
COMPLAIN_RET("Cannot move: stack of different type at destination pos!");
|
||||
|
||||
if(!dst.validSlot())
|
||||
COMPLAIN_RET("Cannot move stack to that slot!");
|
||||
|
||||
if(count == -1)
|
||||
{
|
||||
count = src.army->getStackCount(src.slot);
|
||||
@ -5733,7 +5744,7 @@ bool CGameHandler::moveStack(const StackLocation &src, const StackLocation &dst,
|
||||
&& src.army->Slots().size() == 1 //from the last stack
|
||||
&& src.army->needsLastStack()) //that must be left
|
||||
{
|
||||
COMPLAIN_RET("Cannot move away the alst creature!");
|
||||
COMPLAIN_RET("Cannot move away the last creature!");
|
||||
}
|
||||
|
||||
RebalanceStacks rs;
|
||||
|
Loading…
Reference in New Issue
Block a user