1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-27 22:49:25 +02:00

* blocked map scrolling where dialog window is opened

* it's possible in battles to check remeaining HP of neutral stacks
* function in CGameInterface called when spell is casted. Support for the Magic Arrow from engine side.
* heroes can regain mana
* support for mistycisim and intelligence skills
* fixed leak with creating frameratekeeper every turn
* minor improvements
This commit is contained in:
Michał W. Urbańczyk
2008-10-18 11:41:24 +00:00
parent 20a6e05718
commit 9d099e8c54
17 changed files with 257 additions and 108 deletions

View File

@@ -26,6 +26,7 @@
#include <boost/thread.hpp> #include <boost/thread.hpp>
#include "map.h" #include "map.h"
#include "client/CSpellWindow.h" #include "client/CSpellWindow.h"
#include "lib/CondSh.h"
#pragma warning (disable : 4355) #pragma warning (disable : 4355)
extern TTF_Font * TNRB16, *TNR, *GEOR13, *GEORXX; //fonts extern TTF_Font * TNRB16, *TNR, *GEOR13, *GEORXX; //fonts
@@ -1201,7 +1202,7 @@ void CAdvMapInt::update()
} }
++heroAnim; ++heroAnim;
if(animValHitCount % 4) if((animValHitCount % 4) && !LOCPLINT->showingDialog->get())
{ {
if(scrollingLeft) if(scrollingLeft)
{ {

View File

@@ -1710,8 +1710,8 @@ void CBattleHex::clickRight(boost::logic::tribool down)
pom->defenseBonus = h->primSkills[1]; pom->defenseBonus = h->primSkills[1];
pom->luck = h->getCurrentLuck(); pom->luck = h->getCurrentLuck();
pom->morale = h->getCurrentMorale(); pom->morale = h->getCurrentMorale();
pom->currentHealth = myst.firstHPleft;
} }
pom->currentHealth = myst.firstHPleft;
(new CCreInfoWindow(myst.creature->idNumber,0,myst.amount,pom,boost::function<void()>(),boost::function<void()>(),NULL)) (new CCreInfoWindow(myst.creature->idNumber,0,myst.amount,pom,boost::function<void()>(),boost::function<void()>(),NULL))
->activate(); ->activate();
} }

View File

@@ -22,6 +22,7 @@ class CArmedInstance;
struct BattleResult; struct BattleResult;
struct BattleAttack; struct BattleAttack;
struct BattleStackAttacked; struct BattleStackAttacked;
struct SpellCasted;
class CObstacle class CObstacle
{ {
int ID; int ID;
@@ -74,6 +75,7 @@ public:
virtual void battleEnd(BattleResult *br){}; virtual void battleEnd(BattleResult *br){};
virtual void battleNewRound(int round){}; //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn virtual void battleNewRound(int round){}; //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
virtual void battleStackMoved(int ID, int dest){}; virtual void battleStackMoved(int ID, int dest){};
virtual void battleSpellCasted(SpellCasted *sc){};
virtual void battleStart(CCreatureSet *army1, CCreatureSet *army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, bool side){}; //called by engine when battle starts; side=0 - left, side=1 - right virtual void battleStart(CCreatureSet *army1, CCreatureSet *army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, bool side){}; //called by engine when battle starts; side=0 - left, side=1 - right
virtual void battlefieldPrepared(int battlefieldType, std::vector<CObstacle*> obstacles){}; //called when battlefield is prepared, prior the battle beginning virtual void battlefieldPrepared(int battlefieldType, std::vector<CObstacle*> obstacles){}; //called when battlefield is prepared, prior the battle beginning
}; };

View File

@@ -606,6 +606,15 @@ void CGameState::applyNL(IPack * pack)
applyNL(&br->bsa); applyNL(&br->bsa);
break; break;
} }
case 3009:
{
SpellCasted *sc = static_cast<SpellCasted*>(pack);
CGHeroInstance *h = (sc->side) ? getHero(curB->hero2) : getHero(curB->hero1);
if(h)
h->mana -= VLC->spellh->spells[sc->id].costs[sc->skill];
//TODO: counter
break;
}
} }
} }
void CGameState::apply(IPack * pack) void CGameState::apply(IPack * pack)

12
CMT.cpp
View File

