1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-04-13 11:40:38 +02:00

* swapping artifacts (needs testing)

* various improvements and fixes for interface
* put changelog into ChangeLog
This commit is contained in:
Michał W. Urbańczyk 2008-08-20 19:02:48 +00:00
parent 22ade5efbe
commit 1c7e3718a7
18 changed files with 420 additions and 68 deletions

View File

@ -2,6 +2,7 @@
#include "CAdvmapInterface.h" #include "CAdvmapInterface.h"
#include "client/CBitmapHandler.h" #include "client/CBitmapHandler.h"
#include "CPlayerInterface.h" #include "CPlayerInterface.h"
#include "CCastleInterface.h"
#include "hch/CPreGameTextHandler.h" #include "hch/CPreGameTextHandler.h"
#include "hch/CGeneralTextHandler.h" #include "hch/CGeneralTextHandler.h"
#include "hch/CDefHandler.h" #include "hch/CDefHandler.h"
@ -1098,6 +1099,8 @@ void CAdvMapInt::handleRightClick(std::string text, tribool down, CIntObject * c
{ {
LOCPLINT->objsToBlit.erase(LOCPLINT->objsToBlit.begin()+(i)); LOCPLINT->objsToBlit.erase(LOCPLINT->objsToBlit.begin()+(i));
delete pom; delete pom;
if((LOCPLINT->curint == LOCPLINT->castleInt) && !LOCPLINT->castleInt->subInt)
LOCPLINT->castleInt->showAll(0,true);
} }
} }
} }

View File

@ -456,7 +456,7 @@ void CBattleInterface::stackKilled(int ID, int dmg, int killed, int IDby, bool b
} }
} }
creAnims[ID]->setType(5); //death creAnims[ID]->setType(5); //death
for(int i=0; i<creAnims[ID]->framesInGroup(5)-1; ++i) for(int i=0; i<creAnims[ID]->framesInGroup(5); ++i)
{ {
show(); show();
CSDL_Ext::update(); CSDL_Ext::update();

View File

@ -136,20 +136,24 @@ void CCallback::endTurn()
} }
UpgradeInfo CCallback::getUpgradeInfo(const CArmedInstance *obj, int stackPos) UpgradeInfo CCallback::getUpgradeInfo(const CArmedInstance *obj, int stackPos)
{ {
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
return gs->getUpgradeInfo(const_cast<CArmedInstance*>(obj),stackPos); return gs->getUpgradeInfo(const_cast<CArmedInstance*>(obj),stackPos);
} }
const StartInfo * CCallback::getStartInfo() const StartInfo * CCallback::getStartInfo()
{ {
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
return gs->scenarioOps; return gs->scenarioOps;
} }
int CCallback::howManyTowns() int CCallback::howManyTowns()
{ {
return gs->players[gs->currentPlayer].towns.size(); boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
return gs->players[player].towns.size();
} }
const CGTownInstance * CCallback::getTownInfo(int val, bool mode) //mode = 0 -> val = serial; mode = 1 -> val = ID const CGTownInstance * CCallback::getTownInfo(int val, bool mode) //mode = 0 -> val = serial; mode = 1 -> val = ID
{ {
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
if (!mode) if (!mode)
return gs->players[gs->currentPlayer].towns[val]; return gs->players[gs->currentPlayer].towns[val];
else else
@ -293,6 +297,7 @@ std::vector < const CGHeroInstance *> CCallback::getHeroesInfo(bool onlyOur)
bool CCallback::isVisible(int3 pos) bool CCallback::isVisible(int3 pos)
{ {
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
return isVisible(pos,player); return isVisible(pos,player);
} }
@ -312,6 +317,7 @@ int CCallback::getHeroSerial(const CGHeroInstance * hero)
} }
const CCreatureSet* CCallback::getGarrison(const CGObjectInstance *obj) const CCreatureSet* CCallback::getGarrison(const CGObjectInstance *obj)
{ {
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
if(!obj) if(!obj)
return NULL; return NULL;
if(obj->ID == 34) if(obj->ID == 34)
@ -325,7 +331,6 @@ int CCallback::swapCreatures(const CGObjectInstance *s1, const CGObjectInstance
{ {
if(s1->tempOwner != player || s2->tempOwner != player) if(s1->tempOwner != player || s2->tempOwner != player)
return -1; return -1;
*cl->serv << ui16(502) << ui8(1) << s1->id << ui8(p1) << s2->id << ui8(p2); *cl->serv << ui16(502) << ui8(1) << s1->id << ui8(p1) << s2->id << ui8(p2);
return 0; return 0;
} }
@ -362,31 +367,35 @@ int CCallback::getMySerial()
return gs->players[player].serial; return gs->players[player].serial;
} }
bool CCallback::swapArifacts(const CGHeroInstance * hero1, bool worn1, int pos1, const CGHeroInstance * hero2, bool worn2, int pos2) bool CCallback::swapArifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2)
{ {
if(!hero1 || !hero2) //incorrect data if(player!=hero1->tempOwner || player!=hero2->tempOwner)
return false; return false;
CGHeroInstance * Uhero1 = const_cast<CGHeroInstance *>(hero1); *cl->serv << ui16(509) << hero1->id << pos1 << hero2->id << pos2;
CGHeroInstance * Uhero2 = const_cast<CGHeroInstance *>(hero2);
if(worn1 && worn2)
{
std::swap(Uhero1->artifWorn[pos1], Uhero2->artifWorn[pos2]);
}
else if(worn1 && !worn2)
{
std::swap(Uhero1->artifWorn[pos1], Uhero2->artifacts[pos2]);
}
else if(!worn1 && worn2)
{
std::swap(Uhero1->artifacts[pos1], Uhero2->artifWorn[pos2]);
}
else
{
std::swap(Uhero1->artifacts[pos1], Uhero2->artifacts[pos2]);
}
return true; return true;
//if(!hero1 || !hero2) //incorrect data
// return false;
//CGHeroInstance * Uhero1 = const_cast<CGHeroInstance *>(hero1);
//CGHeroInstance * Uhero2 = const_cast<CGHeroInstance *>(hero2);
//if(worn1 && worn2)
//{
// std::swap(Uhero1->artifWorn[pos1], Uhero2->artifWorn[pos2]);
//}
//else if(worn1 && !worn2)
//{
// std::swap(Uhero1->artifWorn[pos1], Uhero2->artifacts[pos2]);
//}
//else if(!worn1 && worn2)
//{
// std::swap(Uhero1->artifacts[pos1], Uhero2->artifWorn[pos2]);
//}
//else
//{
// std::swap(Uhero1->artifacts[pos1], Uhero2->artifacts[pos2]);
//}
//
//return true;
} }
bool CCallback::buildBuilding(const CGTownInstance *town, si32 buildingID) bool CCallback::buildBuilding(const CGTownInstance *town, si32 buildingID)
@ -401,7 +410,6 @@ bool CCallback::buildBuilding(const CGTownInstance *town, si32 buildingID)
return false; //lack of resources return false; //lack of resources
*cl->serv << ui16(504) << town->id << buildingID; *cl->serv << ui16(504) << town->id << buildingID;
//TODO: check if we are allowed to build
return true; return true;
} }
@ -431,6 +439,7 @@ CStack* CCallback::battleGetStackByID(int ID)
CStack* CCallback::battleGetStackByPos(int pos) CStack* CCallback::battleGetStackByPos(int pos)
{ {
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
return battleGetStackByID(battleGetStack(pos)); return battleGetStackByID(battleGetStack(pos));
} }

