1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-07-17 01:32:21 +02:00

- made main menu configurable (mainmenu.json)

- added credits screen (using NWC credits for now)
- campaigns can be started
This commit is contained in:
Ivan Savenko
2011-11-27 13:14:20 +00:00
parent e02ccb24a5
commit 064466998a
19 changed files with 1039 additions and 1097 deletions

View File

@ -48,7 +48,10 @@ void CButtonBase::update()
text->moveTo(Point(pos.x+pos.w/2, pos.y+pos.h/2)); text->moveTo(Point(pos.x+pos.w/2, pos.y+pos.h/2));
} }
size_t newPos = (int)state + bitmapOffset; int newPos = (int)state + bitmapOffset;
if (newPos < 0)
newPos = 0;
if (state == HIGHLIGHTED && image->size() < 4) if (state == HIGHLIGHTED && image->size() < 4)
newPos = image->size()-1; newPos = image->size()-1;
@ -353,7 +356,8 @@ void CHighlightableButtonsGroup::addButton(const std::map<int,std::string> &tool
CHighlightableButton *bt = new CHighlightableButton(OnSelect, 0, tooltip, HelpBox, false, defName, 0, x, y, key); CHighlightableButton *bt = new CHighlightableButton(OnSelect, 0, tooltip, HelpBox, false, defName, 0, x, y, key);
if(musicLike) if(musicLike)
{ {
bt->setOffset(buttons.size() - 3); if (buttons.size() > 3)
bt->setOffset(buttons.size()-3);
} }
bt->ID = uid; bt->ID = uid;
bt->callback += boost::bind(&CHighlightableButtonsGroup::selectionChanged,this,bt->ID); bt->callback += boost::bind(&CHighlightableButtonsGroup::selectionChanged,this,bt->ID);
@ -393,6 +397,8 @@ void CHighlightableButtonsGroup::selectionChanged(int to)
if(buttons[i]->ID!=to && buttons[i]->isHighlighted()) if(buttons[i]->ID!=to && buttons[i]->isHighlighted())
buttons[i]->select(false); buttons[i]->select(false);
onChange(to); onChange(to);
if (parent)
parent->redraw();
} }
void CHighlightableButtonsGroup::show(SDL_Surface * to ) void CHighlightableButtonsGroup::show(SDL_Surface * to )

View File

@ -1376,11 +1376,14 @@ CHallInterface::CHallInterface(const CGTownInstance *Town):
int buildingID = boxList[row][col][item]; int buildingID = boxList[row][col][item];
building = CGI->buildh->buildings[town->subID][buildingID]; building = CGI->buildh->buildings[town->subID][buildingID];
if ( (buildingID == 18 && !vstd::contains(town->builtBuildings, town->town->hordeLvl[0]+37)) if (buildingID == 18 || buildingID == 24)
|| (buildingID == 24 && !vstd::contains(town->builtBuildings, town->town->hordeLvl[1]+37)) ) {
break; // horde present, no upgraded dwelling -> select 18 or 24 if ( (buildingID == 18 && !vstd::contains(town->builtBuildings, town->town->hordeLvl[0]+37))
else || (buildingID == 24 && !vstd::contains(town->builtBuildings, town->town->hordeLvl[1]+37)) )
continue; //upgraded dwelling, no horde -> select 19 or 25 break; // horde present, no upgraded dwelling -> select 18 or 24
else
continue; //upgraded dwelling, no horde -> select 19 or 25
}
if(vstd::contains(town->builtBuildings,buildingID)) if(vstd::contains(town->builtBuildings,buildingID))
continue; continue;

View File

