1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +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 "client/CBitmapHandler.h"
#include "CPlayerInterface.h"
#include "CCastleInterface.h"
#include "hch/CPreGameTextHandler.h"
#include "hch/CGeneralTextHandler.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));
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
for(int i=0; i<creAnims[ID]->framesInGroup(5)-1; ++i)
for(int i=0; i<creAnims[ID]->framesInGroup(5); ++i)
{
show();
CSDL_Ext::update();

View File

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

View File

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

View File

@ -48,7 +48,6 @@ CGObjectInstance * createObject(int id, int subid, int3 pos, int owner)
nobj->defInfo->handler=NULL;
nobj->defInfo->blockMap[5] = 253;
nobj->defInfo->visitMap[5] = 2;
nobj->artifacts.resize(20);
nobj->artifWorn[16] = 3;
nobj->portrait = subid;
nobj->primSkills.resize(4);
@ -463,6 +462,14 @@ void CGameState::applyNL(IPack * pack)
}
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
{
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)
{
artWorn[g]->myNumber = g;
artWorn[g]->backNumber = -1;
artWorn[g]->slotID = g;
char * hll = new char[200];
sprintf(hll, CGI->generaltexth->heroscrn[1].c_str(), (artWorn[g]->ourArt ? artWorn[g]->ourArt->name.c_str() : ""));
artWorn[g]->hoverText = std::string(hll);
@ -477,7 +476,7 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero)
add->pos.y = 365;
add->pos.h = add->pos.w = 44;
if(s<hero->artifacts.size() && hero->artifacts[s])
add->text = hero->getArt(s)->description;
add->text = hero->getArt(19+s)->description;
else
add->text = std::string();
add->ourWindow = this;
@ -500,8 +499,7 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero)
add->neck = true;
add->shoulders = true;
add->head = true;
add->myNumber = -1;
add->backNumber = s;
add->slotID = 19+s;
backpack.push_back(add);
}
activeArtPlace = NULL;
@ -890,15 +888,7 @@ void CArtPlace::clickLeft(boost::logic::tribool down)
//chceck if swap is possible
if(this->fitsHere(ourWindow->activeArtPlace->ourArt) && ourWindow->activeArtPlace->fitsHere(this->ourArt))
{
//swap artifacts
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());
LOCPLINT->cb->swapArifacts(ourWindow->curHero,slotID,ourWindow->curHero,ourWindow->activeArtPlace->slotID);
const CArtifact * pmh = ourArt;
ourArt = ourWindow->activeArtPlace->ourArt;

View File

@ -64,8 +64,7 @@ public:
bool spellBook, warMachine1, warMachine2, warMachine3, warMachine4,
misc1, misc2, misc3, misc4, misc5, feet, lRing, rRing, torso,
lHand, rHand, neck, shoulders, head; //my types
int myNumber;
int backNumber; //number of artifact if this is backpack artplace
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
bool clicked;
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;
ret.second+=(*txtg)[i][j]->h;
}
if(!(*txtg)[i].size())
ret.second+=19;
if (ret.first<lw)
ret.first=lw;
}
@ -381,7 +383,7 @@ std::vector< std::vector<SComponent*> > * CMessage::breakComps(std::vector<SComp
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;
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 =
(curh=45) //top margin
+ txts.second //text total height
+ 55 //text <=> img
+ imgToBmp //text <=> img
+ bitmap->h
+ 5 // to sibtitle
+ (*txtg)[0][0]->h
+ 30;
SDL_Surface *ret = drawBox1(boxs.first,boxs.second,player);
blitTextOnSur(txtg,curh,ret);
curh += 55;
curh += imgToBmp;
blitAt(bitmap,(ret->w/2)-(bitmap->w/2),curh,ret);
curh += bitmap->h + 5;
CSDL_Ext::printAtMiddle(sub,ret->w/2,curh+( ((*txtg)[0][0]->h) / 2 ),GEOR13,zwykly,ret);
delete tekst;
delete txtg;
return ret;
}

View File

@ -39,7 +39,7 @@ public:
static SDL_Surface * genMessage(std::string title, std::string text, EWindowType type=infoOnly,
std::vector<CDefHandler*> *addPics=NULL, void * cb=NULL);
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
CMessage();
static void init();

View File

@ -575,7 +575,7 @@ void CInfoPopup::close()
delete this;
if(LOCPLINT->curint == LOCPLINT->adventureInt)
LOCPLINT->adventureInt->show();
else if(LOCPLINT->curint == LOCPLINT->castleInt)
else if((LOCPLINT->curint == LOCPLINT->castleInt) && !LOCPLINT->castleInt->subInt)
LOCPLINT->castleInt->showAll();
}
void CInfoPopup::show(SDL_Surface * to)
@ -3167,25 +3167,38 @@ CCreInfoWindow::CCreInfoWindow(int Cid, int Type, int creatureCount, StackState
{
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
{
if(LOCPLINT->cb->getResourceAmount(i->first) < i->second*creatureCount)
enough = false;
upgResCost.push_back(new SComponent(SComponent::resource,i->first,i->second*creatureCount));
}
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
if(enough)
{
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);
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");
else
{
upgrade = new AdventureMapButton("",CGI->preth->zelp[446].second,boost::function<void()>(),pos.x+76,pos.y+237,"IVIEWCR.DEF");
upgrade->callback.funcs.clear();
upgrade->bitmapOffset = 2;
}
}
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);
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:
{
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 -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)
{
if(artifWorn.find(pos)!=artifWorn.end())
return &VLC->arth->artifacts[artifWorn[pos]];
else
int id = getArtAtPos(pos);
if(id>=0)
return &VLC->arth->artifacts[id];
else
return NULL;
}

View File

@ -107,8 +107,8 @@ public:
bool inTownGarrison; // if hero is in 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::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::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
std::set<int> spells; //known spells (spell IDs)
virtual bool isHero() const;
@ -125,6 +125,8 @@ public:
int getCurrentLuck() const;
int getCurrentMorale() const;
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);
CGHeroInstance();
virtual ~CGHeroInstance();

View File

@ -164,6 +164,18 @@ struct SetHeroesInTown : public CPack<SetHeroesInTown> //508
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 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
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;
sg.garrs[id1] = *S1;
if(s1 != s2)
@ -732,6 +737,53 @@ upgend:
}
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:
{
ui32 qid, answer;