1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Merges from trunk. Minor changes.

This commit is contained in:
Michał W. Urbańczyk 2010-11-18 18:07:57 +00:00
commit 4d657eaf47
24 changed files with 799 additions and 450 deletions

View File

@ -120,13 +120,18 @@ int CCallback::getSpellCost(const CSpell * sp, const CGHeroInstance * caster) co
return caster->getSpellCost(sp);
}
int CCallback::estimateSpellDamage(const CSpell * sp) const
int CCallback::estimateSpellDamage(const CSpell * sp, const CGHeroInstance * hero) const
{
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
if(!gs->curB)
return 0;
if(!gs->curB) //no battle
{
if (hero) //but we see hero's spellbook
return gs->curB->calculateSpellDmg(sp, hero, NULL, hero->getSpellSchoolLevel(sp), hero->getPrimSkillLevel(2));
else
return 0; //mage guild
}
//gs->getHero(gs->currentPlayer)
const CGHeroInstance * ourHero = gs->curB->heroes[0]->tempOwner == player ? gs->curB->heroes[0] : gs->curB->heroes[1];
return gs->curB->calculateSpellDmg(sp, ourHero, NULL, ourHero->getSpellSchoolLevel(sp), ourHero->getPrimSkillLevel(2));
}

View File

@ -114,7 +114,7 @@ public:
virtual const StartInfo * getStartInfo()const =0;
virtual const CMapHeader * getMapHeader()const =0;
virtual int getSpellCost(const CSpell * sp, const CGHeroInstance * caster) const =0; //when called during battle, takes into account creatures' spell cost reduction
virtual int estimateSpellDamage(const CSpell * sp) const =0; //estimates damage of given spell; returns 0 if spell causes no dmg
virtual int estimateSpellDamage(const CSpell * sp, const CGHeroInstance * hero) const =0; //estimates damage of given spell; returns 0 if spell causes no dmg
virtual void getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj)=0; //get thieves' guild info obtainable while visiting given object
virtual int3 getGrailPos(float &outKnownRatio)=0;
virtual int getPlayerStatus(int player) const = 0; //-1 if no such player
@ -262,7 +262,7 @@ public:
const StartInfo * getStartInfo() const;
const CMapHeader * getMapHeader()const ;
int getSpellCost(const CSpell * sp, const CGHeroInstance * caster) const; //when called during battle, takes into account creatures' spell cost reduction
int estimateSpellDamage(const CSpell * sp) const; //estimates damage of given spell; returns 0 if spell causes no dmg
int estimateSpellDamage(const CSpell * sp, const CGHeroInstance * hero) const; //estimates damage of given spell; returns 0 if spell causes no dmg
void getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj); //get thieves' guild info obtainable while visiting given object
int3 getGrailPos(float &outKnownRatio); //returns pos and (via arg) percent of discovered obelisks; TODO: relies on fairness of GUI/AI... :/

View File

@ -1,5 +1,5 @@
#include "AdventureMapButton.h"
#include "../hch/CAnimation.h"
#include "CAnimation.h"
#include "CAdvmapInterface.h"
#include "SDL_Extensions.h"
#include "CGameInfo.h"

View File

@ -1,13 +1,15 @@
#include <iostream>
#include <sstream>
#include <boost/foreach.hpp>
#include <boost/bind.hpp>
#include "SDL.h"
#include "SDL_image.h"
#include "../client/CBitmapHandler.h"
#include "CBitmapHandler.h"
#include "CAnimation.h"
#include "CLodHandler.h"
#include "SDL_Extensions.h"
#include "../hch/CLodHandler.h"
/*
* CAnimation.cpp, part of VCMI engine
@ -19,7 +21,6 @@
*
*/
extern DLL_EXPORT CLodHandler *spriteh;
/*************************************************************************
@ -46,23 +47,20 @@ SDL_Surface * CDefFile::loadFrame (const unsigned char * FDef, const BMPPalette
{
SDL_Surface * ret=NULL;
unsigned int BaseOffset,
SpriteWidth, SpriteHeight, //format of sprite
TotalRowLength, // length of read segment
add, FullHeight,FullWidth,
RowAdd,
prSize,
defType2;
int LeftMargin, RightMargin, TopMargin, BottomMargin;
unsigned int DefFormat, // format in which pixel data of sprite is encoded
FullHeight,FullWidth, // full width and height of sprite including borders
SpriteWidth, SpriteHeight, // width and height of encoded sprite
TotalRowLength,
RowAdd, add,
BaseOffset;
unsigned char SegmentType;
int LeftMargin, RightMargin, // position of 1st stored in sprite pixel on surface
TopMargin, BottomMargin;
BaseOffset = 0;
SSpriteDef sd = * reinterpret_cast<const SSpriteDef *>(FDef + BaseOffset);
SSpriteDef sd = * reinterpret_cast<const SSpriteDef *>(FDef);
prSize = SDL_SwapLE32(sd.prSize);
defType2 = SDL_SwapLE32(sd.defType2);
DefFormat = SDL_SwapLE32(sd.defType2);
FullWidth = SDL_SwapLE32(sd.FullWidth);
FullHeight = SDL_SwapLE32(sd.FullHeight);
SpriteWidth = SDL_SwapLE32(sd.SpriteWidth);
@ -72,8 +70,6 @@ SDL_Surface * CDefFile::loadFrame (const unsigned char * FDef, const BMPPalette
RightMargin = FullWidth - SpriteWidth - LeftMargin;
BottomMargin = FullHeight - SpriteHeight - TopMargin;
//if(LeftMargin + RightMargin < 0)
// SpriteWidth += LeftMargin + RightMargin; //ugly construction... TODO: check how to do it nicer
if (LeftMargin<0)
SpriteWidth+=LeftMargin;
if (RightMargin<0)
@ -85,9 +81,8 @@ SDL_Surface * CDefFile::loadFrame (const unsigned char * FDef, const BMPPalette
add=0;
ret = SDL_CreateRGBSurface(SDL_SWSURFACE, FullWidth, FullHeight, 8, 0, 0, 0, 0);
//int tempee2 = readNormalNr(0,4,((unsigned char *)tempee.c_str()));
BaseOffset += sizeof(SSpriteDef);
BaseOffset = sizeof(SSpriteDef);
int BaseOffsetor = BaseOffset;
for (int i=0; i<256; ++i)
@ -100,65 +95,75 @@ SDL_Surface * CDefFile::loadFrame (const unsigned char * FDef, const BMPPalette
(*(ret->format->palette->colors+i))=pr;
}
int ftcp=0;
// If there's a margin anywhere, just blank out the whole surface.
if (TopMargin > 0 || BottomMargin > 0 || LeftMargin > 0 || RightMargin > 0)
{
memset( reinterpret_cast<char*>(ret->pixels), 0, FullHeight*FullWidth);
}
int current=0;//current pixel on output surface
// Skip top margin
if (TopMargin > 0)
ftcp += TopMargin*(FullWidth+add);
current += TopMargin*(FullWidth+add);
switch (defType2)
switch (DefFormat)
{
//pixel data is not compressed, copy each line to surface
case 0:
{
for (unsigned int i=0; i<SpriteHeight; i++)
{
if (LeftMargin>0)
ftcp += LeftMargin;
current += LeftMargin;
memcpy(reinterpret_cast<char*>(ret->pixels)+ftcp, &FDef[BaseOffset], SpriteWidth);
ftcp += SpriteWidth;
memcpy(reinterpret_cast<char*>(ret->pixels)+current, &FDef[BaseOffset], SpriteWidth);
current += SpriteWidth;
BaseOffset += SpriteWidth;
if (RightMargin>0)
ftcp += RightMargin;
current += RightMargin;
}
}
break;
// RLE encoding:
// read offset of pixel data of each line
// for each line
// read type and size
// if type is 0xff
// no encoding, copy to output
// else
// RLE: set size pixels to type
// do this until all line is parsed
case 1:
{
//for each line we have offset of pixel data
const unsigned int * RWEntriesLoc = reinterpret_cast<const unsigned int *>(FDef+BaseOffset);
BaseOffset += sizeof(int) * SpriteHeight;
for (unsigned int i=0; i<SpriteHeight; i++)
{
BaseOffset=BaseOffsetor + SDL_SwapLE32(read_unaligned_u32(RWEntriesLoc + i));
if (LeftMargin>0)
ftcp += LeftMargin;
current += LeftMargin;
TotalRowLength=0;
do
{
unsigned int SegmentLength;
SegmentType=FDef[BaseOffset++];
SegmentLength=FDef[BaseOffset++] + 1;
unsigned char SegmentType=FDef[BaseOffset++];
unsigned int SegmentLength=FDef[BaseOffset++] + 1;
if (SegmentType==0xFF)
{
memcpy(reinterpret_cast<char*>(ret->pixels)+ftcp, FDef + BaseOffset, SegmentLength);
memcpy(reinterpret_cast<char*>(ret->pixels)+current, FDef + BaseOffset, SegmentLength);
BaseOffset+=SegmentLength;
}
else
{
memset(reinterpret_cast<char*>(ret->pixels)+ftcp, SegmentType, SegmentLength);
memset(reinterpret_cast<char*>(ret->pixels)+current, SegmentType, SegmentLength);
}
ftcp += SegmentLength;
current += SegmentLength;
TotalRowLength += SegmentLength;
}
while (TotalRowLength<SpriteWidth);
@ -166,70 +171,80 @@ SDL_Surface * CDefFile::loadFrame (const unsigned char * FDef, const BMPPalette
RowAdd=SpriteWidth-TotalRowLength;
if (RightMargin>0)
ftcp += RightMargin;
current += RightMargin;
if (add>0)
ftcp += add+RowAdd;
current += add+RowAdd;
}
}
break;
// Something like RLE
// read base offset
// for each line
// read type, set code and value
// if code is 7
// copy value pixels
// else
// set value pixels to code
case 2:
{
BaseOffset = BaseOffsetor + SDL_SwapLE16(read_unaligned_u16(FDef + BaseOffsetor));
for (unsigned int i=0; i<SpriteHeight; i++)
{
//BaseOffset = BaseOffsetor+RWEntries[i];
if (LeftMargin>0)
ftcp += LeftMargin;
current += LeftMargin;
TotalRowLength=0;
do
{
SegmentType=FDef[BaseOffset++];
unsigned char SegmentType=FDef[BaseOffset++];
unsigned char code = SegmentType / 32;
unsigned char value = (SegmentType & 31) + 1;
if (code==7)
{
memcpy(reinterpret_cast<char*>(ret->pixels)+ftcp, &FDef[BaseOffset], value);
ftcp += value;
memcpy(reinterpret_cast<char*>(ret->pixels)+current, &FDef[BaseOffset], value);
current += value;
BaseOffset += value;
}
else
{
memset(reinterpret_cast<char*>(ret->pixels)+ftcp, code, value);
ftcp += value;
memset(reinterpret_cast<char*>(ret->pixels)+current, code, value);
current += value;
}
TotalRowLength+=value;
}
while (TotalRowLength<SpriteWidth);
if (RightMargin>0)
ftcp += RightMargin;
current += RightMargin;
RowAdd=SpriteWidth-TotalRowLength;
if (add>0)
ftcp += add+RowAdd;
current += add+RowAdd;
}
}
break;
//combo of 1st and 2nd:
// offset for each line
// code and value combined in 1 byte
case 3:
{
for (unsigned int i=0; i<SpriteHeight; i++)
{
BaseOffset = BaseOffsetor + SDL_SwapLE16(read_unaligned_u16(FDef + BaseOffsetor+i*2*(SpriteWidth/32)));
if (LeftMargin>0)
ftcp += LeftMargin;
current += LeftMargin;
TotalRowLength=0;
do
{
SegmentType=FDef[BaseOffset++];
unsigned char SegmentType=FDef[BaseOffset++];
unsigned char code = SegmentType / 32;
unsigned char value = (SegmentType & 31) + 1;
@ -238,26 +253,26 @@ SDL_Surface * CDefFile::loadFrame (const unsigned char * FDef, const BMPPalette
if (code==7)
{
memcpy((ui8*)ret->pixels + ftcp, FDef + BaseOffset, len);
ftcp += len;
memcpy((ui8*)ret->pixels + current, FDef + BaseOffset, len);
current += len;
BaseOffset += len;
}
else
{
memset((ui8*)ret->pixels + ftcp, code, len);
ftcp += len;
memset((ui8*)ret->pixels + current, code, len);
current += len;
}
TotalRowLength+=( LeftMargin>=0 ? value : value+LeftMargin );
}
while (TotalRowLength<SpriteWidth);
if (RightMargin>0)
ftcp += RightMargin;
current += RightMargin;
RowAdd=SpriteWidth-TotalRowLength;
if (add>0)
ftcp += add+RowAdd;
current += add+RowAdd;
}
}
break;
@ -267,8 +282,9 @@ SDL_Surface * CDefFile::loadFrame (const unsigned char * FDef, const BMPPalette
break;
}
SDL_Color ttcol = ret->format->palette->colors[0];
Uint32 keycol = SDL_MapRGBA(ret->format, ttcol.r, ttcol.b, ttcol.g, ttcol.unused);
SDL_Color *col = ret->format->palette->colors;
Uint32 keycol = SDL_MapRGBA(ret->format, col[0].r, col[0].b, col[0].g, col[0].unused);
SDL_SetColorKey(ret, SDL_SRCCOLORKEY, keycol);
return ret;
};
@ -282,6 +298,15 @@ BMPPalette * CDefFile::getPalette()
CDefFile::CDefFile(std::string Name):data(NULL),colors(NULL)
{
static SDL_Color H3Palette[8] = {{ 0, 0, 0, 255},
{ 0, 0, 0, 192},
/* 5 shadow colors */ { 0, 0, 0, 128},
{ 0, 0, 0, 64},
{ 0, 0, 0, 32},
{255, 255, 0, 255},
/* 3 selection highlight color */{255, 255, 0, 255},
{255, 255, 0, 255}};
data = spriteh->giveFile(Name, FILE_ANIMATION, &datasize);
if (!data)
{
@ -292,37 +317,41 @@ CDefFile::CDefFile(std::string Name):data(NULL),colors(NULL)
colors = new BMPPalette[256];
int it = 0;
//int type = readNormalNr(data, it); it+=4;
type = readNormalNr(data, it); it+=4;
//int width = readNormalNr(data, it); it+=4;//not used
//int height = readNormalNr(data, it); it+=4;
it+=12;
it+=8;
unsigned int totalBlocks = readNormalNr(data, it);
it+=4;
for (unsigned int i=0; i<256; i++)
for (unsigned int i= 0; i<256; i++)
{
colors[i].R = data[it++];
colors[i].G = data[it++];
colors[i].B = data[it++];
colors[i].F = 0;
}
memcpy(colors, H3Palette, (type == 66)? 32:20);//initialize shadow\selection colors
offset.resize(totalBlocks);
offList.insert(datasize);
for (unsigned int i=0; i<totalBlocks; i++)
{
size_t blockID = readNormalNr(data, it);
it+=4;
unsigned int totalEntries = readNormalNr(data, it);
size_t totalEntries = readNormalNr(data, it);
it+=12;
//8 unknown bytes - skipping
//13 bytes for name of every frame in this block - not used, skipping
it+= 13 * totalEntries;
offset.resize(std::max(blockID+1, offset.size()));
for (unsigned int j=0; j<totalEntries; j++)
{
size_t currOffset = readNormalNr(data, it);
offset[i].push_back(currOffset);
offset[blockID].push_back(currOffset);
offList.insert(currOffset);
it += 4;
}
@ -353,6 +382,8 @@ unsigned char * CDefFile::getFrame(size_t frame, size_t group) const
CDefFile::~CDefFile()
{
offset.clear();
offList.clear();
delete[] data;
delete[] colors;
}
@ -379,7 +410,10 @@ CAnimation::AnimEntry::AnimEntry():
bool CAnimation::loadFrame(CDefFile * file, size_t frame, size_t group)
{
if (groupSize(group) <= frame)
{
printError(frame, group, "LoadFrame");
return false;
}
AnimEntry &e = entries[group][frame];
if (e.surf || e.data)
@ -410,7 +444,7 @@ bool CAnimation::loadFrame(CDefFile * file, size_t frame, size_t group)
else
{
e.surf = IMG_Load_RW( SDL_RWFromMem((void*)pic, size), 1);
delete pic;
delete [] pic;
}
}
}
@ -438,7 +472,7 @@ bool CAnimation::unloadFrame(size_t frame, size_t group)
return true;
SDL_FreeSurface(e.surf);
delete e.data;
delete [] e.data;
e.surf = NULL;
e.data = NULL;
@ -501,7 +535,13 @@ void CAnimation::init(CDefFile * file)
if (!toAdd.empty())
{
entries.push_back(toAdd);
break;
}
else
{
entries.resize(entries.size()+1);
if (group > 21)
break;//FIXME: crude workaround: if some groups are not present
//(common for creatures) parser will exit before reaching them
}
}
}
@ -532,7 +572,6 @@ CAnimation::CAnimation(std::string Name, bool Compressed):
int dotPos = name.find_last_of('.');
if ( dotPos != -1 )
name.erase(dotPos);
CDefFile * file = getFile();
init(file);
delete file;
@ -548,12 +587,11 @@ CAnimation::CAnimation():
CAnimation::~CAnimation()
{
delete defPalette;
delete [] defPalette;
for (size_t i = 0; i < entries.size(); i++)
for (size_t j = 0; j < entries.at(i).size(); j++)
{
delete entries[i][j].data;
delete [] entries[i][j].data;
if (entries[i][j].surf)
SDL_FreeSurface(entries[i][j].surf);
}
@ -575,21 +613,25 @@ void CAnimation::add(SDL_Surface * surf, bool shared, size_t group)
entries[group].back().surf = surf;
}
void CAnimation::purgeCompressed()
void CAnimation::removeDecompressed(size_t frame, size_t group)
{
for (size_t group; group < entries.size(); group++)
for (size_t frame; frame < entries[group].size(); frame++)
if (entries[group][frame].surf)
SDL_FreeSurface(entries[group][frame].surf);
AnimEntry &e = entries[group][frame];
if (e.surf && e.data)
{
SDL_FreeSurface(e.surf);
e.surf = NULL;
}
}
SDL_Surface * CAnimation::image(size_t frame)
{
size_t group=0;
for (; group<entries.size() && frame > entries[group].size(); group++)
while (group<entries.size() && frame > entries[group].size())
frame -= entries[group].size();
return image(frame, group);
if (group <entries.size() && frame < entries[group].size())
return image(frame, group);
return NULL;
}
SDL_Surface * CAnimation::image(size_t frame, size_t group)
@ -634,13 +676,14 @@ void CAnimation::loadGroup(size_t group)
{
CDefFile * file = getFile();
for (size_t frame = 0; frame<entries[group].size(); frame++)
for (size_t frame = 0; frame<groupSize(group); frame++)
loadFrame(file, frame, group);
delete file;
}
void CAnimation::unloadGroup(size_t group)
{
for (size_t frame = 0; frame<entries[group].size(); frame++)
for (size_t frame = 0; frame<groupSize(group); frame++)
unloadFrame(frame, group);
}
@ -693,3 +736,249 @@ size_t CAnimation::size() const
}
return ret;
}
/*
CAnimImage::CAnimImage(int x, int y, std::string name, size_t Frame, size_t Group):
anim(name),
frame(Frame),
group(Group)
{
anim.load(frame, group);
pos.w = anim.image(frame, group)->w;
pos.h = anim.image(frame, group)->h;
}
CAnimImage::~CAnimImage()
{
}
void CAnimImage::show(SDL_Surface *to)
{
blitAtLoc(anim.image(frame, group), 0,0, to);
}
void CAnimImage::setFrame(size_t Frame, size_t Group)
{
if (frame == Frame && group==Group)
return;
if (anim.groupSize(Group) > Frame)
{
anim.unload(frame, group);
anim.load(Frame, Group);
frame = Frame;
group = Group;
}
}
*/
CShowableAnim::CShowableAnim(int x, int y, std::string name, unsigned char Flags, unsigned int Delay, size_t Group):
anim(name, Flags),
group(Group),
frame(0),
first(0),
flags(Flags),
frameDelay(Delay),
value(0),
xOffset(0),
yOffset(0)
{
pos.x+=x;
pos.y+=y;
anim.loadGroup(group);
last = anim.groupSize(group);
pos.w = anim.image(0, group)->w;
pos.h = anim.image(0, group)->h;
}
CShowableAnim::~CShowableAnim()
{
}
bool CShowableAnim::set(size_t Group, size_t from, size_t to)
{
size_t max = anim.groupSize(Group);
if (max>to)
max = to;
if (max < from || max == 0)
return false;
anim.load(Group);
anim.unload(group);
group = Group;
frame = first = from;
last = max;
value = 0;
return true;
}
bool CShowableAnim::set(size_t Group)
{
if (anim.groupSize(Group)== 0)
return false;
if (group != Group)
{
anim.loadGroup(Group);
anim.unloadGroup(group);
first = 0;
group = Group;
last = anim.groupSize(Group);
}
frame = value = 0;
return true;
}
void CShowableAnim::reset()
{
value = 0;
frame = first;
if (callback)
callback();
}
void CShowableAnim::movePic( int byX, int byY)
{
xOffset += byX;
yOffset += byY;
}
void CShowableAnim::show(SDL_Surface *to)
{
if ( flags & FLAG_BASE && frame != first)
blitImage(anim.image(first, group), to);
blitImage(anim.image(frame, group), to);
if ( ++value == frameDelay )
{
value = 0;
if (flags & FLAG_COMPRESSED)
anim.removeDecompressed(frame, group);
if ( ++frame == last)
reset();
}
}
void CShowableAnim::showAll(SDL_Surface *to)
{
show(to);
}
void CShowableAnim::blitImage(SDL_Surface *what, SDL_Surface *to)
{
assert(what);
//TODO: SDL RLE?
SDL_Rect dstRect=genRect(pos.h, pos.w, pos.x, pos.y);
SDL_Rect srcRect;
srcRect.x = xOffset;
srcRect.y = yOffset;
srcRect.w = pos.w;
srcRect.h = pos.h;
/*if ( flags & FLAG_ROTATED )
{} //TODO: rotate surface
else */
if (flags & FLAG_ALPHA && what->format->BytesPerPixel == 1) //alpha on 8-bit surf - use custom blitter
CSDL_Ext::blit8bppAlphaTo24bpp(what, &srcRect, to, &dstRect);
else
CSDL_Ext::blitSurface(what, &srcRect, to, &dstRect);
}
void CShowableAnim::rotate(bool on)
{
if (on)
flags |= FLAG_ROTATED;
else
flags &= ~FLAG_ROTATED;
}
CCreatureAnim::CCreatureAnim(int x, int y, std::string name, unsigned char flags, EAnimType type):
CShowableAnim(x,y,name,flags,3,type)
{
if (flags & FLAG_PREVIEW)
callback = boost::bind(&CCreatureAnim::loopPreview,this);
};
void CCreatureAnim::loopPreview()
{
std::vector<EAnimType> available;
if (anim.groupSize(ANIM_HOLDING))
available.push_back(ANIM_HOLDING);
if (anim.groupSize(ANIM_HITTED))
available.push_back(ANIM_HITTED);
if (anim.groupSize(ANIM_DEFENCE))
available.push_back(ANIM_DEFENCE);
if (anim.groupSize(ANIM_ATTACK_FRONT))
available.push_back(ANIM_ATTACK_FRONT);
if (anim.groupSize(ANIM_CAST_FRONT))
available.push_back(ANIM_CAST_FRONT);
size_t rnd = rand()%(available.size()*2);
if (rnd >= available.size())
{
if ( anim.groupSize(ANIM_MOVING) == 0 )//no moving animation present
addLast( ANIM_HOLDING );
else
addLast( ANIM_MOVING ) ;
}
else
addLast(available[rnd]);
}
void CCreatureAnim::addLast(EAnimType newType)
{
if (type != ANIM_MOVING && newType == ANIM_MOVING)//starting moving - play init sequence
{
queue.push( ANIM_MOVE_START );
}
else if (type == ANIM_MOVING && newType != ANIM_MOVING )//previous anim was moving - finish it
{
queue.push( ANIM_MOVE_END);
}
if (newType == ANIM_TURN_L || newType == ANIM_TURN_R)
queue.push(newType);
queue.push(newType);
}
void CCreatureAnim::reset()
{
//if we are in the middle of rotation - set flag
if (type == ANIM_TURN_L && !queue.empty() && queue.front() == ANIM_TURN_L)
flags |= FLAG_ROTATED;
if (type == ANIM_TURN_R && !queue.empty() && queue.front() == ANIM_TURN_R)
flags &= ~FLAG_ROTATED;
while (!queue.empty())//FIXME: remove dublication
{
EAnimType at = queue.front();
queue.pop();
if (set(at))
return;
}
if (callback)
callback();
while (!queue.empty())
{
EAnimType at = queue.front();
queue.pop();
if (set(at))
return;
}
tlog0<<"Warning: next sequence is not found for animation!\n";
}
void CCreatureAnim::clearAndSet(EAnimType type)
{
while (!queue.empty())
queue.pop();
set(type);
}

