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

- fixed crash on opening spellbook during enemy turn

- fixed last known localization issue (bank configs)
- diplomacy and new weeks\month mechanics should be identical to H3
- minor fixes
This commit is contained in:
Ivan Savenko 2012-01-19 14:33:22 +00:00
parent 3fcf8b6f4b
commit dbc603b7d7
19 changed files with 355 additions and 472 deletions

View File

@ -1455,6 +1455,8 @@ void CBattleInterface::bSpellf()
CCS->curh->changeGraphic(0,0);
if ( myTurn && curInt->cb->battleCanCastSpell())
{
const CGHeroInstance * chi = NULL;
if(attackingHeroInstance->tempOwner == curInt->playerID)
chi = attackingHeroInstance;
@ -1463,6 +1465,7 @@ void CBattleInterface::bSpellf()
CSpellWindow * spellWindow = new CSpellWindow(genRect(595, 620, (screen->w - 620)/2, (screen->h - 595)/2), chi, curInt);
GH.pushInt(spellWindow);
}
}
void CBattleInterface::bWaitf()
{

View File

@ -1168,8 +1168,13 @@ CAnimImage::~CAnimImage()
void CAnimImage::showAll(SDL_Surface * to)
{
IImage *img = anim->getImage(frame, group);
if (img)
IImage *img;
if ( flags & CShowableAnim::BASE && frame != 0)
if ((img = anim->getImage(0, group)))
img->draw(to, pos.x, pos.y);
if ((img = anim->getImage(frame, group)))
img->draw(to, pos.x, pos.y);
}

View File

@ -11,17 +11,9 @@
*/
// Use some magic to keep the list of files and their code name in sync.
// FIXME: first half of this list should be read from campmusic.txt
#define VCMI_MUSIC_LIST \
VCMI_MUSIC_ID(AITheme0) VCMI_MUSIC_FILE("AITheme0.mp3") \
VCMI_MUSIC_ID(AITheme1) VCMI_MUSIC_FILE("AITHEME1.MP3") \
VCMI_MUSIC_ID(AITheme2) VCMI_MUSIC_FILE("AITHEME2.MP3") \
VCMI_MUSIC_ID(bladeABCampaign) VCMI_MUSIC_FILE("BladeABCampaign.mp3") \
VCMI_MUSIC_ID(bladeDBCampaign) VCMI_MUSIC_FILE("BladeDBCampaign.mp3") \
VCMI_MUSIC_ID(bladeDSCampaign) VCMI_MUSIC_FILE("BladeDSCampaign.mp3") \
VCMI_MUSIC_ID(bladeFLCampaign) VCMI_MUSIC_FILE("BladeFLCampaign.mp3") \
VCMI_MUSIC_ID(bladeFWCampaign) VCMI_MUSIC_FILE("BladeFWCampaign.mp3") \
VCMI_MUSIC_ID(bladePFCampaign) VCMI_MUSIC_FILE("BladePFCampaign.mp3") \
VCMI_MUSIC_ID(campainMusic01) VCMI_MUSIC_FILE("CampainMusic01.mp3") \
VCMI_MUSIC_ID(campainMusic02) VCMI_MUSIC_FILE("CampainMusic02.mp3") \
VCMI_MUSIC_ID(campainMusic03) VCMI_MUSIC_FILE("CampainMusic03.mp3") \
@ -31,46 +23,55 @@
VCMI_MUSIC_ID(campainMusic07) VCMI_MUSIC_FILE("CampainMusic07.mp3") \
VCMI_MUSIC_ID(campainMusic08) VCMI_MUSIC_FILE("CampainMusic08.mp3") \
VCMI_MUSIC_ID(campainMusic09) VCMI_MUSIC_FILE("CampainMusic09.mp3") \
VCMI_MUSIC_ID(campainMusic10) VCMI_MUSIC_FILE("CampainMusic10.mp3") \
VCMI_MUSIC_ID(campainMusic11) VCMI_MUSIC_FILE("CampainMusic11.mp3") \
VCMI_MUSIC_ID(AITheme0) VCMI_MUSIC_FILE("AITheme0.mp3") \
VCMI_MUSIC_ID(AITheme1) VCMI_MUSIC_FILE("AITHEME1.MP3") \
VCMI_MUSIC_ID(AITheme2) VCMI_MUSIC_FILE("AITHEME2.MP3") \
VCMI_MUSIC_ID(combat1) VCMI_MUSIC_FILE("COMBAT01.MP3") \
VCMI_MUSIC_ID(combat2) VCMI_MUSIC_FILE("COMBAT02.MP3") \
VCMI_MUSIC_ID(combat3) VCMI_MUSIC_FILE("COMBAT03.MP3") \
VCMI_MUSIC_ID(combat4) VCMI_MUSIC_FILE("COMBAT04.MP3") \
VCMI_MUSIC_ID(castleTown) VCMI_MUSIC_FILE("CstleTown.mp3") \
VCMI_MUSIC_ID(defendCastle) VCMI_MUSIC_FILE("Defend Castle.mp3") \
VCMI_MUSIC_ID(dirt) VCMI_MUSIC_FILE("DIRT.MP3") \
VCMI_MUSIC_ID(dungeonTown) VCMI_MUSIC_FILE("DUNGEON.MP3") \
VCMI_MUSIC_ID(elemTown) VCMI_MUSIC_FILE("ElemTown.mp3") \
VCMI_MUSIC_ID(evilTheme) VCMI_MUSIC_FILE("EvilTheme.mp3") \
VCMI_MUSIC_ID(fortressTown) VCMI_MUSIC_FILE("FortressTown.mp3") \
VCMI_MUSIC_ID(goodTheme) VCMI_MUSIC_FILE("GoodTheme.mp3") \
VCMI_MUSIC_ID(grass) VCMI_MUSIC_FILE("GRASS.MP3") \
VCMI_MUSIC_ID(towerTown) VCMI_MUSIC_FILE("TowerTown.mp3") \
VCMI_MUSIC_ID(rampartTown) VCMI_MUSIC_FILE("RAMPART.MP3") \
VCMI_MUSIC_ID(infernoTown) VCMI_MUSIC_FILE("InfernoTown.mp3") \
VCMI_MUSIC_ID(necroTown) VCMI_MUSIC_FILE("necroTown.mp3") \
VCMI_MUSIC_ID(dungeonTown) VCMI_MUSIC_FILE("DUNGEON.MP3") \
VCMI_MUSIC_ID(strongHoldTown) VCMI_MUSIC_FILE("StrongHold.mp3") \
VCMI_MUSIC_ID(fortressTown) VCMI_MUSIC_FILE("FortressTown.mp3") \
VCMI_MUSIC_ID(elemTown) VCMI_MUSIC_FILE("ElemTown.mp3") \
VCMI_MUSIC_ID(dirt) VCMI_MUSIC_FILE("DIRT.MP3") \
VCMI_MUSIC_ID(sand) VCMI_MUSIC_FILE("SAND.MP3") \
VCMI_MUSIC_ID(grass) VCMI_MUSIC_FILE("GRASS.MP3") \
VCMI_MUSIC_ID(snow) VCMI_MUSIC_FILE("SNOW.MP3") \
VCMI_MUSIC_ID(swamp) VCMI_MUSIC_FILE("SWAMP.MP3") \
VCMI_MUSIC_ID(rough) VCMI_MUSIC_FILE("ROUGH.MP3") \
VCMI_MUSIC_ID(underground) VCMI_MUSIC_FILE("Underground.mp3") \
VCMI_MUSIC_ID(lava) VCMI_MUSIC_FILE("LAVA.MP3") \
VCMI_MUSIC_ID(water) VCMI_MUSIC_FILE("WATER.MP3") \
VCMI_MUSIC_ID(goodTheme) VCMI_MUSIC_FILE("GoodTheme.mp3") \
VCMI_MUSIC_ID(neutralTheme) VCMI_MUSIC_FILE("NeutralTheme.mp3") \
VCMI_MUSIC_ID(evilTheme) VCMI_MUSIC_FILE("EvilTheme.mp3") \
VCMI_MUSIC_ID(secretTheme) VCMI_MUSIC_FILE("SecretTheme.mp3") \
VCMI_MUSIC_ID(loopLepr) VCMI_MUSIC_FILE("LoopLepr.mp3") \
VCMI_MUSIC_ID(mainMenu) VCMI_MUSIC_FILE("MAINMENU.MP3") \
VCMI_MUSIC_ID(winScenario) VCMI_MUSIC_FILE("Win Scenario.mp3" ) \
VCMI_MUSIC_ID(campainMusic10) VCMI_MUSIC_FILE("CampainMusic10.mp3") \
VCMI_MUSIC_ID(bladeABcampaign) VCMI_MUSIC_FILE("BladeABCampaign.mp3") \
VCMI_MUSIC_ID(bladeDBcampaign) VCMI_MUSIC_FILE("BladeDBCampaign.mp3") \
VCMI_MUSIC_ID(bladeDScampaign) VCMI_MUSIC_FILE("BladeDSCampaign.mp3") \
VCMI_MUSIC_ID(bladeFLcampaign) VCMI_MUSIC_FILE("BladeFLCampaign.mp3") \
VCMI_MUSIC_ID(bladeFWcampaign) VCMI_MUSIC_FILE("BladeFWCampaign.mp3") \
VCMI_MUSIC_ID(bladePWcampaign) VCMI_MUSIC_FILE("BladePFCampaign.mp3") \
VCMI_MUSIC_ID(campainMusic11) VCMI_MUSIC_FILE("CampainMusic11.mp3") \
VCMI_MUSIC_ID(loseCampain) VCMI_MUSIC_FILE("Lose Campain.mp3") \
VCMI_MUSIC_ID(loseCastle) VCMI_MUSIC_FILE("LoseCastle.mp3") \
VCMI_MUSIC_ID(loseCombat) VCMI_MUSIC_FILE("LoseCombat.mp3") \
VCMI_MUSIC_ID(mainMenu) VCMI_MUSIC_FILE("MAINMENU.MP3") \
VCMI_MUSIC_ID(mainMenuWoG) VCMI_MUSIC_FILE("MainMenuWoG.mp3") \
VCMI_MUSIC_ID(necroTown) VCMI_MUSIC_FILE("necroTown.mp3") \
VCMI_MUSIC_ID(neutralTheme) VCMI_MUSIC_FILE("NeutralTheme.mp3") \
VCMI_MUSIC_ID(rampartTown) VCMI_MUSIC_FILE("RAMPART.MP3") \
VCMI_MUSIC_ID(retreatBattle) VCMI_MUSIC_FILE("Retreat Battle.mp3") \
VCMI_MUSIC_ID(rough) VCMI_MUSIC_FILE("ROUGH.MP3") \
VCMI_MUSIC_ID(sand) VCMI_MUSIC_FILE("SAND.MP3") \
VCMI_MUSIC_ID(secretTheme) VCMI_MUSIC_FILE("SecretTheme.mp3") \
VCMI_MUSIC_ID(snow) VCMI_MUSIC_FILE("SNOW.MP3") \
VCMI_MUSIC_ID(strongHoldTown) VCMI_MUSIC_FILE("StrongHold.mp3") \
VCMI_MUSIC_ID(surrenderBattle) VCMI_MUSIC_FILE("Surrender Battle.mp3") \
VCMI_MUSIC_ID(swamp) VCMI_MUSIC_FILE("SWAMP.MP3") \
VCMI_MUSIC_ID(towerTown) VCMI_MUSIC_FILE("TowerTown.mp3") \
VCMI_MUSIC_ID(ultimateLose) VCMI_MUSIC_FILE("UltimateLose.mp3") \
VCMI_MUSIC_ID(underground) VCMI_MUSIC_FILE("Underground.mp3") \
VCMI_MUSIC_ID(water) VCMI_MUSIC_FILE("WATER.MP3") \
VCMI_MUSIC_ID(winBattle) VCMI_MUSIC_FILE("Win Battle.mp3") \
VCMI_MUSIC_ID(winScenario) VCMI_MUSIC_FILE("Win Scenario.mp3" )
VCMI_MUSIC_ID(defendCastle) VCMI_MUSIC_FILE("Defend Castle.mp3") \
class musicBase
{

View File

@ -487,7 +487,6 @@ CInfoWindow::CInfoWindow(std::string Text, int player, const TCompsInfo &comps,
text->pos.w = text->maxW;
text->pos.h = text->maxH;
}
text->redrawParentOnScrolling = true;
if(buttons.size())
{
@ -914,7 +913,6 @@ CSelWindow::CSelWindow(const std::string &Text, int player, int charperline, con
}
text = new CTextBox(Text, Rect(0, 0, 250, 100), 0, FONT_MEDIUM, CENTER, Colors::Cornsilk);
text->redrawParentOnScrolling = true;
buttons.front()->assignedKeys.insert(SDLK_RETURN); //first button - reacts on enter
buttons.back()->assignedKeys.insert(SDLK_ESCAPE); //last button - reacts on escape
@ -3595,7 +3593,7 @@ void CSystemOptionsWindow::setHeroMoveSpeed( int newSpeed )
void CSystemOptionsWindow::setMapScrollingSpeed( int newSpeed )
{
Settings speed = settings.write["adventure"]["mapScrollingSpeed"];
Settings speed = settings.write["adventure"]["scrollSpeed"];
speed->Float() = newSpeed;
}

View File

@ -139,24 +139,35 @@ public:
void disable(); //deactivates if needed, blocks all automatic activity, allows only disposal
void enable(bool activation = true); //activates if needed, all activity enabled (Warning: may not be symetric with disable if recActions was limited!)
void defActivate();
void defDeactivate();
// activate or deactivate object. Inactive object won't receive any input events (keyboard\mouse)
// usually used automatically by parent
void activate();
void deactivate();
//activate or deactivate specific action (LCLICK, RCLICK...)
void activate(ui16 what);
void deactivate(ui16 what);
//called each frame to update screen
void show(SDL_Surface * to);
//called on complete redraw only
void showAll(SDL_Surface * to);
//request complete redraw
void redraw();
void drawBorderLoc(SDL_Surface * sur, const Rect &r, const int3 &color);
void printAtLoc(const std::string & text, int x, int y, EFonts font, SDL_Color kolor, SDL_Surface * dst);
void printToLoc(const std::string & text, int x, int y, EFonts font, SDL_Color kolor, SDL_Surface * dst);
void printAtMiddleLoc(const std::string & text, int x, int y, EFonts font, SDL_Color kolor, SDL_Surface * dst);
void printAtMiddleLoc(const std::string & text, const Point &p, EFonts font, SDL_Color kolor, SDL_Surface * dst);
void printAtMiddleWBLoc(const std::string & text, int x, int y, EFonts font, int charpr, SDL_Color kolor, SDL_Surface * dst);
//functions for printing text. Use CLabel where possible instead
void printAtLoc(const std::string & text, int x, int y, EFonts font, SDL_Color color, SDL_Surface * dst);
void printToLoc(const std::string & text, int x, int y, EFonts font, SDL_Color color, SDL_Surface * dst);
void printAtMiddleLoc(const std::string & text, int x, int y, EFonts font, SDL_Color color, SDL_Surface * dst);
void printAtMiddleLoc(const std::string & text, const Point &p, EFonts font, SDL_Color color, SDL_Surface * dst);
void printAtMiddleWBLoc(const std::string & text, int x, int y, EFonts font, int charsPerLine, SDL_Color color, SDL_Surface * dst);
//image blitting. If possible use CPicture or CAnimImage instead
void blitAtLoc(SDL_Surface * src, int x, int y, SDL_Surface * dst);
void blitAtLoc(SDL_Surface * src, const Point &p, SDL_Surface * dst);
bool isItInLoc(const SDL_Rect &rect, int x, int y);
bool isItInLoc(const SDL_Rect &rect, const Point &p);
const Rect & center(const Rect &r, bool propagate = true); //sets pos so that r will be in the center of screen, assigns sizes of r to pos, returns new position
@ -164,10 +175,12 @@ public:
const Rect & center(bool propagate = true); //centers when pos.w and pos.h are set, returns new position
void fitToScreen(int borderWidth, bool propagate = true); //moves window to fit into screen
void moveBy(const Point &p, bool propagate = true);
void moveTo(const Point &p, bool propagate = true);
void moveTo(const Point &p, bool propagate = true);//move this to new position, coordinates are absolute (0,0 is topleft screen corner)
void changeUsedEvents(ui16 what, bool enable, bool adjust = true);
//add child without parent to this. Use CGuiHandler::moveChild() if child already have parent
void addChild(CIntObject *child, bool adjustPosition = false);
//remove child from this without deleting
void removeChild(CIntObject *child, bool adjustPosition = false);
void delChild(CIntObject *child); //removes from children list, deletes
template <typename T> void delChildNUll(T *&child, bool deactivateIfNeeded = false) //removes from children list, deletes and sets pointer to NULL

View File

@ -361,14 +361,14 @@ void CAdventureMapButton::setIndex(size_t index, bool playerColoredButton)
setImage(new CAnimation(imageNames[index]), playerColoredButton);
}
void CAdventureMapButton::setImage(CAnimation* anim, bool playerColoredButton)
void CAdventureMapButton::setImage(CAnimation* anim, bool playerColoredButton, int animFlags)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
if (image && active)
image->deactivate();
delChild(image);
image = new CAnimImage(anim, getState());
image = new CAnimImage(anim, getState(), 0, 0, 0, animFlags);
if (active)
image->activate();
if (playerColoredButton)
@ -1189,6 +1189,9 @@ CLabel::CLabel(int x, int y, EFonts Font /*= FONT_SMALL*/, EAlignment Align, con
pos.w = pos.h = 0;
bg = NULL;
ignoreLeadingWhitespace = false;
pos.w = graphics->fonts[font]->getWidth(text.c_str());
pos.h = graphics->fonts[font]->height;
}
void CLabel::setTxt(const std::string &Txt)
@ -1216,7 +1219,7 @@ void CLabelGroup::add(int x, int y, const std::string &text)
CTextBox::CTextBox(std::string Text, const Rect &rect, int SliderStyle, EFonts Font /*= FONT_SMALL*/, EAlignment Align /*= TOPLEFT*/, const SDL_Color &Color /*= Colors::Cornsilk*/)
:CLabel(rect.x, rect.y, Font, Align, Color, Text), sliderStyle(SliderStyle), slider(NULL)
{
redrawParentOnScrolling = false;
type |= REDRAW_PARENT;
autoRedraw = false;
pos.h = rect.h;
pos.w = rect.w;
@ -1270,8 +1273,6 @@ void CTextBox::sliderMoved(int to)
if(!slider)
return;
if(redrawParentOnScrolling)
parent->redraw();
redraw();
}

View File

@ -129,7 +129,7 @@ public:
void init(const CFunctionList<void()> &Callback, const std::map<int,std::string> &Name, const std::string &HelpBox, bool playerColoredButton, const std::string &defName, std::vector<std::string> * add, int x, int y, int key );
void setIndex(size_t index, bool playerColoredButton=false);
void setImage(CAnimation* anim, bool playerColoredButton=false);
void setImage(CAnimation* anim, bool playerColoredButton=false, int animFlags=0);
void setPlayerColor(int player);
void showAll(SDL_Surface * to);
};
@ -340,7 +340,6 @@ public:
int maxH; //total height needed to print all lines
int sliderStyle;
bool redrawParentOnScrolling;
std::vector<std::string> lines;
std::vector<CAnimImage* > effects;

View File

@ -1119,6 +1119,9 @@ std::string CSDL_Ext::processStr(std::string str, std::vector<std::string> & tor
bool CSDL_Ext::isTransparent( SDL_Surface * srf, int x, int y )
{
if (x < 0 || y < 0 || x >= srf->w || y >= srf->h)
return true;
if(srf->format->BytesPerPixel == 1)
{
return ((ui8*)srf->pixels)[x + srf->pitch * y] == 0;

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,12 @@
{
"campaign_regions": [
{
"prefix": "E1",
"prefix": "G1",
"color_suffix_length": 1,
"desc": [
{ "infix": "A", "x": 270, "y": 332 },
{ "infix": "B", "x": 138, "y": 113 },
{ "infix": "C", "x": 26, "y": 70 },
{ "infix": "P1", "x": 256, "y": 127 },
{ "infix": "P2", "x": 57, "y": 314 },
{ "infix": "P3", "x": 137, "y": 310 },
{ "infix": "P4", "x": 44, "y": 163 }
{ "infix": "A", "x": 57, "y": 314 },
{ "infix": "B", "x": 137, "y": 309 },
{ "infix": "C", "x": 44, "y": 163 }
]
},
@ -25,6 +21,30 @@
]
},
{
"prefix": "G3",
"color_suffix_length": 1,
"desc": [
{ "infix": "A", "x": 289, "y": 376 },
{ "infix": "B", "x": 60, "y": 147 },
{ "infix": "C", "x": 131, "y": 202 }
]
},
{
"prefix": "E1",
"color_suffix_length": 1,
"desc": [
{ "infix": "A", "x": 270, "y": 332 },
{ "infix": "B", "x": 138, "y": 113 },
{ "infix": "C", "x": 26, "y": 70 },
{ "infix": "P1", "x": 256, "y": 127 },
{ "infix": "P2", "x": 57, "y": 314 },
{ "infix": "P3", "x": 137, "y": 310 },
{ "infix": "P4", "x": 44, "y": 163 }
]
},
{
"prefix": "E2",
"color_suffix_length": 1,
@ -36,26 +56,6 @@
]
},
{
"prefix": "G1",
"color_suffix_length": 1,
"desc": [
{ "infix": "A", "x": 57, "y": 314 },
{ "infix": "B", "x": 137, "y": 309 },
{ "infix": "C", "x": 44, "y": 163 }
]
},
{
"prefix": "G3",
"color_suffix_length": 1,
"desc": [
{ "infix": "A", "x": 289, "y": 376 },
{ "infix": "B", "x": 60, "y": 147 },
{ "infix": "C", "x": 131, "y": 202 }
]
},
{
"prefix": "N1",
"color_suffix_length": 1,
@ -149,7 +149,7 @@
"prefix": "HS",
"color_suffix_length": 2,
"desc": [
{ "infix": "A", "x": 140, "y": 326 },
{ "infix": "A", "x": 141, "y": 326 },
{ "infix": "B", "x": 238, "y": 275 },
{ "infix": "C", "x": 22, "y": 161 },
{ "infix": "D", "x": 5, "y": 9 }

View File

@ -175,11 +175,11 @@ CCampaignScenario CCampaignHandler::readScenarioFromMemory( const ui8 *buffer, i
ret.packedMapSize = read_le_u32(buffer + outIt); outIt += 4;
if(mapVersion == 18)//unholy alliance
{
ret.preconditionRegion = read_le_u16(buffer + outIt); outIt += 2;
ret.loadPreconditionRegions(read_le_u16(buffer + outIt)); outIt += 2;
}
else
{
ret.preconditionRegion = buffer[outIt++];
ret.loadPreconditionRegions(buffer[outIt++]);
}
ret.regionColor = buffer[outIt++];
ret.difficulty = buffer[outIt++];
@ -192,6 +192,15 @@ CCampaignScenario CCampaignHandler::readScenarioFromMemory( const ui8 *buffer, i
return ret;
}
void CCampaignScenario::loadPreconditionRegions(ui32 regions)
{
for (int i=0; i<32; i++) //for each bit in region. h3c however can only hold up to 16
{
if ( (1 << i) & regions)
preconditionRegions.insert(i);
}
}
CScenarioTravel CCampaignHandler::readScenarioTravelFromMemory( const ui8 * buffer, int & outIt , int version )
{
CScenarioTravel ret;
@ -444,7 +453,7 @@ bool CCampaign::conquerable( int whichScenario ) const
//check preconditioned regions
for (int g=0; g<scenarios.size(); ++g)
{
if(( (1 << g) & scenarios[whichScenario].preconditionRegion ) && !scenarios[g].conquered)
if( vstd::contains(scenarios[whichScenario].preconditionRegions, g) && !scenarios[g].conquered)
return false; //prerequisite does not met
}
@ -510,17 +519,25 @@ void CCampaignScenario::prepareCrossoverHeroes( std::vector<CGHeroInstance *> he
if (!(travelOptions.whatHeroKeeps & 16))
{
//trimming artifacts
for (int g=0; g<VLC->arth->artifacts.size(); ++g)
BOOST_FOREACH(CGHeroInstance * hero, crossoverHeroes)
{
bool takeable = travelOptions.artifsKeptByHero[g / 8] & ( 1 << (g%8) ) ;
if (!takeable)
size_t totalArts = GameConstants::BACKPACK_START + hero->artifactsInBackpack.size();
for (size_t i=0; i<totalArts; i++ )
{
//BOOST_FOREACH(CGHeroInstance * cgh, crossoverHeroes)
{
tlog1 << "TODO TODO TODO - take artifacts from hero\n";
//TODO how was that supposed to work with worn artifacts?
//cgh->artifactsInBackpack -= VLC->arth->artifacts[g];
}
const ArtSlotInfo *info = hero->getSlot(i);
if (!info)
continue;
const CArtifactInstance *art = info->artifact;
if (!art)//FIXME: check spellbook and catapult behaviour
continue;
int id = art->artType->id;
assert( 8*18 > id );//number of arts that fits into h3m format
bool takeable = travelOptions.artifsKeptByHero[id / 8] & ( 1 << (id%8) );
if (takeable)
hero->eraseArtSlot(i);
}
}
}

View File

@ -83,7 +83,7 @@ class DLL_LINKAGE CCampaignScenario
public:
std::string mapName;
ui32 packedMapSize; //generally not used
ui16 preconditionRegion; //what we need to conquer to conquer this one (bitfield!)
std::set<ui8> preconditionRegions; //what we need to conquer to conquer this one (stored as bitfield in h3c)
ui8 regionColor;
ui8 difficulty;
ui8 conquered;
@ -109,13 +109,14 @@ public:
std::vector<CGHeroInstance*> crossoverHeroes;
void loadPreconditionRegions(ui32 regions);
void prepareCrossoverHeroes(std::vector<CGHeroInstance *> heroes);
bool isNotVoid() const;
template <typename Handler> void serialize(Handler &h, const int formatVersion)
{
h & mapName & packedMapSize & preconditionRegion & regionColor & difficulty & conquered & regionText &
h & mapName & packedMapSize & preconditionRegions & regionColor & difficulty & conquered & regionText &
prolog & epilog & travelOptions & crossoverHeroes;
}
};

View File

@ -38,7 +38,7 @@ CCreatureHandler::CCreatureHandler()
// Good: Castle, Rampart, Tower // Evil: Inferno, Necropolis, Dungeon
// Neutral: Stronghold, Fortess, Conflux
factionAlignments += 1, 1, 1, -1, -1, -1, 0, 0, 0;
doubledCreatures += 4, 14, 20, 28, 42, 44, 60, 70, 72, 85, 86, 100, 104; //according to Strategija
doubledCreatures += 4, 14, 20, 28, 44, 60, 70, 72, 85, 86, 100, 104; //according to Strategija
allCreatures.setDescription("All creatures");
creaturesOfLevel[0].setDescription("Creatures of unnormalized tier");

View File

@ -795,7 +795,7 @@ CGameState::CGameState()
}
CGameState::~CGameState()
{
delete mx;
//delete mx;//TODO: crash on Linux (mutex must be unlocked before destruction)
map.dellNull();
curB.dellNull();
//delete scenarioOps; //TODO: fix for loading ind delete

View File

@ -93,32 +93,8 @@ static void readCreatures(const JsonNode &creature, std::vector< std::pair <ui16
std::pair<si16, si32> creInfo = std::make_pair(-1, 0);
std::string creName = creature["name"].String();
// Look for the best creature that is described by given name
if (vstd::contains(VLC->creh->nameToID, creName))
{
creInfo.first = VLC->creh->nameToID[creName];
}
else
{
BOOST_FOREACH(const CCreature *cre, VLC->creh->creatures)
{
if (cre->namePl == creName ||
cre->nameRef == creName ||
cre->nameSing == creName)
creInfo.first = cre->idNumber;
}
}
if (creInfo.first != -1)
{
creInfo.second = creature["number"].Float();
storage.push_back(creInfo);
}
else
{
//FIXME: localization issues. switch to numeric ID's in bank config?
tlog0<<"Unknown creature in bank config: "<<creName<<"\n";
}
creInfo.first = creature["id"].Float();
}
// Bank helper. Process a bank level.
@ -2998,7 +2974,7 @@ void CGCreature::initObj()
switch(character)
{
case 0:
character = 0;
character = -4;
break;
case 1:
character = 1 + ran()%7;
@ -3059,34 +3035,35 @@ void CGCreature::setPropertyDer(ui8 what, ui32 val)
int CGCreature::takenAction(const CGHeroInstance *h, bool allowJoin) const
{
double hlp = h->getTotalStrength() / getArmyStrength();
//calculate relative strength of hero and creatures armies
double relStrength = double(h->getTotalStrength()) / getArmyStrength();
if(!character) //compliant creatures will always join
return 0;
else if(allowJoin)//test for joining
{
int factor;
if(hlp >= 7)
factor = 11;
else if(hlp >= 1)
factor = (int)(2*(hlp-1));
else if(hlp >= 0.5)
factor = -1;
else if(hlp >= 0.333)
factor = -2;
int powerFactor;
if(relStrength >= 7)
powerFactor = 11;
else if(relStrength >= 1)
powerFactor = (int)(2*(relStrength-1));
else if(relStrength >= 0.5)
powerFactor = -1;
else if(relStrength >= 0.333)
powerFactor = -2;
else
factor = -3;
int sympathy = 0;
powerFactor = -3;
std::set<ui32> myKindCres; //what creatures are the same kind as we
myKindCres.insert(subID); //we
myKindCres.insert(VLC->creh->creatures[subID]->upgrades.begin(),VLC->creh->creatures[subID]->upgrades.end()); //our upgrades
for(std::vector<ConstTransitivePtr<CCreature> >::iterator i=VLC->creh->creatures.begin(); i!=VLC->creh->creatures.end(); i++)
if(vstd::contains((*i)->upgrades, (ui32) id)) //it's our base creatures
myKindCres.insert((*i)->idNumber);
int count = 0, //how many creatures of our kind has hero
BOOST_FOREACH(ConstTransitivePtr<CCreature> &crea, VLC->creh->creatures)
{
if(vstd::contains(crea->upgrades, (ui32) id)) //it's our base creatures
myKindCres.insert(crea->idNumber);
}
int count = 0, //how many creatures of similar kind has hero
totalCount = 0;
for (TSlots::const_iterator i = h->Slots().begin(); i != h->Slots().end(); i++)
@ -3096,35 +3073,32 @@ int CGCreature::takenAction(const CGHeroInstance *h, bool allowJoin) const
totalCount += i->second->count;
}
if(count*2 > totalCount)
sympathy++;
int sympathy = 0; // 0 if hero have no similar creatures
if(count)
sympathy++;
sympathy++; // 1 - if hero have at least 1 similar creature
if(count*2 > totalCount)
sympathy++; // 2 - hero have similar creatures more that 50%
int charisma = powerFactor + h->getSecSkillLevel(CGHeroInstance::DIPLOMACY) + sympathy;
int charisma = factor + h->getSecSkillLevel(CGHeroInstance::DIPLOMACY) + sympathy;
if(charisma >= character) //creatures might join...
if(charisma < character) //creatures will fight
return -2;
if (allowJoin)
{
if(h->getSecSkillLevel(CGHeroInstance::DIPLOMACY) + sympathy + 1 >= character)
return 0; //join for free
else if(h->getSecSkillLevel(CGHeroInstance::DIPLOMACY) * 2 + sympathy + 1 >= character)
return VLC->creh->creatures[subID]->cost[6] * getStackCount(0); //join for gold
}
}
//we are still here - creatures not joined heroes, test for fleeing
//we are still here - creatures have not joined hero, flee or fight
//TODO: it's provisional formula, should be replaced with original one (or something closer to it)
//TODO: should be deterministic (will be needed for Vision spell)
int hlp2 = (int) (hlp - 2)*1000;
if(!neverFlees
&& hlp2 >= 0
&& rand()%2000 < hlp2
)
if (charisma > character)
return -1; //flee
else
return -2; //fight
}
void CGCreature::fleeDecision(const CGHeroInstance *h, ui32 pursue) const

View File

@ -688,7 +688,7 @@ class DLL_LINKAGE CGCreature : public CArmedInstance //creatures on map
{
public:
ui32 identifier; //unique code for this monster (used in missions)
si8 character; //character of this set of creatures (0 - the most friendly, 4 - the most hostile) => on init changed to 0 (compliant) - 10 value (savage)
si8 character; //character of this set of creatures (0 - the most friendly, 4 - the most hostile) => on init changed to -4 (compliant) ... 10 value (savage)
std::string message; //message printed for attacking hero
std::vector<ui32> resources; //[res_id], resources given to hero that has won with monsters
si32 gainedArtifact; //ID of artifact gained to hero, -1 if none

View File

@ -754,7 +754,7 @@ public:
#define READ_CHECK_U32(x) \
ui32 length; \
*this >> length; \
if(length > 50000) \
if(length > 500000) \
{ \
tlog2 << "Warning: very big length: " << length << "\n" ;\
reportState(tlog2); \

View File

@ -21,6 +21,7 @@ struct PlayerSettings
si8 bonus; //usees enum type Ebonus
ui8 color; //from 0 -
ui8 handicap;//0-no, 1-mild, 2-severe
ui8 team;
std::string name;
ui8 human; //0 - AI, non-0 serves as player id
@ -35,6 +36,7 @@ struct PlayerSettings
h & handicap;
h & name;
h & human;
h & team;
}
PlayerSettings()
@ -52,7 +54,10 @@ struct StartInfo
ui8 mode; //uses EMode enum
ui8 difficulty; //0=easy; 4=impossible
bmap<int, PlayerSettings> playerInfos; //color indexed
typedef bmap<int, PlayerSettings> TPlayerInfos;
TPlayerInfos playerInfos; //color indexed
ui8 turnTime; //in minutes, 0=unlimited
std::string mapname;
ui8 whichMapInCampaign; //used only for mode CAMPAIGN

View File

@ -1031,15 +1031,16 @@ void CGameHandler::newTurn()
else
availableCount += t->creatureGrowth(k);
if( vstd::contains(t->creatures[k].second, n.creatureid)
|| (n.specialWeek == NewTurn::DEITYOFFIRE && (cre->idNumber == 42 || cre->idNumber == 43)))
//Deity of fire week - upgrade both imps and upgrades
if (n.specialWeek == NewTurn::DEITYOFFIRE && vstd::contains(t->creatures[k].second, n.creatureid))
availableCount += 15;
if( cre->idNumber == n.creatureid ) //bonus week, effect applies only to identical creatures
{
if(n.specialWeek == NewTurn::DOUBLE_GROWTH)
availableCount *= 2;
else if(n.specialWeek == NewTurn::BONUS_GROWTH)
availableCount += 5;
else if(n.specialWeek == NewTurn::DEITYOFFIRE)
availableCount += 15;
}
}
}
@ -1130,9 +1131,17 @@ void CGameHandler::newTurn()
iw.text.addReplacement2(15); //%+d 15
break;
default:
iw.text.addTxt(MetaString::ARRAY_TXT, (newMonth ? 130 : 133));
if (newMonth)
{
iw.text.addTxt(MetaString::ARRAY_TXT, (130));
iw.text.addReplacement(MetaString::ARRAY_TXT, 32 + rand()%10);
}
else
{
iw.text.addTxt(MetaString::ARRAY_TXT, (133));
iw.text.addReplacement(MetaString::ARRAY_TXT, 43 + rand()%15);
}
}
for (std::map<ui8, PlayerState>::iterator i=gs->players.begin() ; i!=gs->players.end(); i++)
{
iw.player = i->first;
@ -4486,7 +4495,7 @@ void CGameHandler::checkLossVictory( ui8 player )
std::vector<CGHeroInstance *> hes;
BOOST_FOREACH(CGHeroInstance * ghi, gs->map->heroes)
{
if (ghi->tempOwner == 0 /*TODO: insert human player's color*/)
if (ghi->tempOwner == vic)
{
hes.push_back(ghi);
}
@ -5530,7 +5539,7 @@ void CGameHandler::spawnWanderingMonsters(int creatureID)
std::vector<int3>::iterator tile;
std::vector<int3> tiles;
getFreeTiles(tiles);
ui32 amount = (tiles.size()) >> 6;
ui32 amount = tiles.size() / 200; //Chance is 0.5% for each tile
std::random_shuffle(tiles.begin(), tiles.end(), p_myrandom);
tlog5 << "Spawning wandering monsters. Found " << tiles.size() << " free tiles. Creature type: " << creatureID << std::endl;
const CCreature *cre = VLC->creh->creatures[creatureID];