View File

@ -34,7 +34,7 @@ public:
virtual int mergeStacks(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2)=0;//joins first stack tothe second (creatures must be same type) virtual int mergeStacks(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2)=0;//joins first stack tothe second (creatures must be same type)
virtual int splitStack(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2, int val)=0;//split creatures from the first stack virtual int splitStack(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2, int val)=0;//split creatures from the first stack
virtual bool dismissHero(const CGHeroInstance * hero)=0; //dismisses diven hero; true - successfuly, false - not successfuly virtual bool dismissHero(const CGHeroInstance * hero)=0; //dismisses diven hero; true - successfuly, false - not successfuly
virtual bool swapArifacts(const CGHeroInstance * hero1, bool worn1, int pos1, const CGHeroInstance * hero2, bool worn2, int pos2)=0; //swaps artifacts between two given heroes virtual bool swapArifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2)=0; //swaps artifacts between two given heroes
virtual void recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amount)=0; virtual void recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amount)=0;
virtual bool dismissCreature(const CArmedInstance *obj, int stackPos)=0; virtual bool dismissCreature(const CArmedInstance *obj, int stackPos)=0;
virtual bool upgradeCreature(const CArmedInstance *obj, int stackPos, int newID=-1)=0; //if newID==-1 then best possible upgrade will be made virtual bool upgradeCreature(const CArmedInstance *obj, int stackPos, int newID=-1)=0; //if newID==-1 then best possible upgrade will be made
@ -106,7 +106,7 @@ public:
int mergeStacks(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2); //first goes to the second int mergeStacks(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2); //first goes to the second
int splitStack(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2, int val); int splitStack(const CGObjectInstance *s1, const CGObjectInstance *s2, int p1, int p2, int val);
bool dismissHero(const CGHeroInstance * hero); bool dismissHero(const CGHeroInstance * hero);
bool swapArifacts(const CGHeroInstance * hero1, bool worn1, int pos1, const CGHeroInstance * hero2, bool worn2, int pos2); bool swapArifacts(const CGHeroInstance * hero1, ui16 pos1, const CGHeroInstance * hero2, ui16 pos2);
bool buildBuilding(const CGTownInstance *town, si32 buildingID); bool buildBuilding(const CGTownInstance *town, si32 buildingID);
void recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amount); void recruitCreatures(const CGObjectInstance *obj, ui32 ID, ui32 amount);
bool dismissCreature(const CArmedInstance *obj, int stackPos); bool dismissCreature(const CArmedInstance *obj, int stackPos);

View File

