1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-25 22:42:04 +02:00

Rewritten battle obstacles. New file for lib: CObstacleInstance.cpp.

Now obstacles should be placed exactly like they were in OH3. 
All problems with displaying obstacles in battlefield should be gone. They should be now matched to the single pixel. 
If there are still some discrepancies, please report them.
This commit is contained in:
Michał W. Urbańczyk
2012-04-23 19:56:37 +00:00
parent 6d03e0bf23
commit 7dc0d6878e
16 changed files with 1606 additions and 300 deletions

View File

@@ -6,13 +6,7 @@
#include "../lib/JsonNode.h"
#include "GameConstants.h"
#include <boost/version.hpp>
#if BOOST_VERSION >= 103800
#include <boost/spirit/include/classic.hpp>
#else
#include <boost/spirit.hpp>
#endif
using namespace boost::spirit;
#include "BattleHex.h"
extern CLodHandler * bitmaph;
void loadToIt(std::string &dest, const std::string &src, int &iter, int mode);
@@ -57,74 +51,37 @@ EAlignment::EAlignment CHeroClass::getAlignment()
return (EAlignment::EAlignment)alignment;
}
int CObstacleInfo::getWidth() const
{
int ret = 1;
int line = 1;
for(int h=0; h<blockmap.size(); ++h)
{
int cur = - line/2;
switch(blockmap[h])
{
case 'X' : case 'N':
++cur;
break;
case 'L':
if(cur > ret)
ret = cur;
++line;
break;
}
}
return ret;
}
int CObstacleInfo::getHeight() const
{
int ret = 1;
for(int h=0; h<blockmap.size(); ++h)
{
if(blockmap[h] == 'L')
{
++ret;
}
}
return ret;
}
std::vector<BattleHex> CObstacleInfo::getBlocked(BattleHex hex) const
{
std::vector<BattleHex> ret;
int cur = hex; //currently browsed hex
int curBeg = hex; //beginning of current line
for(int h=0; h<blockmap.size(); ++h)
if(isAbsoluteObstacle)
{
switch(blockmap[h])
{
case 'X':
ret.push_back(cur);
++cur;
break;
case 'L':
cur = curBeg + GameConstants::BFIELD_WIDTH;
if((cur/GameConstants::BFIELD_WIDTH)%2 != 1)
{
cur--;
}
curBeg = cur;
break;
case 'N':
++cur;
break;
}
assert(!hex.isValid());
range::copy(blockedTiles, std::back_inserter(ret));
return ret;
}
BOOST_FOREACH(int offset, blockedTiles)
{
BattleHex toBlock = hex + offset;
if((hex.getY() & 1) && !(toBlock.getY() & 1))
toBlock += BattleHex::LEFT;
if(!toBlock.isValid())
tlog1 << "Misplaced obstacle!\n";
else
ret.push_back(toBlock);
}
return ret;
}
BattleHex CObstacleInfo::getMaxBlocked(BattleHex hex) const
bool CObstacleInfo::isAppropriate(int terrainType, int specialBattlefield /*= -1*/) const
{
std::vector<BattleHex> blocked = getBlocked(hex);
return *std::max_element(blocked.begin(), blocked.end());
if(specialBattlefield != -1)
return vstd::contains(allowedSpecialBfields, specialBattlefield);
return vstd::contains(allowedTerrains, terrainType);
}
CHeroHandler::~CHeroHandler()
@@ -141,21 +98,27 @@ CHeroHandler::CHeroHandler()
void CHeroHandler::loadObstacles()
{
auto loadObstacles = [](const JsonNode &node, bool absolute, std::map<int, CObstacleInfo> &out)
{
BOOST_FOREACH(const JsonNode &obs, node.Vector())
{
int ID = obs["id"].Float();
CObstacleInfo & obi = out[ID];
obi.ID = ID;
obi.defName = obs["defname"].String();
obi.width = obs["width"].Float();
obi.height = obs["height"].Float();
obi.allowedTerrains = obs["allowedTerrain"].StdVector<ui8>();
obi.allowedSpecialBfields = obs["specialBattlefields"].StdVector<ui8>();
obi.blockedTiles = obs["blockedTiles"].StdVector<si16>();
obi.isAbsoluteObstacle = absolute;
}
};
const JsonNode config(GameConstants::DATA_DIR + "/config/obstacles.json");
BOOST_FOREACH(const JsonNode &obs, config["obstacles"].Vector()) {
CObstacleInfo obi;
obi.ID = obs["id"].Float();
obi.defName = obs["defname"].String();
obi.blockmap = obs["blockmap"].String();
obi.allowedTerrains = obs["terrains"].String();
assert(obi.allowedTerrains.size() >= 25);
obi.posShift.first = obs["shift_x"].Float();
obi.posShift.second = obs["shift_y"].Float();
obstacles[obi.ID] = obi;
}
loadObstacles(config["obstacles"], false, obstacles);
loadObstacles(config["absoluteObstacles"], true, absoluteObstacles);
}
void CHeroHandler::loadPuzzleInfo()
@@ -164,12 +127,12 @@ void CHeroHandler::loadPuzzleInfo()
int faction = 0;
BOOST_FOREACH(const JsonNode &puzzle, config["puzzles"].Vector()) {
BOOST_FOREACH(const JsonNode &puzzle, config["puzzles"].Vector())
{
int idx = 0;
BOOST_FOREACH(const JsonNode &piece, puzzle.Vector()) {
BOOST_FOREACH(const JsonNode &piece, puzzle.Vector())
{
SPuzzleInfo spi;
spi.x = piece["x"].Float();