mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Merge remote-tracking branch 'vcmi/beta' into develop
This commit is contained in:
commit
d0b3319f6a
@ -84,7 +84,7 @@ Goals::TGoalVec RecruitHeroBehavior::decompose() const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(treasureSourcesCount < 5)
|
if(treasureSourcesCount < 5 && (town->garrisonHero || town->getUpperArmy()->getArmyStrength() < 10000))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(cb->getHeroesInfo().size() < cb->getTownsInfo().size() + 1
|
if(cb->getHeroesInfo().size() < cb->getTownsInfo().size() + 1
|
||||||
|
46
ChangeLog.md
46
ChangeLog.md
@ -1,10 +1,50 @@
|
|||||||
# 1.3.0 -> 1.3.1
|
# 1.3.0 -> 1.3.1
|
||||||
(unreleased)
|
|
||||||
|
|
||||||
* Fixed crash on starting game with outdated mods
|
### GENERAL:
|
||||||
* Fixed Android mod manager crash
|
|
||||||
* Fixed framerate drops on hero movement with active hota mod
|
* Fixed framerate drops on hero movement with active hota mod
|
||||||
|
* Fade-out animations will now be skipped when instant hero movement speed is used
|
||||||
|
* Restarting loaded campaing scenario will now correctly reapply starting bonus
|
||||||
* Reverted FPS limit on mobile systems back to 60 fps
|
* Reverted FPS limit on mobile systems back to 60 fps
|
||||||
|
* Fixed loading of translations for maps and campaigns
|
||||||
|
* Fixed loading of preconfigured starting army for heroes with preconfigured spells
|
||||||
|
* Background battlefield obstacles will now appear below creatures
|
||||||
|
* it is now possible to load save game located inside mod
|
||||||
|
* Added option to configure reserved screen area in Launcher on iOS
|
||||||
|
* Fixed border scrolling when game window is maximized
|
||||||
|
|
||||||
|
### AI PLAYER:
|
||||||
|
* BattleAI: Improved performance of AI spell selection
|
||||||
|
* NKAI: Fixed freeze on attempt to exchange army between garrisoned and visiting hero
|
||||||
|
* NKAI: Fixed town threat calculation
|
||||||
|
* NKAI: Fixed recruitment of new heroes
|
||||||
|
* VCAI: Added workaround to avoid freeze on attempting to reach unreachable location
|
||||||
|
* VCAI: Fixed spellcasting by Archangels
|
||||||
|
|
||||||
|
### RANDOM MAP GENERATOR:
|
||||||
|
* Fixed placement of roads inside rock in underground
|
||||||
|
* Fixed placement of shifted creature animations from HotA
|
||||||
|
* Fixed placement of treasures at the boundary of wide connections
|
||||||
|
* Added more potential locations for quest artifacts in zone
|
||||||
|
|
||||||
|
### STABILITY:
|
||||||
|
* When starting client without H3 data game will now show message instead of silently crashing
|
||||||
|
* When starting invalid map in campaign, game will now show message instead of silently crashing
|
||||||
|
* Blocked loading of saves made with different set of mods to prevent crashes
|
||||||
|
* Fixed crash on starting game with outdated mods
|
||||||
|
* Fixed crash on attempt to sacrifice all your artifacts in Altar of Sacrifice
|
||||||
|
* Fixed crash on leveling up after winning battle as defender
|
||||||
|
* Fixed possible crash on end of battle opening sound
|
||||||
|
* Fixed crash on accepting battle result after winning battle as defender
|
||||||
|
* Fixed possible crash on casting spell in battle by AI
|
||||||
|
* Fixed multiple possible crashes on managing mods on Android
|
||||||
|
* Fixed multiple possible crashes on importing data on Android
|
||||||
|
* Fixed crash on refusing rewards from town building
|
||||||
|
* Fixed possible crash on threat evaluation by NKAI
|
||||||
|
* Fixed crash on using haptic feedback on some Android systems
|
||||||
|
* Fixed crash on right-clicking flags area in RMG setup mode
|
||||||
|
* Fixed crash on opening Blacksmith window and Build Structure dialogs in some localizations
|
||||||
|
* Fixed possible crash on displaying animated main menu
|
||||||
|
* Fixed crash on recruiting hero in town located on the border of map
|
||||||
|
|
||||||
# 1.2.1 -> 1.3.0
|
# 1.2.1 -> 1.3.0
|
||||||
|
|
||||||
|
2
Global.h
2
Global.h
@ -118,6 +118,7 @@ static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size.");
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
#include <optional>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <set>
|
#include <set>
|
||||||
@ -126,6 +127,7 @@ static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size.");
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
//The only available version is 3, as of Boost 1.50
|
//The only available version is 3, as of Boost 1.50
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
[![GitHub](https://github.com/vcmi/vcmi/actions/workflows/github.yml/badge.svg)](https://github.com/vcmi/vcmi/actions/workflows/github.yml)
|
[![GitHub](https://github.com/vcmi/vcmi/actions/workflows/github.yml/badge.svg)](https://github.com/vcmi/vcmi/actions/workflows/github.yml)
|
||||||
[![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/1.3.1/total)](https://github.com/vcmi/vcmi/releases/tag/1.3.1)
|
[![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/1.3.1/total)](https://github.com/vcmi/vcmi/releases/tag/1.3.1)
|
||||||
[![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/1.3.0/total)](https://github.com/vcmi/vcmi/releases/tag/1.3.0)
|
[![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/1.3.0/total)](https://github.com/vcmi/vcmi/releases/tag/1.3.0)
|
||||||
|
[![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/1.3.1/total)](https://github.com/vcmi/vcmi/releases/tag/1.3.1)
|
||||||
[![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/total)](https://github.com/vcmi/vcmi/releases)
|
[![Github Downloads](https://img.shields.io/github/downloads/vcmi/vcmi/total)](https://github.com/vcmi/vcmi/releases)
|
||||||
# VCMI Project
|
# VCMI Project
|
||||||
VCMI is work-in-progress attempt to recreate engine for Heroes III, giving it new and extended possibilities.
|
VCMI is work-in-progress attempt to recreate engine for Heroes III, giving it new and extended possibilities.
|
||||||
|
@ -52,6 +52,7 @@
|
|||||||
#include <boost/uuid/uuid.hpp>
|
#include <boost/uuid/uuid.hpp>
|
||||||
#include <boost/uuid/uuid_io.hpp>
|
#include <boost/uuid/uuid_io.hpp>
|
||||||
#include <boost/uuid/uuid_generators.hpp>
|
#include <boost/uuid/uuid_generators.hpp>
|
||||||
|
#include <boost/asio.hpp>
|
||||||
#include "../lib/serializer/Cast.h"
|
#include "../lib/serializer/Cast.h"
|
||||||
#include "LobbyClientNetPackVisitors.h"
|
#include "LobbyClientNetPackVisitors.h"
|
||||||
|
|
||||||
@ -86,6 +87,8 @@ template<typename T> class CApplyOnLobby : public CBaseForLobbyApply
|
|||||||
public:
|
public:
|
||||||
bool applyOnLobbyHandler(CServerHandler * handler, void * pack) const override
|
bool applyOnLobbyHandler(CServerHandler * handler, void * pack) const override
|
||||||
{
|
{
|
||||||
|
boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim);
|
||||||
|
|
||||||
T * ptr = static_cast<T *>(pack);
|
T * ptr = static_cast<T *>(pack);
|
||||||
ApplyOnLobbyHandlerNetPackVisitor visitor(*handler);
|
ApplyOnLobbyHandlerNetPackVisitor visitor(*handler);
|
||||||
|
|
||||||
|
@ -169,10 +169,10 @@ void AdventureMapInterface::tick(uint32_t msPassed)
|
|||||||
void AdventureMapInterface::handleMapScrollingUpdate(uint32_t timePassed)
|
void AdventureMapInterface::handleMapScrollingUpdate(uint32_t timePassed)
|
||||||
{
|
{
|
||||||
/// Width of window border, in pixels, that triggers map scrolling
|
/// Width of window border, in pixels, that triggers map scrolling
|
||||||
static constexpr uint32_t borderScrollWidth = 15;
|
static constexpr int32_t borderScrollWidth = 15;
|
||||||
|
|
||||||
uint32_t scrollSpeedPixels = settings["adventure"]["scrollSpeedPixels"].Float();
|
int32_t scrollSpeedPixels = settings["adventure"]["scrollSpeedPixels"].Float();
|
||||||
uint32_t scrollDistance = scrollSpeedPixels * timePassed / 1000;
|
int32_t scrollDistance = scrollSpeedPixels * timePassed / 1000;
|
||||||
|
|
||||||
Point cursorPosition = GH.getCursorPosition();
|
Point cursorPosition = GH.getCursorPosition();
|
||||||
Point scrollDirection;
|
Point scrollDirection;
|
||||||
|
@ -52,7 +52,7 @@
|
|||||||
</categories>
|
</categories>
|
||||||
<releases>
|
<releases>
|
||||||
<release version="1.4.0" date="2023-12-22" type="development" />
|
<release version="1.4.0" date="2023-12-22" type="development" />
|
||||||
<release version="1.3.1" date="2023-08-18" type="development" />
|
<release version="1.3.1" date="2023-08-18" />
|
||||||
<release version="1.3.0" date="2023-08-04" />
|
<release version="1.3.0" date="2023-08-04" />
|
||||||
<release version="1.2.1" date="2023-04-28" />
|
<release version="1.2.1" date="2023-04-28" />
|
||||||
<release version="1.2.0" date="2023-04-14" />
|
<release version="1.2.0" date="2023-04-14" />
|
||||||
|
@ -1731,6 +1731,10 @@ SpellID CBattleInfoCallback::getRandomCastedSpell(CRandomGenerator & rand,const
|
|||||||
TConstBonusListPtr bl = caster->getBonuses(Selector::type()(BonusType::SPELLCASTER));
|
TConstBonusListPtr bl = caster->getBonuses(Selector::type()(BonusType::SPELLCASTER));
|
||||||
if (!bl->size())
|
if (!bl->size())
|
||||||
return SpellID::NONE;
|
return SpellID::NONE;
|
||||||
|
|
||||||
|
if(bl->size() == 1)
|
||||||
|
return SpellID(bl->front()->subtype);
|
||||||
|
|
||||||
int totalWeight = 0;
|
int totalWeight = 0;
|
||||||
for(const auto & b : *bl)
|
for(const auto & b : *bl)
|
||||||
{
|
{
|
||||||
|
@ -489,23 +489,49 @@ void CModHandler::afterLoad(bool onlyEssential)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModHandler::trySetActiveMods(const std::map<TModID, CModVersion> & modList)
|
void CModHandler::trySetActiveMods(std::vector<TModID> saveActiveMods, const std::map<TModID, CModVersion> & modList)
|
||||||
{
|
{
|
||||||
|
std::vector<TModID> newActiveMods;
|
||||||
|
|
||||||
ModIncompatibility::ModList missingMods;
|
ModIncompatibility::ModList missingMods;
|
||||||
|
|
||||||
for(const auto & mod : modList)
|
for(const auto & m : activeMods)
|
||||||
{
|
{
|
||||||
auto m = mod.first;
|
if (vstd::contains(saveActiveMods, m))
|
||||||
auto mver = mod.second;
|
continue;
|
||||||
|
|
||||||
if(allMods.count(m) && (allMods[m].version.isNull() || mver.isNull() || allMods[m].version.compatible(mver)))
|
auto & modInfo = allMods.at(m);
|
||||||
allMods[m].setEnabled(true);
|
if(modInfo.checkModGameplayAffecting())
|
||||||
else
|
missingMods.emplace_back(m, modInfo.version.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const auto & m : saveActiveMods)
|
||||||
|
{
|
||||||
|
const CModVersion & mver = modList.at(m);
|
||||||
|
|
||||||
|
if (allMods.count(m) == 0)
|
||||||
|
{
|
||||||
|
missingMods.emplace_back(m, mver.toString());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto & modInfo = allMods.at(m);
|
||||||
|
|
||||||
|
bool modAffectsGameplay = modInfo.checkModGameplayAffecting();
|
||||||
|
bool modVersionCompatible = modInfo.version.isNull() || mver.isNull() || modInfo.version.compatible(mver);
|
||||||
|
bool modEnabledLocally = vstd::contains(activeMods, m);
|
||||||
|
bool modCanBeEnabled = modEnabledLocally && modVersionCompatible;
|
||||||
|
|
||||||
|
allMods[m].setEnabled(modCanBeEnabled);
|
||||||
|
|
||||||
|
if (modCanBeEnabled)
|
||||||
|
newActiveMods.push_back(m);
|
||||||
|
|
||||||
|
if (!modCanBeEnabled && modAffectsGameplay)
|
||||||
missingMods.emplace_back(m, mver.toString());
|
missingMods.emplace_back(m, mver.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!missingMods.empty())
|
std::swap(activeMods, newActiveMods);
|
||||||
throw ModIncompatibility(std::move(missingMods));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CIdentifierStorage & CModHandler::getIdentifiers()
|
CIdentifierStorage & CModHandler::getIdentifiers()
|
||||||
|
@ -52,7 +52,7 @@ class DLL_LINKAGE CModHandler : boost::noncopyable
|
|||||||
CModVersion getModVersion(TModID modName) const;
|
CModVersion getModVersion(TModID modName) const;
|
||||||
|
|
||||||
/// Attempt to set active mods according to provided list of mods from save, throws on failure
|
/// Attempt to set active mods according to provided list of mods from save, throws on failure
|
||||||
void trySetActiveMods(const std::map<TModID, CModVersion> & modList);
|
void trySetActiveMods(std::vector<TModID> saveActiveMods, const std::map<TModID, CModVersion> & modList);
|
||||||
|
|
||||||
std::unique_ptr<CIdentifierStorage> identifiers;
|
std::unique_ptr<CIdentifierStorage> identifiers;
|
||||||
|
|
||||||
@ -100,16 +100,14 @@ public:
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
loadMods();
|
loadMods();
|
||||||
std::vector<TModID> newActiveMods;
|
std::vector<TModID> saveActiveMods;
|
||||||
std::map<TModID, CModVersion> modVersions;
|
std::map<TModID, CModVersion> modVersions;
|
||||||
h & newActiveMods;
|
h & saveActiveMods;
|
||||||
|
|
||||||
for(const auto & m : newActiveMods)
|
for(const auto & m : saveActiveMods)
|
||||||
h & modVersions[m];
|
h & modVersions[m];
|
||||||
|
|
||||||
trySetActiveMods(modVersions);
|
trySetActiveMods(saveActiveMods, modVersions);
|
||||||
|
|
||||||
std::swap(activeMods, newActiveMods);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h & identifiers;
|
h & identifiers;
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "../CGeneralTextHandler.h"
|
#include "../CGeneralTextHandler.h"
|
||||||
#include "../VCMI_Lib.h"
|
#include "../VCMI_Lib.h"
|
||||||
|
#include "../filesystem/Filesystem.h"
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_BEGIN
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
|
|
||||||
@ -128,6 +129,48 @@ void CModInfo::loadLocalData(const JsonNode & data)
|
|||||||
validation = validated ? PASSED : FAILED;
|
validation = validated ? PASSED : FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CModInfo::checkModGameplayAffecting() const
|
||||||
|
{
|
||||||
|
if (modGameplayAffecting.has_value())
|
||||||
|
return *modGameplayAffecting;
|
||||||
|
|
||||||
|
static const std::vector<std::string> keysToTest = {
|
||||||
|
"heroClasses",
|
||||||
|
"artifacts",
|
||||||
|
"creatures",
|
||||||
|
"factions",
|
||||||
|
"objects",
|
||||||
|
"heroes",
|
||||||
|
"spells",
|
||||||
|
"skills",
|
||||||
|
"templates",
|
||||||
|
"scripts",
|
||||||
|
"battlefields",
|
||||||
|
"terrains",
|
||||||
|
"rivers",
|
||||||
|
"roads",
|
||||||
|
"obstacles"
|
||||||
|
};
|
||||||
|
|
||||||
|
ResourceID modFileResource(CModInfo::getModFile(identifier));
|
||||||
|
|
||||||
|
if(CResourceHandler::get("initial")->existsResource(modFileResource))
|
||||||
|
{
|
||||||
|
const JsonNode modConfig(modFileResource);
|
||||||
|
|
||||||
|
for(const auto & key : keysToTest)
|
||||||
|
{
|
||||||
|
if (!modConfig[key].isNull())
|
||||||
|
{
|
||||||
|
modGameplayAffecting = true;
|
||||||
|
return *modGameplayAffecting;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
modGameplayAffecting = false;
|
||||||
|
return *modGameplayAffecting;
|
||||||
|
}
|
||||||
|
|
||||||
bool CModInfo::isEnabled() const
|
bool CModInfo::isEnabled() const
|
||||||
{
|
{
|
||||||
return implicitlyEnabled && explicitlyEnabled;
|
return implicitlyEnabled && explicitlyEnabled;
|
||||||
|
@ -18,6 +18,10 @@ using TModID = std::string;
|
|||||||
|
|
||||||
class DLL_LINKAGE CModInfo
|
class DLL_LINKAGE CModInfo
|
||||||
{
|
{
|
||||||
|
/// cached result of checkModGameplayAffecting() call
|
||||||
|
/// Do not serialize - depends on local mod version, not server/save mod version
|
||||||
|
mutable std::optional<bool> modGameplayAffecting;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum EValidationStatus
|
enum EValidationStatus
|
||||||
{
|
{
|
||||||
@ -67,6 +71,9 @@ public:
|
|||||||
static std::string getModDir(const std::string & name);
|
static std::string getModDir(const std::string & name);
|
||||||
static std::string getModFile(const std::string & name);
|
static std::string getModFile(const std::string & name);
|
||||||
|
|
||||||
|
/// return true if this mod can affect gameplay, e.g. adds or modifies any game objects
|
||||||
|
bool checkModGameplayAffecting() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// true if mod is enabled by user, e.g. in Launcher UI
|
/// true if mod is enabled by user, e.g. in Launcher UI
|
||||||
bool explicitlyEnabled;
|
bool explicitlyEnabled;
|
||||||
|
@ -413,14 +413,18 @@ bool ObjectManager::createRequiredObjects()
|
|||||||
|
|
||||||
zone.connectPath(path);
|
zone.connectPath(path);
|
||||||
placeObject(rmgObject, guarded, true);
|
placeObject(rmgObject, guarded, true);
|
||||||
|
}
|
||||||
|
|
||||||
for(const auto & nearby : nearbyObjects)
|
for(const auto & nearby : nearbyObjects)
|
||||||
{
|
{
|
||||||
if(nearby.nearbyTarget != objInfo.obj)
|
auto * targetObject = nearby.nearbyTarget;
|
||||||
|
if (!targetObject || !targetObject->appearance)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
rmg::Object rmgNearObject(*nearby.obj);
|
rmg::Object rmgNearObject(*nearby.obj);
|
||||||
rmg::Area possibleArea(rmgObject.instances().front()->getBlockedArea().getBorderOutside());
|
rmg::Area possibleArea(rmg::Area(targetObject->getBlockedPos()).getBorderOutside());
|
||||||
possibleArea.intersect(zone.areaPossible());
|
possibleArea.intersect(zone.areaPossible());
|
||||||
if(possibleArea.empty())
|
if(possibleArea.empty())
|
||||||
{
|
{
|
||||||
@ -430,6 +434,20 @@ bool ObjectManager::createRequiredObjects()
|
|||||||
|
|
||||||
rmgNearObject.setPosition(*RandomGeneratorUtil::nextItem(possibleArea.getTiles(), zone.getRand()));
|
rmgNearObject.setPosition(*RandomGeneratorUtil::nextItem(possibleArea.getTiles(), zone.getRand()));
|
||||||
placeObject(rmgNearObject, false, false);
|
placeObject(rmgNearObject, false, false);
|
||||||
|
auto path = zone.searchPath(rmgNearObject.getVisitablePosition(), false);
|
||||||
|
if (path.valid())
|
||||||
|
{
|
||||||
|
zone.connectPath(path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (auto* instance : rmgNearObject.instances())
|
||||||
|
{
|
||||||
|
logGlobal->error("Failed to connect nearby object %s at %s",
|
||||||
|
instance->object().getObjectName(), instance->getPosition(true).toString());
|
||||||
|
mapProxy->removeObject(&instance->object());
|
||||||
|
}
|
||||||
|
rmgNearObject.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,7 +77,6 @@
|
|||||||
#define COMPLAIN_RETF(txt, FORMAT) {complain(boost::str(boost::format(txt) % FORMAT)); return false;}
|
#define COMPLAIN_RETF(txt, FORMAT) {complain(boost::str(boost::format(txt) % FORMAT)); return false;}
|
||||||
|
|
||||||
CondSh<bool> battleMadeAction(false);
|
CondSh<bool> battleMadeAction(false);
|
||||||
boost::recursive_mutex battleActionMutex;
|
|
||||||
CondSh<BattleResult *> battleResult(nullptr);
|
CondSh<BattleResult *> battleResult(nullptr);
|
||||||
template <typename T> class CApplyOnGH;
|
template <typename T> class CApplyOnGH;
|
||||||
|
|
||||||
|
@ -102,6 +102,8 @@ class CGameHandler : public IGameCallback, public CBattleInfoCallback, public En
|
|||||||
std::unique_ptr<boost::thread> battleThread;
|
std::unique_ptr<boost::thread> battleThread;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
boost::recursive_mutex battleActionMutex;
|
||||||
|
|
||||||
std::unique_ptr<HeroPoolProcessor> heroPool;
|
std::unique_ptr<HeroPoolProcessor> heroPool;
|
||||||
|
|
||||||
using FireShieldInfo = std::vector<std::pair<const CStack *, int64_t>>;
|
using FireShieldInfo = std::vector<std::pair<const CStack *, int64_t>>;
|
||||||
|
@ -244,7 +244,7 @@ bool HeroPoolProcessor::hireHero(const ObjectInstanceID & objectID, const HeroTy
|
|||||||
hr.hid = recruitedHero->subID;
|
hr.hid = recruitedHero->subID;
|
||||||
hr.player = player;
|
hr.player = player;
|
||||||
hr.tile = recruitedHero->convertFromVisitablePos(targetPos );
|
hr.tile = recruitedHero->convertFromVisitablePos(targetPos );
|
||||||
if(gameHandler->getTile(hr.tile)->isWater() && !recruitedHero->boat)
|
if(gameHandler->getTile(targetPos)->isWater() && !recruitedHero->boat)
|
||||||
{
|
{
|
||||||
//Create a new boat for hero
|
//Create a new boat for hero
|
||||||
gameHandler->createObject(targetPos , Obj::BOAT, recruitedHero->getBoatType().getNum());
|
gameHandler->createObject(targetPos , Obj::BOAT, recruitedHero->getBoatType().getNum());
|
||||||
|
@ -25,8 +25,6 @@
|
|||||||
#include "../lib/spells/ISpellMechanics.h"
|
#include "../lib/spells/ISpellMechanics.h"
|
||||||
#include "../lib/serializer/Cast.h"
|
#include "../lib/serializer/Cast.h"
|
||||||
|
|
||||||
extern boost::recursive_mutex battleActionMutex;
|
|
||||||
|
|
||||||
void ApplyGhNetPackVisitor::visitSaveGame(SaveGame & pack)
|
void ApplyGhNetPackVisitor::visitSaveGame(SaveGame & pack)
|
||||||
{
|
{
|
||||||
gh.save(pack.fname);
|
gh.save(pack.fname);
|
||||||
@ -282,7 +280,7 @@ void ApplyGhNetPackVisitor::visitQueryReply(QueryReply & pack)
|
|||||||
|
|
||||||
void ApplyGhNetPackVisitor::visitMakeAction(MakeAction & pack)
|
void ApplyGhNetPackVisitor::visitMakeAction(MakeAction & pack)
|
||||||
{
|
{
|
||||||
boost::unique_lock lock(battleActionMutex);
|
boost::unique_lock lock(gh.battleActionMutex);
|
||||||
|
|
||||||
const BattleInfo * b = gs.curB;
|
const BattleInfo * b = gs.curB;
|
||||||
if(!b)
|
if(!b)
|
||||||
@ -311,7 +309,7 @@ void ApplyGhNetPackVisitor::visitMakeAction(MakeAction & pack)
|
|||||||
|
|
||||||
void ApplyGhNetPackVisitor::visitMakeCustomAction(MakeCustomAction & pack)
|
void ApplyGhNetPackVisitor::visitMakeCustomAction(MakeCustomAction & pack)
|
||||||
{
|
{
|
||||||
boost::unique_lock lock(battleActionMutex);
|
boost::unique_lock lock(gh.battleActionMutex);
|
||||||
|
|
||||||
const BattleInfo * b = gs.curB;
|
const BattleInfo * b = gs.curB;
|
||||||
if(!b)
|
if(!b)
|
||||||
|
Loading…
Reference in New Issue
Block a user