@ -466,232 +466,6 @@ bool InfoBoxCustom::prepareMessage(std::string &text, SComponent **comp)
return false; return false;
} }
CObjectList::CObjectList(IGuiObjectListManager *Manager):
manager(Manager)
{
}
CObjectList::~CObjectList()
{
delete manager;
}
void CObjectList::deleteItem(CIntObject* item)
{
if (!item)
return;
if (active)
item->deactivate();
removeChild(item);
manager->removeObject(item);
}
CIntObject* CObjectList::createItem(size_t index)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
CIntObject * item = manager->getObject(index);
if (item == NULL)
item = new CIntObject();
item->recActions = defActions;
//May happen if object was created before call to getObject()
if(item->parent != this)
{
if (item->parent)
moveChild(item, item->parent, this);
else
addChild(item);
}
if (item && active)
item->activate();
return item;
}
CTabbedInt::CTabbedInt(IGuiObjectListManager *Manager, Point position, size_t ActiveID):
CObjectList(Manager),
activeTab(NULL),
activeID(ActiveID)
{
pos += position;
reset();
}
void CTabbedInt::setActive(size_t which)
{
if (which != activeID)
{
activeID = which;
reset();
}
}
void CTabbedInt::reset()
{
deleteItem(activeTab);
activeTab = createItem(activeID);
activeTab->moveTo(pos.topLeft());
if (active)
redraw();
}
CIntObject * CTabbedInt::getItem()
{
return activeTab;
}
CListBox::CListBox(IGuiObjectListManager *Manager, Point Pos, Point ItemOffset, size_t VisibleSize,
size_t TotalSize, size_t InitialPos, int Slider, Rect SliderPos):
CObjectList(Manager),
first(InitialPos),
totalSize(TotalSize),
itemOffset(ItemOffset)
{
pos += Pos;
items.resize(VisibleSize, NULL);
if (Slider & 1)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
slider = new CSlider(SliderPos.x, SliderPos.y, SliderPos.w, boost::bind(&CListBox::moveToPos, this, _1),
VisibleSize, TotalSize, InitialPos, Slider & 2, Slider & 4);
}
reset();
}
// Used to move active items after changing list position
void CListBox::updatePositions()
{
Point itemPos = pos.topLeft();
for (std::list<CIntObject*>::iterator it = items.begin(); it!=items.end(); it++)
{
(*it)->moveTo(itemPos);
itemPos += itemOffset;
}
if (active)
{
redraw();
if (slider)
slider->moveTo(first);
}
}
void CListBox::reset()
{
size_t current = first;
for (std::list<CIntObject*>::iterator it = items.begin(); it!=items.end(); it++)
{
deleteItem(*it);
*it = createItem(current++);
}
updatePositions();
}
void CListBox::moveToPos(size_t which)
{
//Calculate new position
size_t maxPossible;
if (totalSize > items.size())
maxPossible = totalSize - items.size();
else
maxPossible = 0;
size_t newPos = std::min(which, maxPossible);
//If move distance is 1 (most of calls from Slider) - use faster shifts instead of resetting all items
if (first - newPos == 1)
moveToPrev();
else if (newPos - first == 1)
moveToNext();
else if (newPos != first)
{
first = newPos;
reset();
}
}
void CListBox::moveToNext()
{
//Remove front item and insert new one to end
if (first + items.size() < totalSize)
{
first++;
deleteItem(items.front());
items.pop_front();
items.push_back(createItem(first+items.size()));
updatePositions();
}
}
void CListBox::moveToPrev()
{
//Remove last item and insert new one at start
if (first)
{
first--;
deleteItem(items.back());
items.pop_back();
items.push_front(createItem(first));
updatePositions();
}
}
std::list<CIntObject*> CListBox::getItems()
{
return items;
}
struct OwnedObjectInfo
{
int imageID;
unsigned int count;
std::string hoverText;
};
class OwnedObjectsListManager : public IGuiObjectListManager
{
std::vector<OwnedObjectInfo> objects;
public:
virtual CIntObject * getObject(size_t position)
{
if (position < objects.size())
{
OwnedObjectInfo &obj = objects[position];
std::string value = boost::lexical_cast<std::string>(obj.count);
return new InfoBox(Point(), InfoBox::POS_CORNER, InfoBox::SIZE_SMALL,
new InfoBoxCustom(value,"", "FLAGPORT", obj.imageID, obj.hoverText));
}
return NULL;
}
OwnedObjectsListManager(std::vector<OwnedObjectInfo> Objects):
objects(Objects)
{
}
};
class TownHeroListManager : public IGuiObjectListManager
{
public:
CIntObject *currentItem;
CIntObject *getObject(size_t position)
{
size_t size = conf.go()->ac.overviewSize;
switch (position)
{
case 0:
return new CKingdHeroList(size);
case 1:
return new CKingdTownList(size);
default:
return NULL;
}
}
};
CKingdomInterface::CKingdomInterface() CKingdomInterface::CKingdomInterface()
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJ_CONSTRUCTION_CAPTURING_ALL;
@ -700,7 +474,7 @@ CKingdomInterface::CKingdomInterface()
pos = background->center(); pos = background->center();
unsigned int footerPos = conf.go()->ac.overviewSize * 116; unsigned int footerPos = conf.go()->ac.overviewSize * 116;
tabArea = new CTabbedInt(new TownHeroListManager, Point(4,4)); tabArea = new CTabbedInt(boost::bind(&CKingdomInterface::createMainTab, this, _1), CTabbedInt::DestroyFunc(), Point(4,4));
std::vector<const CGObjectInstance * > ownedObjects = LOCPLINT->cb->getMyObjects(); std::vector<const CGObjectInstance * > ownedObjects = LOCPLINT->cb->getMyObjects();
generateObjectsList(ownedObjects); generateObjectsList(ownedObjects);
@ -753,15 +527,38 @@ void CKingdomInterface::generateObjectsList(const std::vector<const CGObjectInst
} }
} }
} }
std::vector<OwnedObjectInfo> objectsVector; objects.reserve(visibleObjects.size());
objectsVector.reserve(visibleObjects.size());
std::pair<int, OwnedObjectInfo> element; std::pair<int, OwnedObjectInfo> element;
BOOST_FOREACH(element, visibleObjects) BOOST_FOREACH(element, visibleObjects)
{ {
objectsVector.push_back(element.second); objects.push_back(element.second);
}
dwellingsList = new CListBox(boost::bind(&CKingdomInterface::createOwnedObject, this, _1), CListBox::DestroyFunc(),
Point(740,44), Point(0,57), dwellSize, visibleObjects.size());
}
CIntObject* CKingdomInterface::createOwnedObject(size_t index)
{
if (index < objects.size())
{
OwnedObjectInfo &obj = objects[index];
std::string value = boost::lexical_cast<std::string>(obj.count);
return new InfoBox(Point(), InfoBox::POS_CORNER, InfoBox::SIZE_SMALL,
new InfoBoxCustom(value,"", "FLAGPORT", obj.imageID, obj.hoverText));
}
return NULL;
}
CIntObject * CKingdomInterface::createMainTab(size_t index)
{
size_t size = conf.go()->ac.overviewSize;
switch (index)
{
case 0: return new CKingdHeroList(size);
case 1: return new CKingdTownList(size);
default:return NULL;
} }
dwellingsList = new CListBox(new OwnedObjectsListManager(objectsVector), Point(740,44), Point(0,57), dwellSize, visibleObjects.size());
} }
void CKingdomInterface::generateMinesList(const std::vector<const CGObjectInstance * > &ownedObjects) void CKingdomInterface::generateMinesList(const std::vector<const CGObjectInstance * > &ownedObjects)
@ -887,56 +684,6 @@ void CKingdomInterface::artifactRemoved(const ArtifactLocation& artLoc)
arts->artifactRemoved(artLoc); arts->artifactRemoved(artLoc);
} }
class HeroListManager : public IGuiObjectListManager
{
CWindowWithArtifacts * arts;
CArtifactsOfHero::SCommonPart * artsCommonPart;
public:
HeroListManager(CWindowWithArtifacts * parent);
~HeroListManager();
CIntObject * getObject(size_t position);
void removeObject(CIntObject *object);
};
HeroListManager::HeroListManager(CWindowWithArtifacts * parent)
{
arts = parent;
artsCommonPart = new CArtifactsOfHero::SCommonPart;
}
HeroListManager::~HeroListManager()
{
delete artsCommonPart;
}
CIntObject * HeroListManager::getObject(size_t position)
{
unsigned int picCount = conf.go()->ac.overviewPics;
size_t heroesCount = LOCPLINT->cb->howManyHeroes(false);
if (position < heroesCount)
{
CHeroItem * hero = new CHeroItem(LOCPLINT->cb->getHeroBySerial(position, false), artsCommonPart);
artsCommonPart->participants.insert(hero->heroArts);
arts->artSets.push_back(hero->heroArts);
return hero;
}
else
{
return new CAnimImage("OVSLOT", (position-2) % picCount );
}
};
void HeroListManager::removeObject(CIntObject *object)
{
if (CHeroItem * hero = dynamic_cast<CHeroItem*>(object))
{
arts->artSets.erase(std::find(arts->artSets.begin(), arts->artSets.end(), hero->heroArts));
artsCommonPart->participants.erase(hero->heroArts);
}
delete object;
}
CKingdHeroList::CKingdHeroList(size_t maxSize) CKingdHeroList::CKingdHeroList(size_t maxSize)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJ_CONSTRUCTION_CAPTURING_ALL;
@ -947,7 +694,8 @@ CKingdHeroList::CKingdHeroList(size_t maxSize)
unsigned int townCount = LOCPLINT->cb->howManyHeroes(false); unsigned int townCount = LOCPLINT->cb->howManyHeroes(false);
unsigned int size = conf.go()->ac.overviewSize*116 + 19; unsigned int size = conf.go()->ac.overviewSize*116 + 19;
heroes = new CListBox(new HeroListManager(this), Point(19,21), Point(0,116), maxSize, townCount, 0, 1, Rect(-19, -21, size, size) ); heroes = new CListBox(boost::bind(&CKingdHeroList::createHeroItem, this, _1), boost::bind(&CKingdHeroList::destroyHeroItem, this, _1),
Point(19,21), Point(0,116), maxSize, townCount, 0, 1, Rect(-19, -21, size, size) );
} }
void CKingdHeroList::updateGarrisons() void CKingdHeroList::updateGarrisons()
@ -960,20 +708,33 @@ void CKingdHeroList::updateGarrisons()
} }
} }
class TownListManager : public IGuiObjectListManager CIntObject* CKingdHeroList::createHeroItem(size_t index)
{ {
public: unsigned int picCount = conf.go()->ac.overviewPics;
CIntObject * getObject(size_t position) size_t heroesCount = LOCPLINT->cb->howManyHeroes(false);
{
unsigned int picCount = conf.go()->ac.overviewPics;
size_t townsCount = LOCPLINT->cb->howManyTowns();
if (position < townsCount) if (index < heroesCount)
return new CTownItem(LOCPLINT->cb->getTownBySerial(position)); {
else CHeroItem * hero = new CHeroItem(LOCPLINT->cb->getHeroBySerial(index, false), &artsCommonPart);
return new CAnimImage("OVSLOT", (position-2) % picCount ); artsCommonPart.participants.insert(hero->heroArts);
artSets.push_back(hero->heroArts);
return hero;
} }
}; else
{
return new CAnimImage("OVSLOT", (index-2) % picCount );
}
}
void CKingdHeroList::destroyHeroItem(CIntObject *object)
{
if (CHeroItem * hero = dynamic_cast<CHeroItem*>(object))
{
artSets.erase(std::find(artSets.begin(), artSets.end(), hero->heroArts));
artsCommonPart.participants.erase(hero->heroArts);
}
delete object;
}
CKingdTownList::CKingdTownList(size_t maxSize) CKingdTownList::CKingdTownList(size_t maxSize)
{ {
@ -986,7 +747,8 @@ CKingdTownList::CKingdTownList(size_t maxSize)
unsigned int townCount = LOCPLINT->cb->howManyTowns(); unsigned int townCount = LOCPLINT->cb->howManyTowns();
unsigned int size = conf.go()->ac.overviewSize*116 + 19; unsigned int size = conf.go()->ac.overviewSize*116 + 19;
towns = new CListBox(new TownListManager, Point(19,21), Point(0,116), maxSize, townCount, 0, 1, Rect(-19, -21, size, size) ); towns = new CListBox(boost::bind(&CKingdTownList::createTownItem, this, _1), CListBox::DestroyFunc(),
Point(19,21), Point(0,116), maxSize, townCount, 0, 1, Rect(-19, -21, size, size) );
} }
void CKingdTownList::townChanged(const CGTownInstance *town) void CKingdTownList::townChanged(const CGTownInstance *town)
@ -1010,6 +772,17 @@ void CKingdTownList::updateGarrisons()
} }
} }
CIntObject* CKingdTownList::createTownItem(size_t index)
{
unsigned int picCount = conf.go()->ac.overviewPics;
size_t townsCount = LOCPLINT->cb->howManyTowns();
if (index < townsCount)
return new CTownItem(LOCPLINT->cb->getTownBySerial(index));
else
return new CAnimImage("OVSLOT", (index-2) % picCount );
}
CTownItem::CTownItem(const CGTownInstance* Town): CTownItem::CTownItem(const CGTownInstance* Town):
town(Town) town(Town)
{ {
@ -1102,64 +875,33 @@ public:
} }
}; };
class HeroItemManager : public CIntObject, public IGuiObjectListManager
{
public:
ArtSlotsTab* tab1;
ArtSlotsTab* tab2;
BackpackTab* tab3;
HeroItemManager(const CGHeroInstance* Hero);
CIntObject * getObject(size_t position);
void removeObject(CIntObject * object);
};
HeroItemManager::HeroItemManager(const CGHeroInstance* Hero)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
recActions = 0;
defActions = DISPOSE | SHARE_POS;
tab1 = new ArtSlotsTab;
tab2 = new ArtSlotsTab;
tab3 = new BackpackTab;
}
CIntObject * HeroItemManager::getObject(size_t position)
{
switch (position)
{
case 0: return tab1;
case 1: return tab2;
case 2: return tab3;
default: assert(0);
return NULL;
}
}
void HeroItemManager::removeObject(CIntObject * object)
{
addChild(object, false);
}
CHeroItem::CHeroItem(const CGHeroInstance* Hero, CArtifactsOfHero::SCommonPart * artsCommonPart): CHeroItem::CHeroItem(const CGHeroInstance* Hero, CArtifactsOfHero::SCommonPart * artsCommonPart):
hero(Hero) hero(Hero)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJ_CONSTRUCTION_CAPTURING_ALL;
artTabs.resize(3);
ArtSlotsTab* arts1 = new ArtSlotsTab;
ArtSlotsTab* arts2 = new ArtSlotsTab;
BackpackTab* backpack = new BackpackTab;
artTabs[0] = arts1;
artTabs[1] = arts2;
artTabs[2] = backpack;
arts1->recActions = DISPOSE | SHARE_POS;
arts2->recActions = DISPOSE | SHARE_POS;
backpack->recActions = DISPOSE | SHARE_POS;
name = new CLabel(75, 7, FONT_SMALL, TOPLEFT, zwykly, hero->name); name = new CLabel(75, 7, FONT_SMALL, TOPLEFT, zwykly, hero->name);
HeroItemManager *manager = new HeroItemManager(hero);
std::vector<CArtPlace*> arts; std::vector<CArtPlace*> arts;
arts.insert(arts.end(), manager->tab1->arts.begin(), manager->tab1->arts.end()); arts.insert(arts.end(), arts1->arts.begin(), arts1->arts.end());
arts.insert(arts.end(), manager->tab2->arts.begin(), manager->tab2->arts.end()); arts.insert(arts.end(), arts2->arts.begin(), arts2->arts.end());
heroArts = new CArtifactsOfHero(arts, manager->tab3->arts, manager->tab3->btnLeft, manager->tab3->btnRight, false); heroArts = new CArtifactsOfHero(arts, backpack->arts, backpack->btnLeft, backpack->btnRight, false);
heroArts->commonInfo = artsCommonPart; heroArts->commonInfo = artsCommonPart;
heroArts->setHero(hero); heroArts->setHero(hero);
artsTabs = new CTabbedInt(manager); artsTabs = new CTabbedInt(boost::bind(&CHeroItem::onTabSelected, this, _1), boost::bind(&CHeroItem::onTabDeselected, this, _1));
artButtons = new CHighlightableButtonsGroup(0); artButtons = new CHighlightableButtonsGroup(0);
for (size_t it = 0; it<3; it++) for (size_t it = 0; it<3; it++)
@ -1211,6 +953,17 @@ CHeroItem::CHeroItem(const CGHeroInstance* Hero, CArtifactsOfHero::SCommonPart *
luck->set(hero); luck->set(hero);
} }
CIntObject * CHeroItem::onTabSelected(size_t index)
{
return artTabs[index];
}
void CHeroItem::onTabDeselected(CIntObject *object)
{
addChild(object, false);
object->recActions = DISPOSE | SHARE_POS;
}
void CHeroItem::onArtChange(int tabIndex) void CHeroItem::onArtChange(int tabIndex)
{ {
//redraw item after background change //redraw item after background change

View File

@ -195,99 +195,18 @@ public:
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// Interface used in CTabbedInt and CListBox
class IGuiObjectListManager
{
public:
//Create object for specified position, may return NULL if no object is needed at this position
//NOTE: position may be greater then size (empty rows in ListBox)
virtual CIntObject * getObject(size_t position)=0;
//Called when object needs to be removed
virtual void removeObject(CIntObject * object)
{
delete object;
};
virtual ~IGuiObjectListManager(){};
};
/// Used as base for Tabs and List classes
class CObjectList : public CIntObject
{
IGuiObjectListManager *manager;
protected:
//Internal methods for safe creation of items (Children capturing and activation/deactivation if needed)
void deleteItem(CIntObject* item);
CIntObject* createItem(size_t index);
public:
CObjectList(IGuiObjectListManager *Manager);
~CObjectList();
};
/// Window element with multiple tabs
class CTabbedInt : public CObjectList
{
private:
CIntObject * activeTab;
size_t activeID;
public:
//Manager - object which implements this interface, will be destroyed by TabbedInt
//Pos - position of object, all tabs will be moved here
//ActiveID - ID of initially active tab
CTabbedInt(IGuiObjectListManager *Manager, Point position=Point(), size_t ActiveID=0);
void setActive(size_t which);
//recreate active tab
void reset();
//return currently active item
CIntObject * getItem();
};
/// List of IntObjects with optional slider
class CListBox : public CObjectList
{
private:
std::list< CIntObject* > items;
size_t first;
size_t totalSize;
Point itemOffset;
CSlider * slider;
void updatePositions();
public:
//Manager - object which implements this interface, will be destroyed by ListBox
//Pos - position of first item
//ItemOffset - distance between items in the list
//VisibleSize - maximal number of displayable at once items
//TotalSize
//Slider - slider style, bit field: 1 = present(disabled), 2=horisontal(vertical), 4=blue(brown)
//SliderPos - position of slider, if present
CListBox(IGuiObjectListManager *Manager, Point Pos, Point ItemOffset, size_t VisibleSize,
size_t TotalSize, size_t InitialPos=0, int Slider=0, Rect SliderPos=Rect() );
//recreate all visible items
void reset();
//return currently active items
std::list< CIntObject * > getItems();
//scroll list
void moveToPos(size_t which);
void moveToNext();
void moveToPrev();
};
////////////////////////////////////////////////////////////////////////////////
/// Class which holds all parts of kingdom overview window /// Class which holds all parts of kingdom overview window
class CKingdomInterface : public CGarrisonHolder, public CArtifactHolder class CKingdomInterface : public CGarrisonHolder, public CArtifactHolder
{ {
private: private:
struct OwnedObjectInfo
{
int imageID;
unsigned int count;
std::string hoverText;
};
std::vector<OwnedObjectInfo> objects;
CListBox * dwellingsList; CListBox * dwellingsList;
CTabbedInt * tabArea; CTabbedInt * tabArea;
CPicture * background; CPicture * background;
@ -316,6 +235,9 @@ private:
void generateObjectsList(const std::vector<const CGObjectInstance * > &ownedObjects); void generateObjectsList(const std::vector<const CGObjectInstance * > &ownedObjects);
void generateMinesList(const std::vector<const CGObjectInstance * > &ownedObjects); void generateMinesList(const std::vector<const CGObjectInstance * > &ownedObjects);
CIntObject* createOwnedObject(size_t index);
CIntObject* createMainTab(size_t index);
public: public:
CKingdomInterface(); CKingdomInterface();
@ -356,6 +278,8 @@ class CHeroItem : public CWindowWithGarrison
{ {
const CGHeroInstance * hero; const CGHeroInstance * hero;
std::vector<CIntObject *> artTabs;
CAnimImage *background; CAnimImage *background;
CAnimImage *portrait; CAnimImage *portrait;
CLabel *name; CLabel *name;
@ -370,6 +294,9 @@ class CHeroItem : public CWindowWithGarrison
void onArtChange(int tabIndex); void onArtChange(int tabIndex);
CIntObject * onTabSelected(size_t index);
void onTabDeselected(CIntObject *object);
public: public:
CArtifactsOfHero *heroArts; CArtifactsOfHero *heroArts;
@ -380,12 +307,16 @@ public:
class CKingdHeroList : public CGarrisonHolder, public CWindowWithArtifacts class CKingdHeroList : public CGarrisonHolder, public CWindowWithArtifacts
{ {
private: private:
CArtifactsOfHero::SCommonPart artsCommonPart;
std::vector<CHeroItem*> heroItems; std::vector<CHeroItem*> heroItems;
CListBox * heroes; CListBox * heroes;
CPicture * title; CPicture * title;
CLabel * heroLabel; CLabel * heroLabel;
CLabel * skillsLabel; CLabel * skillsLabel;
CIntObject* createHeroItem(size_t index);
void destroyHeroItem(CIntObject *item);
public: public:
CKingdHeroList(size_t maxSize); CKingdHeroList(size_t maxSize);
@ -403,6 +334,7 @@ private:
CLabel * garrHeroLabel; CLabel * garrHeroLabel;
CLabel * visitHeroLabel; CLabel * visitHeroLabel;
CIntObject* createTownItem(size_t index);
public: public:
CKingdTownList(size_t maxSize); CKingdTownList(size_t maxSize);

File diff suppressed because it is too large Load Diff

View File

@ -28,6 +28,7 @@ class CGStatusBar;
class CTextBox; class CTextBox;
class CCampaignState; class CCampaignState;
class CConnection; class CConnection;
class JsonNode;
struct CPackForSelectionScreen; struct CPackForSelectionScreen;
struct PlayerInfo; struct PlayerInfo;
struct FileInfo; struct FileInfo;
@ -48,7 +49,16 @@ public:
/// The main menu screens listed in the EState enum /// The main menu screens listed in the EState enum
class CMenuScreen : public CIntObject class CMenuScreen : public CIntObject
{ {
const JsonNode& config;
CTabbedInt *tabs;
std::vector<CPicture*> images;
CIntObject *createTab(size_t index);
public: public:
std::vector<std::string> menuNameToEntry;
enum EState { //where are we? enum EState { //where are we?
mainMenu, newGame, loadGame, campaignMain, saveGame, scenarioInfo, campaignList mainMenu, newGame, loadGame, campaignMain, saveGame, scenarioInfo, campaignList
}; };
@ -56,17 +66,36 @@ public:
enum EMultiMode { enum EMultiMode {
SINGLE_PLAYER = 0, MULTI_HOT_SEAT, MULTI_NETWORK_HOST, MULTI_NETWORK_GUEST SINGLE_PLAYER = 0, MULTI_HOT_SEAT, MULTI_NETWORK_HOST, MULTI_NETWORK_GUEST
}; };
CMenuScreen(const JsonNode& configNode);
CPicture *bgAd;
AdventureMapButton *buttons[5];
CMenuScreen(EState which);
~CMenuScreen();
void showAll(SDL_Surface * to);
void show(SDL_Surface * to); void show(SDL_Surface * to);
void moveTo(CMenuScreen *next); void activate();
void deactivate();
void switchToTab(size_t index);
}; };
class CMenuEntry : public CIntObject
{
std::vector<CPicture*> images;
std::vector<AdventureMapButton*> buttons;
AdventureMapButton* createButton(CMenuScreen* parent, const JsonNode& button);
public:
CMenuEntry(CMenuScreen* parent, const JsonNode &config);
};
class CreditsScreen : public CIntObject
{
CTextBox* credits;
public:
CreditsScreen();
void show(SDL_Surface *to);
void clickLeft(tribool down, bool previousState);
void clickRight(tribool down, bool previousState);
};
/// Implementation of the chat box /// Implementation of the chat box
class CChatBox : public CIntObject class CChatBox : public CIntObject
@ -84,8 +113,8 @@ public:
class InfoCard : public CIntObject class InfoCard : public CIntObject
{ {
CPicture *bg;
public: public:
CPicture *bg;
CMenuScreen::EState type; CMenuScreen::EState type;
bool network; bool network;
@ -117,7 +146,7 @@ private:
void parseGames(std::vector<FileInfo> &files, bool multi); void parseGames(std::vector<FileInfo> &files, bool multi);
void parseCampaigns( std::vector<FileInfo> & files ); void parseCampaigns( std::vector<FileInfo> & files );
void getFiles(std::vector<FileInfo> &out, const std::string &dirname, const std::string &ext); void getFiles(std::vector<FileInfo> &out, const std::string &dirname, const std::string &ext);
CMenuScreen::EState tabType; CMenuScreen::EState tabType;
public: public:
int positions; //how many entries (games/maps) can be shown int positions; //how many entries (games/maps) can be shown
CPicture *bg; //general bg image CPicture *bg; //general bg image
@ -132,7 +161,7 @@ public:
CTextInput *txt; CTextInput *txt;
void filter(int size, bool selectFirst = false); //0 - all void filter(int size, bool selectFirst = false); //0 - all
void select(int position); //position: <0 - positions> position on the screen void select(int position); //position: <0 - positions> position on the screen
void selectAbs(int position); //position: absolute position in curItems vector void selectAbs(int position); //position: absolute position in curItems vector
@ -182,7 +211,7 @@ public:
SelectedBox *hero; SelectedBox *hero;
SelectedBox *bonus; SelectedBox *bonus;
enum {HUMAN_OR_CPU, HUMAN, CPU} whoCanPlay; enum {HUMAN_OR_CPU, HUMAN, CPU} whoCanPlay;
PlayerOptionsEntry(OptionsTab *owner, PlayerSettings &S); PlayerOptionsEntry(OptionsTab *owner, PlayerSettings &S);
void selectButtons(); //hides unavailable buttons void selectButtons(); //hides unavailable buttons
void showAll(SDL_Surface * to); void showAll(SDL_Surface * to);
@ -194,7 +223,7 @@ public:
struct PlayerToRestore struct PlayerToRestore
{ {
int color, id; int color, id;
void reset() { color = id = -1; } void reset() { color = id = -1; }
PlayerToRestore(){ reset(); } PlayerToRestore(){ reset(); }
} playerToRestore; } playerToRestore;
@ -287,7 +316,7 @@ public:
class CSavingScreen : public CSelectionScreen class CSavingScreen : public CSelectionScreen
{ {
public: public:
const CMapInfo *ourGame; const CMapInfo *ourGame;
CSavingScreen(bool hotseat = false); CSavingScreen(bool hotseat = false);
@ -414,58 +443,49 @@ public:
/// Campaign selection screen /// Campaign selection screen
class CCampaignScreen : public CIntObject class CCampaignScreen : public CIntObject
{ {
public: public:
enum CampaignStatus {DEFAULT = 0, ENABLED, DISABLED, COMPLETED}; // the status of the campaign enum CampaignStatus {DEFAULT = 0, ENABLED, DISABLED, COMPLETED}; // the status of the campaign
private:
/// A button which plays a video when you move the mouse cursor over it
class CCampaignButton : public CIntObject
{
private: private:
SDL_Surface *bg; // background image CPicture *image;
SDL_Surface *noCamp; // no campaign placeholder CPicture *checkMark;
AdventureMapButton *back; // back button
/// A button which plays a video when you move the mouse cursor over it CLabel *hoverLabel;
class CCampaignButton : public CIntObject CampaignStatus status;
{
private:
std::string image;
SDL_Surface *bg;
SDL_Surface *button;
SDL_Surface *checked;
CLabel *hoverLabel;
CampaignStatus status;
void clickLeft(tribool down, bool previousState); std::string campFile; // the filename/resourcename of the campaign
void hover(bool on); std::string video; // the resource name of the video
std::string hoverText;
public: void clickLeft(tribool down, bool previousState);
std::string campFile; // the filename/resourcename of the campaign void hover(bool on);
std::string video; // the resource name of the video
std::string hoverText; // the text which gets shown when you move the mouse cursor over the button
CCampaignButton(SDL_Surface *bg, const std::string image, const int x, const int y, CampaignStatus status); // c-tor public:
~CCampaignButton(); // d-tor CCampaignButton(const JsonNode &config );
void show(SDL_Surface *to); void show(SDL_Surface *to);
}; };
std::vector<CCampaignButton*> campButtons; // a container which holds all buttons where you can start a campaign AdventureMapButton *back;
std::vector<CCampaignButton*> campButtons;
void drawCampaignPlaceholder(); // draws the no campaign placeholder at the lower right position std::vector<CPicture*> images;
std::string getMapText(int index);
void createButtons(const int buttonCords[7][2], const std::string campFiles[], AdventureMapButton* createExitButton(const JsonNode& button);
const std::string campImages[], const std::string campVideos[], const std::string campTexts[], std::map<std::string, CampaignStatus>& camps, const CampaignStatus campDefaults[]);
public: public:
enum CampaignSet {ROE, AB, SOD, WOG}; enum CampaignSet {ROE, AB, SOD, WOG};
CCampaignScreen(CampaignSet campaigns, std::map<std::string, CampaignStatus>& camps); CCampaignScreen(const JsonNode &config);
~CCampaignScreen();
void show(SDL_Surface *to);
}; };
/// Handles background screen, loads graphics for victory/loss condition and random town or hero selection /// Handles background screen, loads graphics for victory/loss condition and random town or hero selection
class CGPreGame : public CIntObject, public IUpdateable class CGPreGame : public CIntObject, public IUpdateable
{ {
const JsonNode * const pregameConfig;
public: public:
SDL_Surface *mainbg; CMenuScreen* menu;
CMenuScreen *scrs[4];
SDL_Surface *nHero, *rHero, *nTown, *rTown; // none/random hero/town imgs SDL_Surface *nHero, *rHero, *nTown, *rTown; // none/random hero/town imgs
CDefHandler *bonuses; CDefHandler *bonuses;
@ -475,10 +495,11 @@ public:
~CGPreGame(); ~CGPreGame();
void update(); void update();
void openSel(CMenuScreen::EState type, CMenuScreen::EMultiMode multi = CMenuScreen::SINGLE_PLAYER); void openSel(CMenuScreen::EState type, CMenuScreen::EMultiMode multi = CMenuScreen::SINGLE_PLAYER);
void openCampaignScreen(CCampaignScreen::CampaignSet campaigns);
void loadGraphics(); void loadGraphics();
void disposeGraphics(); void disposeGraphics();
void openCampaignScreen(std::string name);
}; };
extern CGPreGame *CGP; extern CGPreGame *CGP;

View File

@ -61,7 +61,8 @@ public:
std::vector<boost::function<Signature> > funcs2 = funcs; //backup std::vector<boost::function<Signature> > funcs2 = funcs; //backup
for(size_t i=0;i<funcs2.size(); ++i) for(size_t i=0;i<funcs2.size(); ++i)
{ {
funcs2[i](); if (funcs2[i])
funcs2[i]();
} }
} }
template <typename Arg> template <typename Arg>
@ -70,7 +71,8 @@ public:
std::vector<boost::function<Signature> > funcs2 = funcs; //backup std::vector<boost::function<Signature> > funcs2 = funcs; //backup
for(int i=0;i<funcs2.size(); i++) for(int i=0;i<funcs2.size(); i++)
{ {
funcs2[i](a); if (funcs2[i])
funcs2[i](a);
} }
} }
}; };

View File

@ -980,11 +980,18 @@ SetCaptureState::~SetCaptureState()
GH.defActionsDef = prevActions; GH.defActionsDef = prevActions;
} }
void IShowable::redraw() void CIntObject::redraw()
{ {
showAll(screenBuf); if (parent && (type & REDRAW_PARENT))
if(screenBuf != screen) {
showAll(screen); parent->redraw();
}
else
{
showAll(screenBuf);
if(screenBuf != screen)
showAll(screen);
}
} }
SDLKey arrowToNum( SDLKey key ) SDLKey arrowToNum( SDLKey key )

View File

@ -300,7 +300,7 @@ struct Rect : public SDL_Rect
class IShowable class IShowable
{ {
public: public:
void redraw(); virtual void redraw()=0;
virtual void show(SDL_Surface * to)=0; virtual void show(SDL_Surface * to)=0;
virtual void showAll(SDL_Surface * to) virtual void showAll(SDL_Surface * to)
{ {
@ -333,7 +333,8 @@ public:
class IShowActivable : public IShowable, public IActivable class IShowActivable : public IShowable, public IActivable
{ {
public: public:
enum {WITH_GARRISON = 1, BLOCK_ADV_HOTKEYS = 2, WITH_ARTIFACTS = 4}; //redraw parent flag - this int may be semi-transparent and require redraw of parent window
enum {WITH_GARRISON = 1, BLOCK_ADV_HOTKEYS = 2, WITH_ARTIFACTS = 4, REDRAW_PARENT=8};
int type; //bin flags using etype int type; //bin flags using etype
IShowActivable(); IShowActivable();
virtual ~IShowActivable(){}; //d-tor virtual ~IShowActivable(){}; //d-tor
@ -426,6 +427,7 @@ public:
void deactivate(ui16 what); void deactivate(ui16 what);
void show(SDL_Surface * to); void show(SDL_Surface * to);
void showAll(SDL_Surface * to); void showAll(SDL_Surface * to);
void redraw();
void drawBorderLoc(SDL_Surface * sur, const Rect &r, const int3 &color); void drawBorderLoc(SDL_Surface * sur, const Rect &r, const int3 &color);
void printAtLoc(const std::string & text, int x, int y, EFonts font, SDL_Color kolor, SDL_Surface * dst); void printAtLoc(const std::string & text, int x, int y, EFonts font, SDL_Color kolor, SDL_Surface * dst);

View File

@ -391,22 +391,14 @@ void CGarrisonInt::createSet(std::vector<CGarrisonSlot*> &ret, const CCreatureSe
void CGarrisonInt::createSlots() void CGarrisonInt::createSlots()
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL; OBJ_CONSTRUCTION_CAPTURING_ALL;
int h, w; //height and width of slot
if(smallIcons) int width = smallIcons? 32 : 58;
{
h = w = 32;
}
else
{
h = 64;
w = 58;
}
if(armedObjs[0]) if(armedObjs[0])
createSet(slotsUp, armedObjs[0], 0, 0, w+interx, 0); createSet(slotsUp, armedObjs[0], 0, 0, width+interx, 0);
if(armedObjs[1]) if(armedObjs[1])
createSet (slotsDown, armedObjs[1], garOffset.x, garOffset.y, w+interx, 1); createSet (slotsDown, armedObjs[1], garOffset.x, garOffset.y, width+interx, 1);
} }
void CGarrisonInt::deleteSlots() void CGarrisonInt::deleteSlots()
@ -958,6 +950,186 @@ void CSelectableComponent::show(SDL_Surface * to)
printAtMiddleWB(subtitle,pos.x+pos.w/2,pos.y+pos.h+25,FONT_SMALL,12,zwykly,to); printAtMiddleWB(subtitle,pos.x+pos.w/2,pos.y+pos.h+25,FONT_SMALL,12,zwykly,to);
} }
static void intDeleter(CIntObject* object)
{
delete object;
}
CObjectList::CObjectList(CreateFunc create, DestroyFunc destroy):
createObject(create),
destroyObject(destroy)
{
if (!destroyObject)
destroyObject = intDeleter;
}
void CObjectList::deleteItem(CIntObject* item)
{
if (!item)
return;
if (active)
item->deactivate();
removeChild(item);
destroyObject(item);
}
CIntObject* CObjectList::createItem(size_t index)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
CIntObject * item = createObject(index);
if (item == NULL)
item = new CIntObject();
item->recActions = defActions;
//May happen if object was created before call to getObject()
if(item->parent != this)
{
if (item->parent)
moveChild(item, item->parent, this);
else
addChild(item);
}
if (item && active)
item->activate();
return item;
}
CTabbedInt::CTabbedInt(CreateFunc create, DestroyFunc destroy, Point position, size_t ActiveID):
CObjectList(create, destroy),
activeTab(NULL),
activeID(ActiveID)
{
pos += position;
reset();
}
void CTabbedInt::setActive(size_t which)
{
if (which != activeID)
{
activeID = which;
reset();
}
}
void CTabbedInt::reset()
{
deleteItem(activeTab);
activeTab = createItem(activeID);
activeTab->moveTo(pos.topLeft());
if (active)
redraw();
}
CIntObject * CTabbedInt::getItem()
{
return activeTab;
}
CListBox::CListBox(CreateFunc create, DestroyFunc destroy, Point Pos, Point ItemOffset, size_t VisibleSize,
size_t TotalSize, size_t InitialPos, int Slider, Rect SliderPos):
CObjectList(create, destroy),
first(InitialPos),
totalSize(TotalSize),
itemOffset(ItemOffset)
{
pos += Pos;
items.resize(VisibleSize, NULL);
if (Slider & 1)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
slider = new CSlider(SliderPos.x, SliderPos.y, SliderPos.w, boost::bind(&CListBox::moveToPos, this, _1),
VisibleSize, TotalSize, InitialPos, Slider & 2, Slider & 4);
}
reset();
}
// Used to move active items after changing list position
void CListBox::updatePositions()
{
Point itemPos = pos.topLeft();
for (std::list<CIntObject*>::iterator it = items.begin(); it!=items.end(); it++)
{
(*it)->moveTo(itemPos);
itemPos += itemOffset;
}
if (active)
{
redraw();
if (slider)
slider->moveTo(first);
}
}
void CListBox::reset()
{
size_t current = first;
for (std::list<CIntObject*>::iterator it = items.begin(); it!=items.end(); it++)
{
deleteItem(*it);
*it = createItem(current++);
}
updatePositions();
}
void CListBox::moveToPos(size_t which)
{
//Calculate new position
size_t maxPossible;
if (totalSize > items.size())
maxPossible = totalSize - items.size();
else
maxPossible = 0;
size_t newPos = std::min(which, maxPossible);
//If move distance is 1 (most of calls from Slider) - use faster shifts instead of resetting all items
if (first - newPos == 1)
moveToPrev();
else if (newPos - first == 1)
moveToNext();
else if (newPos != first)
{
first = newPos;
reset();
}
}
void CListBox::moveToNext()
{
//Remove front item and insert new one to end
if (first + items.size() < totalSize)
{
first++;
deleteItem(items.front());
items.pop_front();
items.push_back(createItem(first+items.size()));
updatePositions();
}
}
void CListBox::moveToPrev()
{
//Remove last item and insert new one at start
if (first)
{
first--;
deleteItem(items.back());
items.pop_back();
items.push_front(createItem(first));
updatePositions();
}
}
std::list<CIntObject*> CListBox::getItems()
{
return items;
}
void CSimpleWindow::show(SDL_Surface * to) void CSimpleWindow::show(SDL_Surface * to)
{ {
if(bitmap) if(bitmap)
@ -3900,6 +4072,7 @@ void CAltarWindow::moveFromSlotToAltar(int slotID, CTradeableItem* altarSlot, co
CSystemOptionsWindow::CSystemOptionsWindow(const SDL_Rect &pos, CPlayerInterface * owner) CSystemOptionsWindow::CSystemOptionsWindow(const SDL_Rect &pos, CPlayerInterface * owner)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL;
this->pos = pos; this->pos = pos;
SDL_Surface *hhlp = BitmapHandler::loadBitmap("SysOpbck.bmp", true); SDL_Surface *hhlp = BitmapHandler::loadBitmap("SysOpbck.bmp", true);
graphics->blueToPlayersAdv(hhlp,LOCPLINT->playerID); graphics->blueToPlayersAdv(hhlp,LOCPLINT->playerID);
@ -3927,44 +4100,44 @@ CSystemOptionsWindow::CSystemOptionsWindow(const SDL_Rect &pos, CPlayerInterface
// load = new AdventureMapButton (CGI->generaltexth->zelp[321].first, CGI->generaltexth->zelp[321].second, boost::bind(&CSystemOptionsWindow::loadf, this), pos.x+246, pos.y+298, "SOLOAD.DEF", SDLK_l); // load = new AdventureMapButton (CGI->generaltexth->zelp[321].first, CGI->generaltexth->zelp[321].second, boost::bind(&CSystemOptionsWindow::loadf, this), pos.x+246, pos.y+298, "SOLOAD.DEF", SDLK_l);
// std::swap(save->imgs[0][0], load->imgs[0][1]); // std::swap(save->imgs[0][0], load->imgs[0][1]);
save = new AdventureMapButton (CGI->generaltexth->zelp[322].first, CGI->generaltexth->zelp[322].second, boost::bind(&CSystemOptionsWindow::bsavef, this), pos.x+357, pos.y+298, "SOSAVE.DEF", SDLK_s); save = new AdventureMapButton (CGI->generaltexth->zelp[322].first, CGI->generaltexth->zelp[322].second, boost::bind(&CSystemOptionsWindow::bsavef, this), 357, 298, "SOSAVE.DEF", SDLK_s);
save->swappedImages = true; save->swappedImages = true;
save->update(); save->update();
// restart = new AdventureMapButton (CGI->generaltexth->zelp[323].first, CGI->generaltexth->zelp[323].second, boost::bind(&CSystemOptionsWindow::bmainmenuf, this), pos.x+346, pos.y+357, "SORSTRT", SDLK_r); // restart = new AdventureMapButton (CGI->generaltexth->zelp[323].first, CGI->generaltexth->zelp[323].second, boost::bind(&CSystemOptionsWindow::bmainmenuf, this), pos.x+346, pos.y+357, "SORSTRT", SDLK_r);
// std::swap(save->imgs[0][0], restart->imgs[0][1]); // std::swap(save->imgs[0][0], restart->imgs[0][1]);
mainMenu = new AdventureMapButton (CGI->generaltexth->zelp[320].first, CGI->generaltexth->zelp[320].second, boost::bind(&CSystemOptionsWindow::bmainmenuf, this), pos.x+357, pos.y+357, "SOMAIN.DEF", SDLK_m); mainMenu = new AdventureMapButton (CGI->generaltexth->zelp[320].first, CGI->generaltexth->zelp[320].second, boost::bind(&CSystemOptionsWindow::bmainmenuf, this), 357, 357, "SOMAIN.DEF", SDLK_m);
mainMenu->swappedImages = true; mainMenu->swappedImages = true;
mainMenu->update(); mainMenu->update();
quitGame = new AdventureMapButton (CGI->generaltexth->zelp[324].first, CGI->generaltexth->zelp[324].second, boost::bind(&CSystemOptionsWindow::bquitf, this), pos.x+246, pos.y+415, "soquit.def", SDLK_q); quitGame = new AdventureMapButton (CGI->generaltexth->zelp[324].first, CGI->generaltexth->zelp[324].second, boost::bind(&CSystemOptionsWindow::bquitf, this), 246, 415, "soquit.def", SDLK_q);
quitGame->swappedImages = true; quitGame->swappedImages = true;
quitGame->update(); quitGame->update();
backToMap = new AdventureMapButton (CGI->generaltexth->zelp[325].first, CGI->generaltexth->zelp[325].second, boost::bind(&CSystemOptionsWindow::breturnf, this), pos.x+357, pos.y+415, "soretrn.def", SDLK_RETURN); backToMap = new AdventureMapButton (CGI->generaltexth->zelp[325].first, CGI->generaltexth->zelp[325].second, boost::bind(&CSystemOptionsWindow::breturnf, this), 357, 415, "soretrn.def", SDLK_RETURN);
backToMap->swappedImages = true; backToMap->swappedImages = true;
backToMap->update(); backToMap->update();
backToMap->assignedKeys.insert(SDLK_ESCAPE); backToMap->assignedKeys.insert(SDLK_ESCAPE);
heroMoveSpeed = new CHighlightableButtonsGroup(0); heroMoveSpeed = new CHighlightableButtonsGroup(0);
heroMoveSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[349].second),CGI->generaltexth->zelp[349].second, "sysopb1.def", pos.x+28, pos.y+77, 1); heroMoveSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[349].second),CGI->generaltexth->zelp[349].second, "sysopb1.def", 28, 77, 1);
heroMoveSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[350].second),CGI->generaltexth->zelp[350].second, "sysopb2.def", pos.x+76, pos.y+77, 2); heroMoveSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[350].second),CGI->generaltexth->zelp[350].second, "sysopb2.def", 76, 77, 2);
heroMoveSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[351].second),CGI->generaltexth->zelp[351].second, "sysopb3.def", pos.x+124, pos.y+77, 4); heroMoveSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[351].second),CGI->generaltexth->zelp[351].second, "sysopb3.def", 124, 77, 4);
heroMoveSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[352].second),CGI->generaltexth->zelp[352].second, "sysopb4.def", pos.x+172, pos.y+77, 8); heroMoveSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[352].second),CGI->generaltexth->zelp[352].second, "sysopb4.def", 172, 77, 8);
heroMoveSpeed->select(owner->sysOpts.heroMoveSpeed, 1); heroMoveSpeed->select(owner->sysOpts.heroMoveSpeed, 1);
heroMoveSpeed->onChange = boost::bind(&SystemOptions::setHeroMoveSpeed, &owner->sysOpts, _1); heroMoveSpeed->onChange = boost::bind(&SystemOptions::setHeroMoveSpeed, &owner->sysOpts, _1);
mapScrollSpeed = new CHighlightableButtonsGroup(0); mapScrollSpeed = new CHighlightableButtonsGroup(0);
mapScrollSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[357].second),CGI->generaltexth->zelp[357].second, "sysopb9.def", pos.x+28, pos.y+210, 1); mapScrollSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[357].second),CGI->generaltexth->zelp[357].second, "sysopb9.def", 28, 210, 1);
mapScrollSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[358].second),CGI->generaltexth->zelp[358].second, "sysob10.def", pos.x+92, pos.y+210, 2); mapScrollSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[358].second),CGI->generaltexth->zelp[358].second, "sysob10.def", 92, 210, 2);
mapScrollSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[359].second),CGI->generaltexth->zelp[359].second, "sysob11.def", pos.x+156, pos.y+210, 4); mapScrollSpeed->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[359].second),CGI->generaltexth->zelp[359].second, "sysob11.def", 156, 210, 4);
mapScrollSpeed->select(owner->sysOpts.mapScrollingSpeed, 1); mapScrollSpeed->select(owner->sysOpts.mapScrollingSpeed, 1);
mapScrollSpeed->onChange = boost::bind(&SystemOptions::setMapScrollingSpeed, &owner->sysOpts, _1); mapScrollSpeed->onChange = boost::bind(&SystemOptions::setMapScrollingSpeed, &owner->sysOpts, _1);
musicVolume = new CHighlightableButtonsGroup(0, true); musicVolume = new CHighlightableButtonsGroup(0, true);
for(int i=0; i<10; ++i) for(int i=0; i<10; ++i)
{ {
musicVolume->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[326+i].second),CGI->generaltexth->zelp[326+i].second, "syslb.def", pos.x+29 + 19*i, pos.y+359, i*11); musicVolume->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[326+i].second),CGI->generaltexth->zelp[326+i].second, "syslb.def", 29 + 19*i, 359, i*11);
} }
musicVolume->select(CCS->musich->getVolume(), 1); musicVolume->select(CCS->musich->getVolume(), 1);
musicVolume->onChange = boost::bind(&SystemOptions::setMusicVolume, &owner->sysOpts, _1); musicVolume->onChange = boost::bind(&SystemOptions::setMusicVolume, &owner->sysOpts, _1);
@ -3972,7 +4145,7 @@ CSystemOptionsWindow::CSystemOptionsWindow(const SDL_Rect &pos, CPlayerInterface
effectsVolume = new CHighlightableButtonsGroup(0, true); effectsVolume = new CHighlightableButtonsGroup(0, true);
for(int i=0; i<10; ++i) for(int i=0; i<10; ++i)
{ {
effectsVolume->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[336+i].second),CGI->generaltexth->zelp[336+i].second, "syslb.def", pos.x+29 + 19*i, pos.y+425, i*11); effectsVolume->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[336+i].second),CGI->generaltexth->zelp[336+i].second, "syslb.def", 29 + 19*i, 425, i*11);
} }
effectsVolume->select(CCS->soundh->getVolume(), 1); effectsVolume->select(CCS->soundh->getVolume(), 1);
effectsVolume->onChange = boost::bind(&SystemOptions::setSoundVolume, &owner->sysOpts, _1); effectsVolume->onChange = boost::bind(&SystemOptions::setSoundVolume, &owner->sysOpts, _1);
@ -3981,15 +4154,6 @@ CSystemOptionsWindow::CSystemOptionsWindow(const SDL_Rect &pos, CPlayerInterface
CSystemOptionsWindow::~CSystemOptionsWindow() CSystemOptionsWindow::~CSystemOptionsWindow()
{ {
SDL_FreeSurface(background); SDL_FreeSurface(background);
delete save;
delete quitGame;
delete backToMap;
delete mainMenu;
delete heroMoveSpeed;
delete mapScrollSpeed;
delete musicVolume;
delete effectsVolume;
} }
void CSystemOptionsWindow::pushSDLEvent(int type, int usercode) void CSystemOptionsWindow::pushSDLEvent(int type, int usercode)
@ -4030,42 +4194,11 @@ void CSystemOptionsWindow::bsavef()
LOCPLINT->showYesNoDialog("Do you want to save current game as " + fname, std::vector<SComponent*>(), boost::bind(&CCallback::save, LOCPLINT->cb, fname), boost::bind(&CSystemOptionsWindow::activate, this), false);*/ LOCPLINT->showYesNoDialog("Do you want to save current game as " + fname, std::vector<SComponent*>(), boost::bind(&CCallback::save, LOCPLINT->cb, fname), boost::bind(&CSystemOptionsWindow::activate, this), false);*/
} }
void CSystemOptionsWindow::activate() void CSystemOptionsWindow::showAll(SDL_Surface *to)
{
save->activate();
quitGame->activate();
backToMap->activate();
mainMenu->activate();
heroMoveSpeed->activate();
mapScrollSpeed->activate();
musicVolume->activate();
effectsVolume->activate();
}
void CSystemOptionsWindow::deactivate()
{
save->deactivate();
quitGame->deactivate();
backToMap->deactivate();
mainMenu->deactivate();
heroMoveSpeed->deactivate();
mapScrollSpeed->deactivate();
musicVolume->deactivate();
effectsVolume->deactivate();
}
void CSystemOptionsWindow::show(SDL_Surface *to)
{ {
CSDL_Ext::blitSurface(background, NULL, to, &pos); CSDL_Ext::blitSurface(background, NULL, to, &pos);
save->showAll(to); CIntObject::showAll(to);
quitGame->showAll(to);
backToMap->showAll(to);
mainMenu->showAll(to);
heroMoveSpeed->showAll(to);
mapScrollSpeed->showAll(to);
musicVolume->showAll(to);
effectsVolume->showAll(to);
} }
CTavernWindow::CTavernWindow(const CGObjectInstance *TavernObj) CTavernWindow::CTavernWindow(const CGObjectInstance *TavernObj)
@ -5518,113 +5651,15 @@ void CExchangeWindow::close()
GH.popIntTotally(this); GH.popIntTotally(this);
} }
void CExchangeWindow::activate() void CExchangeWindow::showAll(SDL_Surface * to)
{
quit->activate();
garr->activate();
//artifs[0]->setHero(heroInst[0]);
artifs[0]->activate();
//artifs[1]->setHero(heroInst[1]);
artifs[1]->activate();
for(int g=0; g<ARRAY_COUNT(secSkillAreas); g++)
{
for(int b=0; b<secSkillAreas[g].size(); ++b)
{
secSkillAreas[g][b]->activate();
}
}
for(int b=0; b<primSkillAreas.size(); ++b)
primSkillAreas[b]->activate();
GH.statusbar = ourBar;
for(int g=0; g<ARRAY_COUNT(questlogButton); g++)
questlogButton[g]->activate();
for(int g=0; g<ARRAY_COUNT(morale); g++)
morale[g]->activate();
for(int g=0; g<ARRAY_COUNT(luck); g++)
luck[g]->activate();
for(int g=0; g<ARRAY_COUNT(portrait); g++)
portrait[g]->activate();
for(int g=0; g<ARRAY_COUNT(spellPoints); g++)
spellPoints[g]->activate();
for(int g=0; g<ARRAY_COUNT(experience); g++)
experience[g]->activate();
for(int g=0; g<ARRAY_COUNT(speciality); g++)
speciality[g]->activate();
}
void CExchangeWindow::deactivate()
{
quit->deactivate();
garr->deactivate();
artifs[0]->deactivate();
artifs[1]->deactivate();
for(int g=0; g<ARRAY_COUNT(secSkillAreas); g++)
{
for(int b=0; b<secSkillAreas[g].size(); ++b)
{
secSkillAreas[g][b]->deactivate();
}
}
for(int b=0; b<primSkillAreas.size(); ++b)
primSkillAreas[b]->deactivate();
for(int g=0; g<ARRAY_COUNT(questlogButton); g++)
questlogButton[g]->deactivate();
for(int g=0; g<ARRAY_COUNT(morale); g++)
morale[g]->deactivate();
for(int g=0; g<ARRAY_COUNT(luck); g++)
luck[g]->deactivate();
for(int g=0; g<ARRAY_COUNT(portrait); g++)
portrait[g]->deactivate();
for(int g=0; g<ARRAY_COUNT(spellPoints); g++)
spellPoints[g]->deactivate();
for(int g=0; g<ARRAY_COUNT(experience); g++)
experience[g]->deactivate();
for(int g=0; g<ARRAY_COUNT(speciality); g++)
speciality[g]->deactivate();
}
void CExchangeWindow::show(SDL_Surface * to)
{ {
blitAt(bg, pos, to); blitAt(bg, pos, to);
quit->showAll(to); CIntObject::showAll(to);
//printing border around window //printing border around window
if(screen->w != 800 || screen->h !=600) if(screen->w != 800 || screen->h !=600)
CMessage::drawBorder(LOCPLINT->playerID,to,828,628,pos.x-14,pos.y-15); CMessage::drawBorder(LOCPLINT->playerID,to,828,628,pos.x-14,pos.y-15);
artifs[0]->showAll(to);
artifs[1]->showAll(to);
ourBar->showAll(to);
for(int g=0; g<ARRAY_COUNT(secSkillAreas); g++)
{
questlogButton[g]->showAll(to);//FIXME: for array count(secondary skill) show quest log button? WTF?
}
garr->showAll(to);
} }
void CExchangeWindow::questlog(int whichHero) void CExchangeWindow::questlog(int whichHero)
@ -5705,6 +5740,7 @@ void CExchangeWindow::prepareBackground()
CExchangeWindow::CExchangeWindow(si32 hero1, si32 hero2) : bg(NULL) CExchangeWindow::CExchangeWindow(si32 hero1, si32 hero2) : bg(NULL)
{ {
OBJ_CONSTRUCTION_CAPTURING_ALL;
char bufor[400]; char bufor[400];
heroInst[0] = LOCPLINT->cb->getHero(hero1); heroInst[0] = LOCPLINT->cb->getHero(hero1);
heroInst[1] = LOCPLINT->cb->getHero(hero2); heroInst[1] = LOCPLINT->cb->getHero(hero2);
@ -5803,61 +5839,20 @@ CExchangeWindow::CExchangeWindow(si32 hero1, si32 hero2) : bg(NULL)
//garrison interface //garrison interface
garr = new CGarrisonInt(pos.x + 69, pos.y + 131, 4, Point(418,0), bg, Point(69,131), heroInst[0],heroInst[1], true, true); garr = new CGarrisonInt(pos.x + 69, pos.y + 131, 4, Point(418,0), bg, Point(69,131), heroInst[0],heroInst[1], true, true);
garr->addSplitBtn(new AdventureMapButton(CGI->generaltexth->tcommands[3],"",boost::bind(&CGarrisonInt::splitClick,garr),pos.x+10,pos.y+132,"TSBTNS.DEF")); {
garr->addSplitBtn(new AdventureMapButton(CGI->generaltexth->tcommands[3],"",boost::bind(&CGarrisonInt::splitClick,garr),pos.x+740,pos.y+132,"TSBTNS.DEF")); BLOCK_CAPTURING;
garr->addSplitBtn(new AdventureMapButton(CGI->generaltexth->tcommands[3],"",boost::bind(&CGarrisonInt::splitClick,garr),pos.x+10,pos.y+132,"TSBTNS.DEF"));
garr->addSplitBtn(new AdventureMapButton(CGI->generaltexth->tcommands[3],"",boost::bind(&CGarrisonInt::splitClick,garr),pos.x+740,pos.y+132,"TSBTNS.DEF"));
}
} }
CExchangeWindow::~CExchangeWindow() //d-tor CExchangeWindow::~CExchangeWindow() //d-tor
{ {
SDL_FreeSurface(bg); SDL_FreeSurface(bg);
delete quit;
//warning: don't experiment with these =NULL lines, they prevent heap corruption!
delete artifs[0]->commonInfo; delete artifs[0]->commonInfo;
artifs[0]->commonInfo = NULL; artifs[0]->commonInfo = NULL;
delete artifs[0];
artifs[1]->commonInfo = NULL; artifs[1]->commonInfo = NULL;
delete artifs[1];
delete garr;
delete ourBar;
for(int g=0; g<ARRAY_COUNT(secSkillAreas); g++)
{
for(int b=0; b<secSkillAreas[g].size(); ++b)
{
delete secSkillAreas[g][b];
}
}
for(int b=0; b<primSkillAreas.size(); ++b)
{
delete primSkillAreas[b];
}
for(int g=0; g<ARRAY_COUNT(questlogButton); g++)
{
delete questlogButton[g];
}
for(int g=0; g<ARRAY_COUNT(morale); g++)
delete morale[g];
for(int g=0; g<ARRAY_COUNT(luck); g++)
delete luck[g];
for(int g=0; g<ARRAY_COUNT(portrait); g++)
delete portrait[g];
for(int g=0; g<ARRAY_COUNT(spellPoints); g++)
delete spellPoints[g];
for(int g=0; g<ARRAY_COUNT(experience); g++)
delete experience[g];
for(int g=0; g<ARRAY_COUNT(speciality); g++)
delete speciality[g];
} }
CShipyardWindow::CShipyardWindow(const std::vector<si32> &cost, int state, int boatType, const boost::function<void()> &onBuy) CShipyardWindow::CShipyardWindow(const std::vector<si32> &cost, int state, int boatType, const boost::function<void()> &onBuy)

