|
@@ -715,9 +715,6 @@ void CGameState::init(StartInfo * si, bool allowSavingRandomMap)
|
|
|
case StartInfo::CAMPAIGN:
|
|
|
initCampaign();
|
|
|
break;
|
|
|
- case StartInfo::DUEL:
|
|
|
- initDuel();
|
|
|
- return;
|
|
|
default:
|
|
|
logGlobal->errorStream() << "Wrong mode: " << (int)scenarioOps->mode;
|
|
|
return;
|
|
@@ -859,107 +856,6 @@ void CGameState::initCampaign()
|
|
|
map = CMapService::loadMap(buffer, mapContent.size(), scenarioName).release();
|
|
|
}
|
|
|
|
|
|
-void CGameState::initDuel()
|
|
|
-{
|
|
|
- DuelParameters dp;
|
|
|
- try //CLoadFile likes throwing
|
|
|
- {
|
|
|
- if(boost::algorithm::ends_with(scenarioOps->mapname, ".json"))
|
|
|
- {
|
|
|
- logGlobal->infoStream() << "Loading duel settings from JSON file: " << scenarioOps->mapname;
|
|
|
- dp = DuelParameters::fromJSON(scenarioOps->mapname);
|
|
|
- logGlobal->info("JSON file has been successfully read!");
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- CLoadFile lf(scenarioOps->mapname);
|
|
|
- lf.serializer & dp;
|
|
|
- }
|
|
|
- }
|
|
|
- catch(...)
|
|
|
- {
|
|
|
- logGlobal->errorStream() << "Cannot load duel settings from " << scenarioOps->mapname;
|
|
|
- throw;
|
|
|
- }
|
|
|
-
|
|
|
- const CArmedInstance *armies[2] = {nullptr};
|
|
|
- const CGHeroInstance *heroes[2] = {nullptr};
|
|
|
- CGTownInstance *town = nullptr;
|
|
|
-
|
|
|
- for(int i = 0; i < 2; i++)
|
|
|
- {
|
|
|
- CArmedInstance *obj = nullptr;
|
|
|
- if(dp.sides[i].heroId >= 0)
|
|
|
- {
|
|
|
- const DuelParameters::SideSettings &ss = dp.sides[i];
|
|
|
- auto h = new CGHeroInstance();
|
|
|
- armies[i] = heroes[i] = h;
|
|
|
- obj = h;
|
|
|
- h->subID = ss.heroId;
|
|
|
- for(int i = 0; i < ss.heroPrimSkills.size(); i++)
|
|
|
- h->pushPrimSkill(static_cast<PrimarySkill::PrimarySkill>(i), ss.heroPrimSkills[i]);
|
|
|
-
|
|
|
- if(!ss.spells.empty())
|
|
|
- {
|
|
|
- h->putArtifact(ArtifactPosition::SPELLBOOK, CArtifactInstance::createNewArtifactInstance(ArtifactID::SPELLBOOK));
|
|
|
- boost::copy(ss.spells, std::inserter(h->spells, h->spells.begin()));
|
|
|
- }
|
|
|
-
|
|
|
- for(auto &parka : ss.artifacts)
|
|
|
- {
|
|
|
- h->putArtifact(ArtifactPosition(parka.first), parka.second);
|
|
|
- }
|
|
|
-
|
|
|
- typedef const std::pair<si32, si8> &TSecSKill;
|
|
|
- for(TSecSKill secSkill : ss.heroSecSkills)
|
|
|
- h->setSecSkillLevel(SecondarySkill(secSkill.first), secSkill.second, 1);
|
|
|
-
|
|
|
- h->initHero(getRandomGenerator(), HeroTypeID(h->subID));
|
|
|
- obj->initObj(getRandomGenerator());
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- auto c = new CGCreature();
|
|
|
- armies[i] = obj = c;
|
|
|
- //c->subID = 34;
|
|
|
- }
|
|
|
-
|
|
|
- obj->setOwner(PlayerColor(i));
|
|
|
-
|
|
|
- for(int j = 0; j < ARRAY_COUNT(dp.sides[i].stacks); j++)
|
|
|
- {
|
|
|
- CreatureID cre = dp.sides[i].stacks[j].type;
|
|
|
- TQuantity count = dp.sides[i].stacks[j].count;
|
|
|
- if(count || obj->hasStackAtSlot(SlotID(j)))
|
|
|
- obj->setCreature(SlotID(j), cre, count);
|
|
|
- }
|
|
|
-
|
|
|
- for(const DuelParameters::CusomCreature &cc : dp.creatures)
|
|
|
- {
|
|
|
- CCreature *c = VLC->creh->creatures[cc.id];
|
|
|
- if(cc.attack >= 0)
|
|
|
- c->getBonusLocalFirst(Selector::typeSubtype(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK))->val = cc.attack;
|
|
|
- if(cc.defense >= 0)
|
|
|
- c->getBonusLocalFirst(Selector::typeSubtype(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE))->val = cc.defense;
|
|
|
- if(cc.speed >= 0)
|
|
|
- c->getBonusLocalFirst(Selector::type(Bonus::STACKS_SPEED))->val = cc.speed;
|
|
|
- if(cc.HP >= 0)
|
|
|
- c->getBonusLocalFirst(Selector::type(Bonus::STACK_HEALTH))->val = cc.HP;
|
|
|
- if(cc.dmg >= 0)
|
|
|
- {
|
|
|
- c->getBonusLocalFirst(Selector::typeSubtype(Bonus::CREATURE_DAMAGE, 1))->val = cc.dmg;
|
|
|
- c->getBonusLocalFirst(Selector::typeSubtype(Bonus::CREATURE_DAMAGE, 2))->val = cc.dmg;
|
|
|
- }
|
|
|
- if(cc.shoots >= 0)
|
|
|
- c->getBonusLocalFirst(Selector::type(Bonus::SHOTS))->val = cc.shoots;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- curB = BattleInfo::setupBattle(int3(-1,-1,-1), dp.terType, dp.bfieldType, armies, heroes, false, town);
|
|
|
- curB->obstacles = dp.obstacles;
|
|
|
- curB->localInit();
|
|
|
-}
|
|
|
-
|
|
|
void CGameState::checkMapChecksum()
|
|
|
{
|
|
|
logGlobal->infoStream() << "\tOur checksum for the map: "<< map->checksum;
|
|
@@ -3166,119 +3062,6 @@ int ArmyDescriptor::getStrength() const
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-DuelParameters::SideSettings::StackSettings::StackSettings()
|
|
|
- : type(CreatureID::NONE), count(0)
|
|
|
-{
|
|
|
-}
|
|
|
-
|
|
|
-DuelParameters::SideSettings::StackSettings::StackSettings(CreatureID Type, si32 Count)
|
|
|
- : type(Type), count(Count)
|
|
|
-{
|
|
|
-}
|
|
|
-
|
|
|
-DuelParameters::SideSettings::SideSettings()
|
|
|
-{
|
|
|
- heroId = -1;
|
|
|
-}
|
|
|
-
|
|
|
-DuelParameters::DuelParameters():
|
|
|
- terType(ETerrainType::DIRT),
|
|
|
- bfieldType(BFieldType::ROCKLANDS)
|
|
|
-{
|
|
|
-}
|
|
|
-
|
|
|
-DuelParameters DuelParameters::fromJSON(const std::string &fname)
|
|
|
-{
|
|
|
- DuelParameters ret;
|
|
|
-
|
|
|
- const JsonNode duelData(ResourceID("DATA/" + fname, EResType::TEXT));
|
|
|
- ret.terType = ETerrainType((int)duelData["terType"].Float());
|
|
|
- ret.bfieldType = BFieldType((int)duelData["bfieldType"].Float());
|
|
|
- for(const JsonNode &n : duelData["sides"].Vector())
|
|
|
- {
|
|
|
- SideSettings &ss = ret.sides[(int)n["side"].Float()];
|
|
|
- int i = 0;
|
|
|
- for(const JsonNode &stackNode : n["army"].Vector())
|
|
|
- {
|
|
|
- ss.stacks[i].type = CreatureID((si32)stackNode.Vector()[0].Float());
|
|
|
- ss.stacks[i].count = stackNode.Vector()[1].Float();
|
|
|
- i++;
|
|
|
- }
|
|
|
-
|
|
|
- if(n["heroid"].isNumber())
|
|
|
- ss.heroId = n["heroid"].Float();
|
|
|
- else
|
|
|
- ss.heroId = -1;
|
|
|
-
|
|
|
- for(const JsonNode &entry : n["heroPrimSkills"].Vector())
|
|
|
- ss.heroPrimSkills.push_back(entry.Float());
|
|
|
-
|
|
|
- for(const JsonNode &skillNode : n["heroSecSkills"].Vector())
|
|
|
- {
|
|
|
- std::pair<si32, si8> secSkill;
|
|
|
- secSkill.first = skillNode.Vector()[0].Float();
|
|
|
- secSkill.second = skillNode.Vector()[1].Float();
|
|
|
- ss.heroSecSkills.push_back(secSkill);
|
|
|
- }
|
|
|
-
|
|
|
- assert(ss.heroPrimSkills.empty() || ss.heroPrimSkills.size() == GameConstants::PRIMARY_SKILLS);
|
|
|
-
|
|
|
- if(ss.heroId != -1)
|
|
|
- {
|
|
|
- const JsonNode & spells = n["spells"];
|
|
|
- if(spells.getType() == JsonNode::DATA_STRING && spells.String() == "all")
|
|
|
- {
|
|
|
- for(auto spell : VLC->spellh->objects)
|
|
|
- if(spell->id <= SpellID::SUMMON_AIR_ELEMENTAL)
|
|
|
- ss.spells.insert(spell->id);
|
|
|
- }
|
|
|
- else
|
|
|
- for(const JsonNode &spell : n["spells"].Vector())
|
|
|
- ss.spells.insert(SpellID(spell.Float()));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- for(const JsonNode &n : duelData["obstacles"].Vector())
|
|
|
- {
|
|
|
- auto oi = std::make_shared<CObstacleInstance>();
|
|
|
- if(n.getType() == JsonNode::DATA_VECTOR)
|
|
|
- {
|
|
|
- oi->ID = n.Vector()[0].Float();
|
|
|
- oi->pos = n.Vector()[1].Float();
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- assert(n.isNumber());
|
|
|
- oi->ID = 21;
|
|
|
- oi->pos = n.Float();
|
|
|
- }
|
|
|
- oi->uniqueID = ret.obstacles.size();
|
|
|
- ret.obstacles.push_back(oi);
|
|
|
- }
|
|
|
-
|
|
|
- for(const JsonNode &n : duelData["creatures"].Vector())
|
|
|
- {
|
|
|
- CusomCreature cc;
|
|
|
- cc.id = n["id"].Float();
|
|
|
-
|
|
|
-#define retrieve(name) \
|
|
|
- if(n[ #name ].isNumber())\
|
|
|
- cc.name = n[ #name ].Float(); \
|
|
|
- else \
|
|
|
- cc.name = -1;
|
|
|
-
|
|
|
- retrieve(attack);
|
|
|
- retrieve(defense);
|
|
|
- retrieve(HP);
|
|
|
- retrieve(dmg);
|
|
|
- retrieve(shoots);
|
|
|
- retrieve(speed);
|
|
|
- ret.creatures.push_back(cc);
|
|
|
- }
|
|
|
-
|
|
|
- return ret;
|
|
|
-}
|
|
|
-
|
|
|
TeamState::TeamState()
|
|
|
{
|
|
|
setNodeType(TEAM);
|