@@ -140,13 +140,9 @@ int main(int argc, char** argv)
CGI->dobjinfo = VLC->dobjinfo; CGI->dobjinfo = VLC->dobjinfo;
CGI->buildh = VLC->buildh; CGI->buildh = VLC->buildh;
tlog0<<"Initializing VCMI_Lib: "<<tmh.getDif()<<std::endl; tlog0<<"Initializing VCMI_Lib: "<<tmh.getDif()<<std::endl;
//cgi->curh->initCursor();
//cgi->curh->showGraphicCursor();
pomtime.getDif(); pomtime.getDif();
cgi->curh = new CCursorHandler; cgi->curh = new CCursorHandler;
cgi->curh->initCursor(); cgi->curh->initCursor();
//cgi->screenh = new CScreenHandler;
//cgi->screenh->initScreen();
tlog0<<"\tScreen handler: "<<pomtime.getDif()<<std::endl; tlog0<<"\tScreen handler: "<<pomtime.getDif()<<std::endl;
CAbilityHandler * abilh = new CAbilityHandler; CAbilityHandler * abilh = new CAbilityHandler;
abilh->loadAbilities(); abilh->loadAbilities();
@@ -187,7 +183,7 @@ int main(int argc, char** argv)
cgi->pathf = new CPathfinder(); cgi->pathf = new CPathfinder();
tlog0<<"\tPathfinder: "<<pomtime.getDif()<<std::endl; tlog0<<"\tPathfinder: "<<pomtime.getDif()<<std::endl;
tlog0<<"Handlers initialization (together): "<<tmh.getDif()<<std::endl; tlog0<<"Handlers initialization (together): "<<tmh.getDif()<<std::endl;
std::ofstream lll("client_log.txt"); std::ofstream logs("client_log.txt");
CConnection *c=NULL; CConnection *c=NULL;
//wait until server is ready //wait until server is ready
@@ -206,7 +202,7 @@ int main(int argc, char** argv)
try try
{ {
tlog0 << "Establishing connection...\n"; tlog0 << "Establishing connection...\n";
c = new CConnection("127.0.0.1",portc,NAME,lll); c = new CConnection("127.0.0.1",portc,NAME,logs);
} }
catch(...) catch(...)
{ {
@@ -281,10 +277,10 @@ void processCommand(const std::string &message)
txth->init(std::string(DATA_DIR "Data" PATHSEPARATOR "H3bitmap.lod"),"data"); txth->init(std::string(DATA_DIR "Data" PATHSEPARATOR "H3bitmap.lod"),"data");
tlog0<<"done.\nScanning .lod file\n"; tlog0<<"done.\nScanning .lod file\n";
int curp=0; int curp=0;
std::string pattern = ".TXT"; std::string pattern = ".TXT", pom;
for(int i=0;i<txth->entries.size(); i++) for(int i=0;i<txth->entries.size(); i++)
{ {
std::string pom = txth->entries[i].nameStr; pom = txth->entries[i].nameStr;
if(boost::algorithm::find_last(pom,pattern)) if(boost::algorithm::find_last(pom,pattern))
{ {
txth->extractFile(std::string("Extracted_txts\\")+pom,pom); txth->extractFile(std::string("Extracted_txts\\")+pom,pom);

View File

@@ -961,6 +961,11 @@ CPlayerInterface::CPlayerInterface(int Player, int serial)
pim = new boost::recursive_mutex; pim = new boost::recursive_mutex;
showingDialog = new CondSh<bool>(false); showingDialog = new CondSh<bool>(false);
heroMoveSpeed = 2; heroMoveSpeed = 2;
//initializing framerate keeper
mainFPSmng = new FPSmanager;
SDL_initFramerate(mainFPSmng);
SDL_setFramerate(mainFPSmng, 48);
//framerate keeper initialized
} }
CPlayerInterface::~CPlayerInterface() CPlayerInterface::~CPlayerInterface()
{ {
@@ -972,12 +977,6 @@ void CPlayerInterface::init(ICallback * CB)
cb = dynamic_cast<CCallback*>(CB); cb = dynamic_cast<CCallback*>(CB);
adventureInt = new CAdvMapInt(playerID); adventureInt = new CAdvMapInt(playerID);
castleInt = NULL; castleInt = NULL;
std::vector <const CGHeroInstance *> hh = cb->getHeroesInfo(false);
for(int i=0;i<hh.size();i++)
{
SDL_Surface * pom = infoWin(hh[i]);
graphics->heroWins.insert(std::pair<int,SDL_Surface*>(hh[i]->subID,pom));
}
std::vector<const CGTownInstance*> tt = cb->getTownsInfo(false); std::vector<const CGTownInstance*> tt = cb->getTownsInfo(false);
for(int i=0;i<tt.size();i++) for(int i=0;i<tt.size();i++)
{ {
@@ -989,19 +988,25 @@ void CPlayerInterface::yourTurn()
{ {
LOCPLINT = this; LOCPLINT = this;
makingTurn = true; makingTurn = true;
for(std::map<int,SDL_Surface*>::iterator i=graphics->heroWins.begin(); i!=graphics->heroWins.end();i++) //redraw hero infoboxes
SDL_FreeSurface(i->second);
graphics->heroWins.clear();
std::vector <const CGHeroInstance *> hh = cb->getHeroesInfo(false);
for(int i=0;i<hh.size();i++)
{
SDL_Surface * pom = infoWin(hh[i]);
graphics->heroWins.insert(std::pair<int,SDL_Surface*>(hh[i]->subID,pom));
}
adventureInt->infoBar.newDay(cb->getDate(1)); adventureInt->infoBar.newDay(cb->getDate(1));
if(adventureInt->heroList.items.size()) if(adventureInt->heroList.items.size())
adventureInt->select(adventureInt->heroList.items[0].first); adventureInt->select(adventureInt->heroList.items[0].first);
else else
adventureInt->select(adventureInt->townList.items[0]); adventureInt->select(adventureInt->townList.items[0]);
adventureInt->activate(); adventureInt->activate();
//show rest of things
//initializing framerate keeper
mainFPSmng = new FPSmanager;
SDL_initFramerate(mainFPSmng);
SDL_setFramerate(mainFPSmng, 48);
//framerate keeper initialized
timeHandler th; timeHandler th;
th.getDif(); th.getDif();
for(;makingTurn;) // main loop for(;makingTurn;) // main loop
@@ -2046,7 +2051,7 @@ void CPlayerInterface::battleStart(CCreatureSet *army1, CCreatureSet *army2, int
{ {
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
curint->deactivate(); curint->deactivate();
curint = new CBattleInterface(army1,army2,hero1,hero2); curint = battleInt = new CBattleInterface(army1,army2,hero1,hero2);
curint->activate(); curint->activate();
LOCPLINT->objsToBlit.push_back(dynamic_cast<IShowable*>(curint)); LOCPLINT->objsToBlit.push_back(dynamic_cast<IShowable*>(curint));
} }
@@ -2058,20 +2063,20 @@ void CPlayerInterface::battlefieldPrepared(int battlefieldType, std::vector<CObs
void CPlayerInterface::battleNewRound(int round) //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn void CPlayerInterface::battleNewRound(int round) //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
{ {
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
dynamic_cast<CBattleInterface*>(curint)->newRound(round); battleInt->newRound(round);
} }
void CPlayerInterface::actionStarted(const BattleAction* action) void CPlayerInterface::actionStarted(const BattleAction* action)
{ {
curAction = action; curAction = action;
if((action->actionType==2 || (action->actionType==6 && action->destinationTile!=cb->battleGetPos(action->stackNumber))) if((action->actionType==2 || (action->actionType==6 && action->destinationTile!=cb->battleGetPos(action->stackNumber)))
&& static_cast<CBattleInterface*>(curint)->creAnims[action->stackNumber]->framesInGroup(20) && battleInt->creAnims[action->stackNumber]->framesInGroup(20)
) )
{ {
static_cast<CBattleInterface*>(curint)->creAnims[action->stackNumber]->setType(20); battleInt->creAnims[action->stackNumber]->setType(20);
if((action->actionType==2 || (action->actionType==6 && action->destinationTile!=cb->battleGetPos(action->stackNumber)))) //deactivating interface when move is started if((action->actionType==2 || (action->actionType==6 && action->destinationTile!=cb->battleGetPos(action->stackNumber)))) //deactivating interface when move is started
{ {
static_cast<CBattleInterface*>(curint)->deactivate(); battleInt->deactivate();
} }
} }
} }
@@ -2081,13 +2086,13 @@ void CPlayerInterface::actionFinished(const BattleAction* action)
curAction = NULL; curAction = NULL;
if((action->actionType==2 || (action->actionType==6 && action->destinationTile!=cb->battleGetPos(action->stackNumber)))) //activating interface when move is finished if((action->actionType==2 || (action->actionType==6 && action->destinationTile!=cb->battleGetPos(action->stackNumber)))) //activating interface when move is finished
{ {
static_cast<CBattleInterface*>(curint)->activate(); battleInt->activate();
} }
} }
BattleAction CPlayerInterface::activeStack(int stackID) //called when it's turn of that stack BattleAction CPlayerInterface::activeStack(int stackID) //called when it's turn of that stack
{ {
CBattleInterface *b = dynamic_cast<CBattleInterface*>(curint); CBattleInterface *b = battleInt;
{ {
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
b->stackActivated(stackID); b->stackActivated(stackID);
@@ -2117,7 +2122,8 @@ void CPlayerInterface::battleResultQuited()
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
((CBattleInterface*)curint)->resWindow->deactivate(); ((CBattleInterface*)curint)->resWindow->deactivate();
objsToBlit -= curint; objsToBlit -= curint;
delete curint; delete battleInt;
battleInt = 0;
curint = adventureInt; curint = adventureInt;
adventureInt->activate(); adventureInt->activate();
LOCPLINT->showingDialog->setn(false); LOCPLINT->showingDialog->setn(false);
@@ -2126,30 +2132,28 @@ void CPlayerInterface::battleResultQuited()
void CPlayerInterface::battleStackMoved(int ID, int dest) void CPlayerInterface::battleStackMoved(int ID, int dest)
{ {
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
dynamic_cast<CBattleInterface*>(curint)->stackMoved(ID, dest, dest==curAction->destinationTile); battleInt->stackMoved(ID, dest, dest==curAction->destinationTile);
}
void CPlayerInterface::battleSpellCasted(SpellCasted *sc)
{
boost::unique_lock<boost::recursive_mutex> un(*pim);
}
void CPlayerInterface::battleStackAttacked(BattleStackAttacked * bsa)
{
boost::unique_lock<boost::recursive_mutex> un(*pim);
} }
void CPlayerInterface::battleAttack(BattleAttack *ba) void CPlayerInterface::battleAttack(BattleAttack *ba)
{ {
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);
if(ba->shot()) if(ba->shot())
dynamic_cast<CBattleInterface*>(curint)->stackIsShooting(ba->stackAttacking,cb->battleGetPos(ba->bsa.stackAttacked)); battleInt->stackIsShooting(ba->stackAttacking,cb->battleGetPos(ba->bsa.stackAttacked));
else else
dynamic_cast<CBattleInterface*>(curint)->stackAttacking( ba->stackAttacking, ba->counter() ? curAction->destinationTile : curAction->additionalInfo ); battleInt->stackAttacking( ba->stackAttacking, ba->counter() ? curAction->destinationTile : curAction->additionalInfo );
if(ba->killed()) if(ba->killed())
dynamic_cast<CBattleInterface*>(curint)->stackKilled(ba->bsa.stackAttacked, ba->bsa.damageAmount, ba->bsa.killedAmount, ba->stackAttacking, ba->shot()); battleInt->stackKilled(ba->bsa.stackAttacked, ba->bsa.damageAmount, ba->bsa.killedAmount, ba->stackAttacking, ba->shot());
else else
dynamic_cast<CBattleInterface*>(curint)->stackIsAttacked(ba->bsa.stackAttacked, ba->bsa.damageAmount, ba->bsa.killedAmount, ba->stackAttacking, ba->shot()); battleInt->stackIsAttacked(ba->bsa.stackAttacked, ba->bsa.damageAmount, ba->bsa.killedAmount, ba->stackAttacking, ba->shot());
} }
//void CPlayerInterface::battleStackKilled(int ID, int dmg, int killed, int IDby, bool byShooting)
//{
// dynamic_cast<CBattleInterface*>(curint)->stackKilled(ID, dmg, killed, IDby, byShooting);
//}
//void CPlayerInterface::battleStackIsShooting(int ID, int dest)
//{
// dynamic_cast<CBattleInterface*>(curint)->stackIsShooting(ID, dest);
//}
void CPlayerInterface::showComp(SComponent comp) void CPlayerInterface::showComp(SComponent comp)
{ {
boost::unique_lock<boost::recursive_mutex> un(*pim); boost::unique_lock<boost::recursive_mutex> un(*pim);

View File

@@ -15,6 +15,7 @@ class CDefEssential;
class CGHeroInstance; class CGHeroInstance;
class CAdvMapInt; class CAdvMapInt;
class CCastleInterface; class CCastleInterface;
class CBattleInterface;
class CStack; class CStack;
class SComponent; class SComponent;
class CCreature; class CCreature;
@@ -326,6 +327,7 @@ public:
CMainInterface *curint; CMainInterface *curint;
CAdvMapInt * adventureInt; CAdvMapInt * adventureInt;
CCastleInterface * castleInt; CCastleInterface * castleInt;
CBattleInterface * battleInt;
FPSmanager * mainFPSmng; FPSmanager * mainFPSmng;
IStatusBar *statusbar; IStatusBar *statusbar;
//to commucate with engine //to commucate with engine
@@ -369,6 +371,8 @@ public:
void battleResultQuited(); void battleResultQuited();
void battleNewRound(int round); //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn void battleNewRound(int round); //called at the beggining of each turn, round=-1 is the tactic phase, round=0 is the first "normal" turn
void battleStackMoved(int ID, int dest); void battleStackMoved(int ID, int dest);
void battleSpellCasted(SpellCasted *sc);
void battleStackAttacked(BattleStackAttacked * bsa);
void battleStart(CCreatureSet *army1, CCreatureSet *army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, bool side); //called by engine when battle starts; side=0 - left, side=1 - right void battleStart(CCreatureSet *army1, CCreatureSet *army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, bool side); //called by engine when battle starts; side=0 - left, side=1 - right
void battlefieldPrepared(int battlefieldType, std::vector<CObstacle*> obstacles); //called when battlefield is prepared, prior the battle beginning void battlefieldPrepared(int battlefieldType, std::vector<CObstacle*> obstacles); //called when battlefield is prepared, prior the battle beginning
@@ -378,7 +382,7 @@ public:
void showComp(SComponent comp); void showComp(SComponent comp);
void openTownWindow(const CGTownInstance * town); //shows townscreen void openTownWindow(const CGTownInstance * town); //shows townscreen
void openHeroWindow(const CGHeroInstance * hero); //shows hero window with given hero void openHeroWindow(const CGHeroInstance * hero); //shows hero window with given hero
SDL_Surface * infoWin(const CGObjectInstance * specific); //specific=0 => draws info about selected town/hero //TODO - gdy sie dorobi sensowna hierarchie klas ins. to wywalic tego brzydkiego void* SDL_Surface * infoWin(const CGObjectInstance * specific); //specific=0 => draws info about selected town/hero
void handleEvent(SDL_Event * sEvent); void handleEvent(SDL_Event * sEvent);
void handleKeyDown(SDL_Event *sEvent); void handleKeyDown(SDL_Event *sEvent);
void handleKeyUp(SDL_Event *sEvent); void handleKeyUp(SDL_Event *sEvent);

View File

@@ -525,6 +525,17 @@ void CClient::process(int what)
gs->apply(&br); gs->apply(&br);
break; break;
} }
case 3005:
{
BattleStackAttacked bsa;
*serv >> bsa;
gs->apply(&bsa);
if(playerint.find(gs->curB->side1) != playerint.end())
playerint[gs->curB->side1]->battleStackAttacked(&bsa);
if(playerint.find(gs->curB->side2) != playerint.end())
playerint[gs->curB->side2]->battleStackAttacked(&bsa);
break;
}
case 3006: case 3006:
{ {
BattleAttack ba; BattleAttack ba;
@@ -544,7 +555,7 @@ void CClient::process(int what)
case 3007: case 3007:
{ {
*serv >> curbaction; *serv >> curbaction;
tlog5 << "Action started. ID: " << curbaction.actionType << ". Destination: "<< curbaction.destinationTile <<std::endl; tlog5 << "Action started. ID: " << (int)curbaction.actionType << ". Destination: "<< curbaction.destinationTile <<std::endl;
if(playerint.find(gs->curB->side1) != playerint.end()) if(playerint.find(gs->curB->side1) != playerint.end())
playerint[gs->curB->side1]->actionStarted(&curbaction); playerint[gs->curB->side1]->actionStarted(&curbaction);
if(playerint.find(gs->curB->side2) != playerint.end()) if(playerint.find(gs->curB->side2) != playerint.end())
@@ -565,6 +576,19 @@ void CClient::process(int what)
playerint[gs->curB->side2]->actionFinished(&curbaction); playerint[gs->curB->side2]->actionFinished(&curbaction);
break; break;
} }
case 3009:
{
tlog5 << "Spell casted!\n";
SpellCasted sc;
*serv >> sc;
gs->apply(&sc);
//todo - apply
if(playerint.find(gs->curB->side1) != playerint.end())
playerint[gs->curB->side1]->battleSpellCasted(&sc);
if(playerint.find(gs->curB->side2) != playerint.end())
playerint[gs->curB->side2]->battleSpellCasted(&sc);
break;
}
case 9999: case 9999:
break; break;
default: default:

View File

@@ -24,18 +24,17 @@ using namespace CSDL_Ext;
Graphics * graphics = NULL; Graphics * graphics = NULL;
SDL_Surface * Graphics::drawPrimarySkill(const CGHeroInstance *curh, SDL_Surface *ret, int from, int to) SDL_Surface * Graphics::drawPrimarySkill(const CGHeroInstance *curh, SDL_Surface *ret, int from, int to)
{ {
char * buf = new char[10]; char buf[10];
for (int i=from;i<to;i++) for (int i=from;i<to;i++)
{ {
SDL_itoa(curh->getPrimSkillLevel(i),buf,10); SDL_itoa(curh->getPrimSkillLevel(i),buf,10);
printAtMiddle(buf,84+28*i,68,GEOR13,zwykly,ret); printAtMiddle(buf,84+28*i,68,GEOR13,zwykly,ret);
} }
delete[] buf;
return ret; return ret;
} }
SDL_Surface * Graphics::drawHeroInfoWin(const CGHeroInstance * curh) SDL_Surface * Graphics::drawHeroInfoWin(const CGHeroInstance * curh)
{ {
char * buf = new char[10]; char buf[10];
blueToPlayersAdv(hInfo,curh->tempOwner); blueToPlayersAdv(hInfo,curh->tempOwner);
SDL_Surface * ret = SDL_DisplayFormat(hInfo); SDL_Surface * ret = SDL_DisplayFormat(hInfo);
SDL_SetColorKey(ret,SDL_SRCCOLORKEY,SDL_MapRGB(ret->format,0,255,255)); SDL_SetColorKey(ret,SDL_SRCCOLORKEY,SDL_MapRGB(ret->format,0,255,255));
@@ -50,14 +49,13 @@ SDL_Surface * Graphics::drawHeroInfoWin(const CGHeroInstance * curh)
blitAt(graphics->portraitLarge[curh->portrait],11,12,ret); blitAt(graphics->portraitLarge[curh->portrait],11,12,ret);
SDL_itoa(curh->mana,buf,10); SDL_itoa(curh->mana,buf,10);
printAtMiddle(buf,166,109,GEORM,zwykly,ret); //mana points printAtMiddle(buf,166,109,GEORM,zwykly,ret); //mana points
delete[] buf;
blitAt(morale22->ourImages[curh->getCurrentMorale()+3].bitmap,14,84,ret); blitAt(morale22->ourImages[curh->getCurrentMorale()+3].bitmap,14,84,ret);
blitAt(luck22->ourImages[curh->getCurrentLuck()+3].bitmap,14,101,ret); blitAt(luck22->ourImages[curh->getCurrentLuck()+3].bitmap,14,101,ret);
return ret; return ret;
} }
SDL_Surface * Graphics::drawTownInfoWin(const CGTownInstance * curh) SDL_Surface * Graphics::drawTownInfoWin(const CGTownInstance * curh)
{ {
char * buf = new char[10]; char buf[10];
blueToPlayersAdv(tInfo,curh->tempOwner); blueToPlayersAdv(tInfo,curh->tempOwner);
SDL_Surface * ret = SDL_DisplayFormat(tInfo); SDL_Surface * ret = SDL_DisplayFormat(tInfo);
SDL_SetColorKey(ret,SDL_SRCCOLORKEY,SDL_MapRGB(ret->format,0,255,255)); SDL_SetColorKey(ret,SDL_SRCCOLORKEY,SDL_MapRGB(ret->format,0,255,255));
@@ -87,7 +85,6 @@ SDL_Surface * Graphics::drawTownInfoWin(const CGTownInstance * curh)
if(curh->garrisonHero) if(curh->garrisonHero)
blitAt(graphics->heroInGarrison,158,87,ret); blitAt(graphics->heroInGarrison,158,87,ret);
blitAt(bigTownPic->ourImages[pom].bitmap,13,13,ret); blitAt(bigTownPic->ourImages[pom].bitmap,13,13,ret);
delete[] buf;
return ret; return ret;
} }

View File

@@ -65,6 +65,7 @@
ShowProgress="0" ShowProgress="0"
AdditionalLibraryDirectories="G:\vcmt\repa\libs" AdditionalLibraryDirectories="G:\vcmt\repa\libs"
GenerateDebugInformation="true" GenerateDebugInformation="true"
OptimizeReferences="1"
TargetMachine="1" TargetMachine="1"
Profile="true" Profile="true"
/> />

View File

@@ -235,6 +235,9 @@ extern DLL_EXPORT CLogger<5> tlog5; //gray - minor log info
{ \ { \
tlog1 << e->what()<< std::endl; \ tlog1 << e->what()<< std::endl; \
delete e; \ delete e; \
} \
catch (const std::string& e) { \
tlog1 << e << std::endl; \
} }
#define HANDLE_EXCEPTIONC(COMMAND) \ #define HANDLE_EXCEPTIONC(COMMAND) \

View File

@@ -27,6 +27,7 @@ void CDefObjInfoHandler::load()
std::istringstream inp(bitmaph->getTextFile("ZOBJCTS.TXT")); std::istringstream inp(bitmaph->getTextFile("ZOBJCTS.TXT"));
int objNumber; int objNumber;
inp>>objNumber; inp>>objNumber;
std::string mapStr;
for(int hh=0; hh<objNumber; ++hh) for(int hh=0; hh<objNumber; ++hh)
{ {
CGDefInfo* nobj = new CGDefInfo(); CGDefInfo* nobj = new CGDefInfo();
@@ -41,7 +42,6 @@ void CDefObjInfoHandler::load()
nobj->blockMap[o] = 0xff; nobj->blockMap[o] = 0xff;
nobj->visitMap[o] = 0x00; nobj->visitMap[o] = 0x00;
} }
std::string mapStr;
inp>>mapStr; inp>>mapStr;
std::reverse(mapStr.begin(), mapStr.end()); std::reverse(mapStr.begin(), mapStr.end());
for(int v=0; v<mapStr.size(); ++v) for(int v=0; v<mapStr.size(); ++v)

View File

@@ -15,6 +15,7 @@ void CObjectHandler::loadObjects()
{ {
VLC->objh = this; VLC->objh = this;
int ID=0; int ID=0;
tlog5 << "\t\tReading OBJNAMES \n";
std::string buf = bitmaph->getTextFile("OBJNAMES.TXT"); std::string buf = bitmaph->getTextFile("OBJNAMES.TXT");
int it=0; int it=0;
while (it<buf.length()-1) while (it<buf.length()-1)
@@ -26,6 +27,7 @@ void CObjectHandler::loadObjects()
names.push_back(nobj); names.push_back(nobj);
} }
tlog5 << "\t\tReading ADVEVENT \n";
buf = bitmaph->getTextFile("ADVEVENT.TXT"); buf = bitmaph->getTextFile("ADVEVENT.TXT");
it=0; it=0;
std::string temp; std::string temp;
@@ -38,6 +40,7 @@ void CObjectHandler::loadObjects()
advobtxt.push_back(temp); advobtxt.push_back(temp);
} }
tlog5 << "\t\tReading XTRAINFO \n";
buf = bitmaph->getTextFile("XTRAINFO.TXT"); buf = bitmaph->getTextFile("XTRAINFO.TXT");
it=0; it=0;
while (it<buf.length()-1) while (it<buf.length()-1)
@@ -46,6 +49,7 @@ void CObjectHandler::loadObjects()
xtrainfo.push_back(temp); xtrainfo.push_back(temp);
} }
tlog5 << "\t\tReading MINENAME \n";
buf = bitmaph->getTextFile("MINENAME.TXT"); buf = bitmaph->getTextFile("MINENAME.TXT");
it=0; it=0;
while (it<buf.length()-1) while (it<buf.length()-1)
@@ -54,6 +58,7 @@ void CObjectHandler::loadObjects()
mines.push_back(std::pair<std::string,std::string>(temp,"")); mines.push_back(std::pair<std::string,std::string>(temp,""));
} }
tlog5 << "\t\tReading MINEEVNT \n";
buf = bitmaph->getTextFile("MINEEVNT.TXT"); buf = bitmaph->getTextFile("MINEEVNT.TXT");
it=0; it=0;
int i=0; int i=0;
@@ -64,6 +69,7 @@ void CObjectHandler::loadObjects()
mines[i++].second = temp; mines[i++].second = temp;
} }
tlog5 << "\t\tReading RESTYPES \n";
buf = bitmaph->getTextFile("RESTYPES.TXT"); buf = bitmaph->getTextFile("RESTYPES.TXT");
it=0; it=0;
while (it<buf.length()-1) while (it<buf.length()-1)
@@ -72,6 +78,7 @@ void CObjectHandler::loadObjects()
restypes.push_back(temp); restypes.push_back(temp);
} }
tlog5 << "\t\tReading cregens \n";
cregens.resize(110); //TODO: hardcoded value - change cregens.resize(110); //TODO: hardcoded value - change
for(int i=0; i<cregens.size();i++) for(int i=0; i<cregens.size();i++)
cregens[i]=-1; cregens[i]=-1;
@@ -84,6 +91,8 @@ void CObjectHandler::loadObjects()
} }
ifs.close(); ifs.close();
ifs.clear(); ifs.clear();
tlog5 << "\t\tReading ZCRGN1 \n";
buf = bitmaph->getTextFile("ZCRGN1.TXT"); buf = bitmaph->getTextFile("ZCRGN1.TXT");
it=0; it=0;
while (it<buf.length()-1) while (it<buf.length()-1)
@@ -91,7 +100,7 @@ void CObjectHandler::loadObjects()
loadToIt(temp,buf,it,3); loadToIt(temp,buf,it,3);
creGens.push_back(temp); creGens.push_back(temp);
} }
tlog5 << "\t\tDone loading objects!\n";
} }
bool CGObjectInstance::isHero() const bool CGObjectInstance::isHero() const
@@ -252,13 +261,25 @@ int CGHeroInstance::getSightDistance() const //returns sight distance of this he
{ {
return 6 + getSecSkillLevel(3); //default + scouting return 6 + getSecSkillLevel(3); //default + scouting
} }
void CGHeroInstance::setPosition(int3 Pos, bool h3m) //as above, but sets position
int CGHeroInstance::manaLimit() const
{ {
if (h3m) double modifier = 1.0;
pos = Pos; switch(getSecSkillLevel(24)) //intelligence level
else {
pos = convertPosition(Pos,true); case 1: modifier+=0.25; break;
case 2: modifier+=0.5; break;
case 3: modifier+=1.0; break;
}
return 10*primSkills[3]*modifier;
} }
//void CGHeroInstance::setPosition(int3 Pos, bool h3m) //as above, but sets position
//{
// if (h3m)
// pos = Pos;
// else
// pos = convertPosition(Pos,true);
//}
bool CGHeroInstance::canWalkOnSea() const bool CGHeroInstance::canWalkOnSea() const
{ {

View File

@@ -120,7 +120,8 @@ public:
static int3 convertPosition(int3 src, bool toh3m); //toh3m=true: manifest->h3m; toh3m=false: h3m->manifest static int3 convertPosition(int3 src, bool toh3m); //toh3m=true: manifest->h3m; toh3m=false: h3m->manifest
int3 getPosition(bool h3m) const; //h3m=true - returns position of hero object; h3m=false - returns position of hero 'manifestation' int3 getPosition(bool h3m) const; //h3m=true - returns position of hero object; h3m=false - returns position of hero 'manifestation'
int getSightDistance() const; //returns sight distance of this hero int getSightDistance() const; //returns sight distance of this hero
void setPosition(int3 Pos, bool h3m); //as above, but sets position int manaLimit() const; //maximum mana value for this hero (basically 10*knowledge)
//void setPosition(int3 Pos, bool h3m); //as above, but sets position
bool canWalkOnSea() const; bool canWalkOnSea() const;
int getCurrentLuck() const; int getCurrentLuck() const;

View File

@@ -416,7 +416,8 @@ struct BattleStackAttacked : public CPack<BattleStackAttacked>//3005
{ {
ui32 stackAttacked; ui32 stackAttacked;
ui32 newAmount, newHP, killedAmount, damageAmount; ui32 newAmount, newHP, killedAmount, damageAmount;
ui8 flags; //1 - is stack killed ui8 flags; //1 - is stack killed; 2 - is there special effect to be shown
ui32 effect; //set only if flag 2 is present
BattleStackAttacked(){flags = 0; type = 3005;}; BattleStackAttacked(){flags = 0; type = 3005;};
@@ -424,9 +425,13 @@ struct BattleStackAttacked : public CPack<BattleStackAttacked>//3005
{ {
return flags & 1; return flags & 1;
} }
bool isEffect() //if target stack was killed
{
return flags & 2;
}
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & stackAttacked & newAmount & newHP & flags & killedAmount & damageAmount; h & stackAttacked & newAmount & newHP & flags & killedAmount & damageAmount & effect;
} }
}; };
@@ -468,6 +473,19 @@ struct StartAction : public CPack<StartAction>//3007
} }
}; };
struct SpellCasted : public CPack<SpellCasted>//3009
{
ui8 side; //which hero casted spell: 0 - attacker, 1 - defender
ui32 id;
ui8 skill;
ui16 tile; //destination tile (may not be set in some global/mass spells
SpellCasted(){type = 3009;};
template <typename Handler> void serialize(Handler &h, const int version)
{
h & side & id & skill & tile;
}
};
struct ShowInInfobox : public CPack<ShowInInfobox> //107 struct ShowInInfobox : public CPack<ShowInInfobox> //107
{ {
ShowInInfobox(){type = 107;}; ShowInInfobox(){type = 107;};

View File

@@ -349,36 +349,39 @@ void CGameHandler::startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile
delete battleResult.data; delete battleResult.data;
} }
void CGameHandler::prepareAttacked(BattleStackAttacked &bsa, CStack *def)
{
bsa.killedAmount = bsa.damageAmount / def->creature->hitPoints;
unsigned damageFirst = bsa.damageAmount % def->creature->hitPoints;
if( def->firstHPleft <= damageFirst )
{
bsa.killedAmount++;
bsa.newHP = def->firstHPleft + def->creature->hitPoints - damageFirst;
}
else
{
bsa.newHP = def->firstHPleft - damageFirst;
}
if(def->amount <= bsa.killedAmount) //stack killed
{
bsa.newAmount = 0;
bsa.flags |= 1;
bsa.killedAmount = def->amount; //we cannot kill more creatures than we have
}
else
{
bsa.newAmount = def->amount - bsa.killedAmount;
}
}
void CGameHandler::prepareAttack(BattleAttack &bat, CStack *att, CStack *def) void CGameHandler::prepareAttack(BattleAttack &bat, CStack *att, CStack *def)
{ {
bat.stackAttacking = att->ID; bat.stackAttacking = att->ID;
bat.bsa.stackAttacked = def->ID; bat.bsa.stackAttacked = def->ID;
bat.bsa.damageAmount = BattleInfo::calculateDmg(att, def, gs->getHero(att->attackerOwned ? gs->curB->hero1 : gs->curB->hero2), gs->getHero(def->attackerOwned ? gs->curB->hero1 : gs->curB->hero2), bat.shot());//counting dealt damage bat.bsa.damageAmount = BattleInfo::calculateDmg(att, def, gs->getHero(att->attackerOwned ? gs->curB->hero1 : gs->curB->hero2), gs->getHero(def->attackerOwned ? gs->curB->hero1 : gs->curB->hero2), bat.shot());//counting dealt damage
prepareAttacked(bat.bsa,def);
//applying damages
bat.bsa.killedAmount = bat.bsa.damageAmount / def->creature->hitPoints;
unsigned damageFirst = bat.bsa.damageAmount % def->creature->hitPoints;
if( def->firstHPleft <= damageFirst )
{
bat.bsa.killedAmount++;
bat.bsa.newHP = def->firstHPleft + def->creature->hitPoints - damageFirst;
}
else
{
bat.bsa.newHP = def->firstHPleft - damageFirst;
}
if(def->amount <= bat.bsa.killedAmount) //stack killed
{
bat.bsa.newAmount = 0;
bat.bsa.flags |= 1;
bat.bsa.killedAmount = def->amount; //we cannot kill more creatures than we have
}
else
{
bat.bsa.newAmount = def->amount - bat.bsa.killedAmount;
}
} }
void CGameHandler::handleConnection(std::set<int> players, CConnection &c) void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
{ {
@@ -427,12 +430,13 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
tmh.result = 0; tmh.result = 0;
tmh.movePoints = h->movement; tmh.movePoints = h->movement;
if((h->getOwner() != gs->currentPlayer) || //not turn of that hero if((h->getOwner() != gs->currentPlayer) //not turn of that hero
(distance(start,end)>=1.5) || //tiles are not neighouring || (distance(start,end)>=1.5) //tiles are not neighouring
(h->movement < cost) || //lack of movement points || (h->movement < cost) //lack of movement points
(t.tertype == rock) || //rock || (t.tertype == rock) //rock
(!h->canWalkOnSea() && t.tertype == water) || || (!h->canWalkOnSea() && t.tertype == water)
(t.blocked && !t.visitable) ) //tile is blocked andnot visitable || (t.blocked && !t.visitable) //tile is blocked andnot visitable
)
goto fail; goto fail;
@@ -1008,8 +1012,19 @@ upgend:
case 1: //hero casts spell case 1: //hero casts spell
{ {
CGHeroInstance *h = (ba.side) ? gs->getHero(gs->curB->hero2) : gs->getHero(gs->curB->hero1); CGHeroInstance *h = (ba.side) ? gs->getHero(gs->curB->hero2) : gs->getHero(gs->curB->hero1);
if(!h)
{
tlog2 << "Wrong caster!\n";
goto customactionend;
}
if(ba.additionalInfo >= VLC->spellh->spells.size())
{
tlog2 << "Wrong spell id (" << ba.additionalInfo << ")!\n";
goto customactionend;
}
CSpell *s = &VLC->spellh->spells[ba.additionalInfo]; CSpell *s = &VLC->spellh->spells[ba.additionalInfo];
int skill = 0; int skill = 0; //skill level
if(s->fire) if(s->fire)
skill = std::max(skill,h->getSecSkillLevel(14)); skill = std::max(skill,h->getSecSkillLevel(14));
@@ -1020,15 +1035,66 @@ upgend:
if(s->earth) if(s->earth)
skill = std::max(skill,h->getSecSkillLevel(17)); skill = std::max(skill,h->getSecSkillLevel(17));
if( !vstd::contains(h->spells,ba.additionalInfo) //hero doesn't know this spell //TODO: skill level may be different on special terrain
|| (h->mana < s->costs[skill]) //not enough mana
if( // !vstd::contains(h->spells,ba.additionalInfo) //hero doesn't know this spell
/*||*/ (h->mana < s->costs[skill]) //not enough mana
|| (ba.additionalInfo < 10) //it's adventure spell (not combat)
|| 0 )//TODO: hero has already casted a spell in this round || 0 )//TODO: hero has already casted a spell in this round
{ {
tlog2 << "Spell cannot be casted!\n";
goto customactionend; goto customactionend;
} }
sendAndApply(&StartAction(ba)); //start spell casting sendAndApply(&StartAction(ba)); //start spell casting
//TODO: spell efects
//TODO: check resistances
SpellCasted sc;
sc.side = ba.side;
sc.id = ba.additionalInfo;
sc.skill = skill;
sc.tile = ba.destinationTile;
sendAndApply(&sc);
switch(ba.additionalInfo) //spell id
{
case 15://magic arrow
{
CStack * attacked = gs->curB->getStackT(ba.destinationTile);
if(!attacked) break;
BattleStackAttacked bsa;
bsa.flags |= 2;
bsa.effect = 64;
bsa.damageAmount = h->primSkills[2] * 10; //TODO: use skill level
bsa.stackAttacked = attacked->ID;
prepareAttacked(bsa,attacked);
sendAndApply(&bsa);
break;
}
case 53: //haste
{
break;
}
}
//TODO: spells to support possibly soon (list by Zamolxis):
/*- Magic Arrow
- Haste
- Bless
- Bloodlust
- Curse
- Dispel
- Shield
- Slow
- Stone Skin
- Lightning Bolt
- Ice Bolt
- Precision
- Blind
- Fire Wall
- Weakness
- Death Ripple */
sendDataToClients(ui16(3008)); //end casting sendDataToClients(ui16(3008)); //end casting
break; break;
} }
@@ -1198,15 +1264,15 @@ void CGameHandler::newTurn()
for(int j=0;j<RESOURCE_QUANTITY;j++) for(int j=0;j<RESOURCE_QUANTITY;j++)
r.res[j] = i->second.resources[j]; r.res[j] = i->second.resources[j];
for (unsigned j=0;j<(*i).second.heroes.size();j++) //handle heroes BOOST_FOREACH(CGHeroInstance *h, (*i).second.heroes)
{ {
NewTurn::Hero h; NewTurn::Hero hth;
h.id = (*i).second.heroes[j]->id; hth.id = h->id;
h.move = valMovePoints((*i).second.heroes[j], true); //TODO: check if hero is really on the land hth.move = valMovePoints(h, true); //TODO: check if hero is really on the land
h.mana = (*i).second.heroes[j]->mana; hth.mana = std::min(h->mana+1+h->getSecSkillLevel(8), h->manaLimit()); //hero regains 1 mana point + mysticism lvel
n.heroes.insert(h); n.heroes.insert(hth);
//handle estates
switch((*i).second.heroes[j]->getSecSkillLevel(13)) switch(h->getSecSkillLevel(13)) //handle estates - give gols
{ {
case 1: //basic case 1: //basic
r.res[6] += 125; r.res[6] += 125;
@@ -1263,10 +1329,10 @@ void CGameHandler::run()
ui8 quantity, pom; ui8 quantity, pom;
//ui32 seed; //ui32 seed;
(*cc) << gs->scenarioOps->mapname << gs->map->checksum << gs->seed; (*cc) << gs->scenarioOps->mapname << gs->map->checksum << gs->seed;
(*cc) >> quantity; (*cc) >> quantity; //how many players will be handled at that client
for(int i=0;i<quantity;i++) for(int i=0;i<quantity;i++)
{ {
(*cc) >> pom; (*cc) >> pom; //read player color
gsm.lock(); gsm.lock();
connections[pom] = cc; connections[pom] = cc;
gsm.unlock(); gsm.unlock();

View File

@@ -13,6 +13,7 @@ class CCPPObjectScript;
class CScriptCallback; class CScriptCallback;
struct BattleResult; struct BattleResult;
struct BattleAttack; struct BattleAttack;
struct BattleStackAttacked;
template <typename T> struct CPack; template <typename T> struct CPack;
template <typename T> struct Query; template <typename T> struct Query;
class CGHeroInstance; class CGHeroInstance;
@@ -58,6 +59,7 @@ class CGameHandler
void moveStack(int stack, int dest); void moveStack(int stack, int dest);
void startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb); //use hero=NULL for no hero void startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, boost::function<void(BattleResult*)> cb); //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 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 checkForBattleEnd( std::vector<CStack*> &stacks );
void setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army1, CCreatureSet &army2, CGHeroInstance * hero1, CGHeroInstance * hero2 ); void setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army1, CCreatureSet &army2, CGHeroInstance * hero1, CGHeroInstance * hero2 );