View File

@ -209,6 +209,87 @@ public:
void deactivate(); void deactivate();
void select(bool on); void select(bool on);
}; };
////////////////////////////////////////////////////////////////////////////////
/// Used as base for Tabs and List classes
class CObjectList : public CIntObject
{
public:
typedef boost::function<CIntObject* (size_t)> CreateFunc;
typedef boost::function<void(CIntObject *)> DestroyFunc;
private:
CreateFunc createObject;
DestroyFunc destroyObject;
protected:
//Internal methods for safe creation of items (Children capturing and activation/deactivation if needed)
void deleteItem(CIntObject* item);
CIntObject* createItem(size_t index);
CObjectList(CreateFunc create, DestroyFunc destroy = DestroyFunc());//Protected constructor
};
/// Window element with multiple tabs
class CTabbedInt : public CObjectList
{
private:
CIntObject * activeTab;
size_t activeID;
public:
//CreateFunc, DestroyFunc - see CObjectList
//Pos - position of object, all tabs will be moved to this position
//ActiveID - ID of initially active tab
CTabbedInt(CreateFunc create, DestroyFunc destroy = DestroyFunc(), Point position=Point(), size_t ActiveID=0);
void setActive(size_t which);
//recreate active tab
void reset();
//return currently active item
CIntObject * getItem();
};
/// List of IntObjects with optional slider
class CListBox : public CObjectList
{
private:
std::list< CIntObject* > items;
size_t first;
size_t totalSize;
Point itemOffset;
CSlider * slider;
void updatePositions();
public:
//CreateFunc, DestroyFunc - see CObjectList
//Pos - position of first item
//ItemOffset - distance between items in the list
//VisibleSize - maximal number of displayable at once items
//TotalSize
//Slider - slider style, bit field: 1 = present(disabled), 2=horisontal(vertical), 4=blue(brown)
//SliderPos - position of slider, if present
CListBox(CreateFunc create, DestroyFunc destroy, Point Pos, Point ItemOffset, size_t VisibleSize,
size_t TotalSize, size_t InitialPos=0, int Slider=0, Rect SliderPos=Rect() );
//recreate all visible items
void reset();
//return currently active items
std::list< CIntObject * > getItems();
//scroll list
void moveToPos(size_t which);
void moveToNext();
void moveToPrev();
};
////////////////////////////////////////////////////////////////////////////////
class CGarrisonInt; class CGarrisonInt;
/// A single garrison slot which holds one creature of a specific amount /// A single garrison slot which holds one creature of a specific amount
@ -798,9 +879,7 @@ public:
void pushSDLEvent(int type, int usercode); void pushSDLEvent(int type, int usercode);
void activate(); void showAll(SDL_Surface * to);
void deactivate();
void show(SDL_Surface * to);
}; };
class CTavernWindow : public CIntObject class CTavernWindow : public CIntObject
@ -1104,9 +1183,7 @@ public:
CArtifactsOfHero * artifs[2]; CArtifactsOfHero * artifs[2];
void close(); void close();
void activate(); void showAll(SDL_Surface * to);
void deactivate();
void show(SDL_Surface * to);
void questlog(int whichHero); //questlog button callback; whichHero: 0 - left, 1 - right void questlog(int whichHero); //questlog button callback; whichHero: 0 - left, 1 - right