View File

@ -1,10 +1,15 @@
#ifndef __CANIMATION_H__
#define __CANIMATION_H__
#include <boost/function.hpp>
#include <vector>
#include <string>
#include <queue>
#include <set>
#include "../global.h"
#include "GUIBase.h"
/*
* CAnimation.h, part of VCMI engine
@ -37,6 +42,7 @@ private:
ui32 TopMargin;
};
unsigned int type;
unsigned char * data;
int datasize;
BMPPalette * colors;
@ -138,7 +144,7 @@ public:
void add(SDL_Surface * surf, bool shared=false, size_t group=0);
//removes all surfaces which have compressed data
void purgeCompressed();
void removeDecompressed(size_t frame, size_t group);
//get pointer to surface, this function ignores groups (like ourImages in DefHandler)
SDL_Surface * image (size_t frame);
@ -173,7 +179,135 @@ public:
//total count of frames in whole anim
size_t size() const;
};
/*
//Class for displaying one image from animation
class CAnimImage: public CIntObject
{
private:
CAnimation anim;
size_t frame;//displayed frame/group
size_t group;
public:
CAnimImage(int x, int y, std::string name, size_t Frame, size_t Group=0);//c-tor
~CAnimImage();//d-tor
//change displayed frame on this one
void setFrame(size_t Frame, size_t Group=0);
void show(SDL_Surface *to);
//TODO: showAll();
};
*/
//Base class for displaying animation, used as superclass for different animations
class CShowableAnim: public CIntObject
{
public:
enum EFlags
{
FLAG_BASE=1, //base frame will be blitted before current one
FLAG_COMPRESSED=2, //animations will be loaded in compressed state
FLAG_ROTATED=4, //will be displayed rotated
FLAG_ALPHA=8, //if image is 8bbp it will be printed with transparency (0=opaque, 255=transparent)
FLAG_USERLE=16, //not used for now, enable RLE compression from SDL
FLAG_PREVIEW=32 //for creatures only: several animation (move, attack, defence...) will be randomly selected
};
protected:
CAnimation anim;
size_t group, frame;//current frame
size_t first, last; //animation range
unsigned char flags;//flags from EFlags enum
unsigned int frameDelay;//delay in frames of each image
unsigned int value;//how many times current frame was showed
//blit image with optional rotation, fitting into rect, etc
void blitImage(SDL_Surface *what, SDL_Surface *to);
//For clipping in rect, offsets of picture coordinates
int xOffset, yOffset;
public:
//called when next animation sequence is required
boost::function<void()> callback;
CShowableAnim(int x, int y, std::string name, unsigned char flags, unsigned int Delay=4, size_t Group=0);
~CShowableAnim();
//set animation to group or part of group
bool set(size_t Group);
bool set(size_t Group, size_t from, size_t to=-1);
//set rotation flag
void rotate(bool on);
//move displayed part of picture (if picture is clipped to rect)
void movePic( int byX, int byY);
//set frame to first, call callback
virtual void reset();
//show current frame and increase counter
void show(SDL_Surface *to);
void showAll(SDL_Surface *to);
};
class CCreatureAnim: public CShowableAnim
{
public:
enum EAnimType // list of creature animations, numbers were taken from def files
{
ANIM_MOVING=0, //will automatically add MOVE_START and MOVE_END to queue
ANIM_MOUSEON=1,
ANIM_HOLDING=2,
ANIM_HITTED=3,
ANIM_DEFENCE=4,
ANIM_DEATH=5,
//ANIM_DEATH2=6, //unused?
ANIM_TURN_L=7, //will automatically play second part of anim and rotate creature
ANIM_TURN_R=8, //same
//ANIM_TURN_L2=9, //identical to previous?
//ANIM_TURN_R2=10,
ANIM_ATTACK_UP=11,
ANIM_ATTACK_FRONT=12,
ANIM_ATTACK_DOWN=13,
ANIM_SHOOT_UP=14,
ANIM_SHOOT_FRONT=15,
ANIM_SHOOT_DOWN=16,
ANIM_CAST_UP=17,
ANIM_CAST_FRONT=18,
ANIM_CAST_DOWN=19,
ANIM_2HEX_ATTACK_UP=17,
ANIM_2HEX_ATTACK_FRONT=18,
ANIM_2HEX_ATTACK_DOWN=19,
ANIM_MOVE_START=20, //no need to use this two directly - ANIM_MOVING will be enought
ANIM_MOVE_END=21
};
private:
// queue of animations waiting to be displayed
std::queue<EAnimType> queue;
//this funcction is used as callback if preview flag was set during construction
void loopPreview();
public:
//change anim to next if queue is not empty, call callback othervice
void reset();
//add sequence to the end of queue
void addLast(EAnimType newType);
//clear queue and set animation to this sequence
void clearAndSet(EAnimType type);
CCreatureAnim(int x, int y, std::string name, unsigned char flags=FLAG_COMPRESSED | FLAG_ALPHA | FLAG_PREVIEW,
EAnimType type=ANIM_HOLDING);
};

View File

@ -4,7 +4,7 @@
#include "SDL_Extensions.h"
#include "CAdvmapInterface.h"
#include "AdventureMapButton.h"
#include "../hch/CAnimation.h"
#include "CAnimation.h"
#include "../hch/CObjectHandler.h"
#include "../hch/CHeroHandler.h"
#include "../hch/CDefHandler.h"
@ -563,8 +563,8 @@ void CDefenceAnim::endAnim()
if(IDby!=-1)
owner->printConsoleAttacked(stackID, dmg, amountKilled, IDby);
const CStack * attacker = owner->curInt->cb->battleGetStackByID(IDby, false);
const CStack * attacked = owner->curInt->cb->battleGetStackByID(stackID, false);
//const CStack * attacker = owner->curInt->cb->battleGetStackByID(IDby, false);
//const CStack * attacked = owner->curInt->cb->battleGetStackByID(stackID, false);
CBattleAnimation::endAnim();
@ -600,7 +600,7 @@ bool CBattleStackMoved::init()
endAnim();
return false;
}
bool twoTiles = movedStack->doubleWide();
//bool twoTiles = movedStack->doubleWide();
Point begPosition = CBattleHex::getXYUnitAnim(curStackPos, movedStack->attackerOwned, movedStack, owner);
Point endPosition = CBattleHex::getXYUnitAnim(destHex, movedStack->attackerOwned, movedStack, owner);

View File

