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

* attacking and capturing towns

* r-click popups on selected town/hero.bonus and teams in pregame
* disabled music due to bugs in SDL_mixer and smpeg (probably it was the source of reported random crashes / hangups)
* minor fixes
This commit is contained in:
Michał W. Urbańczyk 2009-08-22 13:59:15 +00:00
parent 5256038dc3
commit 66dd31fd8a
22 changed files with 483 additions and 113 deletions

View File

@ -295,6 +295,14 @@
>
</File>
</Filter>
<File
RelativePath=".\AIPriorities.cpp"
>
</File>
<File
RelativePath=".\AIPriorities.h"
>
</File>
<File
RelativePath=".\CGeniusAI.cpp"
>
@ -311,6 +319,14 @@
RelativePath=".\DLLMain.cpp"
>
</File>
<File
RelativePath=".\neuralNetwork.cpp"
>
</File>
<File
RelativePath=".\neuralNetwork.h"
>
</File>
</Files>
<Globals>
</Globals>

View File

@ -129,8 +129,8 @@ void init()
CGI->soundh->init();
CGI->soundh->setVolume(GDefaultOptions.soundVolume);
CGI->musich = new CMusicHandler;
CGI->musich->init();
CGI->musich->setVolume(GDefaultOptions.musicVolume);
//CGI->musich->init();
//CGI->musich->setVolume(GDefaultOptions.musicVolume);
tlog0<<"\tInitializing sound: "<<pomtime.getDif()<<std::endl;
tlog0<<"Initializing screen, fonts and sound handling: "<<tmh.getDif()<<std::endl;
@ -242,6 +242,10 @@ void processCommand(const std::string &message)
break;
}
}
else if(cn=="redraw")
{
GH.totalRedraw();
}
else if(cn=="screen")
{
tlog0 << "Screenbuf points to ";
@ -386,6 +390,8 @@ static void setScreenRes(int w, int h, int bpp, bool fullscreen)
tlog1 << "Error: SDL says that " << w << "x" << h << " resolution is not available!\n";
return;
}
bool bufOnScreen = (screenBuf == screen);
if(suggestedBpp != bpp)
{
@ -406,12 +412,16 @@ static void setScreenRes(int w, int h, int bpp, bool fullscreen)
throw "Requested screen resolution is not available\n";
}
tlog0 << "New screen flags: " << screen->flags << std::endl;
if(screen2)
SDL_FreeSurface(screen2);
screen2 = CSDL_Ext::copySurface(screen);
SDL_EnableUNICODE(1);
SDL_WM_SetCaption(NAME.c_str(),""); //set window title
SDL_ShowCursor(SDL_DISABLE);
screenBuf = bufOnScreen ? screen : screen2;
}
void listenForEvents()
@ -421,26 +431,37 @@ void listenForEvents()
{
ev = new SDL_Event();
//tlog0 << "Waiting... ";
int ret = SDL_WaitEvent(ev);
if(ret == 0 || (ev->type==SDL_QUIT) || (ev->type == SDL_KEYDOWN && ev->key.keysym.sym==SDLK_F4 && (ev->key.keysym.mod & KMOD_ALT)))
//tlog0 << "got " << (int)ev->type;
if(/*ret == 0 || */(ev->type==SDL_QUIT) || (ev->type == SDL_KEYDOWN && ev->key.keysym.sym==SDLK_F4 && (ev->key.keysym.mod & KMOD_ALT)))
{
LOCPLINT->pim->lock();
if(LOCPLINT)
LOCPLINT->pim->lock();
client->close();
console->end();
SDL_Delay(750);
tlog0 << "Ending...\n";
exit(EXIT_SUCCESS);
}
else if(ev->type == SDL_KEYDOWN && ev->key.keysym.sym==SDLK_F4)
else if(LOCPLINT && ev->type == SDL_KEYDOWN && ev->key.keysym.sym==SDLK_F4)
{
boost::unique_lock<boost::recursive_mutex> lock(*LOCPLINT->pim);
bool full = !(screen->flags&SDL_FULLSCREEN);
setScreenRes(conf.cc.resx,conf.cc.resy,conf.cc.bpp,full);
GH.totalRedraw();
}
else if(ev->type == SDL_USEREVENT && ev->user.code == 1)
{
setScreenRes(conf.cc.resx,conf.cc.resy,conf.cc.bpp,conf.cc.fullscreen);
delete ev;
continue;
}
//tlog0 << " pushing ";
eventsM.lock();
events.push(ev);
eventsM.unlock();
//tlog0 << " done\n";
}
}
@ -456,7 +477,11 @@ void startGame(StartInfo * options)
if(screen->w != conf.cc.resx || screen->h != conf.cc.resy)
{
setScreenRes(conf.cc.resx,conf.cc.resy,conf.cc.bpp,conf.cc.fullscreen);
//push special event to order event reading thread to change resolution
SDL_Event ev;
ev.type = SDL_USEREVENT;
ev.user.code = 1;
SDL_PushEvent(&ev);
}
CClient cl;

View File

@ -102,12 +102,12 @@ void CMessage::dispose()
SDL_Surface * CMessage::drawBox1(int w, int h, int playerColor) //draws box for window
{
//prepare surface
SDL_Surface * ret = SDL_CreateRGBSurface(screen->flags, w, h, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
SDL_Surface * ret = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
for (int i=0; i<h; i+=background->h)//background
{
for (int j=0; j<w; j+=background->w-1)
for (int j=0; j<w; j+=background->w)
{
SDL_BlitSurface(background,&genRect(background->h,background->w-1,1,0),ret,&genRect(h,w,j,i)); //FIXME taking address of temporary
SDL_BlitSurface(background,&genRect(background->h,background->w,0,0),ret,&genRect(h,w,j,i)); //FIXME taking address of temporary
}
}
drawBorder(playerColor, ret, w, h);
@ -515,7 +515,7 @@ void CMessage::drawBorder(int playerColor, SDL_Surface * ret, int w, int h, int
SDL_BlitSurface
(piecesOfBox[playerColor][6],NULL,ret,&genRect(piecesOfBox[playerColor][6]->h,piecesOfBox[playerColor][6]->w,x+i,y+0));
SDL_BlitSurface
(piecesOfBox[playerColor][7],NULL,ret,&genRect(piecesOfBox[playerColor][7]->h,piecesOfBox[playerColor][7]->w,x+i,y+h-piecesOfBox[playerColor][7]->h));
(piecesOfBox[playerColor][7],NULL,ret,&genRect(piecesOfBox[playerColor][7]->h,piecesOfBox[playerColor][7]->w,x+i,y+h-piecesOfBox[playerColor][7]->h+1));
}
//obwodka I-szego rzedu pionowa //border of 1st series, vertical
for (int i=0; i<h-piecesOfBox[playerColor][4]->h; i+=piecesOfBox[playerColor][4]->h)
@ -531,9 +531,9 @@ void CMessage::drawBorder(int playerColor, SDL_Surface * ret, int w, int h, int
SDL_BlitSurface
(piecesOfBox[playerColor][1],NULL,ret,&genRect(piecesOfBox[playerColor][1]->h,piecesOfBox[playerColor][1]->w,x+w-piecesOfBox[playerColor][1]->w,y+0));
SDL_BlitSurface
(piecesOfBox[playerColor][2],NULL,ret,&genRect(piecesOfBox[playerColor][2]->h,piecesOfBox[playerColor][2]->w,x+0,y+h-piecesOfBox[playerColor][2]->h));
(piecesOfBox[playerColor][2],NULL,ret,&genRect(piecesOfBox[playerColor][2]->h,piecesOfBox[playerColor][2]->w,x+0,y+h-piecesOfBox[playerColor][2]->h+1));
SDL_BlitSurface
(piecesOfBox[playerColor][3],NULL,ret,&genRect(piecesOfBox[playerColor][3]->h,piecesOfBox[playerColor][3]->w,x+w-piecesOfBox[playerColor][3]->w,y+h-piecesOfBox[playerColor][3]->h));
(piecesOfBox[playerColor][3],NULL,ret,&genRect(piecesOfBox[playerColor][3]->h,piecesOfBox[playerColor][3]->w,x+w-piecesOfBox[playerColor][3]->w,y+h-piecesOfBox[playerColor][3]->h+1));
}
ComponentResolved::ComponentResolved()

View File

@ -175,10 +175,8 @@ void CPlayerInterface::yourTurn()
while(makingTurn) // main loop
{
updateWater();
pim->lock();
//if there are any waiting dialogs, show them
if(dialogs.size() && !showingDialog->get())
{
@ -1504,6 +1502,9 @@ void CPlayerInterface::objectPropertyChanged(const SetObjectProperty * sop)
if(cb->isVisible(*it))
adventureInt->minimap.showTile(*it);
}
if(obj->ID == TOWNI_TYPE)
adventureInt->townList.genList();
}
}

View File

@ -23,6 +23,8 @@
#include "../hch/CMusicHandler.h"
#include "../hch/CVideoHandler.h"
#include "AdventureMapButton.h"
#include "GUIClasses.h"
#include "../hch/CCreatureHandler.h"
/*
* CPreGame.cpp, part of VCMI engine
*
@ -212,7 +214,6 @@ CSelectionScreen::CSelectionScreen( EState Type )
break;
case loadGame:
card->difficulty->select(current->seldiff, 0);
sel->recActions = 255;
start = new AdventureMapButton(CGI->generaltexth->zelp[103], bind(&CSelectionScreen::startGame, this), 414, 535, "SCNRLOD.DEF", SDLK_b);
break;
@ -669,6 +670,7 @@ void SelectionTab::clickLeft( tribool down, bool previousState )
InfoCard::InfoCard( EState Type )
{
OBJ_CONSTRUCTION;
used = RCLICK;
sizes = CDefHandler::giveDef("SCNRMPSZ.DEF");
sFlags = CDefHandler::giveDef("ITGFLAGS.DEF");
type = Type;
@ -779,10 +781,10 @@ void InfoCard::showAll( SDL_Surface * to )
//print flags
int fx=64, ex=244, myT;
if (curMap->howManyTeams)
//if (curMap->howManyTeams)
myT = curMap->players[playerColor].team;
else
myT = -1;
//else
// myT = -1;
for (std::vector<PlayerSettings>::const_iterator i = curOpts->playerInfos.begin(); i != curOpts->playerInfos.end(); i++)
{
int *myx = ((i->color == playerColor || curMap->players[i->color].team == myT) ? &fx : &ex);
@ -815,12 +817,47 @@ void InfoCard::showAll( SDL_Surface * to )
void InfoCard::changeSelection( const CMapInfo *to )
{
//current = to;
if(type == loadGame)
difficulty->select(curMap->seldiff, 0);
GH.totalRedraw();
}
OptionsTab::OptionsTab( EState Type/*, StartInfo &Opts */)
//:opts(Opts)
void InfoCard::clickRight( tribool down, bool previousState )
{
static const Rect flagArea(19, 397, 335, 23);
if(down && isItInLoc(flagArea, GH.current->motion.x, GH.current->motion.y))
showTeamsPopup();
}
void InfoCard::showTeamsPopup()
{
SDL_Surface *bmp = CMessage::drawBox1(256, 90 + 50 * curMap->howManyTeams);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[657], 128, 30, FONT_MEDIUM, tytulowy, bmp); //{Team Alignments}
for(int i = 0; i < curMap->howManyTeams; i++)
{
std::vector<ui8> flags;
std::string hlp = CGI->generaltexth->allTexts[656]; //Team %d
hlp.replace(hlp.find("%d"), 2, boost::lexical_cast<std::string>(i+1));
CSDL_Ext::printAtMiddle(hlp, 128, 65 + 50*i, FONT_SMALL, zwykly, bmp);
for(int j = 0; j < PLAYER_LIMIT; j++)
if((curMap->players[j].canHumanPlay || curMap->players[j].canComputerPlay)
&& curMap->players[j].team == i)
flags.push_back(j);
int curx = 128 - 9*flags.size();
for(int j = 0; j < flags.size(); j++)
{
blitAt(sFlags->ourImages[flags[j]].bitmap, curx, 75 + 50*i, bmp);
curx += 18;
}
}
GH.pushInt(new CInfoPopup(bmp, true));
}
OptionsTab::OptionsTab( EState Type)
{
OBJ_CONSTRUCTION;
bg = new CPicture(BitmapHandler::loadBitmap("ADVOPTBK.bmp"), 3, 6, true);
@ -1068,12 +1105,13 @@ OptionsTab::PlayerOptionsEntry::PlayerOptionsEntry( OptionsTab *owner, PlayerSet
else
flag = NULL;
defActions &= ~SHARE_POS;
town = new SelectedBox(TOWN, s.serial);
town->pos = pos + Point(119, 2);
town->pos += pos + Point(119, 2);
hero = new SelectedBox(HERO, s.serial);
hero->pos = pos + Point(195, 2);
hero->pos += pos + Point(195, 2);
bonus = new SelectedBox(BONUS, s.serial);
bonus->pos = pos + Point(271, 2);
bonus->pos += pos + Point(271, 2);
}
void OptionsTab::PlayerOptionsEntry::showAll( SDL_Surface * to )
@ -1104,70 +1142,57 @@ void OptionsTab::PlayerOptionsEntry::selectButtons(bool onlyHero)
void OptionsTab::SelectedBox::showAll( SDL_Surface * to )
{
PlayerSettings &s = curOpts->playerInfos[player];
SDL_Surface *toBlit = NULL;
const std::string *toPrint = NULL;
SDL_Surface *toBlit = getImg();
const std::string *toPrint = getText();
blitAt(toBlit, pos, to);
printAtMiddleLoc(*toPrint, 23, 39, FONT_TINY, zwykly, to);
}
OptionsTab::SelectedBox::SelectedBox( SelType Which, ui8 Player )
:which(Which), player(Player)
{
SDL_Surface *img = getImg();
pos.w = img->w;
pos.h = img->h;
used = RCLICK;
}
SDL_Surface * OptionsTab::SelectedBox::getImg() const
{
PlayerSettings &s = curOpts->playerInfos[player];
switch(which)
{
case TOWN:
{
if (s.castle < F_NUMBER && s.castle >= 0)
{
toBlit = graphics->getPic(s.castle, true, false);
toPrint = &CGI->townh->towns[s.castle].Name();
}
else if (s.castle == -1)
{
toBlit = CGP->rTown;
toPrint = &CGI->generaltexth->allTexts[522];
}
else if (s.castle == -2)
{
toBlit = CGP->nTown;
toPrint = &CGI->generaltexth->allTexts[523];
}
}
break;
if (s.castle < F_NUMBER && s.castle >= 0)
return graphics->getPic(s.castle, true, false);
else if (s.castle == -1)
return CGP->rTown;
else if (s.castle == -2)
return CGP->nTown;
case HERO:
if (s.hero == -1)
{
if (s.hero == -1)
{
toBlit = CGP->rHero;
toPrint = &CGI->generaltexth->allTexts[522];
}
else if (s.hero == -2)
{
if(s.heroPortrait >= 0)
{
toBlit = graphics->portraitSmall[s.heroPortrait];
if(s.heroName.length())
toPrint = &s.heroName;
else
toPrint = &CGI->heroh->heroes[s.heroPortrait]->name;
}
else
{
toBlit = CGP->nHero;
toPrint = &CGI->generaltexth->allTexts[523];
}
}
return CGP->rHero;
}
else if (s.hero == -2)
{
if(s.heroPortrait >= 0)
return graphics->portraitSmall[s.heroPortrait];
else
{
toBlit = graphics->portraitSmall[s.hero];
toPrint = &s.heroName;
}
return CGP->nHero;
}
else
{
return graphics->portraitSmall[s.hero];
}
break;
case BONUS:
{
int pom;
toPrint = &CGI->generaltexth->arraytxt[214 + s.bonus];
switch (s.bonus)
{
case -1:
pom=10;
toPrint = &CGI->generaltexth->allTexts[522];
break;
case 0:
pom=9;
@ -1178,17 +1203,213 @@ void OptionsTab::SelectedBox::showAll( SDL_Surface * to )
case 2:
pom=CGI->townh->towns[s.castle].bonus;
break;
default:
assert(0);
}
toBlit = CGP->bonuses->ourImages[pom].bitmap;
return CGP->bonuses->ourImages[pom].bitmap;
}
break;
default:
return NULL;
}
blitAt(toBlit, pos, to);
printAtMiddleLoc(*toPrint, 23, 39, FONT_TINY, zwykly, to);
}
OptionsTab::SelectedBox::SelectedBox( SelType Which, ui8 Player )
:which(Which), player(Player)
const std::string * OptionsTab::SelectedBox::getText() const
{
PlayerSettings &s = curOpts->playerInfos[player];
switch(which)
{
case TOWN:
if (s.castle < F_NUMBER && s.castle >= 0)
return &CGI->townh->towns[s.castle].Name();
else if (s.castle == -1)
return &CGI->generaltexth->allTexts[522];
else if (s.castle == -2)
return &CGI->generaltexth->allTexts[523];
case HERO:
if (s.hero == -1)
return &CGI->generaltexth->allTexts[522];
else if (s.hero == -2)
{
if(s.heroPortrait >= 0)
{
if(s.heroName.length())
return &s.heroName;
else
return &CGI->heroh->heroes[s.heroPortrait]->name;
}
else
return &CGI->generaltexth->allTexts[523];
}
else
{
//if(s.heroName.length())
// return &s.heroName;
//else
return &CGI->heroh->heroes[s.hero]->name;
}
case BONUS:
switch (s.bonus)
{
case -1:
return &CGI->generaltexth->allTexts[522];
default:
return &CGI->generaltexth->arraytxt[214 + s.bonus];
}
default:
return NULL;
}
}
void OptionsTab::SelectedBox::clickRight( tribool down, bool previousState )
{
if(indeterminate(down) || !down) return;
PlayerSettings &s = curOpts->playerInfos[player];
SDL_Surface *bmp = NULL;
const std::string *title = NULL, *subTitle = NULL;
subTitle = getText();
int val;
switch(which)
{
case TOWN: val = s.castle; break;
case HERO:
val = s.hero;
if(val < 0)
{
int p9 = curMap->players[s.color].p9;
if(p9 != 255)
val = p9;
}
break;
case BONUS: val = s.bonus; break;
}
if(val == -1 || which == BONUS) //random or bonus box
{
bmp = CMessage::drawBox1(256, 190);
std::string *description = NULL;
switch(which)
{
case TOWN:
title = &CGI->generaltexth->allTexts[103];
description = &CGI->generaltexth->allTexts[104];
break;
case HERO:
title = &CGI->generaltexth->allTexts[101];
description = &CGI->generaltexth->allTexts[102];
break;
case BONUS:
{
switch(val)
{
case brandom:
title = &CGI->generaltexth->allTexts[86]; //{Random Bonus}
description = &CGI->generaltexth->allTexts[94]; //Gold, wood and ore, or an artifact is randomly chosen as your starting bonus
break;
case bartifact:
title = &CGI->generaltexth->allTexts[83]; //{Artifact Bonus}
description = &CGI->generaltexth->allTexts[90]; //An artifact is randomly chosen and equipped to your starting hero
break;
case bgold:
title = &CGI->generaltexth->allTexts[84]; //{Gold Bonus}
subTitle = &CGI->generaltexth->allTexts[87]; //500-1000
description = &CGI->generaltexth->allTexts[92]; //At the start of the game, 500-1000 gold is added to your Kingdom's resource pool
break;
case bresource:
{
title = &CGI->generaltexth->allTexts[85]; //{Resource Bonus}
switch(CGI->townh->towns[s.castle].primaryRes)
{
case 1:
subTitle = &CGI->generaltexth->allTexts[694];
description = &CGI->generaltexth->allTexts[690];
break;
case 3:
subTitle = &CGI->generaltexth->allTexts[695];
description = &CGI->generaltexth->allTexts[691];
break;
case 4:
subTitle = &CGI->generaltexth->allTexts[692];
description = &CGI->generaltexth->allTexts[688];
break;
case 5:
subTitle = &CGI->generaltexth->allTexts[693];
description = &CGI->generaltexth->allTexts[689];
break;
case 127:
subTitle = &CGI->generaltexth->allTexts[89]; //5-10 wood / 5-10 ore
description = &CGI->generaltexth->allTexts[93]; //At the start of the game, 5-10 wood and 5-10 ore are added to your Kingdom's resource pool
break;
}
}
break;
}
}
break;
}
if(description)
CSDL_Ext::printAtMiddleWB(*description, 125, 145, FONT_SMALL, 37, zwykly, bmp);
}
else if(val == -2)
{
return;
}
else if(which == TOWN)
{
bmp = CMessage::drawBox1(256, 319);
title = &CGI->generaltexth->allTexts[80];
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[79], 135, 137, FONT_MEDIUM, tytulowy, bmp);
const CTown &t = CGI->townh->towns[val];
//print creatures
int x = 60, y = 159;
for(int i = 0; i < 7; i++)
{
int c = t.basicCreatures[i];
blitAt(graphics->smallImgs[c], x, y, bmp);
CSDL_Ext::printAtMiddleWB(CGI->creh->creatures[c].nameSing, x + 16, y + 45, FONT_TINY, 10, zwykly, bmp);
if(i == 2)
{
x = 40;
y += 76;
}
else
{
x += 52;
}
}
}
else if(val >= 0)
{
const CHero *h = CGI->heroh->heroes[val];
bmp = CMessage::drawBox1(320, 255);
title = &CGI->generaltexth->allTexts[77];
CSDL_Ext::printAtMiddle(*title, 167, 36, FONT_MEDIUM, tytulowy, bmp);
CSDL_Ext::printAtMiddle(*subTitle + " - " + h->heroClass->name, 160, 99, FONT_SMALL, zwykly, bmp);
blitAt(getImg(), 136, 56, bmp);
//print specialty
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[78], 166, 132, FONT_MEDIUM, tytulowy, bmp);
blitAt(graphics->un44->ourImages[val].bitmap, 140, 150, bmp);
GH.pushInt(new CInfoPopup(bmp, true));
return;
}
if(title)
CSDL_Ext::printAtMiddle(*title, 135, 36, FONT_MEDIUM, tytulowy, bmp);
if(subTitle)
CSDL_Ext::printAtMiddle(*subTitle, 127, 103, FONT_SMALL, zwykly, bmp);
blitAt(getImg(), 104, 60, bmp);
GH.pushInt(new CInfoPopup(bmp, true));
}

View File

@ -61,6 +61,8 @@ public:
void changeSelection(const CMapInfo *to);
void showAll(SDL_Surface * to);
void clickRight(tribool down, bool previousState);
void showTeamsPopup();
InfoCard(EState Type);
~InfoCard();
};
@ -106,8 +108,13 @@ public:
{
SelType which;
ui8 player; //serial nr
void showAll(SDL_Surface * to);
SDL_Surface *getImg() const;
const std::string *getText() const;
SelectedBox(SelType Which, ui8 Player);
void showAll(SDL_Surface * to);
void clickRight(tribool down, bool previousState);
};
struct PlayerOptionsEntry : public CIntObject

View File

@ -101,7 +101,7 @@ public:
void heroVisitCastle(int obj, int heroID){};
void stopHeroVisitCastle(int obj, int heroID){};
void giveHeroArtifact(int artid, int hid, int position){}; //pos==-1 - first free slot in backpack=0; pos==-2 - default if available or backpack
void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank, boost::function<void(BattleResult*)> cb = 0){}; //use hero=NULL for no hero
void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank, boost::function<void(BattleResult*)> cb = 0, const CGTownInstance *town = NULL){}; //use hero=NULL for no hero
void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, bool creatureBank, boost::function<void(BattleResult*)> cb = 0){}; //if any of armies is hero, hero will be used
void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, bool creatureBank, boost::function<void(BattleResult*)> cb = 0){}; //if any of armies is hero, hero will be used, visitable tile of second obj is place of battle
void setAmount(int objid, ui32 val){};

View File

@ -536,6 +536,16 @@ void CIntObject::enable(bool activation)
recActions = 255;
}
bool CIntObject::isItInLoc( const SDL_Rect &rect, int x, int y )
{
return isItIn(&rect, x - pos.x, y - pos.y);
}
bool CIntObject::isItInLoc( const SDL_Rect &rect, const Point &p )
{
return isItIn(&rect, p.x - pos.x, p.y - pos.y);
}
CPicture::CPicture( SDL_Surface *BG, int x, int y, bool Free )
{
bg = BG;

View File

@ -331,6 +331,8 @@ public:
void printAtMiddleLoc(const std::string & text, int x, int y, EFonts font, SDL_Color kolor, SDL_Surface * dst, bool refresh = false);
void printAtMiddleWBLoc(const std::string & text, int x, int y, EFonts font, int charpr, SDL_Color kolor, SDL_Surface * dst, bool refrsh = false);
void blitAtLoc(SDL_Surface * src, int x, int y, SDL_Surface * dst);
bool isItInLoc(const SDL_Rect &rect, int x, int y);
bool isItInLoc(const SDL_Rect &rect, const Point &p);
};
//class for binding keys to left mouse button clicks

View File

@ -683,6 +683,11 @@ CInfoPopup::CInfoPopup(SDL_Surface *Bitmap, bool Free)
{
free=Free;
bitmap=Bitmap;
pos.x = screen->w/2 - bitmap->w/2;
pos.y = screen->h/2 - bitmap->h/2;
pos.h = bitmap->h;
pos.w = bitmap->w;
}
void CInfoPopup::close()
@ -1402,6 +1407,7 @@ CTownList::CTownList(int Size, int x, int y, std::string arrupg, std::string arr
void CTownList::genList()
{
items.clear();
int howMany = LOCPLINT->cb->howManyTowns();
for (int i=0;i<howMany;i++)
{

View File

@ -216,6 +216,9 @@ void CSDL_Ext::printAt(const std::string & text, int x, int y, TTF_Font * font,
void CSDL_Ext::printAt( const std::string & text, int x, int y, EFonts font, SDL_Color kolor/*=zwykly*/, SDL_Surface * dst/*=screen*/, bool refresh /*= false*/ )
{
if(!text.size())
return;
assert(dst);
assert(font < Graphics::FONTS_NUMBER);
assert(dst->format->BytesPerPixel == 3 || dst->format->BytesPerPixel == 4); // 24/32 bpp dst only
@ -225,8 +228,11 @@ void CSDL_Ext::printAt( const std::string & text, int x, int y, EFonts font, SDL
Uint8 *px = NULL;
Uint8 *src = NULL;
//if text is in {} braces, we'll ommit them
const int first = (text[0] == '{' ? 1 : 0);
const int beyondEnd = (text[text.size()-1] == '}' ? text.size()-1 : text.size());
for(int txti = 0; txti < text.size(); txti++)
for(int txti = first; txti < beyondEnd; txti++)
{
const unsigned char c = text[txti];
src = f->chars[c].pixels;

View File

@ -512,6 +512,10 @@
RelativePath="..\hch\CVideoHandler.h"
>
</File>
<File
RelativePath=".\FontBase.h"
>
</File>
<File
RelativePath=".\FunctionList.h"
>

View File

@ -1406,7 +1406,26 @@ void CGTownInstance::onHeroVisit(const CGHeroInstance * h) const
{
if(getOwner() != h->getOwner())
{
return;
//TODO ally check
if(army)
{
const CGHeroInstance *defendingHero = NULL;
if(visitingHero)
defendingHero = visitingHero;
else if(garrisonHero)
defendingHero = garrisonHero;
const CArmedInstance *defendingArmy = this;
if(defendingHero)
defendingArmy = defendingHero;
bool outsideTown = (defendingHero == visitingHero && garrisonHero);
cb->startBattleI(h, defendingArmy, getSightCenter(), h, defendingHero, false, boost::bind(&CGTownInstance::fightOver, this, h, _1), (outsideTown ? NULL : this));
}
else
{
cb->setOwner(id, h->tempOwner);
}
}
cb->heroVisitCastle(id,h->id);
}
@ -1440,6 +1459,14 @@ void CGTownInstance::getOutOffsets( std::vector<int3> &offsets ) const
offsets += int3(-1,3,0), int3(-3,3,0);
}
void CGTownInstance::fightOver( const CGHeroInstance *h, BattleResult *result ) const
{
if(result->winner == 0)
{
cb->setOwner(id, h->tempOwner);
}
}
void CGVisitableOPH::onHeroVisit( const CGHeroInstance * h ) const
{
if(visitors.find(h->id)==visitors.end())

View File

@ -397,6 +397,7 @@ public:
//////////////////////////////////////////////////////////////////////////
void fightOver(const CGHeroInstance *h, BattleResult *result) const;
void onHeroVisit(const CGHeroInstance * h) const;
void onHeroLeave(const CGHeroInstance * h) const;
void initObj();

View File

@ -1403,8 +1403,8 @@ bool CGameState::battleCanFlee(int player)
const CGHeroInstance *h1 = getHero(curB->hero1);
const CGHeroInstance *h2 = getHero(curB->hero2);
if(h1->hasBonusOfType(HeroBonus::ENEMY_CANT_ESCAPE) //eg. one of heroes is wearing shakles of war
|| h2->hasBonusOfType(HeroBonus::ENEMY_CANT_ESCAPE))
if(h1 && h1->hasBonusOfType(HeroBonus::ENEMY_CANT_ESCAPE) //eg. one of heroes is wearing shakles of war
|| h2 && h2->hasBonusOfType(HeroBonus::ENEMY_CANT_ESCAPE))
return false;
return true;
@ -1557,7 +1557,7 @@ void CGameState::loadTownDInfos()
void CGameState::getNeighbours(int3 tile, std::vector<int3> &vec, const boost::logic::tribool &onLand)
{
int3 dirs[] = { int3(0,1,0),int3(0,-1,0),int3(-1,0,0),int3(+1,0,0),
static int3 dirs[] = { int3(0,1,0),int3(0,-1,0),int3(-1,0,0),int3(+1,0,0),
int3(1,1,0),int3(-1,1,0),int3(1,-1,0),int3(-1,-1,0) };
vec.clear();
@ -1704,6 +1704,8 @@ bool CGameState::getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath
else
blockLandSea = boost::logic::indeterminate;
const std::vector<std::vector<std::vector<ui8> > > &FoW = getPlayer(hero->tempOwner)->fogOfWarMap;
//graph initialization
std::vector< std::vector<CPathNode> > graph;
graph.resize(map->width);
@ -1726,7 +1728,7 @@ bool CGameState::getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath
if ((tinfo->tertype == TerrainTile::rock) //it's rock
|| ((blockLandSea) && (tinfo->tertype == TerrainTile::water)) //it's sea and we cannot walk on sea
|| ((!blockLandSea) && (tinfo->tertype != TerrainTile::water)) //it's land and we cannot walk on land
|| !getPlayer(hero->tempOwner)->fogOfWarMap[i][j][src.z] //tile is covered by the FoW
|| !FoW[i][j][src.z] //tile is covered by the FoW
)
{
node.accesible = false;
@ -1750,10 +1752,10 @@ bool CGameState::getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath
{
size_t i = 0;
for(; i < t->visitableObjects.size(); i++)
if(t->visitableObjects[i]->ID == 8) //it's a Boat
if(t->visitableObjects[i]->ID == 8 || t->visitableObjects[i]->ID == HEROI_TYPE) //it's a Boat
break;
d.accesible = (i < t->visitableObjects.size()); //dest is accessible only if there is boat
d.accesible = (i < t->visitableObjects.size()); //dest is accessible only if there is boat/hero
}
else if(!blockLandSea && t->tertype != TerrainTile::water) //hero is moving by water
{

View File

@ -110,6 +110,7 @@ struct DLL_EXPORT BattleInfo
ui8 side1, side2; //side1 - attacker, side2 - defender
si32 round, activeStack;
ui8 siege; // = 0 ordinary battle = 1 a siege with a Fort = 2 a siege with a Citadel = 3 a siege with a Castle
si32 tid; //used during town siege - id of attacked town; -1 if not town defence
int3 tile; //for background and bonuses
si32 hero1, hero2;
CCreatureSet army1, army2;

View File

@ -79,7 +79,7 @@ public:
virtual void heroVisitCastle(int obj, int heroID)=0;
virtual void stopHeroVisitCastle(int obj, int heroID)=0;
virtual void giveHeroArtifact(int artid, int hid, int position)=0; //pos==-1 - first free slot in backpack=0; pos==-2 - default if available or backpack
virtual void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank, boost::function<void(BattleResult*)> cb = 0)=0; //use hero=NULL for no hero
virtual void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank, boost::function<void(BattleResult*)> cb = 0, const CGTownInstance *town = NULL)=0; //use hero=NULL for no hero
virtual void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, bool creatureBank, boost::function<void(BattleResult*)> cb = 0)=0; //if any of armies is hero, hero will be used
virtual void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, bool creatureBank, boost::function<void(BattleResult*)> cb = 0)=0; //if any of armies is hero, hero will be used, visitable tile of second obj is place of battle
//virtual void startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb)=0; //for hero<=>neutral army

View File

@ -552,9 +552,26 @@ DLL_EXPORT void SetObjectProperty::applyGs( CGameState *gs )
{
CGObjectInstance *obj = gs->map->objects[id];
if(!obj)
{
tlog1 << "Wrong object ID - property cannot be set!\n";
else
obj->setProperty(what,val);
return;
}
if(what == 1)
{
if(obj->ID == TOWNI_TYPE)
{
CGTownInstance *t = static_cast<CGTownInstance*>(obj);
if(t->tempOwner < PLAYER_LIMIT)
gs->getPlayer(t->tempOwner)->towns -= t;
if(val < PLAYER_LIMIT)
gs->getPlayer(val)->towns.push_back(t);
}
}
obj->setProperty(what,val);
}
DLL_EXPORT void SetHoverName::applyGs( CGameState *gs )

View File

@ -253,7 +253,7 @@ void CMapHeader::initFromMemory( unsigned char *bufor, int &i )
{
for(int rr=0; rr<8; ++rr)
{
players[rr].team=bufor[i++];
players[rr].team = bufor[i++];
}
}
@ -1991,7 +1991,7 @@ void Mapa::readEvents( unsigned char * bufor, int &i )
}
}
bool Mapa::isInTheMap( int3 pos ) const
bool Mapa::isInTheMap(const int3 &pos) const
{
if(pos.x<0 || pos.y<0 || pos.z<0 || pos.x >= width || pos.y >= height || pos.z > twoLevel)
return false;
@ -2086,18 +2086,33 @@ const TerrainTile & Mapa::getTile( int3 tile ) const
return terrain[tile.x][tile.y][tile.z];
}
bool Mapa::isWaterTile( int3 pos ) const
bool Mapa::isWaterTile(const int3 &pos) const
{
return isInTheMap(pos) && getTile(pos).tertype == TerrainTile::water;
}
void CMapInfo::countPlayers()
{
playerAmnt=humenPlayers=0;
for (int i=0;i<PLAYER_LIMIT;i++)
playerAmnt = humenPlayers = 0;
for(int i=0;i<PLAYER_LIMIT;i++)
{
if (players[i].canHumanPlay) {playerAmnt++;humenPlayers++;}
else if (players[i].canComputerPlay) {playerAmnt++;}
if(players[i].canHumanPlay)
{
playerAmnt++;
humenPlayers++;
}
else if(players[i].canComputerPlay)
{
playerAmnt++;
}
}
if(!howManyTeams) //no alliances
{
//howManyTeams = playerAmnt;
for(int i=0;i<PLAYER_LIMIT;i++)
if(players[i].canComputerPlay || players[i].canHumanPlay)
players[i].team = howManyTeams++;
}
}

View File

@ -125,7 +125,7 @@ struct DLL_EXPORT PlayerInfo
PlayerInfo(): p7(0), p8(0), p9(0), canHumanPlay(0), canComputerPlay(0),
AITactic(0), allowedFactions(0), isFactionRandom(0),
mainHeroPortrait(0), hasMainTown(0), generateHeroAtMainTown(0),
team(0), generateHero(0) {};
team(255), generateHero(0) {};
template <typename Handler> void serialize(Handler &h, const int version)
{
@ -219,7 +219,6 @@ public:
LossCondition lossCondition;
CVictoryCondition victoryCondition; //victory conditions
std::vector<PlayerInfo> players; // info about players - size 8
std::vector<ui8> teams; // teams[i] = team of player no i
ui8 howManyTeams;
std::vector<ui8> allowedHeroes; //allowedHeroes[hero_ID] - if the hero is allowed
void initFromMemory(unsigned char *bufor, int &i);
@ -232,7 +231,7 @@ public:
template <typename Handler> void serialize(Handler &h, const int Version)
{
h & version & name & description & width & height & twoLevel & difficulty & levelLimit & areAnyPLayers;
h & players & teams & lossCondition & victoryCondition & howManyTeams;
h & players & lossCondition & victoryCondition & howManyTeams;
}
};
@ -338,8 +337,8 @@ struct DLL_EXPORT Mapa : public CMapHeader
TerrainTile &getTile(int3 tile);
const TerrainTile &getTile(int3 tile) const;
CGHeroInstance * getHero(int ID, int mode=0);
bool isInTheMap(int3 pos) const;
bool isWaterTile(int3 pos) const; //out-of-pos safe
bool isInTheMap(const int3 &pos) const;
bool isWaterTile(const int3 &pos) const; //out-of-pos safe
template <typename Handler> void serialize(Handler &h, const int formatVersion)
{
h & static_cast<CMapHeader&>(*this);

View File

@ -322,10 +322,10 @@ static CCreatureSet takeCasualties(int color, const CCreatureSet &set, BattleInf
return ret;
}
void CGameHandler::startBattle(const CArmedInstance *army1, const CArmedInstance * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank, boost::function<void(BattleResult*)> cb)
void CGameHandler::startBattle(const CArmedInstance *army1, const CArmedInstance * army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank, boost::function<void(BattleResult*)> cb, const CGTownInstance *town)
{
BattleInfo *curB = new BattleInfo;
setupBattle(curB, tile, army1->army, army2->army, hero1, hero2, creatureBank); //initializes stacks, places creatures on battlefield, blocks and informs player interfaces
setupBattle(curB, tile, army1->army, army2->army, hero1, hero2, creatureBank, town); //initializes stacks, places creatures on battlefield, blocks and informs player interfaces
NEW_ROUND;
//TODO: pre-tactic stuff, call scripts etc.
@ -857,13 +857,12 @@ namespace CGH
}
}
void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, const CCreatureSet &army1, const CCreatureSet &army2, const CGHeroInstance * hero1, const CGHeroInstance * hero2, bool creatureBank )
void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, const CCreatureSet &army1, const CCreatureSet &army2, const CGHeroInstance * hero1, const CGHeroInstance * hero2, bool creatureBank, const CGTownInstance *town)
{
battleResult.set(NULL);
std::vector<CStack*> & stacks = (curB->stacks);
curB->tile = tile;
curB->siege = 0; //TODO: add sieges
curB->army1=army1;
curB->army2=army2;
curB->hero1=(hero1)?(hero1->id):(-1);
@ -873,6 +872,17 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, const CCreatureSet
curB->round = -2;
curB->activeStack = -1;
if(town)
{
curB->tid = town->id;
curB->siege = town->fortLevel();
}
else
{
curB->tid = -1;
curB->siege = 0;
}
//reading battleStartpos
std::ifstream positions;
positions.open("config" PATHSEPARATOR "battleStartpos.txt", std::ios_base::in|std::ios_base::binary);
@ -1540,7 +1550,7 @@ void CGameHandler::giveHeroArtifact(int artid, int hid, int position) //pos==-1
sendAndApply(&sha);
}
void CGameHandler::startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank, boost::function<void(BattleResult*)> cb) //use hero=NULL for no hero
void CGameHandler::startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank, boost::function<void(BattleResult*)> cb, const CGTownInstance *town) //use hero=NULL for no hero
{
engageIntoBattle(army1->tempOwner);
engageIntoBattle(army2->tempOwner);
@ -1548,7 +1558,7 @@ void CGameHandler::startBattleI(const CArmedInstance *army1, const CArmedInstanc
if(army2->tempOwner < PLAYER_LIMIT)
states.setFlag(army2->tempOwner,&PlayerStatus::engagedIntoBattle,true);
boost::thread(boost::bind(&CGameHandler::startBattle, this, army1, army2, tile, hero1, hero2, creatureBank, cb));
boost::thread(boost::bind(&CGameHandler::startBattle, this, army1, army2, tile, hero1, hero2, creatureBank, cb, town));
}
void CGameHandler::startBattleI( const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, bool creatureBank, boost::function<void(BattleResult*)> cb )

View File

@ -84,11 +84,11 @@ public:
bool isAllowedExchange(int id1, int id2);
void giveSpells(const CGTownInstance *t, const CGHeroInstance *h);
void moveStack(int stack, int dest);
void startBattle(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank, boost::function<void(BattleResult*)> cb); //use hero=NULL for no hero
void startBattle(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank, boost::function<void(BattleResult*)> cb, const CGTownInstance *town = NULL); //use hero=NULL for no hero
void prepareAttack(BattleAttack &bat, CStack *att, CStack *def); //if last parameter is true, attack is by shooting, if false it's a melee attack
void prepareAttacked(BattleStackAttacked &bsa, CStack *def);
void checkForBattleEnd( std::vector<CStack*> &stacks );
void setupBattle( BattleInfo * curB, int3 tile, const CCreatureSet &army1, const CCreatureSet &army2, const CGHeroInstance * hero1, const CGHeroInstance * hero2, bool creatureBank );
void setupBattle( BattleInfo * curB, int3 tile, const CCreatureSet &army1, const CCreatureSet &army2, const CGHeroInstance * hero1, const CGHeroInstance * hero2, bool creatureBank, const CGTownInstance *town);
CGameHandler(void);
@ -122,7 +122,7 @@ public:
void giveHeroArtifact(int artid, int hid, int position); //pos==-1 - first free slot in backpack; pos==-2 - default if available or backpack
void moveArtifact(int hid, int oldPosition, int destPos);
void removeArtifact(int hid, int pos);
void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank, boost::function<void(BattleResult*)> cb); //use hero=NULL for no hero
void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool creatureBank, boost::function<void(BattleResult*)> cb, const CGTownInstance *town = NULL); //use hero=NULL for no hero
void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, int3 tile, bool creatureBank, boost::function<void(BattleResult*)> cb);
void startBattleI(const CArmedInstance *army1, const CArmedInstance *army2, bool creatureBank, boost::function<void(BattleResult*)> cb = 0); //if any of armies is hero, hero will be used, visitable tile of second obj is place of battle
//void startBattleI(int heroID, CCreatureSet army, int3 tile, boost::function<void(BattleResult*)> cb); //for hero<=>neutral army