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

- fix for #95 and #602

- implemented animation for new town buildings
This commit is contained in:
Ivan Savenko
2011-03-22 13:19:07 +00:00
parent a09a54ba2f
commit c6f1d87ede
10 changed files with 764 additions and 634 deletions

View File

@ -585,7 +585,9 @@ SDLImage::SDLImage(std::string filename, bool compressed):
delete [] pic;
}
else if(bitmaph->haveFile(filename, FILE_GRAPHICS))
{
surf = BitmapHandler::loadBitmap(filename);
}
else
{
tlog0<<"Error: file not found: "<<filename<<"\n";
@ -648,8 +650,9 @@ CompImage::CompImage(SDL_Surface * surf)
assert(0);
}
void CompImage::draw(SDL_Surface *where, int posX, int posY, Rect *src, unsigned char rotation) const
void CompImage::draw(SDL_Surface *where, int posX, int posY, Rect *src, ui8 alpha) const
{
int rotation = 0; //TODO
//rotation & 2 = horizontal rotation
//rotation & 4 = vertical rotation
if (!surf)
@ -706,7 +709,7 @@ void CompImage::draw(SDL_Surface *where, int posX, int posY, Rect *src, unsigned
while (currX + size < sourceRect.w)
{
//blit block, pointers will be modified if needed
BlitBlockWithBpp(bpp, type, size, data, blitPos, rotation & 2);
BlitBlockWithBpp(bpp, type, size, data, blitPos, alpha, rotation & 2);
currX += size;
type = *(data++);
@ -714,14 +717,14 @@ void CompImage::draw(SDL_Surface *where, int posX, int posY, Rect *src, unsigned
}
//Blit last, semi-visible block
size = sourceRect.w - currX;
BlitBlockWithBpp(bpp, type, size, data, blitPos, rotation & 2);
BlitBlockWithBpp(bpp, type, size, data, blitPos, alpha, rotation & 2);
}
}
#define CASEBPP(x,y) case x: BlitBlock<x,y>(type, size, data, dest); break
#define CASEBPP(x,y) case x: BlitBlock<x,y>(type, size, data, dest, alpha); break
//FIXME: better way to get blitter
void CompImage::BlitBlockWithBpp(ui8 bpp, ui8 type, ui8 size, ui8 *&data, ui8 *&dest, bool rotated) const
void CompImage::BlitBlockWithBpp(ui8 bpp, ui8 type, ui8 size, ui8 *&data, ui8 *&dest, ui8 alpha, bool rotated) const
{
assert(bpp>1 && bpp<5);
@ -744,22 +747,33 @@ void CompImage::BlitBlockWithBpp(ui8 bpp, ui8 type, ui8 size, ui8 *&data, ui8 *&
//Blit one block from RLE-d surface
template<int bpp, int dir>
void CompImage::BlitBlock(ui8 type, ui8 size, ui8 *&data, ui8 *&dest) const
void CompImage::BlitBlock(ui8 type, ui8 size, ui8 *&data, ui8 *&dest, ui8 alpha) const
{
//Raw data
if (type == 0xff)
{
ui8 color = *data;
if (alpha != 255)//Per-surface alpha is set
{
for (size_t i=0; i<size; i++)
{
SDL_Color col = palette[*(data++)];
col.unused = (unsigned int)col.unused*(255-alpha)/255;
ColorPutter<bpp, 1>::PutColorAlpha(dest, col);
}
return;
}
if (palette[color].unused == 255)
{
//Put row of RGB data
for (int i=0; i<size; i++)
for (size_t i=0; i<size; i++)
ColorPutter<bpp, 1>::PutColor(dest, palette[*(data++)]);
}
else
{
//Put row of RGBA data
for (int i=0; i<size; i++)
for (size_t i=0; i<size; i++)
ColorPutter<bpp, 1>::PutColorAlpha(dest, palette[*(data++)]);
}
@ -767,6 +781,15 @@ void CompImage::BlitBlock(ui8 type, ui8 size, ui8 *&data, ui8 *&dest) const
//RLE-d sequence
else
{
if (alpha != 255 && palette[type].unused !=0)//Per-surface alpha is set
{
SDL_Color col = palette[type];
col.unused = (int)col.unused*(255-alpha)/255;
for (size_t i=0; i<size; i++)
ColorPutter<bpp, 1>::PutColorAlpha(dest, col);
return;
}
switch (palette[type].unused)
{
case 0:
@ -784,7 +807,7 @@ void CompImage::BlitBlock(ui8 type, ui8 size, ui8 *&data, ui8 *&dest) const
default:
{
//Put RGBA row
for (int i=0; i<size; i++)
for (size_t i=0; i<size; i++)
ColorPutter<bpp, 1>::PutColorAlpha(dest, palette[type]);
break;
}
@ -792,7 +815,6 @@ void CompImage::BlitBlock(ui8 type, ui8 size, ui8 *&data, ui8 *&dest) const
}
}
void CompImage::playerColored(int player)
{
SDL_Color *pal = NULL;
@ -991,6 +1013,7 @@ CAnimation::CAnimation(std::string Name, bool Compressed):
CDefFile * file = getFile();
init(file);
delete file;
loadedAnims.insert(this);
}
CAnimation::CAnimation():
@ -998,6 +1021,7 @@ CAnimation::CAnimation():
compressed(false)
{
init(NULL);
loadedAnims.insert(this);
}
CAnimation::~CAnimation()
@ -1009,6 +1033,7 @@ CAnimation::~CAnimation()
for (image_map::iterator image = group->second.begin(); image != group->second.end(); ++image )
delete image->second;
}
loadedAnims.erase(this);
}
void CAnimation::setCustom(std::string filename, size_t frame, size_t group)
@ -1090,6 +1115,21 @@ size_t CAnimation::size(size_t group) const
return 0;
}
std::set<CAnimation*> CAnimation::loadedAnims;
void CAnimation::getAnimInfo()
{
tlog1<<"Animation stats: Loaded "<<loadedAnims.size()<<" total\n";
for (std::set<CAnimation*>::iterator it = loadedAnims.begin(); it != loadedAnims.end(); it++)
{
CAnimation * anim = *it;
tlog1<<"Name: "<<anim->name<<" Groups: "<<anim->images.size();
if (!anim->images.empty())
tlog1<<", "<<anim->images.begin()->second.size()<<" image loaded in group "<< anim->images.begin()->first;
tlog1<<"\n";
}
}
CAnimImage::CAnimImage(std::string name, size_t Frame, size_t Group, int x, int y, unsigned char Flags):
frame(Frame),
group(Group),
@ -1172,7 +1212,8 @@ CShowableAnim::CShowableAnim(int x, int y, std::string name, unsigned char Flags
value(0),
flags(Flags),
xOffset(0),
yOffset(0)
yOffset(0),
alpha(255)
{
anim.loadGroup(group);
last = anim.size(group);
@ -1188,6 +1229,11 @@ CShowableAnim::~CShowableAnim()
anim.unloadGroup(group);
}
void CShowableAnim::setAlpha(unsigned int alphaValue)
{
alpha = std::min<unsigned int>(alphaValue, 255);
}
bool CShowableAnim::set(size_t Group, size_t from, size_t to)
{
size_t max = anim.size(Group);
@ -1265,7 +1311,7 @@ void CShowableAnim::blitImage(size_t frame, size_t group, SDL_Surface *to)
assert(to);
Rect src( xOffset, yOffset, pos.w, pos.h);
IImage * img = anim.getImage(frame, group);
img->draw(to, pos.x-xOffset, pos.y-yOffset, &src);
img->draw(to, pos.x-xOffset, pos.y-yOffset, &src, alpha);
}
void CShowableAnim::rotate(bool on, bool vertical)
@ -1350,8 +1396,7 @@ void CCreatureAnim::reset()
if (set(at))
return;
}
set(type);
tlog0<<"Warning: next sequence was not found for animation!\n";
set(HOLDING);
}
void CCreatureAnim::startPreview()

View File

@ -68,7 +68,7 @@ class IImage
public:
//draws image on surface "where" at position
virtual void draw(SDL_Surface *where, int posX=0, int posY=0, Rect *src=NULL, unsigned char rotation=0) const=0;
virtual void draw(SDL_Surface *where, int posX=0, int posY=0, Rect *src=NULL, ui8 alpha=255) const=0;
//decrease ref count, returns true if image can be deleted (refCount <= 0)
bool decreaseRef();
@ -104,7 +104,7 @@ public:
SDLImage(SDL_Surface * from, bool extraRef);
~SDLImage();
void draw(SDL_Surface *where, int posX=0, int posY=0, Rect *src=NULL, unsigned char rotation=0) const;
void draw(SDL_Surface *where, int posX=0, int posY=0, Rect *src=NULL, ui8 alpha=255) const;
void playerColored(int player);
int width() const;
int height() const;
@ -140,8 +140,8 @@ class CompImage : public IImage
//Used internally to blit one block of data
template<int bpp, int dir>
void BlitBlock(ui8 type, ui8 size, ui8 *&data, ui8 *&dest) const;
void BlitBlockWithBpp(ui8 bpp, ui8 type, ui8 size, ui8 *&data, ui8 *&dest, bool rotated) const;
void BlitBlock(ui8 type, ui8 size, ui8 *&data, ui8 *&dest, ui8 alpha) const;
void BlitBlockWithBpp(ui8 bpp, ui8 type, ui8 size, ui8 *&data, ui8 *&dest, ui8 alpha, bool rotated) const;
public:
//Load image from def file
@ -150,7 +150,7 @@ public:
CompImage(SDL_Surface * surf);
~CompImage();
void draw(SDL_Surface *where, int posX=0, int posY=0, Rect *src=NULL, unsigned char rotation=0) const;
void draw(SDL_Surface *where, int posX=0, int posY=0, Rect *src=NULL, ui8 alpha=255) const;
void playerColored(int player);
int width() const;
int height() const;
@ -158,9 +158,8 @@ public:
friend class CompImageLoader;
};
/*
* Class for handling animation.
*/
/// Class for handling animation
class CAnimation
{
private:
@ -201,6 +200,10 @@ public:
CAnimation();
~CAnimation();
//static method for debugging - print info about loaded animations in tlog1
static void getAnimInfo();
static std::set<CAnimation*> loadedAnims;
//add custom surface to the selected position.
void setCustom(std::string filename, size_t frame, size_t group=0);
@ -223,9 +226,8 @@ public:
size_t size(size_t group=0) const;
};
/*
* Class for displaying one image from animation
*/
/// Class for displaying one image from animation
class CAnimImage: public CIntObject
{
private:
@ -283,10 +285,15 @@ protected:
//For clipping in rect, offsets of picture coordinates
int xOffset, yOffset;
ui8 alpha;
public:
//called when next animation sequence is required
boost::function<void()> callback;
//Set per-surface alpha, 0 = transparent, 255 = opaque
void setAlpha(unsigned int alphaValue);
CShowableAnim(int x, int y, std::string name, unsigned char flags=0, unsigned int Delay=4, size_t Group=0);
~CShowableAnim();
@ -308,7 +315,7 @@ public:
void showAll(SDL_Surface *to);
};
/// Creature-dependend animations like attacking, moving,... outside battles
/// Creature-dependend animations like attacking, moving,...
class CCreatureAnim: public CShowableAnim
{
public:

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,7 @@ class CTransformerWindow;
class CPicture;
class CCreaturePic;
class CMinorResDataBar;
class CCastleBuildings;
/*
* CCastleInterface.h, part of VCMI engine
@ -34,10 +35,14 @@ class CMinorResDataBar;
class CBuildingRect : public CShowableAnim
{
public:
CCastleBuildings * parent;
const Structure* str;
SDL_Surface* border;
SDL_Surface* area;
CBuildingRect(const Structure *Str); //c-tor
unsigned int stateCounter;//For building construction - current stage in animation
CBuildingRect(CCastleBuildings * Par, const Structure *Str); //c-tor
~CBuildingRect(); //d-tor
bool operator<(const CBuildingRect & p2) const;
void hover(bool on);
@ -67,6 +72,54 @@ public:
~CHeroGSlot(); //d-tor
};
/// Class for town screen management (town background and structures)
class CCastleBuildings : public CIntObject
{
struct AnimRule
{
int townID, buildID;
int toCheck;
size_t firstA, lastA;
size_t firstB, lastB;
};
CPicture *background;
//List of buildings for each group
std::map< int, std::vector<const Structure*> > groups;
//Vector with all blittable buildings
std::vector<CBuildingRect*> buildings;
const CGTownInstance * town;
const CGHeroInstance* getHero();//Select hero for buildings usage
void checkRules();//Check animation rules (special anims for Shipyard and Mana Vortex)
void enterBlacksmith(int ArtifactID);//support for blacksmith + ballista yard
void enterBuilding(int building);//for buildings with simple description + pic left-click messages
void enterCastleGate();
void enterFountain(int building);//Rampart's fountains
void enterMagesGuild();
void enterTownHall();
void openMagesGuild();
void openTownHall();
public:
CBuildingRect * selectedBuilding;
CCastleBuildings(const CGTownInstance* town);
~CCastleBuildings();
void enterDwelling(int level);
void buildingClicked(int building);
void addBuilding(int building);
void removeBuilding(int building);//FIXME: not tested!!!
void show(SDL_Surface *to);
void showAll(SDL_Surface *to);
};
/// Huge class which manages the castle window
class CCastleInterface : public CWindowWithGarrison
{
@ -83,7 +136,7 @@ class CCastleInterface : public CWindowWithGarrison
void clickRight(tribool down, bool previousState);
void show(SDL_Surface * to);
};
/// Town info which gets shown by right-clicking on a town at the map
/// Icons from town screen with castle\town hall images
class CTownInfo : public CIntObject
{
public:
@ -96,15 +149,13 @@ class CCastleInterface : public CWindowWithGarrison
void clickRight(tribool down, bool previousState);
void show(SDL_Surface * to);
};
public:
bool showing; //indicates if interface is active
CBuildingRect * hBuild; //highlighted building
CCastleBuildings *builds;
SDL_Surface * townInt;
SDL_Surface * cityBg;
const CGTownInstance * town;
CStatusBar * statusbar;
CResDataBar *resdatabar;
unsigned char animval, count;
int winMode;//0=right-click popup, 1 = normal, 2 = town hall only, 3 = fort only;
CDefEssential *bars, //0 - yellow, 1 - green, 2 - red, 3 - gray
@ -118,7 +169,6 @@ public:
AdventureMapButton *split;
std::vector<CCreaInfo*> creainfo;//small icons of creatures (bottom-left corner);
std::vector<CBuildingRect*> buildings; //building id, building def, structure struct, border, filling
CCastleInterface(const CGTownInstance * Town, int listPos = 1); //c-tor
~CCastleInterface(); //d-tor
@ -128,22 +178,12 @@ public:
void keyPressed(const SDL_KeyboardEvent & key);
void show(SDL_Surface * to);
void showAll(SDL_Surface * to);
void buildingClicked(int building);
void defaultBuildingClicked(int building);//for buildings with simple description + pic left-click messages
void enterFountain(int building);
void enterBlacksmith(int ArtifactID);//support for blacksmith + ballista yard
void enterTavern();
void enterMageGuild();
void splitClicked(); //for hero meeting (splitting stacks is handled by garrison int)
void showRecruitmentWindow( int level );
void enterHall();
void close();
void splitF();
void activate();
void deactivate();
void addBuilding(int bid);
void removeBuilding(int bid);
void recreateBuildings();
void recreateIcons();
};
@ -153,7 +193,7 @@ class CHallInterface : public CIntObject
public:
CMinorResDataBar * resdatabar;
/// The building information box which gets shown by right-clicking on a building image
/// Building box from town hall (building icon + subtitle)
class CBuildingBox : public CIntObject
{
public:
@ -169,7 +209,7 @@ public:
~CBuildingBox(); //d-tor
};
/// The actual building window where you can decide to buy a building or not
/// Window where you can decide to buy a building or not
class CBuildWindow: public CIntObject
{
public:
@ -263,7 +303,7 @@ public:
};
/// The blacksmith window where you can buy one of the three war machines
/// The blacksmith window where you can buy available in town war machine
class CBlacksmithDialog : public CIntObject
{
public:

View File

@ -66,8 +66,15 @@ private:
int curFrame, internalFrame; //number of currently displayed frame
unsigned int frames; //number of frames
CCreatureAnim::EAnimType type; //type of animation being displayed (-1 - whole animation, >0 - specified part [default: -1])
public:
template<int bpp>
int nextFrameT(SDL_Surface * dest, int x, int y, bool attacker, unsigned char animCount, bool incrementFrame = true, bool yellowBorder = false, bool blueBorder = false, SDL_Rect * destRect = NULL); //0 - success, any other - error //print next
int nextFrameMiddle(SDL_Surface * dest, int x, int y, bool attacker, unsigned char animCount, bool IncrementFrame = true, bool yellowBorder = false, bool blueBorder = false, SDL_Rect * destRect = NULL); //0 - success, any other - error //print next
std::map<int, std::vector<int> > frameGroups; //groups of frames; [groupID] -> vector of frame IDs in group
bool once;
public:
int fullWidth, fullHeight; //read-only, please!
CCreatureAnimation(std::string name); //c-tor
~CCreatureAnimation(); //d-tor
@ -75,17 +82,12 @@ public:
void setType(CCreatureAnim::EAnimType type); //sets type of animation and cleares framecount
CCreatureAnim::EAnimType getType() const; //returns type of animation
template<int bpp>
int nextFrameT(SDL_Surface * dest, int x, int y, bool attacker, unsigned char animCount, bool incrementFrame = true, bool yellowBorder = false, bool blueBorder = false, SDL_Rect * destRect = NULL); //0 - success, any other - error //print next
int nextFrame(SDL_Surface * dest, int x, int y, bool attacker, unsigned char animCount, bool incrementFrame = true, bool yellowBorder = false, bool blueBorder = false, SDL_Rect * destRect = NULL); //0 - success, any other - error //print next
int nextFrameMiddle(SDL_Surface * dest, int x, int y, bool attacker, unsigned char animCount, bool IncrementFrame = true, bool yellowBorder = false, bool blueBorder = false, SDL_Rect * destRect = NULL); //0 - success, any other - error //print next
void incrementFrame();
int getFrame() const;
bool onFirstFrameInGroup();
bool onLastFrameInGroup();
bool once;
void playOnce(CCreatureAnim::EAnimType type); //plays once given stage of animation, then resets to 2
int framesInGroup(CCreatureAnim::EAnimType group) const; //retirns number of fromes in given group

View File

@ -224,8 +224,8 @@ int main(int argc, char** argv)
}
//Set environment vars to make window centered. Sometimes work, sometimes not. :/
putenv("SDL_VIDEO_WINDOW_POS");
putenv("SDL_VIDEO_CENTERED=1");
putenv((char*)"SDL_VIDEO_WINDOW_POS");
putenv((char*)"SDL_VIDEO_CENTERED=1");
timeHandler total, pomtime;
std::cout.flags(std::ios::unitbuf);
@ -482,6 +482,10 @@ void processCommand(const std::string &message)
if(const CArtifactInstance *a = h->getArt(id2))
tlog4 << a->nodeName();
}
else if (what == "anim" )
{
CAnimation::getAnimInfo();
}
}
else if(client && client->serv && client->serv->connected) //send to server
{

View File

@ -264,7 +264,7 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
//TODO: smooth disappear / appear effect
}
if (details.result != TryMoveHero::SUCCESS && details.result != TryMoveHero::FAILED //hero didn't change tile but visit succeeded
if ((details.result != TryMoveHero::SUCCESS && details.result != TryMoveHero::FAILED) //hero didn't change tile but visit succeeded
|| directlyAttackingCreature) // or creature was attacked from endangering tile.
{
eraseCurrentPathOf(ho);
@ -1021,7 +1021,7 @@ void CPlayerInterface::heroBonusChanged( const CGHeroInstance *hero, const Bonus
if(bonus.type == Bonus::NONE) return;
boost::unique_lock<boost::recursive_mutex> un(*pim);
updateInfo(hero);
if (bonus.type == Bonus::FLYING_MOVEMENT || bonus.type == Bonus::WATER_WALKING && !gain)
if ((bonus.type == Bonus::FLYING_MOVEMENT || bonus.type == Bonus::WATER_WALKING) && !gain)
{
//recalculate paths because hero has lost bonus influencing pathfinding
cb->recalculatePaths();
@ -1213,10 +1213,12 @@ void CPlayerInterface::objectPropertyChanged(const SetObjectProperty * sop)
}
if(obj->ID == TOWNI_TYPE)
{
if(obj->tempOwner == playerID)
towns.push_back(static_cast<const CGTownInstance *>(obj));
else
towns -= obj;
}
assert(cb->getTownsInfo().size() == towns.size());
}
@ -1279,7 +1281,7 @@ void CPlayerInterface::newObject( const CGObjectInstance * obj )
&& obj->pos-obj->getVisitableOffset() == LOCPLINT->castleInt->town->bestLocation())
{
CCS->soundh->playSound(soundBase::newBuilding);
LOCPLINT->castleInt->recreateBuildings();
LOCPLINT->castleInt->addBuilding(20);
}
}
@ -2054,7 +2056,7 @@ void CPlayerInterface::showMarketWindow(const IMarket *market, const CGHeroInsta
boost::unique_lock<boost::recursive_mutex> un(*pim);
if(market->o->ID == 2) //Altar
{
EMarketMode mode = market->availableModes().front();
//EMarketMode mode = market->availableModes().front();
if(market->allowsTrade(ARTIFACT_EXP) && visitor->getAlignment() != EVIL)
GH.pushInt(new CAltarWindow(market, visitor, ARTIFACT_EXP));
else if(market->allowsTrade(CREATURE_EXP) && visitor->getAlignment() != GOOD)
@ -2158,7 +2160,7 @@ void CPlayerInterface::newStackInserted(const StackLocation &location, const CSt
void CPlayerInterface::stacksRebalanced(const StackLocation &src, const StackLocation &dst, TQuantity count)
{
boost::unique_lock<boost::recursive_mutex> un(*pim);
bool updateInfobox = true;
//bool updateInfobox = true;
garrisonChanged(src.army, UPDATE_IF(src));
if(dst.army != src.army)
garrisonChanged(dst.army, UPDATE_IF(dst));
@ -2179,27 +2181,39 @@ void CPlayerInterface::artifactMoved(const ArtifactLocation &src, const Artifact
{
boost::unique_lock<boost::recursive_mutex> un(*pim);
BOOST_FOREACH(IShowActivable *isa, GH.listInt)
{
if(isa->type & IShowActivable::WITH_ARTIFACTS)
{
BOOST_FOREACH(CArtifactsOfHero *aoh, (dynamic_cast<CWindowWithArtifacts*>(isa))->artSets)
aoh->artifactMoved(src, dst);
}
}
}
void CPlayerInterface::artifactAssembled(const ArtifactLocation &al)
{
boost::unique_lock<boost::recursive_mutex> un(*pim);
BOOST_FOREACH(IShowActivable *isa, GH.listInt)
{
if(isa->type & IShowActivable::WITH_ARTIFACTS)
{
BOOST_FOREACH(CArtifactsOfHero *aoh, (dynamic_cast<CWindowWithArtifacts*>(isa))->artSets)
aoh->artifactAssembled(al);
}
}
}
void CPlayerInterface::artifactDisassembled(const ArtifactLocation &al)
{
boost::unique_lock<boost::recursive_mutex> un(*pim);
BOOST_FOREACH(IShowActivable *isa, GH.listInt)
{
if(isa->type & IShowActivable::WITH_ARTIFACTS)
{
BOOST_FOREACH(CArtifactsOfHero *aoh, (dynamic_cast<CWindowWithArtifacts*>(isa))->artSets)
aoh->artifactDisassembled(al);
}
}
}
boost::recursive_mutex * CPlayerInterface::pim = new boost::recursive_mutex;

View File

@ -50,6 +50,7 @@ void CGuiHandler::popInt( IShowActivable *top )
if(listInt.size())
listInt.front()->activate();
totalRedraw();
fakeMouseMove();
}
void CGuiHandler::popIntTotally( IShowActivable *top )
@ -333,7 +334,7 @@ void CGuiHandler::fakeMouseMove()
evnt.motion = sme;
current = &evnt;
handleMoveInterested(sme);
handleMouseMotion(&evnt);
}
void CGuiHandler::run()

View File

@ -494,6 +494,8 @@ void CGarrisonInt::setArmy(const CArmedInstance *army, bool bottomGarrison)
CInfoWindow::CInfoWindow(std::string Text, int player, const TCompsInfo &comps, const TButtonsInfo &Buttons, bool delComps)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
type |= BLOCK_ADV_HOTKEYS;
ID = -1;
for(int i=0;i<Buttons.size();i++)
{
@ -4919,9 +4921,9 @@ void LRClickableAreaOpenTown::clickLeft(tribool down, bool previousState)
LOCPLINT->openTownWindow(town);
LOCPLINT->castleInt->winMode = type;
if ( type == 2 )
LOCPLINT->castleInt->buildingClicked(10);
LOCPLINT->castleInt->builds->buildingClicked(10);
else if ( type == 3 && town->fortLevel() )
LOCPLINT->castleInt->buildingClicked(7);
LOCPLINT->castleInt->builds->buildingClicked(7);
}
}

View File

@ -90,6 +90,8 @@ GROUP
19
CASTLE 6
GROUP
21
GROUP
30
37
18