125
config/mainmenu.json Normal file
View File

@ -0,0 +1,125 @@
{
//Main menu window, consists of several sub-menus aka items
"window":
{
"video" : {"x": 8, "y": 105, "name":"ACREDIT.SMK" },//Floating WoG logo
"images" : [ {"x": 0, "y": 0, "name":"ZPIC1005"} ],//Background image
"items" :
[
{
"name" : "main",
"buttons":
[
{"x": 540, "y": 10, "name":"ZMENUNG", "hotkey" : 110, "help": 3, "command": "to new"},
{"x": 532, "y": 132, "name":"ZMENULG", "hotkey" : 108, "help": 4, "command": "to load"},
{"x": 524, "y": 251, "name":"ZMENUHS", "hotkey" : 104, "help": 5, "command": "highscores"},
{"x": 557, "y": 359, "name":"ZMENUCR", "hotkey" : 99, "help": 6, "command": "to credits"},
{"x": 586, "y": 468, "name":"ZMENUQT", "hotkey" : 27, "help": 7, "command": "exit"}
]
},
{
"name" : "new",
"buttons":
[
{"x": 545, "y": 4, "name":"ZTSINGL", "hotkey" : 115, "help": 10, "command": "start single"},
{"x": 568, "y": 120, "name":"ZTMULTI", "hotkey" : 109, "help": 12, "command": "start multi"},
{"x": 541, "y": 233, "name":"ZTCAMPN", "hotkey" : 99, "help": 11, "command": "to campaign"},
{"x": 545, "y": 358, "name":"ZTTUTOR", "hotkey" : 116, "help": 13, "command": "start tutorial"},
{"x": 582, "y": 464, "name":"ZTBACK", "hotkey" : 27, "help": 14, "command": "to main"}
],
"images": [ {"x": 114, "y": 312, "name":"ZNEWGAM"} ]
},
{
"name" : "load",
"buttons":
[
{"x": 545, "y": 8, "name":"ZTSINGL", "hotkey" : 115, "help": 10, "command": "load single"},
{"x": 568, "y": 120, "name":"ZTMULTI", "hotkey" : 109, "help": 12, "command": "load multi"},
{"x": 541, "y": 233, "name":"ZTCAMPN", "hotkey" : 99, "help": 11, "command": "load campaign"},
{"x": 545, "y": 358, "name":"ZTTUTOR", "hotkey" : 116, "help": 13, "command": "load tutorial"},
{"x": 582, "y": 464, "name":"ZTBACK", "hotkey" : 27, "help": 14, "command": "to main"}
],
"images": [ {"x": 114, "y": 312, "name":"ZLOADGAM"} ]
},
{
"name" : "campaign",
"buttons":
[
{"x": 535, "y": 4, "name":"ZSSSOD", "hotkey" : 119, "command": "campaigns sod"},
{"x": 494, "y": 117, "name":"ZSSROE", "hotkey" : 114, "command": "campaigns roe"},
{"x": 486, "y": 241, "name":"ZSSARM", "hotkey" : 97, "command": "campaigns ab"},
{"x": 550, "y": 358, "name":"ZSSCUS", "hotkey" : 99, "command": "start campaign"},
{"x": 582, "y": 464, "name":"ZTBACK", "hotkey" : 27, "command": "to new"}
],
}
]
},
//Campaigns windows, each campaigns set is a separate window activated by "campaigns %name%" command from main menu
"campaignsset":
[
{
"name":"roe",
"images" : [ {"x": 0, "y": 0, "name":"CAMPBACK"} ],
"exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN", "hotkey" : 27},
"items":
[
{ "x":90, "y":72, "file":"GOOD1.H3C", "image":"CAMPGD1S", "video":"CGOOD1", "open": true },
{ "x":539, "y":72, "file":"EVIL1.H3C", "image":"CAMPEV1S", "video":"CEVIL1", "open": true },
{ "x":43, "y":245, "file":"GOOD2.H3C", "image":"CAMPGD2S", "video":"CGOOD2", "open": true },
{ "x":313, "y":244, "file":"NEUTRAL.H3C", "image":"CAMPNEUS", "video":"CNEUTRAL", "open": true },
{ "x":586, "y":246, "file":"EVIL2.H3C", "image":"CAMPEV2S", "video":"CEVIL2", "open": true },
{ "x":34, "y":417, "file":"GOOD3.H3C", "image":"CAMPGD3S", "video":"CGOOD3", "open": true },
{ "x":404, "y":414, "file":"SECRET.H3C", "image":"CAMPSCTS", "video":"CSECRET", "open": true }
]
},
{
"name":"ab",
"images" :
[
{"x": 0, "y": 0, "name":"CAMPBACK"},
{"x": 34, "y": 417, "name":"CAMP1FWX"},//one campaign have special inactive image
{"x": 385, "y": 401, "name":"CAMPNOSC"},//and the last one is not present
],
"exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN", "hotkey" : 27},
"items":
[
{ "x":90, "y":72, "file":"AB.H3C", "image":"CAMP1AB7", "video":"C1ab7", "open": true },
{ "x":539, "y":72, "file":"BLOOD.H3C", "image":"CAMP1DB2", "video":"C1db2", "open": true },
{ "x":43, "y":245, "file":"SLAYER.H3C", "image":"CAMP1DS1", "video":"C1ds1", "open": true },
{ "x":313, "y":244, "file":"FESTIVAL.H3C", "image":"CAMP1FL3", "video":"C1fl3", "open": true },
{ "x":586, "y":246, "file":"FIRE.H3C", "image":"CAMP1PF2", "video":"C1pf2", "open": true },
{ "x":34, "y":417, "file":"FOOL.H3C", "image":"CAMP1FW1", "video":"C1fw1", "open": true }
]
},
{
"name":"sod",
"images" : [ {"x": 0, "y": 0, "name":"CAMPBKX2"} ],
"exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN", "hotkey" : 27},
"items":
[
{ "x":90, "y":72, "file":"GEM.H3C", "image":"CAMPNB1", "video":"NEW", "open": true },
{ "x":539, "y":72, "file":"GELU.H3C", "image":"CAMPEL1", "video":"ELIXIR", "open": true },
{ "x":43, "y":245, "file":"CRAG.H3C", "image":"CAMPHS1", "video":"HACK", "open": true },
{ "x":313, "y":244, "file":"SANDRO.H3C", "image":"CAMPRN1", "video":"RISE", "open": true },
{ "x":586, "y":246, "file":"YOG.H3C", "image":"CAMPBB1", "video":"BIRTH", "open": true },
{ "x":34, "y":417, "file":"FINAL.H3C", "image":"CAMPUA1", "video":"UNHOLY", "open": true },
{ "x":404, "y":414, "file":"SECRET1.H3C", "image":"CAMPSP1", "video":"SPECTRE", "open": true }
]
},
{
"name":"wog",
"images" : [ {"x": 0, "y": 0, "name":"CAMPZALL"} ],
"exitbutton" : {"x": 658, "y": 482, "name":"CMPSCAN", "hotkey" : 27},
"items":
[
{ "x":90, "y":72, "file":"ZC1.H3C", "image":"CAMPZ01", "open": true},
{ "x":539, "y":72, "file":"ZC2.H3C", "image":"CAMPZ02", "open": true},
{ "x":43, "y":245, "file":"ZC3.H3C", "image":"CAMPZ03", "open": true},
{ "x":311, "y":242, "file":"ZC4.H3C", "image":"CAMPZ04", "open": true}
]
}
]
}