@ -334,6 +334,7 @@ public:
CCastleInterface::CCastleInterface(const CGTownInstance * Town, bool Activate) CCastleInterface::CCastleInterface(const CGTownInstance * Town, bool Activate)
:hslotup(241,387,0,Town->garrisonHero,this),hslotdown(241,483,1,Town->visitingHero,this) :hslotup(241,387,0,Town->garrisonHero,this),hslotdown(241,483,1,Town->visitingHero,this)
{ {
subInt = NULL;
hall = NULL; hall = NULL;
townInt = BitmapHandler::loadBitmap("TOWNSCRN.bmp"); townInt = BitmapHandler::loadBitmap("TOWNSCRN.bmp");
cityBg = BitmapHandler::loadBitmap(getBgName(Town->subID)); cityBg = BitmapHandler::loadBitmap(getBgName(Town->subID));
@ -623,6 +624,11 @@ void CCastleInterface::show(SDL_Surface * to)
} }
void CCastleInterface::activate() void CCastleInterface::activate()
{ {
if(subInt)
{
subInt->activate();
return;
}
showing = true; showing = true;
townlist->activate(); townlist->activate();
garr->activate(); garr->activate();
@ -637,6 +643,11 @@ void CCastleInterface::activate()
} }
void CCastleInterface::deactivate() void CCastleInterface::deactivate()
{ {
if(subInt)
{
subInt->deactivate();
return;
}
showing = false; showing = false;
townlist->deactivate(); townlist->deactivate();
garr->deactivate(); garr->deactivate();
@ -980,6 +991,7 @@ CHallInterface::~CHallInterface()
} }
void CHallInterface::close() void CHallInterface::close()
{ {
LOCPLINT->castleInt->subInt = NULL;
deactivate(); deactivate();
delete this; delete this;
LOCPLINT->castleInt->activate(); LOCPLINT->castleInt->activate();
@ -1392,6 +1404,7 @@ void CMageGuildScreen::close()
{ {
deactivate(); deactivate();
delete this; delete this;
LOCPLINT->castleInt->subInt = NULL;
LOCPLINT->castleInt->activate(); LOCPLINT->castleInt->activate();
LOCPLINT->castleInt->showAll(); LOCPLINT->castleInt->showAll();
} }
@ -1430,7 +1443,7 @@ void CMageGuildScreen::Scroll::clickRight (tribool down)
(LOCPLINT->playerID, (LOCPLINT->playerID,
spell->descriptions[0], spell->descriptions[0],
static_cast<CMageGuildScreen*>(LOCPLINT->castleInt->subInt)->scrolls->ourImages[spell->id].bitmap, static_cast<CMageGuildScreen*>(LOCPLINT->castleInt->subInt)->scrolls->ourImages[spell->id].bitmap,
spell->name); spell->name,30,30);
vinya->pos.x = screen->w/2 - vinya->bitmap->w/2; vinya->pos.x = screen->w/2 - vinya->bitmap->w/2;
vinya->pos.y = screen->h/2 - vinya->bitmap->h/2; vinya->pos.y = screen->h/2 - vinya->bitmap->h/2;
vinya->activate(); vinya->activate();

View File

@ -48,7 +48,6 @@ CGObjectInstance * createObject(int id, int subid, int3 pos, int owner)
nobj->defInfo->handler=NULL; nobj->defInfo->handler=NULL;
nobj->defInfo->blockMap[5] = 253; nobj->defInfo->blockMap[5] = 253;
nobj->defInfo->visitMap[5] = 2; nobj->defInfo->visitMap[5] = 2;
nobj->artifacts.resize(20);
nobj->artifWorn[16] = 3; nobj->artifWorn[16] = 3;
nobj->portrait = subid; nobj->portrait = subid;
nobj->primSkills.resize(4); nobj->primSkills.resize(4);
@ -463,6 +462,14 @@ void CGameState::applyNL(IPack * pack)
} }
break; break;
} }
case 509:
{
SetHeroArtifacts *sha = static_cast<SetHeroArtifacts*>(pack);
CGHeroInstance *h = getHero(sha->hid);
h->artifacts = sha->artifacts;
h->artifWorn = sha->artifWorn;
break;
}
case 1001://set object property case 1001://set object property
{ {
SetObjectProperty *p = static_cast<SetObjectProperty*>(pack); SetObjectProperty *p = static_cast<SetObjectProperty*>(pack);

View File

@ -458,8 +458,7 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero)
for(int g=0; g<artWorn.size(); ++g) for(int g=0; g<artWorn.size(); ++g)
{ {
artWorn[g]->myNumber = g; artWorn[g]->slotID = g;
artWorn[g]->backNumber = -1;
char * hll = new char[200]; char * hll = new char[200];
sprintf(hll, CGI->generaltexth->heroscrn[1].c_str(), (artWorn[g]->ourArt ? artWorn[g]->ourArt->name.c_str() : "")); sprintf(hll, CGI->generaltexth->heroscrn[1].c_str(), (artWorn[g]->ourArt ? artWorn[g]->ourArt->name.c_str() : ""));
artWorn[g]->hoverText = std::string(hll); artWorn[g]->hoverText = std::string(hll);
@ -477,7 +476,7 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero)
add->pos.y = 365; add->pos.y = 365;
add->pos.h = add->pos.w = 44; add->pos.h = add->pos.w = 44;
if(s<hero->artifacts.size() && hero->artifacts[s]) if(s<hero->artifacts.size() && hero->artifacts[s])
add->text = hero->getArt(s)->description; add->text = hero->getArt(19+s)->description;
else else
add->text = std::string(); add->text = std::string();
add->ourWindow = this; add->ourWindow = this;
@ -500,8 +499,7 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero)
add->neck = true; add->neck = true;
add->shoulders = true; add->shoulders = true;
add->head = true; add->head = true;
add->myNumber = -1; add->slotID = 19+s;
add->backNumber = s;
backpack.push_back(add); backpack.push_back(add);
} }
activeArtPlace = NULL; activeArtPlace = NULL;
@ -890,15 +888,7 @@ void CArtPlace::clickLeft(boost::logic::tribool down)
//chceck if swap is possible //chceck if swap is possible
if(this->fitsHere(ourWindow->activeArtPlace->ourArt) && ourWindow->activeArtPlace->fitsHere(this->ourArt)) if(this->fitsHere(ourWindow->activeArtPlace->ourArt) && ourWindow->activeArtPlace->fitsHere(this->ourArt))
{ {
//swap artifacts LOCPLINT->cb->swapArifacts(ourWindow->curHero,slotID,ourWindow->curHero,ourWindow->activeArtPlace->slotID);
LOCPLINT->cb->swapArifacts(
ourWindow->curHero,
this->myNumber>=0,
this->myNumber>=0 ? this->myNumber : (this->backNumber + ourWindow->backpackPos)%ourWindow->curHero->artifacts.size(),
ourWindow->curHero,
ourWindow->activeArtPlace->myNumber>=0,
ourWindow->activeArtPlace->myNumber>=0 ? ourWindow->activeArtPlace->myNumber : (ourWindow->activeArtPlace->backNumber + ourWindow->backpackPos)%ourWindow->curHero->artifacts.size());
const CArtifact * pmh = ourArt; const CArtifact * pmh = ourArt;
ourArt = ourWindow->activeArtPlace->ourArt; ourArt = ourWindow->activeArtPlace->ourArt;

View File

@ -64,8 +64,7 @@ public:
bool spellBook, warMachine1, warMachine2, warMachine3, warMachine4, bool spellBook, warMachine1, warMachine2, warMachine3, warMachine4,
misc1, misc2, misc3, misc4, misc5, feet, lRing, rRing, torso, misc1, misc2, misc3, misc4, misc5, feet, lRing, rRing, torso,
lHand, rHand, neck, shoulders, head; //my types lHand, rHand, neck, shoulders, head; //my types
int myNumber; ui16 slotID; //0 head 1 shoulders 2 neck 3 right hand 4 left hand 5 torso 6 right ring 7 left ring 8 feet 9 misc. slot 1 10 misc. slot 2 11 misc. slot 3 12 misc. slot 4 13 ballista (war machine 1) 14 ammo cart (war machine 2) 15 first aid tent (war machine 3) 16 catapult 17 spell book 18 misc. slot 5 19+ backpack slots
int backNumber; //number of artifact if this is backpack artplace
bool clicked; bool clicked;
CHeroWindow * ourWindow; CHeroWindow * ourWindow;

View File

@ -222,6 +222,8 @@ std::pair<int,int> CMessage::getMaxSizes(std::vector<std::vector<SDL_Surface*> >
lw+=(*txtg)[i][j]->w; lw+=(*txtg)[i][j]->w;
ret.second+=(*txtg)[i][j]->h; ret.second+=(*txtg)[i][j]->h;
} }
if(!(*txtg)[i].size())
ret.second+=19;
if (ret.first<lw) if (ret.first<lw)
ret.first=lw; ret.first=lw;
} }
@ -381,7 +383,7 @@ std::vector< std::vector<SComponent*> > * CMessage::breakComps(std::vector<SComp
return ret; return ret;
} }
SDL_Surface * CMessage::drawBoxTextBitmapSub(int player, std::string text, SDL_Surface* bitmap, std::string sub, int charperline) SDL_Surface * CMessage::drawBoxTextBitmapSub( int player, std::string text, SDL_Surface* bitmap, std::string sub, int charperline/*=30*/, int imgToBmp/*=55*/ )
{ {
int curh; int curh;
std::vector<std::string> * tekst = breakText(text,charperline); std::vector<std::string> * tekst = breakText(text,charperline);
@ -392,17 +394,19 @@ SDL_Surface * CMessage::drawBoxTextBitmapSub(int player, std::string text, SDL_S
boxs.second = boxs.second =
(curh=45) //top margin (curh=45) //top margin
+ txts.second //text total height + txts.second //text total height
+ 55 //text <=> img + imgToBmp //text <=> img
+ bitmap->h + bitmap->h
+ 5 // to sibtitle + 5 // to sibtitle
+ (*txtg)[0][0]->h + (*txtg)[0][0]->h
+ 30; + 30;
SDL_Surface *ret = drawBox1(boxs.first,boxs.second,player); SDL_Surface *ret = drawBox1(boxs.first,boxs.second,player);
blitTextOnSur(txtg,curh,ret); blitTextOnSur(txtg,curh,ret);
curh += 55; curh += imgToBmp;
blitAt(bitmap,(ret->w/2)-(bitmap->w/2),curh,ret); blitAt(bitmap,(ret->w/2)-(bitmap->w/2),curh,ret);
curh += bitmap->h + 5; curh += bitmap->h + 5;
CSDL_Ext::printAtMiddle(sub,ret->w/2,curh+( ((*txtg)[0][0]->h) / 2 ),GEOR13,zwykly,ret); CSDL_Ext::printAtMiddle(sub,ret->w/2,curh+( ((*txtg)[0][0]->h) / 2 ),GEOR13,zwykly,ret);
delete tekst;
delete txtg;
return ret; return ret;
} }

View File

@ -39,7 +39,7 @@ public:
static SDL_Surface * genMessage(std::string title, std::string text, EWindowType type=infoOnly, static SDL_Surface * genMessage(std::string title, std::string text, EWindowType type=infoOnly,
std::vector<CDefHandler*> *addPics=NULL, void * cb=NULL); std::vector<CDefHandler*> *addPics=NULL, void * cb=NULL);
static SDL_Surface * drawBox1(int w, int h, int playerColor=1); static SDL_Surface * drawBox1(int w, int h, int playerColor=1);
static SDL_Surface * drawBoxTextBitmapSub(int player, std::string text, SDL_Surface* bitmap, std::string sub, int charperline=30); static SDL_Surface * drawBoxTextBitmapSub(int player, std::string text, SDL_Surface* bitmap, std::string sub, int charperline=30, int imgToBmp=55);
static std::vector<std::string> * breakText(std::string text, int line=30, bool userBreak=true, bool ifor=true); //line - chars per line static std::vector<std::string> * breakText(std::string text, int line=30, bool userBreak=true, bool ifor=true); //line - chars per line
CMessage(); CMessage();
static void init(); static void init();

View File

@ -575,7 +575,7 @@ void CInfoPopup::close()
delete this; delete this;
if(LOCPLINT->curint == LOCPLINT->adventureInt) if(LOCPLINT->curint == LOCPLINT->adventureInt)
LOCPLINT->adventureInt->show(); LOCPLINT->adventureInt->show();
else if(LOCPLINT->curint == LOCPLINT->castleInt) else if((LOCPLINT->curint == LOCPLINT->castleInt) && !LOCPLINT->castleInt->subInt)
LOCPLINT->castleInt->showAll(); LOCPLINT->castleInt->showAll();
} }
void CInfoPopup::show(SDL_Surface * to) void CInfoPopup::show(SDL_Surface * to)
@ -3167,25 +3167,38 @@ CCreInfoWindow::CCreInfoWindow(int Cid, int Type, int creatureCount, StackState
{ {
if(Upg && ui) if(Upg && ui)
{ {
bool enough = true;
for(std::set<std::pair<int,int> >::iterator i=ui->cost[0].begin(); i!=ui->cost[0].end(); i++) //calculate upgrade cost for(std::set<std::pair<int,int> >::iterator i=ui->cost[0].begin(); i!=ui->cost[0].end(); i++) //calculate upgrade cost
{ {
if(LOCPLINT->cb->getResourceAmount(i->first) < i->second*creatureCount)
enough = false;
upgResCost.push_back(new SComponent(SComponent::resource,i->first,i->second*creatureCount)); upgResCost.push_back(new SComponent(SComponent::resource,i->first,i->second*creatureCount));
} }
CFunctionList<void()> fs[2]; if(enough)
fs[0] += Upg;
fs[0] += boost::bind(&CCreInfoWindow::close,this);
CCastleInterface *pom;
if(pom=dynamic_cast<CCastleInterface*>(LOCPLINT->curint)) //if town screen is opened it needs to be redrawn
{ {
fs[1] += boost::bind(&CCastleInterface::showAll,pom,screen,true); CFunctionList<void()> fs[2];
fs[0] += Upg;
fs[0] += boost::bind(&CCreInfoWindow::close,this);
CCastleInterface *pom;
if(pom=dynamic_cast<CCastleInterface*>(LOCPLINT->curint)) //if town screen is opened it needs to be redrawn
{
fs[1] += boost::bind(&CCastleInterface::showAll,pom,screen,true);
}
fs[1] += boost::bind(&CCreInfoWindow::activate,this);
CFunctionList<void()> cfl;
cfl = boost::bind(&CCreInfoWindow::deactivate,this);
cfl += boost::bind(&CPlayerInterface::showYesNoDialog,LOCPLINT,CGI->generaltexth->allTexts[207],boost::ref(upgResCost),fs[0],fs[1],false,false);
upgrade = new AdventureMapButton("",CGI->preth->zelp[446].second,cfl,pos.x+76,pos.y+237,"IVIEWCR.DEF");
} }
fs[1] += boost::bind(&CCreInfoWindow::activate,this); else
CFunctionList<void()> cfl; {
cfl = boost::bind(&CCreInfoWindow::deactivate,this); upgrade = new AdventureMapButton("",CGI->preth->zelp[446].second,boost::function<void()>(),pos.x+76,pos.y+237,"IVIEWCR.DEF");
cfl += boost::bind(&CPlayerInterface::showYesNoDialog,LOCPLINT,CGI->generaltexth->allTexts[207],boost::ref(upgResCost),fs[0],fs[1],false,false); upgrade->callback.funcs.clear();
upgrade = new AdventureMapButton("",CGI->preth->zelp[446].second,cfl,pos.x+76,pos.y+237,"IVIEWCR.DEF"); upgrade->bitmapOffset = 2;
}
} }
if(Dsm) if(Dsm)
{ {

196
ChangeLog
View File

@ -0,0 +1,196 @@
0.61 -> 0.62
General:
* threading and minor changes.
* support for heroes starting in town garrisons
* upgrading creatures
* working gaining levels for heroes (including dialog with skill selection)
* added fast graphical cursor
* showing creature amount in the CCreInfoWindow
Castles:
* icon in infobox showing that there is hero in town garrison
* fort/citadel/castle screen
* taking last stack from the heroes army should be impossible (or at least harder)
* fixed reading forbidden structures
* randomizing spells in towns
* viewing hero window in the town screen
* possibility of moving hero into the garrison
* partially done mage guild screen
Adventure Interface:
* hopefully fixed problems with wrong town defs (village/fort/capitol)
Hero Window:
* bugfix: splitting stacks works in hero window
* removed bug causing significant increase of CPU consumption
Battles:
* shooting
* removed some displaying problems
* showing last group of frames in creature animation won't crash
* added start moving and end moving animations
* fixed moving two-hex creatures
* showing/hiding graphic cursor
* a part of using graphic cursor
* slightly optimized showing of battle interface
* animation of getting hit / death by shooting is displayed when it should be
* improved pathfinding in battles, removed problems with displaying movement, adventure map interface won't be called during battles.
PreGame:
* updates settings when selecting new map after changing sorting criteria
* if sorting not by name, name will be used as a secondary criteria
* when filter is applied a first available map is selected automatically
* slider position updated after sorting in pregame
0.6 -> 0.61 (Jun 15 2008)
Improvements:
* improved attacking in the battles
* it's possible to kill hostile stack
* animations won't go in the same phase
* Better pathfinder
* "%s" substitutions in Right-click information in town hall
* windmill won't give wood
* hover text for heroes
* support for ZSoft-style PCX files in /Data
* Splitting: when moving slider to the right so that 0 is left in old slot the army is moved
* in the townlist in castle selected town will by placed on the 2nd place (not 3rd)
* stack at the limit of unit's range can now be attacked
* range of unit is now properly displayed
* battle log is scrolled down when new event occurs
* console is closed when application exits
Bugfixes:
* stack at the limit of unit's range can now be attacked
* good background for the town hall screen in Stronghold
* fixed typo in hall.txt
* VCMI won't crash when r-click neutral stack during the battle
* water won't blink behind shipyard in the Castle
* fixed several memory leaks
* properly displaying two-hex creatures in recruit/split/info window
* corrupted map file won't cause crash on initializing main menu
0.59 -> 0.6 (Jun 1 2008)
* partially done attacking in battles
* screen isn't now refreshed while blitting creature info window
* r-click creature info windows in battles
* no more divison by 0 in slider
* "plural" reference names for Conflux creatures (starting armies of Conflux heroes should now be working)
* fixed estate problems
* fixed blinking mana vortex
* grail increases creature growths
* new pathfinder
* several minor improvements
0.58 -> 0.59 (May 24 2008 - closed, test release)
* fixed memory leak in battles
* blitting creature animations to rects in the recruitment window
* fixed wrong creatures def names
* better battle pathfinder and unit reversing
* improved slider ( #58 )
* fixed problems with horde buildings (won't block original dwellings)
* giving primary skill when hero get level (but there is still no dialog)
* if an upgraded creature is available it'll be shown as the first in a recruitment window
* creature levels not messed in Fortress
* war machines are added to the hero's inventory, not to the garrison
* support for H3-style PCX graphics in Data/
* VCMI won't crash when is unable to initialize audio system
* fixed displaying wrong town defs
* improvements in recruitment window (slider won't allow to select more creatures than we can afford)
* creature info window (only r-click)
* callback for buttons/lists based on boost::function
* a lot of minor improvements
0.55 -> 0.58 (Apr 20 2008 - closed, test release)
Towns:
* recruiting creatures
* working creature growths (including castle and horde building influences)
* towns give income
* town hall screen
* building buildings (requirements and cost are handled)
* hints for structures
* updating town infobox
Garrisons:
* merging stacks
* splitting stacks
Battles:
* starting battles
* displaying terrain, animations of heroes, units, grid, range of units, battle menu with console, amounts of units in stacks
* leaving battle by pressing flee button
* moving units in battles and displaying thier ranges
* defend command for units
General:
* a number of minor fixes and improvements
0.54 -> 0.55 (Feb 29 2008)
* Sprites/ folder works for h3sprite.lod same as Data/ for h3bitmap.lod (but it's still experimental)
* randomization quantity of creatures on the map
* fix of Pandora's Box handling
* reading disposed/predefined heroes
* new command - "get txt" - VCMI will extract all .txt files from h3bitmap.lod to the Extracted_txts/ folder.
* more detailed logs
* reported problems with hero flags resolved
* heroes cannot occupy the same tile
* hints for most of creature generators
* some minor stuff
0.53b -> 0.54 (Feb 23 2008 - first public release)
* given hero is placed in the town entrance
* some objects such as river delta won't be blitted "on" hero
* tiles under FoW are inaccessible
* giving random hero on RoE maps
* improved protection against hero duplication
* fixed starting values of primary abilities of random heroes on RoE/AB maps
* right click popups with infoboxes for heroes/towns lists
* new interface coloring (many thanks to GrayFace ;])
* fixed bug in object flag's coloring
* added hints in town lists
* eliminated square from city hints
0.53 - 0.53b (Feb 20 2008)
* added giving default buildings in towns
* town infobox won't crash on empty town
0.52 - 0.53 (Feb 18 2008):
* hopefully the last bugfix of Pandora's Box
* fixed blockmaps of generated heroes
* disposed hero cannot be chosen in scenario settings (unless he is in prison)
* fixed town randomization
* fixed hero randomization
* fixed displaying heroes in preGame
* fixed selecting/deselecting artifact slots in hero window
* much faster pathfinder
* memory usage and load time significantly decreased
* it's impossible to select empty artifact slot in hero window
* fixed problem with FoW displaying on minimap on L-sized maps
* fixed crashbug in hero list connected with heroes dismissing
* mostly done town infobox
* town daily income is properly calculated
0.51 - 0.52 (Feb 7 2008):
* [feature] giving starting hero
* [feature] VCMI will try to use files from /Data folder instead of those from h3bitmap.lod
* [feature] picked artifacts are added to hero's backpack
* [feature] possibility of choosing player to play
* [bugfix] ZELP.TXT file *should* be handled correctly even it is non-english
* [bugfix] fixed crashbug in reading defs with negativ left/right margins
* [bugfix] improved randomization
* [bugfix] pathfinder can't be cheated (what caused errors)
0.5 - 0.51 (Feb 3 2008):
* close button properly closes (same does 'q' key)
* two players can't have selected same hero
* double click on "Show Available Scenarios" won't reset options
* fixed possible crashbug in town/hero lists
* fixed crashbug in initializing game caused by wrong prisons handling
* fixed crashbug on reading hero's custom artifacts in RoE maps
* fixed crashbug on reading custom Pandora's Box in RoE maps
* fixed crashbug on reading blank Quest Guards
* better console messages
* map reading speed up (though it's still slow, especially on bigger maps)
to 0.5 (Feb 2 2008 - first closed release):
* Main menu and New game screens
* Scenario selection, part of advanced options support
* Partially done adventure map, town and hero interfaces
* Moving hero
* Interactions with several objects (mines, resources, mills, and others)

View File

@ -360,6 +360,15 @@ void CClient::process(int what)
playerint[t->tempOwner]->heroInGarrisonChange(t); playerint[t->tempOwner]->heroInGarrisonChange(t);
break; break;
} }
case 509:
{
SetHeroArtifacts sha;
*serv >> sha;
std::cout << "Setting artifacts of hero " << sha.hid << std::endl;
gs->apply(&sha);
//TODO: inform interfaces
break;
}
case 1001: case 1001:
{ {
SetObjectProperty sop; SetObjectProperty sop;

9
config/mageBg.txt Normal file
View File

@ -0,0 +1,9 @@
TPMAGECS.bmp
TPMAGERM.bmp
TPMAGETW.bmp
TPMAGEIN.bmp
TPMAGENC.bmp
TPMAGEDN.bmp
TPMAGEST.bmp
TPMAGEFR.bmp
TPMAGEEL.bmp

View File

@ -237,11 +237,45 @@ int CGHeroInstance::getSecSkillLevel(const int & ID) const
return secSkills[i].second; return secSkills[i].second;
return -1; return -1;
} }
ui32 CGHeroInstance::getArtAtPos(ui16 pos) const
{
if(pos<19)
if(vstd::contains(artifWorn,pos))
return artifWorn.find(pos)->second;
else
return -1;
else
if(pos-19 < artifacts.size())
return artifacts[pos-19];
else
return -1;
}
void CGHeroInstance::setArtAtPos(ui16 pos, int art)
{
if(art<0)
{
if(pos<19)
artifWorn.erase(pos);
else
artifacts -= artifacts[pos];
}
else
{
if(pos<19)
artifWorn[pos] = art;
else
if(pos-19 < artifacts.size())
artifacts[pos-19] = art;
else
artifacts.push_back(art);
}
}
const CArtifact * CGHeroInstance::getArt(int pos) const CArtifact * CGHeroInstance::getArt(int pos)
{ {
if(artifWorn.find(pos)!=artifWorn.end()) int id = getArtAtPos(pos);
return &VLC->arth->artifacts[artifWorn[pos]]; if(id>=0)
else return &VLC->arth->artifacts[id];
else
return NULL; return NULL;
} }

View File

@ -107,8 +107,8 @@ public:
bool inTownGarrison; // if hero is in town garrison bool inTownGarrison; // if hero is in town garrison
CGTownInstance * visitedTown; //set if hero is visiting town or in the town garrison CGTownInstance * visitedTown; //set if hero is visiting town or in the town garrison
std::vector<int> artifacts; //hero's artifacts from bag std::vector<ui32> artifacts; //hero's artifacts from bag
std::map<int,int> artifWorn; //map<position,artifact_id>; positions: 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5 std::map<ui16,ui32> artifWorn; //map<position,artifact_id>; positions: 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5
std::set<int> spells; //known spells (spell IDs) std::set<int> spells; //known spells (spell IDs)
virtual bool isHero() const; virtual bool isHero() const;
@ -125,6 +125,8 @@ public:
int getCurrentLuck() const; int getCurrentLuck() const;
int getCurrentMorale() const; int getCurrentMorale() const;
int getSecSkillLevel(const int & ID) const; //-1 - no skill int getSecSkillLevel(const int & ID) const; //-1 - no skill
ui32 getArtAtPos(ui16 pos) const; //-1 - no artifact
void setArtAtPos(ui16 pos, int art);
const CArtifact * getArt(int pos); const CArtifact * getArt(int pos);
CGHeroInstance(); CGHeroInstance();
virtual ~CGHeroInstance(); virtual ~CGHeroInstance();

View File

@ -164,6 +164,18 @@ struct SetHeroesInTown : public CPack<SetHeroesInTown> //508
h & tid & visiting & garrison; h & tid & visiting & garrison;
} }
}; };
struct SetHeroArtifacts : public CPack<SetHeroArtifacts> //509
{
SetHeroArtifacts(){type = 509;};
si32 hid;
std::vector<ui32> artifacts; //hero's artifacts from bag
std::map<ui16,ui32> artifWorn; //map<position,artifact_id>; positions: 0 - head; 1 - shoulders; 2 - neck; 3 - right hand; 4 - left hand; 5 - torso; 6 - right ring; 7 - left ring; 8 - feet; 9 - misc1; 10 - misc2; 11 - misc3; 12 - misc4; 13 - mach1; 14 - mach2; 15 - mach3; 16 - mach4; 17 - spellbook; 18 - misc5
template <typename Handler> void serialize(Handler &h, const int version)
{
h & hid & artifacts & artifWorn;
}
};
struct NewTurn : public CPack<NewTurn> //101 struct NewTurn : public CPack<NewTurn> //101
{ {
struct Hero struct Hero

View File

@ -501,6 +501,11 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
if(!S1->slots[p1].second) //if we've moved all creatures if(!S1->slots[p1].second) //if we've moved all creatures
S1->slots.erase(p1); S1->slots.erase(p1);
} }
if((s1->ID==34 && !S1->slots.size()) //it's not allowed to take last stack from hero army!
|| (s2->ID==34 && !S2->slots.size()))
{
break;
}
SetGarrisons sg; SetGarrisons sg;
sg.garrs[id1] = *S1; sg.garrs[id1] = *S1;
if(s1 != s2) if(s1 != s2)
@ -732,6 +737,53 @@ upgend:
} }
break; break;
} }
case 509:
{
si32 hid1, hid2;
ui16 slot1, slot2;
c >> hid1 >> slot1 >> hid2 >> slot2;
CGHeroInstance *h1 = gs->getHero(hid1), *h2 = gs->getHero(hid2);
if((distance(h1->pos,h2->pos) > 1.0) || (h1->tempOwner != h2->tempOwner))
break;
int a1=h1->getArtAtPos(slot1), a2=h2->getArtAtPos(slot2);
h2->setArtAtPos(slot2,a1);
h1->setArtAtPos(slot1,a2);
// if(std::max(slot1,slot2) < 19)
// {
// if(vstd::contains(h1->artifWorn,slot1) && vstd::contains(h1->artifWorn,slot2))
// std::swap(h1->artifWorn[slot1],h2->artifWorn[slot2]);
// if(vstd::contains(h1->artifWorn,slot1))
// {
// h2->artifWorn[slot2] = h1->artifWorn[slot1];
// h1->artifWorn.erase(slot1);
// }
// else if(vstd::contains(h2->artifWorn,slot2))
// {
// h1->artifWorn[slot1] = h2->artifWorn[slot2];
// h2->artifWorn.erase(slot2);
// }
// else
// {
// std::cout << "Warning, wrong artifact swap command!" << std::endl;
// }
// }
// else
// {
// }
SetHeroArtifacts sha;
sha.hid = hid1;
sha.artifacts = h1->artifacts;
sha.artifWorn = h1->artifWorn;
sendAndApply(&sha);
if(hid1 != hid2)
{
sha.hid = hid2;
sha.artifacts = h2->artifacts;
sha.artifWorn = h2->artifWorn;
sendAndApply(&sha);
}
}
case 2001: case 2001:
{ {
ui32 qid, answer; ui32 qid, answer;