mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-28 08:48:48 +02:00
Whitespace cleanup. (No code changes.)
This commit is contained in:
parent
c550484613
commit
4d9058e412
18
Global.h
18
Global.h
@ -55,7 +55,7 @@ static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size.");
|
|||||||
# define VCMI_UNIX
|
# define VCMI_UNIX
|
||||||
# define VCMI_XDG
|
# define VCMI_XDG
|
||||||
# ifdef __ANDROID__
|
# ifdef __ANDROID__
|
||||||
# define VCMI_ANDROID
|
# define VCMI_ANDROID
|
||||||
# endif
|
# endif
|
||||||
#elif defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
|
#elif defined(__FreeBSD_kernel__) || defined(__FreeBSD__)
|
||||||
# define VCMI_UNIX
|
# define VCMI_UNIX
|
||||||
@ -285,7 +285,7 @@ std::ostream & operator<<(std::ostream & out, const std::vector<T> & container)
|
|||||||
|
|
||||||
namespace vstd
|
namespace vstd
|
||||||
{
|
{
|
||||||
|
|
||||||
// combine hashes. Present in boost but not in std
|
// combine hashes. Present in boost but not in std
|
||||||
template <class T>
|
template <class T>
|
||||||
inline void hash_combine(std::size_t& seed, const T& v)
|
inline void hash_combine(std::size_t& seed, const T& v)
|
||||||
@ -293,7 +293,7 @@ namespace vstd
|
|||||||
std::hash<T> hasher;
|
std::hash<T> hasher;
|
||||||
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
|
seed ^= hasher(v) + 0x9e3779b9 + (seed<<6) + (seed>>2);
|
||||||
}
|
}
|
||||||
|
|
||||||
//returns true if container c contains item i
|
//returns true if container c contains item i
|
||||||
template <typename Container, typename Item>
|
template <typename Container, typename Item>
|
||||||
bool contains(const Container & c, const Item &i)
|
bool contains(const Container & c, const Item &i)
|
||||||
@ -505,7 +505,7 @@ namespace vstd
|
|||||||
void erase_if(std::set<Elem> &setContainer, Predicate pred)
|
void erase_if(std::set<Elem> &setContainer, Predicate pred)
|
||||||
{
|
{
|
||||||
auto itr = setContainer.begin();
|
auto itr = setContainer.begin();
|
||||||
auto endItr = setContainer.end();
|
auto endItr = setContainer.end();
|
||||||
while(itr != endItr)
|
while(itr != endItr)
|
||||||
{
|
{
|
||||||
auto tmpItr = itr++;
|
auto tmpItr = itr++;
|
||||||
@ -519,7 +519,7 @@ namespace vstd
|
|||||||
void erase_if(std::map<Key, Val> &container, Predicate pred)
|
void erase_if(std::map<Key, Val> &container, Predicate pred)
|
||||||
{
|
{
|
||||||
auto itr = container.begin();
|
auto itr = container.begin();
|
||||||
auto endItr = container.end();
|
auto endItr = container.end();
|
||||||
while(itr != endItr)
|
while(itr != endItr)
|
||||||
{
|
{
|
||||||
auto tmpItr = itr++;
|
auto tmpItr = itr++;
|
||||||
@ -554,7 +554,7 @@ namespace vstd
|
|||||||
return vf(lhs) < vf(rhs);
|
return vf(lhs) < vf(rhs);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//Returns iterator to the element for which the value of ValueFunction is maximal
|
//Returns iterator to the element for which the value of ValueFunction is maximal
|
||||||
template<class ForwardRange, class ValueFunction>
|
template<class ForwardRange, class ValueFunction>
|
||||||
auto maxElementByFun(const ForwardRange& rng, ValueFunction vf) -> decltype(std::begin(rng))
|
auto maxElementByFun(const ForwardRange& rng, ValueFunction vf) -> decltype(std::begin(rng))
|
||||||
@ -627,7 +627,7 @@ namespace vstd
|
|||||||
{
|
{
|
||||||
if(index < r.size())
|
if(index < r.size())
|
||||||
return r[index];
|
return r[index];
|
||||||
|
|
||||||
return defaultValue;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -668,12 +668,12 @@ namespace vstd
|
|||||||
boost::sort(vec);
|
boost::sort(vec);
|
||||||
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
|
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void concatenate(std::vector<T> &dest, const std::vector<T> &src)
|
void concatenate(std::vector<T> &dest, const std::vector<T> &src)
|
||||||
{
|
{
|
||||||
dest.reserve(dest.size() + src.size());
|
dest.reserve(dest.size() + src.size());
|
||||||
dest.insert(dest.end(), src.begin(), src.end());
|
dest.insert(dest.end(), src.begin(), src.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -361,7 +361,7 @@ CGTownInstance::EFortLevel CGTownInstance::fortLevel() const //0 - none, 1 - for
|
|||||||
|
|
||||||
int CGTownInstance::hallLevel() const // -1 - none, 0 - village, 1 - town, 2 - city, 3 - capitol
|
int CGTownInstance::hallLevel() const // -1 - none, 0 - village, 1 - town, 2 - city, 3 - capitol
|
||||||
{
|
{
|
||||||
|
|
||||||
if (hasBuilt(BuildingID::CAPITOL))
|
if (hasBuilt(BuildingID::CAPITOL))
|
||||||
return 3;
|
return 3;
|
||||||
if (hasBuilt(BuildingID::CITY_HALL))
|
if (hasBuilt(BuildingID::CITY_HALL))
|
||||||
@ -456,12 +456,12 @@ TResources CGTownInstance::dailyIncome() const
|
|||||||
{
|
{
|
||||||
TResources ret;
|
TResources ret;
|
||||||
|
|
||||||
for (auto & p : town->buildings)
|
for (auto & p : town->buildings)
|
||||||
{
|
{
|
||||||
BuildingID buildingUpgrade;
|
BuildingID buildingUpgrade;
|
||||||
|
|
||||||
for (auto & p2 : town->buildings)
|
for (auto & p2 : town->buildings)
|
||||||
{
|
{
|
||||||
if (p2.second->upgrade == p.first)
|
if (p2.second->upgrade == p.first)
|
||||||
{
|
{
|
||||||
buildingUpgrade = p2.first;
|
buildingUpgrade = p2.first;
|
||||||
@ -472,7 +472,7 @@ TResources CGTownInstance::dailyIncome() const
|
|||||||
{
|
{
|
||||||
ret += p.second->produce;
|
ret += p.second->produce;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -965,7 +965,7 @@ void CGTownInstance::setVisitingHero(CGHeroInstance *h)
|
|||||||
//{
|
//{
|
||||||
// logGlobal->warnStream() << boost::format("Hero visiting town %s is %s ") % name % (visitingHero.get() ? visitingHero->name : "NULL");
|
// logGlobal->warnStream() << boost::format("Hero visiting town %s is %s ") % name % (visitingHero.get() ? visitingHero->name : "NULL");
|
||||||
// logGlobal->warnStream() << boost::format("New hero will be %s ") % (h ? h->name : "NULL");
|
// logGlobal->warnStream() << boost::format("New hero will be %s ") % (h ? h->name : "NULL");
|
||||||
//
|
//
|
||||||
//}
|
//}
|
||||||
assert(!!visitingHero == !h);
|
assert(!!visitingHero == !h);
|
||||||
|
|
||||||
|
@ -339,7 +339,7 @@ void CMapGenOptions::updateCompOnlyPlayers()
|
|||||||
|
|
||||||
// Add some comp only players if necessary
|
// Add some comp only players if necessary
|
||||||
int compOnlyPlayersToAdd = getPlayerCount() - players.size();
|
int compOnlyPlayersToAdd = getPlayerCount() - players.size();
|
||||||
|
|
||||||
if (compOnlyPlayersToAdd < 0)
|
if (compOnlyPlayersToAdd < 0)
|
||||||
{
|
{
|
||||||
logGlobal->errorStream() << boost::format("Incorrect number of players to add. Requested players %d, current players %d") % playerCount % players.size();
|
logGlobal->errorStream() << boost::format("Incorrect number of players to add. Requested players %d, current players %d") % playerCount % players.size();
|
||||||
|
@ -34,7 +34,7 @@ void CMapGenerator::foreachDirectNeighbour(const int3& pos, std::function<void(i
|
|||||||
int3 n = pos + dir;
|
int3 n = pos + dir;
|
||||||
if(map->isInTheMap(n))
|
if(map->isInTheMap(n))
|
||||||
foo(n);
|
foo(n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -191,7 +191,7 @@ void CMapGenerator::addPlayerInfo()
|
|||||||
playerCount = mapGenOptions->getCompOnlyPlayerCount();
|
playerCount = mapGenOptions->getCompOnlyPlayerCount();
|
||||||
teamCount = mapGenOptions->getCompOnlyTeamCount();
|
teamCount = mapGenOptions->getCompOnlyTeamCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(playerCount == 0)
|
if(playerCount == 0)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
@ -261,7 +261,7 @@ void CMapGenerator::genZones()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CMapGenerator::fillZones()
|
void CMapGenerator::fillZones()
|
||||||
{
|
{
|
||||||
//init native town count with 0
|
//init native town count with 0
|
||||||
for (auto faction : VLC->townh->getAllowedFactions())
|
for (auto faction : VLC->townh->getAllowedFactions())
|
||||||
zonesPerFaction[faction] = 0;
|
zonesPerFaction[faction] = 0;
|
||||||
@ -497,8 +497,8 @@ void CMapGenerator::createConnections()
|
|||||||
zoneA->addMonster (this, guardPos, connection.getGuardStrength(), false, true);
|
zoneA->addMonster (this, guardPos, connection.getGuardStrength(), false, true);
|
||||||
//zones can make paths only in their own area
|
//zones can make paths only in their own area
|
||||||
zoneA->crunchPath(this, guardPos, posA, true, zoneA->getFreePaths()); //make connection towards our zone center
|
zoneA->crunchPath(this, guardPos, posA, true, zoneA->getFreePaths()); //make connection towards our zone center
|
||||||
zoneB->crunchPath(this, guardPos, posB, true, zoneB->getFreePaths()); //make connection towards other zone center
|
zoneB->crunchPath(this, guardPos, posB, true, zoneB->getFreePaths()); //make connection towards other zone center
|
||||||
|
|
||||||
zoneA->addRoadNode(guardPos);
|
zoneA->addRoadNode(guardPos);
|
||||||
zoneB->addRoadNode(guardPos);
|
zoneB->addRoadNode(guardPos);
|
||||||
break; //we're done with this connection
|
break; //we're done with this connection
|
||||||
@ -506,7 +506,7 @@ void CMapGenerator::createConnections()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else //create subterranean gates between two zones
|
else //create subterranean gates between two zones
|
||||||
{
|
{
|
||||||
//find point on the path between zones
|
//find point on the path between zones
|
||||||
float3 offset (posB.x - posA.x, posB.y - posA.y, 0);
|
float3 offset (posB.x - posA.x, posB.y - posA.y, 0);
|
||||||
|
|
||||||
@ -573,7 +573,7 @@ void CMapGenerator::createConnections()
|
|||||||
|
|
||||||
zoneA->addRequiredObject (teleport1, connection.getGuardStrength());
|
zoneA->addRequiredObject (teleport1, connection.getGuardStrength());
|
||||||
zoneB->addRequiredObject (teleport2, connection.getGuardStrength());
|
zoneB->addRequiredObject (teleport2, connection.getGuardStrength());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -592,7 +592,7 @@ void CMapGenerator::addHeaderInfo()
|
|||||||
void CMapGenerator::checkIsOnMap(const int3& tile) const
|
void CMapGenerator::checkIsOnMap(const int3& tile) const
|
||||||
{
|
{
|
||||||
if (!map->isInTheMap(tile))
|
if (!map->isInTheMap(tile))
|
||||||
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
throw rmgException(boost::to_string(boost::format("Tile %s is outside the map") % tile));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -635,8 +635,8 @@ bool CMapGenerator::isUsed(const int3 &tile) const
|
|||||||
bool CMapGenerator::isRoad(const int3& tile) const
|
bool CMapGenerator::isRoad(const int3& tile) const
|
||||||
{
|
{
|
||||||
checkIsOnMap(tile);
|
checkIsOnMap(tile);
|
||||||
|
|
||||||
return tiles[tile.x][tile.y][tile.z].isRoad();
|
return tiles[tile.x][tile.y][tile.z].isRoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMapGenerator::setOccupied(const int3 &tile, ETileType::ETileType state)
|
void CMapGenerator::setOccupied(const int3 &tile, ETileType::ETileType state)
|
||||||
@ -650,7 +650,7 @@ void CMapGenerator::setRoad(const int3& tile, ERoadType::ERoadType roadType)
|
|||||||
{
|
{
|
||||||
checkIsOnMap(tile);
|
checkIsOnMap(tile);
|
||||||
|
|
||||||
tiles[tile.x][tile.y][tile.z].setRoadType(roadType);
|
tiles[tile.x][tile.y][tile.z].setRoadType(roadType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ public:
|
|||||||
~CMapGenerator(); // required due to std::unique_ptr
|
~CMapGenerator(); // required due to std::unique_ptr
|
||||||
|
|
||||||
std::unique_ptr<CMap> generate(CMapGenOptions * mapGenOptions, int RandomSeed = std::time(nullptr));
|
std::unique_ptr<CMap> generate(CMapGenOptions * mapGenOptions, int RandomSeed = std::time(nullptr));
|
||||||
|
|
||||||
CMapGenOptions * mapGenOptions;
|
CMapGenOptions * mapGenOptions;
|
||||||
std::unique_ptr<CMap> map;
|
std::unique_ptr<CMap> map;
|
||||||
CRandomGenerator rand;
|
CRandomGenerator rand;
|
||||||
@ -74,14 +74,14 @@ public:
|
|||||||
bool isFree(const int3 &tile) const;
|
bool isFree(const int3 &tile) const;
|
||||||
bool isUsed(const int3 &tile) const;
|
bool isUsed(const int3 &tile) const;
|
||||||
bool isRoad(const int3 &tile) const;
|
bool isRoad(const int3 &tile) const;
|
||||||
|
|
||||||
void setOccupied(const int3 &tile, ETileType::ETileType state);
|
void setOccupied(const int3 &tile, ETileType::ETileType state);
|
||||||
void setRoad(const int3 &tile, ERoadType::ERoadType roadType);
|
void setRoad(const int3 &tile, ERoadType::ERoadType roadType);
|
||||||
|
|
||||||
CTileInfo getTile(const int3 & tile) const;
|
CTileInfo getTile(const int3 & tile) const;
|
||||||
bool isAllowedSpell(SpellID sid) const;
|
bool isAllowedSpell(SpellID sid) const;
|
||||||
|
|
||||||
float getNearestObjectDistance(const int3 &tile) const;
|
float getNearestObjectDistance(const int3 &tile) const;
|
||||||
void setNearestObjectDistance(int3 &tile, float value);
|
void setNearestObjectDistance(int3 &tile, float value);
|
||||||
|
|
||||||
int getNextMonlithIndex();
|
int getNextMonlithIndex();
|
||||||
|
@ -196,7 +196,7 @@ void CRmgTemplateStorage::loadObject(std::string scope, std::string name, const
|
|||||||
{
|
{
|
||||||
zone->setMinesAmount (mineInfo.first, mineInfo.second);
|
zone->setMinesAmount (mineInfo.first, mineInfo.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -239,8 +239,8 @@ CRmgTemplate::CSize CRmgTemplateStorage::parseMapTemplateSize(const std::string
|
|||||||
|
|
||||||
std::vector<std::string> parts;
|
std::vector<std::string> parts;
|
||||||
boost::split(parts, text, boost::is_any_of("+"));
|
boost::split(parts, text, boost::is_any_of("+"));
|
||||||
static const std::map<std::string, int> mapSizeMapping =
|
static const std::map<std::string, int> mapSizeMapping =
|
||||||
{
|
{
|
||||||
{"s", CMapHeader::MAP_SIZE_SMALL},
|
{"s", CMapHeader::MAP_SIZE_SMALL},
|
||||||
{"m", CMapHeader::MAP_SIZE_MIDDLE},
|
{"m", CMapHeader::MAP_SIZE_MIDDLE},
|
||||||
{"l", CMapHeader::MAP_SIZE_LARGE},
|
{"l", CMapHeader::MAP_SIZE_LARGE},
|
||||||
@ -269,12 +269,12 @@ CRmgTemplate::CSize CRmgTemplateStorage::parseMapTemplateSize(const std::string
|
|||||||
|
|
||||||
ETemplateZoneType::ETemplateZoneType CRmgTemplateStorage::parseZoneType(const std::string & type) const
|
ETemplateZoneType::ETemplateZoneType CRmgTemplateStorage::parseZoneType(const std::string & type) const
|
||||||
{
|
{
|
||||||
static const std::map<std::string, ETemplateZoneType::ETemplateZoneType> zoneTypeMapping =
|
static const std::map<std::string, ETemplateZoneType::ETemplateZoneType> zoneTypeMapping =
|
||||||
{
|
{
|
||||||
{"playerStart", ETemplateZoneType::PLAYER_START},
|
{"playerStart", ETemplateZoneType::PLAYER_START},
|
||||||
{"cpuStart", ETemplateZoneType::CPU_START},
|
{"cpuStart", ETemplateZoneType::CPU_START},
|
||||||
{"treasure", ETemplateZoneType::TREASURE},
|
{"treasure", ETemplateZoneType::TREASURE},
|
||||||
{"junction", ETemplateZoneType::JUNCTION},
|
{"junction", ETemplateZoneType::JUNCTION},
|
||||||
};
|
};
|
||||||
auto it = zoneTypeMapping.find(type);
|
auto it = zoneTypeMapping.find(type);
|
||||||
if(it == zoneTypeMapping.end()) throw std::runtime_error("Zone type unknown.");
|
if(it == zoneTypeMapping.end()) throw std::runtime_error("Zone type unknown.");
|
||||||
|
@ -86,7 +86,7 @@ void CRmgTemplateZone::CTownInfo::setCastleDensity(int value)
|
|||||||
castleDensity = value;
|
castleDensity = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
CTileInfo::CTileInfo():nearestObjectDistance(INT_MAX), terrain(ETerrainType::WRONG),roadType(ERoadType::NO_ROAD)
|
CTileInfo::CTileInfo():nearestObjectDistance(INT_MAX), terrain(ETerrainType::WRONG),roadType(ERoadType::NO_ROAD)
|
||||||
{
|
{
|
||||||
occupied = ETileType::POSSIBLE; //all tiles are initially possible to place objects or passages
|
occupied = ETileType::POSSIBLE; //all tiles are initially possible to place objects or passages
|
||||||
}
|
}
|
||||||
@ -638,7 +638,7 @@ do not leave zone border
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto lastDistance = distance;
|
auto lastDistance = distance;
|
||||||
|
|
||||||
auto processNeighbours = [this, gen, ¤tPos, dst, &distance, &result, &end, clearedTiles](int3 &pos)
|
auto processNeighbours = [this, gen, ¤tPos, dst, &distance, &result, &end, clearedTiles](int3 &pos)
|
||||||
{
|
{
|
||||||
if (!result) //not sure if lambda is worth it...
|
if (!result) //not sure if lambda is worth it...
|
||||||
@ -672,19 +672,19 @@ do not leave zone border
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (onlyStraight)
|
if (onlyStraight)
|
||||||
gen->foreachDirectNeighbour (currentPos, processNeighbours);
|
gen->foreachDirectNeighbour (currentPos, processNeighbours);
|
||||||
else
|
else
|
||||||
gen->foreach_neighbour (currentPos,processNeighbours);
|
gen->foreach_neighbour (currentPos,processNeighbours);
|
||||||
|
|
||||||
int3 anotherPos(-1, -1, -1);
|
int3 anotherPos(-1, -1, -1);
|
||||||
|
|
||||||
if (!(result || distance < lastDistance)) //we do not advance, use more advanced pathfinding algorithm?
|
if (!(result || distance < lastDistance)) //we do not advance, use more advanced pathfinding algorithm?
|
||||||
{
|
{
|
||||||
//try any nearby tiles, even if its not closer than current
|
//try any nearby tiles, even if its not closer than current
|
||||||
float lastDistance = 2 * distance; //start with significantly larger value
|
float lastDistance = 2 * distance; //start with significantly larger value
|
||||||
|
|
||||||
auto processNeighbours2 = [this, gen, ¤tPos, dst, &lastDistance, &anotherPos, &end, clearedTiles](int3 &pos)
|
auto processNeighbours2 = [this, gen, ¤tPos, dst, &lastDistance, &anotherPos, &end, clearedTiles](int3 &pos)
|
||||||
{
|
{
|
||||||
if (currentPos.dist2dSQ(dst) < lastDistance) //try closest tiles from all surrounding unused tiles
|
if (currentPos.dist2dSQ(dst) < lastDistance) //try closest tiles from all surrounding unused tiles
|
||||||
@ -700,13 +700,13 @@ do not leave zone border
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (onlyStraight)
|
if (onlyStraight)
|
||||||
gen->foreachDirectNeighbour(currentPos, processNeighbours2);
|
gen->foreachDirectNeighbour(currentPos, processNeighbours2);
|
||||||
else
|
else
|
||||||
gen->foreach_neighbour(currentPos, processNeighbours2);
|
gen->foreach_neighbour(currentPos, processNeighbours2);
|
||||||
|
|
||||||
|
|
||||||
if (anotherPos.valid())
|
if (anotherPos.valid())
|
||||||
{
|
{
|
||||||
if (clearedTiles)
|
if (clearedTiles)
|
||||||
@ -878,7 +878,7 @@ bool CRmgTemplateZone::connectPath(CMapGenerator* gen, const int3& src, bool onl
|
|||||||
|
|
||||||
if (onlyStraight)
|
if (onlyStraight)
|
||||||
gen->foreachDirectNeighbour(currentNode, foo);
|
gen->foreachDirectNeighbour(currentNode, foo);
|
||||||
else
|
else
|
||||||
gen->foreach_neighbour(currentNode, foo);
|
gen->foreach_neighbour(currentNode, foo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -997,8 +997,8 @@ bool CRmgTemplateZone::addMonster(CMapGenerator* gen, int3 &pos, si32 strength,
|
|||||||
static const float multiplier1[] = {0.5, 0.75, 1.0, 1.5, 1.5};
|
static const float multiplier1[] = {0.5, 0.75, 1.0, 1.5, 1.5};
|
||||||
static const float multiplier2[] = {0.5, 0.75, 1.0, 1.0, 1.5};
|
static const float multiplier2[] = {0.5, 0.75, 1.0, 1.0, 1.5};
|
||||||
|
|
||||||
int strength1 = std::max(0.f, (strength - value1[monsterStrength]) * multiplier1[monsterStrength]);
|
int strength1 = std::max(0.f, (strength - value1[monsterStrength]) * multiplier1[monsterStrength]);
|
||||||
int strength2 = std::max(0.f, (strength - value2[monsterStrength]) * multiplier2[monsterStrength]);
|
int strength2 = std::max(0.f, (strength - value2[monsterStrength]) * multiplier2[monsterStrength]);
|
||||||
|
|
||||||
strength = strength1 + strength2;
|
strength = strength1 + strength2;
|
||||||
if (strength < 2000)
|
if (strength < 2000)
|
||||||
@ -1132,7 +1132,7 @@ bool CRmgTemplateZone::createTreasurePile(CMapGenerator* gen, int3 &pos, float m
|
|||||||
info.occupiedPositions.insert(visitablePos + oi.templ.getVisitableOffset());
|
info.occupiedPositions.insert(visitablePos + oi.templ.getVisitableOffset());
|
||||||
|
|
||||||
currentValue += oi.value;
|
currentValue += oi.value;
|
||||||
|
|
||||||
treasures[info.nextTreasurePos] = object;
|
treasures[info.nextTreasurePos] = object;
|
||||||
|
|
||||||
//now find place for next object
|
//now find place for next object
|
||||||
@ -1337,7 +1337,7 @@ void CRmgTemplateZone::initTownType (CMapGenerator* gen)
|
|||||||
town->possibleSpells.push_back(spell->id);
|
town->possibleSpells.push_back(spell->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!totalTowns)
|
if (!totalTowns)
|
||||||
{
|
{
|
||||||
//first town in zone sets the facton of entire zone
|
//first town in zone sets the facton of entire zone
|
||||||
town->subID = townType;
|
town->subID = townType;
|
||||||
@ -1540,7 +1540,7 @@ bool CRmgTemplateZone::placeMines (CMapGenerator* gen)
|
|||||||
bool CRmgTemplateZone::createRequiredObjects(CMapGenerator* gen)
|
bool CRmgTemplateZone::createRequiredObjects(CMapGenerator* gen)
|
||||||
{
|
{
|
||||||
logGlobal->traceStream() << "Creating required objects";
|
logGlobal->traceStream() << "Creating required objects";
|
||||||
|
|
||||||
for(const auto &object : requiredObjects)
|
for(const auto &object : requiredObjects)
|
||||||
{
|
{
|
||||||
auto obj = object.first;
|
auto obj = object.first;
|
||||||
@ -1577,16 +1577,16 @@ bool CRmgTemplateZone::createRequiredObjects(CMapGenerator* gen)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
placeObject(gen, obj, pos);
|
placeObject(gen, obj, pos);
|
||||||
guardObject (gen, obj, object.second, (obj->ID == Obj::MONOLITH_TWO_WAY), true);
|
guardObject (gen, obj, object.second, (obj->ID == Obj::MONOLITH_TWO_WAY), true);
|
||||||
//paths to required objects constitute main paths of zone. otherwise they just may lead to middle and create dead zones
|
//paths to required objects constitute main paths of zone. otherwise they just may lead to middle and create dead zones
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &obj : closeObjects)
|
for (const auto &obj : closeObjects)
|
||||||
{
|
{
|
||||||
std::vector<int3> tiles(possibleTiles.begin(), possibleTiles.end()); //new tiles vector after each object has been placed
|
std::vector<int3> tiles(possibleTiles.begin(), possibleTiles.end()); //new tiles vector after each object has been placed
|
||||||
|
|
||||||
// smallest distance to zone center, greatest distance to nearest object
|
// smallest distance to zone center, greatest distance to nearest object
|
||||||
auto isCloser = [this, gen](const int3 & lhs, const int3 & rhs) -> bool
|
auto isCloser = [this, gen](const int3 & lhs, const int3 & rhs) -> bool
|
||||||
{
|
{
|
||||||
@ -1675,7 +1675,7 @@ void CRmgTemplateZone::createTreasures(CMapGenerator* gen)
|
|||||||
return !gen->isPossible(tile);
|
return !gen->isPossible(tile);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
int3 treasureTilePos;
|
int3 treasureTilePos;
|
||||||
//If we are able to place at least one object with value lower than minGuardedValue, it's ok
|
//If we are able to place at least one object with value lower than minGuardedValue, it's ok
|
||||||
do
|
do
|
||||||
@ -1722,11 +1722,11 @@ void CRmgTemplateZone::createObstacles2(CMapGenerator* gen)
|
|||||||
std::vector<obstaclePair> possibleObstacles;
|
std::vector<obstaclePair> possibleObstacles;
|
||||||
|
|
||||||
//get all possible obstacles for this terrain
|
//get all possible obstacles for this terrain
|
||||||
for (auto primaryID : VLC->objtypeh->knownObjects())
|
for (auto primaryID : VLC->objtypeh->knownObjects())
|
||||||
{
|
{
|
||||||
for (auto secondaryID : VLC->objtypeh->knownSubObjects(primaryID))
|
for (auto secondaryID : VLC->objtypeh->knownSubObjects(primaryID))
|
||||||
{
|
{
|
||||||
auto handler = VLC->objtypeh->getHandlerFor(primaryID, secondaryID);
|
auto handler = VLC->objtypeh->getHandlerFor(primaryID, secondaryID);
|
||||||
if (handler->isStaticObject())
|
if (handler->isStaticObject())
|
||||||
{
|
{
|
||||||
for (auto temp : handler->getTemplates())
|
for (auto temp : handler->getTemplates())
|
||||||
@ -1735,7 +1735,7 @@ void CRmgTemplateZone::createObstacles2(CMapGenerator* gen)
|
|||||||
obstaclesBySize[temp.getBlockedOffsets().size()].push_back(temp);
|
obstaclesBySize[temp.getBlockedOffsets().size()].push_back(temp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto o : obstaclesBySize)
|
for (auto o : obstaclesBySize)
|
||||||
{
|
{
|
||||||
@ -1789,13 +1789,13 @@ void CRmgTemplateZone::createObstacles2(CMapGenerator* gen)
|
|||||||
void CRmgTemplateZone::connectRoads(CMapGenerator* gen)
|
void CRmgTemplateZone::connectRoads(CMapGenerator* gen)
|
||||||
{
|
{
|
||||||
logGlobal->debug("Started building roads");
|
logGlobal->debug("Started building roads");
|
||||||
|
|
||||||
std::set<int3> roadNodesCopy(roadNodes);
|
std::set<int3> roadNodesCopy(roadNodes);
|
||||||
std::set<int3> processed;
|
std::set<int3> processed;
|
||||||
|
|
||||||
while(!roadNodesCopy.empty())
|
while(!roadNodesCopy.empty())
|
||||||
{
|
{
|
||||||
int3 node = *roadNodesCopy.begin();
|
int3 node = *roadNodesCopy.begin();
|
||||||
roadNodesCopy.erase(node);
|
roadNodesCopy.erase(node);
|
||||||
int3 cross(-1, -1, -1);
|
int3 cross(-1, -1, -1);
|
||||||
|
|
||||||
@ -1818,13 +1818,13 @@ void CRmgTemplateZone::connectRoads(CMapGenerator* gen)
|
|||||||
processed.insert(cross); //don't draw road starting at end point which is already connected
|
processed.insert(cross); //don't draw road starting at end point which is already connected
|
||||||
vstd::erase_if_present(roadNodesCopy, cross);
|
vstd::erase_if_present(roadNodesCopy, cross);
|
||||||
}
|
}
|
||||||
|
|
||||||
processed.insert(node);
|
processed.insert(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
drawRoads(gen);
|
drawRoads(gen);
|
||||||
|
|
||||||
logGlobal->debug("Finished building roads");
|
logGlobal->debug("Finished building roads");
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRmgTemplateZone::drawRoads(CMapGenerator* gen)
|
void CRmgTemplateZone::drawRoads(CMapGenerator* gen)
|
||||||
@ -1832,7 +1832,7 @@ void CRmgTemplateZone::drawRoads(CMapGenerator* gen)
|
|||||||
std::vector<int3> tiles;
|
std::vector<int3> tiles;
|
||||||
for (auto tile : roads)
|
for (auto tile : roads)
|
||||||
{
|
{
|
||||||
if(gen->map->isInTheMap(tile))
|
if(gen->map->isInTheMap(tile))
|
||||||
tiles.push_back (tile);
|
tiles.push_back (tile);
|
||||||
}
|
}
|
||||||
for (auto tile : roadNodes)
|
for (auto tile : roadNodes)
|
||||||
@ -1841,8 +1841,8 @@ void CRmgTemplateZone::drawRoads(CMapGenerator* gen)
|
|||||||
tiles.push_back(tile);
|
tiles.push_back(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
gen->editManager->getTerrainSelection().setSelection(tiles);
|
gen->editManager->getTerrainSelection().setSelection(tiles);
|
||||||
gen->editManager->drawRoad(ERoadType::COBBLESTONE_ROAD, &gen->rand);
|
gen->editManager->drawRoad(ERoadType::COBBLESTONE_ROAD, &gen->rand);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1852,7 +1852,7 @@ bool CRmgTemplateZone::fill(CMapGenerator* gen)
|
|||||||
|
|
||||||
//zone center should be always clear to allow other tiles to connect
|
//zone center should be always clear to allow other tiles to connect
|
||||||
gen->setOccupied(this->getPos(), ETileType::FREE);
|
gen->setOccupied(this->getPos(), ETileType::FREE);
|
||||||
freePaths.insert(pos);
|
freePaths.insert(pos);
|
||||||
|
|
||||||
addAllPossibleObjects (gen);
|
addAllPossibleObjects (gen);
|
||||||
|
|
||||||
@ -1861,7 +1861,7 @@ bool CRmgTemplateZone::fill(CMapGenerator* gen)
|
|||||||
placeMines(gen);
|
placeMines(gen);
|
||||||
createRequiredObjects(gen);
|
createRequiredObjects(gen);
|
||||||
createTreasures(gen);
|
createTreasures(gen);
|
||||||
|
|
||||||
logGlobal->infoStream() << boost::format ("Zone %d filled successfully") %id;
|
logGlobal->infoStream() << boost::format ("Zone %d filled successfully") %id;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -2040,7 +2040,7 @@ void CRmgTemplateZone::checkAndPlaceObject(CMapGenerator* gen, CGObjectInstance*
|
|||||||
auto templates = VLC->objtypeh->getHandlerFor(object->ID, object->subID)->getTemplates(terrainType);
|
auto templates = VLC->objtypeh->getHandlerFor(object->ID, object->subID)->getTemplates(terrainType);
|
||||||
if (templates.empty())
|
if (templates.empty())
|
||||||
throw rmgException(boost::to_string(boost::format("Did not find graphics for object (%d,%d) at %s (terrain %d)") %object->ID %object->subID %pos %terrainType));
|
throw rmgException(boost::to_string(boost::format("Did not find graphics for object (%d,%d) at %s (terrain %d)") %object->ID %object->subID %pos %terrainType));
|
||||||
|
|
||||||
object->appearance = templates.front();
|
object->appearance = templates.front();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2059,7 +2059,7 @@ void CRmgTemplateZone::placeObject(CMapGenerator* gen, CGObjectInstance* object,
|
|||||||
points.insert(pos + object->getVisitableOffset());
|
points.insert(pos + object->getVisitableOffset());
|
||||||
points.insert(pos);
|
points.insert(pos);
|
||||||
for(auto p : points)
|
for(auto p : points)
|
||||||
{
|
{
|
||||||
if (gen->map->isInTheMap(p))
|
if (gen->map->isInTheMap(p))
|
||||||
{
|
{
|
||||||
gen->setOccupied(p, ETileType::USED);
|
gen->setOccupied(p, ETileType::USED);
|
||||||
@ -2068,12 +2068,12 @@ void CRmgTemplateZone::placeObject(CMapGenerator* gen, CGObjectInstance* object,
|
|||||||
if (updateDistance)
|
if (updateDistance)
|
||||||
{
|
{
|
||||||
for(auto tile : possibleTiles) //don't need to mark distance for not possible tiles
|
for(auto tile : possibleTiles) //don't need to mark distance for not possible tiles
|
||||||
{
|
{
|
||||||
si32 d = pos.dist2dSQ(tile); //optimization, only relative distance is interesting
|
si32 d = pos.dist2dSQ(tile); //optimization, only relative distance is interesting
|
||||||
gen->setNearestObjectDistance(tile, std::min<float>(d, gen->getNearestObjectDistance(tile)));
|
gen->setNearestObjectDistance(tile, std::min<float>(d, gen->getNearestObjectDistance(tile)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (object->ID)
|
switch (object->ID)
|
||||||
{
|
{
|
||||||
case Obj::TOWN:
|
case Obj::TOWN:
|
||||||
@ -2086,10 +2086,10 @@ void CRmgTemplateZone::placeObject(CMapGenerator* gen, CGObjectInstance* object,
|
|||||||
addRoadNode(object->visitablePos());
|
addRoadNode(object->visitablePos());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CRmgTemplateZone::placeAndGuardObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos, si32 str, bool zoneGuard)
|
void CRmgTemplateZone::placeAndGuardObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos, si32 str, bool zoneGuard)
|
||||||
@ -2116,7 +2116,7 @@ std::vector<int3> CRmgTemplateZone::getAccessibleOffsets (CMapGenerator* gen, CG
|
|||||||
|
|
||||||
auto tilesBlockedByObject = object->getBlockedPos(); //absolue value, as object is already placed
|
auto tilesBlockedByObject = object->getBlockedPos(); //absolue value, as object is already placed
|
||||||
|
|
||||||
gen->foreach_neighbour(visitable, [&](int3& pos)
|
gen->foreach_neighbour(visitable, [&](int3& pos)
|
||||||
{
|
{
|
||||||
if (gen->isPossible(pos) || gen->isFree(pos))
|
if (gen->isPossible(pos) || gen->isFree(pos))
|
||||||
{
|
{
|
||||||
@ -2159,7 +2159,7 @@ bool CRmgTemplateZone::guardObject(CMapGenerator* gen, CGObjectInstance* object,
|
|||||||
if (!gen->isFree(pos))
|
if (!gen->isFree(pos))
|
||||||
gen->setOccupied(pos, ETileType::BLOCKED);
|
gen->setOccupied(pos, ETileType::BLOCKED);
|
||||||
}
|
}
|
||||||
gen->foreach_neighbour (guardTile, [&](int3& pos)
|
gen->foreach_neighbour (guardTile, [&](int3& pos)
|
||||||
{
|
{
|
||||||
if (gen->isPossible(pos))
|
if (gen->isPossible(pos))
|
||||||
gen->setOccupied (pos, ETileType::FREE);
|
gen->setOccupied (pos, ETileType::FREE);
|
||||||
|
@ -47,12 +47,12 @@ public:
|
|||||||
bool isPossible() const;
|
bool isPossible() const;
|
||||||
bool isFree() const;
|
bool isFree() const;
|
||||||
bool isUsed() const;
|
bool isUsed() const;
|
||||||
bool isRoad() const;
|
bool isRoad() const;
|
||||||
void setOccupied(ETileType::ETileType value);
|
void setOccupied(ETileType::ETileType value);
|
||||||
ETerrainType getTerrainType() const;
|
ETerrainType getTerrainType() const;
|
||||||
ETileType::ETileType getTileType() const;
|
ETileType::ETileType getTileType() const;
|
||||||
void setTerrainType(ETerrainType value);
|
void setTerrainType(ETerrainType value);
|
||||||
|
|
||||||
void setRoadType(ERoadType::ERoadType value);
|
void setRoadType(ERoadType::ERoadType value);
|
||||||
private:
|
private:
|
||||||
float nearestObjectDistance;
|
float nearestObjectDistance;
|
||||||
@ -175,7 +175,7 @@ public:
|
|||||||
bool crunchPath(CMapGenerator* gen, const int3 &src, const int3 &dst, bool onlyStraight, std::set<int3>* clearedTiles = nullptr);
|
bool crunchPath(CMapGenerator* gen, const int3 &src, const int3 &dst, bool onlyStraight, std::set<int3>* clearedTiles = nullptr);
|
||||||
bool connectPath(CMapGenerator* gen, const int3& src, bool onlyStraight);
|
bool connectPath(CMapGenerator* gen, const int3& src, bool onlyStraight);
|
||||||
bool connectWithCenter(CMapGenerator* gen, const int3& src, bool onlyStraight);
|
bool connectWithCenter(CMapGenerator* gen, const int3& src, bool onlyStraight);
|
||||||
|
|
||||||
std::vector<int3> getAccessibleOffsets (CMapGenerator* gen, CGObjectInstance* object);
|
std::vector<int3> getAccessibleOffsets (CMapGenerator* gen, CGObjectInstance* object);
|
||||||
|
|
||||||
void addConnection(TRmgTemplateZoneId otherZone);
|
void addConnection(TRmgTemplateZoneId otherZone);
|
||||||
@ -229,11 +229,11 @@ private:
|
|||||||
std::set<int3> possibleTiles; //optimization purposes for treasure generation
|
std::set<int3> possibleTiles; //optimization purposes for treasure generation
|
||||||
std::vector<TRmgTemplateZoneId> connections; //list of adjacent zones
|
std::vector<TRmgTemplateZoneId> connections; //list of adjacent zones
|
||||||
std::set<int3> freePaths; //core paths of free tiles that all other objects will be linked to
|
std::set<int3> freePaths; //core paths of free tiles that all other objects will be linked to
|
||||||
|
|
||||||
std::set<int3> roadNodes; //tiles to be connected with roads
|
std::set<int3> roadNodes; //tiles to be connected with roads
|
||||||
std::set<int3> roads; //all tiles with roads
|
std::set<int3> roads; //all tiles with roads
|
||||||
std::set<int3> tilesToConnectLater; //will be connected after paths are fractalized
|
std::set<int3> tilesToConnectLater; //will be connected after paths are fractalized
|
||||||
|
|
||||||
bool createRoad(CMapGenerator* gen, const int3 &src, const int3 &dst);
|
bool createRoad(CMapGenerator* gen, const int3 &src, const int3 &dst);
|
||||||
void drawRoads(CMapGenerator * gen); //actually updates tiles
|
void drawRoads(CMapGenerator * gen); //actually updates tiles
|
||||||
|
|
||||||
|
@ -206,9 +206,9 @@ ESpellCastResult TownPortalMechanics::applyAdventureEffects(const SpellCastEnvir
|
|||||||
}
|
}
|
||||||
|
|
||||||
CGTownInstance * town = static_cast<CGTownInstance*>(tile.visitableObjects.back());
|
CGTownInstance * town = static_cast<CGTownInstance*>(tile.visitableObjects.back());
|
||||||
|
|
||||||
const auto relations = env->getCb()->getPlayerRelations(town->tempOwner, parameters.caster->tempOwner);
|
const auto relations = env->getCb()->getPlayerRelations(town->tempOwner, parameters.caster->tempOwner);
|
||||||
|
|
||||||
if(relations == PlayerRelations::ENEMIES)
|
if(relations == PlayerRelations::ENEMIES)
|
||||||
{
|
{
|
||||||
env->complain("Can't teleport to enemy!");
|
env->complain("Can't teleport to enemy!");
|
||||||
@ -241,21 +241,21 @@ ESpellCastResult TownPortalMechanics::applyAdventureEffects(const SpellCastEnvir
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const int movementCost = GameConstants::BASE_MOVEMENT_COST * ((parameters.caster->getSpellSchoolLevel(owner) >= 3) ? 2 : 3);
|
const int movementCost = GameConstants::BASE_MOVEMENT_COST * ((parameters.caster->getSpellSchoolLevel(owner) >= 3) ? 2 : 3);
|
||||||
|
|
||||||
if(parameters.caster->movement < movementCost)
|
if(parameters.caster->movement < movementCost)
|
||||||
{
|
{
|
||||||
env->complain("This hero has not enough movement points!");
|
env->complain("This hero has not enough movement points!");
|
||||||
return ESpellCastResult::ERROR;
|
return ESpellCastResult::ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(env->moveHero(parameters.caster->id, town->visitablePos() + parameters.caster->getVisitableOffset() ,1))
|
if(env->moveHero(parameters.caster->id, town->visitablePos() + parameters.caster->getVisitableOffset() ,1))
|
||||||
{
|
{
|
||||||
SetMovePoints smp;
|
SetMovePoints smp;
|
||||||
smp.hid = parameters.caster->id;
|
smp.hid = parameters.caster->id;
|
||||||
smp.val = std::max<ui32>(0, parameters.caster->movement - movementCost);
|
smp.val = std::max<ui32>(0, parameters.caster->movement - movementCost);
|
||||||
env->sendAndApply(&smp);
|
env->sendAndApply(&smp);
|
||||||
}
|
}
|
||||||
return ESpellCastResult::OK;
|
return ESpellCastResult::OK;
|
||||||
}
|
}
|
||||||
@ -271,7 +271,7 @@ ESpellCastResult ViewMechanics::applyAdventureEffects(const SpellCastEnvironment
|
|||||||
for(const CGObjectInstance * obj : env->getMap()->objects)
|
for(const CGObjectInstance * obj : env->getMap()->objects)
|
||||||
{
|
{
|
||||||
//todo:we need to send only not visible objects
|
//todo:we need to send only not visible objects
|
||||||
|
|
||||||
if(obj)//for some reason deleted object remain as empty pointer
|
if(obj)//for some reason deleted object remain as empty pointer
|
||||||
if(filterObject(obj, spellLevel))
|
if(filterObject(obj, spellLevel))
|
||||||
pack.objectPositions.push_back(ObjectPosInfo(obj));
|
pack.objectPositions.push_back(ObjectPosInfo(obj));
|
||||||
|
@ -29,7 +29,7 @@ void HealingSpellMechanics::applyBattleEffects(const SpellCastEnvironment * env,
|
|||||||
for(auto & attackedCre : ctx.attackedCres)
|
for(auto & attackedCre : ctx.attackedCres)
|
||||||
{
|
{
|
||||||
StacksHealedOrResurrected::HealInfo hi;
|
StacksHealedOrResurrected::HealInfo hi;
|
||||||
hi.stackID = (attackedCre)->ID;
|
hi.stackID = (attackedCre)->ID;
|
||||||
int stackHPgained = parameters.caster->getSpellBonus(owner, hpGained, attackedCre);
|
int stackHPgained = parameters.caster->getSpellBonus(owner, hpGained, attackedCre);
|
||||||
hi.healedHP = attackedCre->calculateHealedHealthPoints(stackHPgained, resurrect);
|
hi.healedHP = attackedCre->calculateHealedHealthPoints(stackHPgained, resurrect);
|
||||||
hi.lowLevelResurrection = (healLevel == EHealLevel::RESURRECT);
|
hi.lowLevelResurrection = (healLevel == EHealLevel::RESURRECT);
|
||||||
@ -54,11 +54,11 @@ void AntimagicMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast
|
|||||||
doDispell(battle, packet, [this](const Bonus * b) -> bool
|
doDispell(battle, packet, [this](const Bonus * b) -> bool
|
||||||
{
|
{
|
||||||
if(b->source == Bonus::SPELL_EFFECT)
|
if(b->source == Bonus::SPELL_EFFECT)
|
||||||
{
|
{
|
||||||
return b->sid != owner->id; //effect from this spell
|
return b->sid != owner->id; //effect from this spell
|
||||||
}
|
}
|
||||||
return false; //not a spell effect
|
return false; //not a spell effect
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
///ChainLightningMechanics
|
///ChainLightningMechanics
|
||||||
@ -125,12 +125,12 @@ void CloneMechanics::applyBattleEffects(const SpellCastEnvironment * env, const
|
|||||||
ssp.val = 0;
|
ssp.val = 0;
|
||||||
ssp.absolute = 1;
|
ssp.absolute = 1;
|
||||||
env->sendAndApply(&ssp);
|
env->sendAndApply(&ssp);
|
||||||
|
|
||||||
ssp.stackID = clonedStack->ID;
|
ssp.stackID = clonedStack->ID;
|
||||||
ssp.which = BattleSetStackProperty::HAS_CLONE;
|
ssp.which = BattleSetStackProperty::HAS_CLONE;
|
||||||
ssp.val = bsa.newStackID;
|
ssp.val = bsa.newStackID;
|
||||||
ssp.absolute = 1;
|
ssp.absolute = 1;
|
||||||
env->sendAndApply(&ssp);
|
env->sendAndApply(&ssp);
|
||||||
}
|
}
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem CloneMechanics::isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const
|
ESpellCastProblem::ESpellCastProblem CloneMechanics::isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const
|
||||||
@ -172,7 +172,7 @@ void CureMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * pac
|
|||||||
CSpell * sp = SpellID(b->sid).toSpell();
|
CSpell * sp = SpellID(b->sid).toSpell();
|
||||||
return sp->isNegative();
|
return sp->isNegative();
|
||||||
}
|
}
|
||||||
return false; //not a spell effect
|
return false; //not a spell effect
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,9 +193,9 @@ ESpellCastProblem::ESpellCastProblem DispellMechanics::isImmuneByStack(const ISp
|
|||||||
{
|
{
|
||||||
//just in case
|
//just in case
|
||||||
if(!obj->alive())
|
if(!obj->alive())
|
||||||
return ESpellCastProblem::WRONG_SPELL_TARGET;
|
return ESpellCastProblem::WRONG_SPELL_TARGET;
|
||||||
}
|
}
|
||||||
//DISPELL ignores all immunities, except specific absolute immunity
|
//DISPELL ignores all immunities, except specific absolute immunity
|
||||||
{
|
{
|
||||||
//SPELL_IMMUNITY absolute case
|
//SPELL_IMMUNITY absolute case
|
||||||
std::stringstream cachingStr;
|
std::stringstream cachingStr;
|
||||||
@ -210,7 +210,7 @@ ESpellCastProblem::ESpellCastProblem DispellMechanics::isImmuneByStack(const ISp
|
|||||||
if(obj->hasBonus(Selector::sourceType(Bonus::SPELL_EFFECT), cachingStr.str()))
|
if(obj->hasBonus(Selector::sourceType(Bonus::SPELL_EFFECT), cachingStr.str()))
|
||||||
{
|
{
|
||||||
return ESpellCastProblem::OK;
|
return ESpellCastProblem::OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ESpellCastProblem::WRONG_SPELL_TARGET;
|
return ESpellCastProblem::WRONG_SPELL_TARGET;
|
||||||
//any other immunities are ignored - do not execute default algorithm
|
//any other immunities are ignored - do not execute default algorithm
|
||||||
@ -337,7 +337,7 @@ ESpellCastProblem::ESpellCastProblem EarthquakeMechanics::canBeCast(const CBattl
|
|||||||
{
|
{
|
||||||
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
return ESpellCastProblem::NO_APPROPRIATE_TARGET;
|
||||||
}
|
}
|
||||||
|
|
||||||
CSpell::TargetInfo ti(owner, 0);//TODO: use real spell level
|
CSpell::TargetInfo ti(owner, 0);//TODO: use real spell level
|
||||||
if(ti.smart)
|
if(ti.smart)
|
||||||
{
|
{
|
||||||
@ -353,7 +353,7 @@ ESpellCastProblem::ESpellCastProblem EarthquakeMechanics::canBeCast(const CBattl
|
|||||||
ESpellCastProblem::ESpellCastProblem HypnotizeMechanics::isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const
|
ESpellCastProblem::ESpellCastProblem HypnotizeMechanics::isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const
|
||||||
{
|
{
|
||||||
//todo: maybe do not resist on passive cast
|
//todo: maybe do not resist on passive cast
|
||||||
if(nullptr != caster)
|
if(nullptr != caster)
|
||||||
{
|
{
|
||||||
//TODO: what with other creatures casting hypnotize, Faerie Dragons style?
|
//TODO: what with other creatures casting hypnotize, Faerie Dragons style?
|
||||||
ui64 subjectHealth = (obj->count - 1) * obj->MaxHealth() + obj->firstHPleft;
|
ui64 subjectHealth = (obj->count - 1) * obj->MaxHealth() + obj->firstHPleft;
|
||||||
@ -521,7 +521,7 @@ HealingSpellMechanics::EHealLevel RisingSpellMechanics::getHealLevel(int effectL
|
|||||||
//this may be even distinct class
|
//this may be even distinct class
|
||||||
if((effectLevel <= 1) && (owner->id == SpellID::RESURRECTION))
|
if((effectLevel <= 1) && (owner->id == SpellID::RESURRECTION))
|
||||||
return EHealLevel::RESURRECT;
|
return EHealLevel::RESURRECT;
|
||||||
|
|
||||||
return EHealLevel::TRUE_RESURRECT;
|
return EHealLevel::TRUE_RESURRECT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -532,9 +532,9 @@ ESpellCastProblem::ESpellCastProblem SacrificeMechanics::canBeCast(const CBattle
|
|||||||
|
|
||||||
bool targetExists = false;
|
bool targetExists = false;
|
||||||
bool targetToSacrificeExists = false;
|
bool targetToSacrificeExists = false;
|
||||||
|
|
||||||
const CGHeroInstance * caster = nullptr; //todo: use ISpellCaster
|
const CGHeroInstance * caster = nullptr; //todo: use ISpellCaster
|
||||||
|
|
||||||
if(cb->battleHasHero(cb->playerToSide(player)))
|
if(cb->battleHasHero(cb->playerToSide(player)))
|
||||||
caster = cb->battleGetFightingHero(cb->playerToSide(player));
|
caster = cb->battleGetFightingHero(cb->playerToSide(player));
|
||||||
|
|
||||||
@ -624,7 +624,7 @@ ESpellCastProblem::ESpellCastProblem SpecialRisingSpellMechanics::isImmuneByStac
|
|||||||
return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
|
return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
|
||||||
|
|
||||||
//FIXME: Archangels can cast immune stack and this should be applied for them and not hero
|
//FIXME: Archangels can cast immune stack and this should be applied for them and not hero
|
||||||
// if(caster)
|
// if(caster)
|
||||||
// {
|
// {
|
||||||
// auto maxHealth = calculateHealedHP(caster, obj, nullptr);
|
// auto maxHealth = calculateHealedHP(caster, obj, nullptr);
|
||||||
// if (maxHealth < obj->MaxHealth()) //must be able to rise at least one full creature
|
// if (maxHealth < obj->MaxHealth()) //must be able to rise at least one full creature
|
||||||
@ -640,16 +640,16 @@ ESpellCastProblem::ESpellCastProblem SummonMechanics::canBeCast(const CBattleInf
|
|||||||
const ui8 side = cb->playerToSide(player);
|
const ui8 side = cb->playerToSide(player);
|
||||||
|
|
||||||
//check if there are summoned elementals of other type
|
//check if there are summoned elementals of other type
|
||||||
|
|
||||||
auto otherSummoned = cb->battleGetStacksIf([side, this](const CStack * st)
|
auto otherSummoned = cb->battleGetStacksIf([side, this](const CStack * st)
|
||||||
{
|
{
|
||||||
return (st->attackerOwned == !side)
|
return (st->attackerOwned == !side)
|
||||||
&& (vstd::contains(st->state, EBattleStackState::SUMMONED))
|
&& (vstd::contains(st->state, EBattleStackState::SUMMONED))
|
||||||
&& (st->getCreature()->idNumber != creatureToSummon);
|
&& (st->getCreature()->idNumber != creatureToSummon);
|
||||||
});
|
});
|
||||||
|
|
||||||
if(!otherSummoned.empty())
|
if(!otherSummoned.empty())
|
||||||
return ESpellCastProblem::ANOTHER_ELEMENTAL_SUMMONED;
|
return ESpellCastProblem::ANOTHER_ELEMENTAL_SUMMONED;
|
||||||
|
|
||||||
return ESpellCastProblem::OK;
|
return ESpellCastProblem::OK;
|
||||||
}
|
}
|
||||||
@ -692,7 +692,7 @@ void TeleportMechanics::applyBattleEffects(const SpellCastEnvironment * env, con
|
|||||||
if(!destination.isValid())
|
if(!destination.isValid())
|
||||||
{
|
{
|
||||||
env->complain("TeleportMechanics: invalid teleport destination");
|
env->complain("TeleportMechanics: invalid teleport destination");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
BattleStackMoved bsm;
|
BattleStackMoved bsm;
|
||||||
bsm.distance = -1;
|
bsm.distance = -1;
|
||||||
@ -701,7 +701,7 @@ void TeleportMechanics::applyBattleEffects(const SpellCastEnvironment * env, con
|
|||||||
tiles.push_back(destination);
|
tiles.push_back(destination);
|
||||||
bsm.tilesToMove = tiles;
|
bsm.tilesToMove = tiles;
|
||||||
bsm.teleporting = true;
|
bsm.teleporting = true;
|
||||||
env->sendAndApply(&bsm);
|
env->sendAndApply(&bsm);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -714,7 +714,7 @@ void TeleportMechanics::applyBattleEffects(const SpellCastEnvironment * env, con
|
|||||||
bsm.tilesToMove = tiles;
|
bsm.tilesToMove = tiles;
|
||||||
bsm.teleporting = true;
|
bsm.teleporting = true;
|
||||||
env->sendAndApply(&bsm);
|
env->sendAndApply(&bsm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,14 +15,14 @@
|
|||||||
class DLL_LINKAGE HealingSpellMechanics : public DefaultSpellMechanics
|
class DLL_LINKAGE HealingSpellMechanics : public DefaultSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum class EHealLevel
|
enum class EHealLevel
|
||||||
{
|
{
|
||||||
HEAL,
|
HEAL,
|
||||||
RESURRECT,
|
RESURRECT,
|
||||||
TRUE_RESURRECT
|
TRUE_RESURRECT
|
||||||
};
|
};
|
||||||
|
|
||||||
HealingSpellMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
HealingSpellMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
||||||
protected:
|
protected:
|
||||||
void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
||||||
virtual int calculateHealedHP(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const;
|
virtual int calculateHealedHP(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const;
|
||||||
@ -32,9 +32,9 @@ protected:
|
|||||||
class DLL_LINKAGE AntimagicMechanics : public DefaultSpellMechanics
|
class DLL_LINKAGE AntimagicMechanics : public DefaultSpellMechanics
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
AntimagicMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
AntimagicMechanics(CSpell * s): DefaultSpellMechanics(s){};
|
||||||
|
|
||||||
void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override final;
|
void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override final;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_LINKAGE ChainLightningMechanics : public DefaultSpellMechanics
|
class DLL_LINKAGE ChainLightningMechanics : public DefaultSpellMechanics
|
||||||
@ -59,7 +59,7 @@ public:
|
|||||||
CureMechanics(CSpell * s): HealingSpellMechanics(s){};
|
CureMechanics(CSpell * s): HealingSpellMechanics(s){};
|
||||||
|
|
||||||
void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override final;
|
void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override final;
|
||||||
|
|
||||||
EHealLevel getHealLevel(int effectLevel) const override final;
|
EHealLevel getHealLevel(int effectLevel) const override final;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -130,7 +130,7 @@ public:
|
|||||||
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, PlayerColor player) const override;
|
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, PlayerColor player) const override;
|
||||||
protected:
|
protected:
|
||||||
void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
||||||
int calculateHealedHP(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
int calculateHealedHP(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
///all rising spells but SACRIFICE
|
///all rising spells but SACRIFICE
|
||||||
|
@ -19,7 +19,7 @@ class StacksInjured;
|
|||||||
struct SpellCastContext
|
struct SpellCastContext
|
||||||
{
|
{
|
||||||
SpellCastContext(std::vector<const CStack *> & attackedCres, BattleSpellCast & sc, StacksInjured & si):
|
SpellCastContext(std::vector<const CStack *> & attackedCres, BattleSpellCast & sc, StacksInjured & si):
|
||||||
attackedCres(attackedCres), sc(sc), si(si)
|
attackedCres(attackedCres), sc(sc), si(si)
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
std::vector<const CStack *> & attackedCres;
|
std::vector<const CStack *> & attackedCres;
|
||||||
@ -43,21 +43,21 @@ public:
|
|||||||
std::set<const CStack *> getAffectedStacks(SpellTargetingContext & ctx) const override;
|
std::set<const CStack *> getAffectedStacks(SpellTargetingContext & ctx) const override;
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, PlayerColor player) const override;
|
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, PlayerColor player) const override;
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const override;
|
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const override;
|
||||||
|
|
||||||
virtual void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override;
|
virtual void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const override;
|
||||||
bool adventureCast(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override final;
|
bool adventureCast(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const override final;
|
||||||
void battleCast(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters) const override final;
|
void battleCast(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters) const override final;
|
||||||
|
|
||||||
void battleLogSingleTarget(std::vector<std::string> & logLines, const BattleSpellCast * packet,
|
void battleLogSingleTarget(std::vector<std::string> & logLines, const BattleSpellCast * packet,
|
||||||
const std::string & casterName, const CStack * attackedStack, bool & displayDamage) const override;
|
const std::string & casterName, const CStack * attackedStack, bool & displayDamage) const override;
|
||||||
protected:
|
protected:
|
||||||
virtual void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const;
|
virtual void applyBattleEffects(const SpellCastEnvironment * env, const BattleSpellCastParameters & parameters, SpellCastContext & ctx) const;
|
||||||
|
|
||||||
///actual adventure cast implementation
|
///actual adventure cast implementation
|
||||||
virtual ESpellCastResult applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const;
|
virtual ESpellCastResult applyAdventureEffects(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const;
|
||||||
|
|
||||||
void doDispell(BattleInfo * battle, const BattleSpellCast * packet, const CSelector & selector) const;
|
void doDispell(BattleInfo * battle, const BattleSpellCast * packet, const CSelector & selector) const;
|
||||||
private:
|
private:
|
||||||
void castMagicMirror(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters) const;
|
void castMagicMirror(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters) const;
|
||||||
|
@ -115,7 +115,7 @@ bool CSpell::adventureCast(const SpellCastEnvironment * env, AdventureSpellCastP
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CSpell::battleCast(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters) const
|
void CSpell::battleCast(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters) const
|
||||||
{
|
{
|
||||||
assert(env);
|
assert(env);
|
||||||
if(parameters.destinations.size()<1)
|
if(parameters.destinations.size()<1)
|
||||||
{
|
{
|
||||||
@ -141,7 +141,7 @@ ui32 CSpell::calculateDamage(const ISpellCaster * caster, const CStack * affecte
|
|||||||
//check if spell really does damage - if not, return 0
|
//check if spell really does damage - if not, return 0
|
||||||
if(!isDamageSpell())
|
if(!isDamageSpell())
|
||||||
return 0;
|
return 0;
|
||||||
return adjustRawDamage(caster, affectedCreature, calculateRawEffectValue(spellSchoolLevel, usedSpellPower));
|
return adjustRawDamage(caster, affectedCreature, calculateRawEffectValue(spellSchoolLevel, usedSpellPower));
|
||||||
}
|
}
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem CSpell::canBeCast(const CBattleInfoCallback * cb, PlayerColor player) const
|
ESpellCastProblem::ESpellCastProblem CSpell::canBeCast(const CBattleInfoCallback * cb, PlayerColor player) const
|
||||||
@ -395,7 +395,7 @@ int CSpell::adjustRawDamage(const ISpellCaster * caster, const CStack * affected
|
|||||||
|
|
||||||
int CSpell::calculateRawEffectValue(int effectLevel, int effectPower) const
|
int CSpell::calculateRawEffectValue(int effectLevel, int effectPower) const
|
||||||
{
|
{
|
||||||
return effectPower * power + getPower(effectLevel);
|
return effectPower * power + getPower(effectLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem CSpell::internalIsImmune(const ISpellCaster * caster, const CStack *obj) const
|
ESpellCastProblem::ESpellCastProblem CSpell::internalIsImmune(const ISpellCaster * caster, const CStack *obj) const
|
||||||
@ -420,7 +420,7 @@ ESpellCastProblem::ESpellCastProblem CSpell::internalIsImmune(const ISpellCaster
|
|||||||
std::stringstream cachingStr;
|
std::stringstream cachingStr;
|
||||||
cachingStr << "type_" << Bonus::LEVEL_SPELL_IMMUNITY << "source_" << Bonus::SPELL_EFFECT;
|
cachingStr << "type_" << Bonus::LEVEL_SPELL_IMMUNITY << "source_" << Bonus::SPELL_EFFECT;
|
||||||
|
|
||||||
TBonusListPtr levelImmunitiesFromSpell = obj->getBonuses(Selector::type(Bonus::LEVEL_SPELL_IMMUNITY).And(Selector::sourceType(Bonus::SPELL_EFFECT)), cachingStr.str());
|
TBonusListPtr levelImmunitiesFromSpell = obj->getBonuses(Selector::type(Bonus::LEVEL_SPELL_IMMUNITY).And(Selector::sourceType(Bonus::SPELL_EFFECT)), cachingStr.str());
|
||||||
|
|
||||||
if(levelImmunitiesFromSpell->size() > 0 && levelImmunitiesFromSpell->totalValue() >= level && level)
|
if(levelImmunitiesFromSpell->size() > 0 && levelImmunitiesFromSpell->totalValue() >= level && level)
|
||||||
{
|
{
|
||||||
@ -433,19 +433,19 @@ ESpellCastProblem::ESpellCastProblem CSpell::internalIsImmune(const ISpellCaster
|
|||||||
cachingStr << "type_" << Bonus::SPELL_IMMUNITY << "subtype_" << id.toEnum() << "addInfo_1";
|
cachingStr << "type_" << Bonus::SPELL_IMMUNITY << "subtype_" << id.toEnum() << "addInfo_1";
|
||||||
if(obj->hasBonus(Selector::typeSubtypeInfo(Bonus::SPELL_IMMUNITY, id.toEnum(), 1), cachingStr.str()))
|
if(obj->hasBonus(Selector::typeSubtypeInfo(Bonus::SPELL_IMMUNITY, id.toEnum(), 1), cachingStr.str()))
|
||||||
return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
|
return ESpellCastProblem::STACK_IMMUNE_TO_SPELL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//check receptivity
|
//check receptivity
|
||||||
if (isPositive() && obj->hasBonusOfType(Bonus::RECEPTIVE)) //accept all positive spells
|
if (isPositive() && obj->hasBonusOfType(Bonus::RECEPTIVE)) //accept all positive spells
|
||||||
return ESpellCastProblem::OK;
|
return ESpellCastProblem::OK;
|
||||||
|
|
||||||
//3. Check negation
|
//3. Check negation
|
||||||
//Orb of vulnerability
|
//Orb of vulnerability
|
||||||
//FIXME: Orb of vulnerability mechanics is not such trivial (issue 1791)
|
//FIXME: Orb of vulnerability mechanics is not such trivial (issue 1791)
|
||||||
const bool battleWideNegation = obj->hasBonusOfType(Bonus::NEGATE_ALL_NATURAL_IMMUNITIES, 0);
|
const bool battleWideNegation = obj->hasBonusOfType(Bonus::NEGATE_ALL_NATURAL_IMMUNITIES, 0);
|
||||||
const bool heroNegation = obj->hasBonusOfType(Bonus::NEGATE_ALL_NATURAL_IMMUNITIES, 1);
|
const bool heroNegation = obj->hasBonusOfType(Bonus::NEGATE_ALL_NATURAL_IMMUNITIES, 1);
|
||||||
//anyone can cast on artifact holder`s stacks
|
//anyone can cast on artifact holder`s stacks
|
||||||
if(heroNegation)
|
if(heroNegation)
|
||||||
return ESpellCastProblem::NOT_DECIDED;
|
return ESpellCastProblem::NOT_DECIDED;
|
||||||
//this stack is from other player
|
//this stack is from other player
|
||||||
//todo: check that caster is always present (not trivial is this case)
|
//todo: check that caster is always present (not trivial is this case)
|
||||||
@ -520,9 +520,9 @@ ESpellCastProblem::ESpellCastProblem CSpell::isImmuneByStack(const ISpellCaster
|
|||||||
void CSpell::prepareBattleLog(const CBattleInfoCallback * cb, const BattleSpellCast * packet, std::vector<std::string> & logLines) const
|
void CSpell::prepareBattleLog(const CBattleInfoCallback * cb, const BattleSpellCast * packet, std::vector<std::string> & logLines) const
|
||||||
{
|
{
|
||||||
bool displayDamage = true;
|
bool displayDamage = true;
|
||||||
|
|
||||||
std::string casterName("Something"); //todo: localize
|
std::string casterName("Something"); //todo: localize
|
||||||
|
|
||||||
if(packet->castByHero)
|
if(packet->castByHero)
|
||||||
casterName = cb->battleGetHeroInfo(packet->side).name;
|
casterName = cb->battleGetHeroInfo(packet->side).name;
|
||||||
|
|
||||||
@ -536,13 +536,13 @@ void CSpell::prepareBattleLog(const CBattleInfoCallback * cb, const BattleSpell
|
|||||||
casterName = casterStack->type->namePl;
|
casterName = casterStack->type->namePl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(packet->affectedCres.size() == 1)
|
if(packet->affectedCres.size() == 1)
|
||||||
{
|
{
|
||||||
const CStack * attackedStack = cb->battleGetStackByID(*packet->affectedCres.begin(), false);
|
const CStack * attackedStack = cb->battleGetStackByID(*packet->affectedCres.begin(), false);
|
||||||
|
|
||||||
const std::string attackedNamePl = attackedStack->getCreature()->namePl;
|
const std::string attackedNamePl = attackedStack->getCreature()->namePl;
|
||||||
|
|
||||||
if(packet->castByHero)
|
if(packet->castByHero)
|
||||||
{
|
{
|
||||||
const std::string fmt = VLC->generaltexth->allTexts[195];
|
const std::string fmt = VLC->generaltexth->allTexts[195];
|
||||||
@ -550,17 +550,17 @@ void CSpell::prepareBattleLog(const CBattleInfoCallback * cb, const BattleSpell
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mechanics->battleLogSingleTarget(logLines, packet, casterName, attackedStack, displayDamage);
|
mechanics->battleLogSingleTarget(logLines, packet, casterName, attackedStack, displayDamage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
boost::format text(VLC->generaltexth->allTexts[196]);
|
boost::format text(VLC->generaltexth->allTexts[196]);
|
||||||
text % casterName % this->name;
|
text % casterName % this->name;
|
||||||
logLines.push_back(text.str());
|
logLines.push_back(text.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(packet->dmgToDisplay > 0 && displayDamage)
|
if(packet->dmgToDisplay > 0 && displayDamage)
|
||||||
{
|
{
|
||||||
boost::format dmgInfo(VLC->generaltexth->allTexts[376]);
|
boost::format dmgInfo(VLC->generaltexth->allTexts[376]);
|
||||||
@ -611,7 +611,7 @@ void CSpell::setupMechanics()
|
|||||||
CSpell::AnimationItem::AnimationItem()
|
CSpell::AnimationItem::AnimationItem()
|
||||||
:resourceName(""),verticalPosition(VerticalPosition::TOP),pause(0)
|
:resourceName(""),verticalPosition(VerticalPosition::TOP),pause(0)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -966,7 +966,7 @@ CSpell * CSpellHandler::loadFromJson(const JsonNode & json)
|
|||||||
{
|
{
|
||||||
newItem.pause = item.Float();
|
newItem.pause = item.Float();
|
||||||
}
|
}
|
||||||
|
|
||||||
q.push_back(newItem);
|
q.push_back(newItem);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1043,11 +1043,11 @@ void CSpellHandler::afterLoadFinalization()
|
|||||||
delete bonus;
|
delete bonus;
|
||||||
}
|
}
|
||||||
level.effectsTmp.clear();
|
level.effectsTmp.clear();
|
||||||
|
|
||||||
for(auto & bonus: level.effects)
|
for(auto & bonus: level.effects)
|
||||||
bonus.sid = spell->id;
|
bonus.sid = spell->id;
|
||||||
}
|
}
|
||||||
spell->setup();
|
spell->setup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ public:
|
|||||||
{
|
{
|
||||||
std::string resourceName;
|
std::string resourceName;
|
||||||
VerticalPosition verticalPosition;
|
VerticalPosition verticalPosition;
|
||||||
int pause;
|
int pause;
|
||||||
|
|
||||||
AnimationItem();
|
AnimationItem();
|
||||||
|
|
||||||
@ -78,7 +78,7 @@ public:
|
|||||||
if(version >= 754) //save format backward compatibility
|
if(version >= 754) //save format backward compatibility
|
||||||
{
|
{
|
||||||
h & pause;
|
h & pause;
|
||||||
}
|
}
|
||||||
else if(!h.saving)
|
else if(!h.saving)
|
||||||
{
|
{
|
||||||
pause = 0;
|
pause = 0;
|
||||||
@ -128,8 +128,8 @@ public:
|
|||||||
std::string range;
|
std::string range;
|
||||||
|
|
||||||
std::vector<Bonus> effects;
|
std::vector<Bonus> effects;
|
||||||
|
|
||||||
std::vector<Bonus *> effectsTmp; //TODO: this should replace effects
|
std::vector<Bonus *> effectsTmp; //TODO: this should replace effects
|
||||||
|
|
||||||
LevelInfo();
|
LevelInfo();
|
||||||
~LevelInfo();
|
~LevelInfo();
|
||||||
@ -265,13 +265,13 @@ public:
|
|||||||
friend class Graphics;
|
friend class Graphics;
|
||||||
public:
|
public:
|
||||||
///internal interface (for callbacks)
|
///internal interface (for callbacks)
|
||||||
|
|
||||||
///Checks general but spell-specific problems for all casting modes. Use only during battle.
|
///Checks general but spell-specific problems for all casting modes. Use only during battle.
|
||||||
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, PlayerColor player) const;
|
ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, PlayerColor player) const;
|
||||||
|
|
||||||
///checks for creature immunity / anything that prevent casting *at given hex* - doesn't take into account general problems such as not having spellbook or mana points etc.
|
///checks for creature immunity / anything that prevent casting *at given hex* - doesn't take into account general problems such as not having spellbook or mana points etc.
|
||||||
ESpellCastProblem::ESpellCastProblem isImmuneAt(const CBattleInfoCallback * cb, const ISpellCaster * caster, ECastingMode::ECastingMode mode, BattleHex destination) const;
|
ESpellCastProblem::ESpellCastProblem isImmuneAt(const CBattleInfoCallback * cb, const ISpellCaster * caster, ECastingMode::ECastingMode mode, BattleHex destination) const;
|
||||||
|
|
||||||
///checks for creature immunity / anything that prevent casting *at given target* - doesn't take into account general problems such as not having spellbook or mana points etc.
|
///checks for creature immunity / anything that prevent casting *at given target* - doesn't take into account general problems such as not having spellbook or mana points etc.
|
||||||
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const;
|
ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const;
|
||||||
public:
|
public:
|
||||||
@ -295,7 +295,7 @@ public://internal, for use only by Mechanics classes
|
|||||||
///applies caster`s secondary skills and affectedCreature`s to raw damage
|
///applies caster`s secondary skills and affectedCreature`s to raw damage
|
||||||
int adjustRawDamage(const ISpellCaster * caster, const CStack * affectedCreature, int rawDamage) const;
|
int adjustRawDamage(const ISpellCaster * caster, const CStack * affectedCreature, int rawDamage) const;
|
||||||
///returns raw damage or healed HP
|
///returns raw damage or healed HP
|
||||||
int calculateRawEffectValue(int effectLevel, int effectPower) const;
|
int calculateRawEffectValue(int effectLevel, int effectPower) const;
|
||||||
///generic immunity calculation
|
///generic immunity calculation
|
||||||
ESpellCastProblem::ESpellCastProblem internalIsImmune(const ISpellCaster * caster, const CStack *obj) const;
|
ESpellCastProblem::ESpellCastProblem internalIsImmune(const ISpellCaster * caster, const CStack *obj) const;
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ void DeathStareMechanics::applyBattleEffects(const SpellCastEnvironment * env, c
|
|||||||
BattleStackAttacked bsa;
|
BattleStackAttacked bsa;
|
||||||
bsa.flags |= BattleStackAttacked::SPELL_EFFECT;
|
bsa.flags |= BattleStackAttacked::SPELL_EFFECT;
|
||||||
bsa.spellID = owner->id;
|
bsa.spellID = owner->id;
|
||||||
bsa.damageAmount = parameters.effectPower * (attackedCre)->valOfBonuses(Bonus::STACK_HEALTH);//todo: move here all DeathStare calculation
|
bsa.damageAmount = parameters.effectPower * (attackedCre)->valOfBonuses(Bonus::STACK_HEALTH);//todo: move here all DeathStare calculation
|
||||||
bsa.stackAttacked = (attackedCre)->ID;
|
bsa.stackAttacked = (attackedCre)->ID;
|
||||||
bsa.attackerID = -1;
|
bsa.attackerID = -1;
|
||||||
(attackedCre)->prepareAttacked(bsa, env->getRandomGenerator());
|
(attackedCre)->prepareAttacked(bsa, env->getRandomGenerator());
|
||||||
@ -60,8 +60,8 @@ void DeathStareMechanics::applyBattleEffects(const SpellCastEnvironment * env, c
|
|||||||
void DispellHelpfulMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const
|
void DispellHelpfulMechanics::applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const
|
||||||
{
|
{
|
||||||
DefaultSpellMechanics::applyBattle(battle, packet);
|
DefaultSpellMechanics::applyBattle(battle, packet);
|
||||||
|
|
||||||
doDispell(battle, packet, Selector::positiveSpellEffects);
|
doDispell(battle, packet, Selector::positiveSpellEffects);
|
||||||
}
|
}
|
||||||
|
|
||||||
ESpellCastProblem::ESpellCastProblem DispellHelpfulMechanics::isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const
|
ESpellCastProblem::ESpellCastProblem DispellHelpfulMechanics::isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const
|
||||||
|
@ -24,14 +24,14 @@ BattleSpellCastParameters::Destination::Destination(const CStack * destination):
|
|||||||
stackValue(destination),
|
stackValue(destination),
|
||||||
hexValue(destination->position)
|
hexValue(destination->position)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BattleSpellCastParameters::Destination::Destination(const BattleHex & destination):
|
BattleSpellCastParameters::Destination::Destination(const BattleHex & destination):
|
||||||
stackValue(nullptr),
|
stackValue(nullptr),
|
||||||
hexValue(destination)
|
hexValue(destination)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BattleSpellCastParameters::BattleSpellCastParameters(const BattleInfo * cb, const ISpellCaster * caster, const CSpell * spell)
|
BattleSpellCastParameters::BattleSpellCastParameters(const BattleInfo * cb, const ISpellCaster * caster, const CSpell * spell)
|
||||||
@ -68,10 +68,10 @@ void BattleSpellCastParameters::prepare(const CSpell * spell)
|
|||||||
effectPower = caster->getEffectPower(spell);
|
effectPower = caster->getEffectPower(spell);
|
||||||
effectValue = caster->getEffectValue(spell);
|
effectValue = caster->getEffectValue(spell);
|
||||||
enchantPower = caster->getEnchantPower(spell);
|
enchantPower = caster->getEnchantPower(spell);
|
||||||
|
|
||||||
vstd::amax(spellLvl, 0);
|
vstd::amax(spellLvl, 0);
|
||||||
vstd::amax(effectLevel, 0);
|
vstd::amax(effectLevel, 0);
|
||||||
vstd::amax(enchantPower, 0);
|
vstd::amax(enchantPower, 0);
|
||||||
vstd::amax(enchantPower, 0);
|
vstd::amax(enchantPower, 0);
|
||||||
vstd::amax(effectValue, 0);
|
vstd::amax(effectValue, 0);
|
||||||
}
|
}
|
||||||
@ -118,11 +118,11 @@ ISpellMechanics * ISpellMechanics::createMechanics(CSpell * s)
|
|||||||
case SpellID::SACRIFICE:
|
case SpellID::SACRIFICE:
|
||||||
return new SacrificeMechanics(s);
|
return new SacrificeMechanics(s);
|
||||||
case SpellID::SUMMON_FIRE_ELEMENTAL:
|
case SpellID::SUMMON_FIRE_ELEMENTAL:
|
||||||
return new SummonMechanics(s, CreatureID::FIRE_ELEMENTAL);
|
return new SummonMechanics(s, CreatureID::FIRE_ELEMENTAL);
|
||||||
case SpellID::SUMMON_EARTH_ELEMENTAL:
|
case SpellID::SUMMON_EARTH_ELEMENTAL:
|
||||||
return new SummonMechanics(s, CreatureID::EARTH_ELEMENTAL);
|
return new SummonMechanics(s, CreatureID::EARTH_ELEMENTAL);
|
||||||
case SpellID::SUMMON_WATER_ELEMENTAL:
|
case SpellID::SUMMON_WATER_ELEMENTAL:
|
||||||
return new SummonMechanics(s, CreatureID::WATER_ELEMENTAL);
|
return new SummonMechanics(s, CreatureID::WATER_ELEMENTAL);
|
||||||
case SpellID::SUMMON_AIR_ELEMENTAL:
|
case SpellID::SUMMON_AIR_ELEMENTAL:
|
||||||
return new SummonMechanics(s, CreatureID::AIR_ELEMENTAL);
|
return new SummonMechanics(s, CreatureID::AIR_ELEMENTAL);
|
||||||
case SpellID::TELEPORT:
|
case SpellID::TELEPORT:
|
||||||
@ -151,4 +151,4 @@ ISpellMechanics * ISpellMechanics::createMechanics(CSpell * s)
|
|||||||
return new DefaultSpellMechanics(s);
|
return new DefaultSpellMechanics(s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,13 +34,13 @@ public:
|
|||||||
struct DLL_LINKAGE BattleSpellCastParameters
|
struct DLL_LINKAGE BattleSpellCastParameters
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///Single spell destination.
|
///Single spell destination.
|
||||||
/// (assumes that anything but battle stack can share same hex)
|
/// (assumes that anything but battle stack can share same hex)
|
||||||
struct DLL_LINKAGE Destination
|
struct DLL_LINKAGE Destination
|
||||||
{
|
{
|
||||||
explicit Destination(const CStack * destination);
|
explicit Destination(const CStack * destination);
|
||||||
explicit Destination(const BattleHex & destination);
|
explicit Destination(const BattleHex & destination);
|
||||||
|
|
||||||
const CStack * stackValue;
|
const CStack * stackValue;
|
||||||
const BattleHex hexValue;
|
const BattleHex hexValue;
|
||||||
};
|
};
|
||||||
@ -49,10 +49,10 @@ public:
|
|||||||
void aimToHex(const BattleHex & destination);
|
void aimToHex(const BattleHex & destination);
|
||||||
void aimToStack(const CStack * destination);
|
void aimToStack(const CStack * destination);
|
||||||
BattleHex getFirstDestinationHex() const;
|
BattleHex getFirstDestinationHex() const;
|
||||||
|
|
||||||
const BattleInfo * cb;
|
const BattleInfo * cb;
|
||||||
const ISpellCaster * caster;
|
const ISpellCaster * caster;
|
||||||
const PlayerColor casterColor;
|
const PlayerColor casterColor;
|
||||||
const ui8 casterSide;
|
const ui8 casterSide;
|
||||||
|
|
||||||
std::vector<Destination> destinations;
|
std::vector<Destination> destinations;
|
||||||
@ -63,7 +63,7 @@ public:
|
|||||||
const CStack * selectedStack;//deprecated
|
const CStack * selectedStack;//deprecated
|
||||||
|
|
||||||
///spell school level
|
///spell school level
|
||||||
int spellLvl;
|
int spellLvl;
|
||||||
///spell school level to use for effects
|
///spell school level to use for effects
|
||||||
int effectLevel;
|
int effectLevel;
|
||||||
///actual spell-power affecting effect values
|
///actual spell-power affecting effect values
|
||||||
@ -72,7 +72,7 @@ public:
|
|||||||
int enchantPower;
|
int enchantPower;
|
||||||
///for Archangel-like casting
|
///for Archangel-like casting
|
||||||
int effectValue;
|
int effectValue;
|
||||||
private:
|
private:
|
||||||
void prepare(const CSpell * spell);
|
void prepare(const CSpell * spell);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -105,18 +105,18 @@ public:
|
|||||||
|
|
||||||
virtual std::vector<BattleHex> rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool * outDroppedHexes = nullptr) const = 0;
|
virtual std::vector<BattleHex> rangeInHexes(BattleHex centralHex, ui8 schoolLvl, ui8 side, bool * outDroppedHexes = nullptr) const = 0;
|
||||||
virtual std::set<const CStack *> getAffectedStacks(SpellTargetingContext & ctx) const = 0;
|
virtual std::set<const CStack *> getAffectedStacks(SpellTargetingContext & ctx) const = 0;
|
||||||
|
|
||||||
virtual ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, PlayerColor player) const = 0;
|
virtual ESpellCastProblem::ESpellCastProblem canBeCast(const CBattleInfoCallback * cb, PlayerColor player) const = 0;
|
||||||
|
|
||||||
virtual ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const = 0;
|
virtual ESpellCastProblem::ESpellCastProblem isImmuneByStack(const ISpellCaster * caster, const CStack * obj) const = 0;
|
||||||
|
|
||||||
virtual void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const = 0;
|
virtual void applyBattle(BattleInfo * battle, const BattleSpellCast * packet) const = 0;
|
||||||
virtual bool adventureCast(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const = 0;
|
virtual bool adventureCast(const SpellCastEnvironment * env, AdventureSpellCastParameters & parameters) const = 0;
|
||||||
virtual void battleCast(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters) const = 0;
|
virtual void battleCast(const SpellCastEnvironment * env, BattleSpellCastParameters & parameters) const = 0;
|
||||||
|
|
||||||
virtual void battleLogSingleTarget(std::vector<std::string> & logLines, const BattleSpellCast * packet,
|
virtual void battleLogSingleTarget(std::vector<std::string> & logLines, const BattleSpellCast * packet,
|
||||||
const std::string & casterName, const CStack * attackedStack, bool & displayDamage) const = 0;
|
const std::string & casterName, const CStack * attackedStack, bool & displayDamage) const = 0;
|
||||||
|
|
||||||
static ISpellMechanics * createMechanics(CSpell * s);
|
static ISpellMechanics * createMechanics(CSpell * s);
|
||||||
protected:
|
protected:
|
||||||
CSpell * owner;
|
CSpell * owner;
|
||||||
|
@ -23,15 +23,15 @@ class DLL_LINKAGE ISpellCaster
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~ISpellCaster(){};
|
virtual ~ISpellCaster(){};
|
||||||
|
|
||||||
/// returns level on which given spell would be cast by this(0 - none, 1 - basic etc);
|
/// returns level on which given spell would be cast by this(0 - none, 1 - basic etc);
|
||||||
/// caster may not know this spell at all
|
/// caster may not know this spell at all
|
||||||
/// optionally returns number of selected school by arg - 0 - air magic, 1 - fire magic, 2 - water magic, 3 - earth magic
|
/// optionally returns number of selected school by arg - 0 - air magic, 1 - fire magic, 2 - water magic, 3 - earth magic
|
||||||
virtual ui8 getSpellSchoolLevel(const CSpell * spell, int *outSelectedSchool = nullptr) const = 0;
|
virtual ui8 getSpellSchoolLevel(const CSpell * spell, int *outSelectedSchool = nullptr) const = 0;
|
||||||
|
|
||||||
///applying sorcery secondary skill etc
|
///applying sorcery secondary skill etc
|
||||||
virtual ui32 getSpellBonus(const CSpell * spell, ui32 base, const CStack * affectedStack) const = 0;
|
virtual ui32 getSpellBonus(const CSpell * spell, ui32 base, const CStack * affectedStack) const = 0;
|
||||||
|
|
||||||
///default spell school level for effect calculation
|
///default spell school level for effect calculation
|
||||||
virtual int getEffectLevel(const CSpell * spell) const = 0;
|
virtual int getEffectLevel(const CSpell * spell) const = 0;
|
||||||
|
|
||||||
@ -43,6 +43,6 @@ public:
|
|||||||
|
|
||||||
///damage/heal override(ignores spell configuration, effect level and effect power)
|
///damage/heal override(ignores spell configuration, effect level and effect power)
|
||||||
virtual int getEffectValue(const CSpell * spell) const = 0;
|
virtual int getEffectValue(const CSpell * spell) const = 0;
|
||||||
|
|
||||||
virtual const PlayerColor getOwner() const = 0;
|
virtual const PlayerColor getOwner() const = 0;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user