@ -2,6 +2,7 @@
#include "CCastleInterface.h"
#include "AdventureMapButton.h"
#include "CAdvmapInterface.h"
#include "CAnimation.h"
#include "../CCallback.h"
#include "CGameInfo.h"
#include "CHeroWindow.h"
@ -20,7 +21,7 @@
#include "../lib/map.h"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/assign/std/vector.hpp>
#include <boost/assign/std/vector.hpp>
#include <boost/lexical_cast.hpp>
#include <cmath>
#include <sstream>
@ -52,45 +53,32 @@ int hordeToDwellingID(int bid)//helper, converts horde buiding ID into correspon
}
CBuildingRect::CBuildingRect(Structure *Str)
:moi(false), offset(0), str(Str)
:CShowableAnim(0, 0, Str->defName, CShowableAnim::FLAG_BASE),
moi(false), str(Str)
{
def = CDefHandler::giveDef(Str->defName);
max = def->ourImages.size();
if(str->ID == 33 && str->townID == 4) //little 'hack' for estate in necropolis - background color is not always the first color in the palette
{
for(std::vector<Cimage>::iterator i=def->ourImages.begin();i!=def->ourImages.end();i++)
{
SDL_SetColorKey(i->bitmap,SDL_SRCCOLORKEY,*((char*)i->bitmap->pixels));
}
}
pos.x += str->pos.x + LOCPLINT->castleInt->pos.x;
pos.y += str->pos.y + LOCPLINT->castleInt->pos.y;
if(str->ID == 33 && str->townID == 4) //little 'hack' for estate in necropolis - background color is not always the first color in the palette
for(size_t i=0; i<anim.groupSize(0);i++)
SDL_SetColorKey(anim.image(i,0), SDL_SRCCOLORKEY,
*((char*)(anim.image(i,0)->pixels)));
pos.x = str->pos.x + LOCPLINT->castleInt->pos.x;
pos.y = str->pos.y + LOCPLINT->castleInt->pos.y;
pos.w = def->ourImages[0].bitmap->w;
pos.h = def->ourImages[0].bitmap->h;
if(Str->ID<0 || (Str->ID>=27 && Str->ID<=29))
{
area = border = NULL;
return;
}
border = BitmapHandler::loadBitmap(str->borderName);
if (border)
{
SDL_SetColorKey(border,SDL_SRCCOLORKEY,SDL_MapRGB(border->format,0,255,255));
}
else
border = BitmapHandler::loadBitmap(str->borderName, true);
if (!border)
{
tlog2 << "Warning: no border for "<<Str->ID<<std::endl;
}
area = BitmapHandler::loadBitmap(str->areaName); //FIXME look up
if (area)
{
;//SDL_SetColorKey(area,SDL_SRCCOLORKEY,SDL_MapRGB(area->format,0,255,255));
}
else
area = BitmapHandler::loadBitmap(str->areaName);
if (!area)
{
tlog2 << "Warning: no area for "<<Str->ID<<std::endl;
}
@ -98,7 +86,6 @@ CBuildingRect::CBuildingRect(Structure *Str)
CBuildingRect::~CBuildingRect()
{
delete def;
if(border)
SDL_FreeSurface(border);
if(area)
@ -152,16 +139,14 @@ void CBuildingRect::hover(bool on)
}
}
}
void CBuildingRect::clickLeft(tribool down, bool previousState)
{
if( area && (LOCPLINT->castleInt->hBuild==this) && !(indeterminate(down)) &&
!CSDL_Ext::isTransparent(area, GH.current->motion.x-pos.x, GH.current->motion.y-pos.y) ) //inside building image
{
if(previousState && !down)
if( previousState && !down && area && (LOCPLINT->castleInt->hBuild==this) )
if (!CSDL_Ext::isTransparent(area, GH.current->motion.x-pos.x, GH.current->motion.y-pos.y) ) //inside building image
LOCPLINT->castleInt->buildingClicked(str->ID);
//ClickableL::clickLeft(down);
}
}
void CBuildingRect::clickRight(tribool down, bool previousState)
{
if((!area) || (!((bool)down)) || (this!=LOCPLINT->castleInt->hBuild))
@ -169,7 +154,7 @@ void CBuildingRect::clickRight(tribool down, bool previousState)
if( !CSDL_Ext::isTransparent(area, GH.current->motion.x-pos.x, GH.current->motion.y-pos.y) ) //inside building image
{
int bid = hordeToDwellingID(str->ID);
CBuilding *bld = CGI->buildh->buildings[str->townID].find(bid)->second;
assert(bld);
@ -186,11 +171,24 @@ void CBuildingRect::clickRight(tribool down, bool previousState)
}
}
void CBuildingRect::show(SDL_Surface *to)
{
CShowableAnim::show(to);
if(LOCPLINT->castleInt->hBuild == this && border) //if this this higlighted structure and has border we'll blit it
blitAtLoc(border,0,0,to);
}
void CBuildingRect::showAll(SDL_Surface *to)
{
show(to);
}
std::string getBuildingSubtitle(int tid, int bid)//hover text for building
{
const CGTownInstance * t = LOCPLINT->castleInt->town;
bid = hordeToDwellingID(bid);
if (bid<30)//non-dwellings - only buiding name
return CGI->buildh->buildings[tid].find(bid)->second->Name();
else//dwellings - recruit %creature%
@ -214,27 +212,19 @@ void CBuildingRect::mouseMoved (const SDL_MouseMotionEvent & sEvent)
}
else //inside the area of this building
{
if(LOCPLINT->castleInt->hBuild) //a building is hovered
{
if((*LOCPLINT->castleInt->hBuild)<(*this)) //set if we are on top
{
LOCPLINT->castleInt->hBuild = this;
GH.statusbar->print(getBuildingSubtitle(str->townID, str->ID));
}
}
else //no building hovered
if(! LOCPLINT->castleInt->hBuild //no building hovered
|| (*LOCPLINT->castleInt->hBuild)<(*this)) //or we are on top
{
LOCPLINT->castleInt->hBuild = this;
GH.statusbar->print(getBuildingSubtitle(str->townID, str->ID));
}
}
}
//if(border)
// blitAt(border,pos.x,pos.y);
}
void CHeroGSlot::hover (bool on)
{
if(!on)
if(!on)
{
GH.statusbar->clear();
return;
@ -284,10 +274,6 @@ void CHeroGSlot::hover (bool on)
GH.statusbar->print(temp);
}
void CHeroGSlot::clickRight(tribool down, bool previousState)
{
}
void CHeroGSlot::clickLeft(tribool down, bool previousState)
{
CHeroGSlot *other = upg ? &owner->hslotup : &owner->hslotdown;
@ -341,19 +327,10 @@ void CHeroGSlot::clickLeft(tribool down, bool previousState)
//}
}
void CHeroGSlot::activate()
{
activateLClick();
activateRClick();
activateHover();
}
void CHeroGSlot::deactivate()
{
highlight = false;
deactivateLClick();
deactivateRClick();
deactivateHover();
CIntObject::deactivate();
}
void CHeroGSlot::show(SDL_Surface * to)
@ -544,7 +521,7 @@ void CCastleInterface::buildingClicked(int building)
}
}
else
{
{
enterMageGuild();
}
break;
@ -572,8 +549,8 @@ void CCastleInterface::buildingClicked(int building)
if(!vstd::contains(town->forbiddenBuildings, 26))
{
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[597], //Do you wish this to be the permanent home of the Grail?
std::vector<SComponent*>(),
boost::bind(&CCallback::buildBuilding, LOCPLINT->cb, town, 26),
std::vector<SComponent*>(),
boost::bind(&CCallback::buildBuilding, LOCPLINT->cb, town, 26),
boost::bind(&CCastleInterface::enterHall, this), true);
}
else
@ -643,7 +620,7 @@ void CCastleInterface::buildingClicked(int building)
GH.pushInt(new CUniversityWindow(town->garrisonHero, town));
else//no hero in town - default popup
defaultBuildingClicked(building);
break;
default:
defaultBuildingClicked(building);
@ -665,7 +642,7 @@ void CCastleInterface::buildingClicked(int building)
LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[126], std::vector<SComponent*>(), soundBase::sound_todo);
break;//only visiting hero can use castle gates
}
std::vector <int> availableTowns;
std::vector <const CGTownInstance*> Towns = LOCPLINT->cb->getTownsInfo(false);
for(size_t i=0;i<Towns.size();i++)
@ -690,15 +667,15 @@ void CCastleInterface::buildingClicked(int building)
hero = town->garrisonHero;
else
hero = NULL;//no hero - will trade with town garrison
GH.pushInt ( new CTransformerWindow(hero, town) );
break;
/*Dungeon*/ case 5: //Portal of Summoning
if (town->creatures[CREATURES_PER_TOWN].second.empty())
//extra dwelling has no creatures in it
LOCPLINT->showInfoDialog(CGI->generaltexth->tcommands[30], std::vector<SComponent*>(), soundBase::sound_todo);
else
else
this->showRecruitmentWindow(CREATURES_PER_TOWN);
break;
/*Stronghold*/ case 6: //Ballista Yard
@ -828,30 +805,13 @@ void CCastleInterface::townChange()
void CCastleInterface::show(SDL_Surface * to)
{
count++;
if(count==5)
{
count=0;
animval++;
}
blitAt(cityBg,pos,to);
//blit buildings
for(size_t i=0;i<buildings.size();i++)
{
int frame = ((animval)%(buildings[i]->max - buildings[i]->offset)) + buildings[i]->offset;
if(frame)
{
blitAt(buildings[i]->def->ourImages[0].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,to);
blitAt(buildings[i]->def->ourImages[frame].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,to);
}
else
blitAt(buildings[i]->def->ourImages[frame].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,to);
if(hBuild==buildings[i] && hBuild->border) //if this this higlighted structure and has border we'll blit it
blitAt(hBuild->border,hBuild->pos,to);
buildings[i]->showAll(to);
}
statusbar->show(to);//refreshing statusbar
}
@ -992,7 +952,7 @@ void CCastleInterface::recreateBuildings()
Structure * st = CGI->townh->structures[town->subID][20];
buildings.push_back(new CBuildingRect(st));
s.insert(std::pair<int,int>(st->group,st->ID));
isThereShip = true;
isThereShip = true;
}
}
@ -1012,13 +972,11 @@ void CCastleInterface::recreateBuildings()
}
if(town->builtBuildings.find(4)!=town->builtBuildings.end()) //there is mage Guild level 5
{
vortex->offset = 10;
vortex->max = vortex->def->ourImages.size();
vortex->set(0,10);
}
else
{
vortex->offset = 0;
vortex->max = 10;
vortex->set(0,0,9);
}
}
//code for the shipyard in the Castle
@ -1043,13 +1001,11 @@ void CCastleInterface::recreateBuildings()
}
if(town->builtBuildings.find(8)!=town->builtBuildings.end()) //there is citadel
{
shipyard->offset = 1;
shipyard->max = shipyard->def->ourImages.size();
shipyard->set(0,1);
}
else
{
shipyard->offset = 0;
shipyard->max = 1;
shipyard->set(0,0,0);
}
}
}
@ -1154,7 +1110,7 @@ void CCastleInterface::CCreaInfo::clickRight(tribool down, bool previousState)
descr +="\n"+CGI->generaltexth->allTexts[590];
summ = CGI->creh->creatures[crid]->growth;
boost::algorithm::replace_first(descr,"%d", boost::lexical_cast<std::string>(summ));
if ( level>=0 && level<CREATURES_PER_TOWN)
{
@ -1168,7 +1124,7 @@ void CCastleInterface::CCreaInfo::clickRight(tribool down, bool previousState)
summ+=AddToString(CGI->generaltexth->artifNames[133] + " %+d",descr,
summ * ci->town->valOfGlobalBonuses
(Selector::type(Bonus::CREATURE_GROWTH_PERCENT) && Selector::sourceType(Bonus::ARTIFACT))/100); //Statue of Legion
(Selector::type(Bonus::CREATURE_GROWTH_PERCENT) && Selector::sourceType(Bonus::ARTIFACT))/100); //Statue of Legion
if(ci->town->town->hordeLvl[0]==level)//horde, x to summ
if((bld.find(18)!=bld.end()) || (bld.find(19)!=bld.end()))
@ -1200,7 +1156,7 @@ void CCastleInterface::CCreaInfo::clickRight(tribool down, bool previousState)
};
if (bl.size())
summ+=AddToString (CGI->arth->artifacts[bl.front().id]->Name()+" %+d", descr, bl.totalValue());
//TODO: player bonuses
if(bld.find(26)!=bld.end()) //grail - +50% to ALL growth
@ -1261,7 +1217,7 @@ void CCastleInterface::CTownInfo::hover(bool on)
{
std::string descr;
if ( bid == 6 ) {} //empty "no fort" icon. no hover message
else
else
if ( bid == 14 ) //marketplace/income icon
descr = CGI->generaltexth->allTexts[255];
else
@ -1282,7 +1238,7 @@ void CCastleInterface::CTownInfo::clickLeft(tribool down, bool previousState)
void CCastleInterface::CTownInfo::clickRight(tribool down, bool previousState)
{
if(down)
{
{
if (( bid == 6 ) || ( bid == 14) )
return;
CInfoPopup *mess = new CInfoPopup();
@ -1414,7 +1370,7 @@ void CHallInterface::CBuildingBox::show(SDL_Surface * to)
CCastleInterface *ci = LOCPLINT->castleInt;
if (( (BID == 18) && (vstd::contains(ci->town->builtBuildings,(ci->town->town->hordeLvl[0]+37))))
|| ( (BID == 24) && (vstd::contains(ci->town->builtBuildings,(ci->town->town->hordeLvl[1]+37)))) )
blitAt(ci->bicons->ourImages[BID+1].bitmap,pos.x,pos.y,to);
blitAt(ci->bicons->ourImages[BID+1].bitmap,pos.x,pos.y,to);
else
blitAt(ci->bicons->ourImages[BID].bitmap,pos.x,pos.y,to);
int pom, pom2=-1;
@ -1672,7 +1628,7 @@ CHallInterface::CBuildWindow::CBuildWindow(int Tid, int Bid, int State, bool Mod
CSDL_Ext::printAtMiddleWB(getTextForState(state),199,248,FONT_SMALL,50,zwykly,bitmap);
CSDL_Ext::printAtMiddle(CSDL_Ext::processStr(CGI->generaltexth->hcommands[7],pom),197,30,FONT_BIG,tytulowy,bitmap);
int resamount=0;
int resamount=0;
for(int i=0;i<7;i++)
{
if(CGI->buildh->buildings[tid][bid]->resources[i])
@ -1738,12 +1694,10 @@ CFortScreen::~CFortScreen()
void CFortScreen::show( SDL_Surface * to)
{
blitAt(bg,pos,to);
static unsigned char anim = 1;
for (int i=0; i<crePics.size(); i++)
{
crePics[i]->blitPic(to,pos.x+positions[i].x+159,pos.y+positions[i].y+4,!(anim%4));
crePics[i]->show(to);
}
anim++;
exit->show(to);
resdatabar->show(to);
GH.statusbar->show(to);
@ -1775,7 +1729,7 @@ void CFortScreen::close()
CFortScreen::CFortScreen( CCastleInterface * owner )
{
if (owner->town->creatures.size() > CREATURES_PER_TOWN
if (owner->town->creatures.size() > CREATURES_PER_TOWN
&& owner->town->creatures[CREATURES_PER_TOWN].second.size() )//dungeon with active portal
fortSize = CREATURES_PER_TOWN+1;
else
@ -1809,11 +1763,11 @@ void CFortScreen::draw( CCastleInterface * owner, bool first)
bg2 = BitmapHandler::loadBitmap("TPCASTL7.bmp");
else
bg2 = BitmapHandler::loadBitmap("TPCASTL8.bmp");
SDL_Surface *icons = BitmapHandler::loadBitmap("ZPCAINFO.bmp");
SDL_SetColorKey(icons,SDL_SRCCOLORKEY,SDL_MapRGB(icons->format,0,255,255));
graphics->blueToPlayersAdv(bg2,LOCPLINT->playerID);
bg = SDL_ConvertSurface(bg2,screen->format,0);
bg = SDL_ConvertSurface(bg2,screen->format,0);
SDL_FreeSurface(bg2);
printAtMiddle(CGI->buildh->buildings[owner->town->subID][owner->town->fortLevel()+6]->Name(),400,13,FONT_MEDIUM,zwykly,bg);
for(int i=0;i<fortSize; i++)
@ -1884,7 +1838,7 @@ void CFortScreen::draw( CCastleInterface * owner, bool first)
}
if(first)
{
crePics.push_back(new CCreaturePic(c,false));
crePics.push_back(new CCreaturePic( positions[i].x+pos.x+160, positions[i].y+pos.y+5, c,false));
if(present)
{
recAreas.push_back(new RecArea(i));
@ -1906,24 +1860,32 @@ void CFortScreen::RecArea::clickRight(tribool down, bool previousState)
}
CMageGuildScreen::CMageGuildScreen(CCastleInterface * owner)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
bg = new CPicture("TPMAGE.bmp");
pos = bg->center();
resdatabar = new CMinorResDataBar;
pos = owner->pos;
resdatabar->pos.x += pos.x;
resdatabar->pos.y += pos.y;
bg = BitmapHandler::loadBitmap("TPMAGE.bmp");
LOCPLINT->castleInt->statusbar->clear();
exit = new AdventureMapButton(CGI->generaltexth->allTexts[593],"",boost::bind(&CMageGuildScreen::close,this),pos.x+748,pos.y+556,"TPMAGE1.DEF",SDLK_RETURN);
exit = new AdventureMapButton(CGI->generaltexth->allTexts[593],"",boost::bind(&CMageGuildScreen::close,this), 748, 556,"TPMAGE1.DEF",SDLK_RETURN);
exit->assignedKeys.insert(SDLK_ESCAPE);
scrolls2 = CDefHandler::giveDefEss("TPMAGES.DEF");
CAnimation scrolls("TPMAGES.DEF");
scrolls.load();
SDL_Surface *view = BitmapHandler::loadBitmap(graphics->guildBgs[owner->town->subID]);
SDL_SetColorKey(view,SDL_SRCCOLORKEY,SDL_MapRGB(view->format,0,255,255));
blitAt(view,332,76,*bg);
SDL_FreeSurface(view);
positions.resize(5);
positions[0] += genRect(61,83,222,445), genRect(61,83,312,445), genRect(61,83,402,445), genRect(61,83,520,445), genRect(61,83,610,445), genRect(61,83,700,445);
positions[1] += genRect(61,83,48,53), genRect(61,83,48,147), genRect(61,83,48,241), genRect(61,83,48,335), genRect(61,83,48,429);
positions[2] += genRect(61,83,570,82), genRect(61,83,672,82), genRect(61,83,570,157), genRect(61,83,672,157);
positions[3] += genRect(61,83,183,42), genRect(61,83,183,148), genRect(61,83,183,253);
positions[4] += genRect(61,83,491,325), genRect(61,83,591,325);
blitAt(view,332,76,bg);
for(size_t i=0; i<owner->town->town->mageLevel; i++)
{
size_t sp = owner->town->spellsAtLevel(i+1,false); //spell at level with -1 hmmm?
@ -1931,30 +1893,27 @@ CMageGuildScreen::CMageGuildScreen(CCastleInterface * owner)
{
if(i<owner->town->mageGuildLevel() && owner->town->spells[i].size()>j)
{
spells.push_back(Scroll(&CGI->spellh->spells[owner->town->spells[i][j]]));
spells[spells.size()-1].pos = positions[i][j];
blitAt(graphics->spellscr->ourImages[owner->town->spells[i][j]].bitmap,positions[i][j],bg);
spells.push_back( new Scroll(&CGI->spellh->spells[owner->town->spells[i][j]]));
spells[spells.size()-1]->pos = positions[i][j];
blitAt(graphics->spellscr->ourImages[owner->town->spells[i][j]].bitmap,positions[i][j],*bg);
}
else
{
blitAt(scrolls2->ourImages[1].bitmap,positions[i][j],bg);
blitAt(scrolls.image(1),positions[i][j],*bg);
}
}
}
SDL_FreeSurface(view);
for(size_t i=0;i<spells.size();i++)
{
spells[i].pos.x += pos.x;
spells[i].pos.y += pos.y;
spells[i]->pos.x += pos.x;
spells[i]->pos.y += pos.y;
}
delete scrolls2;
}
CMageGuildScreen::~CMageGuildScreen()
{
delete exit;
SDL_FreeSurface(bg);
delete resdatabar;
}
void CMageGuildScreen::close()
@ -1962,30 +1921,10 @@ void CMageGuildScreen::close()
GH.popIntTotally(this);
}
void CMageGuildScreen::show(SDL_Surface * to)
CMageGuildScreen::Scroll::Scroll(CSpell *Spell)
:spell(Spell)
{
blitAt(bg,pos,to);
resdatabar->show(to);
GH.statusbar->show(to);
exit->show(to);
}
void CMageGuildScreen::activate()
{
exit->activate();
for(size_t i=0;i<spells.size();i++)
{
spells[i].activate();
}
}
void CMageGuildScreen::deactivate()
{
exit->deactivate();
for(size_t i=0;i<spells.size();i++)
{
spells[i].deactivate();
}
used = LCLICK | RCLICK | HOVER;
}
void CMageGuildScreen::Scroll::clickLeft(tribool down, bool previousState)
@ -2017,7 +1956,6 @@ void CMageGuildScreen::Scroll::clickRight(tribool down, bool previousState)
void CMageGuildScreen::Scroll::hover(bool on)
{
//Hoverable::hover(on);
if(on)
GH.statusbar->print(spell->name);
else
@ -2027,66 +1965,39 @@ void CMageGuildScreen::Scroll::hover(bool on)
CBlacksmithDialog::CBlacksmithDialog(bool possible, int creMachineID, int aid, int hid)
{
SDL_Surface *bg2 = BitmapHandler::loadBitmap("TPSMITH.bmp");
SDL_SetColorKey(bg2,SDL_SRCCOLORKEY,SDL_MapRGB(bg2->format,0,255,255));
graphics->blueToPlayersAdv(bg2,LOCPLINT->playerID);
bmp = SDL_ConvertSurface(bg2,screen->format,0);
SDL_FreeSurface(bg2);
bg2 = BitmapHandler::loadBitmap("TPSMITBK.bmp");
blitAt(bg2,64,50,bmp);
SDL_FreeSurface(bg2);
OBJ_CONSTRUCTION_CAPTURING_ALL;
// SDL_SetColorKey(bg2,SDL_SRCCOLORKEY,SDL_MapRGB(bg2->format,0,255,255));
bmp = new CPicture("TPSMITH");
bmp->colorizeAndConvert(LOCPLINT->playerID);
pos = bmp->center();
SDL_Surface *bg = BitmapHandler::loadBitmap("TPSMITBK.bmp");
blitAt(bg,64,50,*bmp);
SDL_FreeSurface(bg);
CCreatureAnimation cra(CGI->creh->creatures[creMachineID]->animDefName);
cra.nextFrameMiddle(bmp,170,120,true,0,false);
CCreatureAnim cra(170, 120, CGI->creh->creatures[creMachineID]->animDefName);
char pom[75];
sprintf(pom,CGI->generaltexth->allTexts[274].c_str(),CGI->creh->creatures[creMachineID]->nameSing.c_str()); //build a new ...
printAtMiddle(pom,165,28,FONT_MEDIUM,tytulowy,bmp);
printAtMiddle(CGI->generaltexth->jktexts[43],165,218,FONT_MEDIUM,zwykly,bmp); //resource cost
printAtMiddle(pom,165,28,FONT_MEDIUM,tytulowy,*bmp);
printAtMiddle(CGI->generaltexth->jktexts[43],165,218,FONT_MEDIUM,zwykly,*bmp); //resource cost
SDL_itoa(CGI->arth->artifacts[aid]->price,pom,10);
printAtMiddle(pom,165,290,FONT_MEDIUM,zwykly,bmp);
printAtMiddle(pom,165,290,FONT_MEDIUM,zwykly,*bmp);
pos.w = bmp->w;
pos.h = bmp->h;
pos.x = screen->w/2 - pos.w/2;
pos.y = screen->h/2 - pos.h/2;
buy = new AdventureMapButton("","",boost::bind(&CBlacksmithDialog::close,this),pos.x + 42,pos.y + 312,"IBUY30.DEF",SDLK_RETURN);
cancel = new AdventureMapButton("","",boost::bind(&CBlacksmithDialog::close,this),pos.x + 224,pos.y + 312,"ICANCEL.DEF",SDLK_ESCAPE);
buy = new AdventureMapButton("","",boost::bind(&CBlacksmithDialog::close,this), 42, 312,"IBUY30.DEF",SDLK_RETURN);
cancel = new AdventureMapButton("","",boost::bind(&CBlacksmithDialog::close,this), 224, 312,"ICANCEL.DEF",SDLK_ESCAPE);
if(possible)
buy->callback += boost::bind(&CCallback::buyArtifact,LOCPLINT->cb,LOCPLINT->cb->getHeroInfo(hid,2),aid);
else
buy->bitmapOffset = 2;
buy->block(2);
blitAt(graphics->resources32->ourImages[6].bitmap,148,244,bmp);
}
void CBlacksmithDialog::show( SDL_Surface * to )
{
blitAt(bmp,pos,to);
buy->show(to);
cancel->show(to);
}
void CBlacksmithDialog::activate()
{
if(!buy->bitmapOffset)
buy->activate();
cancel->activate();
}
void CBlacksmithDialog::deactivate()
{
if(!buy->bitmapOffset)
buy->deactivate();
cancel->deactivate();
blitAt(graphics->resources32->ourImages[6].bitmap,148,244,*bmp);
}
CBlacksmithDialog::~CBlacksmithDialog()
{
SDL_FreeSurface(bmp);
delete cancel;
delete buy;
}
void CBlacksmithDialog::close()

View File

@ -5,6 +5,7 @@
#include "../global.h"
#include <SDL.h>
#include "CAnimation.h"
#include "GUIBase.h"
#include "../hch/CMusicBase.h"
//#include "boost/tuple/tuple.hpp"
@ -19,6 +20,7 @@ class CStatusBar;
class CTownList;
class CRecruitmentWindow;
class CTransformerWindow;
class CPicture;
class CCreaturePic;
class CMinorResDataBar;
@ -32,13 +34,11 @@ class CMinorResDataBar;
*
*/
class CBuildingRect : public CIntObject
class CBuildingRect : public CShowableAnim
{
public:
bool moi; //motion interested is active
int offset, max; //first and last animation frame
Structure* str;
CDefHandler* def;
SDL_Surface* border;
SDL_Surface* area;
CBuildingRect(Structure *Str); //c-tor
@ -50,6 +50,8 @@ public:
void clickLeft(tribool down, bool previousState);
void clickRight(tribool down, bool previousState);
void mouseMoved (const SDL_MouseMotionEvent & sEvent);
void show(SDL_Surface *to);
void showAll(SDL_Surface *to);
};
class CHeroGSlot : public CIntObject
@ -63,9 +65,7 @@ public:
void setHighlight(bool on);
void hover (bool on);
void clickRight(tribool down, bool previousState);
void clickLeft(tribool down, bool previousState);
void activate();
void deactivate();
void show(SDL_Surface * to);
CHeroGSlot(int x, int y, int updown, const CGHeroInstance *h,CCastleInterface * Owner); //c-tor
@ -240,40 +240,35 @@ public:
public:
CSpell *spell;
Scroll(CSpell *Spell):spell(Spell){used = LCLICK | RCLICK | HOVER;};
Scroll(CSpell *Spell);
void clickLeft(tribool down, bool previousState);
void clickRight(tribool down, bool previousState);
void hover(bool on);
};
std::vector<std::vector<SDL_Rect> > positions;
SDL_Surface *bg;
CDefEssential *scrolls, *scrolls2;
CPicture *bg;
AdventureMapButton *exit;
std::vector<Scroll> spells;
std::vector<Scroll *> spells;
CMinorResDataBar * resdatabar;
CMageGuildScreen(CCastleInterface * owner); //c-tor
~CMageGuildScreen(); //d-tor
void close();
void show(SDL_Surface * to);
void activate();
void deactivate();
};
class CBlacksmithDialog : public CIntObject
{
public:
AdventureMapButton *buy, *cancel;
SDL_Surface *bmp; //background
CPicture *bmp; //background
CCreatureAnim * anim;
CBlacksmithDialog(bool possible, int creMachineID, int aid, int hid); //c-tor
~CBlacksmithDialog(); //d-tor
void close();
void show(SDL_Surface * to);
void activate();
void deactivate();
};
#endif // __CCASTLEINTERFACE_H__

View File

@ -2,7 +2,7 @@
#include "CMessage.h"
#include "SDL_ttf.h"
#include "../hch/CDefHandler.h"
#include "../hch/CAnimation.h"
#include "CAnimation.h"
#include "CGameInfo.h"
#include "SDL_Extensions.h"
#include "../hch/CLodHandler.h"

View File

@ -9,7 +9,7 @@
#include "SDL_Extensions.h"
#include "CGameInfo.h"
#include "CCursorHandler.h"
#include "../hch/CAnimation.h"
#include "CAnimation.h"
#include "../hch/CDefHandler.h"
#include "../hch/CDefObjInfoHandler.h"
#include "../hch/CGeneralTextHandler.h"
@ -2097,8 +2097,8 @@ void OptionsTab::PlayerOptionsEntry::selectButtons(bool onlyHero)
if(!btns[0])
return;
if(!onlyHero && pi.defaultCastle() != -1 //fixed tow
|| SEL->isGuest() && s.color != playerColor) //or not our player
if( (!onlyHero && pi.defaultCastle() != -1) //fixed tow
|| (SEL->isGuest() && s.color != playerColor)) //or not our player
{
btns[0]->disable();
btns[1]->disable();
@ -2109,8 +2109,8 @@ void OptionsTab::PlayerOptionsEntry::selectButtons(bool onlyHero)
btns[1]->enable(active);
}
if(pi.defaultHero() != -1 || !s.human || s.castle < 0 //fixed hero
|| SEL->isGuest() && s.color != playerColor)//or not our player
if( (pi.defaultHero() != -1 || !s.human || s.castle < 0) //fixed hero
|| (SEL->isGuest() && s.color != playerColor))//or not our player
{
btns[2]->disable();
btns[3]->disable();
@ -3128,7 +3128,7 @@ void CBonusSelection::CRegion::clickRight( tribool down, bool previousState )
void CBonusSelection::CRegion::show( SDL_Surface * to )
{
const SCampPositions::SRegionDesc & desc = owner->campDescriptions[owner->ourCampaign->camp->header.mapVersion].regions[myNumber];
//const SCampPositions::SRegionDesc & desc = owner->campDescriptions[owner->ourCampaign->camp->header.mapVersion].regions[myNumber];
if (!accessible)
{
//show as striped

View File

@ -709,7 +709,8 @@ void CSpellWindow::SpellArea::clickRight(tribool down, bool previousState)
if(down && mySpell != -1)
{
std::string dmgInfo;
int causedDmg = owner->myInt->cb->estimateSpellDamage( &CGI->spellh->spells[mySpell] );
const CGHeroInstance * hero = owner->myHero;
int causedDmg = owner->myInt->cb->estimateSpellDamage( &CGI->spellh->spells[mySpell], (hero ? hero : NULL));
if(causedDmg == 0)
dmgInfo = "";
else

View File

@ -110,7 +110,7 @@ public:
void showGarrisonDialog(int upobj, int hid, bool removableUnits, const boost::function<void()> &cb){};
void showThievesGuildWindow(int requestingObjId){};
void giveResource(int player, int which, int val){};
void giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet creatures) {};
void giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet creatures, bool remove) {};
void takeCreatures (int objid, TSlots creatures){};
void changeCreatureType (int objid, TSlot slot, TCreature creature){};
void showCompInfo(ShowInInfobox * comp){};

View File

@ -15,7 +15,7 @@
#include "CConfigHandler.h"
#include "CCreatureAnimation.h"
#include "Graphics.h"
#include "../hch/CAnimation.h"
#include "CAnimation.h"
#include "../hch/CArtHandler.h"
#include "../hch/CBuildingHandler.h"
#include "../hch/CGeneralTextHandler.h"
@ -464,8 +464,8 @@ CGarrisonInt::CGarrisonInt(int x, int y, int inx, const Point &garsOffset,
:interx(inx), garOffset(garsOffset), surOffset(SurOffset), highlighted(NULL), sur(pomsur), splitting(false),
smallIcons(smallImgs), removableUnits (_removableUnits), twoRows(_twoRows), oup(s1), odown(s2)
{
ourUp = s1?s1->tempOwner == LOCPLINT->playerID:false;
ourDown = s2?s2->tempOwner == LOCPLINT->playerID:false;
ourUp = s1?(s1->tempOwner == LOCPLINT->playerID || s1->tempOwner == 254):false; //254 - neutral objects (pandora, banks)
ourDown = s2?(s2->tempOwner == LOCPLINT->playerID || s2->tempOwner == 254):false;
set1 = LOCPLINT->cb->getGarrison(s1);
set2 = LOCPLINT->cb->getGarrison(s2);
pos.x += x;
@ -1632,37 +1632,37 @@ int CTownList::size()
return LOCPLINT->towns.size();
}
CCreaturePic::CCreaturePic(const CCreature *cre, bool Big)
CCreaturePic::CCreaturePic(int x, int y, const CCreature *cre, bool Big, bool Animated)
:c(cre),big(Big)
{
anim = new CCreatureAnimation(cre->animDefName);
OBJ_CONSTRUCTION_CAPTURING_ALL;
pos.x+=x;
pos.y+=y;
x = 225 - (c->isDoubleWide()?63:78);
y = 225 - (big?75:65);
anim = new CCreatureAnim(0,0, cre->animDefName);
anim->movePic(x,y);
anim->pos.w = 100;
anim->pos.h = big?130:120;
}
CCreaturePic::~CCreaturePic()
{
delete anim;
}
int CCreaturePic::blitPic(SDL_Surface *to, int x, int y, bool nextFrame)
void CCreaturePic::show(SDL_Surface *to)
{
SDL_Rect dst;
if(big)
{
blitAt(graphics->backgrounds[c->faction],x,y,to);//curx-50,pos.y+130-65);
dst = genRect(130,100,x,y);
}
blitAtLoc(graphics->backgrounds[c->faction],0,0,to);
else
{
blitAt(graphics->backgroundsm[c->faction],x,y,to);//curx-50,pos.y+130-65);
dst = genRect(120,100,x,y);
}
if(c->isDoubleWide())
x-=15;
return anim->nextFrameMiddle(to,x+78,y+(big ? 55 : 45),true,0,nextFrame,false,false,&dst);
}
SDL_Surface * CCreaturePic::getPic(bool nextFrame)
{
//TODO: write
return NULL;
blitAtLoc(graphics->backgroundsm[c->faction],0,0,to);
CIntObject::show(to);
}
void CRecruitmentWindow::close()
{
GH.popIntTotally(this);
@ -1783,7 +1783,6 @@ void CRecruitmentWindow::deactivate()
void CRecruitmentWindow::show(SDL_Surface * to)
{
static char animCounter=0; //animation counter - for determining appropriate animation frame to be shown
blitAt(bitmap,pos.x,pos.y,to);
buy->show(to);
max->show(to);
@ -1809,14 +1808,9 @@ void CRecruitmentWindow::show(SDL_Surface * to)
curx+=32+16;//size of bitmap + distance between them
}
curx = pos.x + 192 + CREATURE_WIDTH - (CREATURE_WIDTH*creatures.size()/2) - (SPACE_BETWEEN*(creatures.size()-1)/2);
for(int i=0; i<creatures.size(); ++i)
{
creatures[i].pic->blitPic(to, curx-50, pos.y+130-65, !(animCounter%4));
curx += TOTAL_CREATURE_WIDTH;
}
creatures[i].pic->show(to);
++animCounter;
bar->show(to);
}
@ -1854,17 +1848,18 @@ CRecruitmentWindow::CRecruitmentWindow(const CGDwelling *Dwelling, int Level, co
drawBorder(bitmap,289,312,66,34,int3(173,142,66));
//border for creatures
int curx = 192 + 51 - (CREATURE_WIDTH*creatures.size()/2) - (SPACE_BETWEEN*(creatures.size()-1)/2);
int curx = 192 + 50 - (CREATURE_WIDTH*creatures.size()/2) - (SPACE_BETWEEN*(creatures.size()-1)/2);
for(int i=0;i<creatures.size();i++)
{
creatures[i].pos.x = curx+1;
creatures[i].pos.x = curx;
creatures[i].pos.y = 65;
creatures[i].pos.w = 100;
creatures[i].pos.h = 130;
if(which==i)
drawBorder(bitmap,curx,64,CREATURE_WIDTH,132,int3(255,0,0));
drawBorder(bitmap,curx-1,64,CREATURE_WIDTH,132,int3(255,0,0));
else
drawBorder(bitmap,curx,64,CREATURE_WIDTH,132,int3(239,215,123));
drawBorder(bitmap,curx-1,64,CREATURE_WIDTH,132,int3(239,215,123));
creatures[i].pic = new CCreaturePic(pos.x+curx, pos.y+65, CGI->creh->creatures[creatures[i].ID]);
curx += TOTAL_CREATURE_WIDTH;
}
@ -1902,8 +1897,7 @@ void CRecruitmentWindow::initCres()
cur.amount = dwelling->creatures[i].first;
cur.ID = dwelling->creatures[i].second[j];
const CCreature *cre = CGI->creh->creatures[cur.ID];
cur.pic = new CCreaturePic(cre);
CCreature * cre= CGI->creh->creatures[cur.ID];
for(int k=0; k<cre->cost.size(); k++)
if(cre->cost[k])
@ -1948,8 +1942,8 @@ CSplitWindow::CSplitWindow(int cid, int max, CGarrisonInt *Owner, int Last, int
slider = new CSlider(pos.x+21,pos.y+194,257,boost::bind(&CSplitWindow::sliderMoved,this,_1),0,sliderPositions,val,true);
a1 = max-val;
a2 = val;
anim = new CCreaturePic(CGI->creh->creatures[cid]);
anim->anim->setType(1);
animLeft = new CCreaturePic(pos.x+20, pos.y+54, CGI->creh->creatures[cid], true, false);
animRight = new CCreaturePic(pos.x+177, pos.y+54, CGI->creh->creatures[cid], true, false);
std::string title = CGI->generaltexth->allTexts[256];
boost::algorithm::replace_first(title,"%s",CGI->creh->creatures[cid]->namePl);
@ -1962,7 +1956,8 @@ CSplitWindow::~CSplitWindow() //d-tor
delete ok;
delete cancel;
delete slider;
delete anim;
delete animLeft;
delete animRight;
}
void CSplitWindow::activate()
@ -2010,8 +2005,8 @@ void CSplitWindow::show(SDL_Surface * to)
slider->show(to);
printAtMiddle(boost::lexical_cast<std::string>(a1) + (!which ? "_" : ""),pos.x+70,pos.y+237,FONT_BIG,zwykly,to);
printAtMiddle(boost::lexical_cast<std::string>(a2) + (which ? "_" : ""),pos.x+233,pos.y+237,FONT_BIG,zwykly,to);
anim->blitPic(to,pos.x+20,pos.y+54,false);
anim->blitPic(to,pos.x+177,pos.y+54,false);
animLeft->show(to);
animRight->show(to);
}
void CSplitWindow::keyPressed (const SDL_KeyboardEvent & key)
@ -2077,9 +2072,7 @@ void CSplitWindow::clickLeft(tribool down, bool previousState)
void CCreInfoWindow::show(SDL_Surface * to)
{
blitAt(*bitmap,pos.x,pos.y,to);
anim->blitPic(to,pos.x+21,pos.y+48,(type) && !(anf%4));
if(++anf==4)
anf=0;
anim->show(to);
if(count.size())
printTo(count.c_str(),pos.x+114,pos.y+174,FONT_TIMES,zwykly,to);
if(upgrade)
@ -2157,7 +2150,6 @@ CCreInfoWindow::CCreInfoWindow(const CStackInstance &st, int Type, boost::functi
if(printed >= 3) //we can fit only 3 effects
break;
}
//print current health
printLine(5, CGI->generaltexth->allTexts[200], battleStack->firstHPleft);
}
@ -2188,19 +2180,13 @@ void CCreInfoWindow::init(const CCreature *cre, const CStackInstance *stack, int
else
finalNode = cre;
anf = 0;
c = cre;
bitmap = new CPicture("CRSTKPU.bmp");
bitmap->colorizeAndConvert(LOCPLINT->playerID);
pos = bitmap->center();
{
BLOCK_CAPTURING;
anim = new CCreaturePic(c);
}
if(!type) anim->anim->setType(2);
anim = new CCreaturePic(21, 48, c);
count = boost::lexical_cast<std::string>(creatureCount);
@ -2253,7 +2239,6 @@ CCreInfoWindow::CCreInfoWindow(int Cid, int Type, int creatureCount)
CCreInfoWindow::~CCreInfoWindow()
{
delete anim;
for(int i=0; i<upgResCost.size();i++)
delete upgResCost[i];
}
@ -2425,6 +2410,11 @@ void CMinorResDataBar::show(SDL_Surface * to)
,pos.x+545+(pos.w-545)/2,pos.y+pos.h/2,FONT_SMALL,zwykly,to);
}
void CMinorResDataBar::showAll(SDL_Surface * to)
{
show(to);
}
CMinorResDataBar::CMinorResDataBar()
{
bg = BitmapHandler::loadBitmap("Z2ESBAR.bmp");
@ -2913,8 +2903,10 @@ void CTradeWindow::getPositionsFor(std::vector<Rect> &poss, bool Left, EType typ
genRect(h, w, x + dx, y + 2*dy);
if(!Left)
{
BOOST_FOREACH(Rect &r, poss)
r.x += leftToRightOffset;
}
}
}
@ -3269,7 +3261,7 @@ void CMarketplaceWindow::selectionChanged(bool side)
bool CMarketplaceWindow::printButtonFor(EMarketMode M) const
{
return market->allowsTrade(M) && M != mode && (hero || M != CREATURE_RESOURCE && M != RESOURCE_ARTIFACT && M != ARTIFACT_RESOURCE);
return market->allowsTrade(M) && M != mode && (hero || ( M != CREATURE_RESOURCE && M != RESOURCE_ARTIFACT && M != ARTIFACT_RESOURCE ));
}
void CMarketplaceWindow::garrisonChanged()
@ -4418,9 +4410,18 @@ void CGarrisonWindow::show(SDL_Surface * to)
quit->show(to);
garr->show(to);
std::string title;
if (garr->odown->tempOwner == garr->oup->tempOwner)
title = CGI->generaltexth->allTexts[709];
else
{
title = CGI->generaltexth->allTexts[35];
boost::algorithm::replace_first(title, "%s", garr->oup->Slots().begin()->second.type->namePl);
}
blitAt(graphics->flags->ourImages[garr->odown->getOwner()].bitmap,pos.x+28,pos.y+124,to);
blitAt(graphics->portraitLarge[static_cast<const CGHeroInstance*>(garr->odown)->portrait],pos.x+29,pos.y+222,to);
printAtMiddle(CGI->generaltexth->allTexts[709],pos.x+275,pos.y+30,FONT_BIG,tytulowy,to);
printAtMiddle(title,pos.x+275,pos.y+30,FONT_BIG,tytulowy,to);
}
CGarrisonWindow::CGarrisonWindow( const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits )
@ -5992,28 +5993,21 @@ CHillFortWindow::CHillFortWindow(const CGHeroInstance *visitor, const CGObjectIn
quit = new AdventureMapButton("","",boost::bind(&CGuiHandler::popIntTotally, &GH, this), 294, 275, "IOKAY.DEF", SDLK_RETURN);
bar = new CGStatusBar(327, 332);
garr = new CGarrisonInt(pos.x+108, pos.y+60, 18, Point(),bg->bg,Point(108,60),hero,NULL);
garr = new CGarrisonInt(108, 60, 18, Point(),bg->bg,Point(108,60),hero,NULL);
updateGarrisons();
}
CHillFortWindow::~CHillFortWindow()
{
delete garr;
}
void CHillFortWindow::activate()
{
CIntObject::activate();
garr->activate();
GH.statusbar = bar;
}
void CHillFortWindow::deactivate()
{
CIntObject::deactivate();
garr->deactivate();
}
void CHillFortWindow::updateGarrisons()
{

View File

@ -42,7 +42,7 @@ class SComponent;
class CCreature;
struct SDL_Surface;
struct CPath;
class CCreatureAnimation;
class CCreatureAnim;
class CSelectableComponent;
class CCreatureSet;
class CGObjectInstance;
@ -435,16 +435,18 @@ public:
int size(); //how many elements do we have
};
class CCreaturePic //draws picture with creature on background, use nextFrame=true to get animation
class CCreaturePic : public CIntObject //draws picture with creature on background, use Animated=true to get animation
{
public:
private:
const CCreature *c; //which creature's picture
bool big; //big => 100x130; !big => 100x120
CCreatureAnimation *anim; //displayed animation
CCreaturePic(const CCreature *cre, bool Big=true); //c-tor
CCreatureAnim *anim; //displayed animation
public:
CCreaturePic(int x, int y, const CCreature *cre, bool Big=true, bool Animated=true); //c-tor
~CCreaturePic(); //d-tor
int blitPic(SDL_Surface *to, int x, int y, bool nextFrame); //prints creature on screen
SDL_Surface * getPic(bool nextFrame); //returns frame of animation
void show(SDL_Surface *to); //prints creature on screen
};
class CRecruitmentWindow : public CIntObject
@ -496,7 +498,7 @@ class CSplitWindow : public CIntObject
public:
CGarrisonInt *gar;
CSlider *slider;
CCreaturePic *anim; //creature's animation
CCreaturePic *animLeft, *animRight; //creature's animation
AdventureMapButton *ok, *cancel;
SDL_Surface *bitmap; //background
int a1, a2, c; //TODO: comment me
@ -538,6 +540,7 @@ class CMinorResDataBar : public CIntObject
public:
SDL_Surface *bg; //background bitmap
void show(SDL_Surface * to);
void showAll(SDL_Surface * to);
CMinorResDataBar(); //c-tor
~CMinorResDataBar(); //d-tor
};
@ -865,7 +868,6 @@ public:
//bool active; //TODO: comment me
int type;//0 - rclick popup; 1 - normal window
CPicture *bitmap; //background
char anf; //animation counter
std::string count; //creature count in text format
boost::function<void()> dsm; //dismiss button callback
@ -1082,7 +1084,7 @@ class CUniversityWindow : public CIntObject
public:
int ID;//id of selected skill
CUniversityWindow * parent;
void showAll(SDL_Surface * to);
void clickLeft(tribool down, bool previousState);
void clickRight(tribool down, bool previousState);
@ -1094,14 +1096,14 @@ class CUniversityWindow : public CIntObject
public:
const CGHeroInstance *hero;
const IMarket * market;
CPicture * green, * yellow, * red;//colored bars near skills
CPicture *bg; //background
std::vector<CItem*> items;
AdventureMapButton *cancel;
CGStatusBar *bar;
CUniversityWindow(const CGHeroInstance * _hero, const IMarket * _market); //c-tor
~CUniversityWindow(); //d-tor
};
@ -1136,13 +1138,12 @@ public:
const CGHeroInstance * hero;
std::vector<int> currState;//current state of slot - to avoid calls to getState or updating buttons
std::vector<std::map<int,int> > costs;// costs [slot ID] [resource ID] = resource count for upgrade
std::vector<int> totalSumm; // totalSum[resource ID] = value
std::vector<int> totalSumm; // totalSum[resource ID] = value
CHillFortWindow(const CGHeroInstance *visitor, const CGObjectInstance *object); //c-tor
~CHillFortWindow(); //d-tor
void activate();
void deactivate();
void showAll (SDL_Surface *to);
std::string getDefForSlot(int slot);//return def name for this slot
std::string getTextForSlot(int slot);//return hover text for this slot

View File

@ -13,8 +13,6 @@ vcmiclient_SOURCES = \
../CThreadHelper.h \
../StartInfo.h \
../global.h \
../hch/CAnimation.h \
../hch/CAnimation.cpp \
../hch/CBuildingHandler.h \
../hch/CDefHandler.cpp \
../hch/CDefHandler.h \
@ -39,6 +37,8 @@ vcmiclient_SOURCES = \
AdventureMapButton.h \
CAdvmapInterface.cpp \
CAdvmapInterface.h \
CAnimation.h \
CAnimation.cpp \
CBattleInterface.cpp \
CBattleInterface.h \
CBitmapHandler.cpp \

View File

@ -59,7 +59,6 @@ PROGRAMS = $(bin_PROGRAMS)
am_vcmiclient_OBJECTS = vcmiclient-CCallback.$(OBJEXT) \
vcmiclient-CGameInterface.$(OBJEXT) \
vcmiclient-CThreadHelper.$(OBJEXT) \
vcmiclient-CAnimation.$(OBJEXT) \
vcmiclient-CDefHandler.$(OBJEXT) \
vcmiclient-CMusicHandler.$(OBJEXT) \
vcmiclient-CSndHandler.$(OBJEXT) \
@ -67,6 +66,7 @@ am_vcmiclient_OBJECTS = vcmiclient-CCallback.$(OBJEXT) \
vcmiclient-CMapInfo.$(OBJEXT) \
vcmiclient-AdventureMapButton.$(OBJEXT) \
vcmiclient-CAdvmapInterface.$(OBJEXT) \
vcmiclient-CAnimation.$(OBJEXT) \
vcmiclient-CBattleInterface.$(OBJEXT) \
vcmiclient-CBitmapHandler.$(OBJEXT) \
vcmiclient-CCastleInterface.$(OBJEXT) \
@ -282,8 +282,6 @@ vcmiclient_SOURCES = \
../CThreadHelper.h \
../StartInfo.h \
../global.h \
../hch/CAnimation.h \
../hch/CAnimation.cpp \
../hch/CBuildingHandler.h \
../hch/CDefHandler.cpp \
../hch/CDefHandler.h \
@ -308,6 +306,8 @@ vcmiclient_SOURCES = \
AdventureMapButton.h \
CAdvmapInterface.cpp \
CAdvmapInterface.h \
CAnimation.h \
CAnimation.cpp \
CBattleInterface.cpp \
CBattleInterface.h \
CBitmapHandler.cpp \
@ -546,22 +546,6 @@ vcmiclient-CThreadHelper.obj: ../CThreadHelper.cpp
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -c -o vcmiclient-CThreadHelper.obj `if test -f '../CThreadHelper.cpp'; then $(CYGPATH_W) '../CThreadHelper.cpp'; else $(CYGPATH_W) '$(srcdir)/../CThreadHelper.cpp'; fi`
vcmiclient-CAnimation.o: ../hch/CAnimation.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -MT vcmiclient-CAnimation.o -MD -MP -MF $(DEPDIR)/vcmiclient-CAnimation.Tpo -c -o vcmiclient-CAnimation.o `test -f '../hch/CAnimation.cpp' || echo '$(srcdir)/'`../hch/CAnimation.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vcmiclient-CAnimation.Tpo $(DEPDIR)/vcmiclient-CAnimation.Po
@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../hch/CAnimation.cpp' object='vcmiclient-CAnimation.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -c -o vcmiclient-CAnimation.o `test -f '../hch/CAnimation.cpp' || echo '$(srcdir)/'`../hch/CAnimation.cpp
vcmiclient-CAnimation.obj: ../hch/CAnimation.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -MT vcmiclient-CAnimation.obj -MD -MP -MF $(DEPDIR)/vcmiclient-CAnimation.Tpo -c -o vcmiclient-CAnimation.obj `if test -f '../hch/CAnimation.cpp'; then $(CYGPATH_W) '../hch/CAnimation.cpp'; else $(CYGPATH_W) '$(srcdir)/../hch/CAnimation.cpp'; fi`
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vcmiclient-CAnimation.Tpo $(DEPDIR)/vcmiclient-CAnimation.Po
@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='../hch/CAnimation.cpp' object='vcmiclient-CAnimation.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -c -o vcmiclient-CAnimation.obj `if test -f '../hch/CAnimation.cpp'; then $(CYGPATH_W) '../hch/CAnimation.cpp'; else $(CYGPATH_W) '$(srcdir)/../hch/CAnimation.cpp'; fi`
vcmiclient-CDefHandler.o: ../hch/CDefHandler.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -MT vcmiclient-CDefHandler.o -MD -MP -MF $(DEPDIR)/vcmiclient-CDefHandler.Tpo -c -o vcmiclient-CDefHandler.o `test -f '../hch/CDefHandler.cpp' || echo '$(srcdir)/'`../hch/CDefHandler.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vcmiclient-CDefHandler.Tpo $(DEPDIR)/vcmiclient-CDefHandler.Po
@ -674,6 +658,22 @@ vcmiclient-CAdvmapInterface.obj: CAdvmapInterface.cpp
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -c -o vcmiclient-CAdvmapInterface.obj `if test -f 'CAdvmapInterface.cpp'; then $(CYGPATH_W) 'CAdvmapInterface.cpp'; else $(CYGPATH_W) '$(srcdir)/CAdvmapInterface.cpp'; fi`
vcmiclient-CAnimation.o: CAnimation.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -MT vcmiclient-CAnimation.o -MD -MP -MF $(DEPDIR)/vcmiclient-CAnimation.Tpo -c -o vcmiclient-CAnimation.o `test -f 'CAnimation.cpp' || echo '$(srcdir)/'`CAnimation.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vcmiclient-CAnimation.Tpo $(DEPDIR)/vcmiclient-CAnimation.Po
@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='CAnimation.cpp' object='vcmiclient-CAnimation.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -c -o vcmiclient-CAnimation.o `test -f 'CAnimation.cpp' || echo '$(srcdir)/'`CAnimation.cpp
vcmiclient-CAnimation.obj: CAnimation.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -MT vcmiclient-CAnimation.obj -MD -MP -MF $(DEPDIR)/vcmiclient-CAnimation.Tpo -c -o vcmiclient-CAnimation.obj `if test -f 'CAnimation.cpp'; then $(CYGPATH_W) 'CAnimation.cpp'; else $(CYGPATH_W) '$(srcdir)/CAnimation.cpp'; fi`
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vcmiclient-CAnimation.Tpo $(DEPDIR)/vcmiclient-CAnimation.Po
@am__fastdepCXX_FALSE@ $(AM_V_CXX) @AM_BACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='CAnimation.cpp' object='vcmiclient-CAnimation.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -c -o vcmiclient-CAnimation.obj `if test -f 'CAnimation.cpp'; then $(CYGPATH_W) 'CAnimation.cpp'; else $(CYGPATH_W) '$(srcdir)/CAnimation.cpp'; fi`
vcmiclient-CBattleInterface.o: CBattleInterface.cpp
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -MT vcmiclient-CBattleInterface.o -MD -MP -MF $(DEPDIR)/vcmiclient-CBattleInterface.Tpo -c -o vcmiclient-CBattleInterface.o `test -f 'CBattleInterface.cpp' || echo '$(srcdir)/'`CBattleInterface.cpp
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/vcmiclient-CBattleInterface.Tpo $(DEPDIR)/vcmiclient-CBattleInterface.Po

View File

@ -91,19 +91,23 @@ unsigned char * CLodHandler::giveFile(const std::string defName, LodFileType typ
if (ourEntry.offset<0) //file is in the sprites/ folder; no compression
{
int result;
unsigned char * outp = new unsigned char[ourEntry.realSize];
outp = new unsigned char[ourEntry.realSize];
FILE * f = fopen((myDir + "/" + ourEntry.realName).c_str(), "rb");
if (f) {
if (f)
{
result = fread(outp,1,ourEntry.realSize,f);
fclose(f);
} else
}
else
result = -1;
mutex->unlock();
if(result<0) {
if(result<0)
{
tlog1<<"Error in file reading: " << myDir << "/" << ourEntry.name << std::endl;
delete[] outp;
return NULL;
} else
}
else
return outp;
}
else if (ourEntry.size==0) //file is not compressed

View File

@ -4458,7 +4458,7 @@ void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward
{
CCreatureSet creatures;
creatures.setCreature (0, rID, rVal);
cb->giveCreatures (id, h, creatures);
cb->giveCreatures (id, h, creatures,false);
}
break;
default:
@ -5027,14 +5027,16 @@ void CGPandoraBox::giveContents( const CGHeroInstance *h, bool afterBattle ) con
iw.text.addReplacement (h->name);
cb->showInfoDialog(&iw);
cb->giveCreatures (id, h, ourArmy);
cb->giveCreatures (id, h, ourArmy, true);
//boost::bind(&CGPandoraBox::endBattle, this, h, _1)
}
if(!afterBattle && message.size())
{
iw.text << message;
cb->showInfoDialog(&iw);
}
cb->removeObject(id);
if (!creatures.Slots().size())
cb->removeObject(id); //only when we don't need to display garrison window
}
void CGPandoraBox::getText( InfoWindow &iw, bool &afterBattle, int text, const CGHeroInstance * h ) const
@ -5905,7 +5907,7 @@ void CBank::endBattle (const CGHeroInstance *h, const BattleResult *result) cons
iw.text.addReplacement (loot.buildList());
iw.text.addReplacement (h->name);
cb->showInfoDialog(&iw);
cb->giveCreatures (id, h, ourArmy);
cb->giveCreatures (id, h, ourArmy, false);
}
cb->setObjProperty (id, 15, 0); //bc = NULL
}
@ -6535,9 +6537,10 @@ void CArmedInstance::setArmy(const CCreatureSet &src)
}
}
CCreatureSet CArmedInstance::getArmy() const
{
return *this;
CCreatureSet& CArmedInstance::getArmy() const
{ //do not return itself by value, or it will xplode
// CCreatureSet set = *this; return set;
return *((CCreatureSet*)(this));
}
void CArmedInstance::randomizeArmy(int type)

View File

@ -223,7 +223,7 @@ public:
BattleInfo *battle; //set to the current battle, if engaged
void setArmy(const CCreatureSet &src);
CCreatureSet getArmy() const;
CCreatureSet& getArmy() const;
void randomizeArmy(int type);
//////////////////////////////////////////////////////////////////////////

View File

@ -4080,6 +4080,10 @@ std::map<ui32,CGHeroInstance *> CGameState::unusedHeroesFromPool()
return pool;
}
void CGameState::buildGameLogicTree()
{
}
const CStack * BattleInfo::getNextStack() const
{
std::vector<const CStack *> hlp;

View File

@ -423,6 +423,7 @@ public:
const TeamState *getTeam(ui8 teamID) const;
const TeamState *getPlayerTeam(ui8 color) const;
void init(StartInfo * si, ui32 checksum, int Seed);
void buildGameLogicTree();
void loadTownDInfos();
void randomizeObject(CGObjectInstance *cur);
std::pair<int,int> pickObject(CGObjectInstance *obj); //chooses type of object to be randomized, returns <type, subtype>

View File

@ -86,7 +86,7 @@ public:
virtual void showGarrisonDialog(int upobj, int hid, bool removableUnits, const boost::function<void()> &cb) =0; //cb will be called when player closes garrison window
virtual void showThievesGuildWindow(int requestingObjId) =0;
virtual void giveResource(int player, int which, int val)=0;
virtual void giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet creatures) =0;
virtual void giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet creatures, bool remove) =0;
virtual void takeCreatures (int objid, TSlots creatures) =0;
virtual void changeCreatureType (int objid, TSlot slot, TCreature creature) =0;
virtual void showCompInfo(ShowInInfobox * comp)=0;

