1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

* most of the obstacles (but needs some polishing)

* more appropriate animation of hero casting spell
This commit is contained in:
mateuszb 2009-02-09 14:50:32 +00:00
parent c847d56a96
commit 445653c880
10 changed files with 358 additions and 126 deletions

View File

@ -237,6 +237,17 @@ CBattleInterface::CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, C
}
backgroundWithHexes = CSDL_Ext::newSurface(background->w, background->h, screen);
//preparing obstacle defs
std::vector<CObstacleInstance> obst = LOCPLINT->cb->battleGetAllObstacles();
for(int t=0; t<obst.size(); ++t)
{
idToObstacle[obst[t].ID] = CDefHandler::giveDef(CGI->heroh->obstacles[obst[t].ID].defName);
for(int n=0; n<idToObstacle[obst[t].ID]->ourImages.size(); ++n)
{
SDL_SetColorKey(idToObstacle[obst[t].ID]->ourImages[n].bitmap, SDL_SRCCOLORKEY, SDL_MapRGB(idToObstacle[obst[t].ID]->ourImages[n].bitmap->format,0,255,255));
}
}
}
CBattleInterface::~CBattleInterface()
@ -273,6 +284,9 @@ CBattleInterface::~CBattleInterface()
for(std::map< int, CDefHandler * >::iterator g=idToProjectile.begin(); g!=idToProjectile.end(); ++g)
delete g->second;
for(std::map< int, CDefHandler * >::iterator g=idToObstacle.begin(); g!=idToObstacle.end(); ++g)
delete g->second;
}
void CBattleInterface::setPrintCellBorders(bool set)
@ -407,6 +421,16 @@ void CBattleInterface::show(SDL_Surface * to)
SDL_GetClipRect(to, &buf);
SDL_SetClipRect(to, &pos);
//showing obstacles
std::vector<CObstacleInstance> obstacles = LOCPLINT->cb->battleGetAllObstacles();
for(int b=0; b<obstacles.size(); ++b)
{
int x = ((obstacles[b].pos/BFIELD_WIDTH)%2==0 ? 22 : 0) + 44*(obstacles[b].pos%BFIELD_WIDTH);
int y = 86 + 42 * (obstacles[b].pos/BFIELD_WIDTH);
std::vector<Cimage> &images = idToObstacle[obstacles[b].ID]->ourImages;
blitAt(images[((animCount+1)/(4/animSpeed))%images.size()].bitmap, x, y, to);
}
//showing hero animations
if(attackingHero)
attackingHero->show(to);
@ -2167,9 +2191,17 @@ void CBattleHero::show(SDL_Surface *to)
{
SDL_Rect posb = pos;
CSDL_Ext::blit8bppAlphaTo24bpp(dh->ourImages[i].bitmap, NULL, to, &posb);
++image;
if(dh->ourImages[(i+1)%dh->ourImages.size()].groupNumber!=phase) //back to appropriate frame
if(phase != 4 || image != 4)
{
++image;
if(dh->ourImages[(i+1)%dh->ourImages.size()].groupNumber!=phase) //back to appropriate frame
{
image = 0;
}
}
if(phase == 4 && nextPhase != -1 && image == 7)
{
phase = nextPhase;
image = 0;
}
break;
@ -2188,8 +2220,16 @@ void CBattleHero::deactivate()
void CBattleHero::setPhase(int newPhase)
{
phase = newPhase;
image = 0;
if(phase != 4)
{
phase = newPhase;
image = 0;
}
else
{
++image;
nextPhase = newPhase;
}
}
void CBattleHero::clickLeft(boost::logic::tribool down)
@ -2210,7 +2250,7 @@ void CBattleHero::clickLeft(boost::logic::tribool down)
}
}
CBattleHero::CBattleHero(const std::string & defName, int phaseG, int imageG, bool flipG, unsigned char player, const CGHeroInstance * hero, const CBattleInterface * owner): phase(phaseG), image(imageG), flip(flipG), flagAnim(0), myHero(hero), myOwner(owner)
CBattleHero::CBattleHero(const std::string & defName, int phaseG, int imageG, bool flipG, unsigned char player, const CGHeroInstance * hero, const CBattleInterface * owner): phase(phaseG), image(imageG), flip(flipG), flagAnim(0), myHero(hero), myOwner(owner), nextPhase(-1)
{
dh = CDefHandler::giveDef( defName );
for(int i=0; i<dh->ourImages.size(); ++i) //transforming images

View File

@ -29,6 +29,7 @@ public:
const CGHeroInstance * myHero; //this animation's hero instance
const CBattleInterface * myOwner; //battle interface to which this animation is assigned
int phase; //stage of animation
int nextPhase; //stage of animation to be set after current phase is fully displayed
int image; //frame of animation
unsigned char flagAnim, flagAnimCount; //for flag animation
void show(SDL_Surface * to); //prints next frame of animation to to
@ -132,6 +133,7 @@ private:
CGHeroInstance * attackingHeroInstance, * defendingHeroInstance;
std::map< int, CCreatureAnimation * > creAnims; //animations of creatures from fighting armies (order by BattleInfo's stacks' ID)
std::map< int, CDefHandler * > idToProjectile; //projectiles of creaures (creatureID, defhandler)
std::map< int, CDefHandler * > idToObstacle; //obstacles located on the battlefield
std::map< int, bool > creDir; // <creatureID, if false reverse creature's animation>
unsigned char animCount;
int activeStack; //number of active stack; -1 - no one

View File

@ -440,7 +440,7 @@ bool CCallback::buildBuilding(const CGTownInstance *town, si32 buildingID)
int CCallback::battleGetBattlefieldType()
{
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
return CGI->mh->ttiles[gs->curB->tile.x][gs->curB->tile.y][gs->curB->tile.z].tileInfo->tertype;
return gs->battleGetBattlefieldType();
}
int CCallback::battleGetObstaclesAtTile(int tile) //returns bitfield
@ -448,6 +448,16 @@ int CCallback::battleGetObstaclesAtTile(int tile) //returns bitfield
//TODO - write
return -1;
}
std::vector<CObstacleInstance> CCallback::battleGetAllObstacles()
{
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
if(gs->curB)
return gs->curB->obstacles;
else
return std::vector<CObstacleInstance>();
}
int CCallback::battleGetStack(int pos)
{
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);

