1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-28 08:48:48 +02:00

* fixed crashbug on loading maps with events giving creatures

* added confirmation window when hero is dismissed
* finished mage guild screen
* fixed some crashbugs with hero window on adventure interface
* fixed giving wrong war machines on start
* added blacksmith functionality
This commit is contained in:
Michał W. Urbańczyk 2008-08-27 10:19:18 +00:00
parent ce6a9ae374
commit e856ad21a9
20 changed files with 276 additions and 81 deletions

View File

@ -14,7 +14,7 @@ AdventureMapButton::AdventureMapButton ()
active=false;
ourObj=NULL;
state=0;
actOnDown = false;
blocked = actOnDown = false;
}
//AdventureMapButton::AdventureMapButton( std::string Name, std::string HelpBox, boost::function<void()> Callback, int x, int y, std::string defName, bool activ, std::vector<std::string> * add, bool playerColoredButton)
//{
@ -28,14 +28,12 @@ AdventureMapButton::AdventureMapButton( std::string Name, std::string HelpBox, C
void AdventureMapButton::clickLeft (tribool down)
{
if(blocked)
return;
if (down)
{
state=1;
}
else
{
state=0;
}
show();
if (actOnDown && down)
{
@ -101,7 +99,7 @@ void AdventureMapButton::deactivate()
void AdventureMapButton::init( CFunctionList<void()> Callback, std::string Name, std::string HelpBox, bool playerColoredButton, std::string defName, std::vector<std::string> * add, int x, int y, bool activ )
{
callback = Callback;
actOnDown = false;
blocked = actOnDown = false;
type=2;
abs=true;
active=false;
@ -146,6 +144,14 @@ void AdventureMapButton::init( CFunctionList<void()> Callback, std::string Name,
activate();
}
void AdventureMapButton::block( bool on )
{
blocked = on;
state = 0;
bitmapOffset = on ? 2 : 0;
show();
}
void CSlider::sliderClicked()
{
if(!moving)

View File

@ -10,12 +10,13 @@ public:
std::string helpBox; //for right-click help
char key; //key shortcut
CFunctionList<void()> callback;
bool colorChange,
bool colorChange, blocked,
actOnDown; //runs when mouse is pressed down over it, not when up
void clickRight (tribool down);
void clickLeft (tribool down);
virtual void hover (bool on);
virtual void block(bool on); //if button is blocked then it'll change it's graphic to inactive (offset==2) and won't react on l-clicks
void keyPressed (SDL_KeyboardEvent & key);
void activate(); // makes button active
void deactivate(); // makes button inactive (but doesn't delete)

View File

@ -957,6 +957,11 @@ void CAdvMapInt::fendTurn()
void CAdvMapInt::activate()
{
if(subInt == heroWindow)
{
heroWindow->activate();
return;
}
LOCPLINT->curint = this;
LOCPLINT->statusbar = &statusbar;
kingOverview.activate();
@ -978,6 +983,11 @@ void CAdvMapInt::activate()
}
void CAdvMapInt::deactivate()
{
if(subInt == heroWindow)
{
heroWindow->deactivate();
return;
}
hide();
}
void CAdvMapInt::show(SDL_Surface *to)

View File

@ -175,16 +175,16 @@ int CCallback::howManyHeroes()
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
return gs->players[player].heroes.size();
}
const CGHeroInstance * CCallback::getHeroInfo(int player, int val, bool mode) //mode = 0 -> val = serial; mode = 1 -> val = ID
const CGHeroInstance * CCallback::getHeroInfo(int val, int mode) //mode = 0 -> val = serial; mode = 1 -> val = ID
{
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
if (gs->currentPlayer!=player) //TODO: checking if we are allowed to give that info
return NULL;
if (!mode)
//if (gs->currentPlayer!=player) //TODO: checking if we are allowed to give that info
// return NULL;
if (!mode) //esrial id
if(val<gs->players[player].heroes.size())
return gs->players[player].heroes[val];
else return NULL;
else
else if(mode==1) //it's hero type id
{
for (int i=0; i<gs->players[player].heroes.size();i++)
{
@ -192,6 +192,10 @@ const CGHeroInstance * CCallback::getHeroInfo(int player, int val, bool mode) //
return gs->players[player].heroes[i];
}
}
else //object id
{
return static_cast<CGHeroInstance*>(gs->map->objects[val]);
}
return NULL;
}

View File

@ -46,7 +46,7 @@ public:
virtual bool verifyPath(CPath * path, bool blockSea)=0;
virtual int getDate(int mode=0)=0; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
virtual std::vector< std::vector< std::vector<unsigned char> > > & getVisibilityMap()=0; //returns visibility map (TODO: make it const)
virtual const CGHeroInstance * getHeroInfo(int player, int val, bool mode)=0; //mode = 0 -> val = serial; mode = 1 -> val = ID
virtual const CGHeroInstance * getHeroInfo(int val, int mode=2)=0; //mode = 0 -> val = serial; mode = 1 -> val = ID
virtual int getResourceAmount(int type)=0;
virtual int howManyHeroes()=0;
virtual const CGTownInstance * getTownInfo(int val, bool mode)=0; //mode = 0 -> val = serial; mode = 1 -> val = ID
@ -120,7 +120,7 @@ public:
bool verifyPath(CPath * path, bool blockSea);
int getDate(int mode=0); //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
std::vector< std::vector< std::vector<unsigned char> > > & getVisibilityMap(); //returns visibility map (TODO: make it const)
const CGHeroInstance * getHeroInfo(int player, int val, bool mode); //mode = 0 -> val = serial; mode = 1 -> val = ID
const CGHeroInstance * getHeroInfo(int val, int mode=2); //mode = 0 -> val = serial; mode = 1 -> val = ID
int getResourceAmount(int type);
std::vector<si32> getResourceAmount();
int howManyHeroes();

View File

@ -9,6 +9,7 @@
#include "SDL_Extensions.h"
#include "client/CCreatureAnimation.h"
#include "client/Graphics.h"
#include "hch/CArtHandler.h"
#include "hch/CBuildingHandler.h"
#include "hch/CDefHandler.h"
#include "hch/CGeneralTextHandler.h"
@ -269,6 +270,7 @@ void CHeroGSlot::activate()
}
void CHeroGSlot::deactivate()
{
highlight = false;
ClickableL::deactivate();
ClickableR::deactivate();
Hoverable::deactivate();
@ -513,6 +515,25 @@ void CCastleInterface::buildingClicked(int building)
case 10: case 11: case 12: case 13:
enterHall();
break;
case 16:
{
const CGHeroInstance *hero = town->visitingHero;
if(!hero)
{
std::string pom = CGI->generaltexth->allTexts[273];
boost::algorithm::replace_first(pom,"%s",CGI->buildh->buildings[town->subID][16]->name);
LOCPLINT->showInfoDialog(pom,std::vector<SComponent*>());
return;
}
int aid = town->town->warMachine;
int price = CGI->arth->artifacts[aid].price;
bool possible = (LOCPLINT->cb->getResourceAmount(6) >= price);
if(vstd::contains(hero->artifWorn,ui16(aid+9))) //hero already has machine
possible = false;
deactivate();
(new CBlacksmithDialog(possible,142+aid,aid,hero->id))->activate();
break;
}
default:
std::cout<<"This building isn't handled...\n";
}
@ -1441,6 +1462,7 @@ void CMageGuildScreen::show(SDL_Surface * to)
{
blitAt(bg,0,0);
resdatabar.show();
LOCPLINT->statusbar->show();
exit->show();
}
void CMageGuildScreen::activate()
@ -1460,7 +1482,14 @@ void CMageGuildScreen::deactivate()
}
void CMageGuildScreen::Scroll::clickLeft (tribool down)
{
if(down)
{
std::vector<SComponent*> comps(1,
new CCustomImgComponent(SComponent::spell,spell->id,0,
static_cast<CMageGuildScreen*>(LOCPLINT->castleInt->subInt)->scrolls->ourImages[spell->id].bitmap,false)
);
LOCPLINT->showInfoDialog(spell->descriptions[0],comps);
}
}
void CMageGuildScreen::Scroll::clickRight (tribool down)
{
@ -1480,6 +1509,11 @@ void CMageGuildScreen::Scroll::clickRight (tribool down)
}
void CMageGuildScreen::Scroll::hover(bool on)
{
Hoverable::hover(on);
if(on)
LOCPLINT->statusbar->print(spell->name);
else
LOCPLINT->statusbar->clear();
}
void CMageGuildScreen::Scroll::activate()
@ -1494,3 +1528,71 @@ void CMageGuildScreen::Scroll::deactivate()
ClickableR::deactivate();
Hoverable::deactivate();
}
CBlacksmithDialog::CBlacksmithDialog(bool possible, int creMachineID, int aid, int hid)
{
SDL_Surface *bg2 = BitmapHandler::loadBitmap("TPSMITH.bmp");
SDL_SetColorKey(bg2,SDL_SRCCOLORKEY,SDL_MapRGB(bg2->format,0,255,255));
graphics->blueToPlayersAdv(bg2,LOCPLINT->playerID);
bmp = SDL_ConvertSurface(bg2,screen->format,0);
SDL_FreeSurface(bg2);
bg2 = BitmapHandler::loadBitmap("TPSMITBK.bmp");
blitAt(bg2,64,50,bmp);
SDL_FreeSurface(bg2);
CCreatureAnimation cra(CGI->creh->creatures[creMachineID].animDefName);
cra.nextFrameMiddle(bmp,165,130,true,false);
char pom[75];
sprintf(pom,CGI->generaltexth->allTexts[274].c_str(),CGI->creh->creatures[creMachineID].nameSing.c_str()); //build a new ...
printAtMiddle(pom,165,28,GEORXX,tytulowy,bmp);
printAtMiddle(CGI->generaltexth->jktexts[43],165,218,GEOR16,zwykly,bmp); //resource cost
SDL_itoa(CGI->arth->artifacts[aid].price,pom,10);
printAtMiddle(pom,165,290,GEOR13,zwykly,bmp);
pos.w = bmp->w;
pos.h = bmp->h;
pos.x = screen->w/2 - pos.w/2;
pos.y = screen->h/2 - pos.h/2;
buy = new AdventureMapButton("","",boost::bind(&CBlacksmithDialog::close,this),pos.x + 42,pos.y + 312,"IBUY30.DEF");
cancel = new AdventureMapButton("","",boost::bind(&CBlacksmithDialog::close,this),pos.x + 224,pos.y + 312,"ICANCEL.DEF");
if(possible)
buy->callback += boost::bind(&CCallback::buyArtifact,LOCPLINT->cb,LOCPLINT->cb->getHeroInfo(hid,2),aid);
else
buy->bitmapOffset = 2;
blitAt(graphics->resources32->ourImages[6].bitmap,148,244,bmp);
}
void CBlacksmithDialog::show( SDL_Surface * to/*=NULL*/ )
{
blitAt(bmp,pos);
buy->show();
cancel->show();
}
void CBlacksmithDialog::activate()
{
LOCPLINT->objsToBlit += this;
if(!buy->bitmapOffset)
buy->activate();
cancel->activate();
}
void CBlacksmithDialog::deactivate()
{
LOCPLINT->objsToBlit -= this;
if(!buy->bitmapOffset)
buy->deactivate();
cancel->deactivate();
}
CBlacksmithDialog::~CBlacksmithDialog()
{
SDL_FreeSurface(bmp);
delete cancel;
delete buy;
}
void CBlacksmithDialog::close()
{
deactivate();
delete this;
LOCPLINT->curint->activate();
}

View File

@ -204,3 +204,17 @@ public:
void activate();
void deactivate();
};
class CBlacksmithDialog : public IShowable, public CIntObject
{
public:
AdventureMapButton *buy, *cancel;
SDL_Surface *bmp;
CBlacksmithDialog(bool possible, int creMachineID, int aid, int hid);
~CBlacksmithDialog();
void close();
void show(SDL_Surface * to=NULL);
void activate();
void deactivate();
};