View File

@ -2140,34 +2140,41 @@ void CGameHandler::giveResource(int player, int which, int val)
sr.val = gs->players.find(player)->second.resources[which]+val;
sendAndApply(&sr);
}
void CGameHandler::giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet creatures)
void CGameHandler::giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet creatures, bool remove)
{
if (creatures.stacksCount() <= 0)
return;
CCreatureSet heroArmy = h->getArmy();
while (creatures.stacksCount())
std::set<int> takenSlots;
for (TSlots::const_iterator it = creatures.Slots().begin(); it != creatures.Slots().end(); it++)
{
int slot = heroArmy.getSlotFor(creatures.Slots().begin()->second.type->idNumber);
if (slot < 0)
break;
heroArmy.addToSlot(slot, creatures.slots.begin()->second);
creatures.slots.erase (creatures.slots.begin());
int slot = heroArmy.getSlotFor(it->second.type->idNumber);
if (slot >= 0)
{
heroArmy.addToSlot(slot, it->second); //move all matching creatures to hero's army
takenSlots.insert(it->first); //slot id
}
}
for (std::set<int>::iterator it = takenSlots.begin(); it != takenSlots.end(); it++)
creatures.eraseStack(*it); //delete them from used army
if (creatures.stacksCount() == 0) //all creatures can be moved to hero army - do that
SetGarrisons sg;
sg.garrs[h->id] = heroArmy;
sg.garrs[objid] = creatures;
sendAndApply (&sg);
if (remove) //show garrison window and let player pick remaining creatures
{
SetGarrisons sg;
sg.garrs[h->id] = heroArmy;
sendAndApply(&sg);
if (creatures.stacksCount()) //Pandora needs to exist until we close garrison window
{
showGarrisonDialog (objid, h->id, true, boost::bind(&CGameHandler::removeObject, this, objid));
}
else
removeObject(objid);
}
else //show garrison window and let player pick creatures
{
SetGarrisons sg;
sg.garrs[objid] = creatures;
sendAndApply (&sg);
else if (creatures.stacksCount())
showGarrisonDialog (objid, h->id, true, 0);
return;
}
}
void CGameHandler::takeCreatures (int objid, TSlots creatures) //probably we could use ArmedInstance as well
{
@ -2662,8 +2669,8 @@ bool CGameHandler::arrangeStacks( si32 id1, si32 id2, ui8 what, ui8 p1, ui8 p2,
if(what==1) //swap
{
if ( (s1->tempOwner != player && S1.slots[p1].count)
|| (s2->tempOwner != player && S2.slots[p2].count))
if ( ((s1->tempOwner != player && s1->tempOwner != 254) && S1.slots[p1].count) //why 254??
|| ((s2->tempOwner != player && s2->tempOwner != 254) && S2.slots[p2].count))
{
complain("Can't take troops from another player!");
return false;
@ -2680,7 +2687,7 @@ bool CGameHandler::arrangeStacks( si32 id1, si32 id2, ui8 what, ui8 p1, ui8 p2,
else if(what==2)//merge
{
if (( S1.slots[p1].type != S2.slots[p2].type && complain("Cannot merge different creatures stacks!"))
|| (s1->tempOwner != player && S2.slots[p2].count) && complain("Can't take troops from another player!"))
|| ((s1->tempOwner != player && s1->tempOwner != 254) && S2.slots[p2].count) && complain("Can't take troops from another player!"))
return false;
S2.slots[p2].count += S1.slots[p1].count;

View File

@ -135,7 +135,7 @@ public:
void showGarrisonDialog(int upobj, int hid, bool removableUnits, const boost::function<void()> &cb);
void showThievesGuildWindow(int requestingObjId); //TODO: make something more general?
void giveResource(int player, int which, int val);
void giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet creatures);
void giveCreatures (int objid, const CGHeroInstance * h, CCreatureSet creatures, bool remove);
void takeCreatures (int objid, TSlots creatures);
void changeCreatureType (int objid, TSlot slot, TCreature creature);
void showCompInfo(ShowInInfobox * comp);