View File

@ -76,6 +76,7 @@ public:
//battle
virtual int battleGetBattlefieldType()=0; // 1. sand/shore 2. sand/mesas 3. dirt/birches 4. dirt/hills 5. dirt/pines 6. grass/hills 7. grass/pines 8. lava 9. magic plains 10. snow/mountains 11. snow/trees 12. subterranean 13. swamp/trees 14. fiery fields 15. rock lands 16. magic clouds 17. lucid pools 18. holy ground 19. clover field 20. evil fog 21. "favourable winds" text on magic plains background 22. cursed ground 23. rough 24. ship to ship 25. ship
virtual int battleGetObstaclesAtTile(int tile)=0; //returns bitfield
virtual std::vector<CObstacleInstance> battleGetAllObstacles()=0; //returns all obstacles on the battlefield
virtual int battleGetStack(int pos)=0; //returns ID of stack on the tile
virtual CStack * battleGetStackByID(int ID)=0; //returns stack info by given ID
virtual CStack * battleGetStackByPos(int pos)=0; //returns stack info by given pos
@ -164,6 +165,7 @@ public:
//battle
int battleGetBattlefieldType(); // 1. sand/shore 2. sand/mesas 3. dirt/birches 4. dirt/hills 5. dirt/pines 6. grass/hills 7. grass/pines 8. lava 9. magic plains 10. snow/mountains 11. snow/trees 12. subterranean 13. swamp/trees 14. fiery fields 15. rock lands 16. magic clouds 17. lucid pools 18. holy ground 19. clover field 20. evil fog 21. "favourable winds" text on magic plains background 22. cursed ground 23. rough 24. ship to ship 25. ship
int battleGetObstaclesAtTile(int tile); //returns bitfield
std::vector<CObstacleInstance> battleGetAllObstacles(); //returns all obstacles on the battlefield
int battleGetStack(int pos); //returns ID of stack on the tile
CStack * battleGetStackByID(int ID); //returns stack info by given ID
CStack * battleGetStackByPos(int pos); //returns stack info by given pos