View File

@ -866,7 +866,7 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
}
//std::cout<<"\tRandomizing objects: "<<th.getDif()<<std::endl;
//giving starting hero
/*********give starting hero****************************************/
for(int i=0;i<PLAYER_LIMIT;i++)
{
if((map->players[i].generateHeroAtMainTown && map->players[i].hasMainTown) || (map->players[i].hasMainTown && map->version==RoE))
@ -893,12 +893,10 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
break;
}
}
//nnn->defInfo->handler = graphics->flags1[0];
map->heroes.push_back(nnn);
map->objects.push_back(nnn);
}
}
//std::cout<<"\tGiving starting heroes: "<<th.getDif()<<std::endl;
/*********creating players entries in gs****************************************/
for (int i=0; i<scenarioOps->playerInfos.size();i++)
@ -909,7 +907,7 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
players.insert(ins);
}
/******************RESOURCES****************************************************/
//TODO: zeby komputer dostawal inaczej niz gracz
//TODO: computer player should receive other amount of resource than computer (depending on difficulty)
std::vector<int> startres;
std::ifstream tis("config/startres.txt");
int k;
@ -988,7 +986,7 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
break;
default:
pom-=145;
vhi->artifWorn[13+pom] = 4+pom;
vhi->artifWorn[12+pom] = 3+pom;
break;
}
continue;
@ -1057,7 +1055,7 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
}
case bartifact:
{
if(!k->second.heroes[0])
if(!k->second.heroes.size())
{
std::cout << "Cannot give starting artifact - no heroes!" << std::endl;
break;
@ -1065,7 +1063,7 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
CArtifact *toGive;
do
{
toGive = VLC->arth->minors[ran() % VLC->arth->minors.size()];
toGive = VLC->arth->treasures[ran() % VLC->arth->treasures.size()];
} while (!map->allowedArtifact[toGive->id]);
CGHeroInstance *hero = k->second.heroes[0];
std::vector<ui16>::iterator slot = vstd::findFirstNot(hero->artifWorn,toGive->possibleSlots);

View File

@ -301,8 +301,6 @@ void CHeroWindow::quit()
LOCPLINT->curint->subInt = NULL;
LOCPLINT->objsToBlit -= this;
deactivate();
if(LOCPLINT->curint == LOCPLINT->castleInt)
LOCPLINT->castleInt->subInt = NULL;
LOCPLINT->curint->activate();
@ -415,9 +413,9 @@ void CHeroWindow::deactivate()
void CHeroWindow::dismissCurrent()
{
const CGHeroInstance * ch = curHero;
quit();
LOCPLINT->cb->dismissHero(ch);
CFunctionList<void()> ony = boost::bind(&CHeroWindow::quit,this);
ony += boost::bind(&CCallback::dismissHero,LOCPLINT->cb,curHero);
LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[22],std::vector<SComponent*>(), ony, boost::bind(&CHeroWindow::activate,this), true, false);
}
void CHeroWindow::questlog()
@ -567,7 +565,7 @@ void CHeroWindow::redrawCurBack()
//hero list blitting
for(int g=0; g<LOCPLINT->cb->howManyHeroes(); ++g)
{
const CGHeroInstance * cur = LOCPLINT->cb->getHeroInfo(player, g, false);
const CGHeroInstance * cur = LOCPLINT->cb->getHeroInfo(g, false);
blitAt(graphics->portraitSmall[cur->portrait], 611, 87+g*54, curBack);
//printing yellow border
if(cur->name == curHero->name)
@ -848,7 +846,7 @@ void LClickableAreaHero::clickLeft(boost::logic::tribool down)
if(!down)
{
owner->deactivate();
const CGHeroInstance * buf = LOCPLINT->cb->getHeroInfo(owner->player, id, false);
const CGHeroInstance * buf = LOCPLINT->cb->getHeroInfo(id, false);
owner->setHero(buf);
owner->redrawCurBack();
owner->activate();

View File

@ -718,6 +718,11 @@ std::vector<int> CPickable::yourObjects() //returns IDs of objects which are han
void CTownScript::onHeroVisit(int objid, int heroID)
{
if(cb->getOwner(objid)!=cb->getOwner(heroID))
{
return;
}
cb->heroVisitCastle(objid,heroID);
}

View File

@ -1,39 +1,40 @@
#include "stdafx.h"
#include <queue>
#include "CPlayerInterface.h"
#include "CAdvmapInterface.h"
#include "CMessage.h"
#include "mapHandler.h"
#include "SDL_Extensions.h"
#include "SDL_framerate.h"
#include "CCursorHandler.h"
#include "CCallback.h"
#include "SDL_Extensions.h"
#include "hch/CLodHandler.h"
#include "CPathfinder.h"
#include <sstream>
#include "hch/CArtHandler.h"
#include "hch/CAbilityHandler.h"
#include "hch/CHeroHandler.h"
#include "hch/CTownHandler.h"
#include "SDL_framerate.h"
#include "hch/CGeneralTextHandler.h"
#include "CCastleInterface.h"
#include "CHeroWindow.h"
#include "timeHandler.h"
#include <boost/thread.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/replace.hpp>
#include "hch/CPreGameTextHandler.h"
#include "hch/CObjectHandler.h"
#include "CBattleInterface.h"
#include "CCallback.h"
#include "CCastleInterface.h"
#include "CCursorHandler.h"
#include "CGameInfo.h"
#include <cmath>
#include "CHeroWindow.h"
#include "CMessage.h"
#include "CPathfinder.h"
#include "CPlayerInterface.h"
#include "SDL_Extensions.h"
#include "SDL_Extensions.h"
#include "SDL_framerate.h"
#include "SDL_framerate.h"
#include "client/CCreatureAnimation.h"
#include "client/Graphics.h"
#include "map.h"
#include "lib/NetPacks.h"
#include "hch/CAbilityHandler.h"
#include "hch/CArtHandler.h"
#include "hch/CGeneralTextHandler.h"
#include "hch/CHeroHandler.h"
#include "hch/CLodHandler.h"
#include "hch/CObjectHandler.h"
#include "hch/CPreGameTextHandler.h"
#include "hch/CSpellHandler.h"
#include "hch/CTownHandler.h"
#include "lib/CondSh.h"
#include "lib/NetPacks.h"
#include "map.h"
#include "mapHandler.h"
#include "timeHandler.h"
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/thread.hpp>
#include <cmath>
#include <queue>
#include <sstream>
using namespace CSDL_Ext;
extern TTF_Font * GEOR16;
@ -603,6 +604,10 @@ void SComponent::init(Etype Type, int Subtype, int Val)
oss << Val;
subtitle = oss.str();
break;
case spell:
description = CGI->spellh->spells[Subtype].descriptions[Val];
subtitle = CGI->spellh->spells[Subtype].name;
break;
case experience:
description = CGI->generaltexth->allTexts[241];
oss << Val ;
@ -619,7 +624,7 @@ void SComponent::init(Etype Type, int Subtype, int Val)
type = Type;
subtype = Subtype;
val = Val;
SDL_Surface * temp = getImg();
SDL_Surface * temp = this->getImg();
pos.w = temp->w;
pos.h = temp->h;
}
@ -2259,6 +2264,7 @@ void CPlayerInterface::openHeroWindow(const CGHeroInstance *hero)
if(curint == castleInt)
castleInt->subInt = adventureInt->heroWindow;
adventureInt->heroWindow->quitButton->callback.funcs.clear();
adventureInt->heroWindow->quitButton->callback += boost::bind(&CHeroWindow::deactivate,adventureInt->heroWindow);
adventureInt->heroWindow->quitButton->callback += boost::bind(&CHeroWindow::quit,adventureInt->heroWindow);
adventureInt->heroWindow->activate();
}
@ -2372,7 +2378,7 @@ void CHeroList::genList()
int howMany = LOCPLINT->cb->howManyHeroes();
for (int i=0;i<howMany;i++)
{
const CGHeroInstance * h = LOCPLINT->cb->getHeroInfo(LOCPLINT->playerID,i,0);
const CGHeroInstance * h = LOCPLINT->cb->getHeroInfo(i,0);
if(!h->inTownGarrison)
items.push_back(std::pair<const CGHeroInstance *,CPath *>(h,NULL));
}
@ -3472,3 +3478,20 @@ CMinorResDataBar::~CMinorResDataBar()
{
SDL_FreeSurface(bg);
}
SDL_Surface * CCustomImgComponent::getImg()
{
return bmp;
}
CCustomImgComponent::CCustomImgComponent( Etype Type, int Subtype, int Val, SDL_Surface *sur, bool freeSur )
:bmp(sur), free(freeSur)
{
init(Type,Subtype,Val);
}
CCustomImgComponent::~CCustomImgComponent()
{
if(free)
SDL_FreeSurface(bmp);
}

View File

@ -219,7 +219,7 @@ class SComponent : public ClickableR
public:
enum Etype
{
primskill, secskill, resource, creature, artifact, experience, secskill44
primskill, secskill, resource, creature, artifact, experience, secskill44, spell
} type;
int subtype;
int val;
@ -230,6 +230,8 @@ public:
void init(Etype Type, int Subtype, int Val);
SComponent(Etype Type, int Subtype, int Val);
SComponent(const Component &c);
SComponent(){};
virtual ~SComponent(){};
void clickRight (boost::logic::tribool down);
virtual SDL_Surface * getImg();
@ -238,6 +240,16 @@ public:
virtual void deactivate();
};
class CCustomImgComponent : public SComponent
{
public:
bool free; //should surface be freed on delete
SDL_Surface *bmp;
SDL_Surface * getImg();
CCustomImgComponent(Etype Type, int Subtype, int Val, SDL_Surface *sur, bool freeSur);
~CCustomImgComponent();
};
class CSelectableComponent : public SComponent, public ClickableL
{
public:

View File

@ -1,4 +1,4 @@
0.61 -> 0.62
0.61 -> 0.62 (Aug 31 2008 hopefully)
General:
* restructured to the server-client model
* support for heroes placed in towns
@ -6,6 +6,7 @@ General:
* working gaining levels for heroes (including dialog with skill selection)
* added graphical cursor
* showing creature amount in the creature info window
* giving starting bonus
Castles:
* icon in infobox showing that there is hero in town garrison
@ -15,7 +16,8 @@ Castles:
* randomizing spells in towns
* viewing hero window in the town screen
* possibility of moving hero into the garrison
* partially done mage guild screen
* mage guild screen
* support for blacksmith
* if hero doesn't have a spell book, he can buy one in a mage guild
Adventure Interface:

View File

@ -1,13 +1,13 @@
9
4 127
5 4
5 5
5 1
5 127
5 3
3 127
3 127
5 1
4 127 4
5 4 6
5 5 5
5 1 5
5 127 6
5 3 4
3 127 5
3 127 6
5 1 4
FORMAT:
#castles

View File

@ -397,7 +397,7 @@ CGObjectInstance::~CGObjectInstance()
}
CGHeroInstance::CGHeroInstance()
{
inTownGarrison = false;
tacticFormationEnabled = inTownGarrison = false;
portrait = level = exp = -1;
isStanding = true;
moveDir = 4;

View File

@ -82,7 +82,7 @@ public:
mutable int moveDir; //format: 123
// 8 4
// 765
mutable bool isStanding;
mutable bool isStanding, tacticFormationEnabled;
CHero * type;
ui32 exp; //experience point
int level; //current level of hero
@ -109,7 +109,7 @@ public:
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)
std::set<ui32> spells; //known spells (spell IDs)
virtual bool isHero() const;
unsigned int getTileCost(const EterrainType & ttype, const Eroad & rdtype, const Eriver & rvtype) const;

