mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
Partially done support for external creature dwellings.
This commit is contained in:
parent
2f73b6cd1e
commit
b551f6a72b
@ -28,6 +28,7 @@ struct TryMoveHero;
|
||||
class CGHeroInstance;
|
||||
class CGTownInstance;
|
||||
class CGObjectInstance;
|
||||
class CGDwelling;
|
||||
class CCreatureSet;
|
||||
class CArmedInstance;
|
||||
struct BattleResult;
|
||||
@ -81,6 +82,7 @@ public:
|
||||
virtual void init(ICallback * CB){};
|
||||
virtual void receivedResource(int type, int val){};
|
||||
virtual void showInfoDialog(const std::string &text, const std::vector<Component*> &components, int soundID){};
|
||||
virtual void showRecruitmentDialog(const CGDwelling *dwelling, int level){}
|
||||
//virtual void showSelDialog(const std::string &text, const std::vector<Component*> &components, ui32 askID){};
|
||||
//virtual void showYesNoDialog(const std::string &text, const std::vector<Component*> &components, ui32 askID){};
|
||||
virtual void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, const int soundID, bool selection, bool cancel) = 0; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
|
||||
|
@ -932,15 +932,19 @@ void CCastleInterface::recreateBuildings()
|
||||
|
||||
CRecruitmentWindow * CCastleInterface::showRecruitmentWindow( int building )
|
||||
{
|
||||
if(building>36)
|
||||
if(building>36) //upg dwelling
|
||||
building-=7;
|
||||
|
||||
int level = building-30;
|
||||
assert(level >= 0 && level <= 6);
|
||||
|
||||
std::vector<std::pair<int,int > > crs;
|
||||
int amount = (const_cast<CGTownInstance*>(town))->strInfo.creatures[building-30]; //trzeba odconstowac, bo inaczej operator [] by sypal :(
|
||||
int amount = town->creatures[level].first;
|
||||
|
||||
if(town->builtBuildings.find(building+7) != town->builtBuildings.end()) //check if there is an upgraded building
|
||||
crs.push_back(std::make_pair(town->town->upgradedCreatures[building-30],amount));
|
||||
const std::vector<ui32> &cres = town->creatures[level].second;
|
||||
|
||||
crs.push_back(std::make_pair(town->town->basicCreatures[building-30],amount));
|
||||
for(size_t i = 0; i < cres.size(); i++)
|
||||
crs.push_back(std::make_pair((int)cres[i],amount));
|
||||
|
||||
CRecruitmentWindow *rw = new CRecruitmentWindow(crs,boost::bind(&CCallback::recruitCreatures,LOCPLINT->cb,town,_1,_2));
|
||||
LOCPLINT->pushInt(rw);
|
||||
@ -1436,7 +1440,7 @@ void CFortScreen::draw( CCastleInterface * owner, bool first)
|
||||
printAtMiddle(CGI->buildh->buildings[owner->town->subID][30+i+upgraded*7]->Name(),positions[i].x+79,positions[i].y+100,GEOR13,zwykly,bg); //dwelling name
|
||||
if(present) //if creature is present print avail able quantity
|
||||
{
|
||||
SDL_itoa(owner->town->strInfo.creatures.find(i)->second,buf,10);
|
||||
SDL_itoa(owner->town->creatures[i].first,buf,10);
|
||||
printAtMiddle(CGI->generaltexth->allTexts[217] + buf,positions[i].x+79,positions[i].y+118,GEOR13,zwykly,bg);
|
||||
}
|
||||
blitAt(icons,positions[i].x+261,positions[i].y+3,bg);
|
||||
|
@ -122,7 +122,7 @@ void init()
|
||||
tlog0<<"Screen handler: "<<pomtime.getDif()<<std::endl;
|
||||
pomtime.getDif();
|
||||
graphics = new Graphics();
|
||||
graphics->loadHeroAnim();
|
||||
graphics->loadHeroAnims();
|
||||
tlog0<<"\tMain graphics: "<<tmh.getDif()<<std::endl;
|
||||
tlog0<<"Initializing game graphics: "<<tmh.getDif()<<std::endl;
|
||||
|
||||
|
@ -1756,3 +1756,16 @@ const CGHeroInstance * CPlayerInterface::getWHero( int pos )
|
||||
return NULL;
|
||||
return wanderingHeroes[pos];
|
||||
}
|
||||
|
||||
void CPlayerInterface::showRecruitmentDialog(const CGDwelling *dwelling, int level)
|
||||
{
|
||||
std::vector<std::pair<int,int> > cres;
|
||||
for(int i = 0; i < dwelling->creatures.size(); i++)
|
||||
{
|
||||
if(i == level || level < 0)
|
||||
for(size_t j = 0; j < dwelling->creatures[i].second.size(); j++)
|
||||
cres.push_back( std::make_pair(dwelling->creatures[i].second[j],dwelling->creatures[i].first));
|
||||
}
|
||||
CRecruitmentWindow *cr = new CRecruitmentWindow(cres, boost::bind(&CCallback::recruitCreatures, cb, dwelling, _1, _2));
|
||||
pushInt(cr);
|
||||
}
|
@ -134,8 +134,7 @@ public:
|
||||
void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town);
|
||||
void receivedResource(int type, int val);
|
||||
void showInfoDialog(const std::string &text, const std::vector<Component*> &components, int soundID);
|
||||
//void showSelDialog(const std::string &text, const std::vector<Component*> &components, ui32 askID);
|
||||
//void showYesNoDialog(const std::string &text, const std::vector<Component*> &components, ui32 askID);
|
||||
void showRecruitmentDialog(const CGDwelling *dwelling, int level);
|
||||
void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, int soundID, bool selection, bool cancel); //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
|
||||
void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, boost::function<void()> &onEnd);
|
||||
void tileHidden(const std::set<int3> &pos); //called when given tiles become hidden under fog of war
|
||||
|
@ -305,49 +305,58 @@ void Graphics::loadHeroPortraits()
|
||||
}
|
||||
of.close();
|
||||
}
|
||||
void Graphics::loadHeroAnim()
|
||||
void Graphics::loadHeroAnims()
|
||||
{
|
||||
heroAnims.resize(F_NUMBER * 2);
|
||||
std::vector<std::pair<int,int> > rotations; //first - group number to be rotated1, second - group number after rotation1
|
||||
rotations += std::make_pair(6,10), std::make_pair(7,11), std::make_pair(8,12), std::make_pair(1,13),
|
||||
std::make_pair(2,14), std::make_pair(3,15);
|
||||
for(size_t i=0; i<heroAnims.size(); ++i)
|
||||
for(size_t i=0; i<F_NUMBER * 2; ++i)
|
||||
{
|
||||
std::ostringstream nm;
|
||||
nm << "AH" << std::setw(2) << std::setfill('0') << i << "_.DEF";
|
||||
loadHeroAnim(nm.str(), rotations, &Graphics::heroAnims);
|
||||
std::string name = nm.str();
|
||||
heroAnims[i] = CDefHandler::giveDefEss(name);
|
||||
int pom = 0; //how many groups has been rotated
|
||||
for(int o=7; pom<6; ++o)
|
||||
}
|
||||
|
||||
loadHeroAnim("AB01_.DEF", rotations, &Graphics::boatAnims);
|
||||
loadHeroAnim("AB02_.DEF", rotations, &Graphics::boatAnims);
|
||||
loadHeroAnim("AB03_.DEF", rotations, &Graphics::boatAnims);
|
||||
}
|
||||
|
||||
void Graphics::loadHeroAnim( const std::string &name, const std::vector<std::pair<int,int> > &rotations, std::vector<CDefEssential *> Graphics::*dst )
|
||||
{
|
||||
CDefEssential *anim = CDefHandler::giveDefEss(name);
|
||||
heroAnims.push_back(anim);
|
||||
int pom = 0; //how many groups has been rotated
|
||||
for(int o=7; pom<6; ++o)
|
||||
{
|
||||
for(int p=0;p<6;p++)
|
||||
{
|
||||
for(int p=0;p<6;p++)
|
||||
if(anim->ourImages[o].groupNumber == rotations[p].first)
|
||||
{
|
||||
if(heroAnims[i]->ourImages[o].groupNumber==rotations[p].first)
|
||||
for(int e=0; e<8; ++e)
|
||||
{
|
||||
for(int e=0; e<8; ++e)
|
||||
{
|
||||
Cimage nci;
|
||||
nci.bitmap = CSDL_Ext::rotate01(heroAnims[i]->ourImages[o+e].bitmap);
|
||||
nci.groupNumber = rotations[p].second;
|
||||
nci.imName = std::string();
|
||||
heroAnims[i]->ourImages.push_back(nci);
|
||||
if(pom>2) //we need only one frame for groups 13/14/15
|
||||
break;
|
||||
}
|
||||
if(pom<3) //there are eight frames of animtion of groups 6/7/8 so for speed we'll skip them
|
||||
o+=8;
|
||||
else //there is only one frame of 1/2/3
|
||||
o+=1;
|
||||
++pom;
|
||||
if(p==2 && pom<4) //group1 starts at index 1
|
||||
o = 1;
|
||||
Cimage nci;
|
||||
nci.bitmap = CSDL_Ext::rotate01(anim->ourImages[o+e].bitmap);
|
||||
nci.groupNumber = rotations[p].second;
|
||||
nci.imName = std::string();
|
||||
anim->ourImages.push_back(nci);
|
||||
if(pom>2) //we need only one frame for groups 13/14/15
|
||||
break;
|
||||
}
|
||||
if(pom<3) //there are eight frames of animtion of groups 6/7/8 so for speed we'll skip them
|
||||
o+=8;
|
||||
else //there is only one frame of 1/2/3
|
||||
o+=1;
|
||||
++pom;
|
||||
if(p==2 && pom<4) //group1 starts at index 1
|
||||
o = 1;
|
||||
}
|
||||
}
|
||||
for(size_t ff=0; ff<heroAnims[i]->ourImages.size(); ++ff)
|
||||
{
|
||||
CSDL_Ext::alphaTransform(heroAnims[i]->ourImages[ff].bitmap);
|
||||
}
|
||||
}
|
||||
for(size_t ff=0; ff<anim->ourImages.size(); ++ff)
|
||||
{
|
||||
CSDL_Ext::alphaTransform(anim->ourImages[ff].bitmap);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,7 @@ public:
|
||||
CDefEssential * smallIcons, *resources32; //resources 32x32
|
||||
CDefEssential * flags;
|
||||
std::vector<CDefEssential *> heroAnims; // [class id: 0 - 17] //added group 10: up - left, 11 - left and 12 - left down // 13 - up-left standing; 14 - left standing; 15 - left down standing
|
||||
std::vector<CDefEssential *> boatAnims; // [boat type: 0 - 3] //added group 10: up - left, 11 - left and 12 - left down // 13 - up-left standing; 14 - left standing; 15 - left down standing
|
||||
//creatures
|
||||
std::map<int,SDL_Surface*> smallImgs; //creature ID -> small 32x32 img of creature; //ID=-2 is for blank (black) img; -1 for the border
|
||||
std::map<int,SDL_Surface*> bigImgs; //creature ID -> big 58x64 img of creature; //ID=-2 is for blank (black) img; -1 for the border
|
||||
@ -69,7 +70,8 @@ public:
|
||||
void loadPaletteAndColors();
|
||||
void loadHeroFlags();
|
||||
void loadHeroFlags(std::pair<std::vector<CDefEssential *> Graphics::*, std::vector<const char *> > &pr, bool mode);
|
||||
void loadHeroAnim();
|
||||
void loadHeroAnims();
|
||||
void loadHeroAnim(const std::string &name, const std::vector<std::pair<int,int> > &rotations, std::vector<CDefEssential *> Graphics::*dst);
|
||||
void loadHeroPortraits();
|
||||
SDL_Surface * drawHeroInfoWin(const CGHeroInstance * curh);
|
||||
SDL_Surface * drawPrimarySkill(const CGHeroInstance *curh, SDL_Surface *ret, int from=0, int to=PRIMARY_SKILLS);
|
||||
|
@ -459,11 +459,27 @@ void ShowInInfobox::applyCl(CClient *cl)
|
||||
}
|
||||
}
|
||||
|
||||
void HeroExchange::applyFirstCl(CClient *cl)
|
||||
void OpenWindow::applyFirstCl(CClient *cl)
|
||||
{
|
||||
}
|
||||
|
||||
void HeroExchange::applyCl(CClient *cl)
|
||||
void OpenWindow::applyCl(CClient *cl)
|
||||
{
|
||||
cl->playerint[player]->heroExchangeStarted(hero1, hero2);
|
||||
switch(window)
|
||||
{
|
||||
case EXCHANGE_WINDOW:
|
||||
{
|
||||
const CGHeroInstance *h = cl->getHero(id1);
|
||||
const CGObjectInstance *h2 = cl->getHero(id2);
|
||||
assert(h && h2);
|
||||
INTERFACE_CALL_IF_PRESENT(h->tempOwner,heroExchangeStarted, id1, id2);
|
||||
}
|
||||
break;
|
||||
case RECRUITMENT_FIRST:
|
||||
{
|
||||
const CGDwelling *dw = dynamic_cast<const CGDwelling*>(cl->getObj(id1));
|
||||
INTERFACE_CALL_IF_PRESENT(dw->tempOwner,showRecruitmentDialog, dw, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -903,6 +903,77 @@ si32 CGHeroInstance::getArtPos(int aid) const
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CGDwelling::initObj()
|
||||
{
|
||||
switch(ID)
|
||||
{
|
||||
case 17:
|
||||
creatures.resize(1);
|
||||
creatures[0].second.push_back(VLC->objh->cregens[subID]);
|
||||
break;
|
||||
case 20:
|
||||
creatures.resize(4);
|
||||
if(subID == 1) // Elemental Conflux
|
||||
{
|
||||
creatures[0].second.push_back(32); //Stone Golem
|
||||
creatures[1].second.push_back(33); //Iron Golem
|
||||
creatures[2].second.push_back(116); //Gold Golem
|
||||
creatures[3].second.push_back(117); //Diamond Golem
|
||||
}
|
||||
else if(subID == 1) //Golem Factory
|
||||
{
|
||||
creatures[0].second.push_back(112); //Air Elemental
|
||||
creatures[1].second.push_back(113); //Earth Elemental
|
||||
creatures[2].second.push_back(114); //Fire Elemental
|
||||
creatures[3].second.push_back(115); //Water Elemental
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CGDwelling::onHeroVisit( const CGHeroInstance * h ) const
|
||||
{
|
||||
if(h->tempOwner != tempOwner)
|
||||
cb->setOwner(id, h->tempOwner);
|
||||
|
||||
OpenWindow ow;
|
||||
ow.id1 = id;
|
||||
ow.id2 = id;
|
||||
ow.window = OpenWindow::RECRUITMENT_FIRST;
|
||||
cb->sendAndApply(&ow);
|
||||
}
|
||||
|
||||
void CGDwelling::newTurn() const
|
||||
{
|
||||
if(cb->getDate(1) != 1) //not first day of week
|
||||
return;
|
||||
|
||||
|
||||
bool change = false;
|
||||
|
||||
SetAvailableCreatures sac;
|
||||
sac.creatures = creatures;
|
||||
sac.tid = id;
|
||||
for (size_t i = 0; i < creatures.size(); i++)
|
||||
{
|
||||
if(creatures[i].second.size())
|
||||
{
|
||||
sac.creatures[i].first += VLC->creh->creatures[creatures[i].second[0]].growth;
|
||||
change = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(change)
|
||||
cb->sendAndApply(&sac);
|
||||
}
|
||||
|
||||
int CGTownInstance::getSightRadious() const //returns sight distance
|
||||
{
|
||||
return 5;
|
||||
@ -1042,6 +1113,15 @@ void CGTownInstance::initObj()
|
||||
MetaString ms;
|
||||
ms << name << ", " << town->Name();
|
||||
hoverName = toString(ms);
|
||||
|
||||
creatures.resize(CREATURES_PER_TOWN);
|
||||
for (int i = 0; i < CREATURES_PER_TOWN; i++)
|
||||
{
|
||||
if(creatureDwelling(i,false))
|
||||
creatures[i].second.push_back(town->basicCreatures[i]);
|
||||
if(creatureDwelling(i,true))
|
||||
creatures[i].second.push_back(town->upgradedCreatures[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int3 CGTownInstance::getSightCenter() const
|
||||
@ -2144,17 +2224,6 @@ const std::string & CGWitchHut::getHoverText() const
|
||||
return hoverName;
|
||||
}
|
||||
|
||||
|
||||
void CGDwelling::onHeroVisit( const CGHeroInstance * h ) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CGDwelling::initObj()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CGBonusingObject::onHeroVisit( const CGHeroInstance * h ) const
|
||||
{
|
||||
bool visited = h->getBonus(HeroBonus::OBJECT,ID);
|
||||
|
@ -284,7 +284,22 @@ public:
|
||||
void onHeroVisit(const CGHeroInstance * h) const;
|
||||
};
|
||||
|
||||
class DLL_EXPORT CGTownInstance : public CArmedInstance
|
||||
class DLL_EXPORT CGDwelling : public CArmedInstance
|
||||
{
|
||||
public:
|
||||
std::vector<std::pair<ui32, std::vector<ui32> > > creatures; //creatures[level] -> <vector of alternative ids (base creature and upgrades, creatures amount>
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CArmedInstance&>(*this) & creatures;
|
||||
}
|
||||
|
||||
void initObj();
|
||||
void onHeroVisit(const CGHeroInstance * h) const;
|
||||
void newTurn() const;
|
||||
};
|
||||
|
||||
class DLL_EXPORT CGTownInstance : public CGDwelling
|
||||
{
|
||||
public:
|
||||
CTown * town;
|
||||
@ -298,15 +313,15 @@ public:
|
||||
std::vector<ui32> possibleSpells, obligatorySpells;
|
||||
std::vector<std::vector<ui32> > spells; //spells[level] -> vector of spells, first will be available in guild
|
||||
|
||||
struct StrInfo
|
||||
{
|
||||
std::map<si32,ui32> creatures; //level - available amount
|
||||
//struct StrInfo
|
||||
//{
|
||||
// std::map<si32,ui32> creatures; //level - available amount
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & creatures;
|
||||
}
|
||||
} strInfo;
|
||||
// template <typename Handler> void serialize(Handler &h, const int version)
|
||||
// {
|
||||
// h & creatures;
|
||||
// }
|
||||
//} strInfo;
|
||||
std::set<CCastleEvent> events;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -316,7 +331,7 @@ public:
|
||||
{
|
||||
h & static_cast<CArmedInstance&>(*this);
|
||||
h & name & builded & destroyed & identifier & alignment & forbiddenBuildings & builtBuildings
|
||||
& possibleSpells & obligatorySpells & spells & strInfo & events;
|
||||
& possibleSpells & obligatorySpells & spells & /*strInfo & */events;
|
||||
|
||||
ui8 standardType = (&VLC->townh->towns[subID] == town);
|
||||
h & standardType;
|
||||
@ -666,19 +681,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_EXPORT CGDwelling : public CGObjectInstance //teleports and subterranean gates
|
||||
{
|
||||
public:
|
||||
static std::map<int,std::map<int, std::vector<int> > > objs; //map[ID][subID] => vector of ids
|
||||
void onHeroVisit(const CGHeroInstance * h) const;
|
||||
void initObj();
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & static_cast<CGObjectInstance&>(*this);
|
||||
}
|
||||
};
|
||||
|
||||
class DLL_EXPORT CGBonusingObject : public CGObjectInstance //objects giving bonuses to luck/morale/movement
|
||||
{
|
||||
public:
|
||||
|
@ -1343,11 +1343,12 @@ int CGameState::battleGetBattlefieldType(int3 tile)
|
||||
else if(tile==int3() && !curB)
|
||||
return -1;
|
||||
|
||||
std::vector <CGObjectInstance*> & objs = map->objects;
|
||||
const std::vector <CGObjectInstance*> & objs = map->objects;
|
||||
for(int g=0; g<objs.size(); ++g)
|
||||
{
|
||||
if( objs[g]->pos.x - tile.x < 0 || objs[g]->pos.x - tile.x >= 8 || tile.y - objs[g]->pos.y + 5 < 0 || tile.y - objs[g]->pos.y + 5 >=6 ||
|
||||
!objs[g]->coveringAt(objs[g]->pos.x - tile.x, tile.y - objs[g]->pos.y + 5)
|
||||
if( !objs[g] || objs[g]->pos.x - tile.x < 0 || objs[g]->pos.x - tile.x >= 8
|
||||
|| tile.y - objs[g]->pos.y + 5 < 0 || tile.y - objs[g]->pos.y + 5 >=6
|
||||
|| !objs[g]->coveringAt(objs[g]->pos.x - tile.x, tile.y - objs[g]->pos.y + 5)
|
||||
) //look only for objects covering given tile
|
||||
continue;
|
||||
switch(objs[g]->ID)
|
||||
|
@ -409,7 +409,7 @@ struct SetAvailableCreatures : public CPackForClient //506
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
si32 tid;
|
||||
std::map<si32,ui32> creatures;
|
||||
std::vector<std::pair<ui32, std::vector<ui32> > > creatures;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
@ -480,19 +480,20 @@ struct GiveHero : public CPackForClient //516
|
||||
}
|
||||
};
|
||||
|
||||
struct HeroExchange : public CPackForClient //517
|
||||
struct OpenWindow : public CPackForClient //517
|
||||
{
|
||||
HeroExchange(){type = 517;};
|
||||
OpenWindow(){type = 517;};
|
||||
void applyFirstCl(CClient *cl);
|
||||
void applyCl(CClient *cl);
|
||||
DLL_EXPORT void applyGs(CGameState *gs);
|
||||
|
||||
si32 hero1, hero2; //heroes for exchange
|
||||
ui8 player;
|
||||
enum EWindow {EXCHANGE_WINDOW, RECRUITMENT_FIRST, RECRUITMENT_ALL};
|
||||
ui8 window;
|
||||
ui32 id1, id2;
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
h & hero1 & hero2 & player;
|
||||
h & window & id1 & id2;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -278,7 +278,7 @@ DLL_EXPORT void NewStructures::applyGs( CGameState *gs )
|
||||
|
||||
DLL_EXPORT void SetAvailableCreatures::applyGs( CGameState *gs )
|
||||
{
|
||||
gs->getTown(tid)->strInfo.creatures = creatures;
|
||||
gs->getTown(tid)->creatures = creatures;
|
||||
}
|
||||
|
||||
DLL_EXPORT void SetHeroesInTown::applyGs( CGameState *gs )
|
||||
@ -418,7 +418,7 @@ DLL_EXPORT void GiveHero::applyGs( CGameState *gs )
|
||||
h->inTownGarrison = false;
|
||||
}
|
||||
|
||||
DLL_EXPORT void HeroExchange::applyGs(CGameState *gs)
|
||||
DLL_EXPORT void OpenWindow::applyGs(CGameState *gs)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -93,7 +93,7 @@ void registerTypes2(Serializer &s)
|
||||
s.template registerType<SetStackEffect>();
|
||||
s.template registerType<StacksInjured>();
|
||||
s.template registerType<ShowInInfobox>();
|
||||
s.template registerType<HeroExchange>();
|
||||
s.template registerType<OpenWindow>();
|
||||
|
||||
s.template registerType<SaveGame>();
|
||||
s.template registerType<SetSelection>();
|
||||
|
12
lib/map.cpp
12
lib/map.cpp
@ -1672,6 +1672,12 @@ void Mapa::readObjects( unsigned char * bufor, int &i)
|
||||
break;
|
||||
}
|
||||
case 17: case 18: case 19: case 20: //dwellings
|
||||
{
|
||||
nobj = new CGDwelling();
|
||||
nobj->setOwner(bufor[i++]);
|
||||
i+=3;
|
||||
break;
|
||||
}
|
||||
case 42: //lighthouse
|
||||
case 87: //shipyard
|
||||
case 220://mine (?)
|
||||
@ -1759,7 +1765,7 @@ void Mapa::readObjects( unsigned char * bufor, int &i)
|
||||
}
|
||||
case 217:
|
||||
{
|
||||
nobj = new CGObjectInstance();
|
||||
nobj = new CGDwelling();
|
||||
CCreGenObjInfo * spec = new CCreGenObjInfo;
|
||||
spec->player = readNormalNr(bufor,i); i+=4;
|
||||
spec->identifier = readNormalNr(bufor,i); i+=4;
|
||||
@ -1779,7 +1785,7 @@ void Mapa::readObjects( unsigned char * bufor, int &i)
|
||||
}
|
||||
case 216:
|
||||
{
|
||||
nobj = new CGObjectInstance();
|
||||
nobj = new CGDwelling();
|
||||
CCreGen2ObjInfo * spec = new CCreGen2ObjInfo;
|
||||
spec->player = readNormalNr(bufor,i); i+=4;
|
||||
spec->identifier = readNormalNr(bufor,i); i+=4;
|
||||
@ -1801,7 +1807,7 @@ void Mapa::readObjects( unsigned char * bufor, int &i)
|
||||
}
|
||||
case 218:
|
||||
{
|
||||
nobj = new CGObjectInstance();
|
||||
nobj = new CGDwelling();
|
||||
CCreGen3ObjInfo * spec = new CCreGen3ObjInfo;
|
||||
spec->player = bufor[i]; ++i;
|
||||
i+=3;
|
||||
|
@ -773,63 +773,61 @@ void CMapHandler::terrainRect(int3 top_tile, unsigned char anim, std::vector< st
|
||||
SDL_Rect pp = objects[h].second;
|
||||
pp.h = sr.h;
|
||||
pp.w = sr.w;
|
||||
const CGHeroInstance * themp = (dynamic_cast<const CGHeroInstance*>(objects[h].first));
|
||||
|
||||
if(themp && themp->moveDir && !themp->isStanding && themp->ID!=62) //last condition - this is not prison
|
||||
const CGHeroInstance * themp = (objects[h].first->ID != HEROI_TYPE
|
||||
? NULL
|
||||
: static_cast<const CGHeroInstance*>(objects[h].first));
|
||||
|
||||
if(themp && themp->moveDir) //it's hero
|
||||
{
|
||||
int imgVal = 8;
|
||||
SDL_Surface * tb;
|
||||
|
||||
if(themp->type==NULL)
|
||||
continue;
|
||||
std::vector<Cimage> & iv = graphics->heroAnims[themp->type->heroType]->ourImages;
|
||||
|
||||
size_t gg;
|
||||
for(gg=0; gg<iv.size(); ++gg)
|
||||
if(!themp->isStanding) //hero is moving
|
||||
{
|
||||
if(iv[gg].groupNumber==getHeroFrameNum(themp->moveDir, !themp->isStanding))
|
||||
size_t gg;
|
||||
for(gg=0; gg<iv.size(); ++gg)
|
||||
{
|
||||
tb = iv[gg+heroAnim%imgVal].bitmap;
|
||||
break;
|
||||
if(iv[gg].groupNumber==getHeroFrameNum(themp->moveDir, !themp->isStanding))
|
||||
{
|
||||
tb = iv[gg+heroAnim%imgVal].bitmap;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CSDL_Ext::blit8bppAlphaTo24bpp(tb,&pp,extSurf,&sr);
|
||||
pp.y+=imgVal*2-32;
|
||||
sr.y-=16;
|
||||
SDL_BlitSurface(graphics->flags4[themp->getOwner()]->ourImages[gg+heroAnim%imgVal+35].bitmap, &pp, extSurf, &sr);
|
||||
}
|
||||
else //hero stands still
|
||||
{
|
||||
size_t gg;
|
||||
for(gg=0; gg < iv.size(); ++gg)
|
||||
{
|
||||
if(iv[gg].groupNumber==getHeroFrameNum(themp->moveDir, !themp->isStanding))
|
||||
{
|
||||
tb = iv[gg].bitmap;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CSDL_Ext::blit8bppAlphaTo24bpp(tb,&pp,extSurf,&sr);
|
||||
|
||||
if(themp->pos.x==top_tile.x+bx && themp->pos.y==top_tile.y+by)
|
||||
{
|
||||
SDL_Rect bufr = sr;
|
||||
bufr.x-=2*32;
|
||||
bufr.y-=1*32;
|
||||
bufr.h = 64;
|
||||
bufr.w = 96;
|
||||
if(bufr.x-extRect->x>-64)
|
||||
SDL_BlitSurface(graphics->flags4[themp->getOwner()]->ourImages[ getHeroFrameNum(themp->moveDir, !themp->isStanding) *8+(heroAnim/4)%imgVal].bitmap, NULL, extSurf, &bufr);
|
||||
}
|
||||
}
|
||||
CSDL_Ext::blit8bppAlphaTo24bpp(tb,&pp,extSurf,&sr);
|
||||
pp.y+=imgVal*2-32;
|
||||
sr.y-=16;
|
||||
SDL_BlitSurface(graphics->flags4[themp->getOwner()]->ourImages[gg+heroAnim%imgVal+35].bitmap, &pp, extSurf, &sr);
|
||||
}
|
||||
else if(themp && themp->moveDir && themp->isStanding && themp->ID!=62) //last condition - this is not prison)
|
||||
{
|
||||
int imgVal = 8;
|
||||
SDL_Surface * tb;
|
||||
|
||||
if(themp->type==NULL)
|
||||
continue;
|
||||
std::vector<Cimage> & iv = graphics->heroAnims[themp->type->heroType]->ourImages;
|
||||
|
||||
size_t gg;
|
||||
for(gg=0; gg < iv.size(); ++gg)
|
||||
{
|
||||
if(iv[gg].groupNumber==getHeroFrameNum(themp->moveDir, !themp->isStanding))
|
||||
{
|
||||
tb = iv[gg].bitmap;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CSDL_Ext::blit8bppAlphaTo24bpp(tb,&pp,extSurf,&sr);
|
||||
|
||||
if(themp->pos.x==top_tile.x+bx && themp->pos.y==top_tile.y+by)
|
||||
{
|
||||
SDL_Rect bufr = sr;
|
||||
bufr.x-=2*32;
|
||||
bufr.y-=1*32;
|
||||
bufr.h = 64;
|
||||
bufr.w = 96;
|
||||
if(bufr.x-extRect->x>-64)
|
||||
SDL_BlitSurface(graphics->flags4[themp->getOwner()]->ourImages[ getHeroFrameNum(themp->moveDir, !themp->isStanding) *8+(heroAnim/4)%imgVal].bitmap, NULL, extSurf, &bufr);
|
||||
}
|
||||
}
|
||||
else
|
||||
else //blit object
|
||||
{
|
||||
const CGObjectInstance *obj = objects[h].first;
|
||||
const std::vector<Cimage> &ourImages = obj->defInfo->handler->ourImages;
|
||||
|
@ -709,14 +709,14 @@ void CGameHandler::newTurn()
|
||||
{
|
||||
SetAvailableCreatures sac;
|
||||
sac.tid = (**j).id;
|
||||
sac.creatures = (**j).strInfo.creatures;
|
||||
sac.creatures = (**j).creatures;
|
||||
for(int k=0;k<CREATURES_PER_TOWN;k++) //creature growths
|
||||
{
|
||||
if((**j).creatureDwelling(k))//there is dwelling (k-level)
|
||||
{
|
||||
sac.creatures[k] += (**j).creatureGrowth(k);
|
||||
sac.creatures[k].first += (**j).creatureGrowth(k);
|
||||
if(!gs->getDate(0)) //first day of game: use only basic growths
|
||||
amin(sac.creatures[k], VLC->creh->creatures[(*j)->town->basicCreatures[k]].growth);
|
||||
amin(sac.creatures[k].first, VLC->creh->creatures[(*j)->town->basicCreatures[k]].growth);
|
||||
}
|
||||
}
|
||||
n.cres.push_back(sac);
|
||||
@ -1203,7 +1203,7 @@ bool CGameHandler::moveHero( si32 hid, int3 dst, ui8 instant, ui8 asker /*= 255*
|
||||
{
|
||||
if (obj->blockVisit)
|
||||
{
|
||||
obj->onHeroVisit(h);
|
||||
objectVisited(obj, h);
|
||||
}
|
||||
}
|
||||
tlog5 << "Blocking visit at " << hmpos << std::endl;
|
||||
@ -1224,7 +1224,7 @@ bool CGameHandler::moveHero( si32 hid, int3 dst, ui8 instant, ui8 asker /*= 255*
|
||||
//call objects if they are visited
|
||||
BOOST_FOREACH(CGObjectInstance *obj, t.visitableObjects)
|
||||
{
|
||||
obj->onHeroVisit(h);
|
||||
objectVisited(obj, h);
|
||||
}
|
||||
}
|
||||
tlog5 << "Movement end!\n";
|
||||
@ -1449,10 +1449,10 @@ void CGameHandler::heroExchange(si32 hero1, si32 hero2)
|
||||
|
||||
if(player1 == player2)
|
||||
{
|
||||
HeroExchange hex;
|
||||
hex.hero1 = hero1;
|
||||
hex.hero2 = hero2;
|
||||
hex.player = player1;
|
||||
OpenWindow hex;
|
||||
hex.window = OpenWindow::EXCHANGE_WINDOW;
|
||||
hex.id1 = hero1;
|
||||
hex.id2 = hero2;
|
||||
sendAndApply(&hex);
|
||||
}
|
||||
}
|
||||
@ -1679,8 +1679,8 @@ bool CGameHandler::buildStructure( si32 tid, si32 bid )
|
||||
{
|
||||
SetAvailableCreatures ssi;
|
||||
ssi.tid = tid;
|
||||
ssi.creatures = t->strInfo.creatures;
|
||||
ssi.creatures[bid-30] = VLC->creh->creatures[t->town->basicCreatures[bid-30]].growth;
|
||||
ssi.creatures = t->creatures;
|
||||
ssi.creatures[bid-30].first = VLC->creh->creatures[t->town->basicCreatures[bid-30]].growth;
|
||||
sendAndApply(&ssi);
|
||||
}
|
||||
|
||||
@ -1715,26 +1715,41 @@ void CGameHandler::sendMessageToAll( const std::string &message )
|
||||
|
||||
bool CGameHandler::recruitCreatures( si32 objid, ui32 crid, ui32 cram )
|
||||
{
|
||||
si32 ser = -1;
|
||||
CGTownInstance * t = static_cast<CGTownInstance*>(gs->map->objects[objid]);
|
||||
const CGDwelling *dw = static_cast<CGDwelling*>(gs->map->objects[objid]);
|
||||
const CArmedInstance *dst = NULL;
|
||||
|
||||
if(dw->ID == TOWNI_TYPE)
|
||||
dst = dw;
|
||||
else if(dw->ID == 17 || dw->ID == 20) //advmap dwelling
|
||||
dst = getHero(gs->getPlayer(dw->tempOwner)->currentSelection); //TODO: check if current hero is really visiting dwelling
|
||||
|
||||
assert(dw && dst);
|
||||
|
||||
//verify
|
||||
bool found = false;
|
||||
int level = -1;
|
||||
|
||||
|
||||
typedef std::pair<const int,int> Parka;
|
||||
for(std::map<si32,ui32>::iterator av = t->strInfo.creatures.begin(); av!=t->strInfo.creatures.end(); av++)
|
||||
for(level = 0; level < dw->creatures.size(); level++) //iterate through all levels
|
||||
{
|
||||
if( ( found = (crid == t->town->basicCreatures[av->first]) ) //creature is available among basic cretures
|
||||
|| (found = (crid == t->town->upgradedCreatures[av->first])) )//creature is available among upgraded cretures
|
||||
const std::pair<ui32, std::vector<ui32> > &cur = dw->creatures[level]; //current level info <amount, list of cr. ids>
|
||||
int i = 0;
|
||||
for(; i < cur.second.size(); i++) //look for crid among available creatures list on current level
|
||||
if(cur.second[i] == crid)
|
||||
break;
|
||||
|
||||
if(i < cur.second.size())
|
||||
{
|
||||
cram = std::min(cram,av->second); //reduce recruited amount up to available amount
|
||||
ser = av->first;
|
||||
found = true;
|
||||
cram = std::min(cram, cur.first); //reduce recruited amount up to available amount
|
||||
break;
|
||||
}
|
||||
}
|
||||
int slot = t->army.getSlotFor(crid);
|
||||
int slot = dst->army.getSlotFor(crid);
|
||||
|
||||
if(!found && complain("Cannot recruit: no such creatures!")
|
||||
|| cram > VLC->creh->creatures[crid].maxAmount(gs->getPlayer(t->tempOwner)->resources) && complain("Cannot recruit: lack of resources!")
|
||||
|| cram > VLC->creh->creatures[crid].maxAmount(gs->getPlayer(dst->tempOwner)->resources) && complain("Cannot recruit: lack of resources!")
|
||||
|| cram<=0 && complain("Cannot recruit: cram <= 0!")
|
||||
|| slot<0 && complain("Cannot recruit: no available slot!"))
|
||||
{
|
||||
@ -1743,24 +1758,24 @@ bool CGameHandler::recruitCreatures( si32 objid, ui32 crid, ui32 cram )
|
||||
|
||||
//recruit
|
||||
SetResources sr;
|
||||
sr.player = t->tempOwner;
|
||||
sr.player = dst->tempOwner;
|
||||
for(int i=0;i<RESOURCE_QUANTITY;i++)
|
||||
sr.res[i] = gs->getPlayer(t->tempOwner)->resources[i] - (VLC->creh->creatures[crid].cost[i] * cram);
|
||||
sr.res[i] = gs->getPlayer(dst->tempOwner)->resources[i] - (VLC->creh->creatures[crid].cost[i] * cram);
|
||||
|
||||
SetAvailableCreatures sac;
|
||||
sac.tid = objid;
|
||||
sac.creatures = t->strInfo.creatures;
|
||||
sac.creatures[ser] -= cram;
|
||||
sac.creatures = dw->creatures;
|
||||
sac.creatures[level].first -= cram;
|
||||
|
||||
SetGarrisons sg;
|
||||
sg.garrs[objid] = t->army;
|
||||
if(sg.garrs[objid].slots.find(slot) == sg.garrs[objid].slots.end()) //take a free slot
|
||||
sg.garrs[dst->id] = dst->army;
|
||||
if(sg.garrs[dst->id].slots.find(slot) == sg.garrs[dst->id].slots.end()) //take a free slot
|
||||
{
|
||||
sg.garrs[objid].slots[slot] = std::make_pair(crid,cram);
|
||||
sg.garrs[dst->id].slots[slot] = std::make_pair(crid,cram);
|
||||
}
|
||||
else //add creatures to a already existing stack
|
||||
{
|
||||
sg.garrs[objid].slots[slot].second += cram;
|
||||
sg.garrs[dst->id].slots[slot].second += cram;
|
||||
}
|
||||
sendAndApply(&sr);
|
||||
sendAndApply(&sac);
|
||||
@ -2667,3 +2682,8 @@ bool CGameHandler::isAllowedExchange( int id1, int id2 )
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void CGameHandler::objectVisited( const CGObjectInstance * obj, const CGHeroInstance * h )
|
||||
{
|
||||
obj->onHeroVisit(h);
|
||||
}
|
@ -156,6 +156,7 @@ public:
|
||||
void close();
|
||||
void handleTimeEvents();
|
||||
bool complain(const std::string &problem); //sends message to all clients, prints on the logs and return true
|
||||
void objectVisited( const CGObjectInstance * obj, const CGHeroInstance * h );
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user