View File

@ -184,7 +184,15 @@ void BattleInfo::getAccessibilityMap(bool *accessibility, int stackToOmmit)
accessibility[stacks[g]->position+1] = false;
}
}
//TODO: obstacles
//obstacles
for(int b=0; b<obstacles.size(); ++b)
{
std::vector<int> blocked = VLC->heroh->obstacles[obstacles[b].ID].getBlocked(obstacles[b].pos);
for(int c=0; c<blocked.size(); ++c)
{
accessibility[blocked[c]] = false;
}
}
}
void BattleInfo::getAccessibilityMapForTwoHex(bool *accessibility, bool atackerSide, int stackToOmmit, bool addOccupiable) //send pointer to at least 187 allocated bytes
{
@ -1540,6 +1548,16 @@ int CGameState::battleGetStack(int pos)
return -1;
}
int CGameState::battleGetBattlefieldType(int3 tile)
{
if(tile!=int3())
return map->terrain[tile.x][tile.y][tile.z].tertype;
else if(curB)
return map->terrain[curB->tile.x][curB->tile.y][curB->tile.z].tertype;
else
return -1;
}
UpgradeInfo CGameState::getUpgradeInfo(CArmedInstance *obj, int stackPos)
{
UpgradeInfo ret;

View File

@ -84,6 +84,16 @@ public:
}
};
struct DLL_EXPORT CObstacleInstance
{
int ID; //ID of obstacle
int pos; //position on battlefield
template <typename Handler> void serialize(Handler &h, const int version)
{
h & ID & pos;
}
};
struct DLL_EXPORT BattleInfo
{
ui8 side1, side2;
@ -93,10 +103,11 @@ struct DLL_EXPORT BattleInfo
si32 hero1, hero2;
CCreatureSet army1, army2;
std::vector<CStack*> stacks;
std::vector<CObstacleInstance> obstacles;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & side1 & side2 & round & activeStack & siege & tile & stacks & army1 & army2 & hero1 & hero2;
h & side1 & side2 & round & activeStack & siege & tile & stacks & army1 & army2 & hero1 & hero2 & obstacles;
}
CStack * getNextStack(); //which stack will have turn after current one
std::vector<CStack> getStackQueue(); //returns stack in order of their movement action
@ -228,6 +239,7 @@ private:
bool battleAttackCreatureStack(int ID, int dest);
bool battleShootCreatureStack(int ID, int dest);
int battleGetStack(int pos); //returns ID of stack at given tile
int battleGetBattlefieldType(int3 tile = int3());// 1. sand/shore 2. sand/mesas 3. dirt/birches 4. dirt/hills 5. dirt/pines 6. grass/hills 7. grass/pines 8. lava 9. magic plains 10. snow/mountains 11. snow/trees 12. subterranean 13. swamp/trees 14. fiery fields 15. rock lands 16. magic clouds 17. lucid pools 18. holy ground 19. clover field 20. evil fog 21. "favourable winds" text on magic plains background 22. cursed ground 23. rough 24. ship to ship 25. ship
UpgradeInfo getUpgradeInfo(CArmedInstance *obj, int stackPos);
float getMarketEfficiency(int player, int mode=0);
std::set<int3> tilesToReveal(int3 pos, int radious, int player) const; //if player==-1 => adds all tiles in radious

View File

@ -7,8 +7,8 @@ BATTLE OBSTACLES
24. ship to ship 25. ship}
{blockmap: X - blocked, N - not blocked, L - description goes to the next line, staring with the left bottom hex }
5 OBBDT01.DEF XXX 1111110000000010000000100
56 OBBHS02.DEF XXLNX 1111100000000010000000100
57 OBBHS03.DEF XXX 1111100000000010000000100
56 OBBHS02.DEF XXLNX 1100000000000000000000100
57 OBBHS03.DEF LXXX 1111100000000010000000100
91 OBBHS04.DEF XXLNXX 1100000000000000000000000
58 OBBHS11A.DEF XXXLNXXX 1100000000000000000000000
59 OBBHS12B.DEF NXXLNXX 1100000000000000000000000
@ -32,7 +32,7 @@ BATTLE OBSTACLES
18 OBDSS17.DEF XXLNXXX 1111100000000010000000100
11 OBDTF03.DEF XX 1111100000000010000000100
12 OBDTS03.DEF XXXX 1111100000000010000000100
13 OBDTS04.DEF XX 1111100000000010000000100
13 OBDTS04.DEF LNXX 1111100000000010000000100
14 OBDTS14.DEF XXLNNX 1111100000000010000000100
15 OBDTS15.DEF XLXLNX 1111100000000010000000100
66 OBEFS00.DEF X 0000000000000000000100000
@ -47,7 +47,8 @@ BATTLE OBSTACLES
83 OBFFS04.DEF XXXLXXXX 0000000100000000000000000
19 OBGLG01.DEF XX 0000000000001010000000000
94 OBGRK01.DEF XX 0000000000001010000000000
20 OBGRK02.DEF XX 0000000000001010000000000
23 OBGRK02.DEF XX 0000000000001010000000000
20 OBGRS02.DEF NXX 0000000000001010000000000
22 OBGRS02.DEF NXXXXLNXXXXX 0000011010001100000000000
35 OBGRSO3.DEF XXXXXXX 1111111010000010000000100
21 OBGST01.DEF X 1111111010000010000000100
@ -82,4 +83,24 @@ BATTLE OBSTACLES
87 OBRLS03.DEF XLNXX 000000000000001000000000
4 OBSKEL1.DEF XX 1111110000000010000000100
3 OBSKEL2.DEF XX 1111110000000010000000100
24 OBSNS01.DEF XXX 0000000001100000000000000
25 OBSNS02.DEF NXXXX 0000000001100000000000000
26 OBSNS03.DEF XLXLX 0000000001100000000000000
27 OBSNS04.DEF XXX 0000000001100000000000000
28 OBSNS05.DEF X 0000000001100000000000000
29 OBSNS06.DEF LNXX 0000000001100000000000000
30 OBSNS07.DEF XX 0000000001100000000000000
31 OBSNS08.DEF LNXXX 0000000001100000000000000
32 OBSNS09.DEF XXXXLNNXXXX 0000000001100000000000000
33 OBSNS10.DEF XXLNXLNXXXLNNXX 0000000001100000000000000
45 OBSUS01.DEF XLXXX 0000000000010000000000000
46 OBSUS02.DEF XXX 0000000000010000000000000
47 OBSUS11B.DEF XXXLXXXX 0000000000010000000000000
34 OBSWS01.DEF LNX 0000000000001000000000000
35 OBSWS02.DEF XXXXXXX 0000000000001000000000000
36 OBSWS03.DEF XX 0000000000001000000000000
37 OBSWS04.DEF XXX 0000000000001000000000000
38 OBSWS11B.DEF XXXXLXXXX 0000000000001000000000000
16 OBSWS11B.DEF NXXXLXXXLXXX 0000000000001000000000000
39 OBSWS13A.DEF XXXXLXX 0000000000001000000000000
-1

View File

@ -33,6 +33,74 @@ int CHeroClass::chooseSecSkill(const std::set<int> & possibles) const //picks se
throw std::string("Cannot pick secondary skill!");
}
int CObstacleInfo::getWidth()
{
int ret = 1;
int line = 1;
for(int h=0; h<blockmap.size(); ++h)
{
int cur = - line/2;
switch(blockmap[h])
{
case 'X' : case 'N':
++cur;
break;
case 'L':
if(cur > ret)
ret = cur;
++line;
break;
}
}
return ret;
}
int CObstacleInfo::getHeight()
{
int ret = 1;
for(int h=0; h<blockmap.size(); ++h)
{
if(blockmap[h] == 'L')
{
++ret;
}
}
return ret;
}
std::vector<int> CObstacleInfo::getBlocked(int hex)
{
std::vector<int> ret;
int cur = hex; //currently browsed hex
int curBeg = hex; //beginning of current line
for(int h=0; h<blockmap.size(); ++h)
{
switch(blockmap[h])
{
case 'X':
ret.push_back(cur);
++cur;
break;
case 'L':
if((cur/17)%2 == 0)
{
cur = curBeg + 17;
curBeg = cur;
}
else
{
cur = curBeg + 16;
curBeg = cur;
}
break;
case 'N':
++cur;
break;
}
}
return ret;
}
CHeroHandler::~CHeroHandler()
{
for (int i = 0; i < heroes.size(); i++)
@ -62,7 +130,7 @@ void CHeroHandler::loadObstacles()
}
while(true)
{
SObstacleInfo obi;
CObstacleInfo obi;
inp>>obi.ID;
if(obi.ID == -1) break;
inp>>obi.defName;

View File

@ -1,117 +1,120 @@
#ifndef __CHEROHANDLER_H__
#define __CHEROHANDLER_H__
#include "../global.h"
#include <string>
#include <vector>
#include <set>
class CHeroClass;
class CDefHandler;
class CGameInfo;
class CGHeroInstance;
class DLL_EXPORT CHero
{
public:
std::string name;
int ID;
int lowStack[3], highStack[3]; //amount of units; described below
std::string refTypeStack[3]; //reference names of units appearing in hero's army if he is recruited in tavern
CHeroClass * heroClass;
EHeroClasses heroType; //hero class
std::vector<std::pair<ui8,ui8> > secSkillsInit; //initial secondary skills; first - ID of skill, second - level of skill (1 - basic, 2 - adv., 3 - expert)
//bool operator<(CHero& drugi){if (ID < drugi.ID) return true; else return false;}
template <typename Handler> void serialize(Handler &h, const int version)
{
h & name & ID & lowStack & highStack & refTypeStack & heroType & ID;
//hero class pointer is restored by herohandler
}
};
class DLL_EXPORT CHeroClass
{
public:
ui32 skillLimit; //how many secondary skills can hero learn
std::string name;
float aggression;
int initialAttack, initialDefence, initialPower, initialKnowledge;
std::vector<std::pair<int,int> > primChance;//primChance[PRIMARY_SKILL_ID] - first is for levels 2 - 9, second for 10+;;; probability (%) of getting point of primary skill when getting new level
std::vector<int> proSec; //probabilities of gaining secondary skills (out of 112), in id order
int selectionProbability[9]; //probability of selection in towns
std::vector<int> terrCosts; //default costs of going through terrains: dirt, sand, grass, snow, swamp, rough, subterranean, lava, water, rock; -1 means terrain is imapassable
int chooseSecSkill(const std::set<int> & possibles) const; //picks secondary skill out from given possibilities
CHeroClass();
~CHeroClass();
template <typename Handler> void serialize(Handler &h, const int version)
{
h & skillLimit & name & aggression & initialAttack & initialDefence & initialPower & initialKnowledge & primChance
& proSec & selectionProbability & terrCosts;
}
};
struct DLL_EXPORT SObstacleInfo
{
int ID;
std::string defName,
blockmap, //blockmap: X - blocked, N - not blocked, L - description goes to the next line, staring with the left bottom hex
#ifndef __CHEROHANDLER_H__
#define __CHEROHANDLER_H__
#include "../global.h"
#include <string>
#include <vector>
#include <set>
class CHeroClass;
class CDefHandler;
class CGameInfo;
class CGHeroInstance;
class DLL_EXPORT CHero
{
public:
std::string name;
int ID;
int lowStack[3], highStack[3]; //amount of units; described below
std::string refTypeStack[3]; //reference names of units appearing in hero's army if he is recruited in tavern
CHeroClass * heroClass;
EHeroClasses heroType; //hero class
std::vector<std::pair<ui8,ui8> > secSkillsInit; //initial secondary skills; first - ID of skill, second - level of skill (1 - basic, 2 - adv., 3 - expert)
//bool operator<(CHero& drugi){if (ID < drugi.ID) return true; else return false;}
template <typename Handler> void serialize(Handler &h, const int version)
{
h & name & ID & lowStack & highStack & refTypeStack & heroType & ID;
//hero class pointer is restored by herohandler
}
};
class DLL_EXPORT CHeroClass
{
public:
ui32 skillLimit; //how many secondary skills can hero learn
std::string name;
float aggression;
int initialAttack, initialDefence, initialPower, initialKnowledge;
std::vector<std::pair<int,int> > primChance;//primChance[PRIMARY_SKILL_ID] - first is for levels 2 - 9, second for 10+;;; probability (%) of getting point of primary skill when getting new level
std::vector<int> proSec; //probabilities of gaining secondary skills (out of 112), in id order
int selectionProbability[9]; //probability of selection in towns
std::vector<int> terrCosts; //default costs of going through terrains: dirt, sand, grass, snow, swamp, rough, subterranean, lava, water, rock; -1 means terrain is imapassable
int chooseSecSkill(const std::set<int> & possibles) const; //picks secondary skill out from given possibilities
CHeroClass();
~CHeroClass();
template <typename Handler> void serialize(Handler &h, const int version)
{
h & skillLimit & name & aggression & initialAttack & initialDefence & initialPower & initialKnowledge & primChance
& proSec & selectionProbability & terrCosts;
}
};
struct DLL_EXPORT CObstacleInfo
{
int ID;
std::string defName,
blockmap, //blockmap: X - blocked, N - not blocked, L - description goes to the next line, staring with the left bottom hex
allowedTerrains; /*terrains[i]: 1. sand/shore 2. sand/mesas 3. dirt/birches 4. dirt/hills 5. dirt/pines 6. grass/hills
7. grass/pines 8. lava 9. magic plains 10. snow/mountains 11. snow/trees 12. subterranean 13. swamp/trees
14. fiery fields 15. rock lands 16. magic clouds 17. lucid pools 18. holy ground 19. clover field
20. evil fog 21. "favourable winds" text on magic plains background 22. cursed ground 23. rough
24. ship to ship 25. ship*/
template <typename Handler> void serialize(Handler &h, const int version)
{
h & ID & defName & blockmap & allowedTerrains;
}
};
class DLL_EXPORT CHeroHandler
{
public:
std::vector<CHero*> heroes; //by³o nodrze
std::vector<CHeroClass *> heroClasses;
std::vector<int> expPerLevel; //expPerLEvel[i] is amount of exp needed to reach level i; if it is not in this vector, multiplicate last value by 1,2 to get next value
struct SBallisticsLevelInfo
{
ui8 keep, tower, gate, wall; //chance to hit in percent (eg. 87 is 87%)
ui8 shots; //how many shots we have
ui8 noDmg, oneDmg, twoDmg; //chances for shot dealing certain dmg in percent (eg. 87 is 87%); must sum to 100
ui8 sum; //I don't know if it is useful for anything, but it's in config file
template <typename Handler> void serialize(Handler &h, const int version)
{
h & keep & tower & gate & wall & shots & noDmg & oneDmg & twoDmg & sum;
}
};
std::vector<SBallisticsLevelInfo> ballistics; //info about ballistics ability per level; [0] - none; [1] - basic; [2] - adv; [3] - expert
std::map<int, SObstacleInfo> obstacles; //info about obstacles that may be placed on battlefield
void loadObstacles();
unsigned int level(unsigned int experience);
unsigned int reqExp(unsigned int level);
void loadHeroes();
void loadHeroClasses();
void initHeroClasses();
void initTerrainCosts();
CHeroHandler();
~CHeroHandler();
template <typename Handler> void serialize(Handler &h, const int version)
{
h & heroClasses & heroes & expPerLevel & ballistics & obstacles;
if(!h.saving)
{
//restore class pointers
for (int i=0; i<heroes.size(); i++)
{
heroes[i]->heroClass = heroClasses[heroes[i]->heroType];
}
}
}
};
#endif // __CHEROHANDLER_H__
24. ship to ship 25. ship*/
int getWidth(); //returns width of obstacle in hexes
int getHeight(); //returns height of obstacle in hexes
std::vector<int> getBlocked(int hex); //returns vector of hexes blocked by obstacle when it's placed on hex 'hex'
template <typename Handler> void serialize(Handler &h, const int version)
{
h & ID & defName & blockmap & allowedTerrains;
}
};
class DLL_EXPORT CHeroHandler
{
public:
std::vector<CHero*> heroes; //by³o nodrze
std::vector<CHeroClass *> heroClasses;
std::vector<int> expPerLevel; //expPerLEvel[i] is amount of exp needed to reach level i; if it is not in this vector, multiplicate last value by 1,2 to get next value
struct SBallisticsLevelInfo
{
ui8 keep, tower, gate, wall; //chance to hit in percent (eg. 87 is 87%)
ui8 shots; //how many shots we have
ui8 noDmg, oneDmg, twoDmg; //chances for shot dealing certain dmg in percent (eg. 87 is 87%); must sum to 100
ui8 sum; //I don't know if it is useful for anything, but it's in config file
template <typename Handler> void serialize(Handler &h, const int version)
{
h & keep & tower & gate & wall & shots & noDmg & oneDmg & twoDmg & sum;
}
};
std::vector<SBallisticsLevelInfo> ballistics; //info about ballistics ability per level; [0] - none; [1] - basic; [2] - adv; [3] - expert
std::map<int, CObstacleInfo> obstacles; //info about obstacles that may be placed on battlefield
void loadObstacles();
unsigned int level(unsigned int experience);
unsigned int reqExp(unsigned int level);
void loadHeroes();
void loadHeroClasses();
void initHeroClasses();
void initTerrainCosts();
CHeroHandler();
~CHeroHandler();
template <typename Handler> void serialize(Handler &h, const int version)
{
h & heroClasses & heroes & expPerLevel & ballistics & obstacles;
if(!h.saving)
{
//restore class pointers
for (int i=0; i<heroes.size(); i++)
{
heroes[i]->heroClass = heroClasses[heroes[i]->heroType];
}
}
}
};
#endif // __CHEROHANDLER_H__

View File

@ -1977,6 +1977,62 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army
//war machiens added
std::stable_sort(stacks.begin(),stacks.end(),cmpst);
//randomize obstacles
bool obAv[BFIELD_SIZE]; //availability of hexes for obstacles;
std::vector<int> possibleObstacles;
for(int i=0; i<BFIELD_SIZE; ++i)
{
if(i%17 < 4 || i%17 > 12)
{
obAv[i] = false;
}
else
{
obAv[i] = true;
}
}
int terType = gs->battleGetBattlefieldType(tile); //TODO: merge it with battleGetBattlefieldType
for(std::map<int, CObstacleInfo>::const_iterator g=VLC->heroh->obstacles.begin(); g!=VLC->heroh->obstacles.end(); ++g)
{
if(g->second.allowedTerrains[terType] == '1')
{
possibleObstacles.push_back(g->first);
}
}
srand(time(NULL));
if(possibleObstacles.size() > 0) //we cannot place any obstacles when we don't have them
{
int toBlock = rand()%6 + 6; //how many hexes should be blocked by obstacles
while(toBlock>0)
{
CObstacleInstance coi;
coi.ID = possibleObstacles[rand()%possibleObstacles.size()];
coi.pos = rand()%BFIELD_SIZE;
std::vector<int> block = VLC->heroh->obstacles[coi.ID].getBlocked(coi.pos);
bool badObstacle = false;
for(int b=0; b<block.size(); ++b)
{
if(!obAv[block[b]])
{
badObstacle = true;
break;
}
}
if(badObstacle) continue;
//obstacle can be placed
curB->obstacles.push_back(coi);
for(int b=0; b<block.size(); ++b)
{
obAv[block[b]] = false;
}
toBlock -= block.size();
}
}
//block engaged players
if(hero1->tempOwner<PLAYER_LIMIT)
states.setFlag(hero1->tempOwner,&PlayerStatus::engagedIntoBattle,true);