mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-30 08:57:00 +02:00
* Fixed enchantments (#1265). Their effects were not properly added when reading config. Battle interface will be little less likely to block itself after corrupted spell cast.
* Fail gracefully when the file from which game is started is in invalid version. * Bumped versions.
This commit is contained in:
parent
be7c2bd07f
commit
fc6e72dc75
@ -97,22 +97,30 @@ void startGame(StartInfo * options, CConnection *serv = NULL);
|
|||||||
|
|
||||||
void startGameFromFile(const std::string &fname)
|
void startGameFromFile(const std::string &fname)
|
||||||
{
|
{
|
||||||
if(fname.size() && boost::filesystem::exists(fname))
|
StartInfo si;
|
||||||
|
try //attempt retrieving start info from given file
|
||||||
{
|
{
|
||||||
StartInfo si;
|
if(!fname.size() || !boost::filesystem::exists(fname))
|
||||||
|
throw std::runtime_error("Startfile \"" + fname + "\" does not exist!");
|
||||||
|
|
||||||
CLoadFile out(fname);
|
CLoadFile out(fname);
|
||||||
if(!out.sfile || !*out.sfile)
|
if(!out.sfile || !*out.sfile)
|
||||||
{
|
{
|
||||||
logGlobal->errorStream() << "Failed to open startfile, falling back to the main menu!";
|
throw std::runtime_error("Cannot read from startfile \"" + fname + "\"!");
|
||||||
GH.curInt = CGPreGame::create();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
out >> si;
|
out >> si;
|
||||||
while(GH.topInt())
|
|
||||||
GH.popIntTotally(GH.topInt());
|
|
||||||
|
|
||||||
startGame(&si);
|
|
||||||
}
|
}
|
||||||
|
catch(std::exception &e)
|
||||||
|
{
|
||||||
|
logGlobal->errorStream() << "Failed to start from the file: " + fname << ". Error: " << e.what()
|
||||||
|
<< " Falling back to main menu.";
|
||||||
|
GH.curInt = CGPreGame::create();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(GH.topInt())
|
||||||
|
GH.popIntTotally(GH.topInt());
|
||||||
|
startGame(&si);
|
||||||
}
|
}
|
||||||
|
|
||||||
void init()
|
void init()
|
||||||
|
@ -2493,10 +2493,7 @@ void CBattleInterface::projectileShowHelper(SDL_Surface * to)
|
|||||||
void CBattleInterface::endAction(const BattleAction* action)
|
void CBattleInterface::endAction(const BattleAction* action)
|
||||||
{
|
{
|
||||||
const CStack * stack = curInt->cb->battleGetStackByID(action->stackNumber);
|
const CStack * stack = curInt->cb->battleGetStackByID(action->stackNumber);
|
||||||
//if((action->actionType==2 || (action->actionType==6 && action->destinationTile!=cb->battleGetPos(action->stackNumber)))) //activating interface when move is finished
|
|
||||||
// {
|
|
||||||
// activate();
|
|
||||||
// }
|
|
||||||
if(action->actionType == Battle::HERO_SPELL)
|
if(action->actionType == Battle::HERO_SPELL)
|
||||||
{
|
{
|
||||||
if(action->side)
|
if(action->side)
|
||||||
@ -2536,6 +2533,12 @@ void CBattleInterface::endAction(const BattleAction* action)
|
|||||||
|
|
||||||
if( action->actionType == Battle::HERO_SPELL) //we have activated next stack after sending request that has been just realized -> blockmap due to movement has changed
|
if( action->actionType == Battle::HERO_SPELL) //we have activated next stack after sending request that has been just realized -> blockmap due to movement has changed
|
||||||
redrawBackgroundWithHexes(activeStack);
|
redrawBackgroundWithHexes(activeStack);
|
||||||
|
|
||||||
|
if(activeStack && !animsAreDisplayed.get() && pendingAnims.empty() && !active)
|
||||||
|
{
|
||||||
|
logGlobal->warnStream() << "Something wrong... interface was deactivated but there is no animation. Reactivating...";
|
||||||
|
activate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CBattleInterface::hideQueue()
|
void CBattleInterface::hideQueue()
|
||||||
|
@ -248,14 +248,19 @@ CSpell::ETargetType CSpell::getTargetType() const
|
|||||||
|
|
||||||
void CSpell::getEffects(std::vector<Bonus>& lst, const int level) const
|
void CSpell::getEffects(std::vector<Bonus>& lst, const int level) const
|
||||||
{
|
{
|
||||||
if (level < 0 || level>3)
|
if (level < 0 || level >= GameConstants::SPELL_SCHOOL_LEVELS)
|
||||||
{
|
{
|
||||||
logGlobal->errorStream() << __FUNCTION__ << " invalid school level " << level;
|
logGlobal->errorStream() << __FUNCTION__ << " invalid school level " << level;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (effects.empty())
|
if (effects.empty())
|
||||||
{
|
{
|
||||||
logGlobal->errorStream() << __FUNCTION__ << " This spell has no bonus effects! " << name;
|
logGlobal->errorStream() << __FUNCTION__ << " This spell (" + name + ") has no bonus effects! " << name;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (effects.size() <= level)
|
||||||
|
{
|
||||||
|
logGlobal->errorStream() << __FUNCTION__ << " This spell (" + name + ") is missing entry for level " << level;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
lst.reserve(lst.size() + effects[level].size());
|
lst.reserve(lst.size() + effects[level].size());
|
||||||
@ -440,7 +445,8 @@ CSpellHandler::CSpellHandler()
|
|||||||
spells.push_back(spells[SpellID::ACID_BREATH_DEFENSE]); //clone Acid Breath attributes for Acid Breath damage effect
|
spells.push_back(spells[SpellID::ACID_BREATH_DEFENSE]); //clone Acid Breath attributes for Acid Breath damage effect
|
||||||
|
|
||||||
//loading of additional spell traits
|
//loading of additional spell traits
|
||||||
const JsonNode config(ResourceID("config/spell_info.json"));
|
JsonNode config(ResourceID("config/spell_info.json"));
|
||||||
|
config.setMeta("core");
|
||||||
|
|
||||||
BOOST_FOREACH(auto &spell, config["spells"].Struct())
|
BOOST_FOREACH(auto &spell, config["spells"].Struct())
|
||||||
{
|
{
|
||||||
@ -493,7 +499,14 @@ CSpellHandler::CSpellHandler()
|
|||||||
auto v = v_node.convertTo<std::vector<int> >();
|
auto v = v_node.convertTo<std::vector<int> >();
|
||||||
auto a = a_node.convertTo<std::vector<int> >();
|
auto a = a_node.convertTo<std::vector<int> >();
|
||||||
|
|
||||||
for (int i=0; i<s->effects.size() ; i++)
|
if(v.size() && v.size() != GameConstants::SPELL_SCHOOL_LEVELS)
|
||||||
|
logGlobal->errorStream() << s->name << " should either have no values or exactly " << GameConstants::SPELL_SCHOOL_LEVELS;
|
||||||
|
if(a.size() && a.size() != GameConstants::SPELL_SCHOOL_LEVELS)
|
||||||
|
logGlobal->errorStream() << s->name << " should either have no ainfos or exactly " << GameConstants::SPELL_SCHOOL_LEVELS;
|
||||||
|
|
||||||
|
s->effects.resize(GameConstants::SPELL_SCHOOL_LEVELS);
|
||||||
|
|
||||||
|
for (int i = 0; i < GameConstants::SPELL_SCHOOL_LEVELS; i++)
|
||||||
{
|
{
|
||||||
Bonus * b = JsonUtils::parseBonus(bonus_node);
|
Bonus * b = JsonUtils::parseBonus(bonus_node);
|
||||||
b->sid = s->id; //for all
|
b->sid = s->id; //for all
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
#include "mapping/CCampaignHandler.h" //for CCampaignState
|
#include "mapping/CCampaignHandler.h" //for CCampaignState
|
||||||
#include "rmg/CMapGenerator.h" // for CMapGenOptions
|
#include "rmg/CMapGenerator.h" // for CMapGenOptions
|
||||||
|
|
||||||
const ui32 version = 739;
|
const ui32 version = 740;
|
||||||
|
|
||||||
class CConnection;
|
class CConnection;
|
||||||
class CGObjectInstance;
|
class CGObjectInstance;
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
namespace GameConstants
|
namespace GameConstants
|
||||||
{
|
{
|
||||||
const std::string VCMI_VERSION = "VCMI 0.92";
|
const std::string VCMI_VERSION = "VCMI 0.92b";
|
||||||
|
|
||||||
const int BFIELD_WIDTH = 17;
|
const int BFIELD_WIDTH = 17;
|
||||||
const int BFIELD_HEIGHT = 11;
|
const int BFIELD_HEIGHT = 11;
|
||||||
@ -30,6 +30,7 @@ namespace GameConstants
|
|||||||
const ui16 BACKPACK_START = 19;
|
const ui16 BACKPACK_START = 19;
|
||||||
const int CREATURES_PER_TOWN = 7; //without upgrades
|
const int CREATURES_PER_TOWN = 7; //without upgrades
|
||||||
const int SPELL_LEVELS = 5;
|
const int SPELL_LEVELS = 5;
|
||||||
|
const int SPELL_SCHOOL_LEVELS = 4;
|
||||||
const int CRE_LEVELS = 10; // number of creature experience levels
|
const int CRE_LEVELS = 10; // number of creature experience levels
|
||||||
|
|
||||||
const int SPELLBOOK_GOLD_COST = 500;
|
const int SPELLBOOK_GOLD_COST = 500;
|
||||||
|
@ -1538,6 +1538,8 @@ CGObjectInstance * CMapLoaderH3M::readHero(ObjectInstanceID idToBeGiven)
|
|||||||
PlayerColor owner = PlayerColor(reader.readUInt8());
|
PlayerColor owner = PlayerColor(reader.readUInt8());
|
||||||
nhi->subID = reader.readUInt8();
|
nhi->subID = reader.readUInt8();
|
||||||
|
|
||||||
|
//If hero of this type has been predefined, use that as a base.
|
||||||
|
//Instance data will overwrite the predefined values where appropriate.
|
||||||
for(int j = 0; j < map->predefinedHeroes.size(); ++j)
|
for(int j = 0; j < map->predefinedHeroes.size(); ++j)
|
||||||
{
|
{
|
||||||
if(map->predefinedHeroes[j]->subID == nhi->subID)
|
if(map->predefinedHeroes[j]->subID == nhi->subID)
|
||||||
|
Loading…
Reference in New Issue
Block a user