1
0
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:
Michał W. Urbańczyk 2012-08-30 16:01:19 +00:00
parent 838c226a31
commit 6530e7a1e1
8 changed files with 60 additions and 57 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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 ]
]
}
],

View File

@ -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
int k = 0; //stack serial
for(TSlots::const_iterator i = armies[0]->Slots().begin(); i!=armies[0]->Slots().end(); i++, k++)
for(int side = 0; side < 2; side++)
{
int pos;
if(creatureBank)
pos = attackerCreBank[armies[0]->stacksCount()-1][k];
else if(armies[0]->formation)
pos = attackerTight[armies[0]->stacksCount()-1][k];
else
pos = attackerLoose[armies[0]->stacksCount()-1][k];
int formationNo = armies[side]->stacksCount() - 1;
vstd::abetween(formationNo, 0, GameConstants::ARMY_SIZE - 1);
CStack * stack = curB->generateNewStack(*i->second, true, i->first, pos);
stacks.push_back(stack);
int k = 0; //stack serial
for(TSlots::const_iterator i = armies[side]->Slots().begin(); i != armies[side]->Slots().end(); i++, k++)
{
std::vector<int> *formationVector = nullptr;
if(creatureBank)
formationVector = &creBankFormations[side][formationNo];
else if(armies[side]->formation)
formationVector = &tightFormations[side][formationNo];
else
formationVector = &looseFormations[side][formationNo];
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)
{

View File

@ -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

View File

@ -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());

View File

@ -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)
{

View File

@ -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;