mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
- setting system: replaced settings.txt + sysopt.bin with json-based system (defaultSetting.json + settings.json)
- some work on system settings window - new menu for selecting resolution (reused town portal graphics), can be opened from system settings
This commit is contained in:
parent
046e54563c
commit
86e7d96b39
@ -244,7 +244,7 @@ void CDefenceAnimation::nextFrame()
|
||||
|
||||
if(!myAnim()->onLastFrameInGroup())
|
||||
{
|
||||
if( myAnim()->getType() == CCreatureAnim::DEATH && (owner->animCount+1)%(4/owner->curInt->sysOpts.animSpeed)==0
|
||||
if( myAnim()->getType() == CCreatureAnim::DEATH && (owner->animCount+1)%(4/owner->getAnimSpeed())==0
|
||||
&& !myAnim()->onLastFrameInGroup() )
|
||||
{
|
||||
myAnim()->incrementFrame();
|
||||
@ -625,7 +625,7 @@ void CMovementStartAnimation::nextFrame()
|
||||
}
|
||||
else
|
||||
{
|
||||
if((owner->animCount+1)%(4/owner->curInt->sysOpts.animSpeed)==0)
|
||||
if((owner->animCount+1)%(4/owner->getAnimSpeed())==0)
|
||||
myAnim()->incrementFrame();
|
||||
}
|
||||
}
|
||||
|
@ -117,7 +117,7 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
|
||||
queue = new CStackQueue(embedQueue, this);
|
||||
if(!embedQueue)
|
||||
{
|
||||
if(curInt->sysOpts.showQueue)
|
||||
if(settings["battle"]["showQueue"].Bool())
|
||||
pos.y += queue->pos.h / 2; //center whole window
|
||||
|
||||
queue->moveTo(Point(pos.x, pos.y - queue->pos.h));
|
||||
@ -423,24 +423,26 @@ CBattleInterface::~CBattleInterface()
|
||||
|
||||
void CBattleInterface::setPrintCellBorders(bool set)
|
||||
{
|
||||
curInt->sysOpts.printCellBorders = set;
|
||||
curInt->sysOpts.settingsChanged();
|
||||
Settings cellBorders = settings.write["battle"]["cellBorders"];
|
||||
cellBorders->Bool() = set;
|
||||
|
||||
redrawBackgroundWithHexes(activeStack);
|
||||
GH.totalRedraw();
|
||||
}
|
||||
|
||||
void CBattleInterface::setPrintStackRange(bool set)
|
||||
{
|
||||
curInt->sysOpts.printStackRange = set;
|
||||
curInt->sysOpts.settingsChanged();
|
||||
Settings stackRange = settings.write["battle"]["stackRange"];
|
||||
stackRange->Bool() = set;
|
||||
|
||||
redrawBackgroundWithHexes(activeStack);
|
||||
GH.totalRedraw();
|
||||
}
|
||||
|
||||
void CBattleInterface::setPrintMouseShadow(bool set)
|
||||
{
|
||||
curInt->sysOpts.printMouseShadow = set;
|
||||
curInt->sysOpts.settingsChanged();
|
||||
Settings shadow = settings.write["battle"]["mouseShadow"];
|
||||
shadow->Bool() = set;
|
||||
}
|
||||
|
||||
void CBattleInterface::activate()
|
||||
@ -463,7 +465,7 @@ void CBattleInterface::activate()
|
||||
attackingHero->activate();
|
||||
if(defendingHero)
|
||||
defendingHero->activate();
|
||||
if(curInt->sysOpts.showQueue)
|
||||
if(settings["battle"]["showQueue"].Bool())
|
||||
queue->activate();
|
||||
|
||||
if(tacticsMode)
|
||||
@ -500,7 +502,7 @@ void CBattleInterface::deactivate()
|
||||
attackingHero->deactivate();
|
||||
if(defendingHero)
|
||||
defendingHero->deactivate();
|
||||
if(curInt->sysOpts.showQueue)
|
||||
if(settings["battle"]["showQueue"].Bool())
|
||||
queue->deactivate();
|
||||
|
||||
if(tacticsMode)
|
||||
@ -537,7 +539,7 @@ void CBattleInterface::show(SDL_Surface * to)
|
||||
{
|
||||
//showing background
|
||||
blitAt(background, pos.x, pos.y, to);
|
||||
if(curInt->sysOpts.printCellBorders)
|
||||
if(settings["battle"]["cellBorders"].Bool())
|
||||
{
|
||||
CSDL_Ext::blit8bppAlphaTo24bpp(cellBorders, NULL, to, &pos);
|
||||
}
|
||||
@ -574,7 +576,7 @@ void CBattleInterface::show(SDL_Surface * to)
|
||||
std::set<ui16> shaded = spToCast.rangeInHexes(b, schoolLevel);
|
||||
for(std::set<ui16>::iterator it = shaded.begin(); it != shaded.end(); ++it) //for spells with range greater then one hex
|
||||
{
|
||||
if(curInt->sysOpts.printMouseShadow && (*it % GameConstants::BFIELD_WIDTH != 0) && (*it % GameConstants::BFIELD_WIDTH != 16))
|
||||
if(settings["battle"]["mouseShadow"].Bool() && (*it % GameConstants::BFIELD_WIDTH != 0) && (*it % GameConstants::BFIELD_WIDTH != 16))
|
||||
{
|
||||
int x = 14 + ((*it/GameConstants::BFIELD_WIDTH)%2==0 ? 22 : 0) + 44*(*it%GameConstants::BFIELD_WIDTH) + pos.x;
|
||||
int y = 86 + 42 * (*it/GameConstants::BFIELD_WIDTH) + pos.y;
|
||||
@ -583,7 +585,7 @@ void CBattleInterface::show(SDL_Surface * to)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(curInt->sysOpts.printMouseShadow) //when not casting spell
|
||||
else if(settings["battle"]["mouseShadow"].Bool()) //when not casting spell
|
||||
{//TODO: do not check it every frame
|
||||
if (activeStack) //highlight all attackable hexes
|
||||
{
|
||||
@ -830,7 +832,7 @@ void CBattleInterface::show(SDL_Surface * to)
|
||||
|
||||
Rect posWithQueue = Rect(pos.x, pos.y, 800, 600);
|
||||
|
||||
if(curInt->sysOpts.showQueue)
|
||||
if(settings["battle"]["showQueue"].Bool())
|
||||
{
|
||||
if(!queue->embedded)
|
||||
{
|
||||
@ -886,7 +888,7 @@ void CBattleInterface::showObstacles(std::multimap<BattleHex, int> *hexToObstacl
|
||||
int x = ((curOb.pos/GameConstants::BFIELD_WIDTH)%2==0 ? 22 : 0) + 44*(curOb.pos%GameConstants::BFIELD_WIDTH) + pos.x + shift.first;
|
||||
int y = 86 + 42 * (curOb.pos/GameConstants::BFIELD_WIDTH) + pos.y + shift.second;
|
||||
std::vector<Cimage> &images = idToObstacle[curOb.ID]->ourImages; //reference to animation of obstacle
|
||||
blitAt(images[((animCount+1)/(4/curInt->sysOpts.animSpeed))%images.size()].bitmap, x, y, to);
|
||||
blitAt(images[((animCount+1)/(4/getAnimSpeed()))%images.size()].bitmap, x, y, to);
|
||||
}
|
||||
}
|
||||
|
||||
@ -894,12 +896,11 @@ void CBattleInterface::keyPressed(const SDL_KeyboardEvent & key)
|
||||
{
|
||||
if(key.keysym.sym == SDLK_q && key.state == SDL_PRESSED)
|
||||
{
|
||||
if(curInt->sysOpts.showQueue) //hide queue
|
||||
if(settings["battle"]["showQueue"].Bool()) //hide queue
|
||||
hideQueue();
|
||||
else
|
||||
showQueue();
|
||||
|
||||
curInt->sysOpts.settingsChanged();
|
||||
}
|
||||
else if(key.keysym.sym == SDLK_ESCAPE && spellDestSelectMode)
|
||||
{
|
||||
@ -1459,7 +1460,7 @@ void CBattleInterface::bSpellf()
|
||||
chi = attackingHeroInstance;
|
||||
else
|
||||
chi = defendingHeroInstance;
|
||||
CSpellWindow * spellWindow = new CSpellWindow(genRect(595, 620, (conf.cc.resx - 620)/2, (conf.cc.resy - 595)/2), chi, curInt);
|
||||
CSpellWindow * spellWindow = new CSpellWindow(genRect(595, 620, (screen->w - 620)/2, (screen->h - 595)/2), chi, curInt);
|
||||
GH.pushInt(spellWindow);
|
||||
}
|
||||
|
||||
@ -2470,13 +2471,13 @@ void CBattleInterface::battleTriggerEffect(const BattleTriggerEffect & bte)
|
||||
|
||||
void CBattleInterface::setAnimSpeed(int set)
|
||||
{
|
||||
curInt->sysOpts.animSpeed = set;
|
||||
curInt->sysOpts.settingsChanged();
|
||||
Settings speed = settings.write["battle"]["animationSpeed"];
|
||||
speed->Float() = set;
|
||||
}
|
||||
|
||||
int CBattleInterface::getAnimSpeed() const
|
||||
{
|
||||
return curInt->sysOpts.animSpeed;
|
||||
return settings["battle"]["animationSpeed"].Float();
|
||||
}
|
||||
|
||||
void CBattleInterface::activateStack()
|
||||
@ -2519,7 +2520,7 @@ void CBattleInterface::activateStack()
|
||||
|
||||
double CBattleInterface::getAnimSpeedMultiplier() const
|
||||
{
|
||||
switch(curInt->sysOpts.animSpeed)
|
||||
switch(getAnimSpeed())
|
||||
{
|
||||
case 1:
|
||||
return 3.5;
|
||||
@ -2552,7 +2553,7 @@ void CBattleInterface::showAliveStack(const CStack *stack, SDL_Surface * to)
|
||||
|
||||
int animType = creAnims[ID]->getType();
|
||||
|
||||
int affectingSpeed = curInt->sysOpts.animSpeed;
|
||||
int affectingSpeed = getAnimSpeed();
|
||||
if(animType == 1 || animType == 2) //standing stacks should not stand faster :)
|
||||
affectingSpeed = 2;
|
||||
bool incrementFrame = (animCount%(4/affectingSpeed)==0) && animType!=5 && animType!=20 && animType!=2;
|
||||
@ -2744,13 +2745,13 @@ void CBattleInterface::redrawBackgroundWithHexes(const CStack * activeStack)
|
||||
attackableHexes.clear();
|
||||
if (activeStack)
|
||||
occupyableHexes = curInt->cb->battleGetAvailableHexes(activeStack, true, &attackableHexes);
|
||||
curInt->cb->battleGetStackCountOutsideHexes(stackCountOutsideHexes);
|
||||
curInt->cb->battleGetStackCountOutsideHexes(stackCountOutsideHexes);
|
||||
//preparating background graphic with hexes and shaded hexes
|
||||
blitAt(background, 0, 0, backgroundWithHexes);
|
||||
if(curInt->sysOpts.printCellBorders)
|
||||
if(settings["battle"]["cellBorders"].Bool())
|
||||
CSDL_Ext::blit8bppAlphaTo24bpp(cellBorders, NULL, backgroundWithHexes, NULL);
|
||||
|
||||
if(curInt->sysOpts.printStackRange)
|
||||
if(settings["battle"]["stackRange"].Bool())
|
||||
{
|
||||
std::vector<BattleHex> hexesToShade = occupyableHexes;
|
||||
hexesToShade.insert(hexesToShade.end(), attackableHexes.begin(), attackableHexes.end());
|
||||
@ -2914,7 +2915,8 @@ void CBattleInterface::endAction(const BattleAction* action)
|
||||
|
||||
void CBattleInterface::hideQueue()
|
||||
{
|
||||
curInt->sysOpts.showQueue = false;
|
||||
Settings showQueue = settings.write["battle"]["showQueue"];
|
||||
showQueue->Bool() = false;
|
||||
|
||||
queue->deactivate();
|
||||
|
||||
@ -2927,7 +2929,8 @@ void CBattleInterface::hideQueue()
|
||||
|
||||
void CBattleInterface::showQueue()
|
||||
{
|
||||
curInt->sysOpts.showQueue = true;
|
||||
Settings showQueue = settings.write["battle"]["showQueue"];
|
||||
showQueue->Bool() = true;
|
||||
|
||||
queue->activate();
|
||||
|
||||
|
@ -204,7 +204,7 @@ void CBattleHero::clickLeft(tribool down, bool previousState)
|
||||
}
|
||||
CCS->curh->changeGraphic(0,0);
|
||||
|
||||
CSpellWindow * spellWindow = new CSpellWindow(genRect(595, 620, (conf.cc.resx - 620)/2, (conf.cc.resy - 595)/2), myHero, myOwner->curInt);
|
||||
CSpellWindow * spellWindow = new CSpellWindow(genRect(595, 620, (screen->w - 620)/2, (screen->h - 595)/2), myHero, myOwner->curInt);
|
||||
GH.pushInt(spellWindow);
|
||||
}
|
||||
}
|
||||
@ -250,11 +250,11 @@ CBattleOptionsWindow::CBattleOptionsWindow(const SDL_Rect & position, CBattleInt
|
||||
background->colorize(owner->curInt->playerID);
|
||||
|
||||
viewGrid = new CHighlightableButton(boost::bind(&CBattleInterface::setPrintCellBorders, owner, true), boost::bind(&CBattleInterface::setPrintCellBorders, owner, false), boost::assign::map_list_of(0,CGI->generaltexth->zelp[427].first)(3,CGI->generaltexth->zelp[427].first), CGI->generaltexth->zelp[427].second, false, "sysopchk.def", NULL, 25, 56, false);
|
||||
viewGrid->select(owner->curInt->sysOpts.printCellBorders);
|
||||
viewGrid->select(settings["battle"]["cellBorders"].Bool());
|
||||
movementShadow = new CHighlightableButton(boost::bind(&CBattleInterface::setPrintStackRange, owner, true), boost::bind(&CBattleInterface::setPrintStackRange, owner, false), boost::assign::map_list_of(0,CGI->generaltexth->zelp[428].first)(3,CGI->generaltexth->zelp[428].first), CGI->generaltexth->zelp[428].second, false, "sysopchk.def", NULL, 25, 89, false);
|
||||
movementShadow->select(owner->curInt->sysOpts.printStackRange);
|
||||
movementShadow->select(settings["battle"]["stackRange"].Bool());
|
||||
mouseShadow = new CHighlightableButton(boost::bind(&CBattleInterface::setPrintMouseShadow, owner, true), boost::bind(&CBattleInterface::setPrintMouseShadow, owner, false), boost::assign::map_list_of(0,CGI->generaltexth->zelp[429].first)(3,CGI->generaltexth->zelp[429].first), CGI->generaltexth->zelp[429].second, false, "sysopchk.def", NULL, 25, 122, false);
|
||||
mouseShadow->select(owner->curInt->sysOpts.printMouseShadow);
|
||||
mouseShadow->select(settings["battle"]["mouseShadow"].Bool());
|
||||
|
||||
animSpeeds = new CHighlightableButtonsGroup(0);
|
||||
animSpeeds->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[422].first),CGI->generaltexth->zelp[422].second, "sysopb9.def", 28, 225, 1);
|
||||
|
@ -350,11 +350,11 @@ void CMinimapSurfacesRef::free()
|
||||
for (int g = 0; g < map_.size(); ++g)
|
||||
SDL_FreeSurface(map_[g]);
|
||||
map_.clear();
|
||||
|
||||
|
||||
for (int g = 0; g < FoW_.size(); ++g)
|
||||
SDL_FreeSurface(FoW_[g]);
|
||||
FoW_.clear();
|
||||
|
||||
|
||||
for (int g = 0; g < flObjs_.size(); ++g)
|
||||
SDL_FreeSurface(flObjs_[g]);
|
||||
flObjs_.clear();
|
||||
@ -396,7 +396,7 @@ void CMinimap::showTile(const int3 &pos)
|
||||
{
|
||||
int3 maplgp ( (pos.x*mw)/mapSizes.x, (pos.y*mh)/mapSizes.y, pos.z );
|
||||
if(((int)wo) * mapSizes.x != mw && pos.x+1 < mapSizes.x)//minimap size in X is not multiple of map size in X
|
||||
|
||||
|
||||
{
|
||||
std::vector < const CGObjectInstance * > op1x = LOCPLINT->cb->getFlaggableObjects(int3(pos.x+1, pos.y, pos.z));
|
||||
if(op1x.size()!=0)
|
||||
@ -588,7 +588,7 @@ void CTerrainRect::showPath(const SDL_Rect * extRect, SDL_Surface * to)
|
||||
|
||||
/* Vector directions
|
||||
* 0 1 2
|
||||
* \ | /
|
||||
* \ | /
|
||||
* 3 - 4 - 5
|
||||
* / | \
|
||||
* 6 7 8
|
||||
@ -597,7 +597,7 @@ void CTerrainRect::showPath(const SDL_Rect * extRect, SDL_Surface * to)
|
||||
* |__\
|
||||
* /
|
||||
* is id1=7, id2=5 (pns[7][5])
|
||||
*/
|
||||
*/
|
||||
bool pathContinuous = curPos.areNeighbours(nextPos) && curPos.areNeighbours(prevPos);
|
||||
if(pathContinuous && cv[i].land == cv[i+1].land)
|
||||
{
|
||||
@ -695,7 +695,7 @@ void CTerrainRect::show(SDL_Surface * to)
|
||||
(adventureInt->position, adventureInt->anim,
|
||||
&LOCPLINT->cb->getVisibilityMap(), true, adventureInt->heroAnim,
|
||||
to, &pos, 0, 0, false, int3());
|
||||
|
||||
|
||||
//SDL_BlitSurface(teren,&genRect(pos.h,pos.w,0,0),screen,&genRect(547,594,7,6));
|
||||
//SDL_FreeSurface(teren);
|
||||
if (currentPath/* && adventureInt->position.z==currentPath->startPos().z*/) //drawing path
|
||||
@ -742,7 +742,7 @@ CResDataBar::CResDataBar(const std::string &defname, int x, int y, int offx, int
|
||||
txtpos[i].second = pos.y + offy;
|
||||
}
|
||||
txtpos[7].first = txtpos[6].first + datedist;
|
||||
datetext = CGI->generaltexth->allTexts[62]+": %s, " + CGI->generaltexth->allTexts[63]
|
||||
datetext = CGI->generaltexth->allTexts[62]+": %s, " + CGI->generaltexth->allTexts[63]
|
||||
+ ": %s, " + CGI->generaltexth->allTexts[64] + ": %s";
|
||||
}
|
||||
CResDataBar::CResDataBar()
|
||||
@ -759,7 +759,7 @@ CResDataBar::CResDataBar()
|
||||
txtpos[i].second = pos.y + ADVOPT.resOffsetY;
|
||||
}
|
||||
txtpos[7].first = txtpos[6].first + ADVOPT.resDateDist;
|
||||
datetext = CGI->generaltexth->allTexts[62]+": %s, " + CGI->generaltexth->allTexts[63]
|
||||
datetext = CGI->generaltexth->allTexts[62]+": %s, " + CGI->generaltexth->allTexts[63]
|
||||
+ ": %s, " + CGI->generaltexth->allTexts[64] + ": %s";
|
||||
}
|
||||
|
||||
@ -1098,14 +1098,14 @@ void CAdvMapInt::fsleepWake()
|
||||
{
|
||||
fnextHero();
|
||||
|
||||
//moveHero.block(true);
|
||||
//moveHero.block(true);
|
||||
//uncomment to enable original HoMM3 behaviour:
|
||||
//move button is disabled for hero going to sleep, even though it's enabled when you reselect him
|
||||
}
|
||||
}
|
||||
|
||||
void CAdvMapInt::fmoveHero()
|
||||
{
|
||||
{
|
||||
const CGHeroInstance *h = curHero();
|
||||
if (!h || !terrain.currentPath)
|
||||
return;
|
||||
@ -1119,7 +1119,8 @@ void CAdvMapInt::fshowSpellbok()
|
||||
return;
|
||||
|
||||
centerOn(selection);
|
||||
CSpellWindow * spellWindow = new CSpellWindow(genRect(595, 620, (conf.cc.resx - 620)/2, (conf.cc.resy - 595)/2), curHero(), LOCPLINT, false);
|
||||
|
||||
CSpellWindow * spellWindow = new CSpellWindow(genRect(595, 620, (screen->w - 620)/2, (screen->h - 595)/2), curHero(), LOCPLINT, false);
|
||||
GH.pushInt(spellWindow);
|
||||
}
|
||||
|
||||
@ -1147,12 +1148,15 @@ void CAdvMapInt::fendTurn()
|
||||
if(!LOCPLINT->makingTurn)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < LOCPLINT->wanderingHeroes.size(); i++)
|
||||
if (!isHeroSleeping(LOCPLINT->wanderingHeroes[i]) && (LOCPLINT->wanderingHeroes[i]->movement > 0))
|
||||
{
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[55], std::vector<CComponent*>(), boost::bind(&CAdvMapInt::endingTurn, this), 0, false);
|
||||
return;
|
||||
}
|
||||
if ( settings["adventure"]["heroReminder"].Bool())
|
||||
{
|
||||
for (int i = 0; i < LOCPLINT->wanderingHeroes.size(); i++)
|
||||
if (!isHeroSleeping(LOCPLINT->wanderingHeroes[i]) && (LOCPLINT->wanderingHeroes[i]->movement > 0))
|
||||
{
|
||||
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[55], std::vector<CComponent*>(), boost::bind(&CAdvMapInt::endingTurn, this), 0, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
endingTurn();
|
||||
}
|
||||
|
||||
@ -1160,7 +1164,7 @@ void CAdvMapInt::updateSleepWake(const CGHeroInstance *h)
|
||||
{
|
||||
sleepWake.block(!h);
|
||||
if (!h)
|
||||
return;
|
||||
return;
|
||||
bool state = isHeroSleeping(h);
|
||||
sleepWake.setIndex(state ? 1 : 0, true);
|
||||
sleepWake.assignedKeys.clear();
|
||||
@ -1171,11 +1175,11 @@ void CAdvMapInt::updateSleepWake(const CGHeroInstance *h)
|
||||
void CAdvMapInt::updateMoveHero(const CGHeroInstance *h, tribool hasPath)
|
||||
{
|
||||
//default value is for everywhere but CPlayerInterface::moveHero, because paths are not updated from there immediately
|
||||
if (hasPath == tribool::indeterminate_value)
|
||||
if (hasPath == tribool::indeterminate_value)
|
||||
hasPath = LOCPLINT->paths[h].nodes.size() ? true : false;
|
||||
if (!h)
|
||||
{
|
||||
moveHero.block(true);
|
||||
moveHero.block(true);
|
||||
return;
|
||||
}
|
||||
moveHero.block(!hasPath || (h->movement == 0));
|
||||
@ -1188,12 +1192,12 @@ int CAdvMapInt::getNextHeroIndex(int startIndex)
|
||||
if (startIndex < 0)
|
||||
startIndex = 0;
|
||||
int i = startIndex;
|
||||
do
|
||||
do
|
||||
{
|
||||
i++;
|
||||
if (i >= LOCPLINT->wanderingHeroes.size())
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
while (((LOCPLINT->wanderingHeroes[i]->movement == 0) || isHeroSleeping(LOCPLINT->wanderingHeroes[i])) && (i != startIndex));
|
||||
|
||||
if ((LOCPLINT->wanderingHeroes[i]->movement != 0) && !isHeroSleeping(LOCPLINT->wanderingHeroes[i]))
|
||||
@ -1204,7 +1208,7 @@ int CAdvMapInt::getNextHeroIndex(int startIndex)
|
||||
|
||||
void CAdvMapInt::updateNextHero(const CGHeroInstance *h)
|
||||
{
|
||||
int start = heroList.getPosOfHero(h);
|
||||
int start = heroList.getPosOfHero(h);
|
||||
int next = getNextHeroIndex(start);
|
||||
if (next < 0)
|
||||
{
|
||||
@ -1338,11 +1342,12 @@ void CAdvMapInt::show(SDL_Surface * to)
|
||||
}
|
||||
++heroAnim;
|
||||
|
||||
int scrollSpeed = settings["adventure"]["scrollSpeed"].Float();
|
||||
//if advmap needs updating AND (no dialog is shown OR ctrl is pressed)
|
||||
if((animValHitCount % (4/LOCPLINT->sysOpts.mapScrollingSpeed)) == 0
|
||||
if((animValHitCount % (4/scrollSpeed)) == 0
|
||||
&& (
|
||||
(GH.topInt() == this)
|
||||
|| SDL_GetKeyState(NULL)[SDLK_LCTRL]
|
||||
|| SDL_GetKeyState(NULL)[SDLK_LCTRL]
|
||||
|| SDL_GetKeyState(NULL)[SDLK_RCTRL]
|
||||
)
|
||||
)
|
||||
@ -1370,7 +1375,7 @@ void CAdvMapInt::show(SDL_Surface * to)
|
||||
terrain.show(to);
|
||||
for(int i=0;i<4;i++)
|
||||
blitAt(gems[i]->ourImages[LOCPLINT->playerID].bitmap,ADVOPT.gemX[i],ADVOPT.gemY[i],to);
|
||||
updateScreen=false;
|
||||
updateScreen=false;
|
||||
LOCPLINT->cingconsole->show(to);
|
||||
}
|
||||
if (updateMinimap)
|
||||
@ -1389,13 +1394,13 @@ void CAdvMapInt::centerOn(int3 on)
|
||||
{
|
||||
on.x -= CGI->mh->frameW;
|
||||
on.y -= CGI->mh->frameH;
|
||||
|
||||
|
||||
on = LOCPLINT->repairScreenPos(on);
|
||||
|
||||
adventureInt->position = on;
|
||||
adventureInt->updateScreen=true;
|
||||
updateMinimap=true;
|
||||
underground.setIndex(on.z,true); //change underground switch button image
|
||||
underground.setIndex(on.z,true); //change underground switch button image
|
||||
if(GH.topInt() == this)
|
||||
underground.redraw();
|
||||
}
|
||||
@ -1415,27 +1420,27 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
|
||||
switch(k)
|
||||
{
|
||||
case SDLK_i:
|
||||
case SDLK_i:
|
||||
if(isActive())
|
||||
CAdventureOptions::showScenarioInfo();
|
||||
return;
|
||||
case SDLK_s:
|
||||
case SDLK_s:
|
||||
if(isActive())
|
||||
GH.pushInt(new CSavingScreen(CPlayerInterface::howManyPeople > 1));
|
||||
return;
|
||||
case SDLK_d:
|
||||
case SDLK_d:
|
||||
{
|
||||
if(h && isActive() && key.state == SDL_PRESSED)
|
||||
LOCPLINT->tryDiggging(h);
|
||||
return;
|
||||
}
|
||||
case SDLK_p:
|
||||
case SDLK_p:
|
||||
if(isActive())
|
||||
LOCPLINT->showPuzzleMap();
|
||||
return;
|
||||
case SDLK_SPACE: //space - try to revisit current object with selected hero
|
||||
{
|
||||
if(!isActive())
|
||||
if(!isActive())
|
||||
return;
|
||||
if(h && key.state == SDL_PRESSED)
|
||||
{
|
||||
@ -1447,7 +1452,7 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
return;
|
||||
case SDLK_RETURN:
|
||||
{
|
||||
if(!isActive() || !selection || key.state != SDL_PRESSED)
|
||||
if(!isActive() || !selection || key.state != SDL_PRESSED)
|
||||
return;
|
||||
if(h)
|
||||
LOCPLINT->openHeroWindow(h);
|
||||
@ -1457,7 +1462,7 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
}
|
||||
case SDLK_ESCAPE:
|
||||
{
|
||||
if(isActive() || GH.topInt() != this || !spellBeingCasted || key.state != SDL_PRESSED)
|
||||
if(isActive() || GH.topInt() != this || !spellBeingCasted || key.state != SDL_PRESSED)
|
||||
return;
|
||||
|
||||
leaveCastingMode();
|
||||
@ -1480,12 +1485,12 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
}
|
||||
|
||||
if(townWithMarket) //if any town has marketplace, open window
|
||||
GH.pushInt(new CMarketplaceWindow(townWithMarket));
|
||||
GH.pushInt(new CMarketplaceWindow(townWithMarket));
|
||||
else //if not - complain
|
||||
LOCPLINT->showInfoDialog("No available marketplace!", std::vector<CComponent*>(), soundBase::sound_todo);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
default:
|
||||
{
|
||||
static const int3 directions[] = { int3(-1, +1, 0), int3(0, +1, 0), int3(+1, +1, 0),
|
||||
int3(-1, 0, 0), int3(0, 0, 0), int3(+1, 0, 0),
|
||||
@ -1496,16 +1501,16 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
{
|
||||
switch(k)
|
||||
{
|
||||
case SDLK_UP:
|
||||
case SDLK_UP:
|
||||
Dir = UP;
|
||||
break;
|
||||
case SDLK_LEFT:
|
||||
case SDLK_LEFT:
|
||||
Dir = LEFT;
|
||||
break;
|
||||
case SDLK_RIGHT:
|
||||
case SDLK_RIGHT:
|
||||
Dir = RIGHT;
|
||||
break;
|
||||
case SDLK_DOWN:
|
||||
case SDLK_DOWN:
|
||||
Dir = DOWN;
|
||||
break;
|
||||
}
|
||||
@ -1520,7 +1525,7 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
if(k < 0 || k > 8 || key.state != SDL_PRESSED)
|
||||
return;
|
||||
|
||||
if(!h)
|
||||
if(!h)
|
||||
break;
|
||||
|
||||
if(k == 4)
|
||||
@ -1720,7 +1725,7 @@ void CAdvMapInt::tileLClicked(const int3 &mp)
|
||||
|
||||
switch(spellBeingCasted->id)
|
||||
{
|
||||
case Spells::SCUTTLE_BOAT: //Scuttle Boat
|
||||
case Spells::SCUTTLE_BOAT: //Scuttle Boat
|
||||
if(topBlocking && topBlocking->ID == 8)
|
||||
leaveCastingMode(true, mp);
|
||||
break;
|
||||
@ -1769,7 +1774,7 @@ void CAdvMapInt::tileLClicked(const int3 &mp)
|
||||
CGPath &path = LOCPLINT->paths[currentHero];
|
||||
terrain.currentPath = &path;
|
||||
bool gotPath = LOCPLINT->cb->getPath2(mp, path); //try getting path, erase if failed
|
||||
updateMoveHero(currentHero);
|
||||
updateMoveHero(currentHero);
|
||||
if (!gotPath)
|
||||
LOCPLINT->eraseCurrentPathOf(currentHero);
|
||||
else
|
||||
@ -1811,7 +1816,7 @@ void CAdvMapInt::tileHovered(const int3 &tile)
|
||||
}
|
||||
|
||||
const CGPathNode *pnode = LOCPLINT->cb->getPathInfo(tile);
|
||||
std::vector<const CGObjectInstance *> objs = LOCPLINT->cb->getBlockingObjs(tile);
|
||||
std::vector<const CGObjectInstance *> objs = LOCPLINT->cb->getBlockingObjs(tile);
|
||||
const CGObjectInstance *objAtTile = objs.size() ? objs.back() : NULL;
|
||||
bool accessible = pnode->turns < 255;
|
||||
|
||||
@ -1885,7 +1890,7 @@ void CAdvMapInt::tileHovered(const int3 &tile)
|
||||
{
|
||||
if(!LOCPLINT->cb->getPlayerRelations( LOCPLINT->playerID, objAtTile->tempOwner)) //enemy town
|
||||
{
|
||||
if(accessible)
|
||||
if(accessible)
|
||||
{
|
||||
const CGTownInstance* townObj = dynamic_cast<const CGTownInstance*>(objAtTile);
|
||||
|
||||
@ -1895,8 +1900,8 @@ void CAdvMapInt::tileHovered(const int3 &tile)
|
||||
else
|
||||
CCS->curh->changeGraphic(0, 5 + turns*6);
|
||||
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
{
|
||||
CCS->curh->changeGraphic(0, 0);
|
||||
}
|
||||
@ -1918,18 +1923,18 @@ void CAdvMapInt::tileHovered(const int3 &tile)
|
||||
}
|
||||
else if (objAtTile->ID == 33 || objAtTile->ID == 219) // Garrison
|
||||
{
|
||||
if (accessible)
|
||||
if (accessible)
|
||||
{
|
||||
const CGGarrison* garrObj = dynamic_cast<const CGGarrison*>(objAtTile); //TODO evil evil cast!
|
||||
|
||||
// Show battle cursor for guarded enemy garrisons, otherwise movement cursor.
|
||||
if (garrObj && garrObj->stacksCount()
|
||||
if (garrObj && garrObj->stacksCount()
|
||||
&& !LOCPLINT->cb->getPlayerRelations( LOCPLINT->playerID, garrObj->tempOwner) )
|
||||
CCS->curh->changeGraphic(0, 5 + turns*6);
|
||||
else
|
||||
CCS->curh->changeGraphic(0, 9 + turns*6);
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
CCS->curh->changeGraphic(0, 0);
|
||||
}
|
||||
else if (guardingCreature && accessible) //(objAtTile->ID == 54) //monster
|
||||
@ -1948,15 +1953,15 @@ void CAdvMapInt::tileHovered(const int3 &tile)
|
||||
else
|
||||
CCS->curh->changeGraphic(0, 0);
|
||||
}
|
||||
}
|
||||
else //no objs
|
||||
}
|
||||
else //no objs
|
||||
{
|
||||
if(accessible/* && pnode->accessible != CGPathNode::FLYABLE*/)
|
||||
{
|
||||
if (guardingCreature)
|
||||
if (guardingCreature)
|
||||
{
|
||||
CCS->curh->changeGraphic(0, 5 + turns*6);
|
||||
} else
|
||||
} else
|
||||
{
|
||||
if(pnode->land)
|
||||
{
|
||||
@ -1994,11 +1999,11 @@ void CAdvMapInt::tileRClicked(const int3 &mp)
|
||||
}
|
||||
|
||||
std::vector < const CGObjectInstance * > objs = LOCPLINT->cb->getBlockingObjs(mp);
|
||||
if(!objs.size())
|
||||
if(!objs.size())
|
||||
{
|
||||
// Bare or undiscovered terrain
|
||||
const TerrainTile * tile = LOCPLINT->cb->getTile(mp);
|
||||
if (tile)
|
||||
if (tile)
|
||||
{
|
||||
std::string hlp;
|
||||
CGI->mh->getTerrainDescr(mp, hlp, true);
|
||||
@ -2032,7 +2037,7 @@ void CAdvMapInt::leaveCastingMode(bool cast /*= false*/, int3 dest /*= int3(-1,
|
||||
|
||||
if(cast)
|
||||
LOCPLINT->cb->castSpell(curHero(), id, dest);
|
||||
else
|
||||
else
|
||||
LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[731]); //Spell cancelled
|
||||
}
|
||||
|
||||
|
@ -1,22 +1,11 @@
|
||||
#include "StdInc.h"
|
||||
#include <boost/version.hpp>
|
||||
#include "StdInc.h"
|
||||
#include "CConfigHandler.h"
|
||||
|
||||
#include "../lib/JsonNode.h"
|
||||
#include "../lib/GameConstants.h"
|
||||
#include "../lib/GameConstants.h"
|
||||
#include "../lib/VCMIDirs.h"
|
||||
|
||||
using namespace config;
|
||||
|
||||
#if BOOST_VERSION >= 103800
|
||||
#include <boost/spirit/include/classic.hpp>
|
||||
using namespace boost::spirit::classic;
|
||||
#else
|
||||
#include <boost/spirit.hpp>
|
||||
using namespace boost::spirit;
|
||||
#endif
|
||||
|
||||
using namespace phoenix;
|
||||
|
||||
/*
|
||||
* CConfigHandler.cpp, part of VCMI engine
|
||||
*
|
||||
@ -26,91 +15,150 @@ using namespace phoenix;
|
||||
* Full text of license available in license.txt file, in main folder
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
SettingsStorage settings;
|
||||
CConfigHandler conf;
|
||||
|
||||
struct lerror
|
||||
|
||||
template<typename Accessor>
|
||||
SettingsStorage::NodeAccessor<Accessor>::NodeAccessor(SettingsStorage & _parent, std::vector<std::string> _path):
|
||||
parent(_parent),
|
||||
path(_path)
|
||||
{
|
||||
std::string txt;
|
||||
lerror(const std::string & TXT):txt(TXT){};
|
||||
void operator()() const
|
||||
{
|
||||
tlog1 << txt << std::endl;
|
||||
}
|
||||
template<typename IteratorT>
|
||||
void operator()(IteratorT t1, IteratorT t2) const
|
||||
{
|
||||
tlog1 << txt << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
struct lerror2
|
||||
}
|
||||
|
||||
template<typename Accessor>
|
||||
SettingsStorage::NodeAccessor<Accessor> SettingsStorage::NodeAccessor<Accessor>::operator [](std::string nextNode) const
|
||||
{
|
||||
std::string txt;
|
||||
lerror2(const std::string & TXT):txt(TXT){};
|
||||
template<typename IteratorT>
|
||||
void operator()(IteratorT t1, IteratorT t2) const
|
||||
{
|
||||
std::string txt2(t1,t2);
|
||||
tlog1 << txt << txt2 << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
struct SettingsGrammar : public grammar<SettingsGrammar>
|
||||
std::vector<std::string> newPath = path;
|
||||
newPath.push_back(nextNode);
|
||||
return NodeAccessor(parent, newPath);
|
||||
}
|
||||
|
||||
template<typename Accessor>
|
||||
SettingsStorage::NodeAccessor<Accessor>::operator Accessor() const
|
||||
{
|
||||
template <typename ScannerT>
|
||||
struct definition
|
||||
{
|
||||
rule<ScannerT> r, clientOption, clientOptionsSequence, ClientSettings;
|
||||
return Accessor(parent, path);
|
||||
}
|
||||
|
||||
template<typename Accessor>
|
||||
SettingsStorage::NodeAccessor<Accessor> SettingsStorage::NodeAccessor<Accessor>::operator () (std::vector<std::string> _path)
|
||||
{
|
||||
std::vector<std::string> newPath = path;
|
||||
newPath.insert( newPath.end(), _path.begin(), _path.end());
|
||||
return NodeAccessor(parent, newPath);
|
||||
}
|
||||
|
||||
definition(SettingsGrammar const& self)
|
||||
{
|
||||
clientOption
|
||||
= str_p("resolution=") >> (uint_p[assign_a(conf.cc.resx)] >> 'x' >> uint_p[assign_a(conf.cc.resy)] | eps_p[lerror("Wrong resolution!")])
|
||||
| str_p("pregameRes=") >> (uint_p[assign_a(conf.cc.pregameResx)] >> 'x' >> uint_p[assign_a(conf.cc.pregameResy)] | eps_p[lerror("Wrong pregame size!")])
|
||||
| str_p("screenSize=") >> (uint_p[assign_a(conf.cc.screenx)] >> 'x' >> uint_p[assign_a(conf.cc.screeny)] | eps_p[lerror("Wrong screen size!")])
|
||||
| str_p("port=") >> (uint_p[assign_a(conf.cc.port)] | eps_p[lerror("Wrong port!")])
|
||||
| str_p("bpp=") >> (uint_p[assign_a(conf.cc.bpp)] | eps_p[lerror("Wrong bpp!")])
|
||||
| str_p("localInformation=") >> (uint_p[assign_a(conf.cc.localInformation)] | eps_p[lerror("Wrong localInformation!")])
|
||||
| str_p("fullscreen=") >> (uint_p[assign_a(conf.cc.fullscreen)] | eps_p[lerror("Wrong fullscreen!")])
|
||||
| str_p("server=") >> ( ( +digit_p >> *('.' >> +digit_p) )[assign_a(conf.cc.server)] | eps_p[lerror("Wrong server!")])
|
||||
| str_p("defaultPlayerAI=") >> ((+(anychar_p - ';'))[assign_a(conf.cc.defaultPlayerAI)] | eps_p[lerror("Wrong defaultAI!")])
|
||||
| str_p("neutralBattleAI=") >> ((+(anychar_p - ';'))[assign_a(conf.cc.defaultBattleAI)] | eps_p[lerror("Wrong defaultAI!")])
|
||||
| str_p("showFPS=") >> (uint_p[assign_a(conf.cc.showFPS)] | eps_p[lerror("Wrong showFPS!")])
|
||||
| str_p("classicCreatureWindow=") >> (uint_p[assign_a(conf.cc.classicCreatureWindow)] | eps_p[lerror("Wrong classicCreatureWindow!")])
|
||||
| (+(anychar_p - '}'))[lerror2("Unrecognized client option: ")]
|
||||
;
|
||||
clientOptionsSequence = *(clientOption >> (';' | eps_p[lerror("Semicolon lacking after client option!")]));
|
||||
ClientSettings = '{' >> clientOptionsSequence >> '}';
|
||||
|
||||
r = str_p("clientSettings") >> (ClientSettings | eps_p[lerror("Wrong clientSettings!")]);
|
||||
|
||||
#ifdef BOOST_SPIRIT_DEBUG
|
||||
BOOST_SPIRIT_DEBUG_RULE(clientOption);
|
||||
BOOST_SPIRIT_DEBUG_RULE(clientOptionsSequence);
|
||||
BOOST_SPIRIT_DEBUG_RULE(ClientSettings);
|
||||
BOOST_SPIRIT_DEBUG_RULE(r);
|
||||
#endif
|
||||
}
|
||||
|
||||
rule<ScannerT> const& start() const { return r; }
|
||||
};
|
||||
};
|
||||
|
||||
struct CommentsGrammar : public grammar<CommentsGrammar>
|
||||
SettingsStorage::SettingsStorage():
|
||||
write(NodeAccessor<Settings>(*this, std::vector<std::string>() )),
|
||||
listen(NodeAccessor<SettingsListener>(*this, std::vector<std::string>() ))
|
||||
{
|
||||
template <typename ScannerT>
|
||||
struct definition
|
||||
{
|
||||
rule<ScannerT> comment;
|
||||
definition(CommentsGrammar const& self)
|
||||
{
|
||||
comment = comment_p("//") | comment_p("/*","*/") | space_p;
|
||||
BOOST_SPIRIT_DEBUG_RULE(comment);
|
||||
}
|
||||
rule<ScannerT> const& start() const { return comment; }
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
void SettingsStorage::init()
|
||||
{
|
||||
JsonNode(GVCMIDirs.UserPath + "/config/settings.json").swap(config);
|
||||
JsonNode schema(GameConstants::DATA_DIR + "/config/defaultSettings.json");
|
||||
config.validate(schema);
|
||||
}
|
||||
|
||||
void SettingsStorage::invalidateNode(const std::vector<std::string> &changedPath)
|
||||
{
|
||||
BOOST_FOREACH(SettingsListener * listener, listeners)
|
||||
listener->nodeInvalidated(changedPath);
|
||||
|
||||
JsonNode savedConf = config;
|
||||
JsonNode schema(GameConstants::DATA_DIR + "/config/defaultSettings.json");
|
||||
|
||||
savedConf.Struct().erase("session");
|
||||
savedConf.minimize(schema);
|
||||
std::ofstream file((GVCMIDirs.UserPath + "/config/settings.json").c_str(), std::ofstream::trunc | std::ofstream::out);
|
||||
file << savedConf;
|
||||
}
|
||||
|
||||
JsonNode & SettingsStorage::getNode(std::vector<std::string> path)
|
||||
{
|
||||
JsonNode *node = &config;
|
||||
BOOST_FOREACH(std::string& value, path)
|
||||
node = &(*node)[value];
|
||||
|
||||
return *node;
|
||||
}
|
||||
|
||||
Settings SettingsStorage::get(std::vector<std::string> path)
|
||||
{
|
||||
return Settings(*this, path);
|
||||
}
|
||||
|
||||
const JsonNode& SettingsStorage::operator [](std::string value)
|
||||
{
|
||||
return config[value];
|
||||
}
|
||||
|
||||
SettingsListener::SettingsListener(SettingsStorage &_parent, const std::vector<std::string> &_path):
|
||||
parent(_parent),
|
||||
path(_path)
|
||||
{
|
||||
parent.listeners.insert(this);
|
||||
}
|
||||
|
||||
SettingsListener::~SettingsListener()
|
||||
{
|
||||
parent.listeners.erase(this);
|
||||
}
|
||||
|
||||
void SettingsListener::nodeInvalidated(const std::vector<std::string> changedPath)
|
||||
{
|
||||
if (!callback)
|
||||
return;
|
||||
|
||||
size_t min = std::min(path.size(), changedPath.size());
|
||||
size_t mismatch = std::mismatch(path.begin(), path.begin()+min, changedPath.begin()).first - path.begin();
|
||||
|
||||
if (min == mismatch)
|
||||
callback(parent.getNode(path));
|
||||
}
|
||||
|
||||
void SettingsListener::operator() (boost::function<void(const JsonNode&)> _callback)
|
||||
{
|
||||
callback = _callback;
|
||||
}
|
||||
|
||||
Settings::Settings(SettingsStorage &_parent, const std::vector<std::string> &_path):
|
||||
parent(_parent),
|
||||
path(_path),
|
||||
node(_parent.getNode(_path)),
|
||||
copy(_parent.getNode(_path))
|
||||
{
|
||||
}
|
||||
|
||||
Settings::~Settings()
|
||||
{
|
||||
if (node != copy)
|
||||
parent.invalidateNode(path);
|
||||
}
|
||||
|
||||
JsonNode* Settings::operator -> ()
|
||||
{
|
||||
return &node;
|
||||
}
|
||||
|
||||
const JsonNode* Settings::operator ->() const
|
||||
{
|
||||
return &node;
|
||||
}
|
||||
|
||||
const JsonNode& Settings::operator [](std::string value) const
|
||||
{
|
||||
return node[value];
|
||||
}
|
||||
|
||||
JsonNode& Settings::operator [](std::string value)
|
||||
{
|
||||
return node[value];
|
||||
}
|
||||
|
||||
template struct SettingsStorage::NodeAccessor<SettingsListener>;
|
||||
template struct SettingsStorage::NodeAccessor<Settings>;
|
||||
|
||||
static void setButton(ButtonInfo &button, const JsonNode &g)
|
||||
{
|
||||
@ -145,29 +193,6 @@ CConfigHandler::~CConfigHandler(void)
|
||||
|
||||
void config::CConfigHandler::init()
|
||||
{
|
||||
std::vector<char> settings;
|
||||
std::string settingsDir = GameConstants::DATA_DIR + "/config/settings.txt";
|
||||
std::ifstream ifs(settingsDir.c_str());
|
||||
if(!ifs)
|
||||
{
|
||||
tlog1 << "Cannot open " << GameConstants::DATA_DIR << "/config/settings.txt !" << std::endl;
|
||||
return;
|
||||
}
|
||||
ifs.unsetf(std::ios::skipws); // Turn of white space skipping on the stream
|
||||
std::copy(std::istream_iterator<char>(ifs),std::istream_iterator<char>(),std::back_inserter(settings));
|
||||
std::vector<char>::const_iterator first = settings.begin(), last = settings.end();
|
||||
SettingsGrammar sg;
|
||||
BOOST_SPIRIT_DEBUG_NODE(sg);
|
||||
CommentsGrammar cg;
|
||||
BOOST_SPIRIT_DEBUG_NODE(cg);
|
||||
|
||||
|
||||
parse_info<std::vector<char>::const_iterator> info = parse(first,last,sg,cg);
|
||||
if(!info.hit)
|
||||
tlog1 << "Cannot parse config/settings.txt file!\n";
|
||||
else if(!info.full)
|
||||
tlog2 << "Not entire config/settings.txt parsed!\n";
|
||||
|
||||
/* Read resolutions. */
|
||||
const JsonNode config(GameConstants::DATA_DIR + "/config/resolutions.json");
|
||||
const JsonVector &guisettings_vec = config["GUISettings"].Vector();
|
||||
@ -244,13 +269,16 @@ void config::CConfigHandler::init()
|
||||
setButton(current->ac.endTurn, g["ButtonEndTurn"]);
|
||||
}
|
||||
|
||||
//fixing screenx / screeny if set to 0x0
|
||||
if (cc.screenx == 0 && cc.screeny == 0)
|
||||
const JsonNode& screenRes = settings["video"]["screenRes"];
|
||||
const JsonNode& gameRes = settings["video"]["gameRes"];
|
||||
|
||||
//fixing screenx / screeny
|
||||
if (screenRes["width"].Float() != gameRes["width"].Float()
|
||||
|| screenRes["height"].Float() != gameRes["height"].Float())
|
||||
{
|
||||
cc.screenx = cc.resx;
|
||||
cc.screeny = cc.resy;
|
||||
Settings screen = settings.write["video"]["screenRes"];
|
||||
screen["width"].Float() = gameRes["width"].Float();
|
||||
screen["height"].Float() = gameRes["height"].Float();
|
||||
}
|
||||
cc.autoSkip = false;
|
||||
cc.oneGoodAI = false;
|
||||
SetResolution(cc.resx, cc.resy);
|
||||
SetResolution(gameRes["width"].Float(), gameRes["height"].Float());
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
|
||||
class CAdvMapInt;
|
||||
#include "../lib/JsonNode.h"
|
||||
|
||||
/*
|
||||
* CConfighandler.h, part of VCMI engine
|
||||
@ -14,22 +12,103 @@ class CAdvMapInt;
|
||||
*
|
||||
*/
|
||||
|
||||
class Settings;
|
||||
class SettingsListener;
|
||||
|
||||
/// Main storage of game settings
|
||||
class SettingsStorage
|
||||
{
|
||||
//Helper struct to access specific node either via chain of operator[] or with one operator() (vector)
|
||||
template<typename Accessor>
|
||||
struct NodeAccessor
|
||||
{
|
||||
SettingsStorage & parent;
|
||||
std::vector<std::string> path;
|
||||
|
||||
NodeAccessor(SettingsStorage & _parent, std::vector<std::string> _path);
|
||||
NodeAccessor<Accessor> operator [] (std::string nextNode) const;
|
||||
NodeAccessor<Accessor> operator () (std::vector<std::string> _path);
|
||||
operator Accessor() const;
|
||||
};
|
||||
|
||||
std::set<SettingsListener*> listeners;
|
||||
JsonNode config;
|
||||
JsonNode & getNode(std::vector<std::string> path);
|
||||
|
||||
// Calls all required listeners
|
||||
void invalidateNode(const std::vector<std::string> &changedPath);
|
||||
|
||||
Settings get(std::vector<std::string> path);
|
||||
public:
|
||||
// Initialize config structure
|
||||
SettingsStorage();
|
||||
void init();
|
||||
|
||||
// Get write access to config node at path
|
||||
const NodeAccessor<Settings> write;
|
||||
|
||||
// Get access to listener at path
|
||||
const NodeAccessor<SettingsListener> listen;
|
||||
|
||||
//Read access, see JsonNode::operator[]
|
||||
const JsonNode& operator [](std::string value);
|
||||
|
||||
friend class SettingsListener;
|
||||
friend class Settings;
|
||||
};
|
||||
|
||||
/// Class for listening changes in specific part of configuration (e.g. change of music volume)
|
||||
class SettingsListener
|
||||
{
|
||||
SettingsStorage &parent;
|
||||
// Path to this node
|
||||
std::vector<std::string> path;
|
||||
// Callback
|
||||
boost::function<void(const JsonNode&)> callback;
|
||||
|
||||
SettingsListener(SettingsStorage &_parent, const std::vector<std::string> &_path);
|
||||
|
||||
// Executes callback if changedpath begins with path
|
||||
void nodeInvalidated(const std::vector<std::string> changedPath);
|
||||
|
||||
public:
|
||||
~SettingsListener();
|
||||
|
||||
// assign callback function
|
||||
void operator()(boost::function<void(const JsonNode&)> _callback);
|
||||
|
||||
friend class SettingsStorage;
|
||||
};
|
||||
|
||||
/// System options, provides write access to config tree with auto-saving on change
|
||||
class Settings
|
||||
{
|
||||
SettingsStorage &parent;
|
||||
//path to this node
|
||||
std::vector<std::string> path;
|
||||
JsonNode &node;
|
||||
JsonNode copy;
|
||||
|
||||
//Get access to node pointed by path
|
||||
Settings(SettingsStorage &_parent, const std::vector<std::string> &_path);
|
||||
|
||||
public:
|
||||
//Saves config if it was modified
|
||||
~Settings();
|
||||
|
||||
//Returns node selected during construction
|
||||
JsonNode* operator ->();
|
||||
const JsonNode* operator ->() const;
|
||||
|
||||
//Helper, replaces JsonNode::operator[]
|
||||
JsonNode& operator [](std::string value);
|
||||
const JsonNode& operator [](std::string value) const;
|
||||
|
||||
friend class SettingsStorage;
|
||||
};
|
||||
|
||||
namespace config
|
||||
{
|
||||
/// Struct holds data about client resolution, colors, fullscreen mode
|
||||
struct ClientConfig
|
||||
{
|
||||
int resx, resy, bpp, fullscreen; //client resolution/colours
|
||||
int screenx, screeny; //real screen resolution
|
||||
int pregameResx, pregameResy; //real screen resolution of preGame
|
||||
int port, localInformation;
|
||||
std::string server, //server address (e.g. 127.0.0.1)
|
||||
defaultPlayerAI, defaultBattleAI; //dll names
|
||||
bool showFPS; //show/hide FPS counter
|
||||
bool classicCreatureWindow;
|
||||
bool autoSkip, oneGoodAI; //for AI testing purposes
|
||||
};
|
||||
|
||||
struct ButtonInfo
|
||||
{
|
||||
std::string defName;
|
||||
@ -84,8 +163,8 @@ namespace config
|
||||
GUIOptions *current; // pointer to current gui options
|
||||
|
||||
public:
|
||||
ClientConfig cc;
|
||||
std::map<std::pair<int,int>, GUIOptions > guiOptions;
|
||||
typedef std::map<std::pair<int,int>, GUIOptions > GuiOptionsMap;
|
||||
GuiOptionsMap guiOptions;
|
||||
void init();
|
||||
CConfigHandler(void); //c-tor
|
||||
~CConfigHandler(void); //d-tor
|
||||
@ -96,4 +175,6 @@ namespace config
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
extern SettingsStorage settings;
|
||||
extern config::CConfigHandler conf;
|
||||
|
@ -177,7 +177,7 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *
|
||||
bonusItems.push_back (new CBonusItem(genRect(0, 0, 251, 57), text, description, stack->bonusToGraphics(&b)));
|
||||
}
|
||||
|
||||
bonusRows = std::min ((int)((bonusItems.size() + 1) / 2), (conf.cc.resy - 230) / 60);
|
||||
bonusRows = std::min ((int)((bonusItems.size() + 1) / 2), (screen->h - 230) / 60);
|
||||
vstd::amin(bonusRows, 4);
|
||||
vstd::amax(bonusRows, 1);
|
||||
|
||||
@ -627,7 +627,7 @@ void CCreInfoWindow::clickRight(tribool down, bool previousState)
|
||||
|
||||
CIntObject * createCreWindow(const CStack *s)
|
||||
{
|
||||
if(conf.cc.classicCreatureWindow)
|
||||
if(settings["general"]["classicCreatureWindow"].Bool())
|
||||
return new CCreInfoWindow(*s);
|
||||
else
|
||||
return new CCreatureWindow(*s, CCreatureWindow::BATTLE);
|
||||
@ -635,7 +635,7 @@ CIntObject * createCreWindow(const CStack *s)
|
||||
|
||||
CIntObject * createCreWindow(int Cid, int Type, int creatureCount)
|
||||
{
|
||||
if(conf.cc.classicCreatureWindow)
|
||||
if(settings["general"]["classicCreatureWindow"].Bool())
|
||||
return new CCreInfoWindow(Cid, Type, creatureCount);
|
||||
else
|
||||
return new CCreatureWindow(Cid, Type, creatureCount);
|
||||
@ -643,7 +643,7 @@ CIntObject * createCreWindow(int Cid, int Type, int creatureCount)
|
||||
|
||||
CIntObject * createCreWindow(const CStackInstance *s, int type, boost::function<void()> Upg, boost::function<void()> Dsm, UpgradeInfo *ui)
|
||||
{
|
||||
if(conf.cc.classicCreatureWindow)
|
||||
if(settings["general"]["classicCreatureWindow"].Bool())
|
||||
return new CCreInfoWindow(*s, type==3, Upg, Dsm, ui);
|
||||
else
|
||||
return new CCreatureWindow(*s, type, Upg, Dsm, ui);
|
||||
|
@ -64,12 +64,11 @@ std::string NAME_AFFIX = "client";
|
||||
std::string NAME = GameConstants::VCMI_VERSION + std::string(" (") + NAME_AFFIX + ')'; //application name
|
||||
CGuiHandler GH;
|
||||
static CClient *client;
|
||||
SDL_Surface *screen = NULL, //main screen surface
|
||||
*screen2 = NULL,//and hlp surface (used to store not-active interfaces layer)
|
||||
SDL_Surface *screen = NULL, //main screen surface
|
||||
*screen2 = NULL,//and hlp surface (used to store not-active interfaces layer)
|
||||
*screenBuf = screen; //points to screen (if only advmapint is present) or screen2 (else) - should be used when updating controls which are not regularly redrawed
|
||||
static boost::thread *mainGUIThread;
|
||||
|
||||
SystemOptions GDefaultOptions;
|
||||
VCMIDirs GVCMIDirs;
|
||||
std::queue<SDL_Event*> events;
|
||||
boost::mutex eventsM;
|
||||
@ -117,33 +116,16 @@ void init()
|
||||
#endif
|
||||
CSDL_Ext::std32bppSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, 1, 1, 32, rmask, gmask, bmask, amask);
|
||||
tlog0 << "\tInitializing minors: " << pomtime.getDiff() << std::endl;
|
||||
{
|
||||
//read system options
|
||||
CLoadFile settings(GVCMIDirs.UserPath + "/config/sysopts.bin", 727);
|
||||
if(settings.sfile)
|
||||
{
|
||||
settings >> GDefaultOptions;
|
||||
}
|
||||
else //file not found (probably, may be also some kind of access problem
|
||||
{
|
||||
tlog2 << "Warning: Cannot read system options, default settings will be used.\n";
|
||||
|
||||
//Try to create file
|
||||
tlog2 << "VCMI will try to save default system options...\n";
|
||||
GDefaultOptions.settingsChanged();
|
||||
}
|
||||
}
|
||||
tlog0 << "\tLoading default system settings: " << pomtime.getDiff() << std::endl;
|
||||
|
||||
//initializing audio
|
||||
// Note: because of interface button range, volume can only be a
|
||||
// multiple of 11, from 0 to 99.
|
||||
CCS->soundh = new CSoundHandler;
|
||||
CCS->soundh->init();
|
||||
CCS->soundh->setVolume(GDefaultOptions.soundVolume);
|
||||
CCS->soundh->setVolume(settings["general"]["sound"].Float());
|
||||
CCS->musich = new CMusicHandler;
|
||||
CCS->musich->init();
|
||||
CCS->musich->setVolume(GDefaultOptions.musicVolume);
|
||||
CCS->musich->setVolume(settings["general"]["music"].Float());
|
||||
tlog0<<"\tInitializing sound: "<<pomtime.getDiff()<<std::endl;
|
||||
tlog0<<"Initializing screen and sound handling: "<<tmh.getDiff()<<std::endl;
|
||||
|
||||
@ -248,12 +230,13 @@ int main(int argc, char** argv)
|
||||
atexit(dispose);
|
||||
tlog0 <<"Creating console and logfile: "<<pomtime.getDiff() << std::endl;
|
||||
|
||||
settings.init();
|
||||
conf.init();
|
||||
tlog0 <<"Loading settings: "<<pomtime.getDiff() << std::endl;
|
||||
tlog0 << NAME << std::endl;
|
||||
|
||||
srand ( time(NULL) );
|
||||
|
||||
|
||||
CCS = new CClientState;
|
||||
CGI = new CGameInfo; //contains all global informations about game (texts, lodHandlers, map handler etc.)
|
||||
|
||||
@ -264,7 +247,11 @@ int main(int argc, char** argv)
|
||||
}
|
||||
atexit(SDL_Quit);
|
||||
|
||||
setScreenRes(conf.cc.pregameResx, conf.cc.pregameResy, conf.cc.bpp, conf.cc.fullscreen);
|
||||
const JsonNode& video = settings["video"];
|
||||
const JsonNode& res = video["menuRes"];
|
||||
|
||||
setScreenRes(res["width"].Float(), res["height"].Float(), video["bitsPerPixel"].Float(), video["fullscreen"].Bool());
|
||||
|
||||
tlog0 <<"\tInitializing screen: "<<pomtime.getDiff() << std::endl;
|
||||
|
||||
// Initialize video
|
||||
@ -289,8 +276,9 @@ int main(int argc, char** argv)
|
||||
if(!vm.count("battle"))
|
||||
{
|
||||
gOnlyAI = vm.count("onlyAI");
|
||||
conf.cc.autoSkip = vm.count("autoSkip");
|
||||
conf.cc.oneGoodAI = vm.count("oneGoodAI");
|
||||
Settings session = settings.write["session"];
|
||||
session["autoSkip"].Bool() = vm.count("autoSkip");
|
||||
session["oneGoodAI"].Bool() = vm.count("oneGoodAI");
|
||||
|
||||
|
||||
if(!vm.count("start"))
|
||||
@ -318,7 +306,8 @@ void printInfoAboutIntObject(const CIntObject *obj, int level)
|
||||
int tabs = level;
|
||||
while(tabs--) tlog4 << '\t';
|
||||
|
||||
tlog4 << typeid(*obj).name() << " *** " << (obj->active ? "" : "not ") << "active\n";
|
||||
tlog4 << typeid(*obj).name() << " *** " << (obj->active ? "" : "not ") << "active";
|
||||
tlog4 << " at " << obj->pos.x <<"x"<< obj->pos.y << "\n";
|
||||
|
||||
BOOST_FOREACH(const CIntObject *child, obj->children)
|
||||
printInfoAboutIntObject(child, level+1);
|
||||
@ -447,10 +436,13 @@ void processCommand(const std::string &message)
|
||||
else
|
||||
{
|
||||
for(j=conf.guiOptions.begin(); j!=conf.guiOptions.end() && hlp++<i; j++); //move j to the i-th resolution info
|
||||
conf.cc.resx = conf.cc.screenx = j->first.first;
|
||||
conf.cc.resy = conf.cc.screeny = j->first.second;
|
||||
conf.SetResolution(conf.cc.screenx, conf.cc.screeny);
|
||||
tlog0 << "Screen resolution set to " << conf.cc.screenx << " x " << conf.cc.screeny <<". It will be applied when the game starts.\n";
|
||||
Settings res = settings.write["video"]["gameRes"];
|
||||
Settings screen = settings.write["video"]["screenRes"];
|
||||
res["width"].Float() = res["width"].Float() = j->first.first;
|
||||
screen["height"].Float() = screen["height"].Float() = j->first.second;
|
||||
conf.SetResolution(screen["width"].Float(), screen["height"].Float());
|
||||
tlog0 << "Screen resolution set to " << (int)screen["width"].Float() << " x "
|
||||
<< (int)screen["height"].Float() <<". It will be applied when the game starts.\n";
|
||||
}
|
||||
}
|
||||
else if(message=="get txt")
|
||||
@ -460,7 +452,7 @@ void processCommand(const std::string &message)
|
||||
CLodHandler * txth = new CLodHandler;
|
||||
txth->init(GameConstants::DATA_DIR + "/Data/H3bitmap.lod","");
|
||||
tlog0<<"done.\nScanning .lod file\n";
|
||||
|
||||
|
||||
BOOST_FOREACH(Entry e, txth->entries)
|
||||
if( e.type == FILE_TEXT )
|
||||
txth->extractFile(std::string(GVCMIDirs.UserPath + "/Extracted_txts/")+e.name, e.name, FILE_TEXT);
|
||||
@ -532,7 +524,8 @@ void processCommand(const std::string &message)
|
||||
}
|
||||
else if (cn == "switchCreWin" )
|
||||
{
|
||||
conf.cc.classicCreatureWindow = !conf.cc.classicCreatureWindow;
|
||||
Settings window = settings.write["general"]["classicCreatureWindow"];
|
||||
window->Bool() = !window->Bool();
|
||||
}
|
||||
else if(cn == "sinfo")
|
||||
{
|
||||
@ -574,7 +567,7 @@ void dispose()
|
||||
}
|
||||
|
||||
static void setScreenRes(int w, int h, int bpp, bool fullscreen)
|
||||
{
|
||||
{
|
||||
// VCMI will only work with 2, 3 or 4 bytes per pixel
|
||||
vstd::amax(bpp, 16);
|
||||
vstd::amin(bpp, 32);
|
||||
@ -674,7 +667,9 @@ static void listenForEvents()
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> lock(*LOCPLINT->pim);
|
||||
bool full = !(screen->flags&SDL_FULLSCREEN);
|
||||
setScreenRes(conf.cc.screenx, conf.cc.screeny, conf.cc.bpp, full);
|
||||
const JsonNode& video = settings["video"];
|
||||
const JsonNode& res = video["screenRes"];
|
||||
setScreenRes(res["width"].Float(), res["height"].Float(), video["bitsPerPixel"].Float(), full);
|
||||
GH.totalRedraw();
|
||||
delete ev;
|
||||
continue;
|
||||
@ -684,10 +679,13 @@ static void listenForEvents()
|
||||
switch(ev->user.code)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
tlog0 << "Changing resolution has been requested\n";
|
||||
setScreenRes(conf.cc.screenx, conf.cc.screeny, conf.cc.bpp, conf.cc.fullscreen);
|
||||
const JsonNode& video = settings["video"];
|
||||
const JsonNode& res = video["gameRes"];
|
||||
setScreenRes(res["width"].Float(), res["height"].Float(), video["bitsPerPixel"].Float(), video["fullscreen"].Bool());
|
||||
break;
|
||||
|
||||
}
|
||||
case 2:
|
||||
client->endGame();
|
||||
delete client;
|
||||
@ -718,20 +716,21 @@ static void listenForEvents()
|
||||
}
|
||||
}
|
||||
|
||||
void startGame(StartInfo * options, CConnection *serv/* = NULL*/)
|
||||
void startGame(StartInfo * options, CConnection *serv/* = NULL*/)
|
||||
{
|
||||
GH.curInt =NULL;
|
||||
SDL_FillRect(screen, 0, 0);
|
||||
if(gOnlyAI)
|
||||
{
|
||||
for(std::map<int, PlayerSettings>::iterator it = options->playerInfos.begin();
|
||||
for(std::map<int, PlayerSettings>::iterator it = options->playerInfos.begin();
|
||||
it != options->playerInfos.end(); ++it)
|
||||
{
|
||||
it->second.human = false;
|
||||
}
|
||||
}
|
||||
const JsonNode& res = settings["video"]["screenRes"];
|
||||
|
||||
if(screen->w != conf.cc.screenx || screen->h != conf.cc.screeny)
|
||||
if(screen->w != res["width"].Float() || screen->h != res["height"].Float())
|
||||
{
|
||||
requestChangingResolution();
|
||||
|
||||
|
@ -390,8 +390,8 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player)
|
||||
|
||||
for(int i = 0;
|
||||
i < ARRAY_COUNT(sizes)
|
||||
&& sizes[i][0] < conf.cc.resx - 150
|
||||
&& sizes[i][1] < conf.cc.resy - 150
|
||||
&& sizes[i][0] < screen->w - 150
|
||||
&& sizes[i][1] < screen->h - 150
|
||||
&& ret->text->slider;
|
||||
i++)
|
||||
{
|
||||
@ -424,7 +424,7 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player)
|
||||
vstd::amax(winSize.first, comps.w);
|
||||
vstd::amax(winSize.first, bw);
|
||||
|
||||
vstd::amin(winSize.first, conf.cc.resx - 150);
|
||||
vstd::amin(winSize.first, screen->w - 150);
|
||||
|
||||
ret->bitmap = drawBox1 (winSize.first + 2*SIDE_MARGIN, winSize.second + 2*SIDE_MARGIN, player);
|
||||
ret->pos.h=ret->bitmap->h;
|
||||
|
@ -66,8 +66,15 @@ void CAudioBase::setVolume(ui32 percent)
|
||||
volume = percent;
|
||||
}
|
||||
|
||||
CSoundHandler::CSoundHandler()
|
||||
void CSoundHandler::onVolumeChange(const JsonNode &volumeNode)
|
||||
{
|
||||
setVolume(volumeNode.Float());
|
||||
}
|
||||
|
||||
CSoundHandler::CSoundHandler():
|
||||
listener(settings.listen["general"]["sound"])
|
||||
{
|
||||
listener(boost::bind(&CSoundHandler::onVolumeChange, this, _1));
|
||||
// Map sound names
|
||||
#define VCMI_SOUND_NAME(x) ( soundBase::x,
|
||||
#define VCMI_SOUND_FILE(y) #y )
|
||||
@ -311,8 +318,15 @@ void CSoundHandler::soundFinishedCallback(int channel)
|
||||
callbacks.erase(iter);
|
||||
}
|
||||
|
||||
CMusicHandler::CMusicHandler()
|
||||
void CMusicHandler::onVolumeChange(const JsonNode &volumeNode)
|
||||
{
|
||||
setVolume(volumeNode.Float());
|
||||
}
|
||||
|
||||
CMusicHandler::CMusicHandler():
|
||||
listener(settings.listen["general"]["music"])
|
||||
{
|
||||
listener(boost::bind(&CMusicHandler::onVolumeChange, this, _1));
|
||||
// Map music IDs
|
||||
#define VCMI_MUSIC_ID(x) ( musicBase::x ,
|
||||
#define VCMI_MUSIC_FILE(y) y )
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "CConfigHandler.h"
|
||||
#include "CSoundBase.h"
|
||||
#include "CMusicBase.h"
|
||||
#include "../lib/CCreatureHandler.h"
|
||||
@ -65,6 +66,9 @@ class CSoundHandler: public CAudioBase
|
||||
private:
|
||||
CSndHandler sndh;
|
||||
soundBase::soundID getSoundID(const std::string &fileName);
|
||||
//update volume on configuration change
|
||||
SettingsListener listener;
|
||||
void onVolumeChange(const JsonNode &volumeNode);
|
||||
|
||||
std::map<soundBase::soundID, Mix_Chunk *> soundChunks;
|
||||
|
||||
@ -137,6 +141,9 @@ private:
|
||||
// Because we use the SDL music callback, our music variables must
|
||||
// be protected
|
||||
boost::mutex musicMutex;
|
||||
//update volume on configuration change
|
||||
SettingsListener listener;
|
||||
void onVolumeChange(const JsonNode &volumeNode);
|
||||
|
||||
std::auto_ptr<MusicEntry> current;
|
||||
std::auto_ptr<MusicEntry> next;
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "../lib/CSpellHandler.h"
|
||||
#include "../lib/CTownHandler.h"
|
||||
#include "../lib/BattleState.h"
|
||||
#include "../lib/JsonNode.h"
|
||||
#include "CMusicHandler.h"
|
||||
#include "../lib/CondSh.h"
|
||||
#include "../lib/NetPacks.h"
|
||||
@ -96,7 +97,6 @@ CPlayerInterface::CPlayerInterface(int Player)
|
||||
//pim = new boost::recursive_mutex;
|
||||
makingTurn = false;
|
||||
showingDialog = new CondSh<bool>(false);
|
||||
sysOpts = GDefaultOptions;
|
||||
cingconsole = new CInGameConsole;
|
||||
terminate_cond.set(false);
|
||||
firstCall = 1; //if loading will be overwritten in serialize
|
||||
@ -285,8 +285,9 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
|
||||
//first initializing done
|
||||
GH.mainFPSmng->framerateDelay(); // after first move
|
||||
|
||||
ui32 speed = settings["adventure"]["heroSpeed"].Float();
|
||||
//main moving
|
||||
for(int i=1; i<32; i+=2*sysOpts.heroMoveSpeed)
|
||||
for(int i=1; i<32; i+=2*speed)
|
||||
{
|
||||
movementPxStep(details, i, hp, ho);
|
||||
adventureInt->updateScreen = true;
|
||||
@ -1082,7 +1083,6 @@ void CPlayerInterface::heroBonusChanged( const CGHeroInstance *hero, const Bonus
|
||||
template <typename Handler> void CPlayerInterface::serializeTempl( Handler &h, const int version )
|
||||
{
|
||||
h & playerID;
|
||||
h & sysOpts;
|
||||
h & spellbookSettings;
|
||||
|
||||
//sleeping heroes
|
||||
@ -1099,7 +1099,7 @@ template <typename Handler> void CPlayerInterface::serializeTempl( Handler &h, c
|
||||
if (!h.saving)
|
||||
{
|
||||
const CGHeroInstance *hero = cb->getHero(hid);
|
||||
sleepingHeroes += hero;
|
||||
sleepingHeroes += hero;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1119,7 +1119,7 @@ template <typename Handler> void CPlayerInterface::serializeTempl( Handler &h, c
|
||||
if (!h.saving)
|
||||
{
|
||||
const CGHeroInstance *hero = cb->getHero(hid);
|
||||
wanderingHeroes += hero;
|
||||
wanderingHeroes += hero;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1132,7 +1132,6 @@ void CPlayerInterface::serialize( COSer<CSaveFile> &h, const int version )
|
||||
void CPlayerInterface::serialize( CISer<CLoadFile> &h, const int version )
|
||||
{
|
||||
serializeTempl(h,version);
|
||||
sysOpts.apply();
|
||||
firstCall = -1;
|
||||
}
|
||||
|
||||
@ -1493,7 +1492,7 @@ void CPlayerInterface::update()
|
||||
else
|
||||
GH.simpleRedraw();
|
||||
|
||||
if (conf.cc.showFPS)
|
||||
if (settings["general"]["showfps"].Bool())
|
||||
GH.drawFPSCounter();
|
||||
|
||||
// draw the mouse cursor and update the screen
|
||||
@ -2023,74 +2022,6 @@ void CPlayerInterface::advmapSpellCast(const CGHeroInstance * caster, int spellI
|
||||
}
|
||||
}
|
||||
|
||||
void SystemOptions::setMusicVolume( int newVolume )
|
||||
{
|
||||
musicVolume = newVolume;
|
||||
CCS->musich->setVolume(newVolume);
|
||||
settingsChanged();
|
||||
}
|
||||
|
||||
void SystemOptions::setSoundVolume( int newVolume )
|
||||
{
|
||||
soundVolume = newVolume;
|
||||
CCS->soundh->setVolume(newVolume);
|
||||
settingsChanged();
|
||||
}
|
||||
|
||||
void SystemOptions::setHeroMoveSpeed( int newSpeed )
|
||||
{
|
||||
heroMoveSpeed = newSpeed;
|
||||
settingsChanged();
|
||||
}
|
||||
|
||||
void SystemOptions::setMapScrollingSpeed( int newSpeed )
|
||||
{
|
||||
mapScrollingSpeed = newSpeed;
|
||||
settingsChanged();
|
||||
}
|
||||
|
||||
void SystemOptions::settingsChanged()
|
||||
{
|
||||
CSaveFile settings(GVCMIDirs.UserPath + "/config/sysopts.bin");
|
||||
|
||||
if(settings.sfile)
|
||||
settings << *this;
|
||||
else
|
||||
tlog1 << "Cannot save settings to config/sysopts.bin!\n";
|
||||
}
|
||||
|
||||
void SystemOptions::apply()
|
||||
{
|
||||
if(CCS->musich->getVolume() != musicVolume)
|
||||
CCS->musich->setVolume(musicVolume);
|
||||
if(CCS->soundh->getVolume() != soundVolume)
|
||||
CCS->soundh->setVolume(soundVolume);
|
||||
|
||||
settingsChanged();
|
||||
}
|
||||
|
||||
SystemOptions::SystemOptions()
|
||||
{
|
||||
heroMoveSpeed = 2;
|
||||
mapScrollingSpeed = 2;
|
||||
musicVolume = 88;
|
||||
soundVolume = 88;
|
||||
|
||||
printCellBorders = true;
|
||||
printStackRange = true;
|
||||
animSpeed = 2;
|
||||
printMouseShadow = true;
|
||||
showQueue = true;
|
||||
|
||||
playerName = "Player";
|
||||
}
|
||||
|
||||
void SystemOptions::setPlayerName(const std::string &newPlayerName)
|
||||
{
|
||||
playerName = newPlayerName;
|
||||
settingsChanged();
|
||||
}
|
||||
|
||||
void CPlayerInterface::eraseCurrentPathOf( const CGHeroInstance * ho, bool checkForExistanceOfPath /*= true */ )
|
||||
{
|
||||
if(checkForExistanceOfPath)
|
||||
@ -2140,7 +2071,7 @@ CGPath * CPlayerInterface::getAndVerifyPath(const CGHeroInstance * h)
|
||||
|
||||
void CPlayerInterface::acceptTurn()
|
||||
{
|
||||
if(conf.cc.autoSkip)
|
||||
if(settings["session"]["autoSkip"].Bool())
|
||||
{
|
||||
while(CInfoWindow *iw = dynamic_cast<CInfoWindow *>(GH.topInt()))
|
||||
iw->close();
|
||||
@ -2177,7 +2108,7 @@ void CPlayerInterface::acceptTurn()
|
||||
|
||||
adventureInt->showAll(screen);
|
||||
|
||||
if(conf.cc.autoSkip && !LOCPLINT->shiftPressed())
|
||||
if(settings["session"]["autoSkip"].Bool() && !LOCPLINT->shiftPressed())
|
||||
{
|
||||
if(CInfoWindow *iw = dynamic_cast<CInfoWindow *>(GH.topInt()))
|
||||
iw->close();
|
||||
|
@ -71,42 +71,6 @@ namespace boost
|
||||
class recursive_mutex;
|
||||
};
|
||||
|
||||
/// Stores information about system options like hero move speed, map scrolling speed, creature animation speed,...
|
||||
struct SystemOptions
|
||||
{
|
||||
std::string playerName;
|
||||
|
||||
ui8 heroMoveSpeed;/*, enemyMoveSpeed*/ //speed of player's hero movement
|
||||
ui8 mapScrollingSpeed; //map scrolling speed
|
||||
ui8 musicVolume, soundVolume;
|
||||
//TODO: rest of system options
|
||||
|
||||
//battle settings
|
||||
ui8 printCellBorders; //if true, cell borders will be printed
|
||||
ui8 printStackRange; //if true,range of active stack will be printed
|
||||
ui8 animSpeed; //speed of animation; 1 - slowest, 2 - medium, 4 - fastest
|
||||
ui8 printMouseShadow; //if true, hex under mouse will be shaded
|
||||
ui8 showQueue;
|
||||
|
||||
SystemOptions();
|
||||
void setHeroMoveSpeed(int newSpeed); //set for the member above
|
||||
void setMapScrollingSpeed(int newSpeed); //set the member above
|
||||
void setMusicVolume(int newVolume);
|
||||
void setSoundVolume(int newVolume);
|
||||
void setPlayerName(const std::string &newPlayerName);
|
||||
void settingsChanged(); //updates file with "default" settings for next running of application
|
||||
void apply();
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & playerName;
|
||||
h & heroMoveSpeed & mapScrollingSpeed & musicVolume & soundVolume;
|
||||
h & printCellBorders & printStackRange & animSpeed & printMouseShadow & showQueue;
|
||||
}
|
||||
};
|
||||
|
||||
extern SystemOptions GDefaultOptions; //defined and inited in CMT.cpp, stores default settings loaded with application
|
||||
|
||||
/// Central class for managing user interface logic
|
||||
class CPlayerInterface : public CGameInterface, public IUpdateable
|
||||
{
|
||||
@ -123,8 +87,6 @@ public:
|
||||
static const int SAVES_COUNT = 5;
|
||||
static int howManyPeople;
|
||||
|
||||
SystemOptions sysOpts;
|
||||
|
||||
CCastleInterface * castleInt; //NULL if castle window isn't opened
|
||||
static CBattleInterface * battleInt; //NULL if no battle
|
||||
CInGameConsole * cingconsole;
|
||||
|
@ -60,7 +60,6 @@ using boost::ref;
|
||||
#endif
|
||||
|
||||
void startGame(StartInfo * options, CConnection *serv = NULL);
|
||||
extern SystemOptions GDefaultOptions;
|
||||
|
||||
CGPreGame * CGP;
|
||||
ISelectionScreenInfo *SEL;
|
||||
@ -454,7 +453,7 @@ void CGPreGame::update()
|
||||
|
||||
GH.topInt()->show(screen);
|
||||
|
||||
if (conf.cc.showFPS)
|
||||
if (settings["general"]["showfps"].Bool())
|
||||
GH.drawFPSCounter();
|
||||
|
||||
// draw the mouse cursor and update the screen
|
||||
@ -2618,7 +2617,7 @@ CMultiMode::CMultiMode()
|
||||
|
||||
bar = new CGStatusBar(new CPicture(Rect(7, 465, 440, 18), 0));//226, 472
|
||||
txt = new CTextInput(Rect(19, 436, 334, 16), *bg);
|
||||
txt->setText(GDefaultOptions.playerName); //Player
|
||||
txt->setText(settings["general"]["playerName"].String()); //Player
|
||||
|
||||
btns[0] = new CAdventureMapButton(CGI->generaltexth->zelp[266], bind(&CMultiMode::openHotseat, this), 373, 78, "MUBHOT.DEF");
|
||||
btns[1] = new CAdventureMapButton("Host TCP/IP game", "", bind(&CMultiMode::hostTCP, this), 373, 78 + 57*1, "MUBHOST.DEF");
|
||||
@ -2633,14 +2632,16 @@ void CMultiMode::openHotseat()
|
||||
|
||||
void CMultiMode::hostTCP()
|
||||
{
|
||||
GDefaultOptions.setPlayerName(txt->text);
|
||||
Settings name = settings.write["general"]["playerName"];
|
||||
name->String() = txt->text;
|
||||
GH.popIntTotally(this);
|
||||
GH.pushInt(new CSelectionScreen(CMenuScreen::newGame, CMenuScreen::MULTI_NETWORK_HOST));
|
||||
}
|
||||
|
||||
void CMultiMode::joinTCP()
|
||||
{
|
||||
GDefaultOptions.setPlayerName(txt->text);
|
||||
Settings name = settings.write["general"]["playerName"];
|
||||
name->String() = txt->text;
|
||||
GH.popIntTotally(this);
|
||||
GH.pushInt(new CSelectionScreen(CMenuScreen::newGame, CMenuScreen::MULTI_NETWORK_GUEST));
|
||||
}
|
||||
@ -2688,7 +2689,8 @@ void CHotSeatPlayers::enterSelectionScreen()
|
||||
if(txt[i]->text.length())
|
||||
names[j++] = txt[i]->text;
|
||||
|
||||
GDefaultOptions.setPlayerName(names.begin()->second); //remember selected name
|
||||
Settings name = settings.write["general"]["playerName"];
|
||||
name->String() = names.begin()->second;
|
||||
|
||||
GH.popInts(2); //pop MP mode window and this
|
||||
GH.pushInt(new CSelectionScreen(CMenuScreen::newGame, CMenuScreen::MULTI_HOT_SEAT, &names));
|
||||
@ -2866,7 +2868,7 @@ void CBonusSelection::selectMap( int whichOne )
|
||||
ourHeader->initFromMemory((const unsigned char*)ourCampaign->camp->mapPieces.find(whichOne)->second.c_str(), i);
|
||||
|
||||
std::map<ui32, std::string> names;
|
||||
names[1] = GDefaultOptions.playerName;
|
||||
names[1] = settings["general"]["playerName"].String();
|
||||
updateStartInfo(ourCampaign->camp->header.filename, sInfo, ourHeader, names);
|
||||
sInfo.turnTime = 0;
|
||||
sInfo.whichMapInCampaign = whichOne;
|
||||
@ -3283,7 +3285,7 @@ ISelectionScreenInfo::ISelectionScreenInfo(const std::map<ui32, std::string> *Na
|
||||
if(Names && Names->size()) //if have custom set of player names - use it
|
||||
playerNames = *Names;
|
||||
else
|
||||
playerNames[1] = GDefaultOptions.playerName; //by default we have only one player and his name is "Player" (or whatever the last used name was)
|
||||
playerNames[1] = settings["general"]["playerName"].String(); //by default we have only one player and his name is "Player" (or whatever the last used name was)
|
||||
}
|
||||
|
||||
ISelectionScreenInfo::~ISelectionScreenInfo()
|
||||
|
@ -7,7 +7,8 @@
|
||||
#include "UIFramework/SDL_Extensions.h"
|
||||
#include "CPlayerInterface.h"
|
||||
|
||||
extern SystemOptions GDefaultOptions;
|
||||
extern CGuiHandler GH; //global gui handler
|
||||
|
||||
//reads events and returns true on key down
|
||||
static bool keyDown()
|
||||
{
|
||||
|
@ -348,7 +348,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
|
||||
}
|
||||
|
||||
int humanPlayers = 0;
|
||||
int sensibleAILimit = conf.cc.oneGoodAI ? 1 : GameConstants::PLAYER_LIMIT;
|
||||
int sensibleAILimit = settings["session"]["oneGoodAI"].Bool() ? 1 : GameConstants::PLAYER_LIMIT;
|
||||
for(std::map<int, PlayerSettings>::iterator it = gs->scenarioOps->playerInfos.begin();
|
||||
it != gs->scenarioOps->playerInfos.end(); ++it)//initializing interfaces for players
|
||||
{
|
||||
@ -362,7 +362,7 @@ void CClient::newGame( CConnection *con, StartInfo *si )
|
||||
CCallback *cb = new CCallback(gs,color,this);
|
||||
if(!it->second.human)
|
||||
{
|
||||
std::string AItoGive = conf.cc.defaultPlayerAI;
|
||||
std::string AItoGive = settings["server"]["playerAI"].String();
|
||||
if(!sensibleAILimit)
|
||||
AItoGive = "GeniusAI";
|
||||
else
|
||||
@ -560,7 +560,9 @@ void CClient::battleStarted(const BattleInfo * info)
|
||||
def = NULL;
|
||||
|
||||
if(att || def || gs->scenarioOps->mode == StartInfo::DUEL)
|
||||
new CBattleInterface(info->belligerents[0], info->belligerents[1], info->heroes[0], info->heroes[1], Rect((conf.cc.resx - 800)/2, (conf.cc.resy - 600)/2, 800, 600), att, def);
|
||||
new CBattleInterface(info->belligerents[0], info->belligerents[1], info->heroes[0], info->heroes[1],
|
||||
Rect((settings["video"]["gameRes"]["width"].Float() - 800)/2,
|
||||
(settings["video"]["gameRes"]["height"].Float() - 600)/2, 800, 600), att, def);
|
||||
|
||||
if(vstd::contains(battleints,info->sides[0]))
|
||||
battleints[info->sides[0]]->battleStart(info->belligerents[0], info->belligerents[1], info->tile, info->heroes[0], info->heroes[1], 0);
|
||||
@ -577,7 +579,7 @@ void CClient::battleStarted(const BattleInfo * info)
|
||||
|
||||
void CClient::loadNeutralBattleAI()
|
||||
{
|
||||
battleints[255] = CDynLibHandler::getNewBattleAI(conf.cc.defaultBattleAI);
|
||||
battleints[255] = CDynLibHandler::getNewBattleAI(settings["server"]["neutralAI"].String());
|
||||
battleints[255]->init(new CBattleCallback(gs, 255, this));
|
||||
}
|
||||
|
||||
@ -656,7 +658,7 @@ CConnection * CServerHandler::connectToServer()
|
||||
waitForServer();
|
||||
|
||||
th.update();
|
||||
CConnection *ret = justConnectToServer(conf.cc.server, port);
|
||||
CConnection *ret = justConnectToServer(settings["server"]["server"].String(), port);
|
||||
|
||||
if(verbose)
|
||||
tlog0<<"\tConnecting to the server: "<<th.getDiff()<<std::endl;
|
||||
@ -668,7 +670,7 @@ CServerHandler::CServerHandler(bool runServer /*= false*/)
|
||||
{
|
||||
serverThread = NULL;
|
||||
shared = NULL;
|
||||
port = boost::lexical_cast<std::string>(conf.cc.port);
|
||||
port = boost::lexical_cast<std::string>(settings["server"]["port"].Float());
|
||||
verbose = false;
|
||||
|
||||
boost::interprocess::shared_memory_object::remove("vcmi_memory"); //if the application has previously crashed, the memory may not have been removed. to avoid problems - try to destroy it
|
||||
@ -701,8 +703,8 @@ CConnection * CServerHandler::justConnectToServer(const std::string &host, const
|
||||
try
|
||||
{
|
||||
tlog0 << "Establishing connection...\n";
|
||||
ret = new CConnection( host.size() ? host : conf.cc.server,
|
||||
port.size() ? port : boost::lexical_cast<std::string>(conf.cc.port),
|
||||
ret = new CConnection( host.size() ? host : settings["server"]["server"].String(),
|
||||
port.size() ? port : boost::lexical_cast<std::string>(settings["server"]["port"].Float()),
|
||||
NAME);
|
||||
}
|
||||
catch(...)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -74,7 +74,7 @@ class CArtPlace;
|
||||
class CAnimImage;
|
||||
|
||||
/// text + comp. + ok button
|
||||
class CInfoWindow : public CSimpleWindow
|
||||
class CInfoWindow : public CSimpleWindow
|
||||
{ //window able to delete its components when closed
|
||||
bool delComps; //whether comps will be deleted
|
||||
|
||||
@ -103,7 +103,7 @@ public:
|
||||
};
|
||||
|
||||
/// component selection window
|
||||
class CSelWindow : public CInfoWindow
|
||||
class CSelWindow : public CInfoWindow
|
||||
{ //warning - this window deletes its components by closing!
|
||||
public:
|
||||
void selectionChange(unsigned to);
|
||||
@ -114,7 +114,7 @@ public:
|
||||
};
|
||||
|
||||
/// popup displayed on R-click
|
||||
class CRClickPopup : public CIntObject
|
||||
class CRClickPopup : public CIntObject
|
||||
{
|
||||
public:
|
||||
virtual void activate();
|
||||
@ -130,7 +130,7 @@ public:
|
||||
};
|
||||
|
||||
/// popup displayed on R-click
|
||||
class CRClickPopupInt : public CRClickPopup
|
||||
class CRClickPopupInt : public CRClickPopup
|
||||
{
|
||||
public:
|
||||
IShowActivatable *inner;
|
||||
@ -173,7 +173,7 @@ public:
|
||||
|
||||
SDL_Surface *img; //our image
|
||||
bool free; //should surface be freed on delete
|
||||
|
||||
|
||||
SDL_Surface * setSurface(std::string defName, int imgPos);
|
||||
|
||||
void init(Etype Type, int Subtype, int Val);
|
||||
@ -246,7 +246,7 @@ public:
|
||||
|
||||
int p2, //TODO: comment me
|
||||
shiftPos;//1st slot of the second row, set shiftPoint for effect
|
||||
bool splitting, pb,
|
||||
bool splitting, pb,
|
||||
smallIcons, //true - 32x32 imgs, false - 58x64
|
||||
removableUnits,//player can remove units from up
|
||||
twoRows,//slots will be placed in 2 rows
|
||||
@ -262,7 +262,7 @@ public:
|
||||
void setArmy(const CArmedInstance *army, bool bottomGarrison);
|
||||
void addSplitBtn(CAdventureMapButton * button);
|
||||
void createSet(std::vector<CGarrisonSlot*> &ret, const CCreatureSet * set, int posX, int distance, int posY, int Upg );
|
||||
|
||||
|
||||
void activate();
|
||||
void createSlots();
|
||||
void deleteSlots();
|
||||
@ -331,12 +331,12 @@ public:
|
||||
};
|
||||
|
||||
/// draws picture with creature on background, use Animated=true to get animation
|
||||
class CCreaturePic : public CIntObject
|
||||
class CCreaturePic : public CIntObject
|
||||
{
|
||||
private:
|
||||
CPicture *bg; //background
|
||||
CCreatureAnim *anim; //displayed animation
|
||||
|
||||
|
||||
public:
|
||||
CCreaturePic(int x, int y, const CCreature *cre, bool Big=true, bool Animated=true); //c-tor
|
||||
~CCreaturePic(); //d-tor
|
||||
@ -441,33 +441,45 @@ public:
|
||||
/// Town portal, castle gate window
|
||||
class CObjectListWindow : public CIntObject
|
||||
{
|
||||
public:
|
||||
class CItem : public CIntObject
|
||||
{
|
||||
CObjectListWindow *parent;
|
||||
CLabel *text;
|
||||
CPicture *border;
|
||||
public:
|
||||
const size_t index;
|
||||
CItem(CObjectListWindow *parent, size_t id, std::string text);
|
||||
|
||||
void select(bool on);
|
||||
void clickLeft(tribool down, bool previousState);
|
||||
};
|
||||
|
||||
boost::function<void(int)> onSelect;//called when OK button is pressed, returns id of selected item.
|
||||
std::string title,descr;//text for title and description
|
||||
CLabel * title;
|
||||
CLabel * descr;
|
||||
|
||||
CListBox *list;
|
||||
CPicture *bg; //background
|
||||
CSlider *slider;
|
||||
CPicture *titleImage;//title image (castle gate\town portal picture)
|
||||
CAdventureMapButton *ok, *exit;
|
||||
|
||||
std::vector<Rect> areas;//areas for each visible item
|
||||
std::vector<int> items;//id of all items present in list
|
||||
int selected;//currently selected item
|
||||
int length;//size of list (=9)
|
||||
bool init;//true = initialization completed
|
||||
std::vector< std::pair<int, std::string> > items;//all items present in list
|
||||
|
||||
void init(CPicture * titlePic, std::string _title, std::string _descr);
|
||||
public:
|
||||
size_t selected;//index of currently selected item
|
||||
/// Callback will be called when OK button is pressed, returns id of selected item. initState = initially selected item
|
||||
/// Image can be NULL
|
||||
///item names will be taken from map objects
|
||||
CObjectListWindow(const std::vector<int> &_items, CPicture * titlePic, std::string _title, std::string _descr,
|
||||
boost::function<void(int)> Callback, int initState=-1); //c-tor
|
||||
~CObjectListWindow(); //d-tor
|
||||
boost::function<void(int)> Callback);
|
||||
CObjectListWindow(const std::vector<std::string> &_items, CPicture * titlePic, std::string _title, std::string _descr,
|
||||
boost::function<void(int)> Callback);
|
||||
|
||||
void elementSelected();//call callback and exit
|
||||
void moveList(int which);//called when slider moves
|
||||
void clickLeft(tribool down, bool previousState); //call-in
|
||||
void keyPressed (const SDL_KeyboardEvent & key); //call-in
|
||||
void show(SDL_Surface * to);
|
||||
void showAll(SDL_Surface * to);
|
||||
CIntObject *genItem(size_t index);
|
||||
void elementSelected();//call callback and close this window
|
||||
void changeSelection(size_t which);
|
||||
void keyPressed (const SDL_KeyboardEvent & key);
|
||||
};
|
||||
|
||||
class CArtifactHolder : public virtual CIntObject
|
||||
@ -501,10 +513,10 @@ public:
|
||||
};
|
||||
class CTradeableItem : public CIntObject
|
||||
{
|
||||
const CArtifactInstance *hlp; //holds ptr to artifact instance id type artifact
|
||||
const CArtifactInstance *hlp; //holds ptr to artifact instance id type artifact
|
||||
public:
|
||||
EType type;
|
||||
int id;
|
||||
int id;
|
||||
int serial;
|
||||
bool left;
|
||||
std::string subtitle; //empty if default
|
||||
@ -563,7 +575,7 @@ public:
|
||||
virtual void selectionChanged(bool side) = 0; //true == left
|
||||
virtual Point selectionOffset(bool Left) const = 0;
|
||||
virtual std::string selectionSubtitle(bool Left) const = 0;
|
||||
virtual void garrisonChanged() = 0;
|
||||
virtual void garrisonChanged() = 0;
|
||||
virtual void artifactsChanged(bool left) = 0;
|
||||
};
|
||||
|
||||
@ -625,7 +637,7 @@ public:
|
||||
|
||||
Point selectionOffset(bool Left) const;
|
||||
std::string selectionSubtitle(bool Left) const;
|
||||
void garrisonChanged();
|
||||
void garrisonChanged();
|
||||
void artifactsChanged(bool left);
|
||||
void calcTotalExp();
|
||||
void setExpToLevel();
|
||||
@ -639,14 +651,28 @@ public:
|
||||
class CSystemOptionsWindow : public CIntObject
|
||||
{
|
||||
private:
|
||||
SDL_Surface * background; //background of window
|
||||
CLabel *title;
|
||||
CLabelGroup *leftGroup;
|
||||
CLabelGroup *rightGroup;
|
||||
CPicture * bg; //background of window
|
||||
CAdventureMapButton *load, *save, *restart, *mainMenu, *quitGame, *backToMap; //load and restart are not used yet
|
||||
CHighlightableButtonsGroup * heroMoveSpeed;
|
||||
CHighlightableButtonsGroup * mapScrollSpeed;
|
||||
CHighlightableButtonsGroup * musicVolume, * effectsVolume;
|
||||
public:
|
||||
CSystemOptionsWindow(const SDL_Rect & pos, CPlayerInterface * owner); //c-tor
|
||||
~CSystemOptionsWindow(); //d-tor
|
||||
|
||||
//CHighlightableButton * showPath;
|
||||
CHighlightableButton * showReminder;
|
||||
//CHighlightableButton * quickCombat;
|
||||
//CHighlightableButton * videoSubs;
|
||||
CHighlightableButton * newCreatureWin;
|
||||
CHighlightableButton * fullscreen;
|
||||
|
||||
CAdventureMapButton *gameResButton;
|
||||
|
||||
void setMusicVolume( int newVolume );
|
||||
void setSoundVolume( int newVolume );
|
||||
void setHeroMoveSpeed( int newSpeed );
|
||||
void setMapScrollingSpeed( int newSpeed );
|
||||
|
||||
//functions bound to buttons
|
||||
void bsavef(); //save game
|
||||
@ -654,9 +680,18 @@ public:
|
||||
void breturnf(); //return to game
|
||||
void bmainmenuf(); //return to main menu
|
||||
|
||||
//functions for checkboxes
|
||||
void toggleReminder(bool on);
|
||||
void toggleCreatureWin(bool on);
|
||||
void toggleFullscreen(bool on);
|
||||
|
||||
void selectGameRes(bool pregame);
|
||||
void setGameRes(bool pregame, int index);
|
||||
|
||||
void pushSDLEvent(int type, int usercode);
|
||||
|
||||
void showAll(SDL_Surface * to);
|
||||
public:
|
||||
CSystemOptionsWindow(const SDL_Rect & pos, CPlayerInterface * owner); //c-tor
|
||||
};
|
||||
|
||||
class CTavernWindow : public CIntObject
|
||||
@ -740,7 +775,7 @@ class MoraleLuckBox : public LRClickableAreaWTextComp
|
||||
public:
|
||||
bool morale; //true if morale, false if luck
|
||||
bool small;
|
||||
|
||||
|
||||
void set(const IBonusBearer *node);
|
||||
void showAll(SDL_Surface * to);
|
||||
|
||||
@ -753,9 +788,9 @@ class CHeroArea: public CIntObject
|
||||
{
|
||||
public:
|
||||
const CGHeroInstance * hero;
|
||||
|
||||
|
||||
CHeroArea(int x, int y, const CGHeroInstance * _hero);
|
||||
|
||||
|
||||
void clickLeft(tribool down, bool previousState);
|
||||
void clickRight(tribool down, bool previousState);
|
||||
void hover(bool on);
|
||||
@ -888,7 +923,7 @@ class CGarrisonWindow : public CWindowWithGarrison
|
||||
{
|
||||
public:
|
||||
CPicture *bg; //background surface
|
||||
CLabel *title;
|
||||
CLabel *title;
|
||||
CAdventureMapButton *quit;
|
||||
|
||||
void close();
|
||||
|
@ -340,7 +340,7 @@ void CGuiHandler::run()
|
||||
setThreadName(-1, "CGuiHandler::run");
|
||||
try
|
||||
{
|
||||
if (conf.cc.fullscreen)
|
||||
if (settings["video"]["fullscreen"].Bool())
|
||||
CCS->curh->centerCursor();
|
||||
|
||||
mainFPSmng->init(); // resets internal clock, needed for FPS manager
|
||||
|
@ -941,6 +941,16 @@ void CListBox::reset()
|
||||
updatePositions();
|
||||
}
|
||||
|
||||
void CListBox::scrollTo(size_t which)
|
||||
{
|
||||
//scroll up
|
||||
if (first > which)
|
||||
moveToPos(which);
|
||||
//scroll down
|
||||
else if (first + items.size() <= which)
|
||||
moveToPos(which - items.size());
|
||||
}
|
||||
|
||||
void CListBox::moveToPos(size_t which)
|
||||
{
|
||||
//Calculate new position
|
||||
@ -1193,6 +1203,16 @@ void CLabel::setTxt(const std::string &Txt)
|
||||
}
|
||||
}
|
||||
|
||||
CLabelGroup::CLabelGroup(EFonts Font, EAlignment Align, const SDL_Color &Color):
|
||||
font(Font), align(Align), color(Color)
|
||||
{};
|
||||
|
||||
void CLabelGroup::add(int x, int y, const std::string &text)
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||
new CLabel(x, y, font, align, color, text);
|
||||
};
|
||||
|
||||
CTextBox::CTextBox(std::string Text, const Rect &rect, int SliderStyle, EFonts Font /*= FONT_SMALL*/, EAlignment Align /*= TOPLEFT*/, const SDL_Color &Color /*= Colors::Cornsilk*/)
|
||||
:CLabel(rect.x, rect.y, Font, Align, Color, Text), sliderStyle(SliderStyle), slider(NULL)
|
||||
{
|
||||
|
@ -274,7 +274,10 @@ public:
|
||||
//return currently active items
|
||||
std::list< CIntObject * > getItems();
|
||||
|
||||
//scroll list
|
||||
//scroll list to make item which visible
|
||||
void scrollTo(size_t which);
|
||||
|
||||
//scroll list to specified position
|
||||
void moveToPos(size_t which);
|
||||
void moveToNext();
|
||||
void moveToPrev();
|
||||
@ -316,6 +319,18 @@ public:
|
||||
CLabel(int x=0, int y=0, EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = Colors::Cornsilk, const std::string &Text = "");
|
||||
};
|
||||
|
||||
//Small helper class to manage group of similar labels
|
||||
class CLabelGroup : public CIntObject
|
||||
{
|
||||
std::list<CLabel*> labels;
|
||||
EFonts font;
|
||||
EAlignment align;
|
||||
const SDL_Color &color;
|
||||
public:
|
||||
CLabelGroup(EFonts Font = FONT_SMALL, EAlignment Align = TOPLEFT, const SDL_Color &Color = Colors::Cornsilk);
|
||||
void add(int x=0, int y=0, const std::string &text = "");
|
||||
};
|
||||
|
||||
/// a multi-line label that tries to fit text with given available width and height; if not possible, it creates a slider for scrolling text
|
||||
class CTextBox
|
||||
: public CLabel
|
||||
|
142
config/defaultSettings.json
Normal file
142
config/defaultSettings.json
Normal file
@ -0,0 +1,142 @@
|
||||
// This is schema for checking game settings from settings.json
|
||||
// Any new settings should be added in this file for correct serialization and initialization
|
||||
{
|
||||
"general" : {
|
||||
"type" : "object",
|
||||
"properties" : {
|
||||
"classicCreatureWindow" : {
|
||||
"type" : "bool",
|
||||
"default" : false
|
||||
},
|
||||
"playerName" : {
|
||||
"type":"string",
|
||||
"default" : "player"
|
||||
},
|
||||
"showfps" : {
|
||||
"type" : "bool",
|
||||
"default" : false
|
||||
},
|
||||
"music" : {
|
||||
"type" : "number",
|
||||
"default" : 88
|
||||
},
|
||||
"sound" : {
|
||||
"type" : "number",
|
||||
"default" : 88
|
||||
}
|
||||
},
|
||||
"default" : {}
|
||||
},
|
||||
"video" : {
|
||||
"type" : "object",
|
||||
"properties" : {
|
||||
"gameRes" : {
|
||||
"type" : "object",
|
||||
"properties" : {
|
||||
"width" : { "type" : "number" },
|
||||
"height" : { "type" : "number" }
|
||||
},
|
||||
"default": {"width" : 800, "height": 600 }
|
||||
},
|
||||
"menuRes" : {
|
||||
"type" : "object",
|
||||
"properties" : {
|
||||
"width" : { "type" : "number" },
|
||||
"height" : { "type" : "number" }
|
||||
},
|
||||
"default": {"width" : 800, "height": 600 }
|
||||
},
|
||||
"screenRes" : {
|
||||
"type" : "object",
|
||||
"properties" : {
|
||||
"width" : { "type" : "number" },
|
||||
"height" : { "type" : "number" }
|
||||
},
|
||||
"default": {"width" : 0, "height": 0 }
|
||||
},
|
||||
"bitsPerPixel" : {
|
||||
"type" : "number",
|
||||
"default" : 24
|
||||
},
|
||||
"fullscreen" : {
|
||||
"type" : "bool",
|
||||
"default" : false
|
||||
}
|
||||
},
|
||||
"default" : {}
|
||||
},
|
||||
"adventure" : {
|
||||
"type" : "object",
|
||||
"properties" : {
|
||||
"heroSpeed" : {
|
||||
"type" : "number",
|
||||
"default" : 2
|
||||
},
|
||||
"enemySpeed" : {
|
||||
"type" : "number",
|
||||
"default" : 2
|
||||
},
|
||||
"scrollSpeed" : {
|
||||
"type" : "number",
|
||||
"default" : 1
|
||||
},
|
||||
"heroReminder" : {
|
||||
"type" : "bool",
|
||||
"default" : true
|
||||
}
|
||||
},
|
||||
"default" : {}
|
||||
},
|
||||
"battle" : {
|
||||
"type" : "object",
|
||||
"properties" : {
|
||||
"animationSpeed" : {
|
||||
"type" : "number",
|
||||
"default" : 2
|
||||
},
|
||||
"mouseShadow" : {
|
||||
"type":"bool",
|
||||
"default" : true
|
||||
},
|
||||
"cellBorders" : {
|
||||
"type" : "bool",
|
||||
"default" : false
|
||||
},
|
||||
"stackRange" : {
|
||||
"type" : "bool",
|
||||
"default" : true
|
||||
},
|
||||
"showQueue" : {
|
||||
"type" : "bool",
|
||||
"default" : true
|
||||
}
|
||||
},
|
||||
"default" : {}
|
||||
},
|
||||
"server" : {
|
||||
"type" : "object",
|
||||
"properties" : {
|
||||
"server" : {
|
||||
"type":"string",
|
||||
"default" : "127.0.0.1"
|
||||
},
|
||||
"port" : {
|
||||
"type" : "number",
|
||||
"default" : 3030
|
||||
},
|
||||
"localInformation" : {
|
||||
"type" : "number",
|
||||
"default" : 2
|
||||
},
|
||||
"playerAI" : {
|
||||
"type" : "string",
|
||||
"default" : "GeniusAI"
|
||||
},
|
||||
"neutralAI" : {
|
||||
"type" : "string",
|
||||
"default" : "StupidAI"
|
||||
}
|
||||
},
|
||||
"default" : {}
|
||||
}
|
||||
}
|
@ -1,3 +1,8 @@
|
||||
THIS FILE IS OUTDATED
|
||||
- to change setting including resolution: use in-game menu
|
||||
- to change setting manually: file settings.json
|
||||
- to add new options or to modify default values: file defaultSettings.json
|
||||
|
||||
//DO NOT EDIT!!!
|
||||
//DO NOT READ!
|
||||
clientSettings
|
||||
|
107
lib/JsonNode.cpp
107
lib/JsonNode.cpp
@ -69,6 +69,38 @@ JsonNode & JsonNode::operator =(JsonNode node)
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool JsonNode::operator == (const JsonNode &other) const
|
||||
{
|
||||
if (getType() == other.getType())
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
break; case DATA_NULL: return true;
|
||||
break; case DATA_BOOL: return Bool() == other.Bool();
|
||||
break; case DATA_FLOAT: return Float() == other.Float();
|
||||
break; case DATA_STRING: return String() == other.String();
|
||||
break; case DATA_VECTOR: return Vector() == other.Vector();
|
||||
break; case DATA_STRUCT: return Struct() == other.Struct();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool JsonNode::operator != (const JsonNode &other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
void JsonNode::minimize(const JsonNode& schema)
|
||||
{
|
||||
JsonValidator validator(*this, schema, true);
|
||||
}
|
||||
|
||||
void JsonNode::validate(const JsonNode& schema)
|
||||
{
|
||||
JsonValidator validator(*this, schema, false);
|
||||
}
|
||||
|
||||
JsonNode::JsonType JsonNode::getType() const
|
||||
{
|
||||
return type;
|
||||
@ -687,6 +719,11 @@ bool JsonValidator::validateType(JsonNode &node, const JsonNode &schema, JsonNod
|
||||
else
|
||||
node = defaultValue;
|
||||
}
|
||||
if (minimize && node == schema["default"])
|
||||
{
|
||||
node.setType(JsonNode::DATA_NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (type != node.getType())
|
||||
{
|
||||
@ -709,18 +746,13 @@ bool JsonValidator::validateNode(JsonNode &node, const JsonNode &schema, const s
|
||||
currentPath.push_back(name);
|
||||
|
||||
JsonNode::JsonType type = JsonNode::DATA_NULL;
|
||||
if (!validateSchema(type, schema))
|
||||
if (!validateSchema(type, schema)
|
||||
|| !validateType(node, schema, type))
|
||||
{
|
||||
node.setType(JsonNode::DATA_NULL);
|
||||
currentPath.pop_back();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!validateType(node, schema, type))
|
||||
{
|
||||
currentPath.pop_back();
|
||||
return false;
|
||||
}
|
||||
|
||||
currentPath.pop_back();
|
||||
return true;
|
||||
}
|
||||
@ -732,12 +764,16 @@ bool JsonValidator::validateItems(JsonNode &node, const JsonNode &schema)
|
||||
if (!validateSchema(type, schema))
|
||||
return false;
|
||||
|
||||
bool result = true;
|
||||
BOOST_FOREACH(JsonNode &entry, node.Vector())
|
||||
{
|
||||
if (!validateType(entry, schema, type))
|
||||
return false;
|
||||
{
|
||||
result = false;
|
||||
entry.setType(JsonNode::DATA_NULL);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return result;
|
||||
}
|
||||
|
||||
//Checks "propertries" entry from schema (type-specific check for Struct)
|
||||
@ -752,29 +788,40 @@ bool JsonValidator::validateProperties(JsonNode &node, const JsonNode &schema)
|
||||
|
||||
while (nodeIter != node.Struct().end() && schemaIter != schema.Struct().end())
|
||||
{
|
||||
std::string current = std::min(nodeIter->first, schemaIter->first);
|
||||
validateNode(node[current], schema[current], current);
|
||||
|
||||
if (nodeIter->first < schemaIter->first)
|
||||
nodeIter++;
|
||||
else
|
||||
if (schemaIter->first < nodeIter->first)
|
||||
schemaIter++;
|
||||
else
|
||||
if (nodeIter->first < schemaIter->first) //No schema for entry
|
||||
{
|
||||
nodeIter++;
|
||||
validateNode(nodeIter->second, JsonNode::nullNode, nodeIter->first);
|
||||
|
||||
JsonMap::iterator toRemove = nodeIter++;
|
||||
node.Struct().erase(toRemove);
|
||||
}
|
||||
else
|
||||
if (schemaIter->first < nodeIter->first) //No entry
|
||||
{
|
||||
if (!validateNode(node[schemaIter->first], schemaIter->second, schemaIter->first))
|
||||
node.Struct().erase(schemaIter->first);
|
||||
schemaIter++;
|
||||
}
|
||||
else //both entry and schema are present
|
||||
{
|
||||
JsonMap::iterator current = nodeIter++;
|
||||
if (!validateNode(current->second, schemaIter->second, current->first))
|
||||
node.Struct().erase(current);
|
||||
|
||||
schemaIter++;
|
||||
}
|
||||
}
|
||||
while (nodeIter != node.Struct().end())
|
||||
{
|
||||
validateNode(nodeIter->second, JsonNode(), nodeIter->first);
|
||||
nodeIter++;
|
||||
validateNode(nodeIter->second, JsonNode::nullNode, nodeIter->first);
|
||||
JsonMap::iterator toRemove = nodeIter++;
|
||||
node.Struct().erase(toRemove);
|
||||
}
|
||||
|
||||
while (schemaIter != schema.Struct().end())
|
||||
{
|
||||
validateNode(node[schemaIter->first], schemaIter->second, schemaIter->first);
|
||||
if (!validateNode(node[schemaIter->first], schemaIter->second, schemaIter->first))
|
||||
node.Struct().erase(schemaIter->first);
|
||||
schemaIter++;
|
||||
}
|
||||
return true;
|
||||
@ -792,14 +839,15 @@ bool JsonValidator::addMessage(const std::string &message)
|
||||
return false;
|
||||
}
|
||||
|
||||
JsonValidator::JsonValidator(JsonNode &root)
|
||||
JsonValidator::JsonValidator(JsonNode &root, bool Minimize):
|
||||
minimize(Minimize)
|
||||
{
|
||||
JsonNode schema;
|
||||
schema.swap(root["schema"]);
|
||||
root.Struct().erase("schema");
|
||||
|
||||
if (!schema.isNull())
|
||||
{
|
||||
root.Struct().erase("schema");
|
||||
validateProperties(root, schema);
|
||||
}
|
||||
//This message is quite annoying now - most files do not have schemas. May be re-enabled later
|
||||
@ -809,3 +857,12 @@ JsonValidator::JsonValidator(JsonNode &root)
|
||||
//TODO: better way to show errors (like printing file name as well)
|
||||
tlog3<<errors;
|
||||
}
|
||||
|
||||
JsonValidator::JsonValidator(JsonNode &root, const JsonNode &schema, bool Minimize):
|
||||
minimize(Minimize)
|
||||
{
|
||||
validateProperties(root, schema);
|
||||
if (schema.isNull())
|
||||
addMessage("Schema not found!");
|
||||
tlog3<<errors;
|
||||
}
|
||||
|
@ -47,6 +47,14 @@ public:
|
||||
void swap(JsonNode &b);
|
||||
JsonNode& operator =(JsonNode node);
|
||||
|
||||
bool operator == (const JsonNode &other) const;
|
||||
bool operator != (const JsonNode &other) const;
|
||||
|
||||
//removes all nodes that are identical to default entry in schema
|
||||
void minimize(const JsonNode& schema);
|
||||
//check schema
|
||||
void validate(const JsonNode& schema);
|
||||
|
||||
//Convert node to another type. Converting to NULL will clear all data
|
||||
void setType(JsonType Type);
|
||||
JsonType getType() const;
|
||||
@ -161,6 +169,7 @@ class JsonValidator
|
||||
{
|
||||
std::string errors; // Contains description of all encountered errors
|
||||
std::list<std::string> currentPath; // path from root node to current one
|
||||
bool minimize;
|
||||
|
||||
bool validateType(JsonNode &node, const JsonNode &schema, JsonNode::JsonType type);
|
||||
bool validateSchema(JsonNode::JsonType &type, const JsonNode &schema);
|
||||
@ -170,5 +179,8 @@ class JsonValidator
|
||||
|
||||
bool addMessage(const std::string &message);
|
||||
public:
|
||||
JsonValidator(JsonNode &root);
|
||||
// validate node with "schema" entry
|
||||
JsonValidator(JsonNode &root, bool minimize=false);
|
||||
// validate with external schema
|
||||
JsonValidator(JsonNode &root, const JsonNode &schema, bool minimize=false);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user