View File

@ -252,7 +252,7 @@ void CTownHandler::loadNames()
of >> si;
for(itr=0; itr<si; itr++)
{
of >> towns[itr].mageLevel >> towns[itr].primaryRes;
of >> towns[itr].mageLevel >> towns[itr].primaryRes >> towns[itr].warMachine;
}
of.close();
of.clear();

View File

@ -16,7 +16,7 @@ public:
std::map<int,int> hordeLvl; //[0] - first horde building creature level; [1] - second horde building (-1 if not present)
ui32 mageLevel; //max available mage guild level
int bonus; //pic number
ui16 primaryRes;
ui16 primaryRes, warMachine;
ui8 typeID;
};

View File

@ -1819,8 +1819,6 @@ void Mapa::readObjects( unsigned char * bufor, int &i)
}
int gcre = readNormalNr(bufor,i, 1); ++i; //number of gained creatures
spec->creatures = readCreatureSet(bufor,i,gcre,(version>RoE));
if(version>RoE)
i+=gcre;
i+=8;
spec->availableFor = readNormalNr(bufor,i, 1); ++i;
spec->computerActivate = readNormalNr(bufor,i, 1); ++i;

View File

@ -10,6 +10,7 @@
#include "../map.h"
#include "../lib/NetPacks.h"
#include "../lib/Connection.h"
#include "../hch/CArtHandler.h"
#include "../hch/CObjectHandler.h"
#include "../hch/CTownHandler.h"
#include "../hch/CBuildingHandler.h"
@ -787,8 +788,29 @@ upgend:
sha.artifWorn[17] = 0;
sendAndApply(&sha);
}
else if(aid < 7 && aid > 3) //war machine
{
int price = VLC->arth->artifacts[aid].price;
if(vstd::contains(hero->artifWorn,ui16(9+aid)) //hero already has this machine
|| !vstd::contains(town->builtBuildings,si32(16)) //no blackismith
|| gs->players[hero->tempOwner].resources[6] < price //no gold
|| town->town->warMachine!= aid ) //this machine is not available here (//TODO: support ballista yard in stronghold)
{
break;
}
SetResource sr;
sr.player = hero->tempOwner;
sr.resid = 6;
sr.val = gs->players[hero->tempOwner].resources[6] - price;
sendAndApply(&sr);
//TODO: war machines
SetHeroArtifacts sha;
sha.hid = hid;
sha.artifacts = hero->artifacts;
sha.artifWorn = hero->artifWorn;
sha.artifWorn[9+aid] = aid;
sendAndApply(&sha);
}
break;
}
case 2001: