mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-03 00:46:55 +02:00
Remove code related to duel mode (#312)
Remove code related to duel mode
This commit is contained in:
@ -261,7 +261,6 @@ int main(int argc, char** argv)
|
|||||||
("version,v", "display version information and exit")
|
("version,v", "display version information and exit")
|
||||||
("disable-shm", "force disable shared memory usage")
|
("disable-shm", "force disable shared memory usage")
|
||||||
("enable-shm-uuid", "use UUID for shared memory identifier")
|
("enable-shm-uuid", "use UUID for shared memory identifier")
|
||||||
("battle,b", po::value<std::string>(), "runs game in duel mode (battle-only")
|
|
||||||
("start", po::value<bfs::path>(), "starts game from saved StartInfo file")
|
("start", po::value<bfs::path>(), "starts game from saved StartInfo file")
|
||||||
("testmap", po::value<std::string>(), "")
|
("testmap", po::value<std::string>(), "")
|
||||||
("spectate,s", "enable spectator interface for AI-only games")
|
("spectate,s", "enable spectator interface for AI-only games")
|
||||||
@ -515,8 +514,6 @@ int main(int argc, char** argv)
|
|||||||
#endif // THREADED
|
#endif // THREADED
|
||||||
logGlobal->infoStream()<<"Initialization of VCMI (together): "<<total.getDiff();
|
logGlobal->infoStream()<<"Initialization of VCMI (together): "<<total.getDiff();
|
||||||
|
|
||||||
if(!vm.count("battle"))
|
|
||||||
{
|
|
||||||
session["autoSkip"].Bool() = vm.count("autoSkip");
|
session["autoSkip"].Bool() = vm.count("autoSkip");
|
||||||
session["oneGoodAI"].Bool() = vm.count("oneGoodAI");
|
session["oneGoodAI"].Bool() = vm.count("oneGoodAI");
|
||||||
session["aiSolo"].Bool() = false;
|
session["aiSolo"].Bool() = false;
|
||||||
@ -558,16 +555,6 @@ int main(int argc, char** argv)
|
|||||||
GH.curInt = CGPreGame::create(); //will set CGP pointer to itself
|
GH.curInt = CGPreGame::create(); //will set CGP pointer to itself
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto si = new StartInfo();
|
|
||||||
si->mode = StartInfo::DUEL;
|
|
||||||
si->mapname = vm["battle"].as<std::string>();
|
|
||||||
si->playerInfos[PlayerColor(0)].color = PlayerColor(0);
|
|
||||||
si->playerInfos[PlayerColor(1)].color = PlayerColor(1);
|
|
||||||
startGame(si);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!settings["session"]["headless"].Bool())
|
if(!settings["session"]["headless"].Bool())
|
||||||
{
|
{
|
||||||
@ -1350,7 +1337,6 @@ void startGame(StartInfo * options, CConnection *serv/* = nullptr*/)
|
|||||||
{
|
{
|
||||||
case StartInfo::NEW_GAME:
|
case StartInfo::NEW_GAME:
|
||||||
case StartInfo::CAMPAIGN:
|
case StartInfo::CAMPAIGN:
|
||||||
case StartInfo::DUEL:
|
|
||||||
client->newGame(serv, options);
|
client->newGame(serv, options);
|
||||||
break;
|
break;
|
||||||
case StartInfo::LOAD_GAME:
|
case StartInfo::LOAD_GAME:
|
||||||
|
@ -113,7 +113,6 @@ CPlayerInterface::CPlayerInterface(PlayerColor Player)
|
|||||||
logGlobal->traceStream() << "\tHuman player interface for player " << Player << " being constructed";
|
logGlobal->traceStream() << "\tHuman player interface for player " << Player << " being constructed";
|
||||||
destinationTeleport = ObjectInstanceID();
|
destinationTeleport = ObjectInstanceID();
|
||||||
destinationTeleportPos = int3(-1);
|
destinationTeleportPos = int3(-1);
|
||||||
observerInDuelMode = false;
|
|
||||||
howManyPeople++;
|
howManyPeople++;
|
||||||
GH.defActionsDef = 0;
|
GH.defActionsDef = 0;
|
||||||
LOCPLINT = this;
|
LOCPLINT = this;
|
||||||
@ -147,8 +146,6 @@ CPlayerInterface::~CPlayerInterface()
|
|||||||
void CPlayerInterface::init(std::shared_ptr<CCallback> CB)
|
void CPlayerInterface::init(std::shared_ptr<CCallback> CB)
|
||||||
{
|
{
|
||||||
cb = CB;
|
cb = CB;
|
||||||
if (observerInDuelMode)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!towns.size() && !wanderingHeroes.size())
|
if (!towns.size() && !wanderingHeroes.size())
|
||||||
initializeHeroTownList();
|
initializeHeroTownList();
|
||||||
@ -1300,8 +1297,11 @@ void CPlayerInterface::heroBonusChanged( const CGHeroInstance *hero, const Bonus
|
|||||||
|
|
||||||
template <typename Handler> void CPlayerInterface::serializeTempl( Handler &h, const int version )
|
template <typename Handler> void CPlayerInterface::serializeTempl( Handler &h, const int version )
|
||||||
{
|
{
|
||||||
|
if(version < 774 && !h.saving)
|
||||||
|
{
|
||||||
|
bool observerInDuelMode;
|
||||||
h & observerInDuelMode;
|
h & observerInDuelMode;
|
||||||
|
}
|
||||||
|
|
||||||
h & wanderingHeroes & towns & sleepingHeroes;
|
h & wanderingHeroes & towns & sleepingHeroes;
|
||||||
|
|
||||||
|
@ -84,7 +84,6 @@ class CPlayerInterface : public CGameInterface, public IUpdateable
|
|||||||
{
|
{
|
||||||
const CArmedInstance * currentSelection;
|
const CArmedInstance * currentSelection;
|
||||||
public:
|
public:
|
||||||
bool observerInDuelMode;
|
|
||||||
ObjectInstanceID destinationTeleport; //contain -1 or object id if teleportation
|
ObjectInstanceID destinationTeleport; //contain -1 or object id if teleportation
|
||||||
int3 destinationTeleportPos;
|
int3 destinationTeleportPos;
|
||||||
|
|
||||||
|
@ -450,12 +450,10 @@ void CClient::newGame( CConnection *con, StartInfo *si )
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
logNetwork->traceStream() << "Preparing interface for player " << color;
|
logNetwork->traceStream() << "Preparing interface for player " << color;
|
||||||
if(si->mode != StartInfo::DUEL)
|
|
||||||
{
|
|
||||||
if(elem.second.playerID == PlayerSettings::PLAYER_AI)
|
if(elem.second.playerID == PlayerSettings::PLAYER_AI)
|
||||||
{
|
{
|
||||||
auto AiToGive = aiNameForPlayer(elem.second, false);
|
auto AiToGive = aiNameForPlayer(elem.second, false);
|
||||||
logNetwork->infoStream() << boost::format("Player %s will be lead by %s") % color % AiToGive;
|
logNetwork->info("Player %s will be lead by %s", color, AiToGive);
|
||||||
installNewPlayerInterface(CDynLibHandler::getNewAI(AiToGive), color);
|
installNewPlayerInterface(CDynLibHandler::getNewAI(AiToGive), color);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -464,33 +462,12 @@ void CClient::newGame( CConnection *con, StartInfo *si )
|
|||||||
humanPlayers++;
|
humanPlayers++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
std::string AItoGive = aiNameForPlayer(elem.second, true);
|
|
||||||
installNewBattleInterface(CDynLibHandler::getNewBattleAI(AItoGive), color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(si->mode == StartInfo::DUEL)
|
|
||||||
{
|
|
||||||
if(!settings["session"]["headless"].Bool())
|
|
||||||
{
|
|
||||||
boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim);
|
|
||||||
auto p = std::make_shared<CPlayerInterface>(PlayerColor::NEUTRAL);
|
|
||||||
p->observerInDuelMode = true;
|
|
||||||
installNewPlayerInterface(p, boost::none);
|
|
||||||
GH.curInt = p.get();
|
|
||||||
}
|
|
||||||
battleStarted(gs->curB);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(settings["session"]["spectate"].Bool())
|
if(settings["session"]["spectate"].Bool())
|
||||||
{
|
{
|
||||||
installNewPlayerInterface(std::make_shared<CPlayerInterface>(PlayerColor::SPECTATOR), PlayerColor::SPECTATOR, true);
|
installNewPlayerInterface(std::make_shared<CPlayerInterface>(PlayerColor::SPECTATOR), PlayerColor::SPECTATOR, true);
|
||||||
}
|
}
|
||||||
loadNeutralBattleAI();
|
loadNeutralBattleAI();
|
||||||
}
|
|
||||||
|
|
||||||
serv->addStdVecItems(gs);
|
serv->addStdVecItems(gs);
|
||||||
hotSeat = (humanPlayers > 1);
|
hotSeat = (humanPlayers > 1);
|
||||||
@ -777,7 +754,7 @@ void CClient::battleStarted(const BattleInfo * info)
|
|||||||
|
|
||||||
if(!settings["session"]["headless"].Bool())
|
if(!settings["session"]["headless"].Bool())
|
||||||
{
|
{
|
||||||
if(!!att || !!def || gs->scenarioOps->mode == StartInfo::DUEL)
|
if(!!att || !!def)
|
||||||
{
|
{
|
||||||
boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim);
|
boost::unique_lock<boost::recursive_mutex> un(*CPlayerInterface::pim);
|
||||||
auto bi = new CBattleInterface(leftSide.armyObject, rightSide.armyObject, leftSide.hero, rightSide.hero,
|
auto bi = new CBattleInterface(leftSide.armyObject, rightSide.armyObject, leftSide.hero, rightSide.hero,
|
||||||
|
@ -721,10 +721,6 @@ void BattleResultsApplied::applyCl(CClient *cl)
|
|||||||
INTERFACE_CALL_IF_PRESENT(player1, battleResultsApplied);
|
INTERFACE_CALL_IF_PRESENT(player1, battleResultsApplied);
|
||||||
INTERFACE_CALL_IF_PRESENT(player2, battleResultsApplied);
|
INTERFACE_CALL_IF_PRESENT(player2, battleResultsApplied);
|
||||||
INTERFACE_CALL_IF_PRESENT(PlayerColor::SPECTATOR, battleResultsApplied);
|
INTERFACE_CALL_IF_PRESENT(PlayerColor::SPECTATOR, battleResultsApplied);
|
||||||
if(GS(cl)->initialOpts->mode == StartInfo::DUEL)
|
|
||||||
{
|
|
||||||
handleQuit();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void StacksHealedOrResurrected::applyCl(CClient *cl)
|
void StacksHealedOrResurrected::applyCl(CClient *cl)
|
||||||
|
@ -493,12 +493,6 @@ void CBattleResultWindow::show(SDL_Surface * to)
|
|||||||
|
|
||||||
void CBattleResultWindow::bExitf()
|
void CBattleResultWindow::bExitf()
|
||||||
{
|
{
|
||||||
if(LOCPLINT->cb->getStartInfo()->mode == StartInfo::DUEL)
|
|
||||||
{
|
|
||||||
CGuiHandler::pushSDLEvent(SDL_QUIT);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CPlayerInterface &intTmp = owner; //copy reference because "this" will be destructed soon
|
CPlayerInterface &intTmp = owner; //copy reference because "this" will be destructed soon
|
||||||
GH.popIntTotally(this);
|
GH.popIntTotally(this);
|
||||||
if(dynamic_cast<CBattleInterface*>(GH.topInt()))
|
if(dynamic_cast<CBattleInterface*>(GH.topInt()))
|
||||||
|
@ -715,9 +715,6 @@ void CGameState::init(StartInfo * si, bool allowSavingRandomMap)
|
|||||||
case StartInfo::CAMPAIGN:
|
case StartInfo::CAMPAIGN:
|
||||||
initCampaign();
|
initCampaign();
|
||||||
break;
|
break;
|
||||||
case StartInfo::DUEL:
|
|
||||||
initDuel();
|
|
||||||
return;
|
|
||||||
default:
|
default:
|
||||||
logGlobal->errorStream() << "Wrong mode: " << (int)scenarioOps->mode;
|
logGlobal->errorStream() << "Wrong mode: " << (int)scenarioOps->mode;
|
||||||
return;
|
return;
|
||||||
@ -859,107 +856,6 @@ void CGameState::initCampaign()
|
|||||||
map = CMapService::loadMap(buffer, mapContent.size(), scenarioName).release();
|
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()
|
void CGameState::checkMapChecksum()
|
||||||
{
|
{
|
||||||
logGlobal->infoStream() << "\tOur checksum for the map: "<< map->checksum;
|
logGlobal->infoStream() << "\tOur checksum for the map: "<< map->checksum;
|
||||||
@ -3166,119 +3062,6 @@ int ArmyDescriptor::getStrength() const
|
|||||||
return ret;
|
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()
|
TeamState::TeamState()
|
||||||
{
|
{
|
||||||
setNodeType(TEAM);
|
setNodeType(TEAM);
|
||||||
|
@ -117,66 +117,6 @@ struct UpgradeInfo
|
|||||||
UpgradeInfo(){oldID = CreatureID::NONE;};
|
UpgradeInfo(){oldID = CreatureID::NONE;};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DLL_EXPORT DuelParameters
|
|
||||||
{
|
|
||||||
ETerrainType terType;
|
|
||||||
BFieldType bfieldType;
|
|
||||||
struct DLL_EXPORT SideSettings
|
|
||||||
{
|
|
||||||
struct DLL_EXPORT StackSettings
|
|
||||||
{
|
|
||||||
CreatureID type;
|
|
||||||
si32 count;
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
|
||||||
{
|
|
||||||
h & type & count;
|
|
||||||
}
|
|
||||||
|
|
||||||
StackSettings();
|
|
||||||
StackSettings(CreatureID Type, si32 Count);
|
|
||||||
} stacks[GameConstants::ARMY_SIZE];
|
|
||||||
|
|
||||||
si32 heroId; //-1 if none
|
|
||||||
std::vector<si32> heroPrimSkills; //may be empty
|
|
||||||
std::map<si32, CArtifactInstance*> artifacts;
|
|
||||||
std::vector<std::pair<si32, si8> > heroSecSkills; //may be empty; pairs <id, level>, level [0-3]
|
|
||||||
std::set<SpellID> spells;
|
|
||||||
|
|
||||||
SideSettings();
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
|
||||||
{
|
|
||||||
h & stacks & heroId & heroPrimSkills & artifacts & heroSecSkills & spells;
|
|
||||||
}
|
|
||||||
} sides[2];
|
|
||||||
|
|
||||||
std::vector<std::shared_ptr<CObstacleInstance> > obstacles;
|
|
||||||
|
|
||||||
static DuelParameters fromJSON(const std::string &fname);
|
|
||||||
|
|
||||||
struct CusomCreature
|
|
||||||
{
|
|
||||||
int id;
|
|
||||||
int attack, defense, dmg, HP, speed, shoots;
|
|
||||||
|
|
||||||
CusomCreature()
|
|
||||||
{
|
|
||||||
id = attack = defense = dmg = HP = speed = shoots = -1;
|
|
||||||
}
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
|
||||||
{
|
|
||||||
h & id & attack & defense & dmg & HP & speed & shoots;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<CusomCreature> creatures;
|
|
||||||
|
|
||||||
DuelParameters();
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
|
||||||
{
|
|
||||||
h & terType & bfieldType & sides & obstacles & creatures;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BattleInfo;
|
struct BattleInfo;
|
||||||
|
|
||||||
DLL_LINKAGE std::ostream & operator<<(std::ostream & os, const EVictoryLossCheckResult & victoryLossCheckResult);
|
DLL_LINKAGE std::ostream & operator<<(std::ostream & os, const EVictoryLossCheckResult & victoryLossCheckResult);
|
||||||
@ -285,7 +225,6 @@ private:
|
|||||||
|
|
||||||
void initNewGame(bool allowSavingRandomMap);
|
void initNewGame(bool allowSavingRandomMap);
|
||||||
void initCampaign();
|
void initCampaign();
|
||||||
void initDuel();
|
|
||||||
void checkMapChecksum();
|
void checkMapChecksum();
|
||||||
void initGrailPosition();
|
void initGrailPosition();
|
||||||
void initRandomFactionsForPlayers();
|
void initRandomFactionsForPlayers();
|
||||||
|
@ -68,7 +68,7 @@ struct PlayerSettings
|
|||||||
/// Struct which describes the difficulty, the turn time,.. of a heroes match.
|
/// Struct which describes the difficulty, the turn time,.. of a heroes match.
|
||||||
struct StartInfo
|
struct StartInfo
|
||||||
{
|
{
|
||||||
enum EMode {NEW_GAME, LOAD_GAME, CAMPAIGN, DUEL, INVALID = 255};
|
enum EMode {NEW_GAME, LOAD_GAME, CAMPAIGN, INVALID = 255};
|
||||||
|
|
||||||
EMode mode;
|
EMode mode;
|
||||||
ui8 difficulty; //0=easy; 4=impossible
|
ui8 difficulty; //0=easy; 4=impossible
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
#include "../ConstTransitivePtr.h"
|
#include "../ConstTransitivePtr.h"
|
||||||
#include "../GameConstants.h"
|
#include "../GameConstants.h"
|
||||||
|
|
||||||
const ui32 SERIALIZATION_VERSION = 773;
|
const ui32 SERIALIZATION_VERSION = 774;
|
||||||
const ui32 MINIMAL_SERIALIZATION_VERSION = 753;
|
const ui32 MINIMAL_SERIALIZATION_VERSION = 753;
|
||||||
const std::string SAVEGAME_MAGIC = "VCMISVG";
|
const std::string SAVEGAME_MAGIC = "VCMISVG";
|
||||||
|
|
||||||
|
@ -574,10 +574,6 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
|
|||||||
if (!battleQuery)
|
if (!battleQuery)
|
||||||
{
|
{
|
||||||
logGlobal->error("Cannot find battle query!");
|
logGlobal->error("Cannot find battle query!");
|
||||||
if (gs->initialOpts->mode == StartInfo::DUEL)
|
|
||||||
{
|
|
||||||
battleQuery = std::make_shared<CBattleQuery>(gs->curB);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (battleQuery != queries.topQuery(gs->curB->sides[0].color))
|
if (battleQuery != queries.topQuery(gs->curB->sides[0].color))
|
||||||
complain("Player " + boost::lexical_cast<std::string>(gs->curB->sides[0].color) + " although in battle has no battle query at the top!");
|
complain("Player " + boost::lexical_cast<std::string>(gs->curB->sides[0].color) + " although in battle has no battle query at the top!");
|
||||||
@ -586,19 +582,11 @@ void CGameHandler::endBattle(int3 tile, const CGHeroInstance *hero1, const CGHer
|
|||||||
|
|
||||||
//Check how many battle queries were created (number of players blocked by battle)
|
//Check how many battle queries were created (number of players blocked by battle)
|
||||||
const int queriedPlayers = battleQuery ? boost::count(queries.allQueries(), battleQuery) : 0;
|
const int queriedPlayers = battleQuery ? boost::count(queries.allQueries(), battleQuery) : 0;
|
||||||
finishingBattle = make_unique<FinishingBattleHelper>(battleQuery, gs->initialOpts->mode == StartInfo::DUEL, queriedPlayers);
|
finishingBattle = make_unique<FinishingBattleHelper>(battleQuery, queriedPlayers);
|
||||||
|
|
||||||
|
|
||||||
CasualtiesAfterBattle cab1(bEndArmy1, gs->curB), cab2(bEndArmy2, gs->curB); //calculate casualties before deleting battle
|
CasualtiesAfterBattle cab1(bEndArmy1, gs->curB), cab2(bEndArmy2, gs->curB); //calculate casualties before deleting battle
|
||||||
|
|
||||||
if (finishingBattle->duel)
|
|
||||||
{
|
|
||||||
duelFinished();
|
|
||||||
sendAndApply(battleResult.data); //after this point casualties objects are destroyed
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
ChangeSpells cs; //for Eagle Eye
|
ChangeSpells cs; //for Eagle Eye
|
||||||
|
|
||||||
if (finishingBattle->winnerHero)
|
if (finishingBattle->winnerHero)
|
||||||
@ -1900,18 +1888,6 @@ void CGameHandler::run(bool resume)
|
|||||||
boost::thread(std::bind(&CGameHandler::handleConnection,this,pom,std::ref(*elem)));
|
boost::thread(std::bind(&CGameHandler::handleConnection,this,pom,std::ref(*elem)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gs->scenarioOps->mode == StartInfo::DUEL)
|
|
||||||
{
|
|
||||||
runBattle();
|
|
||||||
serverShuttingDown = true;
|
|
||||||
|
|
||||||
|
|
||||||
while(conns.size() && (*conns.begin())->isOpen())
|
|
||||||
boost::this_thread::sleep(boost::posix_time::milliseconds(5)); //give time client to close socket
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto playerTurnOrder = generatePlayerTurnOrder();
|
auto playerTurnOrder = generatePlayerTurnOrder();
|
||||||
|
|
||||||
while(!serverShuttingDown)
|
while(!serverShuttingDown)
|
||||||
@ -2730,11 +2706,6 @@ void CGameHandler::save(const std::string & filename)
|
|||||||
void CGameHandler::close()
|
void CGameHandler::close()
|
||||||
{
|
{
|
||||||
logGlobal->info("We have been requested to close.");
|
logGlobal->info("We have been requested to close.");
|
||||||
|
|
||||||
if (gs->initialOpts->mode == StartInfo::DUEL)
|
|
||||||
{
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
serverShuttingDown = true;
|
serverShuttingDown = true;
|
||||||
|
|
||||||
for (auto & elem : conns)
|
for (auto & elem : conns)
|
||||||
@ -6370,48 +6341,6 @@ bool CGameHandler::isVisitCoveredByAnotherQuery(const CGObjectInstance *obj, con
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameHandler::duelFinished()
|
|
||||||
{
|
|
||||||
auto si = getStartInfo();
|
|
||||||
auto getName = [&](int i){ return si->getIthPlayersSettings(gs->curB->sides.at(i).color).name; };
|
|
||||||
|
|
||||||
int casualtiesPoints = 0;
|
|
||||||
logGlobal->debug("Winner side %d\nWinner casualties:", (int)battleResult.data->winner);
|
|
||||||
|
|
||||||
for (auto & elem : battleResult.data->casualties[battleResult.data->winner])
|
|
||||||
{
|
|
||||||
const CCreature *c = VLC->creh->creatures[elem.first];
|
|
||||||
logGlobal->debug("\t* %d of %s", elem.second, c->namePl);
|
|
||||||
casualtiesPoints += c->AIValue * elem.second;
|
|
||||||
}
|
|
||||||
logGlobal->debug("Total casualties points: %d", casualtiesPoints);
|
|
||||||
|
|
||||||
|
|
||||||
time_t timeNow;
|
|
||||||
time(&timeNow);
|
|
||||||
|
|
||||||
std::ofstream out(cmdLineOptions["resultsFile"].as<std::string>(), std::ios::app);
|
|
||||||
if (out)
|
|
||||||
{
|
|
||||||
out << boost::format("%s\t%s\t%s\t%d\t%d\t%d\t%s\n") % si->mapname % getName(0) % getName(1)
|
|
||||||
% battleResult.data->winner % battleResult.data->result % casualtiesPoints
|
|
||||||
% asctime(localtime(&timeNow));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logGlobal->error("Cannot open to write %s", cmdLineOptions["resultsFile"].as<std::string>());
|
|
||||||
}
|
|
||||||
|
|
||||||
CSaveFile resultFile("result.vdrst");
|
|
||||||
resultFile << *battleResult.data;
|
|
||||||
|
|
||||||
BattleResultsApplied resultsApplied;
|
|
||||||
resultsApplied.player1 = finishingBattle->victor;
|
|
||||||
resultsApplied.player2 = finishingBattle->loser;
|
|
||||||
sendAndApply(&resultsApplied);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance * _army, BattleInfo *bat):
|
CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance * _army, BattleInfo *bat):
|
||||||
army(_army)
|
army(_army)
|
||||||
{
|
{
|
||||||
@ -6554,7 +6483,7 @@ void CasualtiesAfterBattle::updateArmy(CGameHandler *gh)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CGameHandler::FinishingBattleHelper::FinishingBattleHelper(std::shared_ptr<const CBattleQuery> Query, bool Duel, int RemainingBattleQueriesCount)
|
CGameHandler::FinishingBattleHelper::FinishingBattleHelper(std::shared_ptr<const CBattleQuery> Query, int RemainingBattleQueriesCount)
|
||||||
{
|
{
|
||||||
assert(Query->result);
|
assert(Query->result);
|
||||||
assert(Query->bi);
|
assert(Query->bi);
|
||||||
@ -6565,14 +6494,12 @@ CGameHandler::FinishingBattleHelper::FinishingBattleHelper(std::shared_ptr<const
|
|||||||
loserHero = result.winner != 0 ? info.sides[0].hero : info.sides[1].hero;
|
loserHero = result.winner != 0 ? info.sides[0].hero : info.sides[1].hero;
|
||||||
victor = info.sides[result.winner].color;
|
victor = info.sides[result.winner].color;
|
||||||
loser = info.sides[!result.winner].color;
|
loser = info.sides[!result.winner].color;
|
||||||
duel = Duel;
|
|
||||||
remainingBattleQueriesCount = RemainingBattleQueriesCount;
|
remainingBattleQueriesCount = RemainingBattleQueriesCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGameHandler::FinishingBattleHelper::FinishingBattleHelper()
|
CGameHandler::FinishingBattleHelper::FinishingBattleHelper()
|
||||||
{
|
{
|
||||||
winnerHero = loserHero = nullptr;
|
winnerHero = loserHero = nullptr;
|
||||||
duel = false;
|
|
||||||
remainingBattleQueriesCount = 0;
|
remainingBattleQueriesCount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +108,6 @@ public:
|
|||||||
void checkBattleStateChanges();
|
void checkBattleStateChanges();
|
||||||
void setupBattle(int3 tile, const CArmedInstance *armies[2], const CGHeroInstance *heroes[2], bool creatureBank, const CGTownInstance *town);
|
void setupBattle(int3 tile, const CArmedInstance *armies[2], const CGHeroInstance *heroes[2], bool creatureBank, const CGTownInstance *town);
|
||||||
void setBattleResult(BattleResult::EResult resultType, int victoriusSide);
|
void setBattleResult(BattleResult::EResult resultType, int victoriusSide);
|
||||||
void duelFinished();
|
|
||||||
|
|
||||||
CGameHandler(void);
|
CGameHandler(void);
|
||||||
~CGameHandler(void);
|
~CGameHandler(void);
|
||||||
@ -256,18 +255,23 @@ public:
|
|||||||
struct FinishingBattleHelper
|
struct FinishingBattleHelper
|
||||||
{
|
{
|
||||||
FinishingBattleHelper();
|
FinishingBattleHelper();
|
||||||
FinishingBattleHelper(std::shared_ptr<const CBattleQuery> Query, bool Duel, int RemainingBattleQueriesCount);
|
FinishingBattleHelper(std::shared_ptr<const CBattleQuery> Query, int RemainingBattleQueriesCount);
|
||||||
|
|
||||||
//std::shared_ptr<const CBattleQuery> query;
|
//std::shared_ptr<const CBattleQuery> query;
|
||||||
const CGHeroInstance *winnerHero, *loserHero;
|
const CGHeroInstance *winnerHero, *loserHero;
|
||||||
PlayerColor victor, loser;
|
PlayerColor victor, loser;
|
||||||
bool duel;
|
|
||||||
|
|
||||||
int remainingBattleQueriesCount;
|
int remainingBattleQueriesCount;
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & /*query & */winnerHero & loserHero & victor & loser & duel & remainingBattleQueriesCount;
|
h & /*query & */winnerHero & loserHero & victor & loser;
|
||||||
|
if(version < 774 && !h.saving)
|
||||||
|
{
|
||||||
|
bool duel;
|
||||||
|
h & duel;
|
||||||
|
}
|
||||||
|
h & remainingBattleQueriesCount;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -546,8 +546,7 @@ static void handleCommandOptions(int argc, char *argv[])
|
|||||||
("uuid", po::value<std::string>(), "")
|
("uuid", po::value<std::string>(), "")
|
||||||
("enable-shm-uuid", "use UUID for shared memory identifier")
|
("enable-shm-uuid", "use UUID for shared memory identifier")
|
||||||
("enable-shm", "enable usage of shared memory")
|
("enable-shm", "enable usage of shared memory")
|
||||||
("port", po::value<ui16>(), "port at which server will listen to connections from client")
|
("port", po::value<ui16>(), "port at which server will listen to connections from client");
|
||||||
("resultsFile", po::value<std::string>()->default_value("./results.txt"), "file to which the battle result will be appended. Used only in the DUEL mode.");
|
|
||||||
|
|
||||||
if(argc > 1)
|
if(argc > 1)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user