View File

@ -154,13 +154,11 @@ CCampaignHeader CCampaignHandler::readHeaderFromMemory( const unsigned char *buf
ret.mapVersion -= 1; //change range of it from [1, 20] to [0, 19] ret.mapVersion -= 1; //change range of it from [1, 20] to [0, 19]
ret.name = readString(buffer, outIt); ret.name = readString(buffer, outIt);
ret.description = readString(buffer, outIt); ret.description = readString(buffer, outIt);
ret.difficultyChoosenByPlayer = readChar(buffer, outIt); if (ret.version > CampaignVersion::RoE)
ret.difficultyChoosenByPlayer = readChar(buffer, outIt);
else
ret.difficultyChoosenByPlayer = 0;
ret.music = readChar(buffer, outIt); ret.music = readChar(buffer, outIt);
if(ret.version == 4) //I saw one campaign with this version, without either difficulty or music - it's
{ //not editable by any editor so I'll just go back by one byte.
outIt--;
}
return ret; return ret;
} }
@ -213,12 +211,12 @@ CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory( const unsigned c
memcpy(ret.monstersKeptByHero, buffer+outIt, ARRAY_COUNT(ret.monstersKeptByHero)); memcpy(ret.monstersKeptByHero, buffer+outIt, ARRAY_COUNT(ret.monstersKeptByHero));
outIt += ARRAY_COUNT(ret.monstersKeptByHero); outIt += ARRAY_COUNT(ret.monstersKeptByHero);
int artifBytes; int artifBytes;
if (version == 5) //AB if (version < CampaignVersion::SoD)
{ {
artifBytes = 17; artifBytes = 17;
ret.artifsKeptByHero[17] = 0; ret.artifsKeptByHero[17] = 0;
} }
else //SoD+ else
{ {
artifBytes = 18; artifBytes = 18;
} }
@ -433,11 +431,7 @@ unsigned char * CCampaignHandler::getFile( const std::string & name, bool fromLo
cmpgn = bitmaph_ab->giveFile(name, FILE_CAMPAIGN, &outSize); cmpgn = bitmaph_ab->giveFile(name, FILE_CAMPAIGN, &outSize);
else else
tlog1 << "Cannot find file: " << name << std::endl; tlog1 << "Cannot find file: " << name << std::endl;
FILE * tmp = fopen("tmp_cmpgn", "wb"); cmpgn = CLodHandler::getUnpackedData(cmpgn, outSize, &outSize);
fwrite(cmpgn, 1, outSize, tmp);
fclose(tmp);
delete [] cmpgn;
cmpgn = CLodHandler::getUnpackedFile("tmp_cmpgn", &outSize);
} }
else else
{ {
@ -532,7 +526,7 @@ void CCampaignScenario::prepareCrossoverHeroes( std::vector<CGHeroInstance *> he
bool takeable = travelOptions.artifsKeptByHero[g / 8] & ( 1 << (g%8) ) ; bool takeable = travelOptions.artifsKeptByHero[g / 8] & ( 1 << (g%8) ) ;
if (!takeable) if (!takeable)
{ {
BOOST_FOREACH(CGHeroInstance * cgh, crossoverHeroes) //BOOST_FOREACH(CGHeroInstance * cgh, crossoverHeroes)
{ {
tlog1 << "TODO TODO TODO - take artifacts from hero\n"; tlog1 << "TODO TODO TODO - take artifacts from hero\n";
//TODO how was that supposed to work with worn artifacts? //TODO how was that supposed to work with worn artifacts?

View File

@ -18,10 +18,21 @@
struct StartInfo; struct StartInfo;
class CGHeroInstance; class CGHeroInstance;
namespace CampaignVersion
{
enum Version
{
RoE = 4,
AB = 5,
SoD = 6,
WoG = 6
};
}
class DLL_EXPORT CCampaignHeader class DLL_EXPORT CCampaignHeader
{ {
public: public:
si32 version; //5 - AB, 6 - SoD, WoG - ?!? si32 version; //4 - RoE, 5 - AB, 6 - SoD and WoG
ui8 mapVersion; //CampText.txt's format ui8 mapVersion; //CampText.txt's format
std::string name, description; std::string name, description;
ui8 difficultyChoosenByPlayer; ui8 difficultyChoosenByPlayer;

View File

@ -930,7 +930,7 @@ void CGameState::init( StartInfo * si, ui32 checksum, int Seed )
std::string &mapContent = campaign->camp->mapPieces[scenarioOps->whichMapInCampaign]; std::string &mapContent = campaign->camp->mapPieces[scenarioOps->whichMapInCampaign];
map = new Mapa(); map = new Mapa();
map->initFromBytes((const unsigned char*)mapContent.c_str()); map->initFromBytes((const unsigned char*)mapContent.c_str(), mapContent.size());
} }
break; break;
case StartInfo::DUEL: case StartInfo::DUEL:

View File

@ -13,6 +13,7 @@
#include <boost/thread.hpp> #include <boost/thread.hpp>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include "vcmi_endian.h" #include "vcmi_endian.h"
#include "VCMIDirs.h"
#ifdef max #ifdef max
#undef max #undef max
#endif #endif
@ -347,6 +348,21 @@ CLodHandler::~CLodHandler()
delete mutex; delete mutex;
} }
//It is possible to use uncompress function from zlib but we need to know decompressed size (not present in compressed data)
unsigned char * CLodHandler::getUnpackedData(unsigned char *data, size_t inputSize, int * outputSize)
{
std::string filename = GVCMIDirs.UserPath + "/tmp_gzip";
FILE * file = fopen(filename.c_str(), "wb");
fwrite(data, 1, inputSize, file);
fclose(file);
unsigned char * ret = getUnpackedFile(filename, outputSize);
remove(filename.c_str());
delete [] data;
return ret;
}
unsigned char * CLodHandler::getUnpackedFile( const std::string & path, int * sizeOut ) unsigned char * CLodHandler::getUnpackedFile( const std::string & path, int * sizeOut )
{ {
const int bufsize = 65536; const int bufsize = 65536;

View File

@ -118,7 +118,10 @@ public:
std::string getTextFile(std::string name, LodFileType type=FILE_TEXT); //extracts one file std::string getTextFile(std::string name, LodFileType type=FILE_TEXT); //extracts one file
void extractFile(const std::string FName, const std::string name, LodFileType type=FILE_ANY); //extracts a specific file void extractFile(const std::string FName, const std::string name, LodFileType type=FILE_ANY); //extracts a specific file
static unsigned char * getUnpackedFile(const std::string & path, int * sizeOut); //loads given file, decompresses and returns //unpack data from memory, input data will be deleted
static unsigned char * getUnpackedData(unsigned char *data, size_t inputSize, int * outputSize);
//loads given file, decompresses and returns
static unsigned char * getUnpackedFile(const std::string & path, int * sizeOut);
}; };

View File

@ -397,8 +397,14 @@ CMapHeader::~CMapHeader()
} }
void Mapa::initFromBytes(const unsigned char * bufor) void Mapa::initFromBytes(const unsigned char * bufor, size_t size)
{ {
// Compute checksum
boost::crc_32_type result;
result.process_bytes(bufor, size);
checksum = result.checksum();
tlog0 << "\tOur map checksum: "<<result.checksum() << std::endl;
int i=0; int i=0;
initFromMemory(bufor,i); initFromMemory(bufor,i);
timeHandler th; timeHandler th;
@ -438,7 +444,8 @@ void Mapa::initFromBytes(const unsigned char * bufor)
} }
tlog0<<"\tCalculating blocked/visitable tiles: "<<th.getDif()<<std::endl; tlog0<<"\tCalculating blocked/visitable tiles: "<<th.getDif()<<std::endl;
tlog0 << "\tMap initialization done!" << std::endl; tlog0 << "\tMap initialization done!" << std::endl;
} }
void Mapa::removeBlockVisTiles(CGObjectInstance * obj, bool total) void Mapa::removeBlockVisTiles(CGObjectInstance * obj, bool total)
{ {
for(int fx=0; fx<8; ++fx) for(int fx=0; fx<8; ++fx)
@ -503,13 +510,7 @@ Mapa::Mapa(std::string filename)
tlog0<<"done."<<std::endl; tlog0<<"done."<<std::endl;
// Compute checksum initFromBytes(initTable, mapsize);
boost::crc_32_type result;
result.process_bytes(initTable, mapsize);
checksum = result.checksum();
tlog0 << "\tOur map checksum: "<<result.checksum() << std::endl;
initFromBytes(initTable);
delete [] initTable; delete [] initTable;
} }

View File

@ -314,7 +314,7 @@ struct DLL_EXPORT Mapa : public CMapHeader
bmap<si32, si32> questIdentifierToId; bmap<si32, si32> questIdentifierToId;
void initFromBytes( const unsigned char * bufor); //creates map from decompressed .h3m data void initFromBytes( const unsigned char * bufor, size_t size); //creates map from decompressed .h3m data
void readEvents( const unsigned char * bufor, int &i); void readEvents( const unsigned char * bufor, int &i);
void readObjects( const unsigned char * bufor, int &i); void readObjects( const unsigned